"use client";
import { useQuery } from "@tanstack/react-query";
import {
PageHeader,
LoadingState,
ErrorState,
Badge,
Card,
CardContent,
EmptyState,
} from "@/components/ds";
import { crmApi, CrmApiError } from "@/modules/crm/services/crm-api";
import { useTenantId } from "@/hooks/useTenantId";
import { CrmStatGrid } from "@/modules/crm/design-system";
export function CrmPageLoader({ label = "در حال بارگذاری…" }: { label?: string }) {
return ;
}
export function CrmPageError({
error,
onRetry,
}: {
error: unknown;
onRetry?: () => void;
}) {
if (error instanceof CrmApiError && error.status === 403) {
return (
);
}
const message = error instanceof Error ? error.message : "خطا در دریافت دادهها";
return ;
}
export function useCrmHealth() {
return useQuery({
queryKey: ["crm", "health"],
queryFn: () => crmApi.health(),
});
}
export function CrmServiceBadge() {
const healthQ = useCrmHealth();
if (!healthQ.data) return null;
return (
CRM v{healthQ.data.version}
);
}
export function useCrmCounts(tenantId: string | null) {
return useQuery({
queryKey: ["crm", tenantId, "counts"],
queryFn: async () => {
const [leads, contacts, orgs, opps, activities, tasks, meetings, calls] =
await Promise.all([
crmApi.leads.list(tenantId!, { page: 1, page_size: 500 }),
crmApi.contacts.list(tenantId!, { page: 1, page_size: 500 }),
crmApi.organizations.list(tenantId!, { page: 1, page_size: 500 }),
crmApi.opportunities.list(tenantId!, { page: 1, page_size: 500 }),
crmApi.activities.list(tenantId!, { page: 1, page_size: 500 }),
crmApi.tasks.list(tenantId!, { page: 1, page_size: 500 }),
crmApi.meetings.list(tenantId!, { page: 1, page_size: 500 }),
crmApi.calls.list(tenantId!, { page: 1, page_size: 500 }),
]);
return {
leads: leads.length,
contacts: contacts.length,
organizations: orgs.length,
opportunities: opps.length,
activities: activities.length,
tasks: tasks.length,
meetings: meetings.length,
calls: calls.length,
openDeals: opps.filter((o) => o.status === "open").length,
wonDeals: opps.filter((o) => o.status === "won").length,
};
},
enabled: !!tenantId,
});
}
export function CrmCountsGrid({ tenantId }: { tenantId: string }) {
const q = useCrmCounts(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);
}