mirror of
https://github.com/Sosokker/B2D-Ventures.git
synced 2025-12-19 05:54:06 +01:00
feat: enhance ImageModal and DisplayFullImage components to support className prop and improve image handling
This commit is contained in:
parent
b3fd664cb4
commit
80b63c02bc
@ -16,26 +16,27 @@ interface ItemProps {
|
||||
alt: string;
|
||||
width: number;
|
||||
height: number;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const ImageModal = ({ src, alt, width, height }: ItemProps) => {
|
||||
const ImageModal = ({ src, alt, width, height, className }: ItemProps) => {
|
||||
return (
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Image src={src} alt={alt} width={width} height={height} className="rounded-lg basis-0" />
|
||||
<Image src={src} alt={alt} width={width} height={height} className={className} />
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Image Preview</DialogTitle>
|
||||
<DialogDescription>Click outside to close the image preview.</DialogDescription>
|
||||
</DialogHeader>
|
||||
<Image src={src} alt={alt} width={700} height={400} />
|
||||
<Image src={src} alt={alt} width={700} height={400} className={className} />
|
||||
<DialogFooter />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export function DisplayFullImage({ src, alt, width, height }: ItemProps) {
|
||||
return <ImageModal src={src} alt={alt} width={width} height={height} />;
|
||||
export function DisplayFullImage({ src, alt, width, height, className }: ItemProps) {
|
||||
return <ImageModal src={src} alt={alt} width={width} height={height} className={className} />;
|
||||
}
|
||||
|
||||
@ -12,16 +12,25 @@ import { Separator } from "@/components/ui/separator";
|
||||
import { createSupabaseClient } from "@/lib/supabase/serverComponentClient";
|
||||
import FollowShareButtons from "./followShareButton";
|
||||
import { DisplayFullImage } from "./displayImage";
|
||||
|
||||
import { getProjectData } from "@/lib/data/projectQuery";
|
||||
import { getDealList } from "@/app/api/dealApi";
|
||||
import { sumByKey, toPercentage } from "@/lib/utils";
|
||||
import { redirect } from "next/navigation";
|
||||
const PHOTO_MATERIAL_ID = 2;
|
||||
|
||||
export default async function ProjectDealPage({ params }: { params: { id: number } }) {
|
||||
const supabase = createSupabaseClient();
|
||||
const { data: projectData, error: projectDataError } = await getProjectData(supabase, params.id);
|
||||
|
||||
const { data: projectMaterial, error: projectMaterialError } = await supabase
|
||||
.from("project_material")
|
||||
.select("material_url")
|
||||
.eq("project_id", params.id)
|
||||
.eq("material_type_id", PHOTO_MATERIAL_ID);
|
||||
// console.log(projectMaterial);
|
||||
if (projectMaterialError) {
|
||||
console.error("Error while fetching project material" + projectMaterialError);
|
||||
}
|
||||
if (!projectData) {
|
||||
redirect("/deals");
|
||||
}
|
||||
@ -44,96 +53,110 @@ export default async function ProjectDealPage({ params }: { params: { id: number
|
||||
const timeDiff = Math.max(new Date(projectData.investment_deadline).getTime() - new Date().getTime(), 0);
|
||||
const hourLeft = Math.floor(timeDiff / (1000 * 60 * 60));
|
||||
|
||||
const carouselData = Array(5).fill({
|
||||
src: projectData.card_image_url || "/boiler1.jpg",
|
||||
alt: `${projectData.project_name} Image`,
|
||||
});
|
||||
// const carouselData = Array(5).fill({
|
||||
// src: projectData.card_image_url || "/boiler1.jpg",
|
||||
// alt: `${projectData.project_name} Image`,
|
||||
// });
|
||||
const carouselData = projectMaterial
|
||||
? projectMaterial.flatMap((item) =>
|
||||
(item.material_url || ["/boiler1.jpg"]).map((url: string) => ({
|
||||
src: url,
|
||||
alt: "Image",
|
||||
}))
|
||||
)
|
||||
: [];
|
||||
|
||||
console.log(carouselData);
|
||||
|
||||
return (
|
||||
<div className="container max-w-screen-xl my-5">
|
||||
<div className="flex flex-col gap-y-10">
|
||||
<div id="content">
|
||||
{/* Name, star and share button packed */}
|
||||
<div id="header" className="flex flex-col">
|
||||
<div className="flex justify-between">
|
||||
<span className="flex">
|
||||
<Image src="/logo.svg" alt="logo" width={50} height={50} className="sm:scale-75" />
|
||||
<h1 className="mt-3 font-bold text-lg md:text-3xl">{projectData?.project_name}</h1>
|
||||
</span>
|
||||
<FollowShareButtons />
|
||||
</div>
|
||||
{/* end of pack */}
|
||||
<p className="mt-2 sm:text-sm">{projectData?.project_short_description}</p>
|
||||
<div className="flex flex-wrap mt-3">
|
||||
{projectData?.tags.map((tag, index) => (
|
||||
<span key={index} className="text-xs rounded-md bg-slate-200 dark:bg-slate-700 p-1 mx-1 mb-1">
|
||||
{tag.tag_name}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
{/* Name, star and share button packed */}
|
||||
<div id="header" className="flex flex-col">
|
||||
<div className="flex justify-between">
|
||||
<span className="flex">
|
||||
<Image src="/logo.svg" alt="logo" width={50} height={50} className="sm:scale-75" />
|
||||
<h1 className="mt-3 font-bold text-lg md:text-3xl">{projectData?.project_name}</h1>
|
||||
</span>
|
||||
<FollowShareButtons />
|
||||
</div>
|
||||
{/* end of pack */}
|
||||
<p className="mt-2 sm:text-sm">{projectData?.project_short_description}</p>
|
||||
<div className="flex flex-wrap mt-3">
|
||||
{projectData?.tags.map((tag, index) => (
|
||||
<span key={index} className="text-xs rounded-md bg-slate-200 dark:bg-slate-700 p-1 mx-1 mb-1">
|
||||
{tag.tag_name}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div id="sub-content" className="flex flex-row mt-5">
|
||||
{/* image carousel */}
|
||||
<div id="image-carousel" className="shrink-0 w-[700px] flex flex-col">
|
||||
{/* first carousel */}
|
||||
<Carousel className="w-full h-[400px] ml-1 overflow-hidden">
|
||||
<CarouselContent className="flex h-full">
|
||||
{carouselData.map((item, index) => (
|
||||
<CarouselItem key={index}>
|
||||
<Image src={item.src} alt={item.alt} width={700} height={400} className="rounded-lg object-cover" />
|
||||
</CarouselItem>
|
||||
))}
|
||||
</CarouselContent>
|
||||
<CarouselPrevious />
|
||||
<CarouselNext />
|
||||
</Carousel>
|
||||
{/* second carousel */}
|
||||
<Carousel className="w-full ml-1 h-[100px] mt-5">
|
||||
<CarouselContent className="flex space-x-1">
|
||||
{carouselData.map((item, index) => (
|
||||
<CarouselItem key={index} className="flex">
|
||||
<DisplayFullImage
|
||||
src={item.src}
|
||||
alt={item.alt}
|
||||
width={200}
|
||||
height={100}
|
||||
className="rounded-lg object-cover basis-0"
|
||||
/>
|
||||
</CarouselItem>
|
||||
))}
|
||||
</CarouselContent>
|
||||
</Carousel>
|
||||
</div>
|
||||
<div id="sub-content" className="flex flex-row mt-5">
|
||||
{/* image carousel */}
|
||||
<div id="image-corousel" className="shrink-0 w-[700px] flex flex-col">
|
||||
<Carousel className="w-full h-full ml-1">
|
||||
<CarouselContent className="flex h-full">
|
||||
{carouselData.map((item, index) => (
|
||||
<CarouselItem key={index}>
|
||||
<Image src={item.src} alt={item.alt} width={700} height={400} className="rounded-lg" />
|
||||
</CarouselItem>
|
||||
))}
|
||||
</CarouselContent>
|
||||
<CarouselPrevious />
|
||||
<CarouselNext />
|
||||
</Carousel>
|
||||
|
||||
<Carousel className="w-full ml-1 h-[100px] mt-5">
|
||||
<CarouselContent className="flex space-x-1">
|
||||
{carouselData.map((item, index) => (
|
||||
<CarouselItem key={index} className="flex">
|
||||
<CarouselItem key={index} className="flex">
|
||||
<DisplayFullImage src="/path/to/image.jpg" alt="Image description" width={300} height={200} />
|
||||
</CarouselItem>
|
||||
</CarouselItem>
|
||||
))}
|
||||
</CarouselContent>
|
||||
</Carousel>
|
||||
</div>
|
||||
<div id="stats" className="flex flex-col w-full mt-4 pl-12">
|
||||
<div className="pl-5">
|
||||
<span>
|
||||
<h1 className="font-semibold text-xl md:text-4xl mt-8">${totalDealAmount}</h1>
|
||||
<p className="text-sm md:text-lg">
|
||||
{toPercentage(totalDealAmount, projectData?.target_investment)}% raised of $
|
||||
{projectData?.target_investment} max goal
|
||||
</p>
|
||||
<Progress
|
||||
value={toPercentage(totalDealAmount, projectData?.target_investment)}
|
||||
className="w-[60%] h-3 mt-3"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
<h1 className="font-semibold text-4xl md:mt-8">
|
||||
<p className="text-xl md:text-4xl">{dealList.length}</p>
|
||||
</h1>
|
||||
<p className="text-sm md:text-lg">Investors</p>
|
||||
</span>
|
||||
<Separator decorative className="mt-3 w-3/4 ml-5" />
|
||||
<span>
|
||||
<h1 className="font-semibold text-xl md:text-4xl mt-8 ml-5"></h1>
|
||||
{projectData?.investment_deadline ? (
|
||||
<>
|
||||
<p className="text-xl md:text-4xl">{Math.floor(hourLeft)} hours</p>
|
||||
<p>Left to invest</p>
|
||||
</>
|
||||
) : (
|
||||
<p className="text-xl md:text-4xl">No deadline</p>
|
||||
)}
|
||||
</span>
|
||||
<Button className="mt-5 w-3/4 h-12">
|
||||
<Link href={`/invest/${params.id}`}>Invest in {projectData?.project_name}</Link>
|
||||
</Button>
|
||||
</div>
|
||||
<div id="stats" className="flex flex-col w-full mt-4 pl-12">
|
||||
<div className="pl-5">
|
||||
<span>
|
||||
<h1 className="font-semibold text-xl md:text-4xl mt-8">${totalDealAmount}</h1>
|
||||
<p className="text-sm md:text-lg">
|
||||
{toPercentage(totalDealAmount, projectData?.target_investment)}% raised of $
|
||||
{projectData?.target_investment} max goal
|
||||
</p>
|
||||
<Progress
|
||||
value={toPercentage(totalDealAmount, projectData?.target_investment)}
|
||||
className="w-[60%] h-3 mt-3"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
<h1 className="font-semibold text-4xl md:mt-8">
|
||||
<p className="text-xl md:text-4xl">{dealList.length}</p>
|
||||
</h1>
|
||||
<p className="text-sm md:text-lg">Investors</p>
|
||||
</span>
|
||||
<Separator decorative className="mt-3 w-3/4 ml-5" />
|
||||
<span>
|
||||
<h1 className="font-semibold text-xl md:text-4xl mt-8 ml-5"></h1>
|
||||
{projectData?.investment_deadline ? (
|
||||
<>
|
||||
<p className="text-xl md:text-4xl">{Math.floor(hourLeft)} hours</p>
|
||||
<p>Left to invest</p>
|
||||
</>
|
||||
) : (
|
||||
<p className="text-xl md:text-4xl">No deadline</p>
|
||||
)}
|
||||
</span>
|
||||
<Button className="mt-5 w-3/4 h-12">
|
||||
<Link href={`/invest/${params.id}`}>Invest in {projectData?.project_name}</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user