From 00cfd1a2a0b98c20ca5916c247b0aafc997ec826 Mon Sep 17 00:00:00 2001 From: parsa aghaei Date: Sat, 5 Sep 2026 17:16:35 +0330 Subject: [PATCH] feat(catalog): redesign digital catalog spread with luxury European apothecary layout and mobile gesture navigation --- .../components/catalog/CatalogPageSpread.tsx | 404 ++++++++++-------- .../components/catalog/FlipbookCatalog.tsx | 111 +++-- 2 files changed, 314 insertions(+), 201 deletions(-) diff --git a/frontend/application/components/catalog/CatalogPageSpread.tsx b/frontend/application/components/catalog/CatalogPageSpread.tsx index 419f563..5b2fd05 100644 --- a/frontend/application/components/catalog/CatalogPageSpread.tsx +++ b/frontend/application/components/catalog/CatalogPageSpread.tsx @@ -26,9 +26,11 @@ import { export interface CategoryMeta { id: string; name: string; - color: string; - lightBg: string; - borderBg: string; + color: string; // پایه تیره + lightBg: string; // پنل روشن + borderBg: string; // اکسنت + accentColor?: string; + secondaryColor?: string; icon: React.ElementType; tagline: string; startPage: number; @@ -201,38 +203,41 @@ export default function CatalogPageSpread({ // ========================================== if (pageType === "toc") { return ( -
+
{/* TOC Header */} -
+
-
+
فهرست تخصصی و راهنمای بالینی
-

+

دسته‌بندی‌های کاتالوگ دارویی

- CANINA PHARMA - Germany + CANINA PHARMA + Germany
{/* Categories List (Compact luxury layout, perfectly fitted) */} -
+
{categoriesList.map((cat, idx) => { const IconComp = cat.icon; + const accent = cat.accentColor || cat.borderBg || "#C88A3F"; + const sec = cat.secondaryColor || "#6B8F71"; return (
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" + className="bg-white border 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" + style={{ borderColor: "rgba(18,33,31,0.08)" }} >
{/* Category Color Icon */}
@@ -240,15 +245,15 @@ export default function CatalogPageSpread({
- + SECTION 0{idx + 1} - +
-

+

{cat.name}

-

+

{cat.tagline}

@@ -256,12 +261,12 @@ export default function CatalogPageSpread({
- صفحه + صفحه {cat.startPage < 10 ? `۰${cat.startPage}` : cat.startPage}
-
+
@@ -271,17 +276,17 @@ export default function CatalogPageSpread({
{/* Quality Seal Note */} -
- -

+

+ +

تمامی فرآورده‌های کنینا آلمان مطابق با مونوگراف‌های دارویی فارماکوپه اروپا (Ph. Eur.) و تحت استاندارد GMP تولید می‌شوند.

{/* TOC Footer */} -
+
راهنمای جامع کاتالوگ دارویی Canina Pharma - صفحه ۰۲ + صفحه ۰۲
); @@ -349,205 +354,258 @@ export default function CatalogPageSpread({ } // ========================================== - // 4. DEDICATED 1-PAGE LUXURY PRODUCT PRESENTATION - // (صفحه اختصاصی و لوکس هر محصول) + // 4. DEDICATED LUXURY PHARMACEUTICAL MONOGRAPH 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"; + + // Locked 5-category European luxury palette + const baseDark = categoryMeta?.color || "#12211F"; + const panelLight = categoryMeta?.lightBg || "#F3EEE0"; + const accentColor = categoryMeta?.accentColor || categoryMeta?.borderBg || "#C88A3F"; + const secondaryColor = categoryMeta?.secondaryColor || "#6B8F71"; + const CategoryIcon = categoryMeta?.icon || Activity; + + // Alternating layout dynamics based on page number (odd vs even pages) + const isEvenPage = pageNumber % 2 === 0; + + // Clean description without HTML + const cleanDescription = (product.shortDescription || (product.description ? product.description.replace(/<[^>]*>/g, '') : '')).trim(); + + // Parse dosage into sequential steps if available + const dosageRaw = (product.dosage_logic || product.feedingAdvice || "").trim(); + const dosageSteps = dosageRaw + ? dosageRaw + .split(/(?:؛|\. |\n| - )/g) + .map(s => s.trim()) + .filter(s => s.length > 5) + .slice(0, 3) + : []; return ( -
- {/* Decorative luxury gradient tint border on top edge */} +
+ {/* Category Delicate Line Watermark in Background */}
+ +
+ + {/* Subtle Luxury Gradient Ambient Aura */} +
- - {/* 1. Header Bar: Category, Species, Form, ArtNo */} -
- - {/* Category Pill */} -
- - - {product.category} - + + {/* Top Accent Rim (Ultra-thin luxury rule) */} +
+ + {/* 1. Header Bar: Minimal Monograph Classification */} +
+
+
+ +
+
+ + {product.category} + + + CANINA VETERINARY DOSSIER + +
- {/* Product Badges (Strictly whitespace-nowrap) */} -
- - {speciesBadge.isBoth ? ( - - - - - ) : ( - - )} - {speciesBadge.label} - - - - {formBadge.label} - - +
+ Art-Nr: {product.artNo} + + {speciesBadge.label} +
- {/* 2. Main Body Content (Luxury grid fitted strictly without overflow) */} -
+ {/* 2. Main Body Content: Asymmetric editorial composition */} +
- {/* Top Product Hero Showcase (Image + Titles + Special Badge) */} -
-
+ {/* Hero Product Stage: Studio Lighting Mockup + Three-Tier Typography */} +
- {/* Studio Image Box */} -
- + {/* Ambient Studio Spotlight Aura */} +
+ {/* Thin Aesthetic Ring behind product */} +
+ +
+ +
+ {product.unit && ( - + {product.unit} )}
- {/* Title & Scientific Tagline */} -
+ {/* Three-Tier Typography: Black Name, Advertising Subtitle, Editorial Body */} +
{product.specialBadge && ( - ★ {product.specialBadge} + {product.specialBadge} )} -

+ +

{product.name}

- {product.scientificTagline && ( -

- {product.scientificTagline} -

- )} -

- {product.shortDescription || (product.description ? product.description.replace(/<[^>]*>/g, '') : '')} + +

+ {product.scientificTagline || "فرمولاسیون دارویی استاندارد جهت ارتقای سلامت زیستی و بالینی پت"} +

+ +

+ {cleanDescription}

- {/* Clinical Indications & Symptoms */} + {/* Section 1: Clinical Indications (Flowing text with refined dot separators, no colored badges) */} {product.symptoms && product.symptoms.length > 0 && ( -
- - موارد مصرف و نشانه‌های بالینی: +
+ + موارد مصرف بالینی -
- {product.symptoms.slice(0, 4).map((symptom, i) => ( - - • {symptom} - +

+ {product.symptoms.map((symptom, i) => ( + + {i > 0 && ( + + )} + {symptom} + ))} -

-
- )} - - {/* Active Ingredients & Composition Table */} - {product.main_ingredients && product.main_ingredients.length > 0 && ( -
-
- - ترکیبات موثره و فرمولاسیون دارویی: -
-
- {product.main_ingredients.slice(0, 4).map((ing, idx) => ( - - {ing} - - ))} -
-
- )} - - {/* Clinical Dosage Protocol */} - {product.dosage_logic && ( -
-
- - پروتکل بالینی تجویز و دوز مصرف: -
-

- {product.dosage_logic}

)} - {/* Specialist Endorsement */} - {product.specialist && product.specialist.name && ( -
-
- {product.specialist.image ? ( - {product.specialist.name} { - (e.target as HTMLElement).style.display = 'none'; - }} - /> - ) : ( - - )} -
-
-
- {product.specialist.name} - {product.specialist.title && ( - ({product.specialist.title}) - )} + {/* Section 2: Active Formulation (Short elegant paragraph, no tables) */} + {product.main_ingredients && product.main_ingredients.length > 0 && ( +
+ + ترکیبات و فرمولاسیون + +

+ {product.main_ingredients.join("، ")}. +

+
+ )} + + {/* Section 3: Clinical Dosage Protocol (Refined sequential numbering ۰۱, ۰۲ or single note) */} + {dosageRaw && ( +
+ + پروتکل دوز و نحوه مصرف + + {dosageSteps.length > 1 ? ( +
+ {dosageSteps.map((step, idx) => { + const numStr = idx === 0 ? "۰۱" : idx === 1 ? "۰۲" : "۰۳"; + return ( +
+ + {numStr} + + + {step} + +
+ ); + })}
- {product.specialist.message && ( -

- «{product.specialist.message}» -

- )} -
+ ) : ( +

+ {dosageRaw} +

+ )}
)}
- {/* 3. Page Footer */} -
-
- - Canina Pharma Germany • استانداردهای بالینی GMP -
- + {/* 3. Page Footer: Minimal luxury accreditation & page number */} +
+ + Canina Pharma Germany • Ph. Eur. & GMP Certified + + صفحه {pageNumber < 10 ? `۰${pageNumber}` : pageNumber} از {totalPages}
diff --git a/frontend/application/components/catalog/FlipbookCatalog.tsx b/frontend/application/components/catalog/FlipbookCatalog.tsx index 57eb2cc..c4cdbde 100644 --- a/frontend/application/components/catalog/FlipbookCatalog.tsx +++ b/frontend/application/components/catalog/FlipbookCatalog.tsx @@ -46,35 +46,52 @@ export default function FlipbookCatalog({ products }: FlipbookCatalogProps) { const containerRef = useRef(null); - // 1. Build Category Metadata with dynamic starting pages + // 1. Build Category Metadata with dynamic starting pages and luxury European apothecary palette const categoryMetaList: CategoryMeta[] = useMemo(() => { - const cats: { id: string; name: string; color: string; lightBg: string; borderBg: string; icon: React.ElementType; tagline: string; matcher: (p: Product) => boolean }[] = [ + const cats: { + id: string; + name: string; + color: string; + lightBg: string; + borderBg: string; + accentColor?: string; + secondaryColor?: string; + icon: React.ElementType; + tagline: string; + matcher: (p: Product) => boolean + }[] = [ { id: "joints", - name: "مفاصل، استخوان و اسکلت", - color: "#0284C7", - lightBg: "bg-sky-50", - borderBg: "border-sky-200", + name: "مفاصل و استخوان", + color: "#12211F", // پایه پاین تیره + lightBg: "#F3EEE0", // پنل روشن استخوانی + borderBg: "#C88A3F", // اکسنت کهربا / برنز + accentColor: "#C88A3F", + secondaryColor: "#6B8F71", // خزه‌ای کمرنگ icon: Activity, tagline: "بازسازی غضروف، هیدروکسی آپاتیت طبیعی و تراکم استخوان", - matcher: (p: Product) => (p.category || '').includes("مفاصل") || p.categorySlug === 'joints' + matcher: (p: Product) => (p.category || '').includes("مفاصل") || (p.category || '').includes("استخوان") || p.categorySlug === 'joints' }, { id: "special-care", name: "پوست، مو و بهداشت تخصصی", - color: "#0D9488", - lightBg: "bg-teal-50", - borderBg: "border-teal-200", + color: "#1A1F2E", // نیلی تیره + lightBg: "#EFEDF5", // خاکستری مرواریدی + borderBg: "#8C7BC9", // بنفش دوداری + accentColor: "#8C7BC9", + secondaryColor: "#B79FE0", // یاسی روشن icon: Sparkles, tagline: "تکنولوژی نقره میکروسیلور، اسیدهای چرب امگا و ترمیم بیولوژیک", - matcher: (p: Product) => (p.category || '').includes("پوست") || (p.category || '').includes("مراقبت") || p.categorySlug === 'special-care' + matcher: (p: Product) => (p.category || '').includes("پوست") || (p.category || '').includes("مراقبت") || (p.category || '').includes("بهداشت") || p.categorySlug === 'special-care' }, { id: "immune", name: "سیستم ایمنی و گوارش", - color: "#16A34A", - lightBg: "bg-emerald-50", - borderBg: "border-emerald-200", + color: "#14241F", // سبز جنگلی تیره + lightBg: "#EEF2E8", // سبز شیری + borderBg: "#7FA05C", // سبز زیتونی + accentColor: "#7FA05C", + secondaryColor: "#C9A15A", // طلایی خاکرس icon: ShieldCheck, tagline: "خمیر آغوز متمرکز (Colostrum) و تقویت فوری ایمونوگلوبولین‌ها", matcher: (p: Product) => (p.category || '').includes("ایمنی") || (p.category || '').includes("گوارش") || p.categorySlug === 'immune' @@ -82,9 +99,11 @@ export default function FlipbookCatalog({ products }: FlipbookCatalogProps) { { id: "vitamins", name: "ویتامین‌ها و انرژی‌بخش‌ها", - color: "#D97706", - lightBg: "bg-amber-50", - borderBg: "border-amber-200", + color: "#2B1810", // قهوه‌ای سوخته تیره + lightBg: "#FBF0DE", // کرم گرم + borderBg: "#D97D3D", // نارنجی زنگاری + accentColor: "#D97D3D", + secondaryColor: "#E8A94B", // کهربای روشن icon: Zap, tagline: "تامین عناصر کمیاب، هموگلوبین و توان فیزیکی پت‌ها", matcher: (p: Product) => (p.category || '').includes("ویتامین") || (p.category || '').includes("تقویت عمومی") || (p.category || '').includes("انرژی") || p.categorySlug === 'energy' || p.categorySlug === 'general' @@ -92,9 +111,11 @@ export default function FlipbookCatalog({ products }: FlipbookCatalogProps) { { id: "nutrition", name: "تغذیه تخصصی و رشد توله‌ها", - color: "#8B5CF6", - lightBg: "bg-purple-50", - borderBg: "border-purple-200", + color: "#1E1A2B", // بنفش شبانه + lightBg: "#F2EEF8", // لاواندر شیری + borderBg: "#9B6FB0", // بنفش عمیق + accentColor: "#9B6FB0", + secondaryColor: "#C79ED9", // ارکیده روشن icon: Baby, tagline: "شیرهای جایگزین مادر با پروتئین بالا و فرنی‌های تغذیه تکمیلی", matcher: (p: Product) => (p.category || '').includes("تغذیه") || (p.category || '').includes("مکمل") || p.categorySlug === 'nutrition' || p.categorySlug === 'supplements' || (!p.category && !p.categorySlug) @@ -111,6 +132,8 @@ export default function FlipbookCatalog({ products }: FlipbookCatalogProps) { color: cat.color, lightBg: cat.lightBg, borderBg: cat.borderBg, + accentColor: cat.accentColor || cat.borderBg, + secondaryColor: cat.secondaryColor || cat.color, icon: cat.icon, tagline: cat.tagline, startPage: currentStartPage @@ -170,20 +193,33 @@ export default function FlipbookCatalog({ products }: FlipbookCatalogProps) { return rawTotal % 2 === 0 ? rawTotal : rawTotal + 1; }, [orderedProducts.length]); + // Determine if device is currently in single-page mode (mobile viewport < 768px) + const isSinglePageMode = () => { + if (typeof window !== "undefined") { + return window.innerWidth < 768; + } + return false; + }; + // 3D Page Flip Forward in Persian (Left page turns over to the right!) const handleNext = () => { if (currentPage < TOTAL_PAGES && !isFlipping) { setIsFlipping(true); setFlipDirection("next"); + const single = isSinglePageMode(); + setTimeout(() => { setCurrentPage(prev => { + if (single) { + return Math.min(prev + 1, TOTAL_PAGES); + } if (prev === 1) return 2; // From cover (1) to spread (2-3) return Math.min(prev + 2, TOTAL_PAGES); }); setIsFlipping(false); setFlipDirection(null); - }, 650); + }, single ? 350 : 650); } }; @@ -193,14 +229,19 @@ export default function FlipbookCatalog({ products }: FlipbookCatalogProps) { setIsFlipping(true); setFlipDirection("prev"); + const single = isSinglePageMode(); + setTimeout(() => { setCurrentPage(prev => { + if (single) { + return Math.max(prev - 1, 1); + } if (prev <= 3) return 1; // Back to cover return Math.max(prev - 2, 1); }); setIsFlipping(false); setFlipDirection(null); - }, 650); + }, single ? 350 : 650); } }; @@ -657,18 +698,32 @@ export default function FlipbookCatalog({ products }: FlipbookCatalogProps) {
- {/* Mobile Single Page View with 3D Flip */} + {/* Mobile Single Page View with Touch Gesture Support */}
-
handleNext()} - className="w-full h-full" - > +
{renderSinglePage(currentPage)} + + {/* Invisible Left & Right Tap Zones for Mobile Navigation */} +
{ e.stopPropagation(); handleNext(); }} + className="absolute left-0 top-0 bottom-0 w-1/4 z-30 cursor-pointer active:bg-black/5 transition-colors" + title="صفحه بعدی" + /> +
{ e.stopPropagation(); handlePrev(); }} + className="absolute right-0 top-0 bottom-0 w-1/4 z-30 cursor-pointer active:bg-black/5 transition-colors" + title="صفحه قبلی" + /> + + {/* Subtle Swipe Guidance Hint on Bottom Center */} +
+ ← کشیدن برای ورق زدن → +