mirror of
https://github.com/Sosokker/B2D-Ventures.git
synced 2025-12-18 13:34:06 +01:00
Merge branch 'front-end' into back-end
This commit is contained in:
commit
38e09f80b6
@ -26,8 +26,12 @@ const nextConfig = {
|
||||
hostname: "avatars.githubusercontent.com",
|
||||
pathname: "/**",
|
||||
},
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "assets.republic.com",
|
||||
pathname: "/**",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
|
||||
@ -98,7 +98,7 @@ export default async function ProjectDealPage({ params }: { params: { id: number
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div id="sub-content" className="flex flex-row mt-5">
|
||||
<div id="sub-content" className="grid grid-cols-1 md:grid-cols-2 mt-5 space-y-5 md:space-y-0">
|
||||
{/* image carousel */}
|
||||
<div id="image-carousel" className="w-full">
|
||||
<Gallery images={carouselData} />
|
||||
@ -152,62 +152,28 @@ export default async function ProjectDealPage({ params }: { params: { id: number
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex justify-between w-full">
|
||||
<Button className="w-[48%] h-12 dark:text-white" variant={"outline"}>
|
||||
<Link href={`/dataroom/${params.id}/files`}>Access Dataroom</Link>
|
||||
<div className="flex justify-between gap-4 w-full">
|
||||
<Button
|
||||
className="flex justify-center items-center w-[48%] h-12 text-xs md:text-sm text-center dark:text-white"
|
||||
variant="outline"
|
||||
>
|
||||
<Link href={`/dataroom/${params.id}/files`} className="block text-center break-words">
|
||||
<span className="block lg:inline">Access</span>
|
||||
<span className="block lg:inline"> Dataroom</span>
|
||||
</Link>
|
||||
</Button>
|
||||
<Button className="w-[48%] h-12 dark:text-white" variant={"outline"}>
|
||||
<Link href={`/dataroom/overview`}>Request Dataroom Access</Link>
|
||||
<Button
|
||||
className="flex justify-center items-center w-[48%] h-12 text-xs md:text-sm text-center dark:text-white"
|
||||
variant="outline"
|
||||
>
|
||||
<Link href={`/dataroom/overview`} className="block text-center break-words">
|
||||
<span className="block lg:inline">Request</span>
|
||||
<span className="block lg:inline"> Dataroom Access</span>
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
|
||||
{/* <div id="stats" className="flex flex-col w-full mt-4 pl-12">
|
||||
<div className="pl-5">
|
||||
<span>
|
||||
<h1 className="font-semibold text-xl md:text-4xl mt-8">${totalDealAmount}</h1>
|
||||
<p className="text-sm md:text-lg">
|
||||
{toPercentage(totalDealAmount, projectData?.target_investment)}% raised of $
|
||||
{projectData?.target_investment} max goal
|
||||
</p>
|
||||
<Progress
|
||||
value={toPercentage(totalDealAmount, projectData?.target_investment)}
|
||||
className="w-[60%] h-3 mt-3"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
<h1 className="font-semibold text-4xl md:mt-8">
|
||||
<p className="text-xl md:text-4xl">{dealList.length}</p>
|
||||
</h1>
|
||||
<p className="text-sm md:text-lg">Investors</p>
|
||||
</span>
|
||||
<Separator decorative className="mt-3 w-3/4 ml-5" />
|
||||
<span>
|
||||
<h1 className="font-semibold text-xl md:text-4xl mt-8 ml-5"></h1>
|
||||
{projectData?.investment_deadline ? (
|
||||
<>
|
||||
<p className="text-xl md:text-4xl">{Math.floor(hourLeft)} hours</p>
|
||||
<p>Left to invest</p>
|
||||
</>
|
||||
) : (
|
||||
<p className="text-xl md:text-4xl">No deadline</p>
|
||||
)}
|
||||
</span>
|
||||
<Button className="mt-5 w-3/4 h-12 dark:text-white">
|
||||
<Link href={`/invest/${params.id}`}>Invest in {projectData?.project_name}</Link>
|
||||
</Button>
|
||||
<div className="flex flex-col space-y-2 py-4 mt-5 w-3/4 h-12 border-2 border-border rounded-md">
|
||||
<p className="text-md font-bold">Dataroom</p>
|
||||
<Button className=" dark:text-white">
|
||||
<Link href={`/invest/${params.id}`}>Access Dataroom</Link>
|
||||
</Button>
|
||||
<Button className=" dark:text-white">
|
||||
<Link href={`/invest/${params.id}`}>Manage Dataroom</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
{/* menu */}
|
||||
<div id="deck">
|
||||
@ -215,7 +181,6 @@ export default async function ProjectDealPage({ params }: { params: { id: number
|
||||
<Tabs.Root defaultValue="pitch" className="w-full">
|
||||
<Tabs.List className="list-none flex gap-10 text-lg md:text-xl">
|
||||
<Tabs.Trigger value="pitch">Pitch</Tabs.Trigger>
|
||||
{/* <Tabs.Trigger value="general">General Data</Tabs.Trigger> */}
|
||||
<Tabs.Trigger value="update">Updates</Tabs.Trigger>
|
||||
</Tabs.List>
|
||||
<Separator className="mb-4 mt-2 w-full border-1" />
|
||||
@ -235,17 +200,6 @@ export default async function ProjectDealPage({ params }: { params: { id: number
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Tabs.Content>
|
||||
{/* <Tabs.Content value="general">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>general</CardTitle>
|
||||
<CardDescription>general Description</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p>general Content</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Tabs.Content> */}
|
||||
<Tabs.Content value="update">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
|
||||
31
src/app/(legal)/about/infoCard.tsx
Normal file
31
src/app/(legal)/about/infoCard.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
|
||||
type CardProps = {
|
||||
imageSrc: string;
|
||||
imageAlt: string;
|
||||
heading: string;
|
||||
content: string[];
|
||||
link: string;
|
||||
buttonText: string;
|
||||
};
|
||||
|
||||
const InfoCard = ({ imageSrc, imageAlt, heading, content, link, buttonText }: CardProps) => {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<Image alt={imageAlt} width={460} height={460} className="w-36" src={imageSrc} />
|
||||
<h1 className="text-2xl font-bold mt-3">{heading}</h1>
|
||||
{content.map((text, index) => (
|
||||
<p key={index} className={index === 0 ? "mt-3" : ""}>
|
||||
{text}
|
||||
</p>
|
||||
))}
|
||||
<Link href={link}>
|
||||
<Button className="p-6 font-semibold text-base mt-5">{buttonText}</Button>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default InfoCard;
|
||||
@ -1,5 +1,6 @@
|
||||
import Image from "next/image";
|
||||
"use client";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import InfoCard from "./infoCard";
|
||||
|
||||
export default function About() {
|
||||
// Static data for the cards
|
||||
@ -38,11 +39,69 @@ export default function About() {
|
||||
},
|
||||
];
|
||||
|
||||
const imageData = {
|
||||
img1: "https://assets.republic.com/assets/static_pages/about/growth_opportunities/individual_investors-0e85dfd02359a24ac4b232be008c7168fc57d3437a2f526f5d5889b874b20221.png",
|
||||
img2: "https://assets.republic.com/assets/static_pages/about/growth_opportunities/accredited_investors-42d6aa046861adb7f0648f26ca3f798b07f3b13bf7024f7dc17c17acb78fdf2c.png",
|
||||
img3: "https://assets.republic.com/assets/static_pages/about/growth_opportunities/entrepreneurs-a0ff450c2f3ba0cea82e2c55cd9265ad5612455c79ec831adaa2c94d09a0e617.png",
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container max-w-screen-xl p-10">
|
||||
<h1 className="mt-3 font-bold text-lg md:text-3xl">About us</h1>
|
||||
<Separator className="my-3" />
|
||||
<div className="border border-border rounded-md">
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<h1 className="mt-3 font-bold text-lg md:text-5xl font-black">Growth opportunities for all sides </h1>
|
||||
<h1 className="mt-3 font-bold text-lg md:text-5xl font-black">of the investment market</h1>
|
||||
<h1 className="text-gray-500 text-2xl mt-1">
|
||||
B2DVentures is where both accredited and non-accredited investors meet
|
||||
</h1>
|
||||
<h1 className="text-gray-500 text-2xl">entrepreneurs and access high-growth potential deals across a range</h1>
|
||||
<h1 className="text-gray-500 text-2xl">of private markets.</h1>
|
||||
</div>
|
||||
<div className="mt-10">
|
||||
<div className="grid grid-cols-1 md:grid-cols-[1fr,auto,1fr] gap-3">
|
||||
<InfoCard
|
||||
imageSrc={imageData.img1}
|
||||
imageAlt="Image1"
|
||||
heading="Individual investors"
|
||||
content={[
|
||||
"B2DVentures's success has been built off our hundreds",
|
||||
"of sourced private deals, all available for",
|
||||
"investment from you with as little as $10 or as ",
|
||||
"much as $124,000.",
|
||||
]}
|
||||
link="/deals"
|
||||
buttonText="Explore opportunities"
|
||||
/>
|
||||
<Separator orientation="vertical" />
|
||||
<InfoCard
|
||||
imageSrc={imageData.img2}
|
||||
imageAlt="Image2"
|
||||
heading="Accredited investors"
|
||||
content={[
|
||||
"The benefits of the Republic platform, optimized for",
|
||||
"accredited investors. Access a curated investor",
|
||||
"portal for unique private investment opportunities. ",
|
||||
]}
|
||||
link="/dataroom/overview"
|
||||
buttonText="Learn more"
|
||||
/>
|
||||
</div>
|
||||
<Separator className="mt-5 mb-5" />
|
||||
<InfoCard
|
||||
imageSrc={imageData.img3}
|
||||
imageAlt="Image3"
|
||||
heading="Entrepreneurs"
|
||||
content={[
|
||||
"Seek funding from a wider base of diverse",
|
||||
"investors while simultaneously growing a loyal",
|
||||
"base and leveraging Republic’s private investment",
|
||||
"network.",
|
||||
]}
|
||||
link="/project/apply"
|
||||
buttonText="Raise money"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* <div className="border border-border rounded-md">
|
||||
<p className="p-5">
|
||||
Welcome to B2D Ventures! We're a dynamic platform committed to bridging the gap between visionary
|
||||
entrepreneurs and passionate investors. Our mission is to empower innovation by connecting groundbreaking
|
||||
@ -56,15 +115,15 @@ export default function About() {
|
||||
lasting impact.
|
||||
</p>
|
||||
<p className="p-5">Let's build the future, together.</p>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
<div className="mt-10 text-center">
|
||||
{/* <div className="mt-10 text-center">
|
||||
<h2 className="font-bold text-lg md:text-3xl">Our Team</h2>
|
||||
<Separator className="my-3" />
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
{/* Card Section */}
|
||||
<div className="mt-10 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
{/* <div className="mt-10 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
{cardData.map((card, index) => (
|
||||
<div key={index} className="bg-white rounded-lg shadow-lg overflow-hidden">
|
||||
<Image src={card.imageSrc} width={460} height={460} alt={card.name} className="w-full h-48 object-cover" />
|
||||
@ -74,7 +133,7 @@ export default function About() {
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ export default function ProjectCardCalendarManageSection({ projectData }: Projec
|
||||
const [currentProjectId, setCurrentProjectId] = useState<number | undefined>(undefined);
|
||||
|
||||
return (
|
||||
<div id="content" className="grid grid-cols-2 space-x-2">
|
||||
<div id="content" className="grid grid-cols-1 md:grid-cols-2 space-x-2">
|
||||
{projectData != null ? (
|
||||
projectData.map((project) => (
|
||||
<Card key={project.id} className="mb-3">
|
||||
|
||||
@ -208,7 +208,7 @@ export function DataTable({ data }: { data: ModalProps[] }) {
|
||||
placeholder="Filter names..."
|
||||
value={(table.getColumn("name")?.getFilterValue() as string) ?? ""}
|
||||
onChange={(event) => table.getColumn("name")?.setFilterValue(event.target.value)}
|
||||
className="max-w-sm"
|
||||
className="md:max-w-sm max-w-xs"
|
||||
/>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
|
||||
28
src/components/listItem.tsx
Normal file
28
src/components/listItem.tsx
Normal file
@ -0,0 +1,28 @@
|
||||
import { NavigationMenuLink } from "@/components/ui/navigation-menu";
|
||||
import { cn } from "@/lib/utils";
|
||||
import React from "react";
|
||||
const ListItem = React.forwardRef<React.ElementRef<"a">, React.ComponentPropsWithoutRef<"a">>(
|
||||
({ className, title, children, ...props }, ref) => {
|
||||
return (
|
||||
<li>
|
||||
<NavigationMenuLink asChild>
|
||||
<a
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<div className="text-sm font-medium leading-none">{title}</div>
|
||||
<hr />
|
||||
<p className="line-clamp-2 text-sm leading-snug text-muted-foreground">{children}</p>
|
||||
</a>
|
||||
</NavigationMenuLink>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
);
|
||||
ListItem.displayName = "ListItem";
|
||||
|
||||
export default ListItem;
|
||||
@ -1,27 +0,0 @@
|
||||
"use client";
|
||||
import { useState } from "react";
|
||||
import { Menu, X } from "lucide-react";
|
||||
import { Button } from "./ui/button";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
export function MobileMenu() {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
return (
|
||||
<div>
|
||||
<Button onClick={() => setIsVisible((prev) => !prev)}>
|
||||
<Menu />
|
||||
</Button>
|
||||
{isVisible && (
|
||||
<motion.div
|
||||
initial={{ x: "-100%" }}
|
||||
animate={{ x: 0 }}
|
||||
exit={{ x: "-100%" }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="fixed top-0 left-0 w-full bg-gray-800 text-white"
|
||||
>
|
||||
<X className="cursor-pointer" onClick={() => setIsVisible(false)} />
|
||||
</motion.div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
23
src/components/navigationBar/menu.ts
Normal file
23
src/components/navigationBar/menu.ts
Normal file
@ -0,0 +1,23 @@
|
||||
export const businessComponents = [
|
||||
{
|
||||
title: "Business",
|
||||
href: "/business/apply",
|
||||
description: "Apply to raise on on B2DVentures",
|
||||
},
|
||||
];
|
||||
|
||||
export const projectComponents = [
|
||||
{
|
||||
title: "Projects",
|
||||
href: "/project/apply",
|
||||
description: "Start your new project on B2DVentures",
|
||||
},
|
||||
];
|
||||
|
||||
export const dataroomComponents = [
|
||||
{
|
||||
title: "Overview",
|
||||
href: "/dataroom/overview",
|
||||
description: "View all dataroom available to you",
|
||||
},
|
||||
];
|
||||
103
src/components/navigationBar/mobileMenu.tsx
Normal file
103
src/components/navigationBar/mobileMenu.tsx
Normal file
@ -0,0 +1,103 @@
|
||||
"use client";
|
||||
import { useState } from "react";
|
||||
import { Menu, X } from "lucide-react";
|
||||
import { Button } from "../ui/button";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import {
|
||||
NavigationMenu,
|
||||
NavigationMenuContent,
|
||||
NavigationMenuItem,
|
||||
NavigationMenuLink,
|
||||
NavigationMenuList,
|
||||
NavigationMenuTrigger,
|
||||
} from "@/components/ui/navigation-menu";
|
||||
import React from "react";
|
||||
import { SearchBar } from "./serchBar";
|
||||
import ListItem from "../listItem";
|
||||
import { businessComponents, projectComponents, dataroomComponents } from "./menu";
|
||||
import { ThemeToggle } from "../theme-toggle";
|
||||
|
||||
export function MobileMenu() {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
return (
|
||||
<div>
|
||||
<Button onClick={() => setIsVisible((prev) => !prev)}>
|
||||
<Menu />
|
||||
</Button>
|
||||
<AnimatePresence>
|
||||
{isVisible && (
|
||||
<motion.div
|
||||
initial={{ y: -100 }}
|
||||
animate={{ y: 0 }}
|
||||
exit={{ y: -100 }}
|
||||
transition={{ type: "spring", stiffness: 300, damping: 30 }}
|
||||
className="fixed top-0 left-0 w-full bg-white dark:bg-slate-900 border-b dark:border-slate-800 shadow-sm z-50"
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex items-center justify-between h-16">
|
||||
<div className="flex items-center">
|
||||
<button
|
||||
onClick={() => setIsVisible(false)}
|
||||
className="p-2 rounded-md hover:bg-slate-100 dark:hover:bg-slate-800"
|
||||
>
|
||||
<X className="w-5 h-5" />
|
||||
</button>
|
||||
|
||||
<NavigationMenu>
|
||||
<NavigationMenuList className="flex space-x-2">
|
||||
<NavigationMenuItem>
|
||||
<NavigationMenuTrigger className="text-sm font-medium">Businesses</NavigationMenuTrigger>
|
||||
<NavigationMenuContent>
|
||||
<ul className="w-[240px] p-4 gap-3">
|
||||
{businessComponents.map((component) => (
|
||||
<ListItem key={component.title} title={component.title} href={component.href}>
|
||||
{component.description}
|
||||
</ListItem>
|
||||
))}
|
||||
</ul>
|
||||
</NavigationMenuContent>
|
||||
</NavigationMenuItem>
|
||||
|
||||
<NavigationMenuItem>
|
||||
<NavigationMenuTrigger className="text-sm font-medium">Projects</NavigationMenuTrigger>
|
||||
<NavigationMenuContent>
|
||||
<ul className="w-[240px] p-4 gap-3">
|
||||
{projectComponents.map((component) => (
|
||||
<ListItem key={component.title} title={component.title} href={component.href}>
|
||||
{component.description}
|
||||
</ListItem>
|
||||
))}
|
||||
</ul>
|
||||
</NavigationMenuContent>
|
||||
</NavigationMenuItem>
|
||||
|
||||
<NavigationMenuItem>
|
||||
<NavigationMenuTrigger className="text-sm font-medium">Dataroom</NavigationMenuTrigger>
|
||||
<NavigationMenuContent>
|
||||
<ul className="w-[240px] p-4 gap-3">
|
||||
{dataroomComponents.map((component) => (
|
||||
<ListItem key={component.title} title={component.title} href={component.href}>
|
||||
{component.description}
|
||||
</ListItem>
|
||||
))}
|
||||
</ul>
|
||||
</NavigationMenuContent>
|
||||
</NavigationMenuItem>
|
||||
</NavigationMenuList>
|
||||
</NavigationMenu>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center ml-2">
|
||||
<SearchBar />
|
||||
<div className="-ml-2">
|
||||
<ThemeToggle />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -2,7 +2,6 @@ import * as React from "react";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { ThemeToggle } from "@/components/theme-toggle";
|
||||
import {
|
||||
@ -21,31 +20,9 @@ import { createSupabaseClient } from "@/lib/supabase/serverComponentClient";
|
||||
import { getUserId } from "@/lib/supabase/actions/getUserId";
|
||||
import { getUnreadNotificationCountByUserId } from "@/lib/data/notificationQuery";
|
||||
|
||||
import { MobileMenu } from "../mobileMenu";
|
||||
|
||||
const ListItem = React.forwardRef<React.ElementRef<"a">, React.ComponentPropsWithoutRef<"a">>(
|
||||
({ className, title, children, ...props }, ref) => {
|
||||
return (
|
||||
<li>
|
||||
<NavigationMenuLink asChild>
|
||||
<a
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<div className="text-sm font-medium leading-none">{title}</div>
|
||||
<hr />
|
||||
<p className="line-clamp-2 text-sm leading-snug text-muted-foreground">{children}</p>
|
||||
</a>
|
||||
</NavigationMenuLink>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
);
|
||||
ListItem.displayName = "ListItem";
|
||||
import { MobileMenu } from "./mobileMenu";
|
||||
import ListItem from "../listItem";
|
||||
import { businessComponents, projectComponents, dataroomComponents } from "./menu";
|
||||
|
||||
export async function NavigationBar() {
|
||||
const client = createSupabaseClient();
|
||||
@ -59,30 +36,6 @@ export async function NavigationBar() {
|
||||
notification_count = 0;
|
||||
}
|
||||
|
||||
const businessComponents = [
|
||||
{
|
||||
title: "Business",
|
||||
href: "/business/apply",
|
||||
description: "Apply to raise on on B2DVentures",
|
||||
},
|
||||
];
|
||||
|
||||
const projectComponents = [
|
||||
{
|
||||
title: "Projects",
|
||||
href: "/project/apply",
|
||||
description: "Start your new project on B2DVentures",
|
||||
},
|
||||
];
|
||||
|
||||
const dataroomComponents = [
|
||||
{
|
||||
title: "Overview",
|
||||
href: "/dataroom/overview",
|
||||
description: "View all dataroom available to you",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<header className="sticky top-0 flex flex-wrap w-full bg-card text-sm py-3 border-b-2 border-border z-50">
|
||||
<nav className="max-w-screen-xl w-full mx-auto px-4">
|
||||
@ -93,15 +46,31 @@ export async function NavigationBar() {
|
||||
href="/"
|
||||
aria-label="Brand"
|
||||
>
|
||||
<span className="inline-flex items-center gap-x-2 text-xl font-semibold dark:text-white">
|
||||
<Image src="/logo.svg" alt="logo" width={50} height={50} />
|
||||
B2DVentures
|
||||
<span className="lg:inline-flex flex items-center gap-x-2 text-xl font-semibold dark:text-white">
|
||||
<Image src="/logo.svg" alt="logo" width={50} height={50} className="w-10 h-10 sm:w-16 sm:h-16" />
|
||||
<span className="block lg:inline">
|
||||
B2D<span className=" lg:inline">Ventures</span>
|
||||
</span>
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="md:hidden">
|
||||
<div className="md:hidden grid grid-cols-2 justify-items-center items-center">
|
||||
<div className="flex justify-end w-10">
|
||||
{userId ? (
|
||||
<AuthenticatedComponents
|
||||
uid={userId}
|
||||
avatarUrl={avatarUrl?.avatar_url}
|
||||
notificationCount={notification_count}
|
||||
/>
|
||||
) : (
|
||||
<UnAuthenticatedComponents />
|
||||
)}
|
||||
</div>
|
||||
<div className="justify-end flex">
|
||||
<MobileMenu />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="hidden md:flex items-center ">
|
||||
<NavigationMenu>
|
||||
<NavigationMenuList>
|
||||
|
||||
@ -2,34 +2,100 @@
|
||||
|
||||
import * as React from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Search } from "lucide-react";
|
||||
import { Search, X } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
export function SearchBar() {
|
||||
const [searchActive, setSearchActive] = React.useState(false);
|
||||
const [query, setQuery] = React.useState("");
|
||||
const router = useRouter();
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const handleKeyDown = async (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (e.key === "Enter") {
|
||||
const query = (e.target as HTMLInputElement).value.trim();
|
||||
if (query) {
|
||||
router.push(`/find?query=${encodeURIComponent(query)}`);
|
||||
const trimmedQuery = query.trim();
|
||||
if (trimmedQuery) {
|
||||
router.push(`/find?query=${encodeURIComponent(trimmedQuery)}`);
|
||||
setSearchActive(false);
|
||||
setQuery("");
|
||||
}
|
||||
} else if (e.key === "Escape") {
|
||||
setSearchActive(false);
|
||||
setQuery("");
|
||||
}
|
||||
};
|
||||
|
||||
// Handle clicks outside of search bar
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
|
||||
setSearchActive(false);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("mousedown", handleClickOutside);
|
||||
return () => document.removeEventListener("mousedown", handleClickOutside);
|
||||
}, []);
|
||||
|
||||
// Focus input when search becomes active
|
||||
useEffect(() => {
|
||||
if (searchActive && inputRef.current) {
|
||||
inputRef.current.focus();
|
||||
}
|
||||
}, [searchActive]);
|
||||
|
||||
return (
|
||||
<div className="flex items-center">
|
||||
<Search onClick={() => setSearchActive(!searchActive)} className="cursor-pointer" />
|
||||
<div
|
||||
ref={containerRef}
|
||||
className={cn(
|
||||
"relative flex items-center transition-all duration-300",
|
||||
searchActive &&
|
||||
"fixed inset-0 bg-white/95 dark:bg-slate-900/95 z-50 px-4 md:relative md:bg-transparent md:dark:bg-transparent md:px-0"
|
||||
)}
|
||||
>
|
||||
{/* Mobile overlay header when search is active */}
|
||||
{searchActive && (
|
||||
<div className="absolute top-0 left-0 right-0 flex items-center p-4 md:hidden">
|
||||
<X
|
||||
className="w-6 h-6 cursor-pointer text-slate-600 dark:text-slate-400"
|
||||
onClick={() => {
|
||||
setSearchActive(false);
|
||||
setQuery("");
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className={cn("flex items-center w-full md:w-auto", searchActive ? "mt-16 md:mt-0" : "")}>
|
||||
<Search
|
||||
onClick={() => setSearchActive(!searchActive)}
|
||||
className={cn(
|
||||
"w-5 h-5 cursor-pointer transition-colors",
|
||||
searchActive ? "text-blue-500" : "text-slate-600 dark:text-slate-400",
|
||||
"md:hover:text-blue-500"
|
||||
)}
|
||||
/>
|
||||
|
||||
<input
|
||||
ref={inputRef}
|
||||
type="text"
|
||||
value={query}
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
placeholder="Enter business name..."
|
||||
className={cn(
|
||||
"ml-2 border rounded-md px-2 py-1 transition-all duration-300 ease-in-out",
|
||||
searchActive ? "w-48 opacity-100" : "w-0 opacity-0"
|
||||
"ml-2 rounded-md transition-all duration-300 ease-in-out outline-none",
|
||||
"placeholder:text-slate-400 dark:placeholder:text-slate-500",
|
||||
"bg-transparent md:bg-slate-100 md:dark:bg-slate-800",
|
||||
"md:px-3 md:py-1.5",
|
||||
searchActive
|
||||
? "w-full opacity-100 border-b md:border md:w-48 lg:w-64 md:border-slate-200 md:dark:border-slate-700"
|
||||
: "w-0 opacity-0 border-transparent"
|
||||
)}
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ export function SiteFooter() {
|
||||
Home
|
||||
</Link>
|
||||
<Link href="/about" className="hover:underline">
|
||||
About Us
|
||||
About
|
||||
</Link>
|
||||
<Link href="/privacy" className="hover:underline">
|
||||
Privacy
|
||||
|
||||
Loading…
Reference in New Issue
Block a user