canina/frontend/application/components/catalog/CatalogPageSpread.tsx
parsa aghaei 8d1b786a24
All checks were successful
Deploy Canina / deploy (push) Successful in 1m50s
chore(brand): rename all Persian occurrences of کانینا to کنینا across the project
2026-08-16 16:40:08 +03:30

499 lines
24 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 React from "react";
import SafeImage from "../SafeImage";
import { Product } from "../../lib/data/products";
import {
Sparkles,
ChevronLeft,
ShieldCheck,
Dog,
Cat,
Pill,
Droplet,
Package,
Award,
Activity,
BookOpen,
CheckCircle2,
Stethoscope,
Heart,
Layers,
Check
} from "lucide-react";
export interface CategoryMeta {
id: string;
name: string;
color: string;
lightBg: string;
borderBg: string;
icon: React.ElementType;
tagline: string;
startPage: number;
}
interface CatalogPageSpreadProps {
pageNumber: number;
totalPages: number;
pageType: "cover" | "toc" | "product" | "backcover" | "category";
categoryMeta?: CategoryMeta;
product?: Product;
products?: Product[];
onSelectProduct?: (product: Product) => void;
onJumpToPage?: (pageNum: number) => void;
categoriesList?: CategoryMeta[];
}
// Helper to determine product form icon & label
const getFormBadge = (unit?: string, name?: string) => {
const str = ((unit || "") + " " + (name || "")).toLowerCase();
if (str.includes("paste") || str.includes("خمیر")) return { label: "خمیر دارویی", icon: Droplet };
if (str.includes("tab") || str.includes("قرص")) return { label: "قرص خوراکی", icon: Pill };
if (str.includes("öl") || str.includes("روغن")) return { label: "روغن خالص", icon: Droplet };
if (str.includes("pulver") || str.includes("پودر") || str.includes("mehl")) return { label: "پودر خوراکی", icon: Package };
if (str.includes("gel") || str.includes("ژل")) return { label: "ژل بهداشتی", icon: Droplet };
if (str.includes("spray") || str.includes("اسپری") || str.includes("shocker")) return { label: "اسپری موضعی", icon: Droplet };
return { label: "مکمل دارویی", icon: Package };
};
// Helper for pet target species icon
const getSpeciesBadge = (suitableFor?: string) => {
if (suitableFor === "سگ") return { label: "مخصوص سگ", icon: Dog };
if (suitableFor === "گربه") return { label: "مخصوص گربه", icon: Cat };
return { label: "سگ و گربه", icon: Heart };
};
export default function CatalogPageSpread({
pageNumber,
totalPages,
pageType,
categoryMeta,
product,
onJumpToPage,
categoriesList = [],
}: CatalogPageSpreadProps) {
// ==========================================
// 1. LUXURY FRONT COVER (طراحی لوکس جلد)
// ==========================================
if (pageType === "cover") {
return (
<div className="w-full h-full bg-gradient-to-br from-slate-950 via-[#0a192f] to-[#040d1a] text-white p-6 md:p-8 flex flex-col justify-between relative overflow-hidden select-none box-border" dir="rtl">
{/* Luxury Background Accents & Gold Borders */}
<div className="absolute inset-0 bg-[radial-gradient(#d4af37_1px,transparent_1px)] [background-size:28px_28px] opacity-[0.07] pointer-events-none" />
<div className="absolute -top-20 -right-20 w-80 h-80 bg-blue-600/15 rounded-full blur-3xl pointer-events-none" />
<div className="absolute -bottom-20 -left-20 w-80 h-80 bg-amber-500/10 rounded-full blur-3xl pointer-events-none" />
{/* Outer Gold Border Frame */}
<div className="absolute inset-3 border border-amber-400/20 rounded-2xl pointer-events-none" />
<div className="absolute inset-4 border border-white/5 rounded-xl pointer-events-none" />
{/* Top Header */}
<div className="relative z-10 flex items-center justify-between border-b border-white/10 pb-4">
<div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-amber-400 to-amber-500 text-slate-950 flex items-center justify-center font-black text-lg shadow-lg font-mono">
CP
</div>
<div>
<span className="text-lg font-black font-lalezar tracking-wide text-white block">
Canina Pharma Germany
</span>
<span className="text-[9px] text-amber-300 font-bold uppercase tracking-widest block font-mono">
🇩🇪 100% Made in Germany Est. 1984
</span>
</div>
</div>
<div className="px-3 py-1 bg-white/10 rounded-full text-[10px] font-bold text-amber-300 border border-amber-400/30 flex items-center gap-1.5">
<Award className="w-3 h-3 text-amber-400" />
<span>نسخه رسمی ۲۰۲۶</span>
</div>
</div>
{/* Center Hero Title & Visual */}
<div className="relative z-10 my-auto text-center space-y-4 py-2">
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-amber-400/10 border border-amber-400/30 text-amber-300 text-[10px] font-black">
<Sparkles className="w-3.5 h-3.5" />
<span>OFFICIAL VETERINARY & CLINICAL CATALOG</span>
</div>
<div className="space-y-2">
<h1 className="text-2xl sm:text-3xl md:text-4xl font-black font-lalezar leading-tight text-transparent bg-clip-text bg-gradient-to-r from-amber-100 via-white to-amber-300">
کاتالوگ تخصصی و راهنمای بالینی مکملهای دارویی کنینا
</h1>
<p className="text-[11px] md:text-xs text-slate-300 font-medium max-w-md mx-auto leading-relaxed">
مرجع رسمی مکملهای درمانی حیوانات خانگی با استانداردهای داروسازی آلمان (GMP) و تاییدیههای ارتوپدی و پوست
</p>
</div>
{/* Hero Render Frame */}
<div className="pt-2 flex justify-center">
<div className="w-36 h-36 md:w-44 md:h-44 rounded-2xl bg-gradient-to-b from-white/10 to-white/5 border border-white/15 backdrop-blur-md p-3 flex flex-col items-center justify-center shadow-2xl relative">
<SafeImage
src="/assets/images/hero-section-image.png"
alt="Canina Pharma Germany"
className="w-full h-full"
imgClassName="object-contain filter drop-shadow-xl"
/>
<div className="absolute -bottom-2.5 bg-gradient-to-r from-amber-400 to-amber-500 text-slate-950 font-black text-[9px] px-3 py-0.5 rounded-full shadow-md">
Pharma Grade Certified
</div>
</div>
</div>
{/* Highlights Pills */}
<div className="flex flex-wrap items-center justify-center gap-2 pt-1 text-[10px] text-slate-300">
<span className="bg-white/5 border border-white/10 px-2.5 py-1 rounded-lg">🦴 مفاصل و اسکلت</span>
<span className="bg-white/5 border border-white/10 px-2.5 py-1 rounded-lg"> پوست و مو</span>
<span className="bg-white/5 border border-white/10 px-2.5 py-1 rounded-lg">🛡 ایمنی و گوارش</span>
<span className="bg-white/5 border border-white/10 px-2.5 py-1 rounded-lg"> ویتامینها</span>
</div>
</div>
{/* Bottom Footer */}
<div className="relative z-10 border-t border-white/10 pt-3 flex items-center justify-between text-[10px] text-slate-400 font-bold">
<div className="flex items-center gap-1.5">
<ShieldCheck className="w-3.5 h-3.5 text-amber-400" />
<span>نمایندگی انحصاری Canina Pharma Germany در ایران</span>
</div>
<span className="font-mono text-slate-400">صفحه ۰۱</span>
</div>
</div>
);
}
// ==========================================
// 2. TABLE OF CONTENTS (فهرست دسته‌بندی‌ها)
// ==========================================
if (pageType === "toc") {
return (
<div className="w-full h-full bg-slate-50 text-slate-800 p-5 md:p-7 flex flex-col justify-between select-none box-border" dir="rtl">
{/* TOC Header */}
<div className="border-b border-slate-200 pb-3 flex items-center justify-between shrink-0">
<div>
<div className="flex items-center gap-1.5 text-[10px] font-black text-canina-blue uppercase tracking-widest">
<BookOpen className="w-3.5 h-3.5" />
<span>فهرست تخصصی و راهنمای بالینی</span>
</div>
<h2 className="text-xl md:text-2xl font-black font-lalezar text-slate-900 mt-0.5">
دستهبندیهای کاتالوگ دارویی
</h2>
</div>
<div className="text-left">
<span className="text-[10px] font-black text-slate-400 block font-mono">CANINA PHARMA</span>
<span className="text-[9px] font-bold text-amber-600 uppercase">Germany</span>
</div>
</div>
{/* Categories List (Compact luxury layout, perfectly fitted) */}
<div className="my-auto space-y-2.5 py-2 flex-1 flex flex-col justify-center min-h-0">
{categoriesList.map((cat, idx) => {
const IconComp = cat.icon;
return (
<div
key={cat.id}
onClick={() => onJumpToPage && onJumpToPage(cat.startPage)}
className="bg-white border border-slate-200/90 hover:border-slate-300 rounded-xl p-2.5 sm:p-3 flex items-center justify-between gap-3 shadow-2xs hover:shadow-md transition-all cursor-pointer group"
>
<div className="flex items-center gap-3 min-w-0">
{/* Category Color Icon */}
<div
className="w-9 h-9 rounded-lg flex items-center justify-center text-white font-black shadow-xs shrink-0 group-hover:scale-105 transition-transform"
style={{ backgroundColor: cat.color }}
>
<IconComp className="w-4 h-4" />
</div>
<div className="min-w-0">
<div className="flex items-center gap-1.5">
<span className="text-[9px] font-black text-slate-400 font-mono">
SECTION 0{idx + 1}
</span>
<span className="w-1.5 h-1.5 rounded-full" style={{ backgroundColor: cat.color }} />
</div>
<h3 className="text-xs sm:text-sm font-black text-slate-900 group-hover:text-canina-blue transition-colors font-vazir truncate">
{cat.name}
</h3>
<p className="text-[10px] text-slate-500 font-medium truncate mt-0.5">
{cat.tagline}
</p>
</div>
</div>
<div className="flex items-center gap-2 shrink-0">
<div className="text-left">
<span className="text-[8px] text-slate-400 font-bold block">صفحه</span>
<span className="text-xs font-black text-slate-900 font-mono">
{cat.startPage < 10 ? `۰${cat.startPage}` : cat.startPage}
</span>
</div>
<div className="w-6 h-6 rounded-full bg-slate-100 group-hover:bg-canina-blue group-hover:text-white text-slate-400 flex items-center justify-center transition-colors">
<ChevronLeft className="w-3.5 h-3.5" />
</div>
</div>
</div>
);
})}
</div>
{/* Quality Seal Note */}
<div className="bg-amber-50/70 border border-amber-200/60 rounded-xl p-2.5 flex items-center gap-2.5 shrink-0">
<Award className="w-4 h-4 text-amber-600 shrink-0" />
<p className="text-[10px] text-amber-900 font-bold leading-relaxed">
تمامی فرآوردههای کنینا آلمان مطابق با مونوگرافهای دارویی فارماکوپه اروپا (Ph. Eur.) و تحت استاندارد GMP تولید میشوند.
</p>
</div>
{/* TOC Footer */}
<div className="border-t border-slate-200 pt-2 flex items-center justify-between text-[10px] text-slate-400 font-bold shrink-0">
<span>راهنمای جامع کاتالوگ دارویی Canina Pharma</span>
<span className="font-mono">صفحه ۰۲</span>
</div>
</div>
);
}
// ==========================================
// 3. LUXURY BACK COVER (شناسنامه پشت جلد)
// ==========================================
if (pageType === "backcover") {
return (
<div className="w-full h-full bg-gradient-to-br from-slate-950 via-[#0a192f] to-[#040d1a] text-white p-6 md:p-8 flex flex-col justify-between relative overflow-hidden select-none box-border" dir="rtl">
<div className="absolute inset-3 border border-amber-400/20 rounded-2xl pointer-events-none" />
<div className="absolute -top-24 -left-24 w-80 h-80 bg-blue-600/10 rounded-full blur-3xl pointer-events-none" />
<div className="relative z-10 border-b border-white/10 pb-3 flex justify-between items-center">
<div className="flex items-center gap-2">
<Award className="w-4 h-4 text-amber-400" />
<span className="text-[10px] font-black uppercase tracking-widest text-amber-400">شناسنامه و استانداردهای دارویی</span>
</div>
<span className="text-[10px] font-mono text-slate-400">صفحه {totalPages}</span>
</div>
<div className="relative z-10 my-auto space-y-5 text-center max-w-sm mx-auto">
<div className="w-16 h-16 mx-auto rounded-2xl bg-gradient-to-br from-amber-400 to-amber-500 text-slate-950 flex items-center justify-center font-black text-2xl shadow-xl font-mono">
CP
</div>
<div className="space-y-1">
<h2 className="text-2xl font-black font-lalezar text-white">Canina Pharma GmbH</h2>
<p className="text-[10px] text-slate-400 font-mono">Made in Germany Quality Guarantee</p>
</div>
{/* Credentials Card */}
<div className="grid grid-cols-2 gap-3 text-right bg-white/5 border border-white/10 p-4 rounded-xl text-[10px] space-y-1">
<div>
<span className="text-slate-400 block">کشور سازنده:</span>
<span className="font-black text-amber-300 font-mono">Germany (آلمان)</span>
</div>
<div>
<span className="text-slate-400 block">گواهی کیفیت:</span>
<span className="font-black text-amber-300 font-mono">GMP & Vet Certified</span>
</div>
<div>
<span className="text-slate-400 block">وبسایت بینالمللی:</span>
<span className="font-black text-white font-mono">canina.de</span>
</div>
<div>
<span className="text-slate-400 block">واردکننده انحصاری:</span>
<span className="font-black text-white">کنینا فارما ایران</span>
</div>
</div>
<div className="flex items-center justify-center gap-3 text-[10px] text-slate-400">
<span className="flex items-center gap-1"><Check className="w-3 h-3 text-emerald-400" /> ۱۰۰٪ طبیعی</span>
<span className="flex items-center gap-1"><Check className="w-3 h-3 text-emerald-400" /> بدون افزودنی شیمیایی</span>
<span className="flex items-center gap-1"><Check className="w-3 h-3 text-emerald-400" /> بدون تست روی حیوانات</span>
</div>
</div>
<div className="relative z-10 border-t border-white/10 pt-3 text-center text-[9px] text-slate-500 font-mono">
© 2026 Canina Pharma GmbH. All Rights Reserved.
</div>
</div>
);
}
// ==========================================
// 4. DEDICATED 1-PAGE LUXURY PRODUCT PRESENTATION
// (صفحه اختصاصی و لوکس هر محصول)
// ==========================================
if (!product) return null;
const formBadge = getFormBadge(product.unit, product.name);
const speciesBadge = getSpeciesBadge(product.suitableFor);
const FormIcon = formBadge.icon;
const SpeciesIcon = speciesBadge.icon;
const themeColor = categoryMeta?.color || "#0284C7";
return (
<div className="w-full h-full bg-white text-slate-800 p-4 sm:p-5 md:p-6 flex flex-col justify-between select-none box-border overflow-hidden" dir="rtl">
{/* 1. Header Bar: Category, Species, Form, ArtNo */}
<div className="border-b border-slate-100 pb-2.5 flex items-center justify-between gap-2 shrink-0">
{/* Category Pill */}
<div className="flex items-center gap-1.5">
<span
className="w-2.5 h-2.5 rounded-full shrink-0"
style={{ backgroundColor: themeColor }}
/>
<span className="text-[10px] font-black uppercase tracking-wider text-slate-700 font-vazir">
{product.category}
</span>
</div>
{/* Product Badges */}
<div className="flex items-center gap-1.5 text-[9px] font-bold">
<span className="bg-slate-100 text-slate-700 px-2 py-0.5 rounded-md flex items-center gap-1 border border-slate-200/60">
<SpeciesIcon className="w-3 h-3 text-slate-500" />
<span>{speciesBadge.label}</span>
</span>
<span className="bg-slate-100 text-slate-700 px-2 py-0.5 rounded-md flex items-center gap-1 border border-slate-200/60">
<FormIcon className="w-3 h-3 text-slate-500" />
<span>{formBadge.label}</span>
</span>
<span className="bg-blue-50 text-canina-blue font-mono px-2 py-0.5 rounded-md border border-blue-100">
Art-Nr: {product.artNo}
</span>
</div>
</div>
{/* 2. Main Body Content (Strictly fitted with flex-1 & min-h-0) */}
<div className="flex-1 min-h-0 flex flex-col justify-between py-2 space-y-2">
{/* Top Product Hero Showcase (Image + Titles + Special Badge) */}
<div className="flex items-center gap-3 bg-gradient-to-l from-slate-50 via-white to-slate-50 border border-slate-200/80 rounded-2xl p-2.5 shrink-0">
{/* Studio Image Box */}
<div className="w-24 h-24 sm:w-28 sm:h-28 bg-white rounded-xl border border-slate-100 p-2 flex items-center justify-center shrink-0 relative shadow-2xs">
<SafeImage
src={product.image}
alt={product.name}
className="w-full h-full"
imgClassName="object-contain max-h-20 sm:max-h-24 filter drop-shadow-md"
/>
{product.unit && (
<span className="absolute bottom-1 right-1 bg-slate-900/90 text-white font-mono text-[8px] font-bold px-1.5 py-0.5 rounded">
{product.unit}
</span>
)}
</div>
{/* Title & Scientific Tagline */}
<div className="min-w-0 space-y-1">
{product.specialBadge && (
<span
className="text-[9px] font-black px-2 py-0.5 rounded-full text-white inline-block shadow-2xs"
style={{ backgroundColor: themeColor }}
>
{product.specialBadge}
</span>
)}
<h2 className="text-sm sm:text-base font-black text-slate-900 font-vazir leading-tight truncate">
{product.name}
</h2>
{product.scientificTagline && (
<p className="text-[10px] text-slate-600 font-bold italic line-clamp-1">
{product.scientificTagline}
</p>
)}
<p className="text-[10px] text-slate-500 font-medium line-clamp-2 leading-relaxed">
{product.shortDescription || product.description}
</p>
</div>
</div>
{/* Clinical Indications & Symptoms */}
{product.symptoms && product.symptoms.length > 0 && (
<div className="space-y-1 shrink-0">
<span className="text-[9px] font-black text-slate-400 uppercase tracking-widest block">
موارد مصرف و نشانههای بالینی:
</span>
<div className="flex flex-wrap gap-1">
{product.symptoms.slice(0, 4).map((symptom, i) => (
<span
key={i}
className="bg-red-50/70 text-red-800 border border-red-200/60 rounded-md px-2 py-0.5 text-[9px] font-bold"
>
{symptom}
</span>
))}
</div>
</div>
)}
{/* Active Ingredients & Composition Table */}
{product.main_ingredients && product.main_ingredients.length > 0 && (
<div className="bg-slate-50 border border-slate-200/80 rounded-xl p-2 space-y-1 shrink-0">
<div className="flex items-center gap-1 text-[9px] font-black text-canina-blue uppercase">
<Layers className="w-3 h-3" />
<span>ترکیبات موثره و فرمولاسیون دارویی:</span>
</div>
<div className="flex flex-wrap gap-1">
{product.main_ingredients.slice(0, 5).map((ing, idx) => (
<span
key={idx}
className="bg-white text-slate-800 border border-slate-200 rounded px-1.5 py-0.5 text-[9px] font-bold shadow-3xs"
>
{ing}
</span>
))}
</div>
</div>
)}
{/* Clinical Dosage Protocol */}
{product.dosage_logic && (
<div className="bg-amber-50/70 border border-amber-200/70 rounded-xl p-2 space-y-0.5 shrink-0">
<div className="flex items-center gap-1 text-amber-900 font-black text-[9px]">
<ShieldCheck className="w-3 h-3 text-amber-600" />
<span>پروتکل بالینی تجویز و دوز مصرف:</span>
</div>
<p className="text-[9px] text-amber-950 font-bold leading-relaxed line-clamp-2">
{product.dosage_logic}
</p>
</div>
)}
{/* Specialist Endorsement */}
{product.specialist && (
<div className="bg-slate-50/80 border border-slate-200/60 rounded-xl p-2 flex items-center gap-2.5 shrink-0">
<SafeImage
src={product.specialist.image}
alt={product.specialist.name}
className="w-8 h-8 rounded-full border border-white shadow-xs shrink-0"
imgClassName="object-cover"
/>
<div className="min-w-0">
<div className="flex items-center gap-1">
<Stethoscope className="w-3 h-3 text-canina-blue" />
<span className="text-[9px] font-black text-slate-900 truncate">{product.specialist.name}</span>
<span className="text-[8px] text-slate-500 truncate font-medium">({product.specialist.title})</span>
</div>
<p className="text-[8px] text-slate-600 italic truncate mt-0.5">
«{product.specialist.message}»
</p>
</div>
</div>
)}
</div>
{/* 3. Page Footer */}
<div className="border-t border-slate-100 pt-2 flex items-center justify-between text-[9px] text-slate-400 font-bold shrink-0">
<div className="flex items-center gap-1.5">
<CheckCircle2 className="w-3 h-3 text-emerald-600" />
<span>گرید دارویی GMP آلمان</span>
</div>
<span className="font-mono">
صفحه {pageNumber < 10 ? `۰${pageNumber}` : pageNumber} از {totalPages}
</span>
</div>
</div>
);
}