Merge branch 'develop'
This commit is contained in:
commit
91050ae491
@ -52,16 +52,16 @@ function ProductCard({ product, priority = false }: { product: Product; priority
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.3, ease: "easeOut" }}
|
||||
onClick={() => router.push(`/shop/${product.slug || product.id}`)}
|
||||
className="group bg-white/90 backdrop-blur-md rounded-2xl sm:rounded-3xl border border-medical-gray-200/80 overflow-hidden hover:shadow-xl hover:shadow-canina-blue/10 hover:border-canina-blue/30 transition-all duration-300 flex flex-col cursor-pointer relative"
|
||||
className="group bg-white/90 backdrop-blur-md rounded-2xl sm:rounded-3xl border border-medical-gray-200/80 overflow-hidden hover:shadow-xl hover:shadow-canina-blue/10 hover:border-canina-blue/30 transition-all duration-300 flex flex-col cursor-pointer relative w-full"
|
||||
>
|
||||
{/* Category Badge */}
|
||||
<div className="absolute top-3 right-3 sm:top-4 sm:right-4 z-30 px-2.5 py-1 bg-white/90 backdrop-blur-md rounded-full border border-medical-gray-200/80 text-2xs sm:text-xs font-black text-medical-gray-700 uppercase tracking-wider shadow-xs group-hover:bg-canina-blue group-hover:text-white transition-all">
|
||||
<div className="absolute top-2.5 right-2.5 sm:top-4 sm:right-4 z-30 px-2 py-0.5 sm:px-2.5 sm:py-1 bg-white/90 backdrop-blur-md rounded-full border border-medical-gray-200/80 text-[10px] sm:text-xs font-black text-medical-gray-700 uppercase tracking-wider shadow-xs group-hover:bg-canina-blue group-hover:text-white transition-all">
|
||||
{product.category}
|
||||
</div>
|
||||
|
||||
{/* Compatibility Tag */}
|
||||
{compatibility && (
|
||||
<div className={`absolute top-[2.8rem] sm:top-[3.25rem] right-3 sm:right-4 z-10 text-3xs font-black uppercase tracking-widest px-2.5 py-0.5 rounded-full shadow-xs flex items-center gap-1 ${
|
||||
<div className={`absolute top-[2.4rem] sm:top-[3.25rem] right-2.5 sm:right-4 z-10 text-[9px] sm:text-3xs font-black uppercase tracking-widest px-2 py-0.5 sm:px-2.5 sm:py-0.5 rounded-full shadow-xs flex items-center gap-1 ${
|
||||
compatibility.type === "alert" ? "bg-amber-100 text-amber-700" :
|
||||
compatibility.type === "success" ? "bg-green-100 text-green-700" : "bg-medical-gray-100 text-medical-gray-600"
|
||||
}`}>
|
||||
@ -88,26 +88,26 @@ function ProductCard({ product, priority = false }: { product: Product; priority
|
||||
)}
|
||||
|
||||
{/* Image Container */}
|
||||
<div className="relative aspect-[16/11] sm:aspect-[4/3] bg-medical-gray-50 flex items-center justify-center overflow-hidden p-1 sm:p-2">
|
||||
<div className="relative aspect-[16/11] sm:aspect-[4/3] bg-medical-gray-50 flex items-center justify-center overflow-hidden p-2 sm:p-3">
|
||||
<SafeImage
|
||||
src={product.image}
|
||||
alt={nameFa}
|
||||
priority={priority}
|
||||
sizes="(max-width: 640px) 180px, (max-width: 1024px) 240px, 280px)"
|
||||
sizes="(max-width: 640px) 240px, (max-width: 1024px) 240px, 280px)"
|
||||
className="w-full h-full group-hover:scale-105 transition-transform duration-500"
|
||||
imgClassName="object-contain w-full h-full max-h-[160px] sm:max-h-[200px] mx-auto"
|
||||
imgClassName="object-contain w-full h-full max-h-[130px] sm:max-h-[200px] mx-auto"
|
||||
/>
|
||||
|
||||
{/* Species Badges (Dog / Cat) */}
|
||||
<div className="absolute bottom-2 left-2 flex gap-1 z-10">
|
||||
{forDog && (
|
||||
<div className="w-6 h-6 bg-white/90 backdrop-blur-xs rounded-md flex items-center justify-center text-medical-gray-500 border border-medical-gray-200 shadow-2xs" title="مناسب برای سگ">
|
||||
<Dog className="w-3.5 h-3.5 text-canina-blue" />
|
||||
<div className="w-5 h-5 sm:w-6 sm:h-6 bg-white/90 backdrop-blur-xs rounded-md flex items-center justify-center text-medical-gray-500 border border-medical-gray-200 shadow-2xs" title="مناسب برای سگ">
|
||||
<Dog className="w-3 h-3 sm:w-3.5 sm:h-3.5 text-canina-blue" />
|
||||
</div>
|
||||
)}
|
||||
{forCat && (
|
||||
<div className="w-6 h-6 bg-white/90 backdrop-blur-xs rounded-md flex items-center justify-center text-medical-gray-500 border border-medical-gray-200 shadow-2xs" title="مناسب برای گربه">
|
||||
<Cat className="w-3.5 h-3.5 text-canina-blue" />
|
||||
<div className="w-5 h-5 sm:w-6 sm:h-6 bg-white/90 backdrop-blur-xs rounded-md flex items-center justify-center text-medical-gray-500 border border-medical-gray-200 shadow-2xs" title="مناسب برای گربه">
|
||||
<Cat className="w-3 h-3 sm:w-3.5 sm:h-3.5 text-canina-blue" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@ -137,35 +137,35 @@ function ProductCard({ product, priority = false }: { product: Product; priority
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="px-3.5 py-3 sm:px-5 sm:py-4 flex flex-col flex-1 gap-2 sm:gap-3">
|
||||
<div className="p-3 sm:px-5 sm:py-4 flex flex-col flex-1 gap-1.5 sm:gap-3">
|
||||
{/* Dual-language Name */}
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<h3 dir="rtl" className="text-xs sm:text-sm font-black text-medical-gray-900 group-hover:text-canina-blue transition-colors leading-snug text-right line-clamp-1 sm:line-clamp-2 font-vazir">
|
||||
{nameFa}
|
||||
</h3>
|
||||
{nameEn && (
|
||||
<span dir="ltr" className="text-2xs sm:text-xs-plus font-semibold text-slate-400 font-sans text-left block line-clamp-1">
|
||||
<span dir="ltr" className="text-[10px] sm:text-xs-plus font-semibold text-slate-400 font-sans text-left block line-clamp-1">
|
||||
{nameEn}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Short description */}
|
||||
<p className="text-xs-plus sm:text-xs text-medical-gray-500 leading-relaxed line-clamp-1 sm:line-clamp-2 flex-1">
|
||||
<p className="text-[11px] sm:text-xs text-medical-gray-500 leading-relaxed line-clamp-2 flex-1">
|
||||
{product.shortDescription || (product.description ? product.description.replace(/<[^>]*>/g, '') : '')}
|
||||
</p>
|
||||
|
||||
{/* Footer: Price + CTA */}
|
||||
<div className="flex items-center justify-between pt-2 sm:pt-3 border-t border-medical-gray-100">
|
||||
<div className="flex items-center justify-between pt-2 sm:pt-3 border-t border-medical-gray-100 mt-auto">
|
||||
<div className="text-xs sm:text-sm md:text-base font-black text-medical-gray-900 font-vazir whitespace-nowrap">
|
||||
{showPrices ? (typeof product.price === 'string' || typeof product.price === 'number' ? String(product.price) : 'تماس بگیرید') : 'تماس بگیرید'}
|
||||
</div>
|
||||
{showPreorderBtn ? (
|
||||
<span className="text-2xs sm:text-xs-plus font-black text-amber-600 bg-amber-50 px-2.5 py-1 rounded-full border border-amber-200">
|
||||
<span className="text-[10px] sm:text-xs-plus font-black text-amber-600 bg-amber-50 px-2 py-0.5 sm:px-2.5 sm:py-1 rounded-full border border-amber-200">
|
||||
ثبت پیشخرید
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-2xs sm:text-xs-plus font-black text-canina-blue uppercase tracking-wider border-b border-canina-blue pb-0.5 group-hover:text-medical-gray-900 group-hover:border-medical-gray-900 transition-all whitespace-nowrap">
|
||||
<span className="text-[10px] sm:text-xs-plus font-black text-canina-blue uppercase tracking-wider border-b border-canina-blue pb-0.5 group-hover:text-medical-gray-900 group-hover:border-medical-gray-900 transition-all whitespace-nowrap">
|
||||
{getText("product_view_details", "مشاهده جزئیات")}
|
||||
</span>
|
||||
)}
|
||||
@ -210,13 +210,21 @@ export default function FeaturedProducts() {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
<div className="flex md:grid md:grid-cols-2 lg:grid-cols-4 gap-4 md:gap-6 overflow-x-auto md:overflow-visible pb-4 md:pb-0 micro-hscroll -mx-4 px-4 md:mx-0 md:px-0 select-none touch-pan-x snap-x snap-mandatory md:snap-none">
|
||||
{isLoading ? (
|
||||
Array.from({ length: 4 }).map((_, i) => <ProductCardSkeleton key={i} />)
|
||||
Array.from({ length: 4 }).map((_, i) => (
|
||||
<div key={i} className="w-[68vw] sm:w-[50vw] md:w-auto flex-shrink-0 snap-start">
|
||||
<ProductCardSkeleton />
|
||||
</div>
|
||||
))
|
||||
) : products.length > 0 ? (
|
||||
products.map((p, i) => <ProductCard key={p.id} product={p} priority={i < 2} />)
|
||||
products.map((p, i) => (
|
||||
<div key={p.id} className="w-[68vw] sm:w-[50vw] md:w-auto flex-shrink-0 snap-start flex">
|
||||
<ProductCard product={p} priority={i < 2} />
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<div className="col-span-full py-16 px-8 flex flex-col items-center justify-center text-center bg-white rounded-[2.5rem] border border-medical-gray-200 shadow-xl max-w-lg mx-auto">
|
||||
<div className="col-span-full py-16 px-8 flex flex-col items-center justify-center text-center bg-white rounded-[2.5rem] border border-medical-gray-200 shadow-xl max-w-lg mx-auto w-full">
|
||||
<AlertCircle className="w-12 h-12 text-canina-teal mb-4" />
|
||||
<h3 className="text-xl font-black text-medical-gray-900 mb-2 font-vazir">
|
||||
{getText("featured_no_products_title", "هیچ محصولی یافت نشد")}
|
||||
|
||||
2
graphify-out/cache/stat-index.json
vendored
2
graphify-out/cache/stat-index.json
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user