Commit completed Torbat Pages admin frontend module, BFF proxy, routes, and validation artifacts for official platform deploy. Co-authored-by: Cursor <cursoragent@cursor.com>
100 lines
4.5 KiB
TypeScript
100 lines
4.5 KiB
TypeScript
"use client";
|
||
|
||
import { useState } from "react";
|
||
import { useQuery } 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 { ExperienceBreadcrumbs } from "@/modules/experience/components/ExperienceBreadcrumbs";
|
||
import { PageHeader, Card, CardContent, Badge, FormField, Select } from "@/components/ds";
|
||
|
||
/** Static catalog of published actions for display — bind flags via metadata_json when API allows. */
|
||
const PUBLISHED_ACTIONS_CATALOG = [
|
||
{ key: "view", label: "مشاهده", description: "دسترسی عمومی به محتوا" },
|
||
{ key: "share", label: "اشتراکگذاری", description: "لینک اشتراک" },
|
||
{ key: "embed", label: "جاسازی", description: "ویجت embed" },
|
||
{ key: "subscribe", label: "عضویت", description: "خبرنامه / follow" },
|
||
{ key: "form_submit", label: "ارسال فرم", description: "ثبت form submission" },
|
||
];
|
||
|
||
export const PublishedActionsPage = function ExperiencePublishedActions() {
|
||
const { tenantId } = useTenantId();
|
||
const [resourceType, setResourceType] = useState("page");
|
||
const [resourceId, setResourceId] = useState("");
|
||
const [flags, setFlags] = useState<Record<string, boolean>>({});
|
||
|
||
const pagesQ = useQuery({
|
||
queryKey: ["experience", tenantId, "pages-for-actions"],
|
||
queryFn: () => experienceApi.pages.list(tenantId!),
|
||
enabled: !!tenantId,
|
||
});
|
||
|
||
const resourceQ = useQuery({
|
||
queryKey: ["experience", tenantId, "resource-actions", resourceType, resourceId],
|
||
queryFn: async () => {
|
||
if (resourceType === "page") return experienceApi.pages.get(tenantId!, resourceId);
|
||
return experienceApi.sites.get(tenantId!, resourceId);
|
||
},
|
||
enabled: !!tenantId && !!resourceId,
|
||
});
|
||
|
||
if (!tenantId || pagesQ.isLoading) return <ExperiencePageLoader />;
|
||
if (pagesQ.error) return <ExperiencePageError error={pagesQ.error} onRetry={() => pagesQ.refetch()} />;
|
||
|
||
const meta = (resourceQ.data?.metadata_json ?? resourceQ.data?.content_shell ?? {}) as Record<string, unknown>;
|
||
const actionFlags = (meta.published_actions ?? {}) as Record<string, boolean>;
|
||
|
||
return (
|
||
<div className="space-y-6">
|
||
<ExperienceBreadcrumbs current="اکشنهای منتشر شده" />
|
||
<PageHeader title="اکشنهای منتشر شده" description="کاتالوگ نمایشی — enable flags در metadata_json (حداقلی)." />
|
||
<Card>
|
||
<CardContent className="flex flex-wrap gap-4 p-4">
|
||
<FormField label="نوع منبع">
|
||
<Select value={resourceType} onChange={(e) => setResourceType(e.target.value)}>
|
||
<option value="page">صفحه</option>
|
||
<option value="site">سایت</option>
|
||
</Select>
|
||
</FormField>
|
||
<FormField label="منبع">
|
||
<Select value={resourceId} onChange={(e) => setResourceId(e.target.value)}>
|
||
<option value="">انتخاب…</option>
|
||
{(pagesQ.data ?? []).map((p) => (
|
||
<option key={String(p.id)} value={String(p.id)}>{String(p.title ?? p.slug)}</option>
|
||
))}
|
||
</Select>
|
||
</FormField>
|
||
</CardContent>
|
||
</Card>
|
||
<div className="grid gap-3 sm:grid-cols-2">
|
||
{PUBLISHED_ACTIONS_CATALOG.map((a) => {
|
||
const enabled = flags[a.key] ?? actionFlags[a.key] ?? false;
|
||
return (
|
||
<Card key={a.key}>
|
||
<CardContent className="flex items-center justify-between p-4">
|
||
<div>
|
||
<p className="font-medium">{a.label}</p>
|
||
<p className="text-xs text-[var(--muted)]">{a.description}</p>
|
||
</div>
|
||
<input
|
||
type="checkbox"
|
||
checked={enabled}
|
||
onChange={(e) => {
|
||
setFlags((f) => ({ ...f, [a.key]: e.target.checked }));
|
||
toast.info("ذخیره metadata_json از طریق PATCH منبع — FE-11.5 حداقلی");
|
||
}}
|
||
className="h-4 w-4 accent-[var(--experience-accent)]"
|
||
/>
|
||
</CardContent>
|
||
</Card>
|
||
);
|
||
})}
|
||
</div>
|
||
{resourceId ? <Badge tone="info">publish_id موقت: {resourceId}</Badge> : null}
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default PublishedActionsPage;
|