diff --git a/next.config.mjs b/next.config.mjs index ff1f0fe..6a3a214 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -26,8 +26,12 @@ const nextConfig = { hostname: "avatars.githubusercontent.com", pathname: "/**", }, + { + protocol: "https", + hostname: "assets.republic.com", + pathname: "/**", + }, ], }, }; - export default nextConfig; diff --git a/src/app/(investment)/deals/[id]/page.tsx b/src/app/(investment)/deals/[id]/page.tsx index 8cb6b8b..2322aef 100644 --- a/src/app/(investment)/deals/[id]/page.tsx +++ b/src/app/(investment)/deals/[id]/page.tsx @@ -98,7 +98,7 @@ export default async function ProjectDealPage({ params }: { params: { id: number ))} -
+
{/* image carousel */} -
- -
- - {/*
-
- -

${totalDealAmount}

-

- {toPercentage(totalDealAmount, projectData?.target_investment)}% raised of $ - {projectData?.target_investment} max goal -

- -
- -

-

{dealList.length}

-

-

Investors

-
- - -

- {projectData?.investment_deadline ? ( - <> -

{Math.floor(hourLeft)} hours

-

Left to invest

- - ) : ( -

No deadline

- )} -
- -
-

Dataroom

- - -
-
-
*/}
{/* menu */}
@@ -215,7 +181,6 @@ export default async function ProjectDealPage({ params }: { params: { id: number Pitch - {/* General Data */} Updates @@ -235,17 +200,6 @@ export default async function ProjectDealPage({ params }: { params: { id: number - {/* - - - general - general Description - - -

general Content

-
-
-
*/} diff --git a/src/app/(legal)/about/infoCard.tsx b/src/app/(legal)/about/infoCard.tsx new file mode 100644 index 0000000..32042ba --- /dev/null +++ b/src/app/(legal)/about/infoCard.tsx @@ -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 ( +
+ {imageAlt} +

{heading}

+ {content.map((text, index) => ( +

+ {text} +

+ ))} + + + +
+ ); +}; + +export default InfoCard; diff --git a/src/app/(legal)/about/page.tsx b/src/app/(legal)/about/page.tsx index 502b0cc..f17f09e 100644 --- a/src/app/(legal)/about/page.tsx +++ b/src/app/(legal)/about/page.tsx @@ -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 (
-

About us

- -
+
+

Growth opportunities for all sides

+

of the investment market

+

+ B2DVentures is where both accredited and non-accredited investors meet +

+

entrepreneurs and access high-growth potential deals across a range

+

of private markets.

+
+
+
+ + + +
+ + +
+ + {/*

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.

Let's build the future, together.

-
+
*/} -
+ {/*

Our Team

-
+
*/} {/* Card Section */} -
+ {/*
{cardData.map((card, index) => (
{card.name} @@ -74,7 +133,7 @@ export default function About() {
))} -
+
*/}
); } diff --git a/src/app/calendar/manage/ProjectCardSection.tsx b/src/app/calendar/manage/ProjectCardSection.tsx index 38b7f7f..09cdf01 100644 --- a/src/app/calendar/manage/ProjectCardSection.tsx +++ b/src/app/calendar/manage/ProjectCardSection.tsx @@ -27,7 +27,7 @@ export default function ProjectCardCalendarManageSection({ projectData }: Projec const [currentProjectId, setCurrentProjectId] = useState(undefined); return ( -
+
{projectData != null ? ( projectData.map((project) => ( diff --git a/src/components/dataTable.tsx b/src/components/dataTable.tsx index 4dd3b99..0d459ae 100644 --- a/src/components/dataTable.tsx +++ b/src/components/dataTable.tsx @@ -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" /> diff --git a/src/components/listItem.tsx b/src/components/listItem.tsx new file mode 100644 index 0000000..ca85cd5 --- /dev/null +++ b/src/components/listItem.tsx @@ -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.ComponentPropsWithoutRef<"a">>( + ({ className, title, children, ...props }, ref) => { + return ( +
  • + + +
    {title}
    +
    +

    {children}

    +
    +
    +
  • + ); + } +); +ListItem.displayName = "ListItem"; + +export default ListItem; diff --git a/src/components/mobileMenu.tsx b/src/components/mobileMenu.tsx deleted file mode 100644 index 9c513a8..0000000 --- a/src/components/mobileMenu.tsx +++ /dev/null @@ -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 ( -
    - - {isVisible && ( - - setIsVisible(false)} /> - - )} -
    - ); -} diff --git a/src/components/navigationBar/menu.ts b/src/components/navigationBar/menu.ts new file mode 100644 index 0000000..d7ad987 --- /dev/null +++ b/src/components/navigationBar/menu.ts @@ -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", + }, +]; diff --git a/src/components/navigationBar/mobileMenu.tsx b/src/components/navigationBar/mobileMenu.tsx new file mode 100644 index 0000000..537000a --- /dev/null +++ b/src/components/navigationBar/mobileMenu.tsx @@ -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 ( +
    + + + {isVisible && ( + +
    +
    +
    + + + + + + Businesses + +
      + {businessComponents.map((component) => ( + + {component.description} + + ))} +
    +
    +
    + + + Projects + +
      + {projectComponents.map((component) => ( + + {component.description} + + ))} +
    +
    +
    + + + Dataroom + +
      + {dataroomComponents.map((component) => ( + + {component.description} + + ))} +
    +
    +
    +
    +
    +
    + +
    + +
    + +
    +
    +
    +
    +
    + )} +
    +
    + ); +} diff --git a/src/components/navigationBar/nav.tsx b/src/components/navigationBar/nav.tsx index e4f0233..da49f4f 100644 --- a/src/components/navigationBar/nav.tsx +++ b/src/components/navigationBar/nav.tsx @@ -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.ComponentPropsWithoutRef<"a">>( - ({ className, title, children, ...props }, ref) => { - return ( -
  • - - -
    {title}
    -
    -

    {children}

    -
    -
    -
  • - ); - } -); -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 (
    -
    - +
    +
    + {userId ? ( + + ) : ( + + )} +
    +
    + +
    +
    diff --git a/src/components/navigationBar/serchBar.tsx b/src/components/navigationBar/serchBar.tsx index 026e52b..00dd390 100644 --- a/src/components/navigationBar/serchBar.tsx +++ b/src/components/navigationBar/serchBar.tsx @@ -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(null); + const containerRef = useRef(null); const handleKeyDown = async (e: React.KeyboardEvent) => { 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 ( -
    - setSearchActive(!searchActive)} className="cursor-pointer" /> - +
    + {/* Mobile overlay header when search is active */} + {searchActive && ( +
    + { + setSearchActive(false); + setQuery(""); + }} + /> +
    + )} + +
    + 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" + )} + /> + + setQuery(e.target.value)} + placeholder="Enter business name..." + className={cn( + "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} + /> +
    ); } diff --git a/src/components/siteFooter.tsx b/src/components/siteFooter.tsx index f7bf49c..c93cd3c 100644 --- a/src/components/siteFooter.tsx +++ b/src/components/siteFooter.tsx @@ -16,7 +16,7 @@ export function SiteFooter() { Home - About Us + About Privacy