source: frontend/src/components/userProfile/ArtistView.tsx@ 98992cf

main
Last change on this file since 98992cf was 98992cf, checked in by Dimitar Arsov <dimitararsov04@…>, 5 months ago

refactor NonAdminUser dtos

  • Property mode set to 100644
File size: 4.4 KB
Line 
1import { useNavigate } from "react-router-dom";
2import { Music, Disc3 } from "lucide-react";
3import type { ArtistContribution } from "../../utils/types";
4
5interface ArtistViewProps {
6 contributions: ArtistContribution[];
7}
8
9const ArtistView = ({ contributions }: ArtistViewProps) => {
10 const navigate = useNavigate();
11
12 const albums = contributions.filter((c) => c.entityType === "ALBUM");
13 const songs = contributions.filter((c) => c.entityType === "SONG");
14
15 const getRoleColor = (role: string) => {
16 const colors: { [key: string]: string } = {
17 COMPOSER: "bg-purple-500",
18 PERFORMER: "bg-blue-500",
19 PRODUCER: "bg-green-500",
20 MAIN_VOCAL: "bg-pink-500",
21 };
22 return colors[role] || "bg-gray-500";
23 };
24
25 return (
26 <div className="mt-8">
27 {albums.length > 0 && (
28 <div className="mb-12">
29 <div className="flex items-center gap-3 mb-6">
30 <Disc3 className="w-8 h-8 text-purple-600" />
31 <h2 className="text-3xl font-bold">Albums</h2>
32 </div>
33 <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
34 {albums.map((album, index) => (
35 <div
36 key={index}
37 className="group cursor-pointer"
38 onClick={() =>
39 navigate(`/musical-entity/${album.musicalEntityId}`)
40 }
41 >
42 <div className="relative aspect-square bg-linear-to-br from-purple-400 via-pink-400 to-blue-400 rounded-lg mb-3 overflow-hidden shadow-lg group-hover:shadow-2xl transition-all duration-300 group-hover:scale-105">
43 <div className="absolute inset-0 flex items-center justify-center">
44 <Disc3 className="w-20 h-20 text-white opacity-40" />
45 </div>
46 <div className="absolute bottom-0 left-0 right-0 bg-linear-to-t from-black/60 to-transparent p-4">
47 <span
48 className={`text-xs px-2 py-1 rounded-full text-white ${getRoleColor(album.role)}`}
49 >
50 {album.role.replace("_", " ")}
51 </span>
52 </div>
53 </div>
54 <h3 className="font-semibold text-base line-clamp-2 group-hover:text-blue-600 transition-colors">
55 {album.title}
56 </h3>
57 </div>
58 ))}
59 </div>
60 </div>
61 )}
62
63 {songs.length > 0 && (
64 <div className="mb-12">
65 <div className="flex items-center gap-3 mb-6">
66 <Music className="w-8 h-8 text-blue-600" />
67 <h2 className="text-3xl font-bold">Songs</h2>
68 </div>
69 <div className="space-y-2">
70 {songs.map((song, index) => (
71 <div
72 key={index}
73 className="group flex items-center gap-4 p-4 rounded-lg hover:bg-gray-50 transition-all cursor-pointer border border-transparent hover:border-gray-200"
74 onClick={() =>
75 navigate(`/musical-entity/${song.musicalEntityId}`)
76 }
77 >
78 <div className="shrink-0 w-14 h-14 bg-linear-to-br from-blue-400 to-cyan-400 rounded flex items-center justify-center group-hover:scale-110 transition-transform shadow-md">
79 <Music className="w-7 h-7 text-white" />
80 </div>
81 <div className="flex-1 min-w-0">
82 <h3 className="font-semibold text-lg group-hover:text-blue-600 transition-colors truncate">
83 {song.title}
84 </h3>
85 <div className="flex items-center gap-2 mt-1">
86 {song.genre}
87 </div>
88 </div>
89 <span
90 className={`px-4 py-2 rounded-full text-white text-sm font-medium ${getRoleColor(song.role)} shadow-md`}
91 >
92 {song.role.replace("_", " ")}
93 </span>
94 </div>
95 ))}
96 </div>
97 </div>
98 )}
99
100 {contributions.length === 0 && (
101 <div className="flex flex-col items-center justify-center py-16 text-gray-400">
102 <Music className="w-24 h-24 mb-4 opacity-20" />
103 <p className="text-xl font-medium">No contributions yet</p>
104 <p className="text-sm mt-2">Start creating music to see it here</p>
105 </div>
106 )}
107 </div>
108 );
109};
110
111export default ArtistView;
Note: See TracBrowser for help on using the repository browser.