mirror of
https://github.com/Sosokker/B2D-Ventures.git
synced 2025-12-19 05:54:06 +01:00
Merge pull request #41 from Sosokker/front-end
style: improve responsiveness of business card and pages
This commit is contained in:
commit
f5a979d7da
@ -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}
|
||||||
|
|||||||
@ -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>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -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 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>
|
||||||
<div>
|
<div className="w-1/2 space-y-2">
|
||||||
<Toaster position="top-right" reverseOrder={false} />
|
<h2 className="text:base md:text-2xl">Investment Amount</h2>
|
||||||
|
<Input
|
||||||
|
className="w-52"
|
||||||
|
type="number"
|
||||||
|
placeholder="min $500"
|
||||||
|
min={500}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-[90%] h-[450px]-500 md:m-auto mt-12 md:mt-12 pl-14 md:pl-24">
|
<Separator className="my-4" />
|
||||||
<div>
|
|
||||||
{/* Name, star and share button packed */}
|
<div className="w-full space-y-2">
|
||||||
<div className="grid grid-cols-4">
|
<h2 className="text:base md:text-2xl">Payment Information</h2>
|
||||||
<div className="flex col-span-2">
|
<CardsPaymentMethod />
|
||||||
<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>
|
||||||
<div className="grid grid-cols-2 gap-5 justify-self-end ">
|
<Separator className="my-4" />
|
||||||
<div className="mt-2 cursor-pointer" onClick={handleFollow}>
|
|
||||||
<TooltipProvider>
|
<div className=" md:w-2/3 space-y-2">
|
||||||
<Tooltip>
|
<h2 className="text-2xl">Terms and Services</h2>
|
||||||
<TooltipTrigger asChild>
|
<Table>
|
||||||
<StarIcon id="follow" fill={isFollow ? "#FFFF00" : "#fff"} strokeWidth={2} />
|
<TableHeader>
|
||||||
</TooltipTrigger>
|
<TableRow>
|
||||||
<TooltipContent>
|
<TableHead>Select</TableHead>
|
||||||
<p>Follow NIVIDIA</p>
|
<TableHead>Term</TableHead>
|
||||||
</TooltipContent>
|
<TableHead>Description</TableHead>
|
||||||
</Tooltip>
|
</TableRow>
|
||||||
</TooltipProvider>
|
</TableHeader>
|
||||||
</div>
|
<TableBody>
|
||||||
<div onClick={handleShare} className=" cursor-pointer mt-2">
|
{term_data.map((item, index) => (
|
||||||
<ShareIcon />
|
<TableRow key={index}>
|
||||||
</div>
|
<TableCell>
|
||||||
</div>
|
<input
|
||||||
</div>
|
type="checkbox"
|
||||||
{/* end of pack */}
|
checked={checkedTerms[index]}
|
||||||
<p className="mt-2 sm:text-sm"> World's first non-metal sustainable battery</p>
|
onChange={() => handleCheckboxChange(index)}
|
||||||
<div className="flex flex-wrap mt-3">
|
/>
|
||||||
{["Technology", "Gaming"].map((tag) => (
|
</TableCell>
|
||||||
<span key={tag} className="text-xs rounded-md bg-slate-200 dark:bg-slate-700 p-1 mx-1 mb-1">
|
<TableCell>{item.term}</TableCell>
|
||||||
{tag}
|
<TableCell>{item.description}</TableCell>
|
||||||
</span>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-2 mt-5">
|
|
||||||
{/* image carousel */}
|
<Dialog>
|
||||||
<div>
|
<DialogTrigger asChild>
|
||||||
<Carousel className="w-full mt-20 md:mt-0">
|
<Button className="mt-4">Invest</Button>
|
||||||
<CarouselContent className="h-[400px] flex h-full">
|
</DialogTrigger>
|
||||||
{Array.from({ length: 5 }).map((_, index) => (
|
<DialogContent>
|
||||||
<CarouselItem key={index}>
|
<DialogHeader>
|
||||||
<img src="./boiler1.jpg" alt="" className="rounded-lg self-center" />
|
<DialogTitle>Are you absolutely sure?</DialogTitle>
|
||||||
</CarouselItem>
|
<DialogDescription>
|
||||||
))}
|
This action cannot be undone. This will permanently!
|
||||||
</CarouselContent>{" "}
|
</DialogDescription>
|
||||||
<CarouselPrevious />
|
</DialogHeader>
|
||||||
<CarouselNext />
|
<DialogFooter className="sm:justify-start">
|
||||||
</Carousel>
|
<Button type="submit" onClick={handleTermServiceClick}>
|
||||||
<Carousel className="w-2/3 md:w-full ml-10 md:ml-0 mt-5 md:mt-10 ">
|
Confirm
|
||||||
<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>
|
</Button>
|
||||||
</div>
|
<DialogClose asChild>
|
||||||
</div>
|
<Button type="button" variant="secondary">
|
||||||
</div>
|
Close
|
||||||
</div>
|
</Button>
|
||||||
{/* menu */}
|
</DialogClose>
|
||||||
<div className="flex w-[90%] mt-24 m-auto ml-10 md:ml-32">
|
</DialogFooter>
|
||||||
<ul className="list-none flex gap-10 text-lg md:text-xl ">
|
{error && (
|
||||||
<li>
|
<p className="text-red-500 mt-2 text-lg font-bold">{error}</p>
|
||||||
<a onClick={() => handleClick("Pitch")} className={tab === "Pitch" ? "text-blue-600" : ""}>
|
)}
|
||||||
Pitch
|
</DialogContent>
|
||||||
</a>
|
</Dialog>
|
||||||
</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>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -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
191
src/app/overview/page.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -8,11 +8,13 @@ import { ExtendableCard } from "@/components/extendableCard";
|
|||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<main>
|
||||||
|
<div className="relative mx-auto">
|
||||||
|
{/* Expanded div */}
|
||||||
<div className="flex flex-row bg-slate-100 dark:bg-gray-800">
|
<div className="flex flex-row bg-slate-100 dark:bg-gray-800">
|
||||||
<div className="flex flex-col w-3/5">
|
<div className="container max-w-screen-xl flex flex-col">
|
||||||
<span className="px-10 md:px-28 py-10 md:py-20">
|
<span className="mx-20 px-10 py-10">
|
||||||
<p className="text-lg md:text-4xl font-bold">Explore the world of ventures</p>
|
<p className="text-4xl font-bold">Explore the world of ventures</p>
|
||||||
<span className="text-sm md:text-lg">
|
<span className="text-lg">
|
||||||
<p>Unlock opportunities and connect with a community of passionate</p>
|
<p>Unlock opportunities and connect with a community of passionate</p>
|
||||||
<p>investors and innovators.</p>
|
<p>investors and innovators.</p>
|
||||||
<p>Together, we turn ideas into impact.</p>
|
<p>Together, we turn ideas into impact.</p>
|
||||||
@ -33,8 +35,10 @@ export default function Home() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-row gap-0 md:gap-10 justify-start md:justify-center mt-3 md:mt-5">
|
<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">
|
<Card className="border-0 shadow-none">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-lg md:text-2xl">100M+</CardTitle>
|
<CardTitle className="text-lg md:text-2xl">100M+</CardTitle>
|
||||||
@ -72,13 +76,13 @@ export default function Home() {
|
|||||||
|
|
||||||
<Separator className="mb-6" />
|
<Separator className="mb-6" />
|
||||||
|
|
||||||
<div className="flex flex-col px-10 md:px-28">
|
<div className="flex flex-col px-10">
|
||||||
<span className="pb-5">
|
<span className="pb-5">
|
||||||
<p className="text-xl md:text-2xl font-bold">Hottest Deals</p>
|
<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>
|
<p className="text-md md:text-lg">The deals attracting the most interest right now</p>
|
||||||
</span>
|
</span>
|
||||||
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
|
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
|
||||||
<Link href={"/invest"}>
|
<Link href={"/overview"}>
|
||||||
<ExtendableCard
|
<ExtendableCard
|
||||||
name={"NVDA"}
|
name={"NVDA"}
|
||||||
description={"Founded in 1993, NVIDIA is a key innovator of computer graphics and AI technology"}
|
description={"Founded in 1993, NVIDIA is a key innovator of computer graphics and AI technology"}
|
||||||
@ -131,6 +135,7 @@ export default function Home() {
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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,66 +14,84 @@ 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]",
|
||||||
|
props.className
|
||||||
|
)}>
|
||||||
|
<div className="flex flex-col h-full">
|
||||||
|
{/* Image */}
|
||||||
|
<div className="relative h-3/4 w-full">
|
||||||
|
{props.imageUri ? (
|
||||||
|
<Image
|
||||||
|
src={props.imageUri}
|
||||||
|
alt="Card image"
|
||||||
|
layout="fill"
|
||||||
|
className="rounded-t-xl bg-background dark:bg-background h-full"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Image
|
||||||
src="/money.png"
|
src="/money.png"
|
||||||
alt="Card image"
|
alt="Card image"
|
||||||
width="400"
|
layout="fill"
|
||||||
height="300"
|
className="rounded-t-xl bg-background dark:bg-background h-full"
|
||||||
className="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105"
|
|
||||||
style={{ aspectRatio: "400/300", objectFit: "cover" }}
|
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="p-1 md:p-4">
|
<div className="flex flex-col h-full justify-between">
|
||||||
<div className="text-sm md:text-lg font-semibold text-card-foreground transition-colors duration-500 group-hover:text-primary">
|
{/* 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}
|
{props.name}
|
||||||
</div>
|
</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">
|
||||||
|
<div className="flex items-center text-muted-foreground">
|
||||||
|
<span className="flex items-center gap-1">
|
||||||
<CalendarDaysIcon width={20} />
|
<CalendarDaysIcon width={20} />
|
||||||
<div className="text-xs md:text-lg">Joined {props.joinDate}</div>
|
<div className="text-xs">Joined {props.joinDate}</div>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2 flex items-center text-muted-foreground group-hover:hidden">
|
<div className="flex items-center text-muted-foreground">
|
||||||
<span className="text-xs md:text-sm">{props.location}</span>
|
<span className="text-xs">{props.location}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2 flex flex-wrap items-center text-muted-foreground group-hover:hidden">
|
<div className="flex flex-wrap mt-1 items-center text-muted-foreground">
|
||||||
{props.tags.map((tag) => (
|
{props.tags.map((tag) => (
|
||||||
<span
|
<span id="tag" key={tag} className="text-[10px] rounded-md bg-slate-200 dark:bg-slate-700 p-1 mr-1">
|
||||||
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}
|
{tag}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Hover content (appears when hovered) */}
|
{/* Info 2 */}
|
||||||
<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">
|
<div className="hidden group-hover:flex group-hover:absolute group-hover:bottom-4 p-4">
|
||||||
<p className="text-xs md:text-sm text-muted-foreground">{props.description}</p>
|
{/* Info 2 (Visible on hover) */}
|
||||||
<div className="mt-4 flex items-center justify-between">
|
<div className="transition-transform duration-500 transform translate-y-6 opacity-0 group-hover:translate-y-0 group-hover:opacity-100">
|
||||||
<div className="flex items-center space-x-2">
|
<hr className="-ml-4 mb-2" />
|
||||||
<div>
|
<p className="text-base">
|
||||||
<hr className="w-screen -ml-4 mb-2" />
|
|
||||||
<p className="text-xs md:text-base">
|
|
||||||
<strong>${props.totalRaised.toLocaleString()}</strong> committed and reserved
|
<strong>${props.totalRaised.toLocaleString()}</strong> committed and reserved
|
||||||
</p>
|
</p>
|
||||||
<hr className="w-screen -ml-4 mb-2 mt-2" />
|
<hr className="-ml-4 mb-2 mt-2" />
|
||||||
<p className="mb-2 text-xs md:text-base">
|
<p className="mb-2 text-base">
|
||||||
<strong>{props.totalInvestor.toLocaleString()}</strong> investors
|
<strong>{props.totalInvestor.toLocaleString()}</strong> investors
|
||||||
</p>
|
</p>
|
||||||
<hr className="w-screen -ml-4 mb-2" />
|
<hr className="-ml-4 mb-2" />
|
||||||
<p className="text-xs md:text-base">
|
<p className="text-base">
|
||||||
<strong>${props.minInvestment.toLocaleString()}</strong> min. investment
|
<strong>${props.minInvestment.toLocaleString()}</strong> min. investment
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -79,6 +99,5 @@ export function ExtendableCard(props: ExtendableCardProps) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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,10 +46,8 @@ 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">
|
|
||||||
>(({ className, title, children, ...props }, ref) => {
|
|
||||||
return (
|
return (
|
||||||
<li>
|
<li>
|
||||||
<NavigationMenuLink asChild>
|
<NavigationMenuLink asChild>
|
||||||
@ -59,18 +57,16 @@ const ListItem = React.forwardRef<
|
|||||||
"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",
|
"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
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}>
|
||||||
>
|
|
||||||
<div className="text-sm font-medium leading-none">{title}</div>
|
<div className="text-sm font-medium leading-none">{title}</div>
|
||||||
<hr />
|
<hr />
|
||||||
<p className="line-clamp-2 text-sm leading-snug text-muted-foreground">
|
<p className="line-clamp-2 text-sm leading-snug text-muted-foreground">{children}</p>
|
||||||
{children}
|
|
||||||
</p>
|
|
||||||
</a>
|
</a>
|
||||||
</NavigationMenuLink>
|
</NavigationMenuLink>
|
||||||
</li>
|
</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"
|
||||||
|
|||||||
@ -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 grid-cols-2">
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label htmlFor="name">Name</Label>
|
<Label htmlFor="firstname">First Name</Label>
|
||||||
<Input id="name" placeholder="First Last" />
|
<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>
|
||||||
|
|||||||
36
src/components/siteFooter.tsx
Normal file
36
src/components/siteFooter.tsx
Normal 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">
|
||||||
|
© {new Date().getFullYear()} B2DVentures. All rights reserved.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -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();
|
||||||
});
|
});
|
||||||
Loading…
Reference in New Issue
Block a user