"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);
}