feat: complete currency, font, new pages, footer logo, dynamic PDP layout and custom dosage titles
@ -1,4 +1,4 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
@ -10,7 +10,7 @@ async function main() {
|
||||
{
|
||||
title: 'محصولات تخصصی مراقبت از مفاصل',
|
||||
subtitle: 'برای سگهای مسن و پرتحرک، تضمین سلامت و شادابی با کلاژن فعال',
|
||||
imageUrl: '/images/slider/slide1.webp', // Assuming we have these in public/images
|
||||
imageUrl: '/assets/images/hero-section-image.png',
|
||||
buttonText: 'مشاهده محصولات مفاصل',
|
||||
buttonLink: '/shop/joints',
|
||||
order: 1,
|
||||
@ -19,7 +19,7 @@ async function main() {
|
||||
{
|
||||
title: 'ویتامینهای ضروری برای رشد توله سگها',
|
||||
subtitle: 'رشد کامل استخوانها و تقویت سیستم ایمنی از ماه اول',
|
||||
imageUrl: '/images/slider/slide2.webp',
|
||||
imageUrl: '/assets/images/regenerated_image_1779109861747.png',
|
||||
buttonText: 'خرید ویتامین توله',
|
||||
buttonLink: '/shop/puppy',
|
||||
order: 2,
|
||||
@ -38,7 +38,7 @@ async function main() {
|
||||
{
|
||||
vetName: 'دکتر علیرضا رضایی',
|
||||
clinicName: 'کلینیک دامپزشکی پایتخت',
|
||||
imageUrl: '/images/vets/vet1.webp',
|
||||
imageUrl: '/assets/images/regenerated_image_1779109861747.png',
|
||||
quote: 'مکملهای مفصلی کانینا از نظر سرعت جذب و اثربخشی در سگهای نژاد بزرگ بینظیر هستند. ما نتایج فوقالعادهای روی دیسپلازی هیپ مشاهده کردیم.',
|
||||
rating: 5,
|
||||
order: 1,
|
||||
@ -47,7 +47,7 @@ async function main() {
|
||||
{
|
||||
vetName: 'دکتر سارا شمس',
|
||||
clinicName: 'بیمارستان دامپزشکی تهران',
|
||||
imageUrl: '/images/vets/vet2.webp',
|
||||
imageUrl: '/assets/images/regenerated_image_1779109861747.png',
|
||||
quote: 'من همیشه برای ریزش مو و مشکلات پوستی گربهها، قرصهای مخمر و بیوتین کانینا را تجویز میکنم. نتایج معمولاً در کمتر از ۳ هفته قابل مشاهده است.',
|
||||
rating: 5,
|
||||
order: 2,
|
||||
|
||||
@ -88,7 +88,7 @@ async function main() {
|
||||
|
||||
// Build display name with size
|
||||
const displayName = `${baseName} - ${sizeLabel}`;
|
||||
const priceDisplay = `${sellPrice.toLocaleString()} T`;
|
||||
const priceDisplay = `${sellPrice.toLocaleString()} تومان`;
|
||||
|
||||
const product = await prisma.product.upsert({
|
||||
where: { artNo },
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as ts from 'typescript';
|
||||
@ -84,7 +84,7 @@ async function main() {
|
||||
},
|
||||
{
|
||||
id: "silver",
|
||||
name: "نقره میکروسیلور (Microsilver)",
|
||||
name: "نقره میکروسیلور (Microsilver BG)",
|
||||
description: "ذرات نقره خالص با ساختار اسفنجی که به دلیل اندازه ذرات درشت، جذب خون نمیشوند اما اثر آنتیباکتریال پایداری بر سطح غشاها دارند. بر خلاف نقره کلوئیدی معمولی، میکروسیلور رسوب سطحی طولانیمدت ایجاد کرده و فلور طبیعی را تخریب نمیکند.",
|
||||
benefits: [
|
||||
"مبارزه با باکتریهای مقاوم در دهان و پوست",
|
||||
@ -95,7 +95,7 @@ async function main() {
|
||||
{
|
||||
id: "colostrum",
|
||||
name: "آغوز (Colostrum)",
|
||||
description: "اولین شیر پستانداران که حاوی دوز بالایی از ایمونوگلوبولینها (IgG, IgA, IgM)، لاکتوفرین و سایتوکاینها برای فعالسازی فوری سیستم ایمنی است. سد دفاعی روده را تقویت کرده و از نفوذ پاتوژنها جلوگیری میکند.",
|
||||
description: "اولین شیر پستانداران پس از زایمان که حاوی دوز بالایی از ایمونوگلوبولینها (IgG, IgA, IgM)، لاکتوفرین و سایتوکاینها برای فعالسازی فوری سیستم ایمنی است. سد دفاعی روده را تقویت کرده و از نفوذ پاتوژنها جلوگیری میکند.",
|
||||
benefits: [
|
||||
"تقویت سد دفاعی روده",
|
||||
"انتقال مستقیم آنتیبادی به نوزادان",
|
||||
@ -104,7 +104,7 @@ async function main() {
|
||||
},
|
||||
{
|
||||
id: "peat-extract",
|
||||
name: "عصاره پیت (Peat Extract)",
|
||||
name: "عصاره پیت (Peat Extract / Moor)",
|
||||
description: "مادهای کاملاً طبیعی حاصل از تجزیه گیاهان در طول هزاران سال که غنی از اسیدهای هومیک با ساختار پلیمری دارای بار منفی است. سموم، قارچها و باکتریهای مضر را در روده به دام انداخته و دفع میکند.",
|
||||
benefits: [
|
||||
"جذب سموم و فلزات سنگین در دستگاه گوارش",
|
||||
@ -115,31 +115,121 @@ async function main() {
|
||||
{
|
||||
id: "collagen",
|
||||
name: "کلاژن هیدرولیز شده",
|
||||
description: "پپتیدهای کلاژن نوع I و II با وزن مولکولی پایین که مستقیماً در ماتریکس غضروف مفصلی جذب شده و سنتز کلاژن را تحریک میکنند. پروتئین خالص ۹۴٪.",
|
||||
description: "پپتیدهای کلاژن نوع I و II با وزن مولکولی پایین که مستقیماً در ماتریکس غضروف مفصلی جذب شده و ساختار استخوانها و تاندونها را تقویت کرده و تحرک مفاصل را بهبود میبخشند.",
|
||||
benefits: [
|
||||
"بازسازی غضروف مفصلی",
|
||||
"تقویت بافت همبند",
|
||||
"تقویت بافت همبند و تاندونها",
|
||||
"بهبود خاصیت ارتجاعی مفاصل"
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "biotin",
|
||||
name: "بیوتین (ویتامین H / B7)",
|
||||
description: "کوآنزیم کربوکسیلازهای مسئول سنتز اسیدهای چرب و گلوکونئوژنز. با دوز ۱,۰۰۰,۰۰۰ میکروگرم در کیلوگرم در محصولات کانینا، قویترین دوز موجود در بازار مکملهای دامپزشکی.",
|
||||
name: "بیوتین (Biotin / Vitamin H)",
|
||||
description: "ویتامین ضروری از گروه B که به عنوان کوآنزیم در مسیرهای سنتز کراتین و چربیها عمل میکند. کمبود آن باعث ریزش مو، کدر شدن پوشش و شکنندگی پنجهها میشود.",
|
||||
benefits: [
|
||||
"جلوگیری از ریزش مو",
|
||||
"تقویت رنگدانه پوشش",
|
||||
"محکمسازی پنجه و ناخن"
|
||||
"جلوگیری از ریزش مو و بازسازی پوشش مویی",
|
||||
"تقویت رنگدانه طبیعی مو و بینی",
|
||||
"محکمسازی پنجه، ناخن و سمها"
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "taurin",
|
||||
name: "تورین",
|
||||
description: "اسید آمینه ضروری شرطی برای گربهها. بدن گربه قادر به سنتز تورین نیست و کمبود آن منجر به دژنراسیون مرکزی شبکیه (نابینایی) و کاردیومیوپاتی متسع میشود.",
|
||||
name: "تورین (Taurine)",
|
||||
description: "اسید آمینه بسیار حیاتی برای گربهها. بدن گربه قادر به سنتز تورین نیست و کمبود آن در رژیم غذایی میتواند به تخریب تدریجی شبکیه چشم (نابینایی) و بیماری قلبی منجر گردد.",
|
||||
benefits: [
|
||||
"سلامت بینایی و شبکیه چشم",
|
||||
"تقویت عضله قلب",
|
||||
"سیستم ایمنی گربه"
|
||||
"سلامت بینایی و شبکیه چشم گربهها",
|
||||
"تقویت عضله قلب و عملکرد پمپاژ خون",
|
||||
"پشتیبانی از سیستم ایمنی و تولید مثل"
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "salmon-oil",
|
||||
name: "روغن ماهی سالمون (Salmon Oil)",
|
||||
description: "روغن ماهی سالمون خالص، سرشار از اسیدهای چرب امگا ۳ (DHA و EPA) که به کاهش پاسخهای التهابی، سلامت سیستم قلبی عروقی و پوست و مو کمک شایانی میکند.",
|
||||
benefits: [
|
||||
"بهبود براقیت و لطافت پوست و مو",
|
||||
"خواص ضدالتهابی قوی در مفاصل",
|
||||
"تقویت سیستم ایمنی و عملکردهای شناختی"
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "black-cumin",
|
||||
name: "سیاه دانه (Black Cumin)",
|
||||
description: "دانههای سیاه دانه مصری غنی از اسیدهای چرب غیراشباع و روغنهای فرار گیاهی با عطر آجیلی قوی که عملکرد گوارش و متابولیسم را بهبود میبخشند.",
|
||||
benefits: [
|
||||
"تنظیم متابولیسم عمومی و هضم بهتر",
|
||||
"تقویت سیستم دفاعی طبیعی بدن",
|
||||
"خواص طبیعی ضد باکتری و ضدقارچ"
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "eggshell",
|
||||
name: "پودر پوسته تخم مرغ (Eggshell Powder)",
|
||||
description: "منبع طبیعی کلسیم ارگانیک با غلظت کلسیم بالا (۳۶٪) و مقدار ناچیز فسفر (۰.۱٪) جهت تنظیم نسبت کلسیم به فسفر در غذاهای گوشتی پخته یا خام.",
|
||||
benefits: [
|
||||
"تامین کلسیم بدون افزایش ناخواسته فسفر",
|
||||
"جایگزین عالی برای حیوانات دارای آلرژی به استخوان",
|
||||
"پشتیبانی از سلامت استخوان و دندان"
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "hawthorn",
|
||||
name: "زالزالک (Hawthorn)",
|
||||
description: "عصاره گیاهی دارویی با سابقه مصرف طولانی جهت مهار طبیعی آنزیمهای آسیبرسان و بهبود خونرسانی و کارایی کلی عضله قلب.",
|
||||
benefits: [
|
||||
"تقویت انقباضات ماهیچه قلب",
|
||||
"بهبود جریان خون در رگهای کرونری",
|
||||
"افزایش نشاط در سگ و گربههای مسن"
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "l-carnitine",
|
||||
name: "ال-کارنیتین (L-Carnitine)",
|
||||
description: "ترکیب شبهآمینه که با تسهیل انتقال اسیدهای چرب به درون میتوکندری، به تولید انرژی سلولی کمک کرده و از خستگی عضلانی جلوگیری مینماید.",
|
||||
benefits: [
|
||||
"تولید انرژی از چربیها در ماهیچه قلب",
|
||||
"بهبود قدرت بدنی و کاهش خستگی عضلات",
|
||||
"حمایت از متابولیسم سالم چربیها"
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "seaweed",
|
||||
name: "جلبک دریایی (Seaweed)",
|
||||
description: "جلبک قهوهای اقیانوسی ارگانیک حاوی اسیدهای آمینه، ویتامینها و ید طبیعی جهت کمک به تنظیم غده تیروئید و تقویت پیگمنتهای تیره حیوان.",
|
||||
benefits: [
|
||||
"تقویت رنگدانه بینی، پنجه و پوشش مویی",
|
||||
"بهبود هضم و جذب مواد مغذی",
|
||||
"پشتیبانی عمومی از سلامت غده تیروئید"
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "hyaluronic",
|
||||
name: "هیالورونات سدیم (Sodium Hyaluronate)",
|
||||
description: "مادهای فوقالعاده با خاصیت اتصال به آب بالا که روانکننده و مرطوبکننده قرنیه چشم بوده و از خشکی و خارش چشمها جلوگیری میکند.",
|
||||
benefits: [
|
||||
"شستشو و تسکین چشمهای تحریکشده و قرمز",
|
||||
"رطوبترسانی ماندگار به سطح خارجی قرنیه",
|
||||
"کمک به رفع چسبندگی و قی کردن چشم"
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "calendula-sea-buckthorn",
|
||||
name: "روغن کالاندولا و سنجد دریایی",
|
||||
description: "روغنهای طبیعی گیاهی با اثرات ضدالتهابی، بازسازیکننده و تسکیندهنده پوست که یک سد دفاعی فیزیکی و بیولوژیکی ایجاد میکنند.",
|
||||
benefits: [
|
||||
"ترمیم خشکی، ترک خوردگی و آسیبهای پنجه",
|
||||
"تسکین التهاب و قرمزی ناشی از گزش حشرات",
|
||||
"کمک به بازسازی سریعتر لایههای آسیبدیده پوست"
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "dodecanoic",
|
||||
name: "اسید دودکانوئیک و مارگوسا",
|
||||
description: "عوامل فعال طبیعی و گیاهی بدون مواد حشرهکش شیمیایی با خواص دورکننده قوی در برابر انگلهای خارجی نظیر کک، کنه و شپش.",
|
||||
benefits: [
|
||||
"دفع موثر کنهها، ککها و شپشهای گزنده",
|
||||
"جلوگیری از مستقر شدن انگلها و تخم آنها در محیط",
|
||||
"ایمن برای حیوان و اعضای خانواده در محیط خانه"
|
||||
]
|
||||
}
|
||||
]),
|
||||
|
||||
|
Before Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 50 KiB |
@ -1,6 +1,6 @@
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { X, Upload, Image as ImageIcon, Trash2, CheckCircle2, Clipboard } from 'lucide-react';
|
||||
import api from '../../services/api';
|
||||
import api, { BASE_DOMAIN } from '../../services/api';
|
||||
import Spinner from './Spinner';
|
||||
|
||||
interface Media {
|
||||
@ -186,7 +186,7 @@ export default function MediaSelector({ isOpen, onClose, onSelect, multiple = fa
|
||||
) : (
|
||||
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
|
||||
{mediaList.map((media) => {
|
||||
const imgUrl = media.url.startsWith('http') ? media.url : `https://apicanina.parsaaghayi.ir${media.url}`;
|
||||
const imgUrl = media.url.startsWith('http') ? media.url : `${BASE_DOMAIN}${media.url}`;
|
||||
const isSelected = selectedUrl && imgUrl === selectedUrl;
|
||||
return (
|
||||
<div
|
||||
|
||||
@ -26,22 +26,22 @@
|
||||
}
|
||||
|
||||
@theme {
|
||||
--font-sans: "Vazirmatn", sans-serif;
|
||||
--font-vazir: "Vazirmatn", sans-serif;
|
||||
--font-shabnam: "Shabnam", sans-serif;
|
||||
--font-sans: "Vazirmatn";
|
||||
--font-vazir: "Vazirmatn";
|
||||
--font-shabnam: "Shabnam";
|
||||
--font-lalezar: "Lalezar", cursive;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
font-family: "Vazirmatn", sans-serif !important;
|
||||
font-family: "Vazirmatn" !important;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--color-gray-50);
|
||||
color: var(--color-gray-900);
|
||||
margin: 0;
|
||||
font-family: "Vazirmatn", sans-serif !important;
|
||||
font-family: "Vazirmatn" !important;
|
||||
}
|
||||
|
||||
button, a {
|
||||
@ -51,6 +51,6 @@
|
||||
|
||||
@layer utilities {
|
||||
.font-vazir {
|
||||
font-family: "Vazirmatn", sans-serif;
|
||||
font-family: "Vazirmatn";
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Search, Plus, Edit2, Trash2, FileText, Image as ImageIcon, CheckCircle2, XCircle } from 'lucide-react';
|
||||
import api from '../services/api';
|
||||
import api, { BASE_DOMAIN } from '../services/api';
|
||||
import Spinner from '../components/ui/Spinner';
|
||||
import Pagination from '../components/ui/Pagination';
|
||||
import MediaSelector from '../components/ui/MediaSelector';
|
||||
@ -152,7 +152,7 @@ export default function Blogs() {
|
||||
<tr key={blog.id} className="hover:bg-gray-50/50 transition-colors">
|
||||
<td className="py-3 px-6">
|
||||
{blog.imageUrl ? (
|
||||
<img src={blog.imageUrl.startsWith('http') ? blog.imageUrl : `https://apicanina.parsaaghayi.ir${blog.imageUrl}`} alt="blog" className="w-16 h-10 rounded-lg object-cover border border-gray-200" />
|
||||
<img src={blog.imageUrl.startsWith('http') ? blog.imageUrl : `${BASE_DOMAIN}${blog.imageUrl}`} alt="blog" className="w-16 h-10 rounded-lg object-cover border border-gray-200" />
|
||||
) : (
|
||||
<div className="w-16 h-10 rounded-lg bg-gray-100 flex items-center justify-center text-gray-400">
|
||||
<ImageIcon className="w-4 h-4" />
|
||||
@ -222,7 +222,7 @@ export default function Blogs() {
|
||||
<label className="text-sm font-bold text-gray-700">تصویر شاخص</label>
|
||||
<div className="flex items-center gap-4">
|
||||
{formData.imageUrl ? (
|
||||
<img src={formData.imageUrl.startsWith('http') ? formData.imageUrl : `https://apicanina.parsaaghayi.ir${formData.imageUrl}`} alt="preview" className="w-24 h-16 rounded-xl object-cover border border-gray-200" />
|
||||
<img src={formData.imageUrl.startsWith('http') ? formData.imageUrl : `${BASE_DOMAIN}${formData.imageUrl}`} alt="preview" className="w-24 h-16 rounded-xl object-cover border border-gray-200" />
|
||||
) : (
|
||||
<div className="w-24 h-16 rounded-xl bg-gray-100 flex items-center justify-center text-gray-400">
|
||||
<ImageIcon className="w-6 h-6" />
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Search, Plus, Edit2, Trash2, FolderTree, Image as ImageIcon, X } from 'lucide-react';
|
||||
import api from '../services/api';
|
||||
import api, { BASE_DOMAIN } from '../services/api';
|
||||
import Spinner from '../components/ui/Spinner';
|
||||
import Pagination from '../components/ui/Pagination';
|
||||
import MediaSelector from '../components/ui/MediaSelector';
|
||||
@ -158,7 +158,7 @@ export default function Categories() {
|
||||
<tr key={cat.id} className="hover:bg-gray-50/50 transition-colors">
|
||||
<td className="py-3 px-6">
|
||||
{cat.imageUrl ? (
|
||||
<img src={cat.imageUrl.startsWith('http') ? cat.imageUrl : `https://apicanina.parsaaghayi.ir${cat.imageUrl}`} alt={cat.name} className="w-12 h-12 rounded-xl object-cover border border-gray-200" />
|
||||
<img src={cat.imageUrl.startsWith('http') ? cat.imageUrl : `${BASE_DOMAIN}${cat.imageUrl}`} alt={cat.name} className="w-12 h-12 rounded-xl object-cover border border-gray-200" />
|
||||
) : (
|
||||
<div className="w-12 h-12 rounded-xl bg-gray-100 flex items-center justify-center text-gray-400">
|
||||
<ImageIcon className="w-5 h-5" />
|
||||
@ -240,7 +240,7 @@ export default function Categories() {
|
||||
<label className="text-sm font-bold text-gray-700">تصویر دستهبندی</label>
|
||||
<div className="flex items-center gap-4">
|
||||
{formData.imageUrl ? (
|
||||
<img src={formData.imageUrl.startsWith('http') ? formData.imageUrl : `https://apicanina.parsaaghayi.ir${formData.imageUrl}`} alt="preview" className="w-16 h-16 rounded-xl object-cover border border-gray-200" />
|
||||
<img src={formData.imageUrl.startsWith('http') ? formData.imageUrl : `${BASE_DOMAIN}${formData.imageUrl}`} alt="preview" className="w-16 h-16 rounded-xl object-cover border border-gray-200" />
|
||||
) : (
|
||||
<div className="w-16 h-16 rounded-xl bg-gray-100 flex items-center justify-center text-gray-400">
|
||||
<ImageIcon className="w-6 h-6" />
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { Upload, Image as ImageIcon, Trash2, Copy, CheckCircle2, Search, X, FolderOpen } from 'lucide-react';
|
||||
import api from '../services/api';
|
||||
import api, { BASE_DOMAIN } from '../services/api';
|
||||
import Spinner from '../components/ui/Spinner';
|
||||
|
||||
interface Media {
|
||||
@ -102,7 +102,7 @@ export default function MediaManager() {
|
||||
};
|
||||
|
||||
const handleCopyUrl = async (media: Media) => {
|
||||
const fullUrl = media.url.startsWith('http') ? media.url : `https://apicanina.parsaaghayi.ir${media.url}`;
|
||||
const fullUrl = media.url.startsWith('http') ? media.url : `${BASE_DOMAIN}${media.url}`;
|
||||
try {
|
||||
await navigator.clipboard.writeText(fullUrl);
|
||||
setCopiedId(media.id);
|
||||
@ -202,7 +202,7 @@ export default function MediaManager() {
|
||||
) : (
|
||||
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4 p-6">
|
||||
{filtered.map(media => {
|
||||
const imgUrl = media.url.startsWith('http') ? media.url : `https://apicanina.parsaaghayi.ir${media.url}`;
|
||||
const imgUrl = media.url.startsWith('http') ? media.url : `${BASE_DOMAIN}${media.url}`;
|
||||
return (
|
||||
<div
|
||||
key={media.id}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Search, Trash2, Heart, Image as ImageIcon } from 'lucide-react';
|
||||
import api from '../services/api';
|
||||
import api, { BASE_DOMAIN } from '../services/api';
|
||||
import Spinner from '../components/ui/Spinner';
|
||||
import Pagination from '../components/ui/Pagination';
|
||||
|
||||
@ -91,7 +91,7 @@ export default function Pets() {
|
||||
<tr key={pet.id} className="hover:bg-gray-50/50 transition-colors">
|
||||
<td className="py-3 px-6">
|
||||
{pet.imageUrl ? (
|
||||
<img src={pet.imageUrl.startsWith('http') ? pet.imageUrl : `https://apicanina.parsaaghayi.ir${pet.imageUrl}`} alt={pet.name} className="w-12 h-12 rounded-full object-cover border-2 border-purple-100" />
|
||||
<img src={pet.imageUrl.startsWith('http') ? pet.imageUrl : `${BASE_DOMAIN}${pet.imageUrl}`} alt={pet.name} className="w-12 h-12 rounded-full object-cover border-2 border-purple-100" />
|
||||
) : (
|
||||
<div className="w-12 h-12 rounded-full bg-purple-50 flex items-center justify-center text-purple-300 border-2 border-purple-100">
|
||||
<ImageIcon className="w-5 h-5" />
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Search, Filter, Box, Plus, Edit2, Trash2, Image as ImageIcon, X } from 'lucide-react';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import api from '../services/api';
|
||||
import api, { BASE_DOMAIN } from '../services/api';
|
||||
import Spinner from '../components/ui/Spinner';
|
||||
import Pagination from '../components/ui/Pagination';
|
||||
import MediaSelector from '../components/ui/MediaSelector';
|
||||
@ -214,7 +214,7 @@ export default function Products() {
|
||||
<tr key={product.id} className="hover:bg-gray-50/50 transition-colors">
|
||||
<td className="py-3 px-6">
|
||||
{product.imageUrl ? (
|
||||
<img src={product.imageUrl.startsWith('http') ? product.imageUrl : `https://apicanina.parsaaghayi.ir${product.imageUrl}`} alt={product.name} className="w-12 h-12 rounded-xl object-cover border border-gray-200" />
|
||||
<img src={product.imageUrl.startsWith('http') ? product.imageUrl : `${BASE_DOMAIN}${product.imageUrl}`} alt={product.name} className="w-12 h-12 rounded-xl object-cover border border-gray-200" />
|
||||
) : (
|
||||
<div className="w-12 h-12 rounded-xl bg-gray-100 flex items-center justify-center text-gray-400">
|
||||
<ImageIcon className="w-5 h-5" />
|
||||
@ -385,7 +385,7 @@ export default function Products() {
|
||||
{formData.imageUrl ? (
|
||||
<div className="w-full flex flex-col items-center">
|
||||
<div className="relative group">
|
||||
<img src={formData.imageUrl.startsWith('http') ? formData.imageUrl : `https://apicanina.parsaaghayi.ir${formData.imageUrl}`} alt="product" className="max-w-xs h-48 object-cover rounded-xl shadow-md" />
|
||||
<img src={formData.imageUrl.startsWith('http') ? formData.imageUrl : `${BASE_DOMAIN}${formData.imageUrl}`} alt="product" className="max-w-xs h-48 object-cover rounded-xl shadow-md" />
|
||||
<div className="absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded-xl flex items-center justify-center gap-3">
|
||||
<button type="button" onClick={() => setIsMediaSelectorOpen(true)} className="bg-white text-gray-800 px-4 py-2 rounded-lg font-bold text-sm">تغییر عکس</button>
|
||||
</div>
|
||||
@ -435,7 +435,7 @@ export default function Products() {
|
||||
isOpen={isMediaSelectorOpen}
|
||||
onClose={() => setIsMediaSelectorOpen(false)}
|
||||
onSelect={(url) => setFormData({...formData, imageUrl: url})}
|
||||
selectedUrl={formData.imageUrl.startsWith('http') ? formData.imageUrl : formData.imageUrl ? `https://apicanina.parsaaghayi.ir${formData.imageUrl}` : undefined}
|
||||
selectedUrl={formData.imageUrl.startsWith('http') ? formData.imageUrl : formData.imageUrl ? `${BASE_DOMAIN}${formData.imageUrl}` : undefined}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -1,7 +1,13 @@
|
||||
import axios from 'axios';
|
||||
|
||||
export const BASE_DOMAIN = import.meta.env.VITE_API_URL
|
||||
? import.meta.env.VITE_API_URL.replace(/\/api$/, '')
|
||||
: (import.meta.env.DEV ? 'http://127.0.0.1:4001' : 'https://apicanina.parsaaghayi.ir');
|
||||
|
||||
const baseURL = `${BASE_DOMAIN}/api`;
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: 'https://apicanina.parsaaghayi.ir/api', // Backend NestJS API URL
|
||||
baseURL,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
|
||||
81
frontend/application/app/about/page.tsx
Normal file
@ -0,0 +1,81 @@
|
||||
import type { Metadata } from "next";
|
||||
import { ShieldCheck, History, Award, CheckCircle } from "lucide-react";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "درباره ما",
|
||||
description: "داستان کانینا ایران و میراث ۴۰ ساله شرکت Canina pharma GmbH آلمان در تولید مکملهای فوقتخصصی دامپزشکی.",
|
||||
};
|
||||
|
||||
export default function AboutPage() {
|
||||
return (
|
||||
<div className="bg-medical-gray-50 py-16 px-4 sm:px-6 lg:px-8 font-vazir" dir="rtl">
|
||||
<div className="max-w-4xl mx-auto space-y-16">
|
||||
|
||||
{/* Hero Section */}
|
||||
<div className="text-center space-y-4">
|
||||
<span 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">
|
||||
<History className="w-4 h-4" />
|
||||
داستان ما از ۱۹۸۴
|
||||
</span>
|
||||
<h1 className="text-4xl lg:text-5xl font-black text-medical-gray-900 leading-tight">
|
||||
درباره <span className="text-canina-blue italic">کانینا ایران</span>
|
||||
</h1>
|
||||
<p className="text-lg text-medical-gray-500 max-w-2xl mx-auto leading-relaxed">
|
||||
میراث علمی و تعهد ما به تدارک هوشمندانه سلامت برای همراهان وفادار شما.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Brand Image Placeholder / Card */}
|
||||
<div className="relative bg-canina-blue rounded-[3rem] p-12 overflow-hidden text-white shadow-2xl">
|
||||
<div className="absolute inset-0 opacity-10 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')]" />
|
||||
<div className="relative z-10 space-y-6">
|
||||
<h2 className="text-3xl font-black italic">Canina pharma GmbH</h2>
|
||||
<p className="text-base text-white/80 leading-relaxed max-w-2xl">
|
||||
شرکت Canina pharma GmbH در سال ۱۹۸۴ توسط پتر و کریستین کرشنمایر در شهر برگیش گلادباخ آلمان تأسیس شد. این کمپانی با فلسفه «مادر طبیعت بهترین نسخه را میداند»، برای بیش از ۴۰ سال است که استاندارد طلایی مکملهای دامپزشکی را در جهان تعریف میکند.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Narrative Section */}
|
||||
<div className="space-y-8 text-medical-gray-700 leading-relaxed">
|
||||
<p>
|
||||
امروز محصولات کانینا در بیش از ۴۰ کشور جهان توزیع میشود. کانینا ایران به عنوان نماینده رسمی این برند، با هدف ارتقای کیفیت زندگی حیوانات خانگی و دسترسی آسان جامعه دامپزشکی و دارندگان حیوانات به این مکملهای ارزشمند، فعالیت خود را آغاز نموده است. تمامی محصولات با بستهبندی اصلی آلمان و دارای برچسب اصالت سازمان دامپزشکی ارائه میشوند.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Key Features Grid */}
|
||||
<div className="grid md:grid-cols-3 gap-6">
|
||||
<div className="bg-white border border-medical-gray-200 rounded-[2rem] p-8 shadow-sm hover:shadow-xl transition-all">
|
||||
<div className="w-12 h-12 bg-canina-blue text-white rounded-2xl flex items-center justify-center mb-6">
|
||||
<ShieldCheck className="w-6 h-6" />
|
||||
</div>
|
||||
<h3 className="text-lg font-black text-medical-gray-900 mb-2">گرید فوقدارویی</h3>
|
||||
<p className="text-sm text-medical-gray-500 font-bold leading-relaxed">
|
||||
استفاده از مواد اولیه کاملاً طبیعی و فرآوری شده در بالاترین سطح کیفی دارویی مطابق استانداردهای اروپا.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-white border border-medical-gray-200 rounded-[2rem] p-8 shadow-sm hover:shadow-xl transition-all">
|
||||
<div className="w-12 h-12 bg-canina-blue text-white rounded-2xl flex items-center justify-center mb-6">
|
||||
<Award className="w-6 h-6" />
|
||||
</div>
|
||||
<h3 className="text-lg font-black text-medical-gray-900 mb-2">گواهیهای بینالمللی</h3>
|
||||
<p className="text-sm text-medical-gray-500 font-bold leading-relaxed">
|
||||
دارای تأییدیههای IFS Food و HACCP که ایمنی، سلامت و یکپارچگی خطوط تولید را تضمین میکند.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-white border border-medical-gray-200 rounded-[2rem] p-8 shadow-sm hover:shadow-xl transition-all">
|
||||
<div className="w-12 h-12 bg-canina-blue text-white rounded-2xl flex items-center justify-center mb-6">
|
||||
<CheckCircle className="w-6 h-6" />
|
||||
</div>
|
||||
<h3 className="text-lg font-black text-medical-gray-900 mb-2">تعهد به اصالت</h3>
|
||||
<p className="text-sm text-medical-gray-500 font-bold leading-relaxed">
|
||||
ارائه محصولات اصل با ضمانت اصالت کالا و برچسبهای رهگیری قانونی وزارت بهداشت و دامپزشکی.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
106
frontend/application/app/contact/page.tsx
Normal file
@ -0,0 +1,106 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Mail, Phone, MapPin, Clock, Send } from "lucide-react";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "تماس با ما",
|
||||
description: "راههای ارتباطی با نمایندگی رسمی مکملهای دامپزشکی کانینا در ایران.",
|
||||
};
|
||||
|
||||
export default function ContactPage() {
|
||||
return (
|
||||
<div className="bg-medical-gray-50 py-16 px-4 sm:px-6 lg:px-8 font-vazir" dir="rtl">
|
||||
<div className="max-w-6xl mx-auto space-y-16">
|
||||
|
||||
{/* Title */}
|
||||
<div className="text-center space-y-4">
|
||||
<span 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">
|
||||
پاسخگوی شما هستیم
|
||||
</span>
|
||||
<h1 className="text-4xl lg:text-5xl font-black text-medical-gray-900 leading-tight">
|
||||
تماس با <span className="text-canina-blue italic">کانینا ایران</span>
|
||||
</h1>
|
||||
<p className="text-lg text-medical-gray-500 max-w-2xl mx-auto leading-relaxed">
|
||||
جهت مشاوره تخصصی، خرید عمده و پیگیری سفارشات با ما در ارتباط باشید.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid lg:grid-cols-12 gap-12 items-start">
|
||||
{/* Contact Details */}
|
||||
<div className="lg:col-span-5 space-y-8">
|
||||
<h3 className="text-2xl font-black text-medical-gray-900">اطلاعات نمایندگی</h3>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="flex gap-4 p-6 bg-white border border-medical-gray-200 rounded-[2rem] shadow-sm">
|
||||
<div className="w-12 h-12 bg-canina-blue/5 text-canina-blue rounded-2xl flex items-center justify-center shrink-0">
|
||||
<Phone className="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-xs font-black text-medical-gray-400 uppercase tracking-wider mb-1">تلفنهای تماس</h4>
|
||||
<p className="text-lg font-black text-medical-gray-900 tracking-wider">۰۲۱-۸۸۸۸ ۴۴۴۴</p>
|
||||
<p className="text-sm text-medical-gray-500 font-bold">شنبه تا چهارشنبه ۹:۰۰ الی ۱۸:۰۰</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-4 p-6 bg-white border border-medical-gray-200 rounded-[2rem] shadow-sm">
|
||||
<div className="w-12 h-12 bg-canina-blue/5 text-canina-blue rounded-2xl flex items-center justify-center shrink-0">
|
||||
<Mail className="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-xs font-black text-medical-gray-400 uppercase tracking-wider mb-1">پست الکترونیک</h4>
|
||||
<p className="text-sm font-black text-medical-gray-900">info@canino-iran.com</p>
|
||||
<p className="text-xs text-medical-gray-500 font-bold">پاسخگویی در کمتر از ۲۴ ساعت کاری</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-4 p-6 bg-white border border-medical-gray-200 rounded-[2rem] shadow-sm">
|
||||
<div className="w-12 h-12 bg-canina-blue/5 text-canina-blue rounded-2xl flex items-center justify-center shrink-0">
|
||||
<MapPin className="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-xs font-black text-medical-gray-400 uppercase tracking-wider mb-1">نشانی دفتر مرکزی</h4>
|
||||
<p className="text-sm font-bold text-medical-gray-900 leading-relaxed">
|
||||
تهران، جردن، خیابان سعیدی، ساختمان کانینا، طبقه ۵، واحد ۱۹
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Contact Form */}
|
||||
<div className="lg:col-span-7 bg-white border border-medical-gray-200 rounded-[3rem] p-10 shadow-xl">
|
||||
<h3 className="text-2xl font-black text-medical-gray-900 mb-8">ارسال پیام مستقیم</h3>
|
||||
|
||||
<form className="space-y-6">
|
||||
<div className="grid md:grid-cols-2 gap-6">
|
||||
<div className="space-y-2">
|
||||
<label className="text-xs font-black text-medical-gray-500">نام و نام خانوادگی</label>
|
||||
<input type="text" className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl p-4 text-sm font-bold focus:outline-none focus:ring-2 focus:ring-canina-blue/20" />
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-xs font-black text-medical-gray-500">شماره موبایل</label>
|
||||
<input type="text" className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl p-4 text-sm font-bold text-left focus:outline-none focus:ring-2 focus:ring-canina-blue/20" dir="ltr" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="text-xs font-black text-medical-gray-500">موضوع پیام</label>
|
||||
<input type="text" className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl p-4 text-sm font-bold focus:outline-none focus:ring-2 focus:ring-canina-blue/20" />
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="text-xs font-black text-medical-gray-500">متن پیام</label>
|
||||
<textarea rows={4} className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl p-4 text-sm font-bold focus:outline-none focus:ring-2 focus:ring-canina-blue/20"></textarea>
|
||||
</div>
|
||||
|
||||
<button type="button" className="w-full bg-canina-blue text-white py-4 rounded-2xl font-black flex items-center justify-center gap-2 hover:shadow-xl hover:shadow-canina-blue/20 transition-all">
|
||||
<Send className="w-5 h-5 rotate-180" />
|
||||
ارسال پیام
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -70,13 +70,13 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
@theme {
|
||||
--font-sans: "Vazirmatn", sans-serif;
|
||||
--font-vazir: "Vazirmatn", sans-serif;
|
||||
--font-shabnam: "Shabnam", sans-serif;
|
||||
--font-sahel: "Sahel", sans-serif;
|
||||
--font-sans: "Vazirmatn";
|
||||
--font-vazir: "Vazirmatn";
|
||||
--font-shabnam: "Shabnam";
|
||||
--font-sahel: "Sahel";
|
||||
--font-lalezar: "Lalezar", cursive;
|
||||
--font-nastaliq: "IranNastaliq", serif;
|
||||
--font-iranian-sans: "IranianSans", sans-serif;
|
||||
--font-iranian-sans: "IranianSans";
|
||||
|
||||
/* Brand Colors */
|
||||
--color-canina-blue: #1E4053;
|
||||
@ -99,11 +99,11 @@
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
font-family: "Vazirmatn", sans-serif !important;
|
||||
font-family: "Vazirmatn" !important;
|
||||
}
|
||||
|
||||
html, body, #root {
|
||||
font-family: "Vazirmatn", sans-serif !important;
|
||||
font-family: "Vazirmatn" !important;
|
||||
@apply bg-medical-gray-50 text-medical-gray-900 antialiased;
|
||||
font-feature-settings: "ss01", "ss02", "cv01", "cv11";
|
||||
}
|
||||
@ -133,7 +133,7 @@
|
||||
|
||||
@layer utilities {
|
||||
.font-vazir {
|
||||
font-family: "Vazirmatn", sans-serif;
|
||||
font-family: "Vazirmatn";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
61
frontend/application/app/privacy/page.tsx
Normal file
@ -0,0 +1,61 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Shield } from "lucide-react";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "حریم خصوصی",
|
||||
description: "سیاستهای حفاظت از اطلاعات شخصی کاربران در وبسایت کانینا ایران.",
|
||||
};
|
||||
|
||||
export default function PrivacyPage() {
|
||||
return (
|
||||
<div className="bg-medical-gray-50 py-16 px-4 sm:px-6 lg:px-8 font-vazir" dir="rtl">
|
||||
<div className="max-w-4xl mx-auto space-y-12">
|
||||
|
||||
{/* Header */}
|
||||
<div className="text-center space-y-4">
|
||||
<div className="w-16 h-16 bg-canina-blue/10 text-canina-blue rounded-[2rem] flex items-center justify-center mx-auto mb-6">
|
||||
<Shield className="w-8 h-8" />
|
||||
</div>
|
||||
<h1 className="text-4xl lg:text-5xl font-black text-medical-gray-900 leading-tight">
|
||||
حریم خصوصی کاربران
|
||||
</h1>
|
||||
<p className="text-lg text-medical-gray-500 max-w-2xl mx-auto leading-relaxed">
|
||||
تعهد ما به امنیت دادهها و اطلاعات شخصی ثبت شده در وبسایت کانینا ایران.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Content Document */}
|
||||
<div className="bg-white border border-medical-gray-200 rounded-[3rem] p-10 md:p-12 shadow-xl space-y-8 text-medical-gray-700 leading-relaxed">
|
||||
<section className="space-y-4">
|
||||
<h3 className="text-xl font-black text-medical-gray-900">۱. جمعآوری اطلاعات</h3>
|
||||
<p>
|
||||
ما برای ارائه خدمات بهتر، از جمله پردازش سفارشات خرید، ثبت مشخصات شناسنامه پت شما در پرونده پزشکی و ارائه هشدارهای هوشمند دورههای درمان، اطلاعات محدودی نظیر شماره تماس، نام، آدرس تحویل و مشخصات حیوان خانگی شما را جمعآوری میکنیم.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section className="space-y-4">
|
||||
<h3 className="text-xl font-black text-medical-gray-900">۲. استفاده از اطلاعات</h3>
|
||||
<p>
|
||||
اطلاعات دریافتی شما صرفاً برای مقاصد عملیاتی سایت (ارسال محصولات، هماهنگیهای پشتیبانی، یادآوری تمدید خودکار مکملها و بهینهسازی تجربه خرید) استفاده خواهد شد و به هیچ عنوان در اختیار شرکتها یا سازمانهای ثالث قرار نمیگیرد.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section className="space-y-4">
|
||||
<h3 className="text-xl font-black text-medical-gray-900">۳. امنیت دادهها</h3>
|
||||
<p>
|
||||
تمامی اطلاعات حساس کاربران با استفاده از پروتکلهای امنیتی استاندارد و بستر امن HTTPS رمزگذاری شده و بر روی سرورهای ابری محافظت شده ذخیره میگردند. تیم فنی کانینا متعهد به پایش مداوم و بهروزرسانی سیستمهای امنیتی جهت جلوگیری از دسترسیهای غیرمجاز است.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section className="space-y-4">
|
||||
<h3 className="text-xl font-black text-medical-gray-900">۴. حقوق کاربران</h3>
|
||||
<p>
|
||||
شما در هر زمان میتوانید با ورود به پنل کاربری خود اقدام به تصحیح، تغییر یا حذف کامل مشخصات پرونده، نشانیها و اطلاعات کاربری خود نمایید.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -139,7 +139,7 @@ const ArchiveProductCard: React.FC<{ product: Product, onClick: (p: Product) =>
|
||||
|
||||
<div className="p-6 flex flex-col flex-1">
|
||||
<div className="text-[10px] font-bold text-canina-blue uppercase tracking-widest mb-2">{product.category}</div>
|
||||
<h3 className="text-lg font-black text-medical-gray-900 group-hover:text-canina-blue transition-colors mb-3 leading-tight">{product.name}</h3>
|
||||
<h3 dir="ltr" className="text-lg font-black text-medical-gray-900 group-hover:text-canina-blue transition-colors mb-3 leading-tight text-left">{product.name}</h3>
|
||||
|
||||
<div className="flex flex-wrap gap-1 mb-6">
|
||||
{product.symptoms.slice(0, 2).map((s, i) => (
|
||||
|
||||
@ -69,7 +69,7 @@ function ProductCard({ product, onClick }: { product: Product; key?: string | nu
|
||||
{/* Content Area */}
|
||||
<div className="p-8 flex flex-col flex-1">
|
||||
<div className="flex items-start justify-between mb-4 gap-2">
|
||||
<h3 className="text-xl font-black text-medical-gray-900 group-hover:text-canina-blue transition-colors leading-tight">
|
||||
<h3 dir="ltr" className="text-xl font-black text-medical-gray-900 group-hover:text-canina-blue transition-colors leading-tight text-left">
|
||||
{product.name}
|
||||
</h3>
|
||||
<ShieldCheck className="w-6 h-6 text-canina-blue flex-shrink-0" />
|
||||
|
||||
@ -16,13 +16,11 @@ export default function Footer({ onNavigate, onShopNavigate, onB2BOpen }: {
|
||||
|
||||
{/* Brand Presence */}
|
||||
<div className="space-y-8">
|
||||
<div className="flex items-center gap-4 cursor-pointer group" onClick={() => onNavigate("home")}>
|
||||
<div className="w-16 h-16 bg-white rounded-2xl flex items-center justify-center p-2 group-hover:scale-105 transition-transform">
|
||||
<img src="https://canina.de/media/fb/d5/47/1683116813/Logo.png" alt="Canina Logo" className="w-full h-auto" referrerPolicy="no-referrer" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-2xl font-black italic tracking-tighter">{getText('footer_brand_title', "کانینا ایران")}</h3>
|
||||
<p className="text-[10px] text-white/40 font-bold uppercase tracking-widest">{getText('footer_brand_subtitle', "نماینده رسمی در ایران")}</p>
|
||||
<div className="flex items-center gap-3 cursor-pointer group" onClick={() => onNavigate("home")}>
|
||||
<div className="w-12 h-12 bg-canina-blue rounded-2xl flex items-center justify-center text-white font-bold text-2xl group-hover:bg-medical-gray-900 transition-all shadow-xl shadow-canina-blue/20 italic">C</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-white font-black text-2xl tracking-tighter leading-none italic font-sans">Canina <span className="text-sm not-italic font-medium border-l-2 border-white/20 pl-2 ml-2 font-vazir">{getText('brand_name_fa', "ایران")}</span></span>
|
||||
<span className="text-[10px] text-white/40 font-bold uppercase tracking-widest leading-none mt-1.5 font-vazir">{getText('brand_subtitle', "نماینده رسمی Canina Pharma GmbH آلمان")}</span>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm text-white/60 leading-relaxed font-medium">
|
||||
@ -119,9 +117,9 @@ export default function Footer({ onNavigate, onShopNavigate, onB2BOpen }: {
|
||||
<div className="pt-12 border-t border-white/5 flex flex-col md:flex-row items-center justify-between gap-6 text-[10px] font-black text-white/20 uppercase tracking-[0.3em]">
|
||||
<div>{getText('footer_copyright', "© ۲۰۲۶ کانینا ایران. تمامی حقوق محفوظ است.")}</div>
|
||||
<div className="flex gap-8 font-vazir">
|
||||
<button onClick={() => onNavigate("home")} className="hover:text-white transition-colors">{getText('footer_about', "درباره ما")}</button>
|
||||
<button onClick={() => onNavigate("home")} className="hover:text-white transition-colors">{getText('footer_contact', "تماس با ما")}</button>
|
||||
<button className="hover:text-white transition-colors">{getText('footer_privacy', "حریم خصوصی")}</button>
|
||||
<button onClick={() => onNavigate("about")} className="hover:text-white transition-colors">{getText('footer_about', "درباره ما")}</button>
|
||||
<button onClick={() => onNavigate("contact")} className="hover:text-white transition-colors">{getText('footer_contact', "تماس با ما")}</button>
|
||||
<button onClick={() => onNavigate("privacy")} className="hover:text-white transition-colors">{getText('footer_privacy', "حریم خصوصی")}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -127,10 +127,33 @@ export default function IngredientWiki() {
|
||||
return (
|
||||
<div className="space-y-32">
|
||||
{filtered.map((ing, idx) => {
|
||||
const hasIngredient = products.filter(p =>
|
||||
p.main_ingredients?.some(mi => mi.toLowerCase().includes(ing.name.toLowerCase())) ||
|
||||
p.main_ingredients?.some(mi => mi.toLowerCase().includes(ing.id.replace('-', ' ')))
|
||||
);
|
||||
const hasIngredient = products.filter(p => {
|
||||
const ingNameClean = ing.name.split('(')[0].trim().toLowerCase();
|
||||
const ingIdClean = ing.id.replace(/-/g, ' ').toLowerCase();
|
||||
|
||||
return p.main_ingredients?.some(mi => {
|
||||
const miClean = mi.toLowerCase();
|
||||
return miClean.includes(ingNameClean) ||
|
||||
ingNameClean.includes(miClean) ||
|
||||
miClean.includes(ingIdClean) ||
|
||||
(ing.id === 'green-mussel' && (miClean.includes('صدف') || miClean.includes('mussel'))) ||
|
||||
(ing.id === 'collagen' && miClean.includes('کلاژن')) ||
|
||||
(ing.id === 'silver' && (miClean.includes('نقره') || miClean.includes('silver'))) ||
|
||||
(ing.id === 'peat-extract' && (miClean.includes('پیت') || miClean.includes('moor') || miClean.includes('عصاره'))) ||
|
||||
(ing.id === 'colostrum' && (miClean.includes('آغوز') || miClean.includes('colostrum'))) ||
|
||||
(ing.id === 'biotin' && (miClean.includes('بیوتین') || miClean.includes('biotin'))) ||
|
||||
(ing.id === 'taurin' && (miClean.includes('تورین') || miClean.includes('taurine'))) ||
|
||||
(ing.id === 'salmon-oil' && (miClean.includes('سالمون') || miClean.includes('salmon') || miClean.includes('ماهی'))) ||
|
||||
(ing.id === 'black-cumin' && (miClean.includes('سیاه دانه') || miClean.includes('زیره') || miClean.includes('cumin'))) ||
|
||||
(ing.id === 'eggshell' && (miClean.includes('پوسته تخم مرغ') || miClean.includes('تخممرغ') || miClean.includes('eggshell'))) ||
|
||||
(ing.id === 'hawthorn' && (miClean.includes('زالزالک') || miClean.includes('hawthorn'))) ||
|
||||
(ing.id === 'l-carnitine' && (miClean.includes('کارنیتین') || miClean.includes('carnitine'))) ||
|
||||
(ing.id === 'seaweed' && (miClean.includes('جلبک') || miClean.includes('seaweed'))) ||
|
||||
(ing.id === 'hyaluronic' && (miClean.includes('هیالورونات') || miClean.includes('hyaluron'))) ||
|
||||
(ing.id === 'calendula-sea-buckthorn' && (miClean.includes('کالاندولا') || miClean.includes('سنجد') || miClean.includes('calendula'))) ||
|
||||
(ing.id === 'dodecanoic' && (miClean.includes('دودکانوئیک') || miClean.includes('مارگوسا') || miClean.includes('insect')));
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<div key={ing.id} className={`flex flex-col lg:flex-row items-center gap-16 ${idx % 2 === 1 ? 'lg:flex-row-reverse' : ''}`}>
|
||||
|
||||
@ -50,7 +50,7 @@ export default function OrderDetailsModal({ isOpen, onClose, order }: OrderDetai
|
||||
font-family: 'Vazirmatn';
|
||||
src: url('https://cdn.jsdelivr.net/gh/rastikerdar/vazirmatn@v33.003/fonts/webfonts/Vazirmatn-Regular.woff2') format('woff2');
|
||||
}
|
||||
body { font-family: 'Vazirmatn', sans-serif; padding: 40px; color: #333; }
|
||||
body { font-family: 'Vazirmatn'; padding: 40px; color: #333; }
|
||||
.header { display: flex; justify-between: space-between; align-items: center; border-bottom: 2px solid #0055FF; pb: 20px; mb: 40px; }
|
||||
.logo { font-size: 24px; font-weight: 900; color: #0055FF; }
|
||||
.info { margin-bottom: 40px; display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
|
||||
|
||||
@ -194,24 +194,49 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
||||
<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">
|
||||
{/* Above the Fold Grid */}
|
||||
<div className="grid md:grid-cols-12 gap-12 items-start mb-12">
|
||||
{/* Right Column: Product Image Frame (md:col-span-5) */}
|
||||
<div className="md:col-span-5 w-full">
|
||||
<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-[380px] flex items-center justify-center p-8"
|
||||
>
|
||||
<div className="absolute top-6 left-6 flex flex-col gap-2 z-10">
|
||||
<div className="px-3 py-1 bg-green-500 text-white rounded-full 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-3 py-1 bg-canina-blue text-white rounded-full text-[10px] font-black uppercase tracking-widest font-vazir whitespace-nowrap shadow-sm">
|
||||
گرید دارویی اختصاصی
|
||||
</div>
|
||||
</div>
|
||||
<SafeImage
|
||||
src={product.image}
|
||||
alt={product.name}
|
||||
className="max-h-[300px] w-auto object-contain drop-shadow-2xl group-hover:scale-105 transition-transform duration-700"
|
||||
/>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Left Column: Product Title & Description (md:col-span-7) */}
|
||||
<div className="md:col-span-7 space-y-6">
|
||||
<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 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">
|
||||
<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>
|
||||
<h1 className="text-4xl lg:text-6xl font-black text-medical-gray-900 leading-tight mb-4 italic font-vazir">
|
||||
<h1 dir="ltr" className="text-2xl md:text-3xl lg:text-4xl font-black text-medical-gray-900 leading-tight mb-4 italic font-sans text-left">
|
||||
{product.name}
|
||||
</h1>
|
||||
<p className="text-xl text-canina-blue font-bold italic opacity-70 leading-relaxed max-w-2xl font-vazir mb-6">
|
||||
<p className="text-xl text-canina-blue font-bold italic opacity-70 leading-relaxed max-w-2xl font-vazir mb-6 text-right" dir="rtl">
|
||||
{pets.length > 0 ? (
|
||||
product.optimisticTemplate?.replace("[PetName]", activePet?.name || "").replace("[OnSet]", product.onSetOfAction || "به زودی")
|
||||
) : (
|
||||
@ -219,12 +244,26 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
||||
)}
|
||||
</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">
|
||||
<p className="text-lg text-medical-gray-600 font-bold 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>
|
||||
)}
|
||||
{fullProduct.description && (
|
||||
<div className="text-base text-medical-gray-500 font-medium leading-loose max-w-3xl font-vazir mt-6 space-y-4">
|
||||
{fullProduct.description.split('\n').filter(Boolean).map((para, pIdx) => (
|
||||
<p key={pIdx}>{para.trim()}</p>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Technical & Commerce Sections */}
|
||||
<div className="grid lg:grid-cols-12 gap-12 items-start border-t border-medical-gray-200 pt-12">
|
||||
{/* Main Content Area */}
|
||||
<div className="lg:col-span-8 space-y-12">
|
||||
|
||||
{/* Key Benefits Section */}
|
||||
{fullProduct.keyBenefits && fullProduct.keyBenefits.length > 0 && (
|
||||
<section className="space-y-8">
|
||||
@ -238,7 +277,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
||||
{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 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" />
|
||||
@ -252,31 +291,69 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
||||
</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" />
|
||||
موجود در انبار
|
||||
{/* Smart Dosage Calculator Utility Section */}
|
||||
<section className="bg-white rounded-[2.5rem] border border-medical-gray-200 p-8 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 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>
|
||||
<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>
|
||||
<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>
|
||||
|
||||
<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-medical-gray-900 text-white rounded-2xl flex items-center justify-center shadow-lg">
|
||||
<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>
|
||||
@ -284,7 +361,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
||||
|
||||
<div className="space-y-10">
|
||||
{/* Ingredients Cards */}
|
||||
<div className="bg-white rounded-[2.5rem] p-8 border border-medical-gray-200">
|
||||
<div className="bg-white rounded-[2.5rem] p-8 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) => {
|
||||
@ -311,7 +388,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
||||
<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 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>
|
||||
@ -322,13 +399,17 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feeding Section */}
|
||||
<section className="bg-canina-blue/5 border border-canina-blue/10 rounded-[3rem] p-10">
|
||||
{/* Feeding / Usage Instructions Section (Dynamic Header based on product category) */}
|
||||
<section className="bg-white border border-medical-gray-200 rounded-[2.5rem] p-10 shadow-md">
|
||||
<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">
|
||||
<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">توصیه غذایی و نحوه مصرف</h3>
|
||||
<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}
|
||||
@ -337,12 +418,12 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
||||
|
||||
{/* Specialist Note */}
|
||||
{product.specialist && (
|
||||
<section className="bg-white rounded-[3rem] p-10 border border-medical-gray-200">
|
||||
<section className="bg-white rounded-[2.5rem] 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-[2.5rem] object-cover border-4 border-medical-gray-50 shadow-xl"
|
||||
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">
|
||||
@ -362,7 +443,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
||||
{/* Specialized Landing Banner */}
|
||||
<section>
|
||||
<div
|
||||
className="relative bg-canina-blue rounded-[3rem] p-12 overflow-hidden group cursor-pointer"
|
||||
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" />
|
||||
@ -394,7 +475,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
||||
</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">
|
||||
<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" />
|
||||
@ -409,52 +490,16 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Sticky Sidebar */}
|
||||
{/* Sticky Sidebar (Clean Buy Box) */}
|
||||
<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="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-4xl font-black font-vazir text-medical-gray-900 tracking-tighter mb-4">
|
||||
<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>
|
||||
|
||||
{/* 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%]">
|
||||
@ -488,12 +533,12 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
||||
</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">
|
||||
<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-[10px] font-bold text-medical-gray-400 font-vazir">
|
||||
<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>
|
||||
@ -502,7 +547,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
||||
|
||||
{/* expected results box */}
|
||||
{product.expectedResults && product.expectedResults.length > 0 && (
|
||||
<div className="bg-white rounded-[2.5rem] border border-medical-gray-200 p-8">
|
||||
<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) => {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export interface ScientificTerm {
|
||||
export interface ScientificTerm {
|
||||
term: string;
|
||||
definition: string;
|
||||
wikiId?: string;
|
||||
@ -7,28 +7,28 @@
|
||||
export const SCIENTIFIC_TERMS: Record<string, ScientificTerm> = {
|
||||
"گلیکوزآمینوگلیکان": {
|
||||
term: "گلیکوزآمینوگلیکان (GAG)",
|
||||
definition: "ترکیبات ساختاری ضروری برای بازسازی غضروفها و مایع مفصلی که در Canhydrox GAG به وفور یافت میشود.",
|
||||
wikiId: "gag"
|
||||
definition: "ترکیبات ساختاری ضروری برای بازسازی غضروفها و مایع مفصلی که در مفاصل و تاندونها نقش حیاتی دارند.",
|
||||
wikiId: "green-mussel"
|
||||
},
|
||||
"اسیدهای هومیک": {
|
||||
term: "اسیدهای هومیک",
|
||||
definition: "مواد آلی طبیعی موجود در عصاره پیت (Moor) که از مخاط روده محافظت کرده و سموم را جذب میکنند.",
|
||||
wikiId: "humic-acids"
|
||||
definition: "مواد آلی طبیعی موجود در عصاره پیت (Moor) که از مخاط روده محافظت کرده و سموم را در گوارش به دام میاندازند.",
|
||||
wikiId: "peat-extract"
|
||||
},
|
||||
"کلاژن زیستفعال": {
|
||||
term: "کلاژن زیستفعال",
|
||||
definition: "پروتئینهای اختصاصی هیدرولیز شده که به سرعت جذب استخوان و تاندون شده و استحکام ساختاری ایجاد میکنند.",
|
||||
term: "کلاژن زیستفعال (Bioactive Collagen)",
|
||||
definition: "پروتئینهای اختصاصی هیدرولیز شده که به سرعت جذب استخوان و تاندون شده و بازسازی مفاصل را بهبود میبخشند.",
|
||||
wikiId: "collagen"
|
||||
},
|
||||
"تیموکینون": {
|
||||
term: "تیموکینون",
|
||||
definition: "ماده موثره اصلی در روغن سیاه دانه (Nigella sativa) با خواص ضدالتهابی، ضدآلرژی و آنتیاکسیدان. با مهار مسیر NF-κB تولید سایتوکاینهای پیشالتهابی را کاهش میدهد.",
|
||||
wikiId: "thymoquinone"
|
||||
term: "تیموکینون (Thymoquinone)",
|
||||
definition: "ماده موثره اصلی در روغن سیاه دانه با خواص ضدالتهابی، ضدآلرژی و آنتیاکسیدان بسیار قوی.",
|
||||
wikiId: "black-cumin"
|
||||
},
|
||||
"امگا ۳": {
|
||||
term: "امگا ۳",
|
||||
definition: "اسیدهای چرب ضروری شامل EPA و DHA که برای سلامت پوست، مو، قلب و عملکرد شناختی حیاتی هستند. EPA پیشماده رزولوینهای ضدالتهابی و DHA ۳۰٪ وزن خشک مغز را تشکیل میدهد.",
|
||||
wikiId: "omega3"
|
||||
term: "امگا ۳ (Omega-3)",
|
||||
definition: "اسیدهای چرب ضروری شامل EPA و DHA که برای سلامت پوست، مو، قلب و عملکرد مغز حیاتی هستند.",
|
||||
wikiId: "salmon-oil"
|
||||
},
|
||||
"میکروسیلور": {
|
||||
term: "نقره میکروسیلور (Microsilver BG)",
|
||||
@ -37,52 +37,97 @@ export const SCIENTIFIC_TERMS: Record<string, ScientificTerm> = {
|
||||
},
|
||||
"صدف لبسبز": {
|
||||
term: "صدف لبسبز (Green-lipped Mussel)",
|
||||
definition: "صدف بومی نیوزلند حاوی گلوکوزامینگلیکانهای طبیعی که نقش حیاتی در بازسازی غضروف و مفاصل دارند.",
|
||||
wikiId: "joints"
|
||||
definition: "صدف بومی نیوزلند حاوی گلوکوزامینگلیکانهای طبیعی که نقش کلیدی در ساخت و بازسازی غضروفها ایفا میکند.",
|
||||
wikiId: "green-mussel"
|
||||
},
|
||||
"نسبت Ca:P": {
|
||||
term: "نسبت کلسیم به فسفر (Ca:P Ratio)",
|
||||
definition: "نسبت ایدهآل کلسیم به فسفر در رژیم حیوانات ۱.۲:۱ تا ۱.۵:۱ است. عدم تعادل این نسبت منجر به مشکلات کلیوی و استخوانی میشود. پودر پوسته تخم مرغ کانینا با ۳۶٪ کلسیم و ۰.۱٪ فسفر بهترین تنظیمکننده این نسبت است.",
|
||||
wikiId: "nutrition"
|
||||
definition: "نسبت کلسیم به فسفر جهت حفظ سلامت استخوانها و کلیه. پودر پوسته تخم مرغ بهترین تنظیمکننده این نسبت است.",
|
||||
wikiId: "eggshell"
|
||||
},
|
||||
"ویتامین D3": {
|
||||
term: "ویتامین D3 (کولهکلسیفرول)",
|
||||
definition: "فرم فعال ویتامین D که جذب کلسیم از روده را تا ۳۰٪ افزایش میدهد. هشدار: مصرف همزمان با ویتامین D2 (ارگوکلسیفرول) مجاز نیست زیرا رقابت این دو جذب مؤثر را کاهش میدهد.",
|
||||
definition: "فرمی فعال از ویتامین D که جذب کلسیم از روده را افزایش داده و به سلامت استخوانها کمک میکند.",
|
||||
wikiId: "vitamins"
|
||||
},
|
||||
"BARF": {
|
||||
term: "رژیم BARF (Biologically Appropriate Raw Food)",
|
||||
definition: "رژیم غذایی خام متناسب با زیستشناسی حیوان که شامل گوشت خام، استخوان، اندامها و سبزیجات است. مکملهای کانینا مانند Eierschalenpulver، Rinderblut Pulver و Rinderfett Pulver برای تکمیل این رژیم طراحی شدهاند.",
|
||||
wikiId: "nutrition"
|
||||
term: "رژیم غذایی خام (BARF)",
|
||||
definition: "رژیم غذایی خام طبیعی شامل گوشت و استخوان که مکملهای پوسته تخم مرغ و پودر خون برای تکمیل آن طراحی شدهاند.",
|
||||
wikiId: "eggshell"
|
||||
},
|
||||
"آغوز": {
|
||||
term: "آغوز (Colostrum)",
|
||||
definition: "اولین شیر پستانداران حاوی IgG, IgA, IgM و لاکتوفرین که سد دفاعی روده را تقویت کرده و ایمنی غیرفعال منتقل میکند. محصول Immun-Booster کانینا حاوی ۲۰٪ پودر آغوز است.",
|
||||
wikiId: "immune"
|
||||
definition: "اولین شیر پستانداران پس از زایمان، غنی از ایمونوگلوبولینها جهت فعالسازی فوری سیستم ایمنی نوزادان.",
|
||||
wikiId: "colostrum"
|
||||
},
|
||||
"ال-کارنیتین": {
|
||||
term: "ال-کارنیتین",
|
||||
definition: "مادهای شبهآمینواسید که اسیدهای چرب زنجیره بلند را به داخل میتوکندری کاردیومیوسیتها منتقل کرده و ATP تولید میکند. محصول Herz Vital کانینا حاوی ۳۰,۰۰۰mg/kg ال-کارنیتین است.",
|
||||
wikiId: "heart"
|
||||
term: "ال-کارنیتین (L-Carnitine)",
|
||||
definition: "آمینو اسیدی که وظیفه انتقال اسیدهای چرب به درون میتوکندری جهت تولید انرژی و تقویت عملکرد قلب را دارد.",
|
||||
wikiId: "l-carnitine"
|
||||
},
|
||||
"زالزالک": {
|
||||
term: "زالزالک (Crataegus oxyacantha)",
|
||||
definition: "گیاه دارویی با اثر مهارکننده ACE طبیعی که جریان خون کرونر را بهبود بخشیده و فشار بر قلب را کاهش میدهد.",
|
||||
wikiId: "heart"
|
||||
term: "زالزالک (Hawthorn)",
|
||||
definition: "عصاره گیاهی تقویتکننده عملکرد انقباضی عضله قلب و بهبودبخش گردش خون عروق کرونر.",
|
||||
wikiId: "hawthorn"
|
||||
},
|
||||
"بیوتین": {
|
||||
term: "بیوتین (ویتامین H / B7)",
|
||||
definition: "کوآنزیم کربوکسیلازهای مسئول سنتز اسیدهای چرب و گلوکونئوژنز. کمبود آن منجر به ریزش مو و شکنندگی پنجه میشود. قرص Biotin-Tabs کانینا با ۱,۰۰۰,۰۰۰ میکروگرم در کیلوگرم قویترین دوز موجود است.",
|
||||
wikiId: "skin"
|
||||
term: "بیوتین (Biotin / Vitamin H)",
|
||||
definition: "کوآنزیم ضروری برای ساخت کراتین و جلوگیری از ریزش مو و تقویت ناخنها و پنجههای حیوان.",
|
||||
wikiId: "biotin"
|
||||
},
|
||||
"هیدروکسی آپاتیت": {
|
||||
term: "هیدروکسی آپاتیت",
|
||||
definition: "کلسیم فسفات بلوری که ۹۰٪ بافت دندان و بخش عمده استخوان را تشکیل میدهد. با جذب مستقیم در توده استخوانی، استحکام اسکلت را تضمین میکند.",
|
||||
wikiId: "joints"
|
||||
term: "هیدروکسی آپاتیت (Hydroxyapatite)",
|
||||
definition: "ترکیب کلسیم فسفات طبیعی که بخش عمده استخوان و دندانها را تشکیل داده و موجب افزایش استحکام اسکلت میشود.",
|
||||
wikiId: "green-mussel"
|
||||
},
|
||||
"EPA/DHA": {
|
||||
term: "EPA و DHA",
|
||||
definition: "ایکوزاپنتائنوئیک اسید (EPA) پیشماده رزولوینهای ضدالتهابی و دوکوزاهگزانوئیک اسید (DHA) ۳۰٪ وزن خشک مغز را تشکیل میدهد. نسبت ۳:۲ EPA:DHA در روغن سالمون کانینا بهینهسازی شده است.",
|
||||
wikiId: "omega3"
|
||||
definition: "اسیدهای چرب بلندزنجیره امگا ۳ که اثرات ضدالتهابی عمیق داشته و برای رشد سیستم عصبی و چشمها حیاتی هستند.",
|
||||
wikiId: "salmon-oil"
|
||||
},
|
||||
"روغن ماهی سالمون": {
|
||||
term: "روغن ماهی سالمون (Salmon Oil)",
|
||||
definition: "منبع ۱۰۰٪ خالص و طبیعی اسیدهای چرب امگا ۳ که کیفیت پوست و مو را ارتقا داده و مفاصل را روان میکند.",
|
||||
wikiId: "salmon-oil"
|
||||
},
|
||||
"سیاه دانه": {
|
||||
term: "سیاه دانه (Black Cumin)",
|
||||
definition: "دانه گیاه سیاه دانه مصری با خواص قوی ضدآلرژی، تقویتکننده سیستم ایمنی و هضم بهتر غذا.",
|
||||
wikiId: "black-cumin"
|
||||
},
|
||||
"جلبک دریایی": {
|
||||
term: "جلبک دریایی (Seaweed)",
|
||||
definition: "جلبک قهوهای غنی از اسیدهای آمینه و مواد معدنی کمیاب (به ویژه ید) جهت تقویت رنگدانههای پوشش، بینی و پنجهها.",
|
||||
wikiId: "seaweed"
|
||||
},
|
||||
"پوسته تخم مرغ": {
|
||||
term: "پودر پوسته تخم مرغ (Eggshell Powder)",
|
||||
definition: "منبع کلسیم ارگانیک صد درصد خالص با جذب بسیار بالا و مناسب برای رژیمهای بدون استخوان یا حساسیتهای غذایی.",
|
||||
wikiId: "eggshell"
|
||||
},
|
||||
"پیت": {
|
||||
term: "عصاره پیت (Peat Extract / Moor)",
|
||||
definition: "عصاره طبیعی حاصل از تجزیه گیاهان در طول هزاران سال، غنی از اسیدهای هومیک برای تنظیم فلور گوارشی.",
|
||||
wikiId: "peat-extract"
|
||||
},
|
||||
"اسید دودکانوئیک": {
|
||||
term: "اسید دودکانوئیک (Dodecanoic Acid)",
|
||||
definition: "اسید چرب با منشأ گیاهی با اثر دفعکننده حشرات موذی نظیر کنه، کک و شپش از محیط زندگی پت.",
|
||||
wikiId: "dodecanoic"
|
||||
},
|
||||
"هیالورونات سدیم": {
|
||||
term: "هیالورونات سدیم (Sodium Hyaluronate)",
|
||||
definition: "روانکننده و رطوبترسان طبیعی قرنیه چشم جهت شستشو و تسکین چشمهای تحریک شده و گریان.",
|
||||
wikiId: "hyaluronic"
|
||||
},
|
||||
"روغن کالاندولا": {
|
||||
term: "روغن کالاندولا و سنجد دریایی (Calendula & Sea Buckthorn)",
|
||||
definition: "روغنهای تسکیندهنده، ضدباکتری و التیامبخش پوست جهت بهبود سوزش، زخمهای سطحی و خشکی پنجهها.",
|
||||
wikiId: "calendula-sea-buckthorn"
|
||||
},
|
||||
"تورین": {
|
||||
term: "تورین (Taurine)",
|
||||
definition: "آمینو اسید بسیار ضروری برای گربهها جهت جلوگیری از دژنراسیون شبکیه (نابینایی) و نارسایی قلبی.",
|
||||
wikiId: "taurin"
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import axios from 'axios';
|
||||
|
||||
const baseURL = typeof window !== 'undefined' ? '/api' : (process.env.NEXT_PUBLIC_API_URL || 'https://apicanina.parsaaghayi.ir/api');
|
||||
const baseURL = typeof window !== 'undefined' ? '/api' : (process.env.NEXT_PUBLIC_API_URL || (process.env.NODE_ENV === 'development' ? 'http://localhost:4001/api' : 'https://apicanina.parsaaghayi.ir/api'));
|
||||
|
||||
const api = axios.create({
|
||||
baseURL,
|
||||
|
||||
@ -55,7 +55,7 @@ export class ProductService {
|
||||
specialBadge: data.specialBadge,
|
||||
onSetOfAction: data.onSetOfAction,
|
||||
optimisticTemplate: data.optimisticTemplate,
|
||||
feedingAdvice: data.feedingAdvice,
|
||||
feedingAdvice: data.dosageLogic || data.feedingAdvice || '',
|
||||
image: data.imageUrl?.startsWith('http') ? data.imageUrl : data.imageUrl ? `/api${data.imageUrl}` : data.image,
|
||||
|
||||
main_ingredients: data.ingredientList?.map((i: any) => i.ingredient) || data.ingredients?.split(/[،,-]/).map((s: string) => s.trim()).filter(Boolean) || [],
|
||||
|
||||