Ignore:
Timestamp:
01/31/26 22:34:40 (5 months ago)
Author:
Dimitar Arsov <dimitararsov04@…>
Branches:
main
Children:
d2af1a6
Parents:
2b08bed
Message:

show songs in playlists/albums

File:
1 edited

Legend:

Unmodified
Added
Removed
  • frontend/src/pages/MusicalCollection.tsx

    r2b08bed r2730163  
    22import { useNavigate, useParams } from "react-router-dom";
    33import axiosInstance from "../api/axiosInstance";
    4 
    5 interface Song {
     4import type { Song, Album, Playlist } from "../utils/types";
     5import { handleError } from "../utils/error";
     6interface CollectionView {
    67  id: number;
    78  title: string;
    8   genre: string;
    9   type: "SONG";
    10   releasedBy: string;
    11   isLikedByCurrentUser?: boolean;
    12 }
    13 
    14 interface MusicalEntity {
    15   id: number;
    16   title: string;
    17   genre: string;
     9  genre?: string;
    1810  type: string;
    1911  releasedBy: string;
    2012  isLikedByCurrentUser?: boolean;
    21   songs?: Song[];
     13  songs: Song[];
    2214}
    2315
     
    2517  const { type, id } = useParams();
    2618  const navigate = useNavigate();
    27   const [collection, setCollection] = useState<MusicalEntity | null>(null);
     19  const [collection, setCollection] = useState<CollectionView | null>(null);
    2820  const [isLoading, setIsLoading] = useState(true);
    2921  const [error, setError] = useState<string | null>(null);
     22
     23  const normalizeCollection = (
     24    data: Album | Playlist,
     25    type: string,
     26  ): CollectionView => {
     27    if (type === "album") {
     28      const album = data as Album;
     29      return {
     30        id: album.id,
     31        title: album.title,
     32        genre: album.genre,
     33        type: album.type,
     34        releasedBy: album.releasedBy,
     35        isLikedByCurrentUser: album.isLikedByCurrentUser,
     36        songs: album.songs,
     37      };
     38    } else {
     39      const playlist = data as Playlist;
     40      return {
     41        id: playlist.id,
     42        title: playlist.name,
     43        genre: undefined,
     44        type: "PLAYLIST",
     45        releasedBy: playlist.creatorName,
     46        isLikedByCurrentUser: undefined,
     47        songs: playlist.songsInPlaylist,
     48      };
     49    }
     50  };
    3051
    3152  useEffect(() => {
     
    3758          type === "album" ? `/albums/${id}` : `/playlists/${id}`;
    3859        const response = await axiosInstance.get(endpoint);
    39         console.log(response.data);
    40         setCollection(response.data);
     60
     61        const normalized = normalizeCollection(response.data, type!);
     62        setCollection(normalized);
    4163      } catch (err: any) {
    42         setError(err.response?.data?.error || "Failed to load collection");
     64        setError(handleError(err));
    4365      } finally {
    4466        setIsLoading(false);
     
    6789      <button
    6890        onClick={() => navigate(-1)}
    69         className="mb-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors duration-200"
     91        className="mb-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors duration-200 cursor-pointer"
    7092      >
    7193        ← Back
     
    88110            <div className="flex items-center gap-3 text-gray-700 mb-4">
    89111              <span className="font-semibold">{collection.releasedBy}</span>
    90               <span>•</span>
    91               <span className="text-gray-600">{collection.genre}</span>
     112              {collection.genre && (
     113                <>
     114                  <span>•</span>
     115                  <span className="text-gray-600">{collection.genre}</span>
     116                </>
     117              )}
    92118              {collection.songs && (
    93119                <>
     
    101127            </div>
    102128
    103             <button
    104               className="flex items-center gap-2 px-4 py-2 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors duration-200"
    105               aria-label={collection.isLikedByCurrentUser ? "Unlike" : "Like"}
    106             >
    107               <svg
    108                 className="w-5 h-5"
    109                 fill={collection.isLikedByCurrentUser ? "#ef4444" : "none"}
    110                 stroke={collection.isLikedByCurrentUser ? "#ef4444" : "#6b7280"}
    111                 strokeWidth="2"
    112                 viewBox="0 0 24 24"
     129            {type === "album" && (
     130              <button
     131                className="flex items-center gap-2 px-4 py-2 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors duration-200"
     132                aria-label={collection.isLikedByCurrentUser ? "Unlike" : "Like"}
    113133              >
    114                 <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" />
    115               </svg>
    116               <span className="text-sm font-medium text-gray-700">
    117                 {collection.isLikedByCurrentUser ? "Liked" : "Like"}
    118               </span>
    119             </button>
     134                <svg
     135                  className="w-5 h-5"
     136                  fill={collection.isLikedByCurrentUser ? "#ef4444" : "none"}
     137                  stroke={
     138                    collection.isLikedByCurrentUser ? "#ef4444" : "#6b7280"
     139                  }
     140                  strokeWidth="2"
     141                  viewBox="0 0 24 24"
     142                >
     143                  <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" />
     144                </svg>
     145                <span className="text-sm font-medium text-gray-700">
     146                  {collection.isLikedByCurrentUser ? "Liked" : "Like"}
     147                </span>
     148              </button>
     149            )}
    120150          </div>
    121151        </div>
Note: See TracChangeset for help on using the changeset viewer.