82 lines
3.4 KiB
TypeScript
82 lines
3.4 KiB
TypeScript
"use client";
|
|
|
|
import Image from "next/image";
|
|
import { motion } from "framer-motion";
|
|
import { ExternalLink } from "lucide-react";
|
|
import { type Product } from "@/lib/products";
|
|
import { useLanguage } from "@/context/language-context";
|
|
import Link from "next/link";
|
|
import { useProduct, useProductStore } from "@/lib/productZustand";
|
|
|
|
interface ProductCardProps {
|
|
product: Product;
|
|
}
|
|
|
|
export function ProductCard({ product }: ProductCardProps) {
|
|
const { t, language } = useLanguage();
|
|
const languageIndex = language === "uz" ? true : false;
|
|
const setProductName = useProductStore((state) => state.setProductName);
|
|
const setProducts = useProduct((state) => state.setProducts);
|
|
return (
|
|
<Link
|
|
href={`/detail?${languageIndex ? product.name_uz : product.name_ru}`}
|
|
onClick={() => {
|
|
setProductName(languageIndex ? product.name_uz : product.name_ru);
|
|
setProducts(product);
|
|
}}
|
|
>
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 20 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
transition={{ duration: 0.3 }}
|
|
className="group relative h-full flex flex-col bg-white rounded-2xl overflow-hidden shadow-md hover:shadow-2xl transition-all duration-300 border border-gray-100"
|
|
>
|
|
{/* Image Container - Fixed Height */}
|
|
<div className="relative w-full h-64 overflow-hidden bg-linear-to-br from-gray-50 to-gray-100">
|
|
<motion.div
|
|
whileHover={{ scale: 1.05 }}
|
|
transition={{ duration: 0.4 }}
|
|
className="w-full h-full relative"
|
|
>
|
|
<Image
|
|
src={`https://admin.promtechno.uz${product.image}`}
|
|
alt={languageIndex ? product.name_uz : product.name_ru}
|
|
fill
|
|
className="w-full h-full object-cover"
|
|
/>
|
|
</motion.div>
|
|
|
|
{/* Gradient Overlay */}
|
|
<div className="absolute inset-0 bg-linear-to-t from-black/20 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
|
|
</div>
|
|
|
|
{/* Content Container - Flex Grow */}
|
|
<div className="flex flex-col grow p-6">
|
|
{/* Product Name */}
|
|
<h3 className="text-xl font-bold text-gray-900 mb-3 line-clamp-2 group-hover:text-primary transition-colors duration-300">
|
|
{languageIndex ? product.name_uz : product.name_ru}
|
|
</h3>
|
|
|
|
{/* Short Description - Fixed Height with Line Clamp */}
|
|
<p className="text-gray-600 text-sm leading-relaxed mb-4 line-clamp-3 grow">
|
|
{languageIndex ? product.name_uz : product.name_ru}
|
|
</p>
|
|
|
|
{/* CTA Button - Always at Bottom */}
|
|
<motion.button
|
|
whileHover={{ scale: 1.02 }}
|
|
whileTap={{ scale: 0.98 }}
|
|
className="w-full flex items-center justify-center gap-2 px-6 py-3 bg-primary text-white rounded-xl font-semibold shadow-lg shadow-blue-500/30 hover:shadow-xl hover:shadow-primary/40 transition-all duration-300 group/button"
|
|
>
|
|
<span>{t.details}</span>
|
|
<ExternalLink className="w-4 h-4 group-hover/button:translate-x-1 transition-transform duration-300" />
|
|
</motion.button>
|
|
</div>
|
|
|
|
{/* Decorative Corner */}
|
|
<div className="absolute top-0 right-0 w-20 h-20 bg-linear-to-br from-blue-500/10 to-transparent rounded-bl-full opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
|
|
</motion.div>
|
|
</Link>
|
|
);
|
|
}
|