Refactor Portfolio component layout for improved responsiveness; adjust card widths and container padding

This commit is contained in:
Pattadon 2024-10-31 14:22:34 +07:00
parent 8792a94b6b
commit 753603420c
3 changed files with 87 additions and 24 deletions

View File

@ -5,8 +5,20 @@ import ReactMarkdown from "react-markdown";
import * as Tabs from "@radix-ui/react-tabs"; import * as Tabs from "@radix-ui/react-tabs";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel"; import {
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel";
import {
Card,
CardContent,
CardHeader,
CardTitle,
CardDescription,
} from "@/components/ui/card";
import { Progress } from "@/components/ui/progress"; import { Progress } from "@/components/ui/progress";
import { Separator } from "@/components/ui/separator"; import { Separator } from "@/components/ui/separator";
import { createSupabaseClient } from "@/lib/supabase/serverComponentClient"; import { createSupabaseClient } from "@/lib/supabase/serverComponentClient";
@ -14,10 +26,17 @@ import FollowShareButtons from "./followShareButton";
import { getProjectData } from "@/lib/data/projectQuery"; import { getProjectData } from "@/lib/data/projectQuery";
export default async function ProjectDealPage({ params }: { params: { id: number } }) { export default async function ProjectDealPage({
params,
}: {
params: { id: number };
}) {
const supabase = createSupabaseClient(); const supabase = createSupabaseClient();
const { data: projectData, error: projectDataError } = await getProjectData(supabase, params.id); const { data: projectData, error: projectDataError } = await getProjectData(
supabase,
params.id
);
const carouselData = [ const carouselData = [
{ src: "/boiler1.jpg", alt: "Boiler 1" }, { src: "/boiler1.jpg", alt: "Boiler 1" },
@ -28,7 +47,8 @@ export default async function ProjectDealPage({ params }: { params: { id: number
]; ];
if (projectDataError) { if (projectDataError) {
return <div>Error</div>; console.error(projectDataError);
return <div>Error while fetching project data</div>;
} }
return ( return (
@ -39,16 +59,29 @@ export default async function ProjectDealPage({ params }: { params: { id: number
<div id="header" className="flex flex-col"> <div id="header" className="flex flex-col">
<div className="flex justify-between"> <div className="flex justify-between">
<span className="flex"> <span className="flex">
<Image src="/logo.svg" alt="logo" width={50} height={50} className="sm:scale-75" /> <Image
<h1 className="mt-3 font-bold text-lg md:text-3xl">{projectData?.project_name}</h1> 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> </span>
<FollowShareButtons /> <FollowShareButtons />
</div> </div>
{/* end of pack */} {/* end of pack */}
<p className="mt-2 sm:text-sm">{projectData?.project_short_description}</p> <p className="mt-2 sm:text-sm">
{projectData?.project_short_description}
</p>
<div className="flex flex-wrap mt-3"> <div className="flex flex-wrap mt-3">
{projectData?.tags.map((tag, index) => ( {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"> <span
key={index}
className="text-xs rounded-md bg-slate-200 dark:bg-slate-700 p-1 mx-1 mb-1"
>
{tag.tag_name} {tag.tag_name}
</span> </span>
))} ))}
@ -56,12 +89,21 @@ export default async function ProjectDealPage({ params }: { params: { id: number
</div> </div>
<div id="sub-content" className="flex flex-row mt-5"> <div id="sub-content" className="flex flex-row mt-5">
{/* image carousel */} {/* image carousel */}
<div id="image-corousel" className="shrink-0 w-[700px] flex flex-col"> <div
id="image-corousel"
className="shrink-0 w-[700px] flex flex-col"
>
<Carousel className="w-full h-full ml-1"> <Carousel className="w-full h-full ml-1">
<CarouselContent className="flex h-full"> <CarouselContent className="flex h-full">
{carouselData.map((item, index) => ( {carouselData.map((item, index) => (
<CarouselItem key={index}> <CarouselItem key={index}>
<Image src={item.src} alt={item.alt} width={700} height={400} className="rounded-lg" /> <Image
src={item.src}
alt={item.alt}
width={700}
height={400}
className="rounded-lg"
/>
</CarouselItem> </CarouselItem>
))} ))}
</CarouselContent> </CarouselContent>
@ -73,7 +115,13 @@ export default async function ProjectDealPage({ params }: { params: { id: number
<CarouselContent className="flex space-x-1"> <CarouselContent className="flex space-x-1">
{carouselData.map((item, index) => ( {carouselData.map((item, index) => (
<CarouselItem key={index} className="flex"> <CarouselItem key={index} className="flex">
<Image src={item.src} alt={item.alt} width={200} height={100} className="rounded-lg basis-0" /> <Image
src={item.src}
alt={item.alt}
width={200}
height={100}
className="rounded-lg basis-0"
/>
</CarouselItem> </CarouselItem>
))} ))}
</CarouselContent> </CarouselContent>
@ -82,16 +130,26 @@ export default async function ProjectDealPage({ params }: { params: { id: number
<div id="stats" className="flex flex-col w-full mt-4 pl-12"> <div id="stats" className="flex flex-col w-full mt-4 pl-12">
<div className="pl-5"> <div className="pl-5">
<span> <span>
<h1 className="font-semibold text-xl md:text-4xl mt-8">${projectData?.total_investment}</h1> <h1 className="font-semibold text-xl md:text-4xl mt-8">
<p className="text-sm md:text-lg"> 5% raised of \$5M max goal</p> ${projectData?.total_investment}
</h1>
<p className="text-sm md:text-lg">
{" "}
5% raised of \$5M max goal
</p>
<Progress <Progress
value={projectData?.total_investment / projectData?.target_investment} value={
projectData?.total_investment /
projectData?.target_investment
}
className="w-[60%] h-3 mt-3" className="w-[60%] h-3 mt-3"
/> />
</span> </span>
<span> <span>
<h1 className="font-semibold text-4xl md:mt-8"> <h1 className="font-semibold text-4xl md:mt-8">
<p className="text-xl md:text-4xl">{projectData?.total_investment}</p> <p className="text-xl md:text-4xl">
{projectData?.total_investment}
</p>
</h1> </h1>
<p className="text-sm md:text-lg"> Investors</p> <p className="text-sm md:text-lg"> Investors</p>
</span> </span>
@ -102,7 +160,9 @@ export default async function ProjectDealPage({ params }: { params: { id: number
<p> Left to invest</p> <p> Left to invest</p>
</span> </span>
<Button className="mt-5 w-3/4 h-12"> <Button className="mt-5 w-3/4 h-12">
<Link href={`/invest/${params.id}`}>Invest in {projectData?.project_name}</Link> <Link href={`/invest/${params.id}`}>
Invest in {projectData?.project_name}
</Link>
</Button> </Button>
</div> </div>
</div> </div>
@ -125,8 +185,11 @@ export default async function ProjectDealPage({ params }: { params: { id: number
<CardDescription></CardDescription> <CardDescription></CardDescription>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div className="prose prose-sm max-w-none "> <div className="prose prose-sm max-w-none">
<ReactMarkdown>{projectData?.project_description || "No pitch available."}</ReactMarkdown> <ReactMarkdown className="text-black dark:text-white">
{projectData?.project_description ||
"No pitch available."}
</ReactMarkdown>
</div> </div>
</CardContent> </CardContent>
</Card> </Card>

View File

@ -19,7 +19,7 @@ interface Project {
id: number; id: number;
project_name: string; project_name: string;
project_short_description: string; project_short_description: string;
card_image_url: string; project_logo: string;
published_time: string; published_time: string;
business: { location: string }[]; business: { location: string }[];
project_tag: { tag: { id: number; value: string }[] }[]; project_tag: { tag: { id: number; value: string }[] }[];
@ -44,7 +44,7 @@ const TopProjects: FC<TopProjectsProps> = ({ projects }) => {
<ProjectCard <ProjectCard
name={project.project_name} name={project.project_name}
description={project.project_short_description} description={project.project_short_description}
imageUri={project.card_image_url} imageUri={project.project_logo}
joinDate={new Date(project.published_time).toLocaleDateString()} joinDate={new Date(project.published_time).toLocaleDateString()}
location={project.business[0]?.location || ""} location={project.business[0]?.location || ""}
tags={project.project_tag.flatMap( tags={project.project_tag.flatMap(

View File

@ -14,7 +14,7 @@ async function getTopProjects(
business_id, business_id,
published_time, published_time,
project_short_description, project_short_description,
card_image_url, project_logo,
project_investment_detail ( project_investment_detail (
min_investment, min_investment,
total_investment, total_investment,
@ -39,7 +39,7 @@ async function getTopProjects(
console.error("Error fetching top projects:", error.message); console.error("Error fetching top projects:", error.message);
return { data: null, error: error.message }; return { data: null, error: error.message };
} }
// console.log(data);
return { data, error: null }; return { data, error: null };
} catch (err) { } catch (err) {
console.error("Unexpected error:", err); console.error("Unexpected error:", err);
@ -88,7 +88,7 @@ async function getProjectData(client: SupabaseClient, projectId: number) {
target_investment, target_investment,
investment_deadline investment_deadline
), ),
tags:item_tag!inner ( tags:project_tag!inner (
...tag!inner ( ...tag!inner (
tag_name:value tag_name:value
) )