Commit completed Torbat Pages admin frontend module, BFF proxy, routes, and validation artifacts for official platform deploy. Co-authored-by: Cursor <cursoragent@cursor.com>
68 lines
2.8 KiB
TypeScript
68 lines
2.8 KiB
TypeScript
"use client";
|
||
|
||
import { useState } from "react";
|
||
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||
import { toast } from "sonner";
|
||
import { useTenantId } from "@/hooks/useTenantId";
|
||
import { experienceApi } from "@/modules/experience/services/experience-api";
|
||
import { ExperiencePageLoader, ExperiencePageError } from "@/modules/experience/pages/shared";
|
||
import { PageHeader, Card, CardContent, Button, Input, FormField } from "@/components/ds";
|
||
import { ExperienceBreadcrumbs } from "@/modules/experience/components/ExperienceBreadcrumbs";
|
||
import { useExperienceWorkspace } from "@/modules/experience/hooks/useExperienceWorkspace";
|
||
|
||
export const SettingsPage = function ExperienceSettingsPage() {
|
||
const { tenantId } = useTenantId();
|
||
const qc = useQueryClient();
|
||
const { workspaceId } = useExperienceWorkspace();
|
||
const [key, setKey] = useState("");
|
||
const [value, setValue] = useState("{}");
|
||
|
||
const listQ = useQuery({
|
||
queryKey: ["experience", tenantId, "settings"],
|
||
queryFn: () => experienceApi.settings.list(tenantId!),
|
||
enabled: !!tenantId,
|
||
});
|
||
|
||
const saveM = useMutation({
|
||
mutationFn: () =>
|
||
experienceApi.settings.upsert(tenantId!, {
|
||
workspace_id: workspaceId || null,
|
||
setting_key: key,
|
||
setting_value: JSON.parse(value || "{}"),
|
||
}),
|
||
onSuccess: () => {
|
||
toast.success("تنظیمات ذخیره شد");
|
||
qc.invalidateQueries({ queryKey: ["experience", tenantId, "settings"] });
|
||
},
|
||
onError: (e: Error) => toast.error(e.message),
|
||
});
|
||
|
||
if (!tenantId || listQ.isLoading) return <ExperiencePageLoader />;
|
||
if (listQ.error) return <ExperiencePageError error={listQ.error} onRetry={() => listQ.refetch()} />;
|
||
|
||
return (
|
||
<div className="space-y-6">
|
||
<ExperienceBreadcrumbs current="تنظیمات" />
|
||
<PageHeader title="تنظیمات" description="کلید-مقدار tenant-scoped." />
|
||
<Card>
|
||
<CardContent className="space-y-4 p-4">
|
||
<FormField label="کلید"><Input value={key} onChange={(e) => setKey(e.target.value)} /></FormField>
|
||
<FormField label="مقدار (JSON)"><Input value={value} onChange={(e) => setValue(e.target.value)} /></FormField>
|
||
<Button onClick={() => saveM.mutate()} loading={saveM.isPending}>ذخیره</Button>
|
||
</CardContent>
|
||
</Card>
|
||
<div className="grid gap-2">
|
||
{(listQ.data ?? []).map((s) => (
|
||
<Card key={String(s.id ?? s.setting_key)}>
|
||
<CardContent className="p-3 text-sm">
|
||
<strong>{String(s.setting_key ?? s.key)}</strong>
|
||
<pre className="mt-1 overflow-x-auto text-xs">{JSON.stringify(s.setting_value ?? s.value, null, 2)}</pre>
|
||
</CardContent>
|
||
</Card>
|
||
))}
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
export default SettingsPage;
|