feat: add playlist

This commit is contained in:
2026-06-11 12:00:39 +03:30
parent 7c6d16693c
commit e374829358
+44 -5
View File
@@ -20,6 +20,14 @@ import { MediaPreview } from "@/components/MediaPreview";
import { ImagePicker } from "@/components/ImagePicker";
import { pickUrl, SOUND_KEYS, IMAGE_KEYS } from "@/lib/media";
interface Playlist {
id: number;
name?: string;
// Some endpoints nest the playlist's sub-categories; key casing varies.
subcategories?: Playlist[];
subCategories?: Playlist[];
}
interface Track {
id: number;
title?: string;
@@ -28,11 +36,12 @@ interface Track {
type?: string;
playlist_id?: number;
image_id?: number | null;
}
interface Playlist {
id: number;
name?: string;
// A track belongs to many playlists; the /music row embeds them as an array.
playlists?: Playlist[];
// Sub-categories may also be embedded directly on the track (key casing varies).
subcategories?: Playlist[];
subCategories?: Playlist[];
sub_categories?: Playlist[];
}
export default function MusicTracksPage() {
@@ -56,6 +65,26 @@ export default function MusicTracksPage() {
const [deleting, setDeleting] = useState<Track | null>(null);
const [removing, setRemoving] = useState(false);
// A track belongs to many playlists — list their names.
function playlistName(r: Track): string {
const names = (r.playlists ?? []).map((p) => p.name).filter(Boolean);
return names.length ? (names as string[]).join("، ") : "—";
}
// Sub-categories may sit on the track directly or come through its playlists;
// key casing varies between endpoints, so gather from every shape.
function subCategoryNames(r: Track): string {
const subs: Playlist[] = [
...(r.subcategories ?? r.subCategories ?? r.sub_categories ?? []),
...(r.playlists ?? []).flatMap(
(p) => p.subcategories ?? p.subCategories ?? [],
),
];
const names = subs.map((s) => s.name).filter(Boolean) as string[];
const unique = Array.from(new Set(names));
return unique.length ? unique.join("، ") : "—";
}
function resetForm() {
setTitle("");
setArtist("");
@@ -163,6 +192,16 @@ export default function MusicTracksPage() {
},
{ key: "title", header: "عنوان" },
{ key: "artist", header: "هنرمند", render: (r) => r.artist ?? "—" },
{
key: "playlist",
header: "پلی‌لیست",
render: (r) => playlistName(r),
},
{
key: "subcategory",
header: "زیر‌دسته",
render: (r) => subCategoryNames(r),
},
{
key: "duration",
header: "مدت زمان",