From ef054280bb0f95dc27aac775950c764eb0ed2332 Mon Sep 17 00:00:00 2001 From: AmirmahdiNourkazemi Date: Sat, 6 Jun 2026 17:22:21 +0330 Subject: [PATCH] feat: add image playlist --- app/dashboard/music/playlists/page.tsx | 42 ++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/app/dashboard/music/playlists/page.tsx b/app/dashboard/music/playlists/page.tsx index 40e3f35..4895659 100644 --- a/app/dashboard/music/playlists/page.tsx +++ b/app/dashboard/music/playlists/page.tsx @@ -15,12 +15,17 @@ import { PageHeader, } from "@/components/ui"; import { EditIcon, PlusIcon, TrashIcon } from "@/components/icons"; +import { ImagePicker } from "@/components/ImagePicker"; +import { MediaPreview } from "@/components/MediaPreview"; +import { pickUrl, IMAGE_KEYS } from "@/lib/media"; import { toFa } from "@/lib/utils"; interface Playlist { id: number; name?: string; description?: string; + image_id?: number | null; + image?: unknown; } interface MusicCategory { @@ -42,6 +47,8 @@ export default function MusicPlaylistsPage() { const [description, setDescription] = useState(""); const [categoryIds, setCategoryIds] = useState([]); const [subcategoryIds, setSubcategoryIds] = useState([]); + const [imageId, setImageId] = useState(null); + const [imageFile, setImageFile] = useState(null); const [deleting, setDeleting] = useState(null); const [removing, setRemoving] = useState(false); @@ -56,6 +63,8 @@ export default function MusicPlaylistsPage() { setDescription(""); setCategoryIds([]); setSubcategoryIds([]); + setImageId(null); + setImageFile(null); setOpen(true); } function openEdit(row: Playlist) { @@ -64,6 +73,8 @@ export default function MusicPlaylistsPage() { setDescription(row.description ?? ""); setCategoryIds([]); setSubcategoryIds([]); + setImageId(row.image_id ?? null); + setImageFile(null); setOpen(true); } @@ -72,10 +83,15 @@ export default function MusicPlaylistsPage() { setSaving(true); try { if (editing) { - // Update is JSON on /music-playlists/:id + // Update is multipart (POST) so an image file can be uploaded. await apiFetch(`/music-playlists/${editing.id}`, { - method: "PUT", - body: { name, description }, + method: "POST", + body: toFormData({ + name, + description, + image_id: imageId, + image: imageFile, + }), }); toast.success("پلی‌لیست ویرایش شد."); } else { @@ -87,6 +103,8 @@ export default function MusicPlaylistsPage() { description, category_ids: categoryIds, subcategory_ids: subcategoryIds, + image_id: imageId, + image: imageFile, }), }); toast.success("پلی‌لیست افزوده شد."); @@ -117,6 +135,14 @@ export default function MusicPlaylistsPage() { const columns: Column[] = [ { key: "id", header: "شناسه", render: (r) => toFa(r.id), className: "w-24" }, + { + key: "image", + header: "تصویر", + className: "w-20", + render: (r) => ( + + ), + }, { key: "name", header: "نام" }, { key: "description", @@ -199,6 +225,16 @@ export default function MusicPlaylistsPage() { /> + + + + {!editing && ( <>