import { useEffect, useState } from "react"; import { Link, useParams } from "react-router-dom"; import axiosInstance, { baseURL } from "../api/axiosInstance"; import SongItem from "../components/SongItem"; import { getErrorMessage } from "../utils/error"; import type { Album, Playlist, Song } from "../utils/types"; interface CollectionView { id: number; title: string; cover?: string | null; genre?: string; type: string; releasedBy: string; isLikedByCurrentUser?: boolean; songs: Song[]; } const MusicalCollection = () => { const { type, id } = useParams(); const [collection, setCollection] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [openDropdownSongId, setOpenDropdownSongId] = useState( null, ); const normalizeCollection = ( data: Album | Playlist, type: string, ): CollectionView => { if (type === "album") { const album = data as Album; return { id: album.id, title: album.title, cover: album.cover, genre: album.genre, type: album.type, releasedBy: album.releasedBy, isLikedByCurrentUser: album.isLikedByCurrentUser, songs: album.songs, }; } else { const playlist = data as Playlist; return { id: playlist.id, title: playlist.name, cover: playlist.cover, genre: undefined, type: "PLAYLIST", releasedBy: playlist.creatorName, isLikedByCurrentUser: undefined, songs: playlist.songsInPlaylist, }; } }; const toggleLike = async (songId: number) => { try { await axiosInstance.post(`/musical-entity/${songId}/like`); setCollection((prev) => { if (!prev) return null; return { ...prev, songs: prev.songs.map((s) => s.id === songId ? { ...s, isLikedByCurrentUser: !s.isLikedByCurrentUser } : s, ), }; }); } catch (err) { console.error("Error toggling like:", err); } }; const toggleCollectionLike = async () => { if (!collection) return; try { await axiosInstance.post(`/musical-entity/${collection.id}/like`); setCollection((prev) => { if (!prev) return null; return { ...prev, isLikedByCurrentUser: !prev.isLikedByCurrentUser }; }); } catch (err) { console.error("Error toggling collection like:", err); } }; useEffect(() => { const fetchData = async () => { setIsLoading(true); setError(null); try { const endpoint = type === "album" ? `/albums/${id}` : `/playlists/${id}`; const response = await axiosInstance.get(endpoint); const normalized = normalizeCollection(response.data, type!); setCollection(normalized); } catch (err: any) { setError(getErrorMessage(err)); } finally { setIsLoading(false); } }; fetchData(); }, [id, type]); if (isLoading) { return (

Loading collection…

); } if (error) { return (

{error}

← Back to Home
); } if (!collection) return null; return (
{/* Back link */} Back to Home {/* Hero section */}
{/* Cover art */}
{collection.title} { (e.target as HTMLImageElement).src = "/favicon.png"; }} />
{/* Collection info */}
{collection.genre ? `${collection.genre} • ` : ""} {collection.type === "PLAYLIST" ? "Playlist" : "Album"}

{collection.title}

{collection.releasedBy}

{collection.songs && (

{collection.songs.length} song {collection.songs.length !== 1 ? "s" : ""}

)} {/* Action buttons */}
{type === "album" && ( )}
{/* Songs list */}

Songs

{collection.songs && collection.songs.length > 0 ? (
{collection.songs.map((song, index) => ( toggleLike(song.id)} isDropdownOpen={openDropdownSongId === song.id} onDropdownToggle={setOpenDropdownSongId} /> ))}
) : (

No songs available

)}
); }; export default MusicalCollection;