"use client"; import { useState } from "react"; import { useForm } from "react-hook-form"; import { z } from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { toast } from "sonner"; import { Plus } from "lucide-react"; import { beautyBusinessApi, type Appointment } from "@/modules/beauty/services/beauty-business-api"; import { useTenantId } from "@/hooks/useTenantId"; import { PageHeader, Button, Dialog, Input, DataTable, EmptyState, LoadingState, ErrorState, Badge, FormField, Select, JalaliDateText, } from "@/components/ds"; const createSchema = z.object({ organization_id: z.string().min(1, "سازمان الزامی است"), branch_id: z.string().min(1, "شعبه الزامی است"), code: z.string().min(1, "کد الزامی است"), scheduled_start: z.string().min(1, "شروع الزامی است"), scheduled_end: z.string().min(1, "پایان الزامی است"), customer_ref: z.string().optional(), notes: z.string().optional(), }); export default function AppointmentsPage() { const { tenantId } = useTenantId(); const qc = useQueryClient(); const [createOpen, setCreateOpen] = useState(false); const orgsQ = useQuery({ queryKey: ["beauty", tenantId, "organizations"], queryFn: () => beautyBusinessApi.organizations.list(tenantId!), enabled: !!tenantId, }); const branchesQ = useQuery({ queryKey: ["beauty", tenantId, "branches"], queryFn: () => beautyBusinessApi.branches.list(tenantId!), enabled: !!tenantId, }); const listQ = useQuery({ queryKey: ["beauty", tenantId, "appointments"], queryFn: () => beautyBusinessApi.appointments.list(tenantId!), enabled: !!tenantId, }); const createForm = useForm>({ resolver: zodResolver(createSchema), defaultValues: { organization_id: "", branch_id: "", code: "", scheduled_start: "", scheduled_end: "", customer_ref: "", notes: "", }, }); const selectedOrg = createForm.watch("organization_id"); const filteredBranches = (branchesQ.data ?? []).filter( (b) => !selectedOrg || b.organization_id === selectedOrg ); const invalidate = () => qc.invalidateQueries({ queryKey: ["beauty", tenantId, "appointments"] }); const createM = useMutation({ mutationFn: (d: z.infer) => beautyBusinessApi.appointments.create(tenantId!, { ...d, scheduled_start: new Date(d.scheduled_start).toISOString(), scheduled_end: new Date(d.scheduled_end).toISOString(), customer_ref: d.customer_ref || undefined, notes: d.notes || undefined, }), onSuccess: async () => { toast.success("نوبت ایجاد شد"); setCreateOpen(false); createForm.reset(); await invalidate(); }, onError: (e: Error) => toast.error(e.message), }); const confirmM = useMutation({ mutationFn: (row: Appointment) => beautyBusinessApi.appointments.confirm(tenantId!, row.id, { version: row.version }), onSuccess: async () => { toast.success("نوبت تأیید شد"); await invalidate(); }, onError: (e: Error) => toast.error(e.message), }); if (!tenantId || listQ.isLoading) return ; if (listQ.error) { return listQ.refetch()} />; } return (
setCreateOpen(true)}> نوبت جدید } /> , }, { key: "status", header: "وضعیت", render: (r) => {String(r.status)}, }, { key: "actions", header: "عملیات", render: (r) => { const row = r as unknown as Appointment; if (row.status !== "requested") return null; return ( ); }, }, ]} rows={(listQ.data ?? []) as unknown as Record[]} empty={ setCreateOpen(true)}>ایجاد نوبت} />} /> setCreateOpen(false)} title="نوبت جدید">
createM.mutate(d))}>
); }