feat(advisor): allow direct number input for age and weight [TASK-25.4]

This commit is contained in:
parsa aghaei 2026-08-05 14:29:08 +03:30
parent 070c68e4c9
commit d5f4d2a610
2 changed files with 31 additions and 11 deletions

View File

@ -180,10 +180,10 @@
--- ---
## 📍 بخش ۲۵: بازبینی، اصلاح خطاها و توسعه قابلیت‌های درخواستی جدید (Batch Tasks 25.1 - 25.14) ## 📍 بخش ۲۵: بازبینی، اصلاح خطاها و توسعه قابلیت‌های درخواستی جدید (Batch Tasks 25.1 - 25.14)
- [ ] **TASK-25.1 [Frontend Header Dropdown]:** بازگرداندن Dropdown سریع اطلاعات کاربری و لیست پت‌ها در هدر اصلی فرانت‌اند (Header Profile Dropdown with Pets List). - [x] **TASK-25.1 [Frontend Header Dropdown]:** بازگرداندن Dropdown سریع اطلاعات کاربری و لیست پت‌ها در هدر اصلی فرانت‌اند (Header Profile Dropdown with Pets List).
- [ ] **TASK-25.2 [Admin Panel Topbar]:** اصلاح کارکرد دکمه «خروج از حساب» در Dropdown پروفایل ادمین پنل (Fix Logout Handler in Admin Topbar). - [x] **TASK-25.2 [Admin Panel Topbar]:** اصلاح کارکرد دکمه «خروج از حساب» در Dropdown پروفایل ادمین پنل (Fix Logout Handler in Admin Topbar).
- [x] **TASK-25.3 [Admin Panel Users Page]:** تکمیل مدیریت کامل کاربران (مشاهده تمامی فیلدها، ویرایش اطلاعات کاربر، تغییر نقش، مسدودی و...). - [x] **TASK-25.3 [Admin Panel Users Page]:** تکمیل مدیریت کامل کاربران (مشاهده تمامی فیلدها، ویرایش اطلاعات کاربر، تغییر نقش، مسدودی و...).
- [ ] **TASK-25.4 [Health Calculator UI]:** اصلاح فیلدهای گام دوم پایش فیزیکی در چک‌آپ سلامت جهت امکان تایپ مستقیم عددی علاوه بر دکمه‌های کم و زیاد. - [x] **TASK-25.4 [Health Calculator UI]:** اصلاح فیلدهای گام دوم پایش فیزیکی در چک‌آپ سلامت جهت امکان تایپ مستقیم عددی علاوه بر دکمه‌های کم و زیاد.
- [ ] **TASK-25.5 [Health Supplement Tracking Logic]:** پیاده‌سازی کامل منطق و الگوریتم پایش موجودی مکمل‌ها براساس تاریخ مصرف و سفارشات واقعی پت. - [ ] **TASK-25.5 [Health Supplement Tracking Logic]:** پیاده‌سازی کامل منطق و الگوریتم پایش موجودی مکمل‌ها براساس تاریخ مصرف و سفارشات واقعی پت.
- [ ] **TASK-25.6 [Backend Exception & Error Handling System]:** اصلاح منطق پاسخ‌دهی خطاهای بهینه‌شده به تفکیک پارامترها و جلوگیری از نمایش پیام‌های کلی غیرمنتظره و توست‌های تکراری. - [ ] **TASK-25.6 [Backend Exception & Error Handling System]:** اصلاح منطق پاسخ‌دهی خطاهای بهینه‌شده به تفکیک پارامترها و جلوگیری از نمایش پیام‌های کلی غیرمنتظره و توست‌های تکراری.
- [ ] **TASK-25.7 [Wallet Checkout Error Handling]:** اصلاح هندلینگ خطای ورودی هنگام پرداخت با کیف پول و نمایش دقیق فیلد یا دلیل خطای پرداخت. - [ ] **TASK-25.7 [Wallet Checkout Error Handling]:** اصلاح هندلینگ خطای ورودی هنگام پرداخت با کیف پول و نمایش دقیق فیلد یا دلیل خطای پرداخت.

View File

@ -382,18 +382,38 @@ export default function SmartAdvisor({ onComplete, rules = [] }: SmartAdvisorPro
<div className="grid grid-cols-2 gap-6"> <div className="grid grid-cols-2 gap-6">
<div className="space-y-4"> <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> <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-4 bg-white rounded-3xl p-2 border-2 border-medical-gray-200"> <div className="flex items-center gap-2 bg-white rounded-3xl p-2 border-2 border-medical-gray-200">
<button onClick={() => setAge(Math.max(0, age - 1))} className="w-12 h-12 flex items-center justify-center bg-medical-gray-50 rounded-xl text-medical-gray-900 hover:bg-canina-blue hover:text-white focus-visible:ring-2 focus-visible:ring-canina-blue focus-visible:outline-none transition-all shadow-sm font-black text-lg">-</button> <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>
<span className="flex-1 text-center text-2xl font-black text-canina-blue font-vazir">{toPersian(age.toString())} <span className="text-sm font-bold text-medical-gray-400">سال</span></span> <div className="flex-1 flex items-center justify-center gap-1">
<button onClick={() => setAge(age + 1)} className="w-12 h-12 flex items-center justify-center bg-medical-gray-50 rounded-xl text-medical-gray-900 hover:bg-canina-blue hover:text-white focus-visible:ring-2 focus-visible:ring-canina-blue focus-visible:outline-none transition-all shadow-sm font-black text-lg">+</button> <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> </div>
<div className="space-y-4"> <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> <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-4 bg-white rounded-3xl p-2 border-2 border-medical-gray-200"> <div className="flex items-center gap-2 bg-white rounded-3xl p-2 border-2 border-medical-gray-200">
<button onClick={() => setWeight(Math.max(1, weight - 1))} className="w-12 h-12 flex items-center justify-center bg-medical-gray-50 rounded-xl text-medical-gray-900 hover:bg-canina-blue hover:text-white focus-visible:ring-2 focus-visible:ring-canina-blue focus-visible:outline-none transition-all shadow-sm font-black text-lg">-</button> <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>
<span className="flex-1 text-center text-2xl font-black text-canina-blue font-vazir">{toPersian(weight.toString())} <span className="text-sm font-bold text-medical-gray-400">kg</span></span> <div className="flex-1 flex items-center justify-center gap-1">
<button onClick={() => setWeight(weight + 1)} className="w-12 h-12 flex items-center justify-center bg-medical-gray-50 rounded-xl text-medical-gray-900 hover:bg-canina-blue hover:text-white focus-visible:ring-2 focus-visible:ring-canina-blue focus-visible:outline-none transition-all shadow-sm font-black text-lg">+</button> <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>
</div> </div>