diff --git a/app/admin/accounting/page.tsx b/app/admin/accounting/page.tsx index 659c5d1..004a5d6 100644 --- a/app/admin/accounting/page.tsx +++ b/app/admin/accounting/page.tsx @@ -170,6 +170,10 @@ export default function AccountingPage() { const [dateFrom, setDateFrom] = useState(''); const [dateTo, setDateTo] = useState(''); + // Time range + const [timeFrom, setTimeFrom] = useState(''); + const [timeTo, setTimeTo] = useState(''); + // Status filter — both paid statuses selected by default const [statuses, setStatuses] = useState([...PAID_STATUSES]); @@ -259,14 +263,28 @@ export default function AccountingPage() { } // Date range (created_at is "Y-m-d H:i:s") - if (dateFrom && p.created_at && p.created_at.slice(0, 10) < dateFrom) return false; - if (dateTo && p.created_at && p.created_at.slice(0, 10) > dateTo) return false; + // When time is also selected, compare full datetime strings; + // otherwise compare only the date portion (YYYY-MM-DD). + const created = p.created_at ?? ''; + if (dateFrom) { + const datePart = created.slice(0, 10); + if (timeFrom) { + // Full datetime comparison: "YYYY-MM-DD HH:mm:ss" + if (created < `${dateFrom} ${timeFrom}`) return false; + } else if (datePart < dateFrom) return false; + } + if (dateTo) { + const datePart = created.slice(0, 10); + if (timeTo) { + if (created > `${dateTo} ${timeTo}`) return false; + } else if (datePart > dateTo) return false; + } return true; }); setResult(computeAccounting(filtered, myket, cafe, fee)); - }, [allPurchases, statuses, selectedProductId, selectedPackageName, dateFrom, dateTo, myketRate, cafeRate, transactionFee]); + }, [allPurchases, statuses, selectedProductId, selectedPackageName, dateFrom, dateTo, timeFrom, timeTo, myketRate, cafeRate, transactionFee]); // Recompute on filter/rate changes (no refetch needed once data is cached) useEffect(() => { @@ -278,6 +296,8 @@ export default function AccountingPage() { setSelectedProductId(''); setDateFrom(''); setDateTo(''); + setTimeFrom(''); + setTimeTo(''); setStatuses([...PAID_STATUSES]); setMyketRate('85'); setCafeRate('85'); @@ -323,7 +343,7 @@ export default function AccountingPage() { }} className="bg-white dark:bg-gray-900 ring-1 ring-gray-200 dark:ring-gray-800 rounded-2xl p-5 sm:p-6 mb-6 shadow-sm" > -
+
setTimeFrom(e.target.value)} + className={inputClass} + placeholder="۰۰:۰۰" + /> +
+
+ +
+ + setTimeTo(e.target.value)} + className={inputClass} + placeholder="۲۳:۵۹" + /> +
{/* Status checkboxes */} diff --git a/app/admin/purchases/page.tsx b/app/admin/purchases/page.tsx index c00356f..acff371 100644 --- a/app/admin/purchases/page.tsx +++ b/app/admin/purchases/page.tsx @@ -15,7 +15,7 @@ import { getPurchaseStatusLabel, } from '@/types/purchase'; import { PackageName } from '@/types/package'; -import { formatPrice, formatDate, getProductTypeLabel, getPurchaseFinalPrice } from '@/lib/utils'; +import { formatPrice, formatDate, formatTime, getProductTypeLabel, getPurchaseFinalPrice } from '@/lib/utils'; import { MagnifyingGlassIcon, ArrowPathIcon } from '@heroicons/react/24/outline'; const statusBadgeClass = (status: number): string => { @@ -212,7 +212,7 @@ export default function PurchasesPage() { قیمت نهایی منبع پرداخت وضعیت - تاریخ + تاریخ و ساعت @@ -254,7 +254,7 @@ export default function PurchasesPage() { - {formatDate(purchase.created_at)} + {formatDate(purchase.created_at)} {formatTime(purchase.created_at)} ))}