canina/frontend/application/components/ProductPage.tsx
parsa aghaei 7615aa0e51 fix: resolve seed encoding, search param, and wiki data source issues
- Fix seed-products.ts TS error (implicit any) and BOM handling
- Re-run full seed to restore correct Persian encoding in DB
- Fix productService query→search param mismatch
- Fix IngredientWiki hardcoded port 4000→use settingsStore
- Restore seed-products-data.json from git after accidental corruption
2026-07-11 15:40:49 +03:30

637 lines
33 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { useState, useMemo, useEffect } from "react";
import { motion, AnimatePresence } from "motion/react";
import {
ArrowRight,
Calculator as CalcIcon,
ChevronLeft,
ShieldCheck,
CheckCircle2,
Clock,
FlaskConical,
Stethoscope,
Info,
CalendarDays,
Dog,
Gamepad2,
X,
Plus,
Minus,
Bell,
Sparkles,
ChevronRight,
ChevronDown,
Activity,
Heart,
Zap,
Flame,
Star,
Users,
ShoppingBag
} from "lucide-react";
const ICON_MAP: Record<string, any> = {
Sparkles,
Activity,
ShieldCheck,
Heart,
Zap,
Flame,
Star,
Users
};
import { toPersian, cn } from "../lib/utils";
import { Product, PRODUCTS } from "../lib/data/products";
import { productService } from "../lib/services/productService";
import { SCIENTIFIC_TERMS } from "../lib/data/scientificTerms";
import { useSettingsStore } from "../lib/store/settingsStore";
import { create } from "zustand";
import { useCartStore } from "../lib/store/cartStore";
import { usePetStore } from "../lib/store/usePetStore";
import { toast } from "sonner";
interface CalculatorState {
petType: "young" | "adult";
weight: number;
setPetType: (type: "young" | "adult") => void;
setWeight: (weight: number) => void;
}
const useCalculatorStore = create<CalculatorState>((set) => ({
petType: "young",
weight: 10,
setPetType: (petType) => set({ petType }),
setWeight: (weight) => set({ weight }),
}));
import Tooltip from "./Tooltip";
import SafeImage from "./SafeImage";
import { useRouter } from 'next/navigation';
export default function ProductPage({ productSlug }: { productSlug: string }) {
const router = useRouter();
const [product, setProduct] = useState<Product | null>(null);
const [isLoading, setIsLoading] = useState(true);
const [activeTab, setActiveTab] = useState<"specs" | "feeding" | "notes">("specs");
const [showRefillModal, setShowRefillModal] = useState(false);
const [itemQuantity, setItemQuantity] = useState(1);
const [allProducts, setAllProducts] = useState<Product[]>([]);
useEffect(() => {
productService.getProducts()
.then((products) => {
setAllProducts(products);
const found = products.find(p => p.slug === productSlug || p.id === productSlug);
setProduct(found || null);
})
.catch(err => console.error("Error fetching products in ProductPage:", err))
.finally(() => setIsLoading(false));
}, [productSlug]);
const { pets, getActivePet } = usePetStore();
const activePet = getActivePet();
const { petType, weight, setPetType, setWeight } = useCalculatorStore();
const { addItem } = useCartStore();
const scientificTerms = useSettingsStore(state => state.scientificTerms);
const termKeys = useMemo(() => {
return Array.from(new Set([
...Object.keys(scientificTerms),
...Object.keys(SCIENTIFIC_TERMS)
]));
}, [scientificTerms]);
// Re-hydrate product to ensure methods like calculateDosage exist
const fullProduct = useMemo(() => {
if (!product) return null;
const apiProduct = allProducts.find(p => p.id === product.id) || product;
if (!apiProduct) return null;
const staticProduct = PRODUCTS.find(p => p.id === apiProduct.id || p.artNo === apiProduct.artNo);
if (staticProduct) {
return {
...apiProduct,
calculateDosage: staticProduct.calculateDosage
};
}
if (typeof apiProduct.calculateDosage !== 'function') {
return {
...apiProduct,
calculateDosage: (w: number, y: boolean) => {
return {
quantity: 1,
unit: apiProduct.unit || "قرص",
description: "مصرف روزانه بر اساس دستور پزشک"
};
}
};
}
return apiProduct;
}, [product, allProducts]);
useEffect(() => {
if (activePet) {
setWeight(activePet.weight);
setPetType(activePet.age <= 1 ? "young" : "adult");
}
}, [activePet, setWeight, setPetType]);
const calculation = useMemo(() => {
if (!fullProduct || typeof fullProduct.calculateDosage !== 'function') return null;
const result = fullProduct.calculateDosage(weight, petType === "young");
const duration = Math.floor(fullProduct.packageSize / result.quantity);
return {
dailyDose: result.quantity,
duration: duration || 0,
unit: result.unit,
description: result.description
};
}, [fullProduct, petType, weight]);
// Suggest quantity inside useEffect to avoid render-phase state update
useEffect(() => {
const duration = calculation?.duration ?? 0;
const suggestedQty = (duration < 30 && duration > 0) ? 2 : 1;
setItemQuantity(suggestedQty);
}, [calculation?.duration]);
if (isLoading) return <div className="min-h-screen flex items-center justify-center">Loading...</div>;
if (!product || !fullProduct || !calculation) return <div className="min-h-screen flex items-center justify-center">محصول یافت نشد</div>;
return (
<div className="min-h-screen bg-medical-gray-50 pt-2 pb-20 px-4 md:px-0" dir="rtl">
<div className="max-w-7xl mx-auto">
{/* Mobile Header with Back Button */}
<div className="flex items-center justify-between mb-6 md:hidden">
<button
onClick={() => router.back()}
className="p-3 bg-white border border-medical-gray-200 rounded-2xl text-medical-gray-700 shadow-sm flex items-center gap-2 font-vazir text-sm font-bold"
>
<ChevronRight className="w-5 h-5" />
بازگشت
</button>
<div className="text-[10px] font-black text-canina-blue bg-canina-blue/5 px-4 py-2 rounded-xl font-vazir whitespace-nowrap">
کانینا ایران
</div>
</div>
{/* Breadcrumbs */}
<nav className="hidden md:flex items-center gap-2 text-xs font-bold text-medical-gray-400 mb-8 overflow-x-auto whitespace-nowrap py-2">
<button
onClick={() => router.push('/')}
className="hover:text-canina-blue transition-colors font-vazir cursor-pointer"
>
خانه
</button>
<ChevronLeft className="w-3 h-3 flex-shrink-0" />
<button
onClick={() => router.push(`/shop?category=${product.categorySlug}`)}
className="hover:text-canina-blue cursor-pointer font-vazir"
>
{product.category}
</button>
<ChevronLeft className="w-3 h-3 flex-shrink-0" />
<span className="text-canina-blue font-vazir whitespace-nowrap">{product.name}</span>
</nav>
<div className="grid lg:grid-cols-12 gap-12 items-start">
{/* Main Content Area */}
<div className="lg:col-span-8 space-y-12">
<div>
<div className="flex flex-wrap items-center gap-3 mb-4">
<div className="px-3 py-1 bg-canina-blue text-white rounded-full text-[10px] font-black uppercase tracking-widest font-vazir whitespace-nowrap">
استاندارد صنعتی آلمان
</div>
{product.specialBadge && (
<div className="px-3 py-1 bg-medical-gray-900 text-white rounded-full text-[10px] font-black uppercase tracking-widest font-vazir whitespace-nowrap">
{product.specialBadge}
</div>
)}
</div>
<h1 className="text-4xl lg:text-6xl font-black text-medical-gray-900 leading-tight mb-4 italic font-vazir">
{product.name}
</h1>
<p className="text-xl text-canina-blue font-bold italic opacity-70 leading-relaxed max-w-2xl font-vazir mb-6">
{pets.length > 0 ? (
product.optimisticTemplate?.replace("[PetName]", activePet?.name || "").replace("[OnSet]", product.onSetOfAction || "به زودی")
) : (
product.scientificTagline
)}
</p>
{fullProduct.shortDescription && (
<p className="text-lg text-medical-gray-600 font-medium leading-relaxed max-w-3xl font-vazir border-r-4 border-canina-blue pr-6 py-2 bg-canina-blue/5 rounded-l-2xl">
{fullProduct.shortDescription}
</p>
)}
</div>
{/* Key Benefits Section */}
{fullProduct.keyBenefits?.length > 0 && (
<section className="space-y-8">
<div className="flex items-center gap-4">
<div className="w-12 h-12 bg-canina-blue text-white rounded-2xl flex items-center justify-center shadow-lg">
<Star className="w-6 h-6" />
</div>
<h3 className="text-3xl font-black text-medical-gray-900 italic font-vazir">چرا {fullProduct.name}؟</h3>
</div>
<div className="grid md:grid-cols-3 gap-6">
{fullProduct.keyBenefits.map((benefit, i) => {
const Icon = ICON_MAP[benefit.icon] || CheckCircle2;
return (
<div key={i} className="bg-white border border-medical-gray-100 rounded-[2rem] p-8 shadow-sm hover:shadow-xl hover:-translate-y-1 transition-all group overflow-hidden relative">
<div className="absolute -top-10 -left-10 w-24 h-24 bg-canina-blue/5 rounded-full group-hover:scale-150 transition-transform duration-700" />
<div className="w-12 h-12 bg-medical-gray-50 rounded-2xl flex items-center justify-center text-canina-blue mb-6 group-hover:bg-canina-blue group-hover:text-white transition-all">
<Icon className="w-6 h-6" />
</div>
<h4 className="text-xl font-black text-medical-gray-900 mb-2 font-vazir">{benefit.title}</h4>
<p className="text-sm text-medical-gray-500 font-bold font-vazir">{benefit.description}</p>
</div>
);
})}
</div>
</section>
)}
<motion.div
initial={{ opacity: 0, scale: 0.95 }}
animate={{ opacity: 1, scale: 1 }}
className="bg-white rounded-[3.5rem] p-12 border border-medical-gray-200 shadow-xl relative group overflow-hidden"
>
<div className="absolute top-6 left-6 flex flex-col gap-2 z-10">
<div className="px-3 py-1 bg-green-50 text-green-600 rounded-full text-[10px] font-black uppercase tracking-widest border border-green-100 flex items-center gap-1 font-vazir">
<CheckCircle2 className="w-3 h-3" />
موجود در انبار
</div>
<div className="px-3 py-1 bg-canina-blue/5 text-canina-blue rounded-full text-[10px] font-black uppercase tracking-widest border border-canina-blue/10 font-vazir whitespace-nowrap">
گرید دارویی اختصاصی
</div>
</div>
<SafeImage
src={product.image}
alt={product.name}
className="w-full max-w-md mx-auto h-auto drop-shadow-2xl group-hover:scale-105 transition-transform duration-700"
/>
</motion.div>
{/* Ingredients Section */}
<section className="space-y-8">
<div className="flex items-center gap-4">
<div className="w-12 h-12 bg-medical-gray-900 text-white rounded-2xl flex items-center justify-center shadow-lg">
<FlaskConical className="w-6 h-6" />
</div>
<h3 className="text-3xl font-black text-medical-gray-900 italic font-vazir">ترکیبات و آنالیز علمی</h3>
</div>
<div className="space-y-10">
{/* Ingredients Cards */}
<div className="bg-white rounded-[2.5rem] p-8 border border-medical-gray-200">
<h4 className="text-xs font-black text-medical-gray-400 uppercase tracking-widest mb-6 font-vazir">مواد تشکیلدهنده برتر</h4>
<div className="flex flex-wrap gap-3">
{product.main_ingredients.map((ing, idx) => {
const termKey = termKeys.find(key => ing.includes(key));
return (
<div key={idx} className="bg-medical-gray-50 border border-medical-gray-100 px-5 py-3 rounded-2xl flex items-center gap-3 group hover:border-canina-blue/30 transition-all">
<span className="text-sm font-bold text-medical-gray-700 font-vazir">
{termKey ? (
<Tooltip termKey={termKey} onWikiNavigate={(id) => router.push(`/wiki?term=${id}`)}>
{ing}
</Tooltip>
) : ing}
</span>
<Sparkles className="w-3 h-3 text-canina-blue opacity-40 group-hover:opacity-100 transition-opacity" />
</div>
);
})}
</div>
</div>
{/* Analysis Cards Grid */}
{Object.keys(product.analysis).length > 0 && (
<div className="space-y-6">
<div className="text-[10px] font-black text-medical-gray-400 uppercase tracking-widest mb-4 font-vazir">تخمین اتمام بسته (هوش مصنوعی)</div>
<div className="grid grid-cols-2 gap-4">
{Object.entries(product.analysis).map(([key, value]) => (
<div key={key} className="bg-canina-blue text-white p-8 rounded-[2rem] border-b-2 border-white/20 shadow-xl group hover:scale-[1.02] transition-all duration-300">
<div className="text-[10px] font-black text-white/80 uppercase tracking-widest mb-3 font-vazir whitespace-nowrap">{key}</div>
<div className="text-3xl font-black font-vazir tracking-tighter text-white">{toPersian(value)}</div>
</div>
))}
</div>
</div>
)}
</div>
</section>
{/* Feeding Section */}
<section className="bg-canina-blue/5 border border-canina-blue/10 rounded-[3rem] p-10">
<div className="flex items-center gap-4 mb-8">
<div className="w-10 h-10 bg-canina-blue text-white rounded-xl flex items-center justify-center">
<CalendarDays className="w-6 h-6" />
</div>
<h3 className="text-2xl font-black text-medical-gray-900 italic font-vazir">توصیه غذایی و نحوه مصرف</h3>
</div>
<p className="text-medical-gray-700 leading-relaxed text-sm md:text-base font-medium font-vazir">
{product.feedingAdvice}
</p>
</section>
{/* Specialist Note */}
{product.specialist && (
<section className="bg-white rounded-[3rem] p-10 border border-medical-gray-200">
<div className="flex flex-col md:flex-row gap-10 items-start">
<img
src={product.specialist.image}
alt={product.specialist.name}
className="w-32 h-32 rounded-[2.5rem] object-cover border-4 border-medical-gray-50 shadow-xl"
/>
<div className="flex-1">
<div className="inline-flex items-center gap-2 px-3 py-1 bg-medical-gray-900 text-white rounded-full text-[10px] font-black uppercase tracking-widest mb-4 font-vazir whitespace-nowrap">
<Stethoscope className="w-3 h-3" />
مورد تأیید دامپزشکان
</div>
<h4 className="text-2xl font-black text-medical-gray-900 mb-1 font-vazir">{product.specialist.name}</h4>
<p className="text-sm font-bold text-canina-blue mb-6 font-vazir">{product.specialist.title}</p>
<p className="text-base text-medical-gray-600 leading-relaxed italic font-vazir">
"{product.specialist.message}"
</p>
</div>
</div>
</section>
)}
{/* Specialized Landing Banner */}
<section>
<div
className="relative bg-canina-blue rounded-[3rem] p-12 overflow-hidden group cursor-pointer"
onClick={() => toast.info("بزودی: صفحه فرود تخصصی این محصول در حال آماده‌سازی است")}
>
<div className="absolute top-0 right-0 w-full h-full bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] opacity-10" />
<div className="absolute -bottom-20 -left-20 w-80 h-80 bg-white/10 rounded-full blur-3xl group-hover:bg-white/20 transition-all duration-700" />
<div className="relative z-10 flex flex-col md:flex-row items-center justify-between gap-8">
<div className="text-center md:text-right">
<h3 className="text-3xl lg:text-4xl font-black text-white mb-4 italic">مشاهده بررسی تخصصی و نتایج درمانی</h3>
<p className="text-white/80 font-bold font-vazir max-w-lg">
گزارشهای علمی، ویدیوهای آموزشی و تجربیات واقعی دیگر صاحبان پت در لندینگپیج اختصاصی این محصول.
</p>
</div>
<div className="bg-white text-canina-blue px-8 py-4 rounded-2xl font-black shadow-2xl hover:scale-105 transition-transform flex items-center gap-3">
ورود به آزمایشگاه علمی
<ArrowRight className="w-5 h-5 rotate-180" />
</div>
</div>
</div>
</section>
{/* FAQ Section */}
{product.faqs?.length > 0 && (
<section className="pt-10">
<div className="flex items-center gap-4 mb-10">
<div className="w-12 h-12 bg-blue-100 text-canina-blue rounded-2xl flex items-center justify-center">
<Info className="w-6 h-6" />
</div>
<h3 className="text-3xl font-black text-medical-gray-900 italic font-vazir">پاسخ به ابهامات شما</h3>
</div>
<div className="grid md:grid-cols-1 gap-4">
{product.faqs.map((faq, i) => (
<details key={i} className="group bg-white border border-medical-gray-200 rounded-3xl overflow-hidden hover:border-canina-blue/30 transition-all">
<summary className="flex items-center justify-between p-6 cursor-pointer list-none">
<span className="font-bold text-medical-gray-900 font-vazir">{faq.question}</span>
<ChevronDown className="w-5 h-5 text-canina-blue group-open:rotate-180 transition-transform" />
</summary>
<div className="px-6 pb-6 text-sm text-medical-gray-500 font-medium leading-relaxed font-vazir border-t border-medical-gray-50 pt-4">
{faq.answer}
</div>
</details>
))}
</div>
</section>
)}
</div>
{/* Sticky Sidebar */}
<div className="lg:col-span-4 lg:sticky lg:top-24 space-y-8">
<div className="bg-white rounded-[3rem] border-2 border-medical-gray-100 p-8 shadow-2xl relative overflow-hidden">
<div className="absolute top-0 right-0 w-24 h-24 bg-canina-blue/5 rounded-full -mr-12 -mt-12" />
<div className="text-4xl font-black font-vazir text-medical-gray-900 tracking-tighter mb-4">
{toPersian(product.price)}
</div>
{/* Refill Auto-Calculator */}
<div className="bg-canina-blue rounded-[2rem] p-6 text-white mb-8 border-b-8 border-white/20 shadow-2xl">
<div className="flex items-center gap-2 mb-4 opacity-90">
<Clock className="w-4 h-4 text-white" />
<span className="text-[10px] font-bold uppercase tracking-widest font-vazir text-white">هوش مصنوعی تکرار خرید</span>
</div>
<div className="flex items-center justify-between">
<div>
<div className="text-2xl font-black font-vazir text-white">{toPersian(calculation.duration)} روز</div>
<div className="text-[9px] font-bold text-white/80 font-vazir whitespace-nowrap">تخمین اتمام برای {toPersian(weight)} کیلوگرم</div>
</div>
<div className="text-left">
<div className="text-xl font-black font-vazir text-white">{toPersian(calculation.dailyDose)}</div>
<div className="text-[9px] font-bold text-white/80 font-vazir whitespace-nowrap">دوز روزانه ({calculation.unit === 'g' ? 'گرم' : calculation.unit})</div>
</div>
</div>
</div>
{/* Manual Calculator (Mini) */}
<div className="bg-medical-gray-50 rounded-2xl p-6 border border-medical-gray-100 mb-8 space-y-6">
<div className="flex items-center justify-between">
<span className="text-[10px] font-black text-medical-gray-400 font-vazir">وزن پت (کیلوگرم)</span>
<span className="text-sm font-black text-canina-blue font-vazir">{toPersian(weight)}</span>
</div>
<input
type="range"
min="1" max="100"
value={weight}
onChange={(e) => setWeight(parseInt(e.target.value))}
className="w-full h-1.5 bg-medical-gray-200 rounded-lg appearance-none cursor-pointer accent-canina-blue"
/>
<div className="flex gap-2">
<button onClick={() => setPetType("young")} className={`flex-1 py-2 rounded-xl text-[10px] font-black transition-all ${petType === "young" ? 'bg-canina-blue text-white shadow-lg' : 'bg-white text-medical-gray-400'}`}>جوان</button>
<button onClick={() => setPetType("adult")} className={`flex-1 py-2 rounded-xl text-[10px] font-black transition-all ${petType === "adult" ? 'bg-canina-blue text-white shadow-lg' : 'bg-white text-medical-gray-400'}`}>بالغ</button>
</div>
</div>
<div className="flex gap-4 mb-6">
{/* Quantity Selector - 40% Width */}
<div className="flex items-center gap-4 bg-medical-gray-50 border border-medical-gray-100 rounded-2xl p-2 h-16 w-[40%]">
<button
onClick={() => setItemQuantity(Math.max(1, itemQuantity - 1))}
className="w-10 h-10 flex items-center justify-center rounded-xl bg-white text-medical-gray-900 border border-medical-gray-200 hover:bg-canina-blue hover:text-white hover:border-canina-blue transition-all shadow-sm"
>
<Minus className="w-4 h-4" />
</button>
<span className="text-xl font-black text-medical-gray-900 flex-1 text-center font-vazir">
{toPersian(itemQuantity)}
</span>
<button
onClick={() => setItemQuantity(itemQuantity + 1)}
className="w-10 h-10 flex items-center justify-center rounded-xl bg-white text-medical-gray-900 border border-medical-gray-200 hover:bg-canina-blue hover:text-white hover:border-canina-blue transition-all shadow-sm"
>
<Plus className="w-4 h-4" />
</button>
</div>
{/* Add to Cart Button - 60% Width */}
<button
onClick={() => {
addItem(product, itemQuantity, { quantity: calculation.dailyDose, unit: calculation.unit });
toast.success(`${toPersian(itemQuantity)} عدد ${product.name} به سبد خرید اضافه شد`);
}}
className="w-[60%] flex items-center justify-center gap-1.5 px-4 bg-medical-gray-900 text-white rounded-2xl h-16 font-black text-sm hover:bg-canina-blue transition-all shadow-xl shadow-black/10 font-vazir whitespace-nowrap"
>
<ShoppingBag className="w-5 h-5 mb-1" />
افزودن به سبد خرید
</button>
</div>
<div className="mt-6 flex flex-col gap-3">
<div className="flex items-center gap-2 text-[10px] font-bold text-medical-gray-400 font-vazir">
<ShieldCheck className="w-4 h-4 text-green-500" />
ضمانت اصالت محصول (Made in Germany)
</div>
<div className="flex items-center gap-2 text-[10px] font-bold text-medical-gray-400 font-vazir">
<Clock className="w-4 h-4 text-canina-blue" />
آماده ارسال (تحویل حداکثر ۴۸ ساعت)
</div>
</div>
</div>
{/* expected results box */}
{product.expectedResults?.length > 0 && (
<div className="bg-white rounded-[2.5rem] border border-medical-gray-200 p-8">
<h4 className="text-[10px] font-black text-medical-gray-400 uppercase tracking-widest mb-6 font-vazir">تغییرات قابل انتظار</h4>
<div className="space-y-4">
{product.expectedResults.map((res, i) => {
const Icon = ICON_MAP[res.icon] || Sparkles;
return (
<div key={i} className="flex items-center gap-4 group">
<div className="w-10 h-10 bg-medical-gray-50 rounded-xl flex items-center justify-center text-canina-blue group-hover:bg-canina-blue group-hover:text-white transition-all">
<Icon className="w-5 h-5" />
</div>
<span className="text-xs font-bold text-medical-gray-700 font-vazir">{res.text}</span>
</div>
);
})}
</div>
</div>
)}
</div>
</div>
{/* Smart Cross-sell: Recommended Combinations */}
{product.relatedProducts && product.relatedProducts.length > 0 && (
<section className="mt-32 pt-20 border-t border-medical-gray-200">
<div className="flex flex-col items-center text-center mb-16 px-4">
<div className="inline-flex items-center gap-2 px-4 py-2 bg-canina-blue/5 border border-canina-blue/10 rounded-full text-canina-blue text-xs font-black uppercase tracking-widest mb-6 font-vazir whitespace-nowrap">
<Sparkles className="w-4 h-4" />
فرمولاسیون ترکیبی همافزا (Synergy Blend)
</div>
<h2 className="text-3xl lg:text-5xl font-black text-medical-gray-900 leading-tight">
اثربخشی <span className="text-canina-blue italic">دوبرابر</span> با ترکیب هوشمند
</h2>
</div>
<div className="grid lg:grid-cols-2 gap-8">
{product.relatedProducts.map(relId => {
const relProduct = allProducts.find(p => p.id === relId);
if (!relProduct) return null;
return (
<motion.div
key={relId}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
className="bg-white rounded-[3rem] p-8 border border-medical-gray-200 flex flex-col md:flex-row gap-8 items-center cursor-pointer hover:shadow-2xl transition-all"
onClick={() => router.push(`/shop/${relProduct.id}`)}
>
<div className="w-40 h-40 bg-medical-gray-50 rounded-[2rem] p-4 flex items-center justify-center">
<SafeImage src={relProduct.image} alt={relProduct.name} className="w-full h-full drop-shadow-xl" imgClassName="object-contain" />
</div>
<div className="flex-1 text-center md:text-right">
<h4 className="text-xl font-black text-medical-gray-900 mb-2">{relProduct.name}</h4>
<p className="text-sm text-medical-gray-500 mb-6">{relProduct.description}</p>
<div className="flex items-center justify-center md:justify-start gap-4">
<span className="text-lg font-black text-canina-blue">{relProduct.price}</span>
<ArrowRight className="w-4 h-4 text-medical-gray-300" />
</div>
</div>
<div className="w-px h-24 bg-medical-gray-100 hidden md:block" />
<div className="flex items-center justify-center gap-1 group">
<span className="text-xs font-black text-medical-gray-400 group-hover:text-canina-blue transition-colors">مشاهده محصول مکمل</span>
<ChevronLeft className="w-4 h-4 text-medical-gray-300 group-hover:text-canina-blue group-hover:-translate-x-1 transition-all rtl:group-hover:translate-x-1" />
</div>
</motion.div>
);
})}
</div>
</section>
)}
</div>
{/* Refill Automation Popup */}
<AnimatePresence>
{showRefillModal && (
<div className="fixed inset-0 z-[100] flex items-center justify-center p-4">
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
onClick={() => setShowRefillModal(false)}
className="absolute inset-0 bg-medical-gray-900/60 backdrop-blur-md"
/>
<motion.div
initial={{ opacity: 0, scale: 0.9, y: 20 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.9, y: 20 }}
className="bg-white w-full max-w-lg rounded-[3rem] p-10 relative z-10 shadow-2xl overflow-hidden"
>
<div className="absolute top-0 left-0 w-full h-2 bg-gradient-to-r from-canina-blue via-blue-400 to-canina-blue" />
<button
onClick={() => setShowRefillModal(false)}
className="absolute top-6 left-6 text-medical-gray-400 hover:text-medical-gray-600 transition-colors"
>
<X className="w-6 h-6" />
</button>
<div className="text-center">
<div className="w-20 h-20 bg-canina-blue/10 rounded-[2rem] flex items-center justify-center mx-auto mb-8">
<Bell className="w-10 h-10 text-canina-blue animate-bounce" />
</div>
<h3 className="text-3xl font-black text-medical-gray-900 mb-4 leading-tight italic">سیستم یادآوری هوشمند</h3>
<div className="bg-medical-gray-50 border border-medical-gray-100 rounded-3xl p-6 mb-8 text-right">
<p className="text-medical-gray-700 leading-relaxed font-medium font-vazir">
بر اساس وزن <span className="text-canina-blue font-bold">{toPersian(weight)} کیلوگرمی</span> {activePet ? `برای ${activePet.name}` : 'سگ شما'}، این بسته {toPersian(product.packageSize)} تایی دقیقاً <span className="text-canina-blue font-bold">{toPersian(calculation.duration)} روز</span> دیگر تمام میشود.
</p>
<div className="mt-4 flex items-center gap-2 text-xs font-bold text-medical-gray-500 font-vazir">
<ShieldCheck className="w-4 h-4 text-green-500" />
آیا مایلید سیستم ۵ روز قبل از اتمام، به شما پیامک یادآوری ارسال کند؟
</div>
</div>
<div className="flex flex-col gap-3">
<button
onClick={() => setShowRefillModal(false)}
className="w-full bg-canina-blue text-white py-5 rounded-2xl font-black text-lg hover:shadow-xl hover:shadow-canina-blue/20 transition-all flex items-center justify-center gap-2"
>
<CheckCircle2 className="w-5 h-5" />
بله، پیامک یادآوری فعال شود
</button>
<button
onClick={() => setShowRefillModal(false)}
className="w-full py-4 text-medical-gray-400 font-bold text-sm hover:text-medical-gray-600 transition-colors"
>
خیر، فقط محصول را به سبد خرید اضافه کن
</button>
</div>
</div>
</motion.div>
</div>
)}
</AnimatePresence>
</div>
);
}