Changeset 2730163 for frontend/src/pages/MusicalCollection.tsx
- Timestamp:
- 01/31/26 22:34:40 (5 months ago)
- Branches:
- main
- Children:
- d2af1a6
- Parents:
- 2b08bed
- File:
-
- 1 edited
-
frontend/src/pages/MusicalCollection.tsx (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
frontend/src/pages/MusicalCollection.tsx
r2b08bed r2730163 2 2 import { useNavigate, useParams } from "react-router-dom"; 3 3 import axiosInstance from "../api/axiosInstance"; 4 5 interface Song { 4 import type { Song, Album, Playlist } from "../utils/types"; 5 import { handleError } from "../utils/error"; 6 interface CollectionView { 6 7 id: number; 7 8 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; 18 10 type: string; 19 11 releasedBy: string; 20 12 isLikedByCurrentUser?: boolean; 21 songs ?: Song[];13 songs: Song[]; 22 14 } 23 15 … … 25 17 const { type, id } = useParams(); 26 18 const navigate = useNavigate(); 27 const [collection, setCollection] = useState< MusicalEntity| null>(null);19 const [collection, setCollection] = useState<CollectionView | null>(null); 28 20 const [isLoading, setIsLoading] = useState(true); 29 21 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 }; 30 51 31 52 useEffect(() => { … … 37 58 type === "album" ? `/albums/${id}` : `/playlists/${id}`; 38 59 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); 41 63 } catch (err: any) { 42 setError( err.response?.data?.error || "Failed to load collection");64 setError(handleError(err)); 43 65 } finally { 44 66 setIsLoading(false); … … 67 89 <button 68 90 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" 70 92 > 71 93 ← Back … … 88 110 <div className="flex items-center gap-3 text-gray-700 mb-4"> 89 111 <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 )} 92 118 {collection.songs && ( 93 119 <> … … 101 127 </div> 102 128 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"} 113 133 > 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 )} 120 150 </div> 121 151 </div>
Note:
See TracChangeset
for help on using the changeset viewer.
