export type DashboardRange = 'day' | 'week' | 'month' | 'season'; export type TransactionStatus = 'all' | 'Paid' | 'Verified' | 'Failed' | 'Reversed'; export interface DashboardFilters { range: DashboardRange; period: string; terminal: string; status: TransactionStatus; minAmount: number | null; maxAmount: number | null; } const ranges = new Set(['day', 'week', 'month', 'season']); const statuses = new Set(['all', 'Paid', 'Verified', 'Failed', 'Reversed']); const periodPatterns: Record = { day: /^d-\d{4}-\d{2}-\d{2}$/, week: /^w-\d{4}-\d{2}-\d{2}$/, month: /^jm-\d{4}-\d{2}$/, season: /^ps-\d{4}-(?:01|04|07|10)$/, }; function positiveAmount(value: string | null): number | null { if (!value) return null; const parsed = Number(value); return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : null; } export function parseDashboardFilters( query: URLSearchParams, terminalIds: readonly string[] = [], ): DashboardFilters { const rawRange = query.get('range') as DashboardRange | null; const range = rawRange && ranges.has(rawRange) ? rawRange : 'month'; const rawPeriod = query.get('period'); const rawStatus = query.get('status') as TransactionStatus | null; const rawTerminal = query.get('terminal'); let minAmount = positiveAmount(query.get('minAmount')); let maxAmount = positiveAmount(query.get('maxAmount')); if (minAmount !== null && maxAmount !== null && minAmount > maxAmount) { [minAmount, maxAmount] = [maxAmount, minAmount]; } return { range, period: rawPeriod && periodPatterns[range].test(rawPeriod) ? rawPeriod : '', terminal: rawTerminal && terminalIds.includes(rawTerminal) ? rawTerminal : 'all', status: rawStatus && statuses.has(rawStatus) ? rawStatus : 'all', minAmount, maxAmount, }; } export function setDashboardQuery( current: URL, updates: Partial>, ): URL { const next = new URL(current); for (const [key, value] of Object.entries(updates)) { if (value === null || value === '' || value === 'all') next.searchParams.delete(key); else next.searchParams.set(key, String(value)); } return next; } export const rangeLabels: Record = { day: 'روزانه', week: 'هفتگی', month: 'ماهانه', season: 'فصلی', }; export const rangePeriodTypes: Record = { day: 'DAY', week: 'WEEK', month: 'JALALI_MONTH', season: 'PERSIAN_SEASON', };