178 lines
6.5 KiB
TypeScript
178 lines
6.5 KiB
TypeScript
import { Card } from "@/components/ui/card";
|
|
import { Separator } from "@/components/ui/separator";
|
|
import { Star, Package, Tag, Palette } from "lucide-react";
|
|
|
|
interface ProductProperty {
|
|
name: string;
|
|
value: string;
|
|
}
|
|
|
|
interface ProductInfoCardProps {
|
|
name: string;
|
|
brandName?: string;
|
|
stock?: number;
|
|
barcode?: string;
|
|
colour?: string;
|
|
properties?: ProductProperty[];
|
|
description?: string;
|
|
averageRating: number;
|
|
reviewsCount: number;
|
|
t: (key: string, params?: any) => string;
|
|
}
|
|
|
|
export function ProductInfoCard({
|
|
name,
|
|
brandName,
|
|
stock,
|
|
barcode,
|
|
colour,
|
|
properties,
|
|
description,
|
|
averageRating,
|
|
reviewsCount,
|
|
t,
|
|
}: ProductInfoCardProps) {
|
|
return (
|
|
<div className="flex-1 space-y-6 bg-transparent">
|
|
{/* Main Info Card */}
|
|
<Card className="p-3 md:p-6 rounded-lg border border-gray-200 shadow-sm hover:shadow-md transition-shadow duration-300 gap-0">
|
|
<div className="">
|
|
<h1 className="text-3xl font-bold text-gray-900 leading-tight mb-3">
|
|
{name}
|
|
</h1>
|
|
|
|
{/* Rating Section */}
|
|
{reviewsCount > 0 && (
|
|
<div className="flex items-center gap-3 pt-2">
|
|
<div className="flex items-center gap-1.5">
|
|
{Array.from({ length: 5 }).map((_, idx) => (
|
|
<Star
|
|
key={idx}
|
|
className={`h-5 w-5 ${
|
|
idx < Math.floor(averageRating)
|
|
? "fill-amber-400 text-amber-400"
|
|
: "fill-gray-200 text-gray-200"
|
|
}`}
|
|
/>
|
|
))}
|
|
</div>
|
|
<span className="text-sm font-semibold text-gray-900">
|
|
{averageRating.toFixed(1)}
|
|
</span>
|
|
<span className="text-sm text-gray-500">
|
|
({reviewsCount} {t("reviews")})
|
|
</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<Separator className="my-6 bg-gray-100" />
|
|
|
|
{/* Specifications */}
|
|
<div className="space-y-1">
|
|
{brandName && (
|
|
<>
|
|
<div className="flex justify-between items-center py-3.5 px-4 rounded-xl hover:bg-gray-50 transition-colors group">
|
|
<div className="flex items-center gap-3">
|
|
<div className="h-9 w-9 rounded-xl bg-gray-100 group-hover:bg-gray-200 flex items-center justify-center transition-colors">
|
|
<Package className="h-4.5 w-4.5 text-gray-700" />
|
|
</div>
|
|
<span className="text-gray-600 font-medium">
|
|
{t("brands")}
|
|
</span>
|
|
</div>
|
|
<span className="font-semibold text-gray-900">{brandName}</span>
|
|
</div>
|
|
<Separator className="bg-gray-100" />
|
|
</>
|
|
)}
|
|
|
|
{colour && (
|
|
<>
|
|
<div className="flex justify-between items-center py-3.5 px-4 rounded-xl hover:bg-gray-50 transition-colors group">
|
|
<div className="flex items-center gap-3">
|
|
<div className="h-9 w-9 rounded-xl bg-gray-100 group-hover:bg-gray-200 flex items-center justify-center transition-colors">
|
|
<Palette className="h-4.5 w-4.5 text-gray-700" />
|
|
</div>
|
|
<span className="text-gray-600 font-medium">
|
|
{t("color")}
|
|
</span>
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<span className="font-semibold text-gray-900">{colour}</span>
|
|
</div>
|
|
</div>
|
|
<Separator className="bg-gray-100" />
|
|
</>
|
|
)}
|
|
|
|
{properties && properties.length > 0 && (
|
|
<>
|
|
{properties.map(
|
|
(prop, idx) =>
|
|
prop.value && (
|
|
<div key={idx}>
|
|
<div className="flex justify-between items-center py-3.5 px-4 rounded-xl hover:bg-gray-50 transition-colors group">
|
|
<div className="flex items-center gap-3">
|
|
<div className="h-9 w-9 rounded-xl bg-gray-100 group-hover:bg-gray-200 flex items-center justify-center transition-colors">
|
|
<Tag className="h-4.5 w-4.5 text-gray-700" />
|
|
</div>
|
|
<span className="text-gray-600 font-medium">
|
|
{prop.name}
|
|
</span>
|
|
</div>
|
|
<span className="font-semibold text-gray-900 text-right max-w-[200px] truncate">
|
|
{prop.value}
|
|
</span>
|
|
</div>
|
|
{idx < properties.length - 1 && (
|
|
<Separator className="bg-gray-100" />
|
|
)}
|
|
</div>
|
|
),
|
|
)}
|
|
</>
|
|
)}
|
|
</div>
|
|
</Card>
|
|
|
|
{/* Description Card */}
|
|
{description && (
|
|
<Card className="p-8 rounded-3xl border border-gray-200 shadow-sm hover:shadow-md transition-shadow duration-300">
|
|
<div className="flex items-center gap-3 mb-6">
|
|
<div className="h-10 w-10 rounded-xl bg-gray-900 flex items-center justify-center">
|
|
<svg
|
|
className="h-5 w-5 text-white"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<h3 className="text-2xl font-bold text-gray-900">
|
|
{t("product_description")}
|
|
</h3>
|
|
</div>
|
|
|
|
<div
|
|
className="text-gray-700 leading-relaxed prose prose-sm max-w-none
|
|
prose-headings:text-gray-900 prose-headings:font-bold
|
|
prose-p:text-gray-700 prose-p:leading-relaxed
|
|
prose-ul:text-gray-700 prose-ol:text-gray-700
|
|
prose-li:text-gray-700 prose-li:leading-relaxed
|
|
prose-strong:text-gray-900 prose-strong:font-semibold
|
|
prose-a:text-gray-900 prose-a:font-medium hover:prose-a:text-gray-700"
|
|
dangerouslySetInnerHTML={{ __html: description }}
|
|
/>
|
|
</Card>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|