"use client"; import { ChangeEvent, FormEvent, useCallback, useEffect, useRef, useState } from "react"; import ClothesShell from "@/components/clothes/ClothesShell"; import IconButton, { EditIcon, TrashIcon, } from "@/components/ui/IconButton"; import ImageCropper from "@/components/ui/ImageCropper"; import { FormModal } from "@/components/ui/Modal"; import type { Brand } from "@/data/clothes"; import { ApiError, uploadMedia } from "@/lib/api"; import { createBrand, deleteBrand, fetchBrands, updateBrand, } from "@/lib/clothes-api"; import { useConfirm } from "@/components/ui/ConfirmDialog"; type AspectRatio = "1:1" | "3:2"; const DEFAULT_IMAGE = "/images/ola-szkolda-J61EvbE1UCE-unsplash.jpg"; export default function BrandsPage() { const confirmDialog = useConfirm(); const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [saving, setSaving] = useState(false); const [modalOpen, setModalOpen] = useState(false); const [editingId, setEditingId] = useState(null); const [nameFa, setNameFa] = useState(""); const [nameEn, setNameEn] = useState(""); const [aspect, setAspect] = useState("1:1"); const [imagePreview, setImagePreview] = useState(DEFAULT_IMAGE); const [imageFile, setImageFile] = useState(null); const fileInputRef = useRef(null); const reload = useCallback(async () => { setLoading(true); setError(null); try { setItems(await fetchBrands()); } catch (err) { setError( err instanceof ApiError ? err.message : "بارگذاری برندها ناموفق بود.", ); } finally { setLoading(false); } }, []); useEffect(() => { void reload(); }, [reload]); function resetForm() { setEditingId(null); setNameFa(""); setNameEn(""); setAspect("1:1"); setImagePreview(DEFAULT_IMAGE); setImageFile(null); if (fileInputRef.current) fileInputRef.current.value = ""; } function closeModal() { setModalOpen(false); resetForm(); } function openCreate() { resetForm(); setModalOpen(true); } function openEdit(brand: Brand) { setEditingId(brand.id); setNameFa(brand.nameFa); setNameEn(brand.nameEn); setImagePreview(brand.image || DEFAULT_IMAGE); setImageFile(null); setModalOpen(true); } function handleImageChange(event: ChangeEvent) { const file = event.target.files?.[0]; if (!file) return; setImageFile(file); setImagePreview(URL.createObjectURL(file)); } async function handleSubmit(event: FormEvent) { event.preventDefault(); if (!nameFa.trim()) return; setSaving(true); setError(null); try { let imageUrl: string | undefined; let imageKey: string | undefined; if (imageFile) { const uploaded = await uploadMedia(imageFile, "brand"); imageUrl = uploaded.url; imageKey = uploaded.storageKey; } if (editingId) { await updateBrand(editingId, { nameFa: nameFa.trim(), nameEn: nameEn.trim() || undefined, ...(imageUrl ? { imageUrl, imageKey } : {}), }); } else { await createBrand({ nameFa: nameFa.trim(), nameEn: nameEn.trim() || undefined, imageUrl, imageKey, }); } await reload(); closeModal(); } catch (err) { setError( err instanceof ApiError ? err.message : "ذخیره برند ناموفق بود.", ); } finally { setSaving(false); } } async function handleDelete(id: string) { if (!(await confirmDialog("این برند حذف شود؟"))) return; setError(null); try { await deleteBrand(id); setItems((prev) => prev.filter((item) => item.id !== id)); } catch (err) { setError( err instanceof ApiError ? err.message : "حذف برند ناموفق بود.", ); } } return ( <> {error ? (

{error}

) : null} {loading ? (

در حال بارگذاری...

) : (
{items.length === 0 ? (

هنوز برندی ثبت نشده است.

) : null} {items.map((brand, i) => (
{/* eslint-disable-next-line @next/next/no-img-element */} {brand.nameFa}

{brand.nameFa}

{brand.nameEn}

openEdit(brand)} > void handleDelete(brand.id)} >
))}
)}
نسبت برش
تصویر برند
setNameFa(e.target.value)} placeholder="مثلاً مانا" required />
setNameEn(e.target.value)} placeholder="Mana" />
); }