-
تمام مواد اولیه ما دارای گواهینامه گرید دارویی اختصاصی هستند.
+
تمام مواد اولیه ما دارای گواهینامه گرید دارویی اختصاصی هستند.
این یعنی استانداردی فراتر از مکملهای معمولی، مشابه استانداردهای تولید دارو در اتحادیه اروپا.
-
۱۰۰٪
+
۱۰۰٪
تست آزمایشگاهی
diff --git a/frontend/application/components/LoginModal.tsx b/frontend/application/components/LoginModal.tsx
index 9cac5f6..eab1c15 100644
--- a/frontend/application/components/LoginModal.tsx
+++ b/frontend/application/components/LoginModal.tsx
@@ -137,7 +137,7 @@ export default function LoginModal({ isOpen, onClose, onLogin, petName, isAdviso
dir="rtl"
>
{/* Top color indicator */}
-
+
{/* Close Button */}
-
-
+
+
- ورود به کانینا
+ ورود به کانینو
{isAdvisorContext ? (
- تحلیل سلامت {petName || "همدم شما"} آماده است! برای مشاهده رژیم مکمل پیشنهادی و ذخیره شناسنامه، وارد شوید.
+ تحلیل سلامت {petName || "همدم شما"} آماده است! برای مشاهده رژیم مکمل پیشنهادی و ذخیره شناسنامه، وارد شوید.
) : (
برای دسترسی به پنل مدیریت سلامت، وارد شوید
@@ -187,7 +187,7 @@ export default function LoginModal({ isOpen, onClose, onLogin, petName, isAdviso
value={phoneNumber}
onChange={(e) => setPhoneNumber(e.target.value.replace(/[^0-9]/g, ''))}
disabled={isLoading}
- className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 pr-12 pl-4 focus:ring-2 focus:ring-canina-blue/20 focus:border-canina-blue outline-none font-bold text-lg text-left tracking-widest"
+ className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 pr-12 pl-4 focus:ring-2 focus:ring-canino-blue/20 focus:border-canino-blue outline-none font-bold text-lg text-left tracking-widest"
/>
@@ -195,7 +195,7 @@ export default function LoginModal({ isOpen, onClose, onLogin, petName, isAdviso
{isLoading ? (
@@ -222,7 +222,7 @@ export default function LoginModal({ isOpen, onClose, onLogin, petName, isAdviso
setStep("phone")}
- className="text-[10px] font-black text-canina-blue flex items-center gap-1 hover:underline"
+ className="text-[10px] font-black text-canino-blue flex items-center gap-1 hover:underline"
>
ویرایش شماره
@@ -238,7 +238,7 @@ export default function LoginModal({ isOpen, onClose, onLogin, petName, isAdviso
value={otpCode}
onChange={(e) => setOtpCode(e.target.value.replace(/[^0-9]/g, ''))}
disabled={isLoading}
- className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 pr-12 pl-4 focus:ring-2 focus:ring-canina-blue/20 focus:border-canina-blue outline-none font-black text-2xl text-center tracking-[0.5em]"
+ className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 pr-12 pl-4 focus:ring-2 focus:ring-canino-blue/20 focus:border-canino-blue outline-none font-black text-2xl text-center tracking-[0.5em]"
/>
@@ -256,7 +256,7 @@ export default function LoginModal({ isOpen, onClose, onLogin, petName, isAdviso
type="button"
onClick={handleResendOtp}
disabled={isLoading}
- className="text-xs font-black text-canina-blue hover:underline flex items-center gap-1.5"
+ className="text-xs font-black text-canino-blue hover:underline flex items-center gap-1.5"
>
ارسال مجدد کد تایید
@@ -267,7 +267,7 @@ export default function LoginModal({ isOpen, onClose, onLogin, petName, isAdviso
{isLoading ? (
diff --git a/frontend/application/components/OrderDetailsModal.tsx b/frontend/application/components/OrderDetailsModal.tsx
index a66c2af..aad7f64 100644
--- a/frontend/application/components/OrderDetailsModal.tsx
+++ b/frontend/application/components/OrderDetailsModal.tsx
@@ -62,7 +62,7 @@ export default function OrderDetailsModal({ isOpen, onClose, order }: OrderDetai
@@ -139,7 +139,7 @@ export default function OrderDetailsModal({ isOpen, onClose, order }: OrderDetai
{/* Header */}
-
+
@@ -168,7 +168,7 @@ export default function OrderDetailsModal({ isOpen, onClose, order }: OrderDetai
کد رهگیری
-
{toPersian(order.trackingNumber)}
+
{toPersian(order.trackingNumber)}
زمان ثبت
@@ -182,12 +182,12 @@ export default function OrderDetailsModal({ isOpen, onClose, order }: OrderDetai
{/* Items List */}
-
+
سبد محصولات خریده شده
{(order.items || []).map((item: any) => (
-
+
-
{toPersian((item.product.priceValue * item.quantity).toLocaleString())} تومان
+
{toPersian((item.product.priceValue * item.quantity).toLocaleString())} تومان
))}
@@ -214,7 +214,7 @@ export default function OrderDetailsModal({ isOpen, onClose, order }: OrderDetai
-
+
اطلاعات ارسال
@@ -223,7 +223,7 @@ export default function OrderDetailsModal({ isOpen, onClose, order }: OrderDetai
-
+
جزئیات پرداخت
@@ -253,7 +253,7 @@ export default function OrderDetailsModal({ isOpen, onClose, order }: OrderDetai
دانلود فاکتور رسمی
-
+
diff --git a/frontend/application/components/OrderSuccess.tsx b/frontend/application/components/OrderSuccess.tsx
index 72b669c..02c035e 100644
--- a/frontend/application/components/OrderSuccess.tsx
+++ b/frontend/application/components/OrderSuccess.tsx
@@ -35,33 +35,33 @@ export default function OrderSuccess({ orderId }: { orderId: string }) {
className="bg-white rounded-[4rem] border border-medical-gray-200 p-12 text-center shadow-2xl relative overflow-hidden"
>
{/* Confetti-like background elements */}
-
+
سفارش شما با موفقیت ثبت شد!
-
شماره سفارش: {order.id}
+
شماره سفارش: {order.id}
{/* Empathetic Message */}
-
+
-
+
-
خیالت راحت باشه!
+
خیالت راحت باشه!
-
+
{activePet ? (
<>
- انتخاب درستی برای {activePet.name} کردی.
+ انتخاب درستی برای {activePet.name} کردی.
{hasCanhydrox ? (
` مکمل Canhydrox با فرمول آلمانیاش دقیقاً همون چیزیه که استخوانهای ${activePet.name} برای بازیگوشی دوباره بهش نیاز دارن.`
) : (
@@ -94,13 +94,13 @@ export default function OrderSuccess({ orderId }: { orderId: string }) {
router.push('/track')}
- className="w-full bg-medical-gray-900 text-white py-5 rounded-2xl font-black text-lg hover:bg-canina-blue transition-all"
+ className="w-full bg-medical-gray-900 text-white py-5 rounded-2xl font-black text-lg hover:bg-canino-blue transition-all"
>
مشاهده و پیگیری زنده سفارش
router.push('/shop')}
- className="flex items-center justify-center gap-2 w-full text-medical-gray-400 font-bold hover:text-canina-blue transition-colors"
+ className="flex items-center justify-center gap-2 w-full text-medical-gray-400 font-bold hover:text-canino-blue transition-colors"
>
بازگشت به فروشگاه
diff --git a/frontend/application/components/OrderTracking.tsx b/frontend/application/components/OrderTracking.tsx
index 1a15b0c..dbbe074 100644
--- a/frontend/application/components/OrderTracking.tsx
+++ b/frontend/application/components/OrderTracking.tsx
@@ -44,24 +44,24 @@ export default function OrderTracking() {
router.back()}
- className="flex items-center gap-2 text-medical-gray-500 font-bold hover:text-canina-blue transition-colors"
+ className="flex items-center gap-2 text-medical-gray-500 font-bold hover:text-canino-blue transition-colors"
>
بازگشت
- router.push('/')}>کانینا
+ router.push('/')}>کانینو
- پیگیری سفارش
+ پیگیری سفارش
{/* Desktop Breadcrumbs */}
- router.push('/')}>خانه
+ router.push('/')}>خانه
- رهگیری هوشمند محموله
+ رهگیری هوشمند محموله
@@ -78,12 +78,12 @@ export default function OrderTracking() {
placeholder="شماره سفارش (CN-XXXXX) یا کد رهگیری پستی را وارد کنید..."
value={searchId}
onChange={(e) => setSearchId(e.target.value)}
- className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 pr-12 pl-6 text-sm focus:ring-2 focus:ring-canina-blue/20 outline-none font-mono"
+ className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 pr-12 pl-6 text-sm focus:ring-2 focus:ring-canino-blue/20 outline-none font-mono"
/>
رهگیری آنی
@@ -97,7 +97,7 @@ export default function OrderTracking() {
کد رهگیری پستی
-
{activeOrder.trackingNumber}
+
{activeOrder.trackingNumber}
تاریخ ثبت
@@ -110,7 +110,7 @@ export default function OrderTracking() {
{steps.map((step, i) => (
-
+
{step.status === 'completed' ? : step.icon}
@@ -136,13 +136,13 @@ export default function OrderTracking() {
مجموع فاکتور
- {activeOrder.total.toLocaleString()} تومان
+ {activeOrder.total.toLocaleString()} تومان
-
+
آدرس تحویل
diff --git a/frontend/application/components/PetProfile.tsx b/frontend/application/components/PetProfile.tsx
index 46d111d..85f55bd 100644
--- a/frontend/application/components/PetProfile.tsx
+++ b/frontend/application/components/PetProfile.tsx
@@ -285,7 +285,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
setView("add");
setStep(1);
}}
- className="bg-canina-blue text-white px-8 py-4 rounded-[2rem] font-black shadow-xl shadow-canina-blue/20 hover:scale-105 transition-all flex items-center gap-3"
+ className="bg-canino-blue text-white px-8 py-4 rounded-[2rem] font-black shadow-xl shadow-canino-blue/20 hover:scale-105 transition-all flex items-center gap-3"
>
صدور شناسنامه جدید
@@ -299,7 +299,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
whileHover={{ y: -5 }}
className="bg-white rounded-[3rem] border border-medical-gray-200 p-8 shadow-sm hover:shadow-2xl transition-all relative group"
>
-
+
{pet.type === "سگ" ? : }
{pet.name}
@@ -318,7 +318,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
{ setActivePet(pet.id); setView("detail"); }}
- className="w-full py-4 bg-medical-gray-900 text-white rounded-2xl font-black hover:bg-canina-blue transition-all flex items-center justify-center gap-2 group-hover:shadow-lg"
+ className="w-full py-4 bg-medical-gray-900 text-white rounded-2xl font-black hover:bg-canino-blue transition-all flex items-center justify-center gap-2 group-hover:shadow-lg"
>
مشاهده شناسنامه سلامت
@@ -390,7 +390,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
{/* Progress Bar */}
@@ -401,7 +401,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
{view === "edit" ? "ویرایش شناسنامه" : "صدور شناسنامه سلامت"}
مرحله {toPersian(step)} از {toPersian(3)}: بروزرسانی اطلاعات تخصصی
-
@@ -422,7 +422,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
type="text"
value={formData.name}
onChange={e => setFormData({...formData, name: e.target.value})}
- className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canina-blue/20 outline-none font-black text-lg"
+ className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canino-blue/20 outline-none font-black text-lg"
placeholder="مثلاً: لوسی"
/>
@@ -431,14 +431,14 @@ export default function PetProfile({ initialView, advisorNeed }: {
setFormData({...formData, type: "سگ"})}
- className={`flex items-center justify-center gap-3 py-4 border-2 rounded-2xl transition-all ${formData.type === "سگ" ? 'border-canina-blue bg-canina-blue/5 text-canina-blue font-black' : 'border-medical-gray-200 text-medical-gray-400 font-bold'}`}
+ className={`flex items-center justify-center gap-3 py-4 border-2 rounded-2xl transition-all ${formData.type === "سگ" ? 'border-canino-blue bg-canino-blue/5 text-canino-blue font-black' : 'border-medical-gray-200 text-medical-gray-400 font-bold'}`}
>
سگ
setFormData({...formData, type: "گربه"})}
- className={`flex items-center justify-center gap-3 py-4 border-2 rounded-2xl transition-all ${formData.type === "گربه" ? 'border-canina-blue bg-canina-blue/5 text-canina-blue font-black' : 'border-medical-gray-200 text-medical-gray-400 font-bold'}`}
+ className={`flex items-center justify-center gap-3 py-4 border-2 rounded-2xl transition-all ${formData.type === "گربه" ? 'border-canino-blue bg-canino-blue/5 text-canino-blue font-black' : 'border-medical-gray-200 text-medical-gray-400 font-bold'}`}
>
گربه
@@ -451,7 +451,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
type="text"
value={formData.breed}
onChange={e => setFormData({...formData, breed: e.target.value})}
- className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canina-blue/20 outline-none font-bold"
+ className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canino-blue/20 outline-none font-bold"
placeholder="آلمانی، پرشین، میکس و..."
/>
@@ -473,7 +473,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
type="number"
value={formData.age || ""}
onChange={e => setFormData({...formData, age: parseInt(e.target.value)})}
- className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canina-blue/20 outline-none font-black text-lg"
+ className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canino-blue/20 outline-none font-black text-lg"
placeholder="۳"
/>
@@ -484,7 +484,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
type="number"
value={formData.weight || ""}
onChange={e => setFormData({...formData, weight: parseFloat(e.target.value)})}
- className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 pr-6 pl-12 focus:ring-2 focus:ring-canina-blue/20 outline-none font-black text-lg"
+ className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 pr-6 pl-12 focus:ring-2 focus:ring-canino-blue/20 outline-none font-black text-lg"
/>
@@ -497,7 +497,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
setFormData({...formData, activityLevel: level as any})}
- className={`py-4 border-2 rounded-2xl transition-all text-sm font-black italic ${formData.activityLevel === level ? 'border-canina-blue bg-canina-blue/5 text-canina-blue shadow-lg shadow-canina-blue/10' : 'border-medical-gray-100 text-medical-gray-400'}`}
+ className={`py-4 border-2 rounded-2xl transition-all text-sm font-black italic ${formData.activityLevel === level ? 'border-canino-blue bg-canino-blue/5 text-canino-blue shadow-lg shadow-canino-blue/10' : 'border-medical-gray-100 text-medical-gray-400'}`}
>
{level}
@@ -536,9 +536,9 @@ export default function PetProfile({ initialView, advisorNeed }: {
: [...current, condition]
})
}}
- className={`flex items-center gap-4 p-4 border-2 rounded-2xl transition-all ${formData.medicalConditions.includes(condition) ? 'border-canina-blue bg-canina-blue/5 text-canina-blue' : 'border-medical-gray-50 text-medical-gray-500'}`}
+ className={`flex items-center gap-4 p-4 border-2 rounded-2xl transition-all ${formData.medicalConditions.includes(condition) ? 'border-canino-blue bg-canino-blue/5 text-canino-blue' : 'border-medical-gray-50 text-medical-gray-500'}`}
>
-
+
{formData.medicalConditions.includes(condition) && }
{condition}
@@ -556,7 +556,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
else if (pets.length > 0) setView("index");
else router.back();
}}
- className="absolute top-8 left-8 text-medical-gray-400 hover:text-canina-blue transition-colors text-[10px] font-black uppercase tracking-widest"
+ className="absolute top-8 left-8 text-medical-gray-400 hover:text-canino-blue transition-colors text-[10px] font-black uppercase tracking-widest"
>
انصراف
@@ -572,7 +572,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
{step === 3 ? (view === "edit" ? "ذخیره تغییرات" : "مشاهده پرونده سلامت") : "گام بعدی"}
@@ -594,21 +594,21 @@ export default function PetProfile({ initialView, advisorNeed }: {
{/* Navigation Bar */}
- setView("index")}>همدمهای من
+ setView("index")}>همدمهای من
- پرونده سلامت {activePet?.name}
+ پرونده سلامت {activePet?.name}
setView("index")}
- className="px-6 py-2.5 bg-white border border-medical-gray-200 rounded-xl text-[10px] font-black uppercase tracking-widest hover:border-canina-blue transition-all"
+ className="px-6 py-2.5 bg-white border border-medical-gray-200 rounded-xl text-[10px] font-black uppercase tracking-widest hover:border-canino-blue transition-all"
>
بازگشت به لیست
ویرایش پرونده
@@ -619,10 +619,10 @@ export default function PetProfile({ initialView, advisorNeed }: {
{/* Profile Card */}
-
+
-
-
+
+
{activePet.type === "سگ" ? : }
@@ -652,7 +652,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
{activePet.medicalConditions.map(c => (
-
+
{c}
@@ -661,7 +661,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
-
+
@@ -712,10 +712,10 @@ export default function PetProfile({ initialView, advisorNeed }: {
{/* Refill & Stock Tracking */}
-
+
بروزرسانی لحظهای بر اساس مصرف
@@ -744,7 +744,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
{toPersian(Math.round(percentage))}%
@@ -754,7 +754,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
@@ -783,11 +783,11 @@ export default function PetProfile({ initialView, advisorNeed }: {
setActivePetTab(tab.id as any)}
- className={`pb-4 flex items-center gap-2 text-sm font-black transition-all relative ${activePetTab === tab.id ? "text-canina-blue" : "text-medical-gray-400 hover:text-medical-gray-600"}`}
+ className={`pb-4 flex items-center gap-2 text-sm font-black transition-all relative ${activePetTab === tab.id ? "text-canino-blue" : "text-medical-gray-400 hover:text-medical-gray-600"}`}
>
{tab.icon}
{tab.label}
- {activePetTab === tab.id && }
+ {activePetTab === tab.id && }
))}
@@ -798,7 +798,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
-
+
توصیههای درمانی اختصاصی
@@ -817,7 +817,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
className="bg-white rounded-[2.5rem] p-6 border border-medical-gray-200 hover:shadow-2xl transition-all cursor-pointer group flex flex-col justify-between relative overflow-hidden"
>
{reason && (
-
+
{reason}
)}
@@ -825,9 +825,9 @@ export default function PetProfile({ initialView, advisorNeed }: {
-
{p.name}
+
{p.name}
{p.benefits}
-
+
بررسی تخصصی
@@ -842,7 +842,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
-
+
یادآورهای فعال
@@ -863,7 +863,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
key={reminder.id}
className={cn(
"flex items-center justify-between p-5 rounded-2xl border transition-all group",
- isCompleted ? "bg-green-50 border-green-200" : "bg-medical-gray-50 border-medical-gray-100 hover:border-canina-blue/30"
+ isCompleted ? "bg-green-50 border-green-200" : "bg-medical-gray-50 border-medical-gray-100 hover:border-canino-blue/30"
)}
>
@@ -871,7 +871,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
onClick={() => handleToggleReminder(reminder)}
className={cn(
"w-10 h-10 rounded-xl flex items-center justify-center shadow-inner transition-colors",
- isCompleted ? "bg-green-500 text-white" : "bg-white text-medical-gray-300 hover:text-canina-blue"
+ isCompleted ? "bg-green-500 text-white" : "bg-white text-medical-gray-300 hover:text-canino-blue"
)}
>
{isCompleted ?
:
}
@@ -892,7 +892,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
setIsAddingReminder(true)}
- className="w-full mt-8 py-5 border-2 border-dashed border-medical-gray-200 rounded-2xl text-medical-gray-400 font-black hover:border-canina-blue hover:text-canina-blue transition-all flex items-center justify-center gap-2"
+ className="w-full mt-8 py-5 border-2 border-dashed border-medical-gray-200 rounded-2xl text-medical-gray-400 font-black hover:border-canino-blue hover:text-canino-blue transition-all flex items-center justify-center gap-2"
>
افزودن یادآور جدید
@@ -902,7 +902,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
{/* Health Logs */}
-
+
تایملاین سلامت
@@ -919,7 +919,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
{toPersian(new Date(log.date).toLocaleDateString("fa-IR"))}
-
{log.appetite}
+
{log.appetite}
{log.energy}
@@ -933,7 +933,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
setIsAddingHealthLog(true)}
- className="w-full mt-8 py-5 bg-canina-blue text-white rounded-2xl font-black hover:bg-medical-gray-900 transition-all shadow-xl shadow-canina-blue/20"
+ className="w-full mt-8 py-5 bg-canino-blue text-white rounded-2xl font-black hover:bg-medical-gray-900 transition-all shadow-xl shadow-canino-blue/20"
>
ثبت گزارش روزانه جدید
@@ -958,7 +958,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
مجموع هزینه درمانی
-
{toPersian(petOrders.reduce((a,b) => a + b.total, 0).toLocaleString())} تومان
+
{toPersian(petOrders.reduce((a,b) => a + b.total, 0).toLocaleString())} تومان
@@ -968,7 +968,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
هنوز سفارشی برای {activePet.name} ثبت نکردهاید.
-
router.push('/shop')} className="bg-canina-blue text-white px-10 py-4 rounded-2xl font-black hover:scale-105 transition-all">شروع اولین خرید
+
router.push('/shop')} className="bg-canino-blue text-white px-10 py-4 rounded-2xl font-black hover:scale-105 transition-all">شروع اولین خرید
) : (
@@ -984,10 +984,10 @@ export default function PetProfile({ initialView, advisorNeed }: {
>
{/* Info on Left (Text side) */}
-
{item.product.name}
+
{item.product.name}
-
+
{toPersian(new Date(order.date).toLocaleDateString("fa-IR", { year: 'numeric', month: 'long', day: 'numeric' }))}
@@ -1020,11 +1020,11 @@ export default function PetProfile({ initialView, advisorNeed }: {
{/* Seal of Authenticity */}
-
ضمانت اصالت و سلامت کانینا آلمان
+
ضمانت اصالت و سلامت کانینو آلمان
- این گزارش توسط سیستم هوش مصنوعی کانینا و با انطباق کامل بر پروتکلهای درمانی Canina Pharma GmbH آلمان تولید شده است. تمامی مکملهای پیشنهادی دارای استاندارد دارویی (Pharmaceutical Grade) میباشند.
+ این گزارش توسط سیستم هوش مصنوعی کانینو و با انطباق کامل بر پروتکلهای درمانی Canina Pharma GmbH آلمان تولید شده است. تمامی مکملهای پیشنهادی دارای استاندارد دارویی (Pharmaceutical Grade) میباشند.
@@ -1059,7 +1059,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
value={reminderForm.title}
onChange={e => setReminderForm({...reminderForm, title: e.target.value})}
placeholder="مثلاً: قرص مفاصل، کانهیدروکس"
- className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canina-blue/20 outline-none font-bold"
+ className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canino-blue/20 outline-none font-bold"
/>
@@ -1069,7 +1069,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
type="time"
value={reminderForm.time}
onChange={e => setReminderForm({...reminderForm, time: e.target.value})}
- className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canina-blue/20 outline-none font-black"
+ className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canino-blue/20 outline-none font-black"
/>
@@ -1077,7 +1077,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
setReminderForm({...reminderForm, frequency: e.target.value as any})}
- className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canina-blue/20 outline-none font-black text-sm"
+ className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canino-blue/20 outline-none font-black text-sm"
>
روزانه
هفتگی
@@ -1089,7 +1089,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
setReminderForm({...reminderForm, productId: e.target.value})}
- className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canina-blue/20 outline-none font-black text-sm"
+ className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canino-blue/20 outline-none font-black text-sm"
>
هیچکدام
{recommendedProducts.map(p => (
@@ -1100,7 +1100,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
ثبت نهایی یادآور
@@ -1142,7 +1142,7 @@ export default function PetProfile({ initialView, advisorNeed }: {
onClick={() => setLogForm({...logForm, appetite: opt as any})}
className={cn(
"py-3 border-2 rounded-xl text-xs font-black transition-all",
- logForm.appetite === opt ? "border-canina-blue bg-canina-blue/10 text-canina-blue" : "border-medical-gray-100 text-medical-gray-400"
+ logForm.appetite === opt ? "border-canino-blue bg-canino-blue/10 text-canino-blue" : "border-medical-gray-100 text-medical-gray-400"
)}
>
{opt}
@@ -1176,13 +1176,13 @@ export default function PetProfile({ initialView, advisorNeed }: {
value={logForm.note}
onChange={e => setLogForm({...logForm, note: e.target.value})}
placeholder="مشاهدات خود را برای بررسی دکتر سیستم اینجا بنویسید..."
- className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canina-blue/20 outline-none font-bold text-sm resize-none"
+ className="w-full bg-medical-gray-50 border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canino-blue/20 outline-none font-bold text-sm resize-none"
/>
ثبت نهایی گزارش
diff --git a/frontend/application/components/ProductPage.tsx b/frontend/application/components/ProductPage.tsx
index 4c752ea..45b2147 100644
--- a/frontend/application/components/ProductPage.tsx
+++ b/frontend/application/components/ProductPage.tsx
@@ -169,8 +169,8 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
بازگشت
-
- کانینا ایران
+
+ کانینو ایران
@@ -178,19 +178,19 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
router.push('/')}
- className="hover:text-canina-blue transition-colors font-vazir cursor-pointer"
+ className="hover:text-canino-blue transition-colors font-vazir cursor-pointer"
>
خانه
router.push(`/shop?category=${product.category}`)}
- className="hover:text-canina-blue cursor-pointer font-vazir"
+ className="hover:text-canino-blue cursor-pointer font-vazir"
>
{product.category}
- {product.name}
+ {product.name}
@@ -198,7 +198,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
-
+
استاندارد صنعتی آلمان
{product.specialBadge && (
@@ -210,7 +210,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
{product.name}
-
+
{pets.length > 0 ? (
product.optimisticTemplate?.replace("[PetName]", activePet?.name || "").replace("[OnSet]", product.onSetOfAction || "به زودی")
) : (
@@ -218,7 +218,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
)}
{fullProduct.shortDescription && (
-
+
{fullProduct.shortDescription}
)}
@@ -228,7 +228,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
{fullProduct.keyBenefits && (
-
+
چرا {fullProduct.name}؟
@@ -238,8 +238,8 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
const Icon = ICON_MAP[benefit.icon] || CheckCircle2;
return (
-
-
+
+
{benefit.title}
@@ -261,7 +261,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
موجود در انبار
-
@@ -289,7 +289,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
{product.main_ingredients.map((ing, idx) => {
const termKey = termKeys.find(key => ing.includes(key));
return (
-
+
{termKey ? (
router.push(`/wiki?term=${id}`)}>
@@ -297,7 +297,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
) : ing}
-
+
);
})}
@@ -309,7 +309,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
تخمین اتمام بسته (هوش مصنوعی)
{Object.entries(product.analysis).map(([key, value]) => (
-
+
@@ -320,9 +320,9 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
{/* Feeding Section */}
-
+
-
+
توصیه غذایی و نحوه مصرف
@@ -347,7 +347,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
مورد تأیید دامپزشکان
{product.specialist.name}
-
{product.specialist.title}
+
{product.specialist.title}
"{product.specialist.message}"
@@ -359,7 +359,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
{/* Specialized Landing Banner */}
toast.info("بزودی: صفحه فرود تخصصی این محصول در حال آمادهسازی است")}
>
@@ -372,7 +372,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
گزارشهای علمی، ویدیوهای آموزشی و تجربیات واقعی دیگر صاحبان پت در لندینگپیج اختصاصی این محصول.
-
+
@@ -384,17 +384,17 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
{product.faqs && (
-
{product.faqs.map((faq, i) => (
-
+
{faq.question}
-
+
{faq.answer}
@@ -409,14 +409,14 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
{/* Sticky Sidebar */}
-
+
{toPersian(product.price)}
{/* Refill Auto-Calculator */}
-
+
هوش مصنوعی تکرار خرید
@@ -437,18 +437,18 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
وزن پت (کیلوگرم)
- {toPersian(weight)}
+ {toPersian(weight)}
setWeight(parseInt(e.target.value))}
- className="w-full h-1.5 bg-medical-gray-200 rounded-lg appearance-none cursor-pointer accent-canina-blue"
+ className="w-full h-1.5 bg-medical-gray-200 rounded-lg appearance-none cursor-pointer accent-canino-blue"
/>
- 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'}`}>جوان
- 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'}`}>بالغ
+ setPetType("young")} className={`flex-1 py-2 rounded-xl text-[10px] font-black transition-all ${petType === "young" ? 'bg-canino-blue text-white shadow-lg' : 'bg-white text-medical-gray-400'}`}>جوان
+ setPetType("adult")} className={`flex-1 py-2 rounded-xl text-[10px] font-black transition-all ${petType === "adult" ? 'bg-canino-blue text-white shadow-lg' : 'bg-white text-medical-gray-400'}`}>بالغ
@@ -457,7 +457,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
setItemQuantity(Math.max(1, itemQuantity - 1))}
- className="w-10 h-10 flex items-center justify-center rounded-xl bg-white text-medical-gray-900 border border-medical-gray-200 hover:bg-canina-blue hover:text-white hover:border-canina-blue transition-all shadow-sm"
+ className="w-10 h-10 flex items-center justify-center rounded-xl bg-white text-medical-gray-900 border border-medical-gray-200 hover:bg-canino-blue hover:text-white hover:border-canino-blue transition-all shadow-sm"
>
@@ -466,7 +466,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
setItemQuantity(itemQuantity + 1)}
- className="w-10 h-10 flex items-center justify-center rounded-xl bg-white text-medical-gray-900 border border-medical-gray-200 hover:bg-canina-blue hover:text-white hover:border-canina-blue transition-all shadow-sm"
+ className="w-10 h-10 flex items-center justify-center rounded-xl bg-white text-medical-gray-900 border border-medical-gray-200 hover:bg-canino-blue hover:text-white hover:border-canino-blue transition-all shadow-sm"
>
@@ -478,7 +478,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
addItem(product, itemQuantity, { quantity: calculation.dailyDose, unit: calculation.unit });
toast.success(`${toPersian(itemQuantity)} عدد ${product.name} به سبد خرید اضافه شد`);
}}
- className="w-[60%] flex items-center justify-center gap-1.5 px-4 bg-medical-gray-900 text-white rounded-2xl h-16 font-black text-sm hover:bg-canina-blue transition-all shadow-xl shadow-black/10 font-vazir whitespace-nowrap"
+ className="w-[60%] flex items-center justify-center gap-1.5 px-4 bg-medical-gray-900 text-white rounded-2xl h-16 font-black text-sm hover:bg-canino-blue transition-all shadow-xl shadow-black/10 font-vazir whitespace-nowrap"
>
افزودن به سبد خرید
@@ -491,7 +491,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
ضمانت اصالت محصول (Made in Germany)
-
+
آماده ارسال (تحویل حداکثر ۴۸ ساعت)
@@ -506,7 +506,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
const Icon = ICON_MAP[res.icon] || Sparkles;
return (
-
+
{res.text}
@@ -523,12 +523,12 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
{product.relatedProducts && product.relatedProducts.length > 0 && (
-
+
فرمولاسیون ترکیبی همافزا (Synergy Blend)
- اثربخشی دوبرابر با ترکیب هوشمند
+ اثربخشی دوبرابر با ترکیب هوشمند
@@ -552,14 +552,14 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
{relProduct.name}
{relProduct.description}
-
{relProduct.price}
+
{relProduct.price}
- مشاهده محصول مکمل
-
+ مشاهده محصول مکمل
+
);
@@ -586,7 +586,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
exit={{ opacity: 0, scale: 0.9, y: 20 }}
className="bg-white w-full max-w-lg rounded-[3rem] p-10 relative z-10 shadow-2xl overflow-hidden"
>
-
+
setShowRefillModal(false)}
className="absolute top-6 left-6 text-medical-gray-400 hover:text-medical-gray-600 transition-colors"
@@ -595,13 +595,13 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
-
-
+
+
سیستم یادآوری هوشمند
- بر اساس وزن {toPersian(weight)} کیلوگرمی {activePet ? `برای ${activePet.name}` : 'سگ شما'}، این بسته {toPersian(product.packageSize)} تایی دقیقاً {toPersian(calculation.duration)} روز دیگر تمام میشود.
+ بر اساس وزن {toPersian(weight)} کیلوگرمی {activePet ? `برای ${activePet.name}` : 'سگ شما'}، این بسته {toPersian(product.packageSize)} تایی دقیقاً {toPersian(calculation.duration)} روز دیگر تمام میشود.
@@ -612,7 +612,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
setShowRefillModal(false)}
- className="w-full bg-canina-blue text-white py-5 rounded-2xl font-black text-lg hover:shadow-xl hover:shadow-canina-blue/20 transition-all flex items-center justify-center gap-2"
+ className="w-full bg-canino-blue text-white py-5 rounded-2xl font-black text-lg hover:shadow-xl hover:shadow-canino-blue/20 transition-all flex items-center justify-center gap-2"
>
بله، پیامک یادآوری فعال شود
diff --git a/frontend/application/components/SafeImage.tsx b/frontend/application/components/SafeImage.tsx
index 16de38d..cf9d448 100644
--- a/frontend/application/components/SafeImage.tsx
+++ b/frontend/application/components/SafeImage.tsx
@@ -32,17 +32,17 @@ export default function SafeImage({
{Array.from({length: 24}).map((_, i) => (
-
+
))}
- C
+ C
-
+
-
+
{fallbackText}
@@ -53,7 +53,7 @@ export default function SafeImage({
{loading && (
-
+
)}
-
router.back()} className="flex items-center gap-2 text-medical-gray-400 font-black mb-10 hover:text-canina-blue transition-colors">
+ router.back()} className="flex items-center gap-2 text-medical-gray-400 font-black mb-10 hover:text-canino-blue transition-colors">
بازگشت
@@ -40,7 +40,7 @@ export default function SearchResultsPage({ query }: { query: string }) {
- نتایج جستجو برای: "{query}"
+ نتایج جستجو برای: "{query}"
{results.length} محصول با معیارهای شما مطابقت دارد.
@@ -65,7 +65,7 @@ export default function SearchResultsPage({ query }: { query: string }) {
key={product.id}
layoutId={product.id}
onClick={() => router.push(`/shop/${product.slug || product.id}`)}
- className="bg-white rounded-[2.5rem] p-8 border border-medical-gray-200 group cursor-pointer hover:shadow-2xl hover:shadow-canina-blue/10 transition-all flex flex-col relative"
+ className="bg-white rounded-[2.5rem] p-8 border border-medical-gray-200 group cursor-pointer hover:shadow-2xl hover:shadow-canino-blue/10 transition-all flex flex-col relative"
>
-
{product.category}
-
{product.name}
+
{product.category}
+
{product.name}
{product.benefits}
@@ -100,7 +100,7 @@ export default function SearchResultsPage({ query }: { query: string }) {
{product.price}
-
+
diff --git a/frontend/application/components/SmartAdvisor.tsx b/frontend/application/components/SmartAdvisor.tsx
index bc412b9..0d100f4 100644
--- a/frontend/application/components/SmartAdvisor.tsx
+++ b/frontend/application/components/SmartAdvisor.tsx
@@ -89,18 +89,18 @@ export default function SmartAdvisor({ onComplete, rules = [] }: SmartAdvisorPro
};
return (
-
+
-
- تکنولوژی پایش هوشمند
+
+ تکنولوژی پایش هوشمند
-
دستیار سلامت کانینا
+
دستیار سلامت کانینو
فقط چند قدم تا صدور شناسنامه هوشمند و دریافت پیشنهادات تخصصی
@@ -108,7 +108,7 @@ export default function SmartAdvisor({ onComplete, rules = [] }: SmartAdvisorPro
{/* Progress Indicator */}
setType("سگ")}
- className={`flex flex-col items-center gap-4 p-8 rounded-[2.5rem] border-4 transition-all ${type === "سگ" ? 'border-canina-blue bg-white shadow-xl shadow-canina-blue/10 scale-105' : 'border-transparent bg-white/50 text-medical-gray-300 hover:bg-white'}`}
+ className={`flex flex-col items-center gap-4 p-8 rounded-[2.5rem] border-4 transition-all ${type === "سگ" ? 'border-canino-blue bg-white shadow-xl shadow-canino-blue/10 scale-105' : 'border-transparent bg-white/50 text-medical-gray-300 hover:bg-white'}`}
>
-
+
سگ
setType("گربه")}
- className={`flex flex-col items-center gap-4 p-8 rounded-[2.5rem] border-4 transition-all ${type === "گربه" ? 'border-canina-blue bg-white shadow-xl shadow-canina-blue/10 scale-105' : 'border-transparent bg-white/50 text-medical-gray-300 hover:bg-white'}`}
+ className={`flex flex-col items-center gap-4 p-8 rounded-[2.5rem] border-4 transition-all ${type === "گربه" ? 'border-canino-blue bg-white shadow-xl shadow-canino-blue/10 scale-105' : 'border-transparent bg-white/50 text-medical-gray-300 hover:bg-white'}`}
>
-
+
گربه
@@ -154,7 +154,7 @@ export default function SmartAdvisor({ onComplete, rules = [] }: SmartAdvisorPro
value={name}
onChange={e => setName(e.target.value)}
placeholder="لوسی، تدی..."
- className="w-full bg-white border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canina-blue/20 outline-none font-black text-lg font-vazir"
+ className="w-full bg-white border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canino-blue/20 outline-none font-black text-lg font-vazir"
/>
@@ -164,7 +164,7 @@ export default function SmartAdvisor({ onComplete, rules = [] }: SmartAdvisorPro
value={breed}
onChange={e => setBreed(e.target.value)}
placeholder="ژرمن، پرشین..."
- className="w-full bg-white border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canina-blue/20 outline-none font-bold font-vazir"
+ className="w-full bg-white border border-medical-gray-200 rounded-2xl py-4 px-6 focus:ring-2 focus:ring-canino-blue/20 outline-none font-bold font-vazir"
/>
@@ -172,7 +172,7 @@ export default function SmartAdvisor({ onComplete, rules = [] }: SmartAdvisorPro
ثبت هویت و ادامه
@@ -197,17 +197,17 @@ export default function SmartAdvisor({ onComplete, rules = [] }: SmartAdvisorPro
سن (سال)
- setAge(Math.max(0, age - 1))} className="w-10 h-10 flex items-center justify-center bg-medical-gray-50 rounded-xl text-medical-gray-900 hover:bg-canina-blue hover:text-white transition-all shadow-sm">-
- {toPersian(age.toString())}
- setAge(age + 1)} className="w-10 h-10 flex items-center justify-center bg-medical-gray-50 rounded-xl text-medical-gray-900 hover:bg-canina-blue hover:text-white transition-all shadow-sm">+
+ setAge(Math.max(0, age - 1))} className="w-10 h-10 flex items-center justify-center bg-medical-gray-50 rounded-xl text-medical-gray-900 hover:bg-canino-blue hover:text-white transition-all shadow-sm">-
+ {toPersian(age.toString())}
+ setAge(age + 1)} className="w-10 h-10 flex items-center justify-center bg-medical-gray-50 rounded-xl text-medical-gray-900 hover:bg-canino-blue hover:text-white transition-all shadow-sm">+
وزن (کیلوگرم)
- setWeight(Math.max(1, weight - 1))} className="w-10 h-10 flex items-center justify-center bg-medical-gray-50 rounded-xl text-medical-gray-900 hover:bg-canina-blue hover:text-white transition-all shadow-sm">-
- {toPersian(weight.toString())}
- setWeight(weight + 1)} className="w-10 h-10 flex items-center justify-center bg-medical-gray-50 rounded-xl text-medical-gray-900 hover:bg-canina-blue hover:text-white transition-all shadow-sm">+
+ setWeight(Math.max(1, weight - 1))} className="w-10 h-10 flex items-center justify-center bg-medical-gray-50 rounded-xl text-medical-gray-900 hover:bg-canino-blue hover:text-white transition-all shadow-sm">-
+ {toPersian(weight.toString())}
+ setWeight(weight + 1)} className="w-10 h-10 flex items-center justify-center bg-medical-gray-50 rounded-xl text-medical-gray-900 hover:bg-canino-blue hover:text-white transition-all shadow-sm">+
@@ -219,7 +219,7 @@ export default function SmartAdvisor({ onComplete, rules = [] }: SmartAdvisorPro
setActivityLevel(level as any)}
- className={`py-4 rounded-2xl border-2 transition-all font-black italic ${activityLevel === level ? 'border-canina-blue bg-white text-canina-blue shadow-lg' : 'border-transparent bg-white/50 text-medical-gray-400 hover:bg-white'}`}
+ className={`py-4 rounded-2xl border-2 transition-all font-black italic ${activityLevel === level ? 'border-canino-blue bg-white text-canino-blue shadow-lg' : 'border-transparent bg-white/50 text-medical-gray-400 hover:bg-white'}`}
>
{level}
@@ -237,7 +237,7 @@ export default function SmartAdvisor({ onComplete, rules = [] }: SmartAdvisorPro
گام نهایی سلامت
@@ -268,12 +268,12 @@ export default function SmartAdvisor({ onComplete, rules = [] }: SmartAdvisorPro
prev.includes(opt.condition) ? prev.filter(c => c !== opt.condition) : [...prev, opt.condition]
);
}}
- className={`flex items-center gap-4 p-5 rounded-2xl border-2 transition-all text-right ${medicalConditions.includes(opt.condition) ? 'border-canina-blue bg-white shadow-md' : 'border-transparent bg-white/50 text-medical-gray-500 hover:bg-white'}`}
+ className={`flex items-center gap-4 p-5 rounded-2xl border-2 transition-all text-right ${medicalConditions.includes(opt.condition) ? 'border-canino-blue bg-white shadow-md' : 'border-transparent bg-white/50 text-medical-gray-500 hover:bg-white'}`}
>
-
+
-
{opt.label}
+
{opt.label}
))}
@@ -288,7 +288,7 @@ export default function SmartAdvisor({ onComplete, rules = [] }: SmartAdvisorPro
تکمیل و صدور شناسنامه
diff --git a/frontend/application/components/Tooltip.tsx b/frontend/application/components/Tooltip.tsx
index c6b4451..1450d59 100644
--- a/frontend/application/components/Tooltip.tsx
+++ b/frontend/application/components/Tooltip.tsx
@@ -20,7 +20,7 @@ export default function Tooltip({ termKey, children, onWikiNavigate }: TooltipPr
return (
setIsVisible(true)}
onMouseLeave={() => setIsVisible(false)}
>
@@ -35,9 +35,9 @@ export default function Tooltip({ termKey, children, onWikiNavigate }: TooltipPr
className="absolute bottom-full left-1/2 -translate-x-1/2 mb-3 w-64 p-4 bg-medical-gray-900 text-white rounded-2xl shadow-2xl z-[100] text-sm"
dir="rtl"
>
-
+
- دانشنامه علمی کانینا
+ دانشنامه علمی کانینو
{termData.term}
@@ -46,7 +46,7 @@ export default function Tooltip({ termKey, children, onWikiNavigate }: TooltipPr
{termData.wikiId && (
onWikiNavigate?.(termData.wikiId!)}
- className="flex items-center gap-1.5 text-canina-blue hover:text-white transition-colors text-[10px] font-bold"
+ className="flex items-center gap-1.5 text-canino-blue hover:text-white transition-colors text-[10px] font-bold"
>
مطالعه مقاله کامل
diff --git a/frontend/application/components/TopUpModal.tsx b/frontend/application/components/TopUpModal.tsx
index ab34e8b..7eaef30 100644
--- a/frontend/application/components/TopUpModal.tsx
+++ b/frontend/application/components/TopUpModal.tsx
@@ -75,7 +75,7 @@ export default function TopUpModal({ isOpen, onClose, onConfirm }: TopUpModalPro
>
-
+
شارژ سریع کیف پول
@@ -100,8 +100,8 @@ export default function TopUpModal({ isOpen, onClose, onConfirm }: TopUpModalPro
className={cn(
"px-6 py-3 rounded-2xl text-sm font-black transition-all border",
selectedPreset === preset.value
- ? "bg-canina-blue text-white border-canina-blue shadow-lg shadow-canina-blue/20"
- : "bg-white text-medical-gray-700 border-medical-gray-100 hover:border-canina-blue"
+ ? "bg-canino-blue text-white border-canino-blue shadow-lg shadow-canino-blue/20"
+ : "bg-white text-medical-gray-700 border-medical-gray-100 hover:border-canino-blue"
)}
>
{preset.label}
@@ -118,7 +118,7 @@ export default function TopUpModal({ isOpen, onClose, onConfirm }: TopUpModalPro
type="text"
value={amount ? parseInt(amount).toLocaleString() : ""}
onChange={handleInputChange}
- className="w-full bg-medical-gray-50 border border-medical-gray-100 rounded-3xl py-6 px-8 outline-none font-black text-2xl text-center text-medical-gray-900 transition-all focus:ring-4 focus:ring-canina-blue/10 focus:border-canina-blue italic"
+ className="w-full bg-medical-gray-50 border border-medical-gray-100 rounded-3xl py-6 px-8 outline-none font-black text-2xl text-center text-medical-gray-900 transition-all focus:ring-4 focus:ring-canino-blue/10 focus:border-canino-blue italic"
placeholder="۰"
/>
{amount && (
@@ -128,14 +128,14 @@ export default function TopUpModal({ isOpen, onClose, onConfirm }: TopUpModalPro
-
-
با شارژ کیف پول، از هدیههای هوشمند کانینا و اولویت در ارسال سفارشها بهرهمند شوید.
+
+
با شارژ کیف پول، از هدیههای هوشمند کانینو و اولویت در ارسال سفارشها بهرهمند شوید.
{loading ? (
diff --git a/frontend/application/components/UserDashboard.tsx b/frontend/application/components/UserDashboard.tsx
index 0a7a718..f81d87d 100644
--- a/frontend/application/components/UserDashboard.tsx
+++ b/frontend/application/components/UserDashboard.tsx
@@ -143,9 +143,9 @@ export default function UserDashboard() {
{/* Breadcrumb */}
- router.push('/')}>خانه
+ router.push('/')}>خانه
- پنل کاربری
+ پنل کاربری
@@ -153,7 +153,7 @@ export default function UserDashboard() {
-
+
@@ -167,7 +167,7 @@ export default function UserDashboard() {
setActiveTab(tab.id as any)}
- className={`w-full flex items-center gap-3 p-4 rounded-2xl transition-all font-bold ${activeTab === tab.id ? "bg-canina-blue text-white shadow-lg shadow-canina-blue/20" : "text-medical-gray-600 hover:bg-medical-gray-50"}`}
+ className={`w-full flex items-center gap-3 p-4 rounded-2xl transition-all font-bold ${activeTab === tab.id ? "bg-canino-blue text-white shadow-lg shadow-canino-blue/20" : "text-medical-gray-600 hover:bg-medical-gray-50"}`}
>
{tab.icon}
{tab.label}
@@ -185,7 +185,7 @@ export default function UserDashboard() {
-
+
موجودی کیف پول
@@ -196,7 +196,7 @@ export default function UserDashboard() {
{ setActiveTab("wallet"); setIsTopUpModalOpen(true); }}
disabled={isTopUpModalOpen}
- className="mt-8 bg-canina-blue w-full py-4 rounded-2xl font-black hover:bg-white hover:text-canina-blue transition-all shadow-lg shadow-black/20 flex items-center justify-center gap-2"
+ className="mt-8 bg-canino-blue w-full py-4 rounded-2xl font-black hover:bg-white hover:text-canino-blue transition-all shadow-lg shadow-black/20 flex items-center justify-center gap-2"
>
شارژ کیف پول
@@ -263,7 +263,7 @@ export default function UserDashboard() {
className={cn(
"w-full border p-4 rounded-2xl font-bold outline-none transition-all",
isEditing
- ? "bg-white border-canina-blue/30 focus:ring-2 focus:ring-canina-blue/20"
+ ? "bg-white border-canino-blue/30 focus:ring-2 focus:ring-canino-blue/20"
: "bg-medical-gray-50 border-medical-gray-100"
)}
/>
@@ -282,7 +282,7 @@ export default function UserDashboard() {
className={cn(
"w-full border p-4 rounded-2xl font-bold outline-none transition-all",
isEditing
- ? "bg-white border-canina-blue/30 focus:ring-2 focus:ring-canina-blue/20"
+ ? "bg-white border-canino-blue/30 focus:ring-2 focus:ring-canino-blue/20"
: "bg-medical-gray-50 border-medical-gray-100"
)}
/>
@@ -301,7 +301,7 @@ export default function UserDashboard() {
className={cn(
"w-full border p-4 rounded-2xl font-bold outline-none transition-all text-left",
isEditing
- ? "bg-white border-canina-blue/30 focus:ring-2 focus:ring-canina-blue/20"
+ ? "bg-white border-canino-blue/30 focus:ring-2 focus:ring-canino-blue/20"
: "bg-medical-gray-50 border-medical-gray-100"
)}
dir="ltr"
@@ -322,7 +322,7 @@ export default function UserDashboard() {
className={cn(
"w-full border p-4 rounded-2xl font-bold outline-none transition-all text-left",
isEditing
- ? "bg-white border-canina-blue/30 focus:ring-2 focus:ring-canina-blue/20"
+ ? "bg-white border-canino-blue/30 focus:ring-2 focus:ring-canino-blue/20"
: "bg-medical-gray-50 border-medical-gray-100 opacity-75 cursor-not-allowed"
)}
dir="ltr"
@@ -336,7 +336,7 @@ export default function UserDashboard() {
{isSavingProfile && }
ذخیره تغییرات
@@ -361,7 +361,7 @@ export default function UserDashboard() {
setIsEditing(true)}
- className="bg-medical-gray-900 text-white px-10 py-4 rounded-2xl font-black hover:bg-canina-blue transition-all"
+ className="bg-medical-gray-900 text-white px-10 py-4 rounded-2xl font-black hover:bg-canino-blue transition-all"
>
ویرایش اطلاعات
@@ -383,7 +383,7 @@ export default function UserDashboard() {
هنوز سفارشی ثبت نکردهاید.
-
router.push('/shop')} className="mt-6 text-canina-blue font-black underline underline-offset-8">برو به فروشگاه
+
router.push('/shop')} className="mt-6 text-canino-blue font-black underline underline-offset-8">برو به فروشگاه
) : (
@@ -395,15 +395,15 @@ export default function UserDashboard() {
key={order.id}
whileHover={{ scale: 1.01, x: -5 }}
onClick={() => setSelectedOrder(order)}
- className="p-6 border border-medical-gray-100 rounded-[2.5rem] hover:border-canina-blue transition-all group cursor-pointer bg-white overflow-hidden relative"
+ className="p-6 border border-medical-gray-100 rounded-[2.5rem] hover:border-canino-blue transition-all group cursor-pointer bg-white overflow-hidden relative"
>
-
+
-
سفارش {toPersian(order.id.toUpperCase())}
+
سفارش {toPersian(order.id.toUpperCase())}
{toPersian(new Date(order.date).toLocaleDateString("fa-IR"))}
@@ -413,7 +413,7 @@ export default function UserDashboard() {
{toPersian(order.total.toLocaleString())} تومان
-
+
{order.status === 'delivered' ? 'تحویل شده' : 'ارسال شده'}
@@ -434,7 +434,7 @@ export default function UserDashboard() {
آدرسهای من
افزودن آدرس جدید
@@ -455,12 +455,12 @@ export default function UserDashboard() {
animate={{ opacity: 1, y: 0 }}
className={cn(
"p-8 bg-white border rounded-[2.5rem] relative group transition-all",
- addr.isDefault ? "border-canina-blue shadow-xl shadow-canina-blue/5" : "border-medical-gray-100 hover:border-medical-gray-200"
+ addr.isDefault ? "border-canino-blue shadow-xl shadow-canino-blue/5" : "border-medical-gray-100 hover:border-medical-gray-200"
)}
>
-
+
@@ -476,7 +476,7 @@ export default function UserDashboard() {
handleEditClick(addr)}
- className="w-10 h-10 flex items-center justify-center rounded-xl bg-medical-gray-50 text-medical-gray-400 hover:bg-canina-blue hover:text-white transition-all shadow-sm"
+ className="w-10 h-10 flex items-center justify-center rounded-xl bg-medical-gray-50 text-medical-gray-400 hover:bg-canino-blue hover:text-white transition-all shadow-sm"
>
@@ -495,11 +495,11 @@ export default function UserDashboard() {
-
+
{toPersian(addr.phone)}
-
+
{toPersian(addr.zipCode)}
{!addr.isDefault && (
@@ -512,7 +512,7 @@ export default function UserDashboard() {
toast.error("خطا در تغییر آدرس پیشفرض");
}
}}
- className="mr-auto text-[10px] font-black text-canina-blue hover:text-medical-gray-900 uppercase tracking-widest whitespace-nowrap"
+ className="mr-auto text-[10px] font-black text-canino-blue hover:text-medical-gray-900 uppercase tracking-widest whitespace-nowrap"
>
انتخاب به عنوان پیشفرض
@@ -542,7 +542,7 @@ export default function UserDashboard() {
{/* Main Balance Card */}
-
+
@@ -572,7 +572,7 @@ export default function UserDashboard() {
setIsTopUpModalOpen(true)}
- className="flex-1 md:w-40 h-16 bg-white text-canina-blue rounded-2xl font-black text-sm flex items-center justify-center gap-2 hover:bg-medical-gray-900 hover:text-white transition-all shadow-xl shadow-black/10 group/topup"
+ className="flex-1 md:w-40 h-16 bg-white text-canino-blue rounded-2xl font-black text-sm flex items-center justify-center gap-2 hover:bg-medical-gray-900 hover:text-white transition-all shadow-xl shadow-black/10 group/topup"
>
شارژ آنی
@@ -598,7 +598,7 @@ export default function UserDashboard() {
) : (
(profile?.transactions || []).map((trx) => (
-
+
-
+
Vet Insights
- مشاوره ویدئویی دوست دامپزشک پت شما
+ مشاوره ویدئویی دوست دامپزشک پت شما
- متخصصین آلمانی کانینا مستقیماً با شما صحبت میکنند. نحوه مصرف، مزایای رقابتی و دانش تخصصی پشت هر محصول.
+ متخصصین آلمانی کانینو مستقیماً با شما صحبت میکنند. نحوه مصرف، مزایای رقابتی و دانش تخصصی پشت هر محصول.
router.push('/videos')}
- className="inline-flex items-center gap-2 text-canina-blue font-bold text-sm hover:translate-x-1 transition-transform rtl:hover:-translate-x-1"
+ className="inline-flex items-center gap-2 text-canino-blue font-bold text-sm hover:translate-x-1 transition-transform rtl:hover:-translate-x-1"
>
مشاهده همه ویدئوها
@@ -80,7 +80,7 @@ export default function VetGallery({ testimonials = [] }: { testimonials?: any[]
className="w-full h-full object-cover grayscale-[30%] group-hover:grayscale-0 transition-all duration-700"
/>
-
@@ -88,11 +88,11 @@ export default function VetGallery({ testimonials = [] }: { testimonials?: any[]
{video.duration || '۱:۰۰'}
-
+
{video.title || video.quote?.substring(0, 40) + '...'}
-
+
{video.doctor || video.vetName}
diff --git a/frontend/application/components/VideosPage.tsx b/frontend/application/components/VideosPage.tsx
index 082e3e5..d7293ec 100644
--- a/frontend/application/components/VideosPage.tsx
+++ b/frontend/application/components/VideosPage.tsx
@@ -69,12 +69,12 @@ export default function VideosPage() {
{/* Header */}
-
+
- آکادمی ویدئویی کانینا
+ آکادمی ویدئویی کانینو
-
@@ -126,7 +126,7 @@ export default function VideosPage() {
-
{video.title}
+
{video.title}
@@ -173,7 +173,7 @@ export default function VideosPage() {
className="w-full h-full object-contain"
/>
-
+
Verified Insight
diff --git a/frontend/application/components/__tests__/Footer.test.tsx b/frontend/application/components/__tests__/Footer.test.tsx
index 72a2f19..a0248cb 100644
--- a/frontend/application/components/__tests__/Footer.test.tsx
+++ b/frontend/application/components/__tests__/Footer.test.tsx
@@ -8,9 +8,9 @@ describe('Footer', () => {
it('renders footer brand text and standard layout elements', () => {
render(
);
- expect(screen.getByText('کانینا ایران')).toBeInTheDocument();
+ expect(screen.getByText('کانینو ایران')).toBeInTheDocument();
expect(screen.getByText('نماینده رسمی در ایران')).toBeInTheDocument();
- expect(screen.getByText('تهران، جردن، خیابان سعیدی، ساختمان کانینا، طبقه ۵، واحد ۱۹')).toBeInTheDocument();
+ expect(screen.getByText('تهران، جردن، خیابان سعیدی، ساختمان کانینو، طبقه ۵، واحد ۱۹')).toBeInTheDocument();
});
it('triggers onNavigate and onShopNavigate when quick links are clicked', () => {
diff --git a/frontend/application/components/__tests__/Header.test.tsx b/frontend/application/components/__tests__/Header.test.tsx
index 1113e2c..831b365 100644
--- a/frontend/application/components/__tests__/Header.test.tsx
+++ b/frontend/application/components/__tests__/Header.test.tsx
@@ -54,7 +54,7 @@ describe('Header', () => {
/>
);
- expect(screen.getByText('Canina')).toBeInTheDocument();
+ expect(screen.getByText('Canino')).toBeInTheDocument();
expect(screen.getByText('ایران')).toBeInTheDocument();
expect(screen.getByText('ورود / ثبتنام')).toBeInTheDocument();
});
diff --git a/frontend/application/lib/data/products.ts b/frontend/application/lib/data/products.ts
index 8872302..87e04f8 100644
--- a/frontend/application/lib/data/products.ts
+++ b/frontend/application/lib/data/products.ts
@@ -215,7 +215,7 @@ export const PRODUCTS: Product[] = [
image: "https://images.unsplash.com/photo-1594824812397-237f41c63230?auto=format&fit=crop&q=80&w=200",
message: "خمیر ایمون بوستر با استفاده از آغوز با کیفیت دارویی، بلافاصله سیستم ایمنی غیرفعال پت را فعال میکند."
},
- image: "https://www.canina.de/media/8c/fb/8e/311000_Canina_Immun_Booster_Paste_Abwehrkraefte_1280x1280.png"
+ image: "https://www.canina.de/media/8c/fb/8e/311000_Canino_Immun_Booster_Paste_Abwehrkraefte_1280x1280.png"
},
{
id: "mikrosilber-zahngel",
@@ -303,7 +303,7 @@ export const PRODUCTS: Product[] = [
image: "https://images.unsplash.com/photo-1559839734-2b71f1536783?auto=format&fit=crop&q=80&w=200",
message: "فیبر سیب منبع پکتین است که به رشد باکتریهای مفید روده کمک شایانی میکند."
},
- image: "https://www.canina.de/media/4c/32/38/1715077271/Ballaststoff-Mix-140108-V1-Canina-100g_600x600.webp"
+ image: "https://www.canina.de/media/4c/32/38/1715077271/Ballaststoff-Mix-140108-V1-Canino-100g_600x600.webp"
},
{
id: "lachs-ol",
@@ -346,9 +346,9 @@ export const PRODUCTS: Product[] = [
name: "دکتر ماری کونیگ",
title: "متخصص تغذیه دامپزشکی",
image: "https://images.unsplash.com/photo-1559839734-2b71f1536783?auto=format&fit=crop&q=80&w=200",
- message: "روغن سالمون کانینا به روش پرس سرد تهیه شده تا تمامی ویتامینهای حساس به حرارت حفظ شوند."
+ message: "روغن سالمون کانینو به روش پرس سرد تهیه شده تا تمامی ویتامینهای حساس به حرارت حفظ شوند."
},
- image: "https://www.canina.de/media/6b/48/81/731000_Canina_Lachsoel_Lachs_Oel_1280x1280.png"
+ image: "https://www.canina.de/media/6b/48/81/731000_Canino_Lachsoel_Lachs_Oel_1280x1280.png"
},
{
id: "herz-vital",
@@ -386,7 +386,7 @@ export const PRODUCTS: Product[] = [
image: "https://images.unsplash.com/photo-1559839734-2b71f1536783?auto=format&fit=crop&q=80&w=200",
message: "زالزالک جریان خون کرونر را بهبود بخشیده و فشار بر قلب را کاهش میدهد."
},
- image: "https://www.canina.de/media/73/6e/8b/1715077271/Herz-Vital-111858-V1-Canina-100ml_600x600.webp"
+ image: "https://www.canina.de/media/73/6e/8b/1715077271/Herz-Vital-111858-V1-Canino-100ml_600x600.webp"
},
{
id: "energy-gel",
@@ -426,7 +426,7 @@ export const PRODUCTS: Product[] = [
image: "https://images.unsplash.com/photo-1559839734-2b71f1536783?auto=format&fit=crop&q=80&w=200",
message: "این ژل برای پتهایی که در شرایط بحرانی نیاز به کالری فوزی دارند بینظیر است."
},
- image: "https://www.canina.de/media/cc/e0/75/1715077271/Petvital-Energy-Gel-111452-V1-Canina-100g_600x600.webp"
+ image: "https://www.canina.de/media/cc/e0/75/1715077271/Petvital-Energy-Gel-111452-V1-Canino-100g_600x600.webp"
},
{
id: "moor-tranke",
@@ -507,8 +507,8 @@ export const PRODUCTS: Product[] = [
name: "دکتر مونیخ",
title: "متخصص طب طبیعی دامپزشکی",
image: "https://images.unsplash.com/photo-1559839734-2b71f1536783?auto=format&fit=crop&q=80&w=200",
- message: "روغن سیاه دانه مصری کانینا حاوی مقادیر بالایی اسیدهای چرب چند غیراشباع است."
+ message: "روغن سیاه دانه مصری کانینو حاوی مقادیر بالایی اسیدهای چرب چند غیراشباع است."
},
- image: "https://www.canina.de/media/1b/83/7d/1715077272/Schwarz-Kuemmel-112503-V1-Canina-250ml_600x600.webp"
+ image: "https://www.canina.de/media/1b/83/7d/1715077272/Schwarz-Kuemmel-112503-V1-Canino-250ml_600x600.webp"
}
];
diff --git a/frontend/application/lib/store/__tests__/cartStore.test.ts b/frontend/application/lib/store/__tests__/cartStore.test.ts
index 911127d..4bac978 100644
--- a/frontend/application/lib/store/__tests__/cartStore.test.ts
+++ b/frontend/application/lib/store/__tests__/cartStore.test.ts
@@ -92,17 +92,17 @@ describe('cartStore', () => {
it('should apply discount coupon', () => {
const store = useCartStore.getState();
- const success = store.applyCoupon('CANINA2024');
+ const success = store.applyCoupon('CANINO2024');
expect(success).toBe(true);
const state = useCartStore.getState();
- expect(state.coupon).toEqual({ code: 'CANINA2024', discount: 0.1 });
+ expect(state.coupon).toEqual({ code: 'CANINO2024', discount: 0.1 });
});
it('should calculate subtotal, discount and total', () => {
const store = useCartStore.getState();
store.addItem(mockProduct, 2); // 2 * 1000 = 2000
- store.applyCoupon('CANINA2024'); // 10% discount
+ store.applyCoupon('CANINO2024'); // 10% discount
expect(useCartStore.getState().getSubtotal()).toBe(2000);
expect(useCartStore.getState().getDiscount()).toBe(200);
diff --git a/frontend/application/lib/store/__tests__/settingsStore.test.ts b/frontend/application/lib/store/__tests__/settingsStore.test.ts
index 548d31a..c4752a3 100644
--- a/frontend/application/lib/store/__tests__/settingsStore.test.ts
+++ b/frontend/application/lib/store/__tests__/settingsStore.test.ts
@@ -33,7 +33,7 @@ describe('settingsStore', () => {
it('should fetch settings successfully and map array to object', async () => {
const mockUiTexts = [
- { key: 'hero_title', value: 'Welcome to Canina' },
+ { key: 'hero_title', value: 'Welcome to Canino' },
{ key: 'hero_desc', value: 'Best supplements' },
];
const mockTerms = [
@@ -54,7 +54,7 @@ describe('settingsStore', () => {
await store.fetchSettings();
const state = useSettingsStore.getState();
- expect(state.texts['hero_title']).toBe('Welcome to Canina');
+ expect(state.texts['hero_title']).toBe('Welcome to Canino');
expect(state.texts['hero_desc']).toBe('Best supplements');
expect(state.scientificTerms['mussel']).toEqual(mockTerms[0]);
expect(state.isLoading).toBe(false);
diff --git a/frontend/application/lib/store/cartStore.ts b/frontend/application/lib/store/cartStore.ts
index eb416ca..cc8c530 100644
--- a/frontend/application/lib/store/cartStore.ts
+++ b/frontend/application/lib/store/cartStore.ts
@@ -165,6 +165,6 @@ export const useCartStore = create
()(
},
getTotal: () => get().getSubtotal() - get().getDiscount() + get().charityDonation,
}),
- { name: "canina-cart" }
+ { name: "canino-cart" }
)
);
diff --git a/frontend/application/lib/store/usePetStore.ts b/frontend/application/lib/store/usePetStore.ts
index a280dea..829a9b6 100644
--- a/frontend/application/lib/store/usePetStore.ts
+++ b/frontend/application/lib/store/usePetStore.ts
@@ -212,6 +212,6 @@ export const usePetStore = create()(
set({ pets: mappedPets, activePetId: get().activePetId && mappedPets.some(p => p.id === get().activePetId) ? get().activePetId : (mappedPets[0]?.id || null) });
},
}),
- { name: "canina-pets" }
+ { name: "canino-pets" }
)
);
diff --git a/frontend/application/lib/store/userStore.ts b/frontend/application/lib/store/userStore.ts
index db3b3f1..e192dc0 100644
--- a/frontend/application/lib/store/userStore.ts
+++ b/frontend/application/lib/store/userStore.ts
@@ -191,6 +191,6 @@ export const useUserStore = create()(
}
},
}),
- { name: "canina-user" }
+ { name: "canino-user" }
)
);
diff --git a/frontend/implementation_plan.md b/frontend/implementation_plan.md
index 57f2c21..922155b 100644
--- a/frontend/implementation_plan.md
+++ b/frontend/implementation_plan.md
@@ -1,6 +1,6 @@
# Application Backend Integration & Refactoring Plan
-This plan details the migration of the CaninaIran frontend application from using mock data to communicating entirely with the backend APIs, adding email/password authentication, and resolving issues with the pet profile forms.
+This plan details the migration of the CaninoIran frontend application from using mock data to communicating entirely with the backend APIs, adding email/password authentication, and resolving issues with the pet profile forms.
## User Review Required
> [!IMPORTANT]
@@ -18,15 +18,15 @@ This plan details the migration of the CaninaIran frontend application from usin
### 1. Database & Backend Auth [Backend]
Adds email/password authentication capabilities and standardizes the auth endpoints.
-#### [MODIFY] [schema.prisma](file:///c:/Users/parsa/Desktop/work/caninairan/backend/prisma/schema.prisma)
+#### [MODIFY] [schema.prisma](file:///c:/Users/parsa/Desktop/work/caninoiran/backend/prisma/schema.prisma)
- Add `password String? @db.VarChar(255)` to the `User` model.
- Run `npx prisma migrate dev --name add_user_password`.
-#### [MODIFY] [auth.controller.ts](file:///c:/Users/parsa/Desktop/work/caninairan/backend/src/auth/auth.controller.ts)
+#### [MODIFY] [auth.controller.ts](file:///c:/Users/parsa/Desktop/work/caninoiran/backend/src/auth/auth.controller.ts)
- Add `@Post('register-email')` endpoint to accept `email`, `password`, `firstName`, and `lastName`.
- Add `@Post('login-email')` endpoint to accept `email` and `password`.
-#### [MODIFY] [auth.service.ts](file:///c:/Users/parsa/Desktop/work/caninairan/backend/src/auth/auth.service.ts)
+#### [MODIFY] [auth.service.ts](file:///c:/Users/parsa/Desktop/work/caninoiran/backend/src/auth/auth.service.ts)
- Implement `bcrypt` hashing for `registerEmail` and password verification for `loginEmail`.
- Update `sendOtp` to return the generated code in the response body (as a fallback before SMS panel is implemented) and add a `// TODO: Connect to SMS provider` comment.
@@ -34,7 +34,7 @@ Adds email/password authentication capabilities and standardizes the auth endpoi
### 2. Frontend Auth (Storefront) [Frontend]
Refactors the storefront authentication modal to remove mock tests and integrate real email/password + mobile/OTP login.
-#### [MODIFY] [AuthModal.tsx](file:///c:/Users/parsa/Desktop/work/caninairan/frontend/application/components/AuthModal.tsx)
+#### [MODIFY] [AuthModal.tsx](file:///c:/Users/parsa/Desktop/work/caninoiran/frontend/application/components/AuthModal.tsx)
- Remove the "ورود سریع تستی" (mock login) button entirely.
- Implement two tabs: "ایمیل و رمز عبور" (Email/Password) and "شماره موبایل" (Mobile OTP).
- Wire up the Email tab to `/auth/register-email` and `/auth/login-email`.
@@ -45,11 +45,11 @@ Refactors the storefront authentication modal to remove mock tests and integrate
### 3. Pet Profile Update Form [Frontend]
Resolves the issue where updating the pet profile in the multi-step form sends an incomplete payload to the backend.
-#### [MODIFY] [PetProfileWizard.tsx](file:///c:/Users/parsa/Desktop/work/caninairan/frontend/application/components/PetProfileWizard.tsx)
+#### [MODIFY] [PetProfileWizard.tsx](file:///c:/Users/parsa/Desktop/work/caninoiran/frontend/application/components/PetProfileWizard.tsx)
- Update the `handleComplete` or `onSubmit` function to ensure it merges the state of all wizard steps (Name, Breed, Age, Weight, Activity Level, Medical Conditions).
- Ensure the payload strictly matches what the backend `PUT /api/pets/:id` expects.
-#### [MODIFY] [usePetStore.ts](file:///c:/Users/parsa/Desktop/work/caninairan/frontend/application/lib/store/usePetStore.ts)
+#### [MODIFY] [usePetStore.ts](file:///c:/Users/parsa/Desktop/work/caninoiran/frontend/application/lib/store/usePetStore.ts)
- Verify `updatePet` action properly merges changes and reflects the server response.
---
@@ -64,7 +64,7 @@ Currently, several sections in the Home page (`page.tsx`) rely on mock data or h
> 4. **Categories/Links:** Links to `/shop` and `/wiki` are static HTML.
> 5. **Hero Section:** Banners and text are static.
-#### [MODIFY] [page.tsx](file:///c:/Users/parsa/Desktop/work/caninairan/frontend/application/app/page.tsx)
+#### [MODIFY] [page.tsx](file:///c:/Users/parsa/Desktop/work/caninoiran/frontend/application/app/page.tsx)
- No immediate file changes if we just wanted the list, but we will wrap components to fetch data dynamically where applicable.
- For `SmartAdvisor`, we will ensure it uses the real database.
@@ -72,7 +72,7 @@ Currently, several sections in the Home page (`page.tsx`) rely on mock data or h
### 5. Blogs/Wiki Integration [Frontend & Backend]
Connects the Wiki page to the real backend database instead of hardcoded articles.
-#### [MODIFY] [wiki/page.tsx](file:///c:/Users/parsa/Desktop/work/caninairan/frontend/application/app/wiki/page.tsx)
+#### [MODIFY] [wiki/page.tsx](file:///c:/Users/parsa/Desktop/work/caninoiran/frontend/application/app/wiki/page.tsx)
- Replace static blog cards with `api.get('/blogs')` or Server-Side Rendering (SSR) fetching from the database.
- Create dynamic routing `/wiki/[slug]/page.tsx` for individual blog articles.
diff --git a/metadata.json b/metadata.json
index 61d4762..448fa19 100644
--- a/metadata.json
+++ b/metadata.json
@@ -1,5 +1,5 @@
{
- "name": "Canina Iran - Official Representative",
+ "name": "Canino Iran - Official Representative",
"description": "The official representative of Canina pharma GmbH in Iran. Specialist in veterinary supplements and pharmaceutical-grade pet care products since 1984.",
"requestFramePermissions": [],
"majorCapabilities": [
diff --git a/package.json b/package.json
index 26c749e..8da06e3 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "name": "caninairan-workspace",
+ "name": "caninoiran-workspace",
"version": "1.0.0",
"private": true,
"scripts": {
diff --git a/swagger.yml b/swagger.yml
index bb0cd82..bd56c3e 100644
--- a/swagger.yml
+++ b/swagger.yml
@@ -1,10 +1,10 @@
openapi: 3.0.0
info:
- title: Canina Iran API
- description: API Documentation for Canina Iran Pet Health & Supplement Platform
+ title: Canino Iran API
+ description: API Documentation for Canino Iran Pet Health & Supplement Platform
version: 1.0.0
servers:
- - url: https://api.canina.ir/v1
+ - url: https://api.canino.ir/v1
description: Production Server
paths: