Index: frontend/src/pages/MusicalCollection.tsx
===================================================================
--- frontend/src/pages/MusicalCollection.tsx	(revision 2b08bed6a1ac91c0de26078bed3ee44d43611bd4)
+++ frontend/src/pages/MusicalCollection.tsx	(revision 2b08bed6a1ac91c0de26078bed3ee44d43611bd4)
@@ -0,0 +1,176 @@
+import { useEffect, useState } from "react";
+import { useNavigate, useParams } from "react-router-dom";
+import axiosInstance from "../api/axiosInstance";
+
+interface Song {
+  id: number;
+  title: string;
+  genre: string;
+  type: "SONG";
+  releasedBy: string;
+  isLikedByCurrentUser?: boolean;
+}
+
+interface MusicalEntity {
+  id: number;
+  title: string;
+  genre: string;
+  type: string;
+  releasedBy: string;
+  isLikedByCurrentUser?: boolean;
+  songs?: Song[];
+}
+
+const MusicalCollection = () => {
+  const { type, id } = useParams();
+  const navigate = useNavigate();
+  const [collection, setCollection] = useState<MusicalEntity | null>(null);
+  const [isLoading, setIsLoading] = useState(true);
+  const [error, setError] = useState<string | null>(null);
+
+  useEffect(() => {
+    const fetchData = async () => {
+      setIsLoading(true);
+      setError(null);
+      try {
+        const endpoint =
+          type === "album" ? `/albums/${id}` : `/playlists/${id}`;
+        const response = await axiosInstance.get(endpoint);
+        console.log(response.data);
+        setCollection(response.data);
+      } catch (err: any) {
+        setError(err.response?.data?.error || "Failed to load collection");
+      } finally {
+        setIsLoading(false);
+      }
+    };
+    fetchData();
+  }, [id, type]);
+
+  if (isLoading) {
+    return <div className="p-6">Loading...</div>;
+  }
+
+  if (error) {
+    return (
+      <div className="p-6 bg-red-50 border border-red-200 text-red-700 rounded-lg">
+        <h2 className="font-bold">Error</h2>
+        <p>{error}</p>
+      </div>
+    );
+  }
+
+  if (!collection) return null;
+
+  return (
+    <div className="container mx-auto p-6">
+      <button
+        onClick={() => navigate(-1)}
+        className="mb-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors duration-200"
+      >
+        ← Back
+      </button>
+
+      <div className="bg-white shadow-lg rounded-lg p-8">
+        <div className="flex items-start gap-6 mb-8">
+          <div className="shrink-0">
+            <div className="w-40 h-40 rounded-lg bg-gradient-to-br from-blue-400 to-purple-500 flex items-center justify-center text-white text-5xl font-bold shadow-lg">
+              {collection.title.charAt(0).toUpperCase()}
+            </div>
+          </div>
+
+          <div className="flex-1">
+            <span className="inline-block px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm font-medium mb-2">
+              {collection.type}
+            </span>
+            <h1 className="text-4xl font-bold mb-3">{collection.title}</h1>
+
+            <div className="flex items-center gap-3 text-gray-700 mb-4">
+              <span className="font-semibold">{collection.releasedBy}</span>
+              <span>•</span>
+              <span className="text-gray-600">{collection.genre}</span>
+              {collection.songs && (
+                <>
+                  <span>•</span>
+                  <span className="text-gray-600">
+                    {collection.songs.length} song
+                    {collection.songs.length !== 1 ? "s" : ""}
+                  </span>
+                </>
+              )}
+            </div>
+
+            <button
+              className="flex items-center gap-2 px-4 py-2 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors duration-200"
+              aria-label={collection.isLikedByCurrentUser ? "Unlike" : "Like"}
+            >
+              <svg
+                className="w-5 h-5"
+                fill={collection.isLikedByCurrentUser ? "#ef4444" : "none"}
+                stroke={collection.isLikedByCurrentUser ? "#ef4444" : "#6b7280"}
+                strokeWidth="2"
+                viewBox="0 0 24 24"
+              >
+                <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" />
+              </svg>
+              <span className="text-sm font-medium text-gray-700">
+                {collection.isLikedByCurrentUser ? "Liked" : "Like"}
+              </span>
+            </button>
+          </div>
+        </div>
+
+        <div className="border-t pt-6">
+          <h2 className="text-2xl font-bold mb-4 text-gray-800">Songs</h2>
+
+          {collection.songs && collection.songs.length > 0 ? (
+            <div className="space-y-2">
+              {collection.songs.map((song, index) => (
+                <div
+                  key={song.id}
+                  className="flex items-center gap-4 p-3 rounded-lg hover:bg-gray-50 transition-colors duration-150"
+                >
+                  <span className="text-gray-500 font-medium w-8 text-center">
+                    {index + 1}
+                  </span>
+
+                  <div className="flex-1 min-w-0">
+                    <p className="font-semibold text-gray-900 truncate">
+                      {song.title}
+                    </p>
+                    <p className="text-sm text-gray-600 truncate">
+                      {song.releasedBy}
+                    </p>
+                  </div>
+
+                  <span className="text-sm text-gray-600 px-3 py-1 bg-gray-100 rounded-full">
+                    {song.genre}
+                  </span>
+
+                  <button
+                    className="p-2 hover:bg-gray-100 rounded-full transition-colors duration-200"
+                    aria-label={song.isLikedByCurrentUser ? "Unlike" : "Like"}
+                  >
+                    <svg
+                      className="w-5 h-5"
+                      fill={song.isLikedByCurrentUser ? "#ef4444" : "none"}
+                      stroke={song.isLikedByCurrentUser ? "#ef4444" : "#6b7280"}
+                      strokeWidth="2"
+                      viewBox="0 0 24 24"
+                    >
+                      <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" />
+                    </svg>
+                  </button>
+                </div>
+              ))}
+            </div>
+          ) : (
+            <p className="text-center text-gray-500 py-8">No songs available</p>
+          )}
+        </div>
+      </div>
+    </div>
+  );
+};
+
+export default MusicalCollection;
Index: frontend/src/pages/UserDetailView.tsx
===================================================================
--- frontend/src/pages/UserDetailView.tsx	(revision 98992cf92cf1399ea586c26d6dd45842df661773)
+++ frontend/src/pages/UserDetailView.tsx	(revision 2b08bed6a1ac91c0de26078bed3ee44d43611bd4)
@@ -4,24 +4,17 @@
 import ArtistView from "../components/userProfile/ArtistView";
 import ListenerView from "../components/userProfile/ListenerView";
+import UserListModal from "../components/userProfile/UserListModal";
 import type {
   MusicalEntity,
   Playlist,
   ArtistContribution,
+  BaseNonAdminUser,
 } from "../utils/types";
 
-interface BaseUser {
-  id: number;
-  fullName: string;
-  userType: string;
-  followers: number;
-  following: number;
-  isFollowedByCurrentUser: boolean;
-}
-
-interface Artist extends BaseUser {
+interface Artist extends BaseNonAdminUser {
   userType: "ARTIST";
   contributions: ArtistContribution[];
 }
-interface Listener extends BaseUser {
+interface Listener extends BaseNonAdminUser {
   userType: "LISTENER";
   likedEntities: MusicalEntity[];
@@ -33,8 +26,13 @@
 const UserDetail = () => {
   // user refers to the selected user NOT to the user from context
+  const baseURL = import.meta.env.VITE_API_BASE_URL;
   const { userId } = useParams();
   const navigate = useNavigate();
   const [user, setUser] = useState<UserProfile | null>(null);
   const [error, setError] = useState<string | null>(null);
+  const [showModal, setShowModal] = useState(false);
+  const [modalTitle, setModalTitle] = useState("");
+  const [modalUsers, setModalUsers] = useState<any[]>([]);
+  const [isLoadingModal, setIsLoadingModal] = useState(false);
   const [isFollowing, setIsFollowing] = useState(false);
 
@@ -47,8 +45,61 @@
         `/users/follow/${userId}`,
       );
+      setUser(response.data);
     } catch (err: any) {
       console.error(err.response?.data?.error);
     } finally {
       setIsFollowing(false);
+    }
+  };
+
+  const displayFollowers = async () => {
+    setIsLoadingModal(true);
+    try {
+      const response = await axiosInstance.get(`/users/followers/${userId}`);
+      setModalUsers(response.data);
+      setModalTitle("Followers");
+      setShowModal(true);
+    } catch (err) {
+      console.error("Failed to fetch followers");
+    } finally {
+      setIsLoadingModal(false);
+    }
+  };
+  const displayFollowing = async () => {
+    setIsLoadingModal(true);
+    try {
+      const response = await axiosInstance.get(`/users/following/${userId}`);
+      setModalUsers(response.data);
+      setModalTitle("Following");
+      setShowModal(true);
+    } catch (err) {
+      console.error("Failed to fetch following users");
+    } finally {
+      setIsLoadingModal(false);
+    }
+  };
+
+  const handleFollowInModal = async (targetId: number) => {
+    try {
+      await axiosInstance.post(`/users/follow/${targetId}`);
+      setModalUsers((prevUsers) =>
+        prevUsers.map((u) => {
+          if (u.id === targetId) {
+            const isNowFollowing = !u.isFollowedByCurrentUser;
+            return {
+              ...u,
+              isFollowedByCurrentUser: isNowFollowing,
+            };
+          }
+          return u;
+        }),
+      );
+
+      if (user && user.id === targetId) {
+        const response = await axiosInstance.get(`/users/${targetId}`);
+        setUser(response.data);
+      }
+    } catch (err) {
+      console.error("Failed to toggle follow in modal", err);
     }
   };
@@ -60,5 +111,4 @@
         const response = await axiosInstance.get(`/users/${userId}`);
         console.log(response.data);
-
         setUser(response.data);
       } catch (err: any) {
@@ -84,4 +134,11 @@
   return (
     <div className="container mx-auto p-6">
+      {isLoadingModal && (
+        <div className="fixed inset-0 z-40 bg-black/30 backdrop-blur-sm flex items-center justify-center">
+          <div className="flex items-center gap-3">
+            <div className="w-6 h-6 border-3 border-blue-500 border-t-transparent rounded-full animate-spin"></div>
+          </div>
+        </div>
+      )}
       <button
         onClick={() => navigate(-1)}
@@ -94,6 +151,14 @@
         <div className="flex items-start gap-6 mb-8">
           <div className="shrink-0">
-            <div className="w-32 h-32 rounded-full bg-linear-to-br from-blue-400 to-purple-500 flex items-center justify-center text-white text-4xl font-bold shadow-lg">
-              {user.fullName.charAt(0).toUpperCase()}
+            <div className="w-32 h-32 rounded-full bg-linear-to-br from-blue-400 to-purple-500 flex items-center justify-center text-white text-4xl font-bold shadow-lg overflow-hidden">
+              {user.profilePhoto ? (
+                <img
+                  src={`${baseURL}/${user.profilePhoto}`}
+                  alt={user.fullName}
+                  className="w-full h-full object-cover"
+                />
+              ) : (
+                user.fullName.charAt(0).toUpperCase()
+              )}
             </div>
           </div>
@@ -106,9 +171,19 @@
 
             <div className="flex gap-6 mb-4 text-gray-700">
-              <div className="flex flex-col">
+              <div
+                className={`flex flex-col ${user.userType == "LISTENER" ? "cursor-pointer" : "cursor-default"}`}
+                onClick={
+                  user.userType === "LISTENER" ? displayFollowers : undefined
+                }
+              >
                 <span className="text-2xl font-bold">{user.followers}</span>
                 <span className="text-sm text-gray-500">Followers</span>
               </div>
-              <div className="flex flex-col">
+              <div
+                className={`flex flex-col ${user.userType == "LISTENER" ? "cursor-pointer" : "cursor-default"}`}
+                onClick={
+                  user.userType === "LISTENER" ? displayFollowing : undefined
+                }
+              >
                 <span className="text-2xl font-bold">{user.following}</span>
                 <span className="text-sm text-gray-500">Following</span>
@@ -144,4 +219,13 @@
           />
         )}
+
+        {showModal && (
+          <UserListModal
+            title={modalTitle}
+            users={modalUsers}
+            onClose={() => setShowModal(false)}
+            onFollowToggle={handleFollowInModal}
+          />
+        )}
       </div>
     </div>
