TorbatYar/frontend/modules/crm/features/sales/tasks.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

76 lines
2.5 KiB
TypeScript

"use client";
import { z } from "zod";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { Check } from "lucide-react";
import { Button } from "@/components/ds";
import { crmApi } from "@/modules/crm/services/crm-api";
import { createCrmListPage } from "@/modules/crm/components/CrmListCrudPage";
import type { Task } from "@/modules/crm/types";
import { useTenantId } from "@/hooks/useTenantId";
const schema = z.object({
title: z.string().min(1),
description: z.string().optional(),
priority: z.enum(["low", "medium", "high", "urgent"]).default("medium"),
});
function TaskCompleteButton({ row }: { row: Task }) {
const { tenantId } = useTenantId();
const qc = useQueryClient();
const completeM = useMutation({
mutationFn: () => crmApi.tasks.complete(tenantId!, row.id),
onSuccess: async () => {
toast.success("وظیفه تکمیل شد");
await qc.invalidateQueries({ queryKey: ["crm", tenantId, "tasks"] });
},
onError: (e: Error) => toast.error(e.message),
});
if (row.status === "completed") return <span className="text-xs text-[var(--muted)]"></span>;
return (
<Button variant="ghost" size="icon" onClick={() => completeM.mutate()} aria-label="تکمیل">
<Check className="h-4 w-4" />
</Button>
);
}
export default createCrmListPage<Task>({
title: "وظایف",
description: "مدیریت task های فروش.",
breadcrumb: "وظایف",
resourceKey: "tasks",
createSchema: schema,
editSchema: schema.partial(),
createDefaults: { title: "", description: "", priority: "medium" },
fields: [
{ name: "title", label: "عنوان" },
{ name: "description", label: "توضیحات", type: "textarea" },
{
name: "priority",
label: "اولویت",
type: "select",
options: [
{ value: "low", label: "کم" },
{ value: "medium", label: "متوسط" },
{ value: "high", label: "بالا" },
{ value: "urgent", label: "فوری" },
],
},
],
columns: [
{ key: "title", header: "عنوان" },
{ key: "status", header: "وضعیت" },
{ key: "priority", header: "اولویت" },
{
key: "complete",
header: "تکمیل",
render: (r) => <TaskCompleteButton row={r} />,
},
],
list: (tid) => crmApi.tasks.list(tid, { page: 1, page_size: 500 }),
create: (tid, d) => crmApi.tasks.create(tid, d),
exportColumns: ["title", "status", "priority"],
});