"use client"; import { useQuery } from "@tanstack/react-query"; import { LoadingState, ErrorState, Badge, EmptyState, } from "@/components/ds"; import { loyaltyApi, LoyaltyApiError } from "@/modules/loyalty/services/loyalty-api"; import { useTenantId } from "@/hooks/useTenantId"; import { LoyaltyStatGrid } from "@/modules/loyalty/design-system"; export function LoyaltyPageLoader({ label = "در حال بارگذاری…" }: { label?: string }) { return ; } export function LoyaltyPageError({ error, onRetry, }: { error: unknown; onRetry?: () => void; }) { if (error instanceof LoyaltyApiError && error.status === 403) { return ( ); } const message = error instanceof Error ? error.message : "خطا در دریافت داده‌ها"; return ; } export function useLoyaltyHealth() { return useQuery({ queryKey: ["loyalty", "health"], queryFn: () => loyaltyApi.health(), }); } export function LoyaltyServiceBadge() { const healthQ = useLoyaltyHealth(); if (!healthQ.data) return null; return ( Loyalty v{healthQ.data.version} ); } export function useLoyaltyCounts(tenantId: string | null) { return useQuery({ queryKey: ["loyalty", tenantId, "counts"], queryFn: async () => { const [programs, members, tiers, rewards, campaigns, wallets, pointAccounts] = await Promise.all([ loyaltyApi.programs.list(tenantId!, { page: 1, page_size: 500 }), loyaltyApi.members.list(tenantId!, { page: 1, page_size: 500 }), loyaltyApi.tiers.list(tenantId!, { page: 1, page_size: 500 }), loyaltyApi.rewards.list(tenantId!, { page: 1, page_size: 500 }), loyaltyApi.campaigns.list(tenantId!, { page: 1, page_size: 500 }), loyaltyApi.wallets.list(tenantId!, { page: 1, page_size: 500 }), loyaltyApi.pointAccounts.list(tenantId!, { page: 1, page_size: 500 }), ]); return { programs: programs.length, members: members.length, activeMembers: members.filter((m) => m.status === "active").length, tiers: tiers.length, rewards: rewards.length, campaigns: campaigns.length, activeCampaigns: campaigns.filter((c) => c.status === "active").length, wallets: wallets.length, pointAccounts: pointAccounts.length, }; }, enabled: !!tenantId, }); } export function LoyaltyCountsGrid({ tenantId }: { tenantId: string }) { const q = useLoyaltyCounts(tenantId); if (q.isLoading) return ; if (q.error) return q.refetch()} />; const c = q.data!; return ( ); } export function exportToCsv(filename: string, rows: Record[], columns: string[]) { const header = columns.join(","); const lines = rows.map((r) => columns.map((c) => JSON.stringify(r[c] ?? "")).join(",")); const blob = new Blob(["\uFEFF" + [header, ...lines].join("\n")], { type: "text/csv;charset=utf-8;", }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = filename; a.click(); URL.revokeObjectURL(url); }