canina/frontend/application/components/ProductPage.tsx

816 lines
46 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[]>([]);
const [isMounted, setIsMounted] = useState(false);
useEffect(() => {
setIsMounted(true);
productService.getProducts({ limit: 999 })
.then((res) => {
const products = res.data;
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 && typeof staticProduct.calculateDosage === 'function') {
return {
...apiProduct,
calculateDosage: staticProduct.calculateDosage,
packageSize: apiProduct.packageSize || staticProduct.packageSize || 100
};
}
// Dynamic weight-based calculation fallback for any product without custom logic
return {
...apiProduct,
packageSize: apiProduct.packageSize || 100,
calculateDosage: (w: number, isYoung: boolean) => {
const factor = isYoung ? 0.2 : 0.1;
const baseQty = Math.max(1, Math.round(w * factor));
return {
quantity: baseQty,
unit: apiProduct.unit?.includes('ml') ? "میلی‌لیتر" : apiProduct.unit?.includes('g') ? "گرم" : "قرص",
description: isYoung ? "دوز رشد روزانه" : "دوز نگهداری روزانه"
};
}
};
}, [product, allProducts]);
useEffect(() => {
if (activePet && activePet.weight > 0) {
setWeight(activePet.weight);
setPetType(activePet.age <= 1 ? "young" : "adult");
}
}, [activePet]);
const calculation = useMemo(() => {
if (!fullProduct || typeof fullProduct.calculateDosage !== 'function') return null;
const result = fullProduct.calculateDosage(weight, petType === "young");
const packageSize = fullProduct.packageSize || 100;
const duration = Math.max(1, Math.floor(packageSize / (result.quantity || 1)));
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 bg-medical-gray-50 p-6 max-w-7xl mx-auto font-vazir" dir="rtl">
<div className="animate-pulse space-y-6">
<div className="h-8 bg-medical-gray-200 rounded-2xl w-48" />
<div className="grid md:grid-cols-12 gap-8">
<div className="md:col-span-5 h-80 bg-white border border-medical-gray-200 rounded-[2.5rem]" />
<div className="md:col-span-7 space-y-4">
<div className="h-10 bg-medical-gray-200 rounded-2xl w-3/4" />
<div className="h-6 bg-medical-gray-100 rounded-xl w-1/2" />
<div className="h-24 bg-medical-gray-100 rounded-2xl w-full" />
</div>
</div>
</div>
</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-36 sm:pb-20 px-4 sm:px-6 lg:px-8 font-vazir overflow-x-hidden" dir="rtl">
<div className="max-w-7xl mx-auto w-full">
{/* Breadcrumbs for Mobile and Desktop */}
<nav className="flex items-center gap-2 text-xs md:text-sm font-semibold text-medical-gray-600 mb-6 md:mb-10 overflow-x-auto whitespace-nowrap py-3 border-b border-medical-gray-100 font-vazir scrollbar-thin scrollbar-thumb-medical-gray-200 scrollbar-track-transparent pr-1" dir="rtl">
<button
onClick={() => router.push('/')}
className="hover:text-canina-blue transition-colors font-vazir cursor-pointer"
>
خانه
</button>
<ChevronLeft className="w-3.5 h-3.5 flex-shrink-0 text-medical-gray-300" />
<button
onClick={() => router.push(`/shop?category=${product.categorySlug}`)}
className="hover:text-canina-blue cursor-pointer font-vazir"
>
{product.category}
</button>
<ChevronLeft className="w-3.5 h-3.5 flex-shrink-0 text-medical-gray-300" />
<span className="text-canina-blue font-vazir whitespace-nowrap font-bold">{product.nameFa || product.name}</span>
</nav>
{/* Global Single Grid Layout - Aligns Sticky Buy Box at the Top */}
<div className="grid grid-cols-1 lg:grid-cols-12 gap-12 items-start w-full">
{/* Right/Main Content Column (lg:col-span-8) */}
<div className="w-full lg:col-span-8 space-y-12">
{/* Above the Fold Grid */}
<div className="grid grid-cols-1 md:grid-cols-12 gap-8 md:gap-12 items-center md:items-start text-center md:text-right font-vazir w-full" dir="rtl">
{/* Right Column: Product Image Frame (md:col-span-5) */}
<div className="md:col-span-5 w-full mx-auto max-w-sm md:max-w-none">
<motion.div
initial={{ opacity: 0, scale: 0.95 }}
animate={{ opacity: 1, scale: 1 }}
className="bg-white rounded-[2.5rem] border border-medical-gray-200 shadow-xl relative group overflow-hidden h-[300px] sm:h-[380px] flex items-center justify-center p-6 sm:p-8"
>
<div className="absolute top-4 left-4 sm:top-6 sm:left-6 flex flex-col gap-1.5 sm:gap-2 z-10 items-start">
<div className="px-2.5 py-1 bg-green-500 text-white rounded-full text-[9px] sm:text-[10px] font-black uppercase tracking-widest flex items-center gap-1 font-vazir shadow-sm">
<CheckCircle2 className="w-3 h-3" />
موجود در انبار
</div>
<div className="px-2.5 py-1 bg-canina-blue text-white rounded-full text-[9px] sm:text-[10px] font-black uppercase tracking-widest font-vazir whitespace-nowrap shadow-sm">
گرید دارویی اختصاصی
</div>
</div>
<SafeImage
src={product.image}
alt={product.name}
className="w-full h-full"
imgClassName="max-h-[240px] sm:max-h-[300px] w-auto object-contain drop-shadow-2xl group-hover:scale-105 transition-transform duration-700 mx-auto my-auto"
/>
</motion.div>
</div>
{/* Left Column: Product Title & Description (md:col-span-7) */}
<div className="md:col-span-7 space-y-4 sm:space-y-6 flex flex-col items-center md:items-start">
<div className="w-full flex flex-col items-center md:items-start">
<div className="flex flex-wrap justify-center md:justify-start items-center gap-2 sm:gap-3 mb-3 sm: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 shadow-sm">
استاندارد صنعتی آلمان
</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 shadow-sm">
{product.specialBadge}
</div>
)}
</div>
<div className="flex flex-col gap-1.5 mb-4 text-center md:text-right w-full">
<h1 dir="rtl" className="text-xl sm:text-2xl md:text-3xl lg:text-4xl font-black text-medical-gray-900 leading-tight font-vazir">
{product.nameFa || product.name}
</h1>
{product.nameEn && (
<h2 dir="ltr" className="text-xs sm:text-base text-slate-400 font-bold italic font-sans text-center md:text-left">
{product.nameEn}
</h2>
)}
</div>
<p className="text-base sm:text-xl text-canina-blue font-bold italic opacity-80 leading-relaxed max-w-2xl font-vazir mb-4 text-center md:text-right" dir="rtl">
{isMounted && pets.length > 0 ? (
product.optimisticTemplate?.replace("[PetName]", activePet?.name || "").replace("[OnSet]", product.onSetOfAction || "به زودی")
) : (
product.scientificTagline
)}
</p>
{fullProduct.shortDescription && (
<div className="w-full text-right bg-canina-blue/5 border-r-4 border-canina-blue p-4 sm:p-6 rounded-2xl">
<p className="text-sm sm:text-lg text-medical-gray-600 font-bold leading-relaxed font-vazir">
{fullProduct.shortDescription}
</p>
</div>
)}
</div>
</div>
</div>
{/* ─── Symptoms / Therapeutic Indications Section ─── */}
{fullProduct.symptoms && fullProduct.symptoms.length > 0 && (
<section className="bg-canina-blue/[0.03] border border-canina-blue/10 rounded-[2rem] p-6 md:p-8 space-y-4">
<div className="flex items-center gap-3">
<div className="w-9 h-9 bg-canina-blue/10 text-canina-blue rounded-xl flex items-center justify-center">
<Stethoscope className="w-5 h-5" />
</div>
<h3 className="text-base font-black text-medical-gray-900 font-vazir">علائم و موارد درمانی مرتبط</h3>
</div>
<p className="text-[12px] text-medical-gray-400 font-vazir font-bold">این محصول برای رفع علائم زیر توسط دامپزشکان توصیه میشود:</p>
<div className="flex flex-wrap gap-2">
{fullProduct.symptoms.map((symptom: string, idx: number) => (
<a
key={idx}
href={`/shop?symptom=${encodeURIComponent(symptom)}`}
className="inline-flex items-center gap-1.5 px-3.5 py-1.5 rounded-full text-[11px] font-bold bg-white border border-canina-blue/20 text-canina-blue hover:bg-canina-blue hover:text-white hover:border-canina-blue transition-all shadow-sm cursor-pointer font-vazir whitespace-nowrap"
>
<span className="w-1.5 h-1.5 rounded-full bg-current opacity-60" />
{symptom}
</a>
))}
</div>
</section>
)}
{/* Key Benefits Section */}
{fullProduct.keyBenefits && fullProduct.keyBenefits.length > 0 && (
<section className="space-y-8 pt-6 border-t border-medical-gray-100">
<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-200 rounded-[2.5rem] 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>
)}
{/* Comprehensive Product Description Section (Below the fold) */}
{fullProduct.description && (
<section className="bg-white border border-medical-gray-200 rounded-[2.5rem] p-8 md:p-10 shadow-md space-y-6">
<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">
<Info className="w-6 h-6" />
</div>
<h3 className="text-2xl font-black text-medical-gray-900 italic font-vazir">توضیحات و معرفی محصول</h3>
</div>
<div className="text-base text-medical-gray-600 font-medium leading-loose font-vazir space-y-4 pt-4 border-t border-medical-gray-100">
{fullProduct.description.split('\n').filter(Boolean).map((para, pIdx) => (
<p key={pIdx}>{para.trim()}</p>
))}
</div>
</section>
)}
{/* Smart Dosage Calculator Utility Section / Topical Usage Notice */}
{fullProduct.categorySlug === 'special-care' ||
fullProduct.name.toLowerCase().includes('pfotenpflege') ||
fullProduct.name.toLowerCase().includes('augenpflege') ||
fullProduct.unit?.includes('ml Lotion') ||
fullProduct.unit?.includes('Balsam') ||
fullProduct.nameFa?.includes('کرم') ||
fullProduct.nameFa?.includes('قطره تمیزکننده') ||
fullProduct.nameFa?.includes('اسپری') ? (
<section className="bg-white rounded-[2.5rem] border border-medical-gray-200 p-8 md:p-10 shadow-md space-y-6">
<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">
<Sparkles className="w-6 h-6" />
</div>
<div>
<h3 className="text-2xl font-black text-medical-gray-900 italic font-vazir">نحوه استفاده موضعی و کاربرد</h3>
<p className="text-xs text-medical-gray-400 font-bold font-vazir mt-1">محصولات بهداشتی و بهداشت موضعی نیاز به دوزبندی بر اساس وزن ندارند</p>
</div>
</div>
<div className="bg-medical-gray-50 rounded-[2rem] p-6 border border-medical-gray-100 flex items-start gap-4">
<div className="w-10 h-10 rounded-xl bg-canina-blue/10 text-canina-blue flex items-center justify-center font-black flex-shrink-0">
</div>
<div>
<h4 className="text-sm font-black text-medical-gray-900 mb-1 font-vazir">راهنمای مصرف موضعی</h4>
<p className="text-xs text-medical-gray-600 font-bold font-vazir leading-relaxed">
این محصول یک فرآورده موضعی/بهداشتی است و مقدار مصرف آن به صورت موضعی (روی پوست، چشم یا پنجه) اعمال میشود و وابسته به وزن بدن حیوان نمیباشد. ماندگاری بسته بسته به میزان و تکرار مصرف روزانه شما متفاوت خواهد بود.
</p>
</div>
</div>
</section>
) : (
<section className="bg-white rounded-[2.5rem] border border-medical-gray-200 p-8 md:p-10 shadow-md 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">
<Clock className="w-6 h-6" />
</div>
<div>
<h3 className="text-lg sm:text-2xl font-black text-medical-gray-900 italic font-vazir whitespace-nowrap">ماشین حساب هوشمند مصرف</h3>
<p className="text-[11px] sm:text-xs text-medical-gray-400 font-bold font-vazir mt-0.5 sm:mt-1">تخمین دقیق دوز روزانه و ماندگاری هر بسته بر اساس مشخصات پت شما</p>
</div>
</div>
<div className="grid md:grid-cols-2 gap-8 items-center">
{/* Manual Slider Inputs */}
<div className="bg-medical-gray-50 rounded-[2rem] p-6 border border-medical-gray-100 space-y-6">
<div className="flex items-center justify-between">
<span className="text-xs font-black text-medical-gray-500 font-vazir">وزن پت (کیلوگرم)</span>
<span className="text-lg 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-2 bg-medical-gray-200 rounded-lg appearance-none cursor-pointer accent-canina-blue [&::-webkit-slider-thumb]:w-6 [&::-webkit-slider-thumb]:h-6 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-canina-blue [&::-webkit-slider-thumb]:appearance-none"
/>
<div className="space-y-2">
<span className="text-[10px] font-black text-medical-gray-400 font-vazir">سن حیوان</span>
<div className="flex gap-2">
<button onClick={() => setPetType("young")} className={`flex-1 py-3 rounded-xl text-xs font-black transition-all border ${petType === "young" ? 'bg-canina-blue border-canina-blue text-white shadow-lg' : 'bg-white border-medical-gray-200 text-medical-gray-400'}`}>جوان</button>
<button onClick={() => setPetType("adult")} className={`flex-1 py-3 rounded-xl text-xs font-black transition-all border ${petType === "adult" ? 'bg-canina-blue border-canina-blue text-white shadow-lg' : 'bg-white border-medical-gray-200 text-medical-gray-400'}`}>بالغ</button>
</div>
</div>
</div>
{/* Calculation Results Output */}
<div className="bg-canina-blue rounded-[2rem] p-8 text-white border-b-8 border-white/20 shadow-2xl flex flex-col justify-between h-full min-h-[220px]">
<div className="flex items-center gap-2 mb-4 opacity-90 border-b border-white/10 pb-3">
<Sparkles className="w-4 h-4 text-white" />
<span className="text-[10px] font-bold uppercase tracking-widest font-vazir text-white">تخمین هوش مصنوعی (AI Advice)</span>
</div>
<div className="flex items-center justify-between">
<div>
<div className="text-3xl font-black font-vazir text-white">{toPersian(calculation.duration)} روز</div>
<div className="text-[10px] font-bold text-white/80 font-vazir whitespace-nowrap mt-1">تخمین اتمام مصرف بسته</div>
</div>
<div className="text-left">
<div className="text-2xl font-black font-vazir text-white">{toPersian(calculation.dailyDose)}</div>
<div className="text-[10px] font-bold text-white/80 font-vazir whitespace-nowrap mt-1">دوز روزانه ({calculation.unit === 'g' ? 'گرم' : calculation.unit})</div>
</div>
</div>
<p className="text-[11px] text-white/60 font-bold font-vazir mt-6 leading-relaxed">
* دوزها تخمینی هستند؛ توصیه میشود برای مصرف دقیق کاتالوگ محصول را مطالعه کنید.
</p>
</div>
</div>
</section>
)}
{/* Ingredients Section */}
<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">
<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 md:p-10 border border-medical-gray-200 shadow-md">
<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 => {
const termObj = scientificTerms[key] || SCIENTIFIC_TERMS[key];
const termName = termObj?.term || key;
const ingClean = ing.toLowerCase();
const keyClean = key.toLowerCase();
const termNameClean = termName.toLowerCase();
return ingClean.includes(keyClean) ||
keyClean.includes(ingClean) ||
ingClean.includes(termNameClean) ||
termNameClean.includes(ingClean);
});
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-[2.5rem] 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 / Usage Instructions Section (Dynamic Header based on product category) */}
<section className="bg-white border border-medical-gray-200 rounded-[2.5rem] p-8 md:p-10 shadow-md">
<div className="flex items-center gap-4 mb-8">
<div className="w-12 h-12 bg-canina-blue text-white rounded-2xl flex items-center justify-center shadow-lg">
<CalendarDays className="w-6 h-6" />
</div>
<h3 className="text-2xl font-black text-medical-gray-900 italic font-vazir">
{product.categorySlug === 'special-care' || product.name.toLowerCase().includes('pfotenpflege') || product.name.toLowerCase().includes('augenpflege')
? 'دستورالعمل و نحوه استفاده موضعی'
: 'توصیه غذایی و نحوه مصرف'}
</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-[2.5rem] p-8 md:p-10 border border-medical-gray-200 shadow-md">
<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-[2rem] 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-[2.5rem] p-12 overflow-hidden group cursor-pointer border border-medical-gray-200 shadow-md"
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 && 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-[2rem] 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 (Clean Buy Box) - Hidden on mobile as mobile floating buy bar is active */}
<div className="hidden lg:block lg:col-span-4 lg:sticky lg:top-28 space-y-8">
<div className="bg-white rounded-[2.5rem] 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-[10px] font-black text-medical-gray-400 uppercase tracking-widest mb-1 font-vazir">قیمت نهایی محصول</div>
<div className="text-4xl font-black font-vazir text-medical-gray-900 tracking-tighter mb-8">
{toPersian(product.price)}
</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 border-t border-medical-gray-50 pt-6">
<div className="flex items-center gap-2 text-xs font-bold text-medical-gray-500 font-vazir">
<ShieldCheck className="w-4 h-4 text-green-500" />
ضمانت اصالت محصول (Made in Germany)
</div>
<div className="flex items-center gap-2 text-xs font-bold text-medical-gray-500 font-vazir">
<Clock className="w-4 h-4 text-canina-blue" />
آماده ارسال (تحویل حداکثر ۴۸ ساعت)
</div>
</div>
</div>
{/* expected results box */}
{product.expectedResults && product.expectedResults.length > 0 && (
<div className="bg-white rounded-[2.5rem] border border-medical-gray-200 p-8 shadow-md">
<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>
{/* Mobile Floating Sticky Bottom Buy Bar */}
<div className="lg:hidden fixed bottom-0 left-0 right-0 z-40 bg-white border-t border-medical-gray-200 p-3 shadow-2xl flex items-center justify-between gap-3 font-vazir" dir="rtl">
<div>
<span className="text-[10px] text-medical-gray-400 font-bold block">قیمت نهایی</span>
<span className="text-lg font-black text-medical-gray-900 font-vazir">{toPersian(product.price)}</span>
</div>
<div className="flex items-center gap-2 flex-1 max-w-[240px]">
<div className="flex items-center gap-1 bg-medical-gray-50 border border-medical-gray-200 rounded-xl p-1 h-11">
<button
onClick={() => setItemQuantity(Math.max(1, itemQuantity - 1))}
className="w-7 h-7 flex items-center justify-center rounded-lg bg-white text-medical-gray-900 border border-medical-gray-200 font-bold text-xs"
>
-
</button>
<span className="w-5 text-center font-black text-medical-gray-900 text-xs font-vazir">
{toPersian(itemQuantity)}
</span>
<button
onClick={() => setItemQuantity(itemQuantity + 1)}
className="w-7 h-7 flex items-center justify-center rounded-lg bg-white text-medical-gray-900 border border-medical-gray-200 font-bold text-xs"
>
+
</button>
</div>
<button
onClick={() => {
addItem(product, itemQuantity, { quantity: calculation.dailyDose, unit: calculation.unit });
toast.success(`${toPersian(itemQuantity)} عدد به سبد خرید اضافه شد`);
}}
className="flex-1 bg-canina-blue text-white py-2.5 px-3 rounded-xl font-black text-xs hover:bg-canina-dark transition-all flex items-center justify-center gap-1.5 shadow-md shadow-canina-blue/20 whitespace-nowrap"
>
<ShoppingBag className="w-4 h-4" />
افزودن به سبد
</button>
</div>
</div>
</div>
);
}