"use client"; import { useState } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { toast } from "sonner"; import { Plus, Pencil } from "lucide-react"; import { beautyBusinessApi } from "@/modules/beauty/services/beauty-business-api"; import { useTenantId } from "@/hooks/useTenantId"; import { useBeautyPermissions } from "@/modules/beauty/hooks/useBeautyPermissions"; import { PageHeader, Button, Dialog, Input, DataTable, EmptyState, LoadingState, ErrorState, FormField, Select, Card, CardContent, Badge, TableToolbar, Textarea, } from "@/components/ds"; import { PermissionDeniedState } from "@/src/shared/ui"; import { useDebouncedValue } from "@/src/shared/hooks"; export default function BeautySettingsPage() { const { tenantId } = useTenantId(); const qc = useQueryClient(); const { can, canManage } = useBeautyPermissions(); const [open, setOpen] = useState(false); const [editKey, setEditKey] = useState(null); const [search, setSearch] = useState(""); const debouncedSearch = useDebouncedValue(search); const [form, setForm] = useState({ organization_id: "", key: "", valueJson: "{}", description: "", }); const orgsQ = useQuery({ queryKey: ["beauty", tenantId, "organizations"], queryFn: () => beautyBusinessApi.organizations.list(tenantId!), enabled: !!tenantId, }); const settingsQ = useQuery({ queryKey: ["beauty", tenantId, "settings"], queryFn: () => beautyBusinessApi.settings.list(tenantId!), enabled: !!tenantId && can("beauty_business.settings.view"), }); const permissionsQ = useQuery({ queryKey: ["beauty", tenantId, "permissions-catalog"], queryFn: () => beautyBusinessApi.permissions.catalog(tenantId!), enabled: !!tenantId, }); const invalidate = () => qc.invalidateQueries({ queryKey: ["beauty", tenantId, "settings"] }); const upsertM = useMutation({ mutationFn: () => { let value: Record | undefined; try { value = form.valueJson ? (JSON.parse(form.valueJson) as Record) : undefined; } catch { throw new Error("JSON مقدار نامعتبر است"); } return beautyBusinessApi.settings.upsert(tenantId!, { organization_id: form.organization_id || undefined, key: form.key, value, description: form.description || undefined, }); }, onSuccess: async () => { toast.success("تنظیم ذخیره شد"); setOpen(false); setEditKey(null); setForm({ organization_id: "", key: "", valueJson: "{}", description: "" }); await invalidate(); }, onError: (e: Error) => toast.error(e.message), }); const manageAllowed = canManage("beauty_business.settings.view", "beauty_business.settings.manage"); if (!tenantId) return ; if (!can("beauty_business.settings.view")) return ; if (settingsQ.isLoading) return ; if (settingsQ.error) { return settingsQ.refetch()} />; } const rows = (settingsQ.data ?? []).filter((s) => { if (!debouncedSearch) return true; const q = debouncedSearch.toLowerCase(); return s.key.toLowerCase().includes(q) || (s.description ?? "").toLowerCase().includes(q); }); const openEdit = (row: (typeof rows)[0]) => { setEditKey(row.key); setForm({ organization_id: row.organization_id ?? "", key: row.key, valueJson: row.value ? JSON.stringify(row.value, null, 2) : "{}", description: row.description ?? "", }); setOpen(true); }; return (
{ setEditKey(null); setForm({ organization_id: "", key: "", valueJson: "{}", description: "" }); setOpen(true); }} > تنظیم جدید ) : null } /> ( {r.value ? JSON.stringify(r.value).slice(0, 80) : "—"} ), }, { key: "actions", header: "عملیات", render: (r) => manageAllowed ? ( ) : null, }, ]} rows={rows as unknown as Record[]} empty={ setOpen(true)}>افزودن تنظیم ) : undefined } /> } /> {permissionsQ.data ? (

کاتالوگ مجوزها

{permissionsQ.data.count} مجوز ثبت‌شده

پیشوند: {permissionsQ.data.prefix}

) : null} { setOpen(false); setEditKey(null); }} title={editKey ? "ویرایش تنظیم" : "تنظیم جدید"} size="lg" >
setForm((f) => ({ ...f, key: e.target.value }))} disabled={!!editKey} required />