"use client"; import { useState } from "react"; import { apiFetch, ApiError, toFormData } from "@/lib/api"; import { useList } from "@/lib/useResource"; import { useToast } from "@/components/toast"; import { DataTable, type Column } from "@/components/DataTable"; import { Button, ConfirmDialog, Field, Input, Textarea, Select, Modal, PageHeader, Badge, } from "@/components/ui"; import { EditIcon, PlusIcon, TrashIcon } from "@/components/icons"; import { MediaPreview } from "@/components/MediaPreview"; import { pickUrl, IMAGE_KEYS } from "@/lib/media"; interface ImageItem { id: number; title?: string; type?: string; description?: string; url?: string; image?: string; path?: string; } type ImageType = "public" | "private"; const typeLabels: Record = { public: "عمومی", private: "خصوصی", }; export default function ImagesPage() { const { data, loading, error, reload } = useList("/images/all"); const toast = useToast(); const [editing, setEditing] = useState(null); const [open, setOpen] = useState(false); const [title, setTitle] = useState(""); const [type, setType] = useState("public"); const [description, setDescription] = useState(""); const [file, setFile] = useState(null); const [saving, setSaving] = useState(false); const [deleting, setDeleting] = useState(null); const [removing, setRemoving] = useState(false); function openCreate() { setEditing(null); setTitle(""); setType("public"); setDescription(""); setFile(null); setOpen(true); } function openEdit(row: ImageItem) { setEditing(row); setTitle(row.title ?? ""); setType(row.type === "private" ? "private" : "public"); setDescription(row.description ?? ""); setFile(null); setOpen(true); } async function save(e: React.FormEvent) { e.preventDefault(); setSaving(true); try { if (editing) { // Update is JSON on /images/:id await apiFetch(`/images/${editing.id}`, { method: "PUT", body: { title, description, type }, }); toast.success("تصویر ویرایش شد."); } else { // Create is multipart on /images await apiFetch("/images", { method: "POST", body: toFormData({ image: file, title, type, description }), }); toast.success("تصویر افزوده شد."); } setOpen(false); reload(); } catch (err) { toast.error(err instanceof ApiError ? err.message : "خطا در ذخیره‌سازی"); } finally { setSaving(false); } } async function confirmDelete() { if (!deleting) return; setRemoving(true); try { await apiFetch(`/images/${deleting.id}`, { method: "DELETE" }); toast.success("تصویر حذف شد."); setDeleting(null); reload(); } catch (err) { toast.error(err instanceof ApiError ? err.message : "خطا در حذف"); } finally { setRemoving(false); } } const columns: Column[] = [ { key: "preview", header: "پیش‌نمایش", className: "w-20", render: (r) => ( ), }, { key: "title", header: "عنوان", render: (r) => r.title ?? "—" }, { key: "type", header: "نوع", render: (r) => r.type ? ( {typeLabels[r.type] ?? r.type} ) : ( ), }, { key: "description", header: "توضیحات", render: (r) => r.description ?? "—", }, ]; return (
} onClick={openCreate}> تصویر جدید } /> } onClick={openCreate}> تصویر جدید } actions={(row) => ( <> )} /> setOpen(false)} title={editing ? "ویرایش تصویر" : "تصویر جدید"} footer={ <> } >
{!editing && ( setFile(e.target.files?.[0] ?? null)} required /> )} setTitle(e.target.value)} placeholder="مثلاً پس‌زمینه آرامش" autoFocus />