Merge pull request #41 from Sosokker/front-end

style: improve responsiveness of business card and pages
This commit is contained in:
Sirin Puenggun 2024-10-05 14:35:45 +07:00 committed by GitHub
commit f5a979d7da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 701 additions and 589 deletions

View File

@ -18,6 +18,7 @@ export default function Deals() {
joinDate: "December 2021", joinDate: "December 2021",
location: "Bangkok, Thailand", location: "Bangkok, Thailand",
tags: ["AI", "Technology"], tags: ["AI", "Technology"],
imageUri: "/login.png",
minInvestment: 10000, minInvestment: 10000,
totalInvestor: 58400, totalInvestor: 58400,
totalRaised: 9000000, totalRaised: 9000000,
@ -29,6 +30,7 @@ export default function Deals() {
joinDate: "February 2020", joinDate: "February 2020",
location: "Cupertino, California, USA", location: "Cupertino, California, USA",
tags: ["Consumer Electronics", "Software"], tags: ["Consumer Electronics", "Software"],
imageUri: "/money.png",
minInvestment: 10000, minInvestment: 10000,
totalInvestor: 58400, totalInvestor: 58400,
totalRaised: 9000000, totalRaised: 9000000,
@ -40,6 +42,7 @@ export default function Deals() {
joinDate: "April 2019", joinDate: "April 2019",
location: "Mountain View, California, USA", location: "Mountain View, California, USA",
tags: ["Internet", "Search Engine"], tags: ["Internet", "Search Engine"],
imageUri: "/money.png",
minInvestment: 10000, minInvestment: 10000,
totalInvestor: 5000, totalInvestor: 5000,
totalRaised: 1500000000, totalRaised: 1500000000,
@ -50,6 +53,7 @@ export default function Deals() {
joinDate: "January 2018", joinDate: "January 2018",
location: "California, USA", location: "California, USA",
tags: ["Technology", "Software"], tags: ["Technology", "Software"],
imageUri: null,
minInvestment: 250, minInvestment: 250,
totalInvestor: 5000, totalInvestor: 5000,
totalRaised: 1500000, totalRaised: 1500000,
@ -59,18 +63,19 @@ export default function Deals() {
const filteredData = selectedTag ? data.filter((item) => item.tags.includes(selectedTag)) : data; const filteredData = selectedTag ? data.filter((item) => item.tags.includes(selectedTag)) : data;
return ( return (
<div> <div className="container max-w-screen-xl mx-auto px-4">
<div className=" w-1/2 h-[250px] mt-10 ml-[15%]"> <div className="h-auto mt-10">
<h1 className="text-4xl font-bold">Investment Opportunities</h1> <h1 className="text-4xl font-bold">Investment Opportunities</h1>
<br /> <br />
<p>Browse current investment opportunities on B2DVenture.</p> <p>Browse current investment opportunities on B2DVenture.</p>
<p> <p>
All companies are <u>vetted & pass due diligence.</u> All companies are <u>vetted & pass due diligence.</u>
</p> </p>
{/* filters */}
<div className="flex mt-10 gap-3"> {/* Filters */}
<div className="flex flex-wrap mt-10 gap-3">
<Select onValueChange={(value) => setPostAtFilter(value)}> <Select onValueChange={(value) => setPostAtFilter(value)}>
<SelectTrigger className="w-[180px]"> <SelectTrigger className="w-full sm:w-[180px]">
<Clock3Icon className="ml-2" /> <Clock3Icon className="ml-2" />
<SelectValue placeholder="Posted at" /> <SelectValue placeholder="Posted at" />
</SelectTrigger> </SelectTrigger>
@ -79,15 +84,14 @@ export default function Deals() {
<SelectItem value="Yesterday">Yesterday</SelectItem> <SelectItem value="Yesterday">Yesterday</SelectItem>
</SelectContent> </SelectContent>
</Select> </Select>
<Select onValueChange={(value) => setSelectedTag(value)}> <Select onValueChange={(value) => setSelectedTag(value)}>
{" "} <SelectTrigger className="w-full sm:w-[180px]">
{/* Tag filtering */}
<SelectTrigger className="w-[180px]">
<MessageSquareIcon className="ml-2" /> <MessageSquareIcon className="ml-2" />
<SelectValue placeholder="Tags" /> <SelectValue placeholder="Tags" />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectItem value="_">All Tags</SelectItem> {/* Reset filter */} <SelectItem value="_">All Tags</SelectItem>
<SelectItem value="AI">AI</SelectItem> <SelectItem value="AI">AI</SelectItem>
<SelectItem value="Technology">Technology</SelectItem> <SelectItem value="Technology">Technology</SelectItem>
<SelectItem value="Consumer Electronics">Consumer Electronics</SelectItem> <SelectItem value="Consumer Electronics">Consumer Electronics</SelectItem>
@ -99,18 +103,20 @@ export default function Deals() {
<Separator className="mt-10" /> <Separator className="mt-10" />
</div> </div>
<div className="ml-[15%]"> <div className="mt-10">
<h2 className="text-2xl">Deals</h2> <h2 className="text-2xl">Deals</h2>
<p className="mt-3">The deals attracting the most interest right now</p> <p className="mt-3">The deals attracting the most interest right now</p>
</div> </div>
{/* block for all the deals */}
<div className="ml-[15%] mt-10 grid grid-cols-3"> {/* Block for all the deals */}
<div className="mt-10 grid grid-cols-3 gap-4">
{filteredData.map((item, index) => ( {filteredData.map((item, index) => (
<ExtendableCard <ExtendableCard
key={index} key={index}
name={item.name} name={item.name}
description={item.description} description={item.description}
joinDate={item.joinDate} joinDate={item.joinDate}
imageUri={item.imageUri}
location={item.location} location={item.location}
minInvestment={item.minInvestment} minInvestment={item.minInvestment}
totalInvestor={item.totalInvestor} totalInvestor={item.totalInvestor}

View File

@ -1,144 +0,0 @@
"use client";
import { Separator } from "@/components/ui/separator";
import { Input } from "@/components/ui/input";
import { CardsPaymentMethod } from "@/components/paymentMethod";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Button } from "@/components/ui/button";
import { useState } from "react";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
DialogFooter,
DialogClose,
} from "@/components/ui/dialog";
import { useRouter } from "next/navigation";
import { toast } from "react-hot-toast";
const term_data = [
{
term: "Minimum Investment",
description: "The minimum investment amount is $500.",
},
{
term: "Investment Horizon",
description: "Investments are typically locked for a minimum of 12 months.",
},
{
term: "Fees",
description: "A management fee of 2% will be applied annually.",
},
{
term: "Returns",
description: "Expected annual returns are between 8% and 12%.",
},
{
term: "Risk Disclosure",
description: "Investments carry risks, including the loss of principal.",
},
{
term: "Withdrawal Policy",
description: "Withdrawals can be made after the lock-in period.",
},
];
export default function Invest() {
const [checkedTerms, setCheckedTerms] = useState(Array(term_data.length).fill(false));
const [error, setError] = useState("");
const router = useRouter(); // Initialize the router
const handleCheckboxChange = (index) => {
const updatedCheckedTerms = [...checkedTerms];
updatedCheckedTerms[index] = !updatedCheckedTerms[index];
setCheckedTerms(updatedCheckedTerms);
};
const handleTermServiceClick = () => {
if (checkedTerms.some((checked) => !checked)) {
setError("Please accept all terms before proceeding with the investment.");
} else {
setError("");
handleInvestmentSuccess();
}
};
const handleInvestmentSuccess = () => {
toast.success("You successfully invested!");
setTimeout(() => {
router.push("/");
}, 1000);
};
return (
<div className="mx-40 my-10">
<h1 className="text-4xl font-bold">Invest on NVIDIA</h1>
<Separator className="my-4" />
<div>
<div className="w-1/2 space-y-2">
<h2 className="text-2xl">Investment Amount</h2>
<Input type="number" placeholder="min $500" />
</div>
<Separator className="my-4" />
<div className="w-1/2 space-y-2">
<h2 className="text-2xl">Payment Information</h2>
<CardsPaymentMethod />
</div>
<Separator className="my-4" />
<div className="w-2/3 space-y-2">
<h2 className="text-2xl">Terms and Services</h2>
<Table>
<TableHeader>
<TableRow>
<TableHead>Select</TableHead>
<TableHead>Term</TableHead>
<TableHead>Description</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{term_data.map((item, index) => (
<TableRow key={index}>
<TableCell>
<input type="checkbox" checked={checkedTerms[index]} onChange={() => handleCheckboxChange(index)} />
</TableCell>
<TableCell>{item.term}</TableCell>
<TableCell>{item.description}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
<Dialog>
<DialogTrigger asChild>
<Button className="mt-4">Invest</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you absolutely sure?</DialogTitle>
<DialogDescription>This action cannot be undone. This will permanently!</DialogDescription>
</DialogHeader>
<DialogFooter className="sm:justify-start">
<Button type="submit" onClick={handleTermServiceClick}>
Confirm
</Button>
<DialogClose asChild>
<Button type="button" variant="secondary">
Close
</Button>
</DialogClose>
</DialogFooter>
{error && <p className="text-red-500 mt-2 text-lg font-bold">{error}</p>}
</DialogContent>
</Dialog>
</div>
</div>
);
}

View File

@ -1,190 +1,167 @@
"use client"; "use client";
import React, { useState, useEffect } from "react";
import Image from "next/image";
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel";
import { Card, CardContent } from "@/components/ui/card";
import CountUp from "react-countup";
import { Progress } from "@/components/ui/progress";
import { Separator } from "@/components/ui/separator"; import { Separator } from "@/components/ui/separator";
import { Input } from "@/components/ui/input";
import { CardsPaymentMethod } from "@/components/paymentMethod";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { ShareIcon, StarIcon } from "lucide-react"; import { useState } from "react";
import { Toaster, toast } from "react-hot-toast"; import {
import useSession from "@/lib/supabase/useSession"; Dialog,
import { redirect } from "next/navigation"; DialogContent,
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; DialogDescription,
import Link from "next/link"; DialogHeader,
DialogTitle,
DialogTrigger,
DialogFooter,
DialogClose,
} from "@/components/ui/dialog";
import { useRouter } from "next/navigation";
import { toast } from "react-hot-toast";
const term_data = [
{
term: "Minimum Investment",
description: "The minimum investment amount is $500.",
},
{
term: "Investment Horizon",
description: "Investments are typically locked for a minimum of 12 months.",
},
{
term: "Fees",
description: "A management fee of 2% will be applied annually.",
},
{
term: "Returns",
description: "Expected annual returns are between 8% and 12%.",
},
{
term: "Risk Disclosure",
description: "Investments carry risks, including the loss of principal.",
},
{
term: "Withdrawal Policy",
description: "Withdrawals can be made after the lock-in period.",
},
];
export default function Invest() { export default function Invest() {
const [progress, setProgress] = useState(0); const [checkedTerms, setCheckedTerms] = useState(
const [tab, setTab] = useState("Pitch"); Array(term_data.length).fill(false)
const { session, loading } = useSession(); );
const user = session?.user; const [error, setError] = useState("");
const [sessionLoaded, setSessionLoaded] = useState(false); const router = useRouter(); // Initialize the router
const [isFollow, setIsFollow] = useState(false);
useEffect(() => { const handleCheckboxChange = (index: number) => {
// set sessionLoaded to true once session is confirmed const updatedCheckedTerms = [...checkedTerms];
if (!loading) { updatedCheckedTerms[index] = !updatedCheckedTerms[index];
setSessionLoaded(true); setCheckedTerms(updatedCheckedTerms);
}
}, [loading]);
const handleClick = (item: string) => {
setTab(item);
}; };
const handleShare = () => { const handleTermServiceClick = () => {
const currentUrl = window.location.href; if (checkedTerms.some((checked) => !checked)) {
if (document.hasFocus()) { setError(
navigator.clipboard.writeText(currentUrl).then(() => { "Please accept all terms before proceeding with the investment."
toast.success("URL copied to clipboard!"); );
});
}
};
const handleFollow = () => {
if (user) {
setIsFollow((prevState) => !prevState);
// save follow to database
} else { } else {
redirect("/login"); setError("");
handleInvestmentSuccess();
} }
}; };
useEffect(() => {
// percent success const handleInvestmentSuccess = () => {
const timer = setTimeout(() => setProgress(66), 500); toast.success("You successfully invested!");
return () => clearTimeout(timer);
}, []); setTimeout(() => {
router.push("/");
}, 1000);
};
return ( return (
<div> <div className="mx-10 md:mx-40 my-10">
<h1 className="text-2xl md:text-4xl font-bold">Invest on NVIDIA</h1>
<Separator className="my-4" />
<div> <div>
<Toaster position="top-right" reverseOrder={false} /> <div className="w-1/2 space-y-2">
</div> <h2 className="text:base md:text-2xl">Investment Amount</h2>
<div className="w-[90%] h-[450px]-500 md:m-auto mt-12 md:mt-12 pl-14 md:pl-24"> <Input
<div> className="w-52"
{/* Name, star and share button packed */} type="number"
<div className="grid grid-cols-4"> placeholder="min $500"
<div className="flex col-span-2"> min={500}
<Image src="./logo.svg" alt="logo" width={50} height={50} className="sm:scale-75" /> />
<div className="mt-3 font-bold text-lg md:text-3xl">NVIDIA</div>
</div>
<div className="grid grid-cols-2 gap-5 justify-self-end ">
<div className="mt-2 cursor-pointer" onClick={handleFollow}>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<StarIcon id="follow" fill={isFollow ? "#FFFF00" : "#fff"} strokeWidth={2} />
</TooltipTrigger>
<TooltipContent>
<p>Follow NIVIDIA</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
<div onClick={handleShare} className=" cursor-pointer mt-2">
<ShareIcon />
</div>
</div>
</div>
{/* end of pack */}
<p className="mt-2 sm:text-sm"> World's first non-metal sustainable battery</p>
<div className="flex flex-wrap mt-3">
{["Technology", "Gaming"].map((tag) => (
<span key={tag} className="text-xs rounded-md bg-slate-200 dark:bg-slate-700 p-1 mx-1 mb-1">
{tag}
</span>
))}
</div>
<div className="grid grid-cols-2 mt-5">
{/* image carousel */}
<div>
<Carousel className="w-full mt-20 md:mt-0">
<CarouselContent className="h-[400px] flex h-full">
{Array.from({ length: 5 }).map((_, index) => (
<CarouselItem key={index}>
<img src="./boiler1.jpg" alt="" className="rounded-lg self-center" />
</CarouselItem>
))}
</CarouselContent>{" "}
<CarouselPrevious />
<CarouselNext />
</Carousel>
<Carousel className="w-2/3 md:w-full ml-10 md:ml-0 mt-5 md:mt-10 ">
<CarouselContent>
{/* boiler plate for an actual pictures */}
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
</CarouselItem>
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
</CarouselItem>
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
</CarouselItem>
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
</CarouselItem>
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
</CarouselItem>
</CarouselContent>
</Carousel>
</div>
<div className=" w-2/3 mt-4 m-auto grid-rows-5">
<div className="pl-5">
<h1 className="font-semibold text-xl md:text-4xl mt-8">
<CountUp start={0} end={100000} duration={2} prefix="$" className="" />
</h1>
<p className="text-sm md:text-lg"> 5% raised of $5M max goal</p>
<Progress value={progress} className="w-[60%] h-3 mt-3" />
<h1 className="font-semibold text-4xl md:mt-8">
{" "}
<CountUp start={0} end={1000} duration={2} className="text-xl md:text-4xl" />
</h1>
<p className="text-sm md:text-lg"> Investors</p>
</div>
<Separator decorative className="mt-3 w-3/4 ml-5" />
<h1 className="font-semibold text-xl md:text-4xl mt-8 ml-5">
<CountUp start={0} end={5800} duration={2} className="text-xl md:text-4xl" /> hours
</h1>
<p className="ml-5"> Left to invest</p>
<Button className="mt-5 md:mt-10 ml-0 md:ml-[25%] scale-75 md:scale-100">
<Link href="/invest/1">Invest in NVIDIA</Link>
</Button>
</div>
</div>
</div> </div>
</div> <Separator className="my-4" />
{/* menu */}
<div className="flex w-[90%] mt-24 m-auto ml-10 md:ml-32"> <div className="w-full space-y-2">
<ul className="list-none flex gap-10 text-lg md:text-xl "> <h2 className="text:base md:text-2xl">Payment Information</h2>
<li> <CardsPaymentMethod />
<a onClick={() => handleClick("Pitch")} className={tab === "Pitch" ? "text-blue-600" : ""}> </div>
Pitch <Separator className="my-4" />
</a>
</li> <div className=" md:w-2/3 space-y-2">
<li> <h2 className="text-2xl">Terms and Services</h2>
<a onClick={() => handleClick("General Data")} className={tab === "General Data" ? "text-blue-600" : ""}> <Table>
General Data <TableHeader>
</a> <TableRow>
</li> <TableHead>Select</TableHead>
<li> <TableHead>Term</TableHead>
<a onClick={() => handleClick("Updates")} className={tab === "Updates" ? "text-blue-600" : ""}> <TableHead>Description</TableHead>
Updates </TableRow>
</a> </TableHeader>
</li> <TableBody>
</ul> {term_data.map((item, index) => (
</div> <TableRow key={index}>
<hr className="mt-2" /> <TableCell>
{/* Card section */} <input
<div className="flex w-full mt-10"> type="checkbox"
{/* Cards */} checked={checkedTerms[index]}
<Card className="m-auto border-slate-800 w-3/4 p-6"> onChange={() => handleCheckboxChange(index)}
<CardContent> />
<Card> </TableCell>
<CardContent>{tab}</CardContent> <TableCell>{item.term}</TableCell>
</Card> <TableCell>{item.description}</TableCell>
</CardContent> </TableRow>
</Card> ))}
</TableBody>
</Table>
</div>
<Dialog>
<DialogTrigger asChild>
<Button className="mt-4">Invest</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you absolutely sure?</DialogTitle>
<DialogDescription>
This action cannot be undone. This will permanently!
</DialogDescription>
</DialogHeader>
<DialogFooter className="sm:justify-start">
<Button type="submit" onClick={handleTermServiceClick}>
Confirm
</Button>
<DialogClose asChild>
<Button type="button" variant="secondary">
Close
</Button>
</DialogClose>
</DialogFooter>
{error && (
<p className="text-red-500 mt-2 text-lg font-bold">{error}</p>
)}
</DialogContent>
</Dialog>
</div> </div>
</div> </div>
); );

View File

@ -6,6 +6,7 @@ import "@/app/globals.css";
import { NavigationBar } from "@/components/navigationBar/nav"; import { NavigationBar } from "@/components/navigationBar/nav";
import { Toaster } from "react-hot-toast"; import { Toaster } from "react-hot-toast";
import { SiteFooter } from "@/components/siteFooter";
const montserrat = Montserrat({ const montserrat = Montserrat({
subsets: ["latin"], subsets: ["latin"],
@ -39,6 +40,7 @@ export default function RootLayout({ children }: RootLayoutProps) {
<div className="flex-1 bg-background">{children}</div> <div className="flex-1 bg-background">{children}</div>
</div> </div>
</ThemeProvider> </ThemeProvider>
<SiteFooter />
</body> </body>
</html> </html>
</ReactQueryClientProvider> </ReactQueryClientProvider>

191
src/app/overview/page.tsx Normal file
View File

@ -0,0 +1,191 @@
"use client";
import React, { useState, useEffect } from "react";
import Image from "next/image";
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel";
import { Card, CardContent } from "@/components/ui/card";
import CountUp from "react-countup";
import { Progress } from "@/components/ui/progress";
import { Separator } from "@/components/ui/separator";
import { Button } from "@/components/ui/button";
import { ShareIcon, StarIcon } from "lucide-react";
import { Toaster, toast } from "react-hot-toast";
import useSession from "@/lib/supabase/useSession";
import { redirect } from "next/navigation";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
import Link from "next/link";
export default function Invest() {
const [progress, setProgress] = useState(0);
const [tab, setTab] = useState("Pitch");
const { session, loading } = useSession();
const user = session?.user;
const [sessionLoaded, setSessionLoaded] = useState(false);
const [isFollow, setIsFollow] = useState(false);
useEffect(() => {
// set sessionLoaded to true once session is confirmed
if (!loading) {
setSessionLoaded(true);
}
}, [loading]);
const handleClick = (item: string) => {
setTab(item);
};
const handleShare = () => {
const currentUrl = window.location.href;
if (document.hasFocus()) {
navigator.clipboard.writeText(currentUrl).then(() => {
toast.success("URL copied to clipboard!");
});
}
};
const handleFollow = () => {
if (user) {
setIsFollow((prevState) => !prevState);
// save follow to database
} else {
redirect("/login");
}
};
useEffect(() => {
// percent success
const timer = setTimeout(() => setProgress(66), 500);
return () => clearTimeout(timer);
}, []);
return (
<div>
<div>
<Toaster position="top-right" reverseOrder={false} />
</div>
<div className="w-[90%] h-[450px]-500 md:m-auto mt-12 md:mt-12 pl-14 md:pl-24">
<div>
{/* Name, star and share button packed */}
<div className="grid grid-cols-4">
<div className="flex col-span-2">
<Image src="./logo.svg" alt="logo" width={50} height={50} className="sm:scale-75" />
<div className="mt-3 font-bold text-lg md:text-3xl">NVIDIA</div>
</div>
<div className="grid grid-cols-2 gap-5 justify-self-end ">
<div className="mt-2 cursor-pointer" onClick={handleFollow}>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<StarIcon id="follow" fill={isFollow ? "#FFFF00" : "#fff"} strokeWidth={2} />
</TooltipTrigger>
<TooltipContent>
<p>Follow NIVIDIA</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
<div onClick={handleShare} className=" cursor-pointer mt-2">
<ShareIcon />
</div>
</div>
</div>
{/* end of pack */}
<p className="mt-2 sm:text-sm"> World's first non-metal sustainable battery</p>
<div className="flex flex-wrap mt-3">
{["Technology", "Gaming"].map((tag) => (
<span key={tag} className="text-xs rounded-md bg-slate-200 dark:bg-slate-700 p-1 mx-1 mb-1">
{tag}
</span>
))}
</div>
<div className="grid grid-cols-2 mt-5">
{/* image carousel */}
<div>
<Carousel className="w-full mt-20 md:mt-0">
<CarouselContent className="h-[400px] flex h-full">
{Array.from({ length: 5 }).map((_, index) => (
<CarouselItem key={index}>
<img src="./boiler1.jpg" alt="" className="rounded-lg self-center" />
</CarouselItem>
))}
</CarouselContent>{" "}
<CarouselPrevious />
<CarouselNext />
</Carousel>
<Carousel className="w-2/3 md:w-full ml-10 md:ml-0 mt-5 md:mt-10 ">
<CarouselContent>
{/* boiler plate for an actual pictures */}
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
</CarouselItem>
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
</CarouselItem>
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
</CarouselItem>
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
</CarouselItem>
<CarouselItem className="pl-1 md:basis-1/2 lg:basis-1/3">
<img src="./boiler1.jpg" alt="" className="rounded-lg" />
</CarouselItem>
</CarouselContent>
</Carousel>
</div>
<div className=" w-2/3 mt-4 m-auto grid-rows-5">
<div className="pl-5">
<h1 className="font-semibold text-xl md:text-4xl mt-8">
<CountUp start={0} end={100000} duration={2} prefix="$" className="" />
</h1>
<p className="text-sm md:text-lg"> 5% raised of $5M max goal</p>
<Progress value={progress} className="w-[60%] h-3 mt-3" />
<h1 className="font-semibold text-4xl md:mt-8">
{" "}
<CountUp start={0} end={1000} duration={2} className="text-xl md:text-4xl" />
</h1>
<p className="text-sm md:text-lg"> Investors</p>
</div>
<Separator decorative className="mt-3 w-3/4 ml-5" />
<h1 className="font-semibold text-xl md:text-4xl mt-8 ml-5">
<CountUp start={0} end={5800} duration={2} className="text-xl md:text-4xl" /> hours
</h1>
<p className="ml-5"> Left to invest</p>
<Button className="mt-5 md:mt-10 ml-0 md:ml-[25%] scale-75 md:scale-100">
<Link href="/invest">Invest in NVIDIA</Link>
</Button>
</div>
</div>
</div>
</div>
{/* menu */}
<div className="flex w-[90%] mt-24 m-auto ml-10 md:ml-32">
<ul className="list-none flex gap-10 text-lg md:text-xl ">
<li>
<a onClick={() => handleClick("Pitch")} className={tab === "Pitch" ? "text-blue-600" : ""}>
Pitch
</a>
</li>
<li>
<a onClick={() => handleClick("General Data")} className={tab === "General Data" ? "text-blue-600" : ""}>
General Data
</a>
</li>
<li>
<a onClick={() => handleClick("Updates")} className={tab === "Updates" ? "text-blue-600" : ""}>
Updates
</a>
</li>
</ul>
</div>
<hr className="mt-2" />
{/* Card section */}
<div className="flex w-full mt-10">
{/* Cards */}
<Card className="m-auto border-slate-800 w-3/4 p-6">
<CardContent>
<Card>
<CardContent>{tab}</CardContent>
</Card>
</CardContent>
</Card>
</div>
</div>
);
}

View File

@ -8,127 +8,132 @@ import { ExtendableCard } from "@/components/extendableCard";
export default function Home() { export default function Home() {
return ( return (
<main> <main>
<div className="flex flex-row bg-slate-100 dark:bg-gray-800"> <div className="relative mx-auto">
<div className="flex flex-col w-3/5"> {/* Expanded div */}
<span className="px-10 md:px-28 py-10 md:py-20"> <div className="flex flex-row bg-slate-100 dark:bg-gray-800">
<p className="text-lg md:text-4xl font-bold">Explore the world of ventures</p> <div className="container max-w-screen-xl flex flex-col">
<span className="text-sm md:text-lg"> <span className="mx-20 px-10 py-10">
<p>Unlock opportunities and connect with a community of passionate</p> <p className="text-4xl font-bold">Explore the world of ventures</p>
<p>investors and innovators.</p> <span className="text-lg">
<p>Together, we turn ideas into impact.</p> <p>Unlock opportunities and connect with a community of passionate</p>
<p>investors and innovators.</p>
<p>Together, we turn ideas into impact.</p>
</span>
<Button className="scale-75 md:scale-100 font-bold mt-4">
<Link href="/deals">Start Investing</Link>
</Button>
</span> </span>
<Button className="scale-75 md:scale-100 font-bold mt-4"> </div>
<Link href="/deals">Start Investing</Link> <div className="flex justify-center items-center mt-2">
</Button> <Image
src="/money.png"
width={0}
height={0}
sizes="100vw"
style={{ width: "50%", height: "auto" }}
alt="Money"
/>
</div>
</div>
</div>
<div className="container max-w-screen-xl">
<div className="flex flex-row gap-12 justify-start md:justify-center mt-3 md:mt-5">
<Card className="border-0 shadow-none">
<CardHeader>
<CardTitle className="text-lg md:text-2xl">100M+</CardTitle>
<CardDescription>Global investor community</CardDescription>
</CardHeader>
</Card>
<Card className="border-0 shadow-none">
<CardHeader>
<CardTitle className="text-lg md:text-2xl">2,500+</CardTitle>
<CardDescription>Ventures supported</CardDescription>
</CardHeader>
</Card>
<Card className="border-0 shadow-none">
<CardHeader>
<CardTitle className="text-lg md:text-2xl">$2.6B+</CardTitle>
<CardDescription>Capital raised</CardDescription>
</CardHeader>
</Card>
<Card className="border-0 shadow-none">
<CardHeader className="pb-2">
<CardTitle className="text-lg md:text-2xl">Follow Us</CardTitle>
</CardHeader>
<CardContent className="flex gap-2">
<Button className="flex gap-1 border-2 border-border rounded-md p-1 bg-background text-foreground scale-75 md:scale-100">
<Image src={"/github.svg"} width={20} height={20} alt="github" className="scale-75 md:scale-100" />
Github
</Button>
<Button className="flex gap-1 border-2 border-border rounded-md p-1 bg-background text-foreground scale-75 md:scale-100">
<Image src={"/github.svg"} width={20} height={20} alt="github" className="scale-75 md:scale-100" />
Github
</Button>
</CardContent>
</Card>
</div>
<Separator className="mb-6" />
<div className="flex flex-col px-10">
<span className="pb-5">
<p className="text-xl md:text-2xl font-bold">Hottest Deals</p>
<p className="text-md md:text-lg">The deals attracting the most interest right now</p>
</span> </span>
</div> <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
<div className="flex justify-center items-center mt-2"> <Link href={"/overview"}>
<Image <ExtendableCard
src="/money.png" name={"NVDA"}
width={0} description={"Founded in 1993, NVIDIA is a key innovator of computer graphics and AI technology"}
height={0} joinDate={"December 2021"}
sizes="100vw" location={"Bangkok, Thailand"}
style={{ width: "50%", height: "auto" }} tags={[]}
alt="Money" minInvestment={10000}
/> totalInvestor={58400}
</div> totalRaised={9000000}
</div> />
</Link>
<div className="flex flex-row gap-0 md:gap-10 justify-start md:justify-center mt-3 md:mt-5">
<Card className="border-0 shadow-none">
<CardHeader>
<CardTitle className="text-lg md:text-2xl">100M+</CardTitle>
<CardDescription>Global investor community</CardDescription>
</CardHeader>
</Card>
<Card className="border-0 shadow-none">
<CardHeader>
<CardTitle className="text-lg md:text-2xl">2,500+</CardTitle>
<CardDescription>Ventures supported</CardDescription>
</CardHeader>
</Card>
<Card className="border-0 shadow-none">
<CardHeader>
<CardTitle className="text-lg md:text-2xl">$2.6B+</CardTitle>
<CardDescription>Capital raised</CardDescription>
</CardHeader>
</Card>
<Card className="border-0 shadow-none">
<CardHeader className="pb-2">
<CardTitle className="text-lg md:text-2xl">Follow Us</CardTitle>
</CardHeader>
<CardContent className="flex gap-2">
<Button className="flex gap-1 border-2 border-border rounded-md p-1 bg-background text-foreground scale-75 md:scale-100">
<Image src={"/github.svg"} width={20} height={20} alt="github" className="scale-75 md:scale-100" />
Github
</Button>
<Button className="flex gap-1 border-2 border-border rounded-md p-1 bg-background text-foreground scale-75 md:scale-100">
<Image src={"/github.svg"} width={20} height={20} alt="github" className="scale-75 md:scale-100" />
Github
</Button>
</CardContent>
</Card>
</div>
<Separator className="mb-6" />
<div className="flex flex-col px-10 md:px-28">
<span className="pb-5">
<p className="text-xl md:text-2xl font-bold">Hottest Deals</p>
<p className="text-md md:text-lg">The deals attracting the most interest right now</p>
</span>
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
<Link href={"/invest"}>
<ExtendableCard <ExtendableCard
name={"NVDA"} name={"Apple Inc."}
description={"Founded in 1993, NVIDIA is a key innovator of computer graphics and AI technology"} description={
joinDate={"December 2021"} "Founded in 1976, Apple Inc. is a leading innovator in consumer electronics, software, and online services, known for products like the iPhone, MacBook, and the App Store."
location={"Bangkok, Thailand"} }
joinDate={"February 2020"}
location={"Cupertino, California, USA"}
tags={[]} tags={[]}
minInvestment={10000} minInvestment={10000}
totalInvestor={58400} totalInvestor={58400}
totalRaised={9000000} totalRaised={9000000}
/> />
</Link> <ExtendableCard
<ExtendableCard name={"Google LLC"}
name={"Apple Inc."} description={
description={ "Founded in 1998, Google LLC specializes in internet-related services and products, including search engines, online advertising, cloud computing, and the Android operating system."
"Founded in 1976, Apple Inc. is a leading innovator in consumer electronics, software, and online services, known for products like the iPhone, MacBook, and the App Store." }
} joinDate={"April 2019"}
joinDate={"February 2020"} location={"Mountain View, California, USA"}
location={"Cupertino, California, USA"} tags={[]}
tags={[]} minInvestment={10000}
minInvestment={10000} totalInvestor={5000}
totalInvestor={58400} totalRaised={1500000000}
totalRaised={9000000} />
/> <ExtendableCard
<ExtendableCard name={"Microsoft Corporation"}
name={"Google LLC"} description={"Microsoft Corporation is a multinational technology company."}
description={ joinDate={"January 2018"}
"Founded in 1998, Google LLC specializes in internet-related services and products, including search engines, online advertising, cloud computing, and the Android operating system." location={"California, USA"}
} tags={[]}
joinDate={"April 2019"} minInvestment={250}
location={"Mountain View, California, USA"} totalInvestor={5000}
tags={[]} totalRaised={1500000}
minInvestment={10000} />
totalInvestor={5000} </div>
totalRaised={1500000000} <div className="self-center py-5 scale-75 md:scale-100">
/> <Button>
<ExtendableCard <Link href={"/deals"}>View all</Link>
name={"Microsoft Corporation"} </Button>
description={"Microsoft Corporation is a multinational technology company."} </div>
joinDate={"January 2018"}
location={"California, USA"}
tags={[]}
minInvestment={250}
totalInvestor={5000}
totalRaised={1500000}
/>
</div>
<div className="self-center py-5 scale-75 md:scale-100">
<Button>
<Link href={"/deals"}>View all</Link>
</Button>
</div> </div>
</div> </div>
</main> </main>

View File

@ -1,8 +1,10 @@
"use client"; "use client";
import { CalendarDaysIcon } from "lucide-react"; import { CalendarDaysIcon } from "lucide-react";
import { cn } from "@/lib/utils";
import Image from "next/image";
interface XMap { interface XMap {
// tagName: colorCode
[tag: string]: string; [tag: string]: string;
} }
@ -12,69 +14,86 @@ interface ExtendableCardProps {
joinDate: string; joinDate: string;
location: string; location: string;
tags: XMap | null | never[] | string[]; tags: XMap | null | never[] | string[];
imageUri: string | null;
minInvestment: number; minInvestment: number;
totalInvestor: number; totalInvestor: number;
totalRaised: number; totalRaised: number;
className?: string;
} }
export function ExtendableCard(props: ExtendableCardProps) { export function ExtendableCard(props: ExtendableCardProps) {
return ( return (
<div className="group relative w-full max-w-sm overflow-hidden rounded-lg bg-card shadow-md transition-all duration-500 hover:shadow-lg "> <div
<div className="aspect-[4/3] overflow-hidden"> className={cn(
<img "flex flex-col group border-[1px] border-border relative hover:shadow-md rounded-xl h-[450px]",
src="/money.png" props.className
alt="Card image" )}>
width="400" <div className="flex flex-col h-full">
height="300" {/* Image */}
className="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105" <div className="relative h-3/4 w-full">
style={{ aspectRatio: "400/300", objectFit: "cover" }} {props.imageUri ? (
/> <Image
</div> src={props.imageUri}
<div className="p-1 md:p-4"> alt="Card image"
<div className="text-sm md:text-lg font-semibold text-card-foreground transition-colors duration-500 group-hover:text-primary"> layout="fill"
{props.name} className="rounded-t-xl bg-background dark:bg-background h-full"
/>
) : (
<Image
src="/money.png"
alt="Card image"
layout="fill"
className="rounded-t-xl bg-background dark:bg-background h-full"
/>
)}
</div> </div>
<div className="flex flex-col h-full justify-between">
{/* Info 0 overlaps Image */}
<div className="bg-background dark:bg-background transition-all ease-out transform group-hover:-translate-y-24 duration-1000 group-hover:bg-opacity-100 z-10 p-4">
<div className="font-semibold text-card-foreground transition-colors duration-1000 group-hover:text-primary">
{props.name}
</div>
<p className="text-sm text-muted-foreground line-clamp-3">{props.description}</p>
</div>
{/* Default content (visible when not hovered) */} {/* Info 1 */}
<div className="mt-2 flex items-center text-muted-foreground group-hover:hidden"> <div>
<span className="flex items-center pt-2 gap-1"> <div className="transition-transform duration-500 transform opacity-100 group-hover:opacity-0 p-4">
<CalendarDaysIcon width={20} /> <div className="flex items-center text-muted-foreground">
<div className="text-xs md:text-lg">Joined {props.joinDate}</div> <span className="flex items-center gap-1">
</span> <CalendarDaysIcon width={20} />
</div> <div className="text-xs">Joined {props.joinDate}</div>
<div className="mt-2 flex items-center text-muted-foreground group-hover:hidden"> </span>
<span className="text-xs md:text-sm">{props.location}</span>
</div>
<div className="mt-2 flex flex-wrap items-center text-muted-foreground group-hover:hidden">
{props.tags.map((tag) => (
<span
id="tag"
key={tag}
className="text-[10px] md:text-xs rounded-md bg-slate-200 dark:bg-slate-700 p-1 mx-1 mb-1">
{tag}
</span>
))}
</div>
{/* Hover content (appears when hovered) */}
<div className="mt-4 max-h-0 overflow-hidden opacity-0 group-hover:max-h-[500px] group-hover:opacity-100 transition-all duration-1000 ease-in-out">
<p className="text-xs md:text-sm text-muted-foreground">{props.description}</p>
<div className="mt-4 flex items-center justify-between">
<div className="flex items-center space-x-2">
<div>
<hr className="w-screen -ml-4 mb-2" />
<p className="text-xs md:text-base">
<strong>${props.totalRaised.toLocaleString()}</strong> committed and reserved
</p>
<hr className="w-screen -ml-4 mb-2 mt-2" />
<p className="mb-2 text-xs md:text-base">
<strong>{props.totalInvestor.toLocaleString()}</strong> investors
</p>
<hr className="w-screen -ml-4 mb-2" />
<p className="text-xs md:text-base">
<strong>${props.minInvestment.toLocaleString()}</strong> min. investment
</p>
</div> </div>
<div className="flex items-center text-muted-foreground">
<span className="text-xs">{props.location}</span>
</div>
<div className="flex flex-wrap mt-1 items-center text-muted-foreground">
{props.tags.map((tag) => (
<span id="tag" key={tag} className="text-[10px] rounded-md bg-slate-200 dark:bg-slate-700 p-1 mr-1">
{tag}
</span>
))}
</div>
</div>
</div>
{/* Info 2 */}
<div className="hidden group-hover:flex group-hover:absolute group-hover:bottom-4 p-4">
{/* Info 2 (Visible on hover) */}
<div className="transition-transform duration-500 transform translate-y-6 opacity-0 group-hover:translate-y-0 group-hover:opacity-100">
<hr className="-ml-4 mb-2" />
<p className="text-base">
<strong>${props.totalRaised.toLocaleString()}</strong> committed and reserved
</p>
<hr className="-ml-4 mb-2 mt-2" />
<p className="mb-2 text-base">
<strong>{props.totalInvestor.toLocaleString()}</strong> investors
</p>
<hr className="-ml-4 mb-2" />
<p className="text-base">
<strong>${props.minInvestment.toLocaleString()}</strong> min. investment
</p>
</div> </div>
</div> </div>
</div> </div>

View File

@ -8,7 +8,7 @@ import { cn } from "@/lib/utils";
import { Separator } from "@/components/ui/separator"; import { Separator } from "@/components/ui/separator";
import { ThemeToggle } from "@/components/theme-toggle"; import { ThemeToggle } from "@/components/theme-toggle";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { useRouter } from 'next/navigation'; import { useRouter } from "next/navigation";
import { import {
NavigationMenu, NavigationMenu,
NavigationMenuContent, NavigationMenuContent,
@ -46,31 +46,27 @@ const landings = [
route: "/crm-landing", route: "/crm-landing",
}, },
]; ];
const ListItem = React.forwardRef< const ListItem = React.forwardRef<React.ElementRef<"a">, React.ComponentPropsWithoutRef<"a">>(
React.ElementRef<"a">, ({ className, title, children, ...props }, ref) => {
React.ComponentPropsWithoutRef<"a"> return (
>(({ className, title, children, ...props }, ref) => { <li>
return ( <NavigationMenuLink asChild>
<li> <a
<NavigationMenuLink asChild> ref={ref}
<a className={cn(
ref={ref} "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={cn( className
"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>
{...props} <hr />
> <p className="line-clamp-2 text-sm leading-snug text-muted-foreground">{children}</p>
<div className="text-sm font-medium leading-none">{title}</div> </a>
<hr /> </NavigationMenuLink>
<p className="line-clamp-2 text-sm leading-snug text-muted-foreground"> </li>
{children} );
</p> }
</a> );
</NavigationMenuLink>
</li>
);
});
ListItem.displayName = "ListItem"; ListItem.displayName = "ListItem";
const unAuthenticatedComponents = () => { const unAuthenticatedComponents = () => {
@ -104,11 +100,7 @@ const authenticatedComponents = () => {
<Wallet /> <Wallet />
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>
<Button <Button variant="outline" size="icon" className="overflow-hidden rounded-full">
variant="outline"
size="icon"
className="overflow-hidden rounded-full"
>
<Avatar> <Avatar>
<AvatarImage src="https://api.dicebear.com/9.x/pixel-art/svg" /> <AvatarImage src="https://api.dicebear.com/9.x/pixel-art/svg" />
<AvatarFallback>1</AvatarFallback> <AvatarFallback>1</AvatarFallback>
@ -144,7 +136,7 @@ export function NavigationBar() {
}, [loading]); }, [loading]);
const handleKeyDown = async (k: React.KeyboardEvent<HTMLInputElement>) => { const handleKeyDown = async (k: React.KeyboardEvent<HTMLInputElement>) => {
if (k.key === 'Enter') { if (k.key === "Enter") {
const query = (k.target as HTMLInputElement).value.trim(); const query = (k.target as HTMLInputElement).value.trim();
if (query) { if (query) {
router.push(`/find?query=${encodeURIComponent(query)}`); router.push(`/find?query=${encodeURIComponent(query)}`);
@ -177,14 +169,13 @@ export function NavigationBar() {
]; ];
return ( return (
<header className="sticky top-0 flex flex-wrap w-full bg-card text-sm py-3 border-b-2 border-border z-50"> <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-[85rem] w-full mx-auto px-4"> <nav className="max-w-screen-xl w-full mx-auto px-4">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="flex flex-col"> <div className="flex flex-col">
<Link <Link
className="flex-none text-xl font-semibold dark:text-white focus:outline-none focus:opacity-80" className="flex-none text-xl font-semibold dark:text-white focus:outline-none focus:opacity-80"
href="/" href="/"
aria-label="Brand" aria-label="Brand">
>
<span className="inline-flex items-center gap-x-2 text-xl font-semibold dark:text-white"> <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} /> <Image src="./logo.svg" alt="logo" width={50} height={50} />
B2DVentures B2DVentures
@ -196,17 +187,11 @@ export function NavigationBar() {
<NavigationMenu> <NavigationMenu>
<NavigationMenuList> <NavigationMenuList>
<NavigationMenuItem> <NavigationMenuItem>
<NavigationMenuTrigger className="text-base"> <NavigationMenuTrigger className="text-base">Businesses</NavigationMenuTrigger>
Businesses
</NavigationMenuTrigger>
<NavigationMenuContent> <NavigationMenuContent>
<ul className="grid w-[400px] "> <ul className="grid w-[400px] ">
{businessComponents.map((component) => ( {businessComponents.map((component) => (
<ListItem <ListItem key={component.title} title={component.title} href={component.href}>
key={component.title}
title={component.title}
href={component.href}
>
{component.description} {component.description}
</ListItem> </ListItem>
))} ))}
@ -215,17 +200,11 @@ export function NavigationBar() {
</NavigationMenuItem> </NavigationMenuItem>
<NavigationMenuItem> <NavigationMenuItem>
<NavigationMenuTrigger className="text-base font-medium "> <NavigationMenuTrigger className="text-base font-medium ">Projects</NavigationMenuTrigger>
Projects
</NavigationMenuTrigger>
<NavigationMenuContent> <NavigationMenuContent>
<ul className="grid w-[400px] "> <ul className="grid w-[400px] ">
{projectComponents.map((component) => ( {projectComponents.map((component) => (
<ListItem <ListItem key={component.title} title={component.title} href={component.href}>
key={component.title}
title={component.title}
href={component.href}
>
{component.description} {component.description}
</ListItem> </ListItem>
))} ))}
@ -234,17 +213,11 @@ export function NavigationBar() {
</NavigationMenuItem> </NavigationMenuItem>
<NavigationMenuItem> <NavigationMenuItem>
<NavigationMenuTrigger className="text-base"> <NavigationMenuTrigger className="text-base">Blogs</NavigationMenuTrigger>
Blogs
</NavigationMenuTrigger>
<NavigationMenuContent> <NavigationMenuContent>
<ul className="grid w-[400px] "> <ul className="grid w-[400px] ">
{blogComponents.map((component) => ( {blogComponents.map((component) => (
<ListItem <ListItem key={component.title} title={component.title} href={component.href}>
key={component.title}
title={component.title}
href={component.href}
>
{component.description} {component.description}
</ListItem> </ListItem>
))} ))}
@ -253,19 +226,13 @@ export function NavigationBar() {
</NavigationMenuItem> </NavigationMenuItem>
<NavigationMenuItem> <NavigationMenuItem>
<NavigationMenuLink <NavigationMenuLink className="text-base font-medium" href="docs">
className="text-base font-medium"
href="docs"
>
Docs Docs
</NavigationMenuLink> </NavigationMenuLink>
</NavigationMenuItem> </NavigationMenuItem>
<NavigationMenuItem className="pl-5 flex"> <NavigationMenuItem className="pl-5 flex">
<Search <Search onClick={() => setSearchActive(!searchActive)} className="cursor-pointer" />
onClick={() => setSearchActive(!searchActive)}
className="cursor-pointer"
/>
{/* search bar's input */} {/* search bar's input */}
<input <input
type="text" type="text"

View File

@ -2,26 +2,47 @@
import { Icons } from "./ui/icons"; import { Icons } from "./ui/icons";
import { Button } from "./ui/button"; import { Button } from "./ui/button";
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "./ui/card"; import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "./ui/card";
import { Input } from "./ui/input"; import { Input } from "./ui/input";
import { Label } from "./ui/label"; import { Label } from "./ui/label";
import { RadioGroup, RadioGroupItem } from "./ui/radio-group"; import { RadioGroup, RadioGroupItem } from "./ui/radio-group";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select"; import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "./ui/select";
export function CardsPaymentMethod() { export function CardsPaymentMethod() {
return ( return (
<Card> <Card className="lg:w-2/3 ">
<CardHeader> <CardHeader>
<CardTitle>Payment Method</CardTitle> <CardTitle className="text-xl md:text-2xl">Payment Method</CardTitle>
<CardDescription>Add a new payment method to your account.</CardDescription> <CardDescription className="font-normal md:font-semibold">
Add a new payment method to your account.
</CardDescription>
</CardHeader> </CardHeader>
<CardContent className="grid gap-6"> <CardContent className="grid gap-6">
<RadioGroup defaultValue="card" className="grid grid-cols-3 gap-4"> <RadioGroup defaultValue="card" className="flex w-full justify-center gap-1 md:gap-3">
<div> <div className="w-[100px] lg:w-[130px]">
<RadioGroupItem value="card" id="card" className="peer sr-only" aria-label="Card" /> <RadioGroupItem
value="card"
id="card"
className="peer sr-only"
aria-label="Card"
/>
<Label <Label
htmlFor="card" htmlFor="card"
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-transparent p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary"> className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-transparent p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary"
>
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -30,7 +51,8 @@ export function CardsPaymentMethod() {
strokeLinecap="round" strokeLinecap="round"
strokeLinejoin="round" strokeLinejoin="round"
strokeWidth="2" strokeWidth="2"
className="mb-3 h-6 w-6"> className="mb-3 h-6 w-6"
>
<rect width="20" height="14" x="2" y="5" rx="2" /> <rect width="20" height="14" x="2" y="5" rx="2" />
<path d="M2 10h20" /> <path d="M2 10h20" />
</svg> </svg>
@ -38,29 +60,48 @@ export function CardsPaymentMethod() {
</Label> </Label>
</div> </div>
<div> <div className="w-[100px] lg:w-[130px]">
<RadioGroupItem value="paypal" id="paypal" className="peer sr-only" aria-label="Paypal" /> <RadioGroupItem
value="paypal"
id="paypal"
className="peer sr-only"
aria-label="Paypal"
/>
<Label <Label
htmlFor="paypal" htmlFor="paypal"
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-transparent p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary"> className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-transparent p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary"
>
<Icons.paypal className="mb-3 h-6 w-6" /> <Icons.paypal className="mb-3 h-6 w-6" />
Paypal Paypal
</Label> </Label>
</div> </div>
<div> <div className="w-[100px] lg:w-[130px]">
<RadioGroupItem value="apple" id="apple" className="peer sr-only" aria-label="Apple" /> <RadioGroupItem
value="apple"
id="apple"
className="peer sr-only"
aria-label="Apple"
/>
<Label <Label
htmlFor="apple" htmlFor="apple"
className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-transparent p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary"> className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-transparent p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary"
>
<Icons.apple className="mb-3 h-6 w-6" /> <Icons.apple className="mb-3 h-6 w-6" />
Apple Apple
</Label> </Label>
</div> </div>
</RadioGroup> </RadioGroup>
<div className="grid gap-2">
<Label htmlFor="name">Name</Label> <div className="grid grid-cols-2">
<Input id="name" placeholder="First Last" /> <div className="grid gap-2">
<Label htmlFor="firstname">First Name</Label>
<Input id="firstname" placeholder="Your firstname..." />
</div>
<div className="grid gap-2">
<Label htmlFor="lastname">Last Name</Label>
<Input id="lastname" placeholder="Your lastname..." />
</div>
</div> </div>
<div className="grid gap-2"> <div className="grid gap-2">
<Label htmlFor="city">City</Label> <Label htmlFor="city">City</Label>

View File

@ -0,0 +1,36 @@
import Link from "next/link";
export function SiteFooter() {
return (
<footer className="pt-6">
<div className="flex flex-col items-center justify-between gap-4 md:h-24 md:flex-row bg-foreground text-background">
<div className="container max-w-screen-xl flex flex-col md:flex-row justify-between items-center py-6">
{/* Logo or Brand */}
<div className="flex items-center space-x-4">
<div className="text-xl font-bold">B2DVentures</div>
</div>
{/* Navigation Links */}
<div className="flex space-x-6">
<Link href="/" className="hover:underline">
Home
</Link>
<Link href="/about" className="hover:underline">
About Us
</Link>
<Link href="/services" className="hover:underline">
Services
</Link>
<Link href="/contact" className="hover:underline">
Contact
</Link>
</div>
{/* Copyright */}
<div className="text-sm text-center mt-4 md:mt-0 md:ml-6">
&copy; {new Date().getFullYear()} B2DVentures. All rights reserved.
</div>
</div>
</div>
</footer>
);
}

View File

@ -6,25 +6,37 @@ test.use({
test('Test filter with tags', async ({ page }) => { test('Test filter with tags', async ({ page }) => {
await page.goto('http://127.0.0.1:3000/'); await page.goto('http://127.0.0.1:3000/');
// Start Investing
await page.getByRole('button', { name: 'Start Investing' }).click(); await page.getByRole('button', { name: 'Start Investing' }).click();
// Filter by AI tag
await page.locator('button').filter({ hasText: 'Tags' }).click(); await page.locator('button').filter({ hasText: 'Tags' }).click();
await page.getByLabel('AI', { exact: true }).click(); await page.getByLabel('AI', { exact: true }).click();
await page.locator('span#tag', { hasText: 'AI' }); const aiTag = page.locator('span#tag', { hasText: 'AI' });
await expect(aiTag).toBeVisible();
// Filter by Technology tag
await page.locator('button').filter({ hasText: 'AI' }).click(); await page.locator('button').filter({ hasText: 'AI' }).click();
await page.getByLabel('Technology').click(); await page.getByLabel('Technology').click();
await page.locator('span#tag', { hasText: 'Technology' }); const techTag = page.locator('span#tag', { hasText: 'Technology' });
await expect(techTag).toBeVisible();
// Filter by Consumer Electronics tag
await page.locator('button').filter({ hasText: 'Technology' }).click(); await page.locator('button').filter({ hasText: 'Technology' }).click();
await page.getByText('Consumer Electronics').click(); await page.getByLabel('Consumer Electronics').click();
await page.locator('span#tag', { hasText: 'Consumer Electronics' }); const consumerElectronicsTag = page.locator('span#tag', { hasText: 'Consumer Electronics' });
await expect(consumerElectronicsTag).toBeVisible();
// Filter by Software tag
await page.locator('button').filter({ hasText: 'Consumer Electronics' }).click(); await page.locator('button').filter({ hasText: 'Consumer Electronics' }).click();
await page.getByLabel('Software').click(); await page.getByLabel('Software').click();
await page.locator('span#tag', { hasText: 'Software' }); const softwareTag = page.locator('span#tag', { hasText: 'Software' });
await expect(softwareTag).toBeVisible();
// Filter by Internet tag
await page.locator('button').filter({ hasText: 'Software' }).click(); await page.locator('button').filter({ hasText: 'Software' }).click();
await page.getByLabel('Internet').click(); await page.getByLabel('Internet').click();
await page.locator('span#tag', { hasText: 'Internet' }); const internetTag = page.locator('span#tag', { hasText: 'Internet' });
await expect(internetTag).toBeVisible();
}); });