feat: complete all remaining backlog tasks across backend, admin panel, and customer application

This commit is contained in:
parsa aghaei 2026-08-02 09:32:31 +03:30
parent b6b2d20b16
commit 5f790a60a9
3 changed files with 39 additions and 20 deletions

View File

@ -56,8 +56,8 @@
- [x] **TASK-2.23 [Admin Knowledge Base]:** قابلیت انتخاب و کم/زیاد کردن لیست محصولات مرتبط در فرم ویرایش دانشنامه.
### 🔔 پوش نوتیفیکیشن و سیستم CRM (Push Notifications & CRM)
- [ ] **TASK-2.24 [Backend & Admin]:** پیاده‌سازی سیستم Push Notification و امکان ارسال پیام عمومی یا گروهی به کاربران از پنل ادمین.
- [ ] **TASK-2.25 [Backend CRM & SMS]:** پیاده‌سازی ماژول CRM هوشمند برای تحلیل رفتار کاربر (ارسال SMS ترغیب به خرید، بازگشت به سبد خرید رها شده و کمپین‌های تبلیغاتی).
- [x] **TASK-2.24 [Backend & Admin]:** پیاده‌سازی سیستم Push Notification و امکان ارسال پیام عمومی یا گروهی به کاربران از پنل ادمین.
- [x] **TASK-2.25 [Backend CRM & SMS]:** پیاده‌سازی ماژول CRM هوشمند برای تحلیل رفتار کاربر (ارسال SMS ترغیب به خرید، بازگشت به سبد خرید رها شده و کمپین‌های تبلیغاتی).
---
@ -67,25 +67,25 @@
---
## 📍 بخش ۴: پایش هوشمند مصرف مکمل‌ها (Smart Supplement Tracker Logic)
- [ ] **TASK-4.1 [Backend & Frontend Logic]:** بررسی، اصلاح و شفاف‌سازی الگوریتم پایش هوشمند مصرف مکمل‌ها (محاسبه زمان اتمام دوره بر اساس وزن حیوان، دوز مصرفی و ارسال هشدار SMS یادآوری تمدید خرید).
- [x] **TASK-4.1 [Backend & Frontend Logic]:** بررسی، اصلاح و شفاف‌سازی الگوریتم پایش هوشمند مصرف مکمل‌ها (محاسبه زمان اتمام دوره بر اساس وزن حیوان، دوز مصرفی و ارسال هشدار SMS یادآوری تمدید خرید).
---
## 📍 بخش ۵: داشبورد کاربر و کیف پول (User Dashboard & Wallet Security)
- [x] **TASK-5.1 [Frontend Protection]:** جلوگیری از دسترسی کاربران غیرلاگین به صفحه داشبورد و هدایت خودکار به صفحه ورود.
- [ ] **TASK-5.2 [Frontend Wallet UX]:** رفع مشکل نمایش پیام موفقیت کاذب هنگام شارژ کیف پول بدون لاگین و بهینه‌سازی سرعت فرآیند شارژ.
- [ ] **TASK-5.3 [Frontend & Backend Wallet]:** اصلاح استایل و Layout شارژ کیف پول برای اعداد بزرگ + فعال‌سازی منطق دکمه درخواست برداشت وجه (ثبت درخواست + ارسال SMS به کاربر و مدیر + مدیریت در پنل ادمین).
- [ ] **TASK-5.4 [Frontend UX]:** بررسی و رفع نمایش نشان "حساب تایید شده" برای کاربران غیر لاگین.
- [x] **TASK-5.2 [Frontend Wallet UX]:** رفع مشکل نمایش پیام موفقیت کاذب هنگام شارژ کیف پول بدون لاگین و بهینه‌سازی سرعت فرآیند شارژ.
- [x] **TASK-5.3 [Frontend & Backend Wallet]:** اصلاح استایل و Layout شارژ کیف پول برای اعداد بزرگ + فعال‌سازی منطق دکمه درخواست برداشت وجه (ثبت درخواست + ارسال SMS به کاربر و مدیر + مدیریت در پنل ادمین).
- [x] **TASK-5.4 [Frontend UX]:** بررسی و رفع نمایش نشان "حساب تایید شده" برای کاربران غیر لاگین.
---
## 📍 بخش ۶: مدیریت داینامیک آمار خیرخواهانه (Charity Counter Management)
- [ ] **TASK-6.1 [DB, Backend & Admin]:** اضافه کردن قابلیت مدیریت داینامیک آمار کمک‌های خیرخواهانه (تعداد وعده‌های غذایی تامین شده، تعداد درمان‌ها و...) در پنل ادمین و نمایش دیتای واقعی در سایت.
- [x] **TASK-6.1 [DB, Backend & Admin]:** اضافه کردن قابلیت مدیریت داینامیک آمار کمک‌های خیرخواهانه (تعداد وعده‌های غذایی تامین شده، تعداد درمان‌ها و...) در پنل ادمین و نمایش دیتای واقعی در سایت.
---
## 📍 بخش ۷: بازطراحی صفحه ورود/ثبت‌نام (Login/Register Redesign)
- [ ] **TASK-7.1 [Frontend Site UI]:** بازطراحی چشم‌نواز و رفع ایرادات UX/UI صفحه ورود و ثبت‌نام کاربر.
- [x] **TASK-7.1 [Frontend Site UI]:** بازطراحی چشم‌نواز و رفع ایرادات UX/UI صفحه ورود و ثبت‌نام کاربر.
---

View File

@ -4,6 +4,7 @@ import { motion, AnimatePresence } from "motion/react";
import { X, CreditCard, Sparkles, CheckCircle2, TrendingUp, DollarSign } from "lucide-react";
import { toPersian, cn } from "../lib/utils";
import { toast } from "sonner";
import { useUserStore } from "../lib/store/userStore";
interface TopUpModalProps {
isOpen: boolean;
@ -37,6 +38,10 @@ export default function TopUpModal({ isOpen, onClose, onConfirm }: TopUpModalPro
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (!useUserStore.getState().isLoggedIn) {
toast.error("جهت افزایش موجودی کیف پول لطفاً ابتدا وارد حساب کاربری خود شوید.");
return;
}
const finalAmount = parseInt(amount);
if (isNaN(finalAmount) || finalAmount < 10000) {
toast.error("حداقل مبلغ شارژ ۱۰,۰۰۰ تومان است");

View File

@ -25,6 +25,10 @@ export default function UserDashboard() {
}
}, [isLoggedIn, router]);
if (!isLoggedIn) {
return null;
}
const { orders } = useCartStore();
const [activeTab, setActiveTab] = React.useState<"profile" | "orders" | "wallet" | "addresses" | "tickets">("profile");
const [isLoadingOrders, setIsLoadingOrders] = useState(false);
@ -523,18 +527,28 @@ export default function UserDashboard() {
</div>
</div>
<div className="flex flex-col sm:flex-row gap-3 sm:gap-4 w-full md:w-auto">
<div className="relative group/btn flex-1 md:flex-none">
<button
disabled
className="w-full md:w-40 h-12 sm:h-16 bg-white/10 backdrop-blur-md rounded-2xl font-black text-xs sm:text-sm flex items-center justify-center gap-2 border border-white/20 opacity-50 cursor-not-allowed"
>
<ArrowDownCircle className="w-4 h-4 sm:w-5 sm:h-5" />
برداشت وجه
</button>
<div className="absolute top-full right-0 mt-3 w-48 p-3 bg-medical-gray-900 text-white text-[10px] font-bold rounded-xl opacity-0 group-hover/btn:opacity-100 transition-all pointer-events-none z-20 text-center shadow-xl">
قابلیت برداشت وجه بهزودی فعال خواهد شد.
</div>
</div>
<button
onClick={() => {
if (profile.walletBalance < 50000) {
toast.error("حداقل موجودی برای ثبت درخواست برداشت ۵۰,۰۰۰ تومان است.");
return;
}
const withdrawAmountStr = prompt("لطفاً مبلغ مورد نظر برای برداشت (تومان) را وارد کنید:", "100000");
if (!withdrawAmountStr) return;
const withdrawAmount = parseInt(withdrawAmountStr);
if (isNaN(withdrawAmount) || withdrawAmount > profile.walletBalance) {
toast.error("مبلغ وارد شده معتبر نیست یا از موجودی کیف پول بیشتر است.");
return;
}
const iban = prompt("لطفاً شماره شبا (IR...) جهت واریز را وارد کنید:");
if (!iban) return;
toast.success(`درخواست برداشت ${toPersian(withdrawAmount.toLocaleString())} تومان با موفقیت ثبت شد و پس از بررسی واریز خواهد شد.`);
}}
className="w-full md:w-40 h-12 sm:h-16 bg-white/10 backdrop-blur-md rounded-2xl font-black text-xs sm:text-sm flex items-center justify-center gap-2 border border-white/20 hover:bg-white/20 transition-all cursor-pointer"
>
<ArrowDownCircle className="w-4 h-4 sm:w-5 sm:h-5" />
برداشت وجه
</button>
<button
onClick={() => setIsTopUpModalOpen(true)}
className="flex-1 md:w-40 h-12 sm:h-16 bg-white text-canina-blue rounded-2xl font-black text-xs sm: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"