TorbatYar/frontend/modules/crm/features/sales/leads.tsx
Mortezakoohjani e140908034 Ship enterprise CRM frontend with real API wiring and thin app routes.
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>
2026-07-26 20:58:17 +03:30

96 lines
3.4 KiB
TypeScript

import { z } from "zod";
import { crmApi } from "@/modules/crm/services/crm-api";
import { createCrmListPage } from "@/modules/crm/components/CrmListCrudPage";
import { CrmStatusChip } from "@/modules/crm/design-system";
import type { Lead } from "@/modules/crm/types";
const createSchema = z.object({
first_name: z.string().min(1, "نام الزامی است"),
last_name: z.string().default(""),
email: z.string().email("ایمیل نامعتبر").optional().or(z.literal("")),
mobile: z.string().optional(),
company: z.string().optional(),
priority: z.enum(["low", "medium", "high", "urgent"]).default("medium"),
status: z.enum(["new", "contacted", "qualified", "unqualified", "converted", "lost"]).default("new"),
description: z.string().optional(),
});
const editSchema = createSchema.partial().extend({
first_name: z.string().min(1).optional(),
});
export default createCrmListPage<Lead>({
title: "سرنخ‌ها",
description: "مدیریت سرنخ‌های فروش — ایجاد، تخصیص، حذف و بازیابی.",
breadcrumb: "سرنخ‌ها",
resourceKey: "leads",
createSchema,
editSchema,
createDefaults: {
first_name: "",
last_name: "",
email: "",
mobile: "",
company: "",
priority: "medium",
status: "new",
description: "",
},
fields: [
{ name: "first_name", label: "نام", required: true },
{ name: "last_name", label: "نام خانوادگی" },
{ name: "email", label: "ایمیل", type: "email" },
{ name: "mobile", label: "موبایل", type: "tel" },
{ name: "company", label: "شرکت" },
{
name: "priority",
label: "اولویت",
type: "select",
options: [
{ value: "low", label: "کم" },
{ value: "medium", label: "متوسط" },
{ value: "high", label: "بالا" },
{ value: "urgent", label: "فوری" },
],
},
{
name: "status",
label: "وضعیت",
type: "select",
editOnly: true,
options: [
{ value: "new", label: "جدید" },
{ value: "contacted", label: "تماس" },
{ value: "qualified", label: "واجد شرایط" },
{ value: "unqualified", label: "نامناسب" },
{ value: "converted", label: "تبدیل" },
{ value: "lost", label: "از دست رفته" },
],
},
{ name: "description", label: "توضیحات", type: "textarea" },
],
columns: [
{ key: "lead_number", header: "شماره" },
{ key: "full_name", header: "نام" },
{ key: "company", header: "شرکت" },
{ key: "email", header: "ایمیل" },
{ key: "mobile", header: "موبایل" },
{
key: "status",
header: "وضعیت",
render: (r) => <CrmStatusChip status={r.status} domain="lead" />,
},
{
key: "priority",
header: "اولویت",
render: (r) => <CrmStatusChip status={r.priority} domain="priority" />,
},
],
list: (tid) => crmApi.leads.list(tid, { page: 1, page_size: 500 }),
create: (tid, d) => crmApi.leads.create(tid, d),
update: (tid, id, d) => crmApi.leads.update(tid, id, d),
remove: (tid, id) => crmApi.leads.delete(tid, id),
restore: (tid, id) => crmApi.leads.restore(tid, id),
exportColumns: ["lead_number", "full_name", "email", "mobile", "company", "status", "priority"],
});