"use client";
import { useQuery } from "@tanstack/react-query";
import { PageHeader } from "@/components/ds";
import { useTenantId } from "@/hooks/useTenantId";
import {
CrmCountsGrid,
CrmPageLoader,
CrmPageError,
CrmServiceBadge,
useCrmCounts,
} from "@/modules/crm/pages/shared";
import { CrmBreadcrumbs } from "@/modules/crm/components/CrmBreadcrumbs";
import { CrmStatGrid } from "@/modules/crm/design-system";
import { crmApi } from "@/modules/crm/services/crm-api";
function DashboardShell({
title,
description,
children,
}: {
title: string;
description: string;
children: React.ReactNode;
}) {
return (
);
}
export function OverviewDashboard() {
const { tenantId } = useTenantId();
if (!tenantId) return ;
return (
);
}
export function SalesDashboard() {
const { tenantId } = useTenantId();
const q = useCrmCounts(tenantId);
const goalsQ = useQuery({
queryKey: ["crm", tenantId, "goals"],
queryFn: () => crmApi.goals.list(tenantId!, { page: 1, page_size: 50 }),
enabled: !!tenantId,
});
const targetsQ = useQuery({
queryKey: ["crm", tenantId, "targets"],
queryFn: () => crmApi.targets.list(tenantId!, { page: 1, page_size: 50 }),
enabled: !!tenantId,
});
if (!tenantId || q.isLoading) return ;
if (q.error) return q.refetch()} />;
return (
);
}
export function PipelineDashboard() {
const { tenantId } = useTenantId();
const pipelinesQ = useQuery({
queryKey: ["crm", tenantId, "pipelines"],
queryFn: () => crmApi.pipelines.list(tenantId!, { page: 1, page_size: 100 }),
enabled: !!tenantId,
});
const oppsQ = useQuery({
queryKey: ["crm", tenantId, "opportunities"],
queryFn: () => crmApi.opportunities.list(tenantId!, { page: 1, page_size: 500 }),
enabled: !!tenantId,
});
if (!tenantId || pipelinesQ.isLoading || oppsQ.isLoading) return ;
if (pipelinesQ.error) return pipelinesQ.refetch()} />;
const opps = oppsQ.data ?? [];
const byPipeline = (pipelinesQ.data ?? []).map((p) => ({
label: p.name,
value: opps.filter((o) => o.pipeline_id === p.id).length,
}));
return (
);
}
export function LeadDashboard() {
const { tenantId } = useTenantId();
const q = useQuery({
queryKey: ["crm", tenantId, "leads"],
queryFn: () => crmApi.leads.list(tenantId!, { page: 1, page_size: 500 }),
enabled: !!tenantId,
});
if (!tenantId || q.isLoading) return ;
if (q.error) return q.refetch()} />;
const leads = q.data ?? [];
const byStatus = ["new", "contacted", "qualified", "converted", "lost"].map((s) => ({
label: s,
value: leads.filter((l) => l.status === s && !l.is_deleted).length,
}));
return (
);
}
export function ActivityDashboard() {
const { tenantId } = useTenantId();
const q = useQuery({
queryKey: ["crm", tenantId, "activity-dash"],
queryFn: async () => {
const [activities, tasks, meetings] = await Promise.all([
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 }),
]);
return { activities, tasks, meetings };
},
enabled: !!tenantId,
});
if (!tenantId || q.isLoading) return ;
if (q.error) return q.refetch()} />;
return (
a.status === "completed").length,
},
]}
/>
);
}
export function CalendarDashboard() {
const { tenantId } = useTenantId();
const q = useQuery({
queryKey: ["crm", tenantId, "meetings"],
queryFn: () => crmApi.meetings.list(tenantId!, { page: 1, page_size: 500 }),
enabled: !!tenantId,
});
if (!tenantId || q.isLoading) return ;
if (q.error) return q.refetch()} />;
const upcoming = (q.data ?? [])
.filter((m) => new Date(m.starts_at) >= new Date())
.slice(0, 10);
return (
{upcoming.map((m) => (
{m.subject}
{new Date(m.starts_at).toLocaleString("fa-IR")}
{m.location ? ` — ${m.location}` : ""}
))}
{upcoming.length === 0 ? (
جلسه آیندهای ثبت نشده.
) : null}
);
}