Connect all CRM pages to the BFF and CRM service, add module docs, and mark CRM available in the SuperApp catalog. Co-authored-by: Cursor <cursoragent@cursor.com>
66 lines
2.7 KiB
TypeScript
66 lines
2.7 KiB
TypeScript
"use client";
|
||
|
||
import { useQuery } from "@tanstack/react-query";
|
||
import { PageHeader, Card, CardContent } from "@/components/ds";
|
||
import { crmApi } from "@/modules/crm/services/crm-api";
|
||
import { useTenantId } from "@/hooks/useTenantId";
|
||
import { CrmStatGrid } from "@/modules/crm/design-system";
|
||
import { CrmBreadcrumbs } from "@/modules/crm/components/CrmBreadcrumbs";
|
||
import { CrmPageLoader, CrmPageError } from "@/modules/crm/pages/shared";
|
||
|
||
export default function ReportsPage() {
|
||
const { tenantId } = useTenantId();
|
||
const q = useQuery({
|
||
queryKey: ["crm", tenantId, "reports"],
|
||
queryFn: async () => {
|
||
const [leads, opps, quotes, forecasts] = await Promise.all([
|
||
crmApi.leads.list(tenantId!, { page: 1, page_size: 500 }),
|
||
crmApi.opportunities.list(tenantId!, { page: 1, page_size: 500 }),
|
||
crmApi.quotes.list(tenantId!, { page: 1, page_size: 500 }),
|
||
crmApi.forecasts.list(tenantId!, { page: 1, page_size: 50 }),
|
||
]);
|
||
const pipelineValue = opps
|
||
.filter((o) => o.status === "open")
|
||
.reduce((s, o) => s + Number(o.amount || 0), 0);
|
||
return {
|
||
leadCount: leads.length,
|
||
openDeals: opps.filter((o) => o.status === "open").length,
|
||
wonDeals: opps.filter((o) => o.status === "won").length,
|
||
pipelineValue,
|
||
quoteCount: quotes.length,
|
||
forecastCount: forecasts.length,
|
||
};
|
||
},
|
||
enabled: !!tenantId,
|
||
});
|
||
|
||
if (!tenantId || q.isLoading) return <CrmPageLoader />;
|
||
if (q.error) return <CrmPageError error={q.error} onRetry={() => q.refetch()} />;
|
||
|
||
return (
|
||
<div>
|
||
<CrmBreadcrumbs items={[{ label: "گزارشها" }]} />
|
||
<PageHeader
|
||
title="گزارشهای فروش"
|
||
description="گزارشهای محاسبهشده client-side از API lists — بدون reporting engine."
|
||
/>
|
||
<CrmStatGrid
|
||
stats={[
|
||
{ label: "سرنخها", value: q.data!.leadCount },
|
||
{ label: "معاملات باز", value: q.data!.openDeals },
|
||
{ label: "معاملات برنده", value: q.data!.wonDeals },
|
||
{ label: "ارزش pipeline", value: q.data!.pipelineValue.toLocaleString("fa-IR") },
|
||
{ label: "پیشفاکتور", value: q.data!.quoteCount },
|
||
{ label: "Forecast", value: q.data!.forecastCount },
|
||
]}
|
||
/>
|
||
<Card className="mt-6">
|
||
<CardContent className="pt-5 text-sm text-[var(--muted)]">
|
||
گزارشهای پیشرفته (PDF/scheduled) در Analytics Platform آینده — فعلاً فقط aggregate از list
|
||
endpoints.
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
);
|
||
}
|