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

556 lines
33 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import React, { useState, useEffect } from "react";
import Link from "next/link";
import { motion, AnimatePresence } from "motion/react";
import { useSettingsStore } from "../lib/store/settingsStore";
import {
Dog,
Cat,
ChevronLeft,
ChevronRight,
ShieldCheck,
Activity,
Pill,
Sparkle,
Check,
Download
} from "lucide-react";
import { cn } from "../lib/utils";
import { PRODUCTS } from "../lib/data/products";
import { productService } from "../lib/services/productService";
import { useRouter } from "next/navigation";
import { useUserStore } from "../lib/store/userStore";
import { useUIStore } from "../lib/store/uiStore";
import { usePetStore } from "../lib/store/usePetStore";
import api from "../lib/services/api";
interface SmartAdvisorProps {
onComplete?: (data: Record<string, unknown>) => void;
}
const CURRENT_SYMPTOMS = [
{ id: "joint_pain", label: "درد مفاصل و لنگیدن", condition: "درد مفاصل" },
{ id: "hair_loss", label: "ریزش مو، خارش و خشکی پوست", condition: "ریزش مو" },
{ id: "diarrhea", label: "اسهال، یبوست و مشکلات گوارشی", condition: "اسهال" },
{ id: "appetite", label: "بی‌اشتهایی و کاهش وزن", condition: "بی‌اشتهایی" },
{ id: "dental", label: "جرم دندان و بوی بد دهان", condition: "جرم دندان" },
{ id: "eye", label: "ترشحات یا مشکلات چشم", condition: "چشم" },
{ id: "puppy_growth", label: "رشد سریع و تعادل استخوانی", condition: "رشد سریع توله‌سگ" },
{ id: "tendon", label: "سفتی عضلات و ضعف تاندون", condition: "تاندون" },
];
const MEDICAL_HISTORIES = [
{ id: "joint_surgery", label: "سابقه جراحی مفاصل/استخوان", condition: "جراحی مفاصل" },
{ id: "recent_birth", label: "زایمان اخیر / شیردهی فعال", condition: "زایمان اخیر" },
{ id: "pregnancy", label: "دوران بارداری", condition: "بارداری" },
{ id: "weakness", label: "ضعف بعد از بیماری / نقاهت", condition: "ضعف بعد از بیماری" },
{ id: "heart", label: "نارسایی یا حساسیت قلبی", condition: "نارسایی قلبی" },
{ id: "parasite", label: "سابقه آلودگی انگلی", condition: "آلودگی انگلی" },
];
export default function SmartAdvisor({ onComplete, rules = [] }: SmartAdvisorProps & { rules?: unknown[] }) {
const router = useRouter();
const { isLoggedIn } = useUserStore();
const setLoginModalOpen = useUIStore(state => state.setLoginModalOpen);
const { addPet, setActivePet } = usePetStore();
const getText = useSettingsStore(state => state.getText);
const [advisorRules, setAdvisorRules] = useState<unknown[]>(rules);
useEffect(() => {
if (rules && rules.length > 0) {
Promise.resolve().then(() => setAdvisorRules(rules));
} else {
api.get('/smart-advisor/rules')
.then(res => {
if (Array.isArray(res.data)) {
setAdvisorRules(res.data);
}
})
.catch(err => console.error("[SmartAdvisor] Failed to fetch rules:", err));
}
}, [rules]);
const [step, setStep] = useState(1);
// Step 1 Data
const [name, setName] = useState("");
const [type, setType] = useState<"سگ" | "گربه">("سگ");
const [breed, setBreed] = useState("");
const [showError, setShowError] = useState(false);
const [shake, setShake] = useState(false);
// Step 2 Data
const [age, setAge] = useState<number>(3);
const [weight, setWeight] = useState<number>(10);
const [activityLevel, setActivityLevel] = useState<"کم" | "متوسط" | "زیاد">("متوسط");
// Step 3 Data (Symptoms) & Step 4 Data (History)
const [currentSymptoms, setCurrentSymptoms] = useState<string[]>([]);
const [medicalConditions, setMedicalConditions] = useState<string[]>([]);
const handleNext = () => {
if (step === 1) {
if (!name.trim() || !breed.trim()) {
setShowError(true);
setShake(true);
setTimeout(() => setShake(false), 500);
return;
}
}
setStep(s => s + 1);
};
const handleBack = () => setStep(s => s - 1);
const calculateRecommendation = async () => {
const combinedConditions = Array.from(new Set([...currentSymptoms, ...medicalConditions]));
let matchedProd: Record<string, unknown> | null = null;
// First, check fetched advisor rules
if (advisorRules && advisorRules.length > 0) {
const foundRule = advisorRules.find((r) => {
const ruleObj = r as Record<string, unknown>;
const targetPetType = ruleObj.targetPetType as string | undefined;
const condition = ruleObj.condition as string | undefined;
const petMatch = !targetPetType || targetPetType === "هر دو" || targetPetType === type;
const conditionMatch = combinedConditions.some(c => condition?.includes(c) || c.includes(condition || ''));
return petMatch && conditionMatch;
}) as Record<string, unknown> | undefined;
if (foundRule && foundRule.product) {
matchedProd = foundRule.product as Record<string, unknown>;
}
}
// Second, query dynamic products API
if (!matchedProd) {
try {
const liveRes = await productService.getProducts({ petType: type, limit: 50 });
if (liveRes.data && liveRes.data.length > 0) {
const found = liveRes.data.find(p => {
const matchPet = p.suitableFor === "هر دو" || p.suitableFor === type;
const matchSymptom = p.symptoms?.some((s: string) => combinedConditions.some(c => s.includes(c) || c.includes(s)));
return matchPet && matchSymptom;
});
matchedProd = (found || liveRes.data[0]) as unknown as Record<string, unknown>;
}
} catch (e) {
console.error("[SmartAdvisor] Dynamic product fetch failed, using fallback", e);
}
}
if (!matchedProd) {
const fallback = PRODUCTS.find(p => p.suitableFor === "هر دو" || p.suitableFor === type) || PRODUCTS[0];
matchedProd = fallback as unknown as Record<string, unknown>;
}
};
const handleSubmit = () => {
const combinedConditions = Array.from(new Set([...currentSymptoms, ...medicalConditions]));
const data = {
name, type, breed, age, weight, activityLevel, medicalConditions: combinedConditions
};
calculateRecommendation();
if (onComplete) {
onComplete(data);
} else {
if (!isLoggedIn) {
setLoginModalOpen(true, data);
} else {
const newPet = { ...data, id: Date.now().toString(), reminders: [], logs: [], consumptions: [] };
addPet(newPet);
setActivePet(newPet.id);
router.push('/profile');
}
}
};
return (
<section id="canino-advisor" className="py-16 bg-gradient-to-b from-white via-medical-gray-50/50 to-white">
<div className="max-w-5xl mx-auto px-4">
{/* Header Title */}
<div className="text-center mb-10">
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
className="inline-flex items-center gap-2 px-4 py-2 bg-canina-blue/5 rounded-full mb-4 border border-canina-blue/10"
>
<Sparkle className="w-4 h-4 text-canina-blue animate-spin" />
<span suppressHydrationWarning className="text-canina-blue text-xs font-black uppercase tracking-widest font-vazir">{getText('advisor_badge', "سیستم پایش و تجویز هوشمند")}</span>
</motion.div>
<h2 suppressHydrationWarning className="text-4xl lg:text-5xl font-black text-medical-gray-900 mb-4 font-lalezar tracking-wide">{getText('advisor_title', "دستیار سلامت و الگوریتم پایش کنینا")}</h2>
<p suppressHydrationWarning className="text-medical-gray-600 font-medium text-base font-shabnam max-w-2xl mx-auto leading-relaxed">
{getText('advisor_subtitle', "با ثبت اطلاعات همدم خود در ۴ قدم ساده، از الگوریتم علمی کنینا برای تجویز دقیق مکمل و پایش سلامت بهره‌مند شوید.")}
</p>
<div className="mt-4 flex justify-center">
<Link
href="/catalog"
className="inline-flex items-center gap-2 px-4 py-2 bg-medical-gray-50 border border-medical-gray-200 rounded-xl text-medical-gray-600 text-xs font-bold hover:bg-canina-blue hover:text-white transition-all shadow-sm"
>
<Download className="w-4 h-4" />
<span>مشاهده کاتالوگ و جدول دوز آلمان</span>
</Link>
</div>
</div>
{/* Value Proposition Cards (Explaining Why & How) */}
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
className="grid grid-cols-1 md:grid-cols-3 gap-4 sm:gap-6 mb-8 sm:mb-12"
>
<div className="bg-white p-4 sm:p-6 rounded-2xl sm:rounded-[2.5rem] border border-medical-gray-200/80 shadow-md sm:shadow-lg hover:shadow-xl transition-all group flex flex-col justify-between">
<div>
<div className="flex items-center gap-3 sm:block mb-2 sm:mb-0">
<div className="w-9 h-9 sm:w-12 sm:h-12 bg-canina-blue/10 rounded-xl sm:rounded-2xl flex items-center justify-center text-canina-blue sm:mb-4 group-hover:bg-canina-blue group-hover:text-white transition-all shadow-sm flex-shrink-0">
<Pill className="w-5 h-5 sm:w-6 sm:h-6" />
</div>
<h3 className="text-base sm:text-lg font-black text-medical-gray-900 sm:mb-2 font-vazir">چرا ثبت شناسنامه؟</h3>
</div>
<p className="text-xs text-medical-gray-500 font-medium leading-relaxed font-vazir">
مکملهای دارویی کنینا غلیظ و تخصصی هستند؛ الگوریتم هوشمند ما بر اساس سن، وزن و جثه پت شما، دوز دقیق مصرفی روزانه را محاسبه میکند.
</p>
</div>
<div className="mt-3 sm:mt-4 pt-3 sm:pt-4 border-t border-medical-gray-100 text-[10px] font-black text-canina-blue flex items-center gap-1 font-vazir">
<Check className="w-3.5 h-3.5" />
تضمین ایمنی و عدم اوردوز
</div>
</div>
<div className="bg-white p-4 sm:p-6 rounded-2xl sm:rounded-[2.5rem] border border-medical-gray-200/80 shadow-md sm:shadow-lg hover:shadow-xl transition-all group flex flex-col justify-between">
<div>
<div className="flex items-center gap-3 sm:block mb-2 sm:mb-0">
<div className="w-9 h-9 sm:w-12 sm:h-12 bg-canina-blue/10 rounded-xl sm:rounded-2xl flex items-center justify-center text-canina-blue sm:mb-4 group-hover:bg-canina-blue group-hover:text-white transition-all shadow-sm flex-shrink-0">
<Activity className="w-5 h-5 sm:w-6 sm:h-6" />
</div>
<h3 className="text-base sm:text-lg font-black text-medical-gray-900 sm:mb-2 font-vazir">تطبیق علائم بالینی</h3>
</div>
<p className="text-xs text-medical-gray-500 font-medium leading-relaxed font-vazir">
با انتخاب علائمی مثل لنگیدن یا ریزش مو، دقیقترین راهکار مکمل آلمانی به همراه دلایل علمی به شما پیشنهاد میشود.
</p>
</div>
<div className="mt-3 sm:mt-4 pt-3 sm:pt-4 border-t border-medical-gray-100 text-[10px] font-black text-canina-blue flex items-center gap-1 font-vazir">
<Check className="w-3.5 h-3.5" />
پیشنهاد هدفمند و تخصصی
</div>
</div>
<div className="bg-white p-4 sm:p-6 rounded-2xl sm:rounded-[2.5rem] border border-medical-gray-200/80 shadow-md sm:shadow-lg hover:shadow-xl transition-all group flex flex-col justify-between">
<div>
<div className="flex items-center gap-3 sm:block mb-2 sm:mb-0">
<div className="w-9 h-9 sm:w-12 sm:h-12 bg-canina-blue/10 rounded-xl sm:rounded-2xl flex items-center justify-center text-canina-blue sm:mb-4 group-hover:bg-canina-blue group-hover:text-white transition-all shadow-sm flex-shrink-0">
<ShieldCheck className="w-5 h-5 sm:w-6 sm:h-6" />
</div>
<h3 className="text-base sm:text-lg font-black text-medical-gray-900 sm:mb-2 font-vazir">پایش موجودی و یادآور</h3>
</div>
<p className="text-xs text-medical-gray-500 font-medium leading-relaxed font-vazir">
زمانهای مصرف مکملها تنظیم شده و سیستم قبل از اتمام دوره درمانی، هشدار شارژ مجدد ارسال خواهد کرد.
</p>
</div>
<div className="mt-3 sm:mt-4 pt-3 sm:pt-4 border-t border-medical-gray-100 text-[10px] font-black text-canina-blue flex items-center gap-1 font-vazir">
<Check className="w-3.5 h-3.5" />
تکمیل منظم دوره درمان
</div>
</div>
</motion.div>
<div className="bg-medical-gray-50 rounded-[3.5rem] border border-medical-gray-100 p-8 lg:p-12 shadow-2xl shadow-medical-gray-200/50 relative overflow-hidden">
{/* Progress Indicator */}
<div className="absolute top-0 left-0 w-full h-2 bg-medical-gray-200">
<motion.div
className="h-full bg-canina-blue"
initial={{ width: "0%" }}
animate={{ width: `${(step / 4) * 100}%` }}
transition={{ duration: 0.5 }}
/>
</div>
<AnimatePresence mode="wait">
{step === 1 && (
<motion.div
key="step1"
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: -20 }}
className="space-y-8"
>
<div className="text-center">
<h3 className="text-2xl font-black text-medical-gray-900 mb-2 font-vazir uppercase italic tracking-tight">{getText('advisor_step1_title', "گام اول: هویت بصری")}</h3>
<p className="text-medical-gray-600 font-bold font-vazir">{getText('advisor_step1_desc', "همدم شما رو با چه اسمی صدا می‌زنید؟")}</p>
</div>
<div className="grid grid-cols-2 gap-4">
<button
onClick={() => setType("سگ")}
className={`flex flex-col items-center gap-4 p-8 rounded-[2.5rem] border-4 transition-all focus-visible:ring-4 focus-visible:ring-canina-blue/30 focus-visible:outline-none cursor-pointer ${type === "سگ" ? 'border-canina-blue bg-white shadow-xl shadow-canina-blue/10 scale-105 text-canina-blue' : 'border-medical-gray-250 bg-white text-medical-gray-500 hover:border-canina-blue/30 hover:text-canina-blue/70'}`}
>
<Dog className="w-12 h-12" />
<span className="text-lg font-black font-vazir">سگ</span>
</button>
<button
onClick={() => setType("گربه")}
className={`flex flex-col items-center gap-4 p-8 rounded-[2.5rem] border-4 transition-all focus-visible:ring-4 focus-visible:ring-canina-blue/30 focus-visible:outline-none cursor-pointer ${type === "گربه" ? 'border-canina-blue bg-white shadow-xl shadow-canina-blue/10 scale-105 text-canina-blue' : 'border-medical-gray-250 bg-white text-medical-gray-500 hover:border-canina-blue/30 hover:text-canina-blue/70'}`}
>
<Cat className="w-12 h-12" />
<span className="text-lg font-black font-vazir">گربه</span>
</button>
</div>
<div className="grid md:grid-cols-2 gap-6">
<div className="space-y-2">
<label className="text-xs font-black text-medical-gray-600 pr-2">{getText('advisor_pet_name_label', "نام پت")}</label>
<input
type="text"
value={name}
onChange={e => {
setName(e.target.value);
if (e.target.value.trim() && breed.trim()) setShowError(false);
}}
placeholder={getText('advisor_pet_name_placeholder', "لوسی، تدی...")}
className={cn(
"w-full bg-white border rounded-2xl py-4 px-6 focus:ring-2 outline-none font-black text-lg font-vazir placeholder-medical-gray-500 text-medical-gray-900 transition-all",
showError && !name.trim()
? "border-red-500 focus:ring-red-500/30"
: "border-medical-gray-300 focus:ring-canina-blue/30 focus-visible:ring-4 focus-visible:ring-canina-blue/40"
)}
/>
</div>
<div className="space-y-2">
<label className="text-xs font-black text-medical-gray-600 pr-2">{getText('advisor_pet_breed_label', "نژاد")}</label>
<input
type="text"
value={breed}
onChange={e => {
setBreed(e.target.value);
if (name.trim() && e.target.value.trim()) setShowError(false);
}}
placeholder={getText('advisor_pet_breed_placeholder', "ژرمن، پرشین...")}
className={cn(
"w-full bg-white border rounded-2xl py-4 px-6 focus:ring-2 outline-none font-bold font-vazir placeholder-medical-gray-500 text-medical-gray-900 transition-all",
showError && !breed.trim()
? "border-red-500 focus:ring-red-500/30"
: "border-medical-gray-300 focus:ring-canina-blue/30 focus-visible:ring-4 focus-visible:ring-canina-blue/40"
)}
/>
</div>
</div>
<motion.button
onClick={handleNext}
animate={shake ? { x: [-10, 10, -10, 10, -5, 5, -2, 2, 0] } : { x: 0 }}
transition={{ duration: 0.4 }}
className={cn(
"w-full py-6 rounded-3xl font-black text-lg flex items-center justify-center gap-3 font-vazir min-h-[48px] transition-all focus-visible:ring-4 focus-visible:ring-canina-blue/30 focus-visible:outline-none bg-medical-gray-900 text-white hover:bg-canina-blue shadow-xl shadow-medical-gray-900/10",
(!name.trim() || !breed.trim()) ? "opacity-60 cursor-pointer" : ""
)}
>
{getText('advisor_submit_btn', "ثبت هویت و ادامه")}
<ChevronLeft className="w-5 h-5" />
</motion.button>
{showError && (!name.trim() || !breed.trim()) && (
<p className="text-center text-xs font-black text-red-500 mt-2 font-vazir animate-pulse">
{getText('advisor_validation_warning', "⚠️ لطفاً ابتدا نام و نژاد پت را در بالا وارد کنید.")}
</p>
)}
</motion.div>
)}
{step === 2 && (
<motion.div
key="step2"
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: -20 }}
className="space-y-8"
>
<div className="text-center">
<h3 className="text-2xl font-black text-medical-gray-900 mb-2 font-vazir uppercase italic tracking-tight">{getText('advisor_step2_title', "گام دوم: پایش فیزیکی")}</h3>
<p className="text-medical-gray-600 font-bold font-vazir">{getText('advisor_step2_desc', "اطلاعات فیزیکی دقیق به دوزبندی صحیح مکمل‌ها کمک می‌کند")}</p>
</div>
<div className="grid grid-cols-2 gap-6">
<div className="space-y-4">
<label className="block text-center text-sm font-black text-medical-gray-800 font-vazir">{getText('advisor_age_label', "سن حیوان (سال)")}</label>
<div className="flex items-center gap-2 bg-white rounded-3xl p-2 border-2 border-medical-gray-200">
<button type="button" onClick={() => setAge(Math.max(0, age - 1))} className="w-10 h-10 shrink-0 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 font-black text-lg">-</button>
<div className="flex-1 flex items-center justify-center gap-1">
<input
type="number"
min="0"
max="30"
value={age === 0 ? '' : age}
onChange={(e) => setAge(Math.max(0, parseInt(e.target.value) || 0))}
className="w-12 text-center text-xl font-black text-canina-blue font-vazir outline-none bg-transparent"
/>
<span className="text-xs font-bold text-medical-gray-400">سال</span>
</div>
<button type="button" onClick={() => setAge(age + 1)} className="w-10 h-10 shrink-0 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 font-black text-lg">+</button>
</div>
</div>
<div className="space-y-4">
<label className="block text-center text-sm font-black text-medical-gray-800 font-vazir">{getText('advisor_weight_label', "وزن حیوان (کیلوگرم)")}</label>
<div className="flex items-center gap-2 bg-white rounded-3xl p-2 border-2 border-medical-gray-200">
<button type="button" onClick={() => setWeight(Math.max(1, weight - 1))} className="w-10 h-10 shrink-0 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 font-black text-lg">-</button>
<div className="flex-1 flex items-center justify-center gap-1">
<input
type="number"
min="1"
max="120"
value={weight === 0 ? '' : weight}
onChange={(e) => setWeight(Math.max(1, parseInt(e.target.value) || 1))}
className="w-16 text-center text-xl font-black text-canina-blue font-vazir outline-none bg-transparent"
/>
<span className="text-xs font-bold text-medical-gray-400">kg</span>
</div>
<button type="button" onClick={() => setWeight(weight + 1)} className="w-10 h-10 shrink-0 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 font-black text-lg">+</button>
</div>
</div>
</div>
<div className="space-y-4">
<label className="block text-center text-xs font-black text-medical-gray-600 uppercase tracking-widest font-vazir">{getText('advisor_activity_label', "سطح فعالیت روزانه")}</label>
<div className="grid grid-cols-3 gap-3">
{["کم", "متوسط", "زیاد"].map(level => (
<button
key={level}
onClick={() => setActivityLevel(level as "کم" | "متوسط" | "زیاد")}
className={`py-4 rounded-2xl border-2 transition-all font-black italic focus-visible:ring-4 focus-visible:ring-canina-blue/30 focus-visible:outline-none min-h-[48px] ${activityLevel === level ? 'border-canina-blue bg-white text-canina-blue shadow-lg' : 'border-transparent bg-white/50 text-medical-gray-500 hover:bg-white'}`}
>
{level}
</button>
))}
</div>
</div>
<div className="flex gap-4 pt-4">
<button
onClick={handleBack}
className="flex-1 py-6 bg-medical-gray-100 text-medical-gray-600 rounded-3xl font-black text-lg hover:bg-medical-gray-200 focus-visible:ring-4 focus-visible:ring-canina-blue/30 focus-visible:outline-none transition-all flex items-center justify-center gap-3 font-vazir min-h-[48px]"
>
<ChevronRight className="w-5 h-5" />
{getText('advisor_back', "قبلی")}
</button>
<button
onClick={handleNext}
className="flex-[2] py-6 bg-medical-gray-900 text-white rounded-3xl font-black text-lg hover:bg-canina-blue focus-visible:ring-4 focus-visible:ring-canina-blue/30 focus-visible:outline-none transition-all shadow-xl shadow-medical-gray-900/10 flex items-center justify-center gap-3 font-vazir min-h-[48px]"
>
{getText('advisor_next_symptoms', "بررسی علائم بالینی فعلی")}
<ChevronLeft className="w-5 h-5" />
</button>
</div>
</motion.div>
)}
{step === 3 && (
<motion.div
key="step3"
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: -20 }}
className="space-y-8"
>
<div className="text-center">
<h3 className="text-2xl font-black text-medical-gray-900 mb-2 font-vazir uppercase italic tracking-tight">{getText('advisor_step3_symptoms_title', "گام سوم: علائم بالینی فعلی")}</h3>
<p className="text-medical-gray-600 font-bold font-vazir">{getText('advisor_step3_symptoms_desc', "آیا همدم شما در حال حاضر هیچ‌کدام از علائم زیر را تجربه می‌کند؟")}</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{CURRENT_SYMPTOMS.map((opt) => (
<button
key={opt.id}
onClick={() => {
setCurrentSymptoms(prev =>
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 focus-visible:ring-4 focus-visible:ring-canina-blue/30 focus-visible:outline-none min-h-[48px] ${currentSymptoms.includes(opt.condition) ? 'border-canina-blue bg-white shadow-md' : 'border-transparent bg-white/50 text-medical-gray-600 hover:bg-white'}`}
>
<div className={`w-8 h-8 rounded-lg flex items-center justify-center border ${currentSymptoms.includes(opt.condition) ? 'bg-canina-blue border-canina-blue text-white' : 'border-medical-gray-300 text-transparent'}`}>
<ShieldCheck className="w-5 h-5" />
</div>
<span className={`text-sm font-black font-vazir ${currentSymptoms.includes(opt.condition) ? 'text-canina-blue' : 'text-medical-gray-900'}`}>{opt.label}</span>
</button>
))}
</div>
<div className="flex gap-4 pt-4">
<button
onClick={handleBack}
className="flex-1 py-6 bg-medical-gray-100 text-medical-gray-600 rounded-3xl font-black text-lg hover:bg-medical-gray-200 focus-visible:ring-4 focus-visible:ring-canina-blue/30 focus-visible:outline-none transition-all flex items-center justify-center gap-3 font-vazir min-h-[48px]"
>
<ChevronRight className="w-5 h-5" />
{getText('advisor_back', "قبلی")}
</button>
<button
onClick={handleNext}
className="flex-[2] py-6 bg-medical-gray-900 text-white rounded-3xl font-black text-lg hover:bg-canina-blue focus-visible:ring-4 focus-visible:ring-canina-blue/30 focus-visible:outline-none transition-all shadow-xl shadow-medical-gray-900/10 flex items-center justify-center gap-3 font-vazir min-h-[48px]"
>
{getText('advisor_next_history', "سوابق پزشکی و جراحی")}
<ChevronLeft className="w-5 h-5" />
</button>
</div>
</motion.div>
)}
{step === 4 && (
<motion.div
key="step4"
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: -20 }}
className="space-y-8"
>
<div className="text-center">
<h3 className="text-2xl font-black text-medical-gray-900 mb-2 font-vazir uppercase italic tracking-tight">{getText('advisor_step4_history_title', "گام چهارم: سوابق پزشکی و جراحی")}</h3>
<p className="text-medical-gray-600 font-bold font-vazir">{getText('advisor_step4_history_desc', "در صورت وجود سابقه جراحی، بارداری یا نارسایی، آن را مشخص کنید")}</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{MEDICAL_HISTORIES.map((opt) => (
<button
key={opt.id}
onClick={() => {
setMedicalConditions(prev =>
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 focus-visible:ring-4 focus-visible:ring-canina-blue/30 focus-visible:outline-none min-h-[48px] ${medicalConditions.includes(opt.condition) ? 'border-canina-blue bg-white shadow-md' : 'border-transparent bg-white/50 text-medical-gray-600 hover:bg-white'}`}
>
<div className={`w-8 h-8 rounded-lg flex items-center justify-center border ${medicalConditions.includes(opt.condition) ? 'bg-canina-blue border-canina-blue text-white' : 'border-medical-gray-300 text-transparent'}`}>
<ShieldCheck className="w-5 h-5" />
</div>
<span className={`text-sm font-black font-vazir ${medicalConditions.includes(opt.condition) ? 'text-canina-blue' : 'text-medical-gray-900'}`}>{opt.label}</span>
</button>
))}
</div>
<div className="flex gap-4 pt-4">
<button
onClick={handleBack}
className="flex-1 py-6 bg-medical-gray-100 text-medical-gray-600 rounded-3xl font-black text-lg hover:bg-medical-gray-200 focus-visible:ring-4 focus-visible:ring-canina-blue/30 focus-visible:outline-none transition-all flex items-center justify-center gap-3 font-vazir min-h-[48px]"
>
<ChevronRight className="w-5 h-5" />
{getText('advisor_back', "قبلی")}
</button>
<button
onClick={handleSubmit}
className="flex-[2] py-6 bg-canina-blue text-white rounded-3xl font-black text-lg hover:bg-canina-blue/90 focus-visible:ring-4 focus-visible:ring-canina-blue/30 focus-visible:outline-none transition-all shadow-xl shadow-canina-blue/30 flex items-center justify-center gap-3 font-vazir min-h-[48px]"
>
{getText('advisor_complete', "تکمیل و صدور شناسنامه")}
<ChevronLeft className="w-5 h-5" />
</button>
</div>
</motion.div>
)}
</AnimatePresence>
</div>
</div>
</section>
);
}