Index: frontend/src/App.tsx
===================================================================
--- frontend/src/App.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ frontend/src/App.tsx	(revision 15ec67f0faa204c0c5d0e1f4d4979ee8ff4fcd4a)
@@ -1,136 +1,19 @@
-import { useEffect, useState } from "react";
-import {
-	createBrowserRouter,
-	Outlet,
-	RouterProvider,
-	useLocation,
-} from "react-router-dom";
-import { ToastContainer } from "react-toastify";
-import "react-toastify/dist/ReactToastify.css";
-import LoadingSpinner from "./components/LoadingSpinner";
-import MiniPlayer from "./components/MiniPlayer";
-import Sidebar from "./components/Sidebar";
-import { useAuth } from "./context/authContext";
-import { usePlayer } from "./context/playerContext";
-// import AllUsers from "./pages/AllUsers";
-import LandingPage from "./pages/LandingPage";
-import Login from "./pages/Login";
-import MusicalCollection from "./pages/MusicalCollection";
-import MySongs from "./pages/MySongs";
-import Nav from "./pages/Nav";
-import PublishSong from "./pages/PublishSong";
-import Register from "./pages/Register";
-import SongDetail from "./pages/SongDetail";
-import UserDetail from "./pages/UserDetail";
+import { useEffect } from "react";
 
-const MainLayout = () => {
-	const { user } = useAuth();
-	const { currentSong } = usePlayer();
-	const location = useLocation();
-	// show sidebar only if user is logged in and is on the landing page
-	const isLandingPage = location.pathname === "/";
-	const [isSidebarOpen, setIsSidebarOpen] = useState(
-		!!user && isLandingPage && !user?.isArtist && !user?.isAdmin,
-	);
-
-	// Open sidebar when user logs in and navigates to landing page
+function App() {
 	useEffect(() => {
-		if (user && isLandingPage && !user.isArtist && !user.isAdmin) {
-			setIsSidebarOpen(true);
-		}
-	}, [user, isLandingPage]);
+		const fetchData = async () => {
+			const response = await fetch("http://localhost:8080/");
+			const data = await response.json();
+			console.log(data);
+		};
+		fetchData();
+	});
 
 	return (
-		<div className="flex flex-col min-h-screen bg-[#121212]">
-			<Nav
-				isSidebarOpen={isSidebarOpen}
-				onToggleSidebar={() => setIsSidebarOpen(!isSidebarOpen)}
-			/>
-			<Sidebar isOpen={isSidebarOpen} onClose={() => setIsSidebarOpen(false)} />
-			<ToastContainer
-				position="top-right"
-				autoClose={2000}
-				hideProgressBar={false}
-				newestOnTop={false}
-				closeOnClick
-				rtl={false}
-				pauseOnFocusLoss
-				draggable
-				pauseOnHover
-				theme="light"
-			/>
-			<main
-				className={`grow transition-all duration-300 pt-20 ${
-					isSidebarOpen ? "ml-64" : "ml-0"
-				} ${currentSong ? "pb-20" : ""}`}
-			>
-				<Outlet />
-			</main>
-			<MiniPlayer />
-		</div>
+		<>
+			<p className="text-red-500">ok</p>
+		</>
 	);
-};
-
-const Layout = () => {
-	const { isAuthLoading } = useAuth();
-
-	if (isAuthLoading) {
-		return <LoadingSpinner />;
-	}
-
-	return <MainLayout />;
-};
-
-const router = createBrowserRouter([
-	{
-		path: "",
-		element: <Layout />,
-		children: [
-			{
-				path: "/",
-				element: <LandingPage />,
-			},
-			{
-				path: "/login",
-				element: <Login />,
-			},
-			// {
-			// 	path: "/users",
-			// 	element: <AllUsers />,
-			// },
-			{
-				path: "/users/:username",
-				element: <UserDetail />,
-			},
-			{
-				path: "/register",
-				element: <Register />,
-			},
-			{
-				path: "/my-songs",
-				element: <MySongs />,
-			},
-			{
-				path: "/publish",
-				element: <PublishSong />,
-			},
-			{
-				path: "/songs/:id",
-				element: <SongDetail />,
-			},
-			{
-				path: "/collection/:type/:id",
-				element: <MusicalCollection />,
-			},
-			{
-				path: "/me",
-				element: <UserDetail />,
-			},
-		],
-	},
-]);
-
-function App() {
-	return <RouterProvider router={router} />;
 }
 
Index: frontend/src/api/axiosInstance.ts
===================================================================
--- frontend/src/api/axiosInstance.ts	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,90 +1,0 @@
-import axios from "axios";
-
-export const baseURL = import.meta.env.VITE_API_BASE_URL;
-
-export const axiosInstance = axios.create({
-	baseURL,
-	withCredentials: true,
-});
-
-// set content-type to application/json unless sending FormData
-axiosInstance.interceptors.request.use((config) => {
-	if (!(config.data instanceof FormData)) {
-		config.headers["Content-Type"] = "application/json";
-	}
-	return config;
-});
-
-let refreshPromise: Promise<void> | null = null;
-let refreshTimeout: number | null = null;
-
-export const clearRefreshTimeout = () => {
-	if (refreshTimeout) {
-		clearTimeout(refreshTimeout);
-		refreshTimeout = null;
-	}
-};
-
-export const scheduleTokenRefresh = (expiryTimeSeconds: number) => {
-	clearRefreshTimeout();
-
-	if (!expiryTimeSeconds || expiryTimeSeconds <= 0) {
-		return;
-	}
-
-	const refreshTime = (expiryTimeSeconds - 60) * 1000;
-	if (refreshTime <= 0) {
-		refreshTokenMethod();
-	} else {
-		refreshTimeout = setTimeout(refreshTokenMethod, refreshTime);
-	}
-};
-
-export const refreshTokenMethod = async (): Promise<void | null> => {
-	if (refreshPromise) {
-		return refreshPromise;
-	}
-
-	refreshPromise = (async () => {
-		try {
-			const refreshResponse = await axiosInstance.post<{
-				tokenExpiresIn: number;
-			}>("/auth/refresh");
-			scheduleTokenRefresh(refreshResponse.data.tokenExpiresIn);
-		} catch (err) {
-			clearRefreshTimeout();
-			console.error(err);
-			throw err;
-		} finally {
-			refreshPromise = null;
-		}
-	})();
-	return refreshPromise;
-};
-
-axiosInstance.interceptors.response.use(
-	(response) => response,
-	async (error) => {
-		const originalConfig = error.config;
-		if (
-			[401, 403].includes(error.response?.status) &&
-			!originalConfig._retry &&
-			originalConfig.url !== "/auth/refresh" &&
-			originalConfig.url !== "/auth/login" &&
-			originalConfig.url !== "/auth/register"
-		) {
-			originalConfig._retry = true;
-
-			try {
-				await refreshTokenMethod();
-				return axiosInstance(originalConfig);
-			} catch (err) {
-				clearRefreshTimeout();
-				return Promise.reject(err);
-			}
-		}
-		return Promise.reject(error);
-	},
-);
-
-export default axiosInstance;
Index: frontend/src/components/LoadingSpinner.tsx
===================================================================
--- frontend/src/components/LoadingSpinner.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,9 +1,0 @@
-const LoadingSpinner = () => {
-	return (
-		<div className="flex h-screen items-center justify-center bg-[#121212]">
-			<div className="w-12 h-12 border-4 border-white/10 border-t-[#1db954] rounded-full animate-spin"></div>
-		</div>
-	);
-};
-
-export default LoadingSpinner;
Index: frontend/src/components/MiniPlayer.tsx
===================================================================
--- frontend/src/components/MiniPlayer.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,214 +1,0 @@
-import { baseURL } from "../api/axiosInstance";
-import { usePlayer } from "../context/playerContext";
-
-const MiniPlayer = () => {
-	const { currentSong, isMinimized, stop, toggleMinimize } = usePlayer();
-
-	if (!currentSong) return null;
-
-	return (
-		<>
-			{/* Fullscreen overlay - only visible when not minimized */}
-			<div
-				className={`fixed inset-0 z-100 bg-[#0a0a0f] flex flex-col transition-opacity duration-300 ${
-					isMinimized
-						? "opacity-0 pointer-events-none"
-						: "opacity-100 pointer-events-auto"
-				}`}
-			>
-				{/* Header bar */}
-				<div className="flex items-center justify-between px-6 py-4 bg-[#1a1a2e]/80 backdrop-blur-sm">
-					<div className="flex items-center gap-4">
-						<img
-							src={
-								currentSong.cover
-									? `${baseURL}/${currentSong.cover}`
-									: "/favicon.png"
-							}
-							alt={currentSong.title}
-							className="w-12 h-12 rounded-lg object-cover shadow-lg"
-							onError={(e) => {
-								(e.target as HTMLImageElement).src = "/favicon.png";
-							}}
-						/>
-						<div>
-							<p className="text-white font-semibold text-lg">
-								{currentSong.title}
-							</p>
-							<p className="text-gray-400 text-sm">{currentSong.artist}</p>
-						</div>
-					</div>
-
-					<div className="flex items-center gap-2">
-						{/* Minimize */}
-						<button
-							onClick={toggleMinimize}
-							className="text-gray-400 hover:text-white p-2.5 rounded-full hover:bg-white/10 transition-all"
-							aria-label="Minimize player"
-						>
-							<svg
-								className="w-6 h-6"
-								fill="none"
-								stroke="currentColor"
-								viewBox="0 0 24 24"
-							>
-								<path
-									strokeLinecap="round"
-									strokeLinejoin="round"
-									strokeWidth={2}
-									d="M19 14l-7 7m0 0l-7-7m7 7V3"
-								/>
-							</svg>
-						</button>
-
-						{/* Close */}
-						<button
-							onClick={stop}
-							className="text-gray-400 hover:text-red-400 p-2.5 rounded-full hover:bg-white/10 transition-all"
-							aria-label="Close player"
-						>
-							<svg
-								className="w-6 h-6"
-								fill="none"
-								stroke="currentColor"
-								viewBox="0 0 24 24"
-							>
-								<path
-									strokeLinecap="round"
-									strokeLinejoin="round"
-									strokeWidth={2}
-									d="M6 18L18 6M6 6l12 12"
-								/>
-							</svg>
-						</button>
-					</div>
-				</div>
-
-				{/* Video container - visible only in fullscreen */}
-				<div className="flex-1 flex items-center justify-center p-4">
-					<div
-						className={`w-full max-w-5xl aspect-video rounded-xl overflow-hidden shadow-2xl ${
-							isMinimized ? "invisible" : "visible"
-						}`}
-					>
-						{/* Single iframe - always mounted to preserve playback state */}
-						<iframe
-							key={currentSong.embedUrl}
-							src={`${currentSong.embedUrl}?autoplay=1`}
-							title={currentSong.title}
-							className="w-full h-full"
-							allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
-							allowFullScreen
-						/>
-					</div>
-				</div>
-			</div>
-
-			{/* Minimized bar - always visible at bottom */}
-			<div
-				className={`fixed bottom-0 left-0 right-0 z-100 h-16 bg-[#1a1a2e] border-t border-white/10 shadow-lg transition-transform duration-300 ${
-					isMinimized ? "translate-y-0" : "translate-y-full"
-				}`}
-			>
-				<div className="flex items-center justify-between px-4 h-full max-w-7xl mx-auto">
-					{/* Song info */}
-					<div className="flex items-center gap-3 min-w-0 flex-1">
-						<img
-							src={
-								currentSong.cover
-									? `${baseURL}/${currentSong.cover}`
-									: "/favicon.png"
-							}
-							alt={currentSong.title}
-							className="w-10 h-10 rounded object-cover shrink-0"
-							onError={(e) => {
-								(e.target as HTMLImageElement).src = "/favicon.png";
-							}}
-						/>
-						<div className="min-w-0">
-							<p className="text-white text-sm font-medium truncate">
-								{currentSong.title}
-							</p>
-							<p className="text-gray-400 text-xs truncate">
-								{currentSong.artist}
-							</p>
-						</div>
-					</div>
-
-					{/* Now playing indicator */}
-					<div className="hidden sm:flex items-center gap-1.5 px-4">
-						<div className="flex items-end gap-0.5 h-4">
-							<div
-								className="w-1 bg-[#1db954] rounded-full animate-[bounce_0.6s_ease-in-out_infinite]"
-								style={{ height: "60%" }}
-							/>
-							<div
-								className="w-1 bg-[#1db954] rounded-full animate-[bounce_0.6s_ease-in-out_infinite_0.1s]"
-								style={{ height: "100%" }}
-							/>
-							<div
-								className="w-1 bg-[#1db954] rounded-full animate-[bounce_0.6s_ease-in-out_infinite_0.2s]"
-								style={{ height: "40%" }}
-							/>
-							<div
-								className="w-1 bg-[#1db954] rounded-full animate-[bounce_0.6s_ease-in-out_infinite_0.3s]"
-								style={{ height: "80%" }}
-							/>
-						</div>
-						<span className="text-[#1db954] text-xs font-medium ml-1">
-							Playing
-						</span>
-					</div>
-
-					{/* Controls */}
-					<div className="flex items-center gap-1">
-						{/* Expand - shows fullscreen to allow seeking */}
-						<button
-							onClick={toggleMinimize}
-							className="text-gray-400 hover:text-white p-2 rounded-full hover:bg-white/10 transition-all"
-							aria-label="Expand player to seek"
-							title="Expand to seek in video"
-						>
-							<svg
-								className="w-5 h-5"
-								fill="none"
-								stroke="currentColor"
-								viewBox="0 0 24 24"
-							>
-								<path
-									strokeLinecap="round"
-									strokeLinejoin="round"
-									strokeWidth={2}
-									d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4"
-								/>
-							</svg>
-						</button>
-
-						{/* Close */}
-						<button
-							onClick={stop}
-							className="text-gray-400 hover:text-red-400 p-2 rounded-full hover:bg-white/10 transition-all"
-							aria-label="Close player"
-						>
-							<svg
-								className="w-5 h-5"
-								fill="none"
-								stroke="currentColor"
-								viewBox="0 0 24 24"
-							>
-								<path
-									strokeLinecap="round"
-									strokeLinejoin="round"
-									strokeWidth={2}
-									d="M6 18L18 6M6 6l12 12"
-								/>
-							</svg>
-						</button>
-					</div>
-				</div>
-			</div>
-		</>
-	);
-};
-
-export default MiniPlayer;
Index: frontend/src/components/Sidebar.tsx
===================================================================
--- frontend/src/components/Sidebar.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,281 +1,0 @@
-import { useEffect, useState } from "react";
-import { useNavigate } from "react-router-dom";
-import { toast } from "react-toastify";
-import axiosInstance, { baseURL } from "../api/axiosInstance";
-import { useAuth } from "../context/authContext";
-import { usePlayer } from "../context/playerContext";
-import { useCreatedPlaylists } from "../context/playlistContext";
-import { getErrorMessage } from "../utils/error";
-import type { BasicSong, SidebarProps } from "../utils/types";
-import { toEmbedUrl } from "../utils/utils";
-import CreatePlaylistModal from "./playlist/CreatePlaylistModal";
-
-const Sidebar = ({ isOpen, onClose }: SidebarProps) => {
-	const { user } = useAuth();
-	const {
-		createdPlaylists,
-		isLoading: playlistsLoading,
-		refreshPlaylists,
-	} = useCreatedPlaylists();
-	const navigate = useNavigate();
-	const { play, currentSong } = usePlayer();
-	const [recentlyListened, setRecentlyListened] = useState<BasicSong[]>([]);
-	const [songsLoading, setSongsLoading] = useState(false);
-	const [isModalOpen, setIsModalOpen] = useState(false);
-
-	useEffect(() => {
-		const fetchData = async () => {
-			setSongsLoading(true);
-			try {
-				const data = await axiosInstance.get<BasicSong[]>("/songs/recent");
-				setRecentlyListened(data.data);
-			} catch (error) {
-				toast.error(getErrorMessage(error));
-			} finally {
-				setSongsLoading(false);
-			}
-		};
-		if (user) {
-			fetchData();
-		} else {
-			setRecentlyListened([]);
-			setSongsLoading(false);
-		}
-	}, [user]);
-
-	const isLoading = songsLoading || playlistsLoading;
-
-	return (
-		<>
-			<div
-				className={`fixed left-0 top-0 h-full bg-[#121212] border-r border-white/10 transition-transform duration-300 ease-in-out z-40 ${
-					isOpen ? "translate-x-0" : "-translate-x-full"
-				} w-64 overflow-y-auto`}
-			>
-				<div className="p-6">
-					{/* Sidebar Header */}
-					<div className="flex justify-between items-center mb-6 pt-2">
-						<h2 className="text-xl font-bold text-white">Library</h2>
-						<button
-							onClick={onClose}
-							className="text-gray-400 hover:text-white transition-colors cursor-pointer"
-							aria-label="Close sidebar"
-						>
-							<svg
-								className="w-6 h-6"
-								fill="none"
-								stroke="currentColor"
-								viewBox="0 0 24 24"
-							>
-								<path
-									strokeLinecap="round"
-									strokeLinejoin="round"
-									strokeWidth={2}
-									d="M6 18L18 6M6 6l12 12"
-								/>
-							</svg>
-						</button>
-					</div>
-
-					{/* Loading State */}
-					{isLoading ? (
-						<div className="flex items-center justify-center py-16">
-							<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-[#1db954]"></div>
-						</div>
-					) : (
-						<>
-							{/* Recently Listened */}
-							<div className="mb-8">
-								<h3 className="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-4">
-									Recently Played
-								</h3>
-								<div className="space-y-3">
-									{recentlyListened.map((song) => (
-										<div
-											key={song.id}
-											className="flex items-center gap-3 p-2 rounded-lg hover:bg-white/5 cursor-pointer transition-colors group relative"
-										>
-											<img
-												src={
-													song.cover
-														? `${baseURL}/${song.cover}`
-														: "/favicon.png"
-												}
-												alt={song.title}
-												className="w-10 h-10 rounded object-cover"
-												onError={(e) => {
-													(e.target as HTMLImageElement).src = "/favicon.png";
-												}}
-											/>
-											<div className="flex-1 min-w-0">
-												<p
-													onClick={() => navigate(`/songs/${song.id}`)}
-													className="text-sm font-medium text-white truncate hover:underline cursor-pointer"
-												>
-													{song.title}
-												</p>
-												<div className="flex items-center gap-1 text-xs text-gray-400">
-													<span
-														onClick={(e) => {
-															e.stopPropagation();
-															if (song.artistUsername) {
-																navigate(`/users/${song.artistUsername}`);
-															}
-														}}
-														className={`truncate ${
-															song.artistUsername
-																? "hover:underline cursor-pointer hover:text-white"
-																: ""
-														}`}
-													>
-														{song.artist}
-													</span>
-													{song.album && (
-														<>
-															<span>•</span>
-															<span
-																onClick={(e) => {
-																	e.stopPropagation();
-																	if (song.albumId) {
-																		navigate(
-																			`/collection/album/${song.albumId}`,
-																		);
-																	}
-																}}
-																className={`truncate ${
-																	song.albumId
-																		? "hover:underline cursor-pointer hover:text-white"
-																		: ""
-																}`}
-															>
-																{song.album}
-															</span>
-														</>
-													)}
-												</div>
-											</div>
-											{song.link && (
-												<button
-													onClick={(e) => {
-														e.stopPropagation();
-														play({
-															id: song.id,
-															title: song.title,
-															artist: song.artist,
-															cover: song.cover,
-															embedUrl: toEmbedUrl(song.link!),
-														});
-													}}
-													className={`p-1.5 rounded-full transition-all opacity-0 group-hover:opacity-100  ${
-														currentSong?.id === song.id
-															? "bg-white text-[#1db954]"
-															: "bg-[#1db954] text-black hover:scale-110 cursor-pointer"
-													}`}
-													aria-label={
-														currentSong?.id === song.id
-															? "Now playing"
-															: "Play song"
-													}
-												>
-													{currentSong?.id === song.id ? (
-														<svg
-															className="w-4 h-4"
-															fill="currentColor"
-															viewBox="0 0 24 24"
-														>
-															<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z" />
-														</svg>
-													) : (
-														<svg
-															className="w-4 h-4"
-															fill="currentColor"
-															viewBox="0 0 24 24"
-														>
-															<path d="M8 5v14l11-7z" />
-														</svg>
-													)}
-												</button>
-											)}
-										</div>
-									))}
-								</div>
-							</div>
-
-							{/* Playlists */}
-							<div>
-								<h3 className="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-4">
-									Your Playlists
-								</h3>
-								<div className="space-y-2">
-									{createdPlaylists?.map((playlist) => (
-										<div
-											key={playlist.id}
-											onClick={() => {
-												navigate(`/collection/playlist/${playlist.id}`);
-											}}
-											className="flex items-center justify-between p-3 rounded-lg hover:bg-white/5 cursor-pointer transition-colors"
-										>
-											<div className="flex items-center gap-3">
-												<div className="w-10 h-10 bg-linear-to-br from-purple-500 to-pink-500 rounded flex items-center justify-center">
-													<svg
-														className="w-5 h-5 text-white"
-														fill="currentColor"
-														viewBox="0 0 20 20"
-													>
-														<path d="M18 3a1 1 0 00-1.196-.98l-10 2A1 1 0 006 5v9.114A4.369 4.369 0 005 14c-1.657 0-3 .895-3 2s1.343 2 3 2 3-.895 3-2V7.82l8-1.6v5.894A4.37 4.37 0 0015 12c-1.657 0-3 .895-3 2s1.343 2 3 2 3-.895 3-2V3z" />
-													</svg>
-												</div>
-												<div>
-													<p className="text-sm font-medium text-white">
-														{playlist.name}
-													</p>
-													<p className="text-xs text-gray-400">
-														{playlist.songCount} songs
-													</p>
-												</div>
-											</div>
-										</div>
-									))}
-
-									{/* Create Playlist Button */}
-									<button
-										onClick={() => setIsModalOpen(true)}
-										className="w-full flex items-center gap-3 p-3 rounded-lg hover:bg-white/5 cursor-pointer transition-colors group mt-2"
-									>
-										<div className="w-10 h-10 bg-[#282828] group-hover:bg-[#3a3a3a] rounded flex items-center justify-center transition-colors">
-											<svg
-												className="w-5 h-5 text-gray-400 group-hover:text-white transition-colors"
-												fill="none"
-												stroke="currentColor"
-												viewBox="0 0 24 24"
-											>
-												<path
-													strokeLinecap="round"
-													strokeLinejoin="round"
-													strokeWidth={2}
-													d="M12 4v16m8-8H4"
-												/>
-											</svg>
-										</div>
-										<p className="text-sm font-medium text-gray-400 group-hover:text-white transition-colors">
-											Create Playlist
-										</p>
-									</button>
-								</div>
-							</div>
-						</>
-					)}
-				</div>
-			</div>
-
-			<CreatePlaylistModal
-				isOpen={isModalOpen}
-				onClose={() => setIsModalOpen(false)}
-				onSuccess={() => refreshPlaylists(false)}
-				songId={null}
-			/>
-		</>
-	);
-};
-
-export default Sidebar;
Index: frontend/src/components/SongItem.tsx
===================================================================
--- frontend/src/components/SongItem.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,248 +1,0 @@
-import { use, useRef, useState } from "react";
-import { useNavigate } from "react-router-dom";
-import { baseURL } from "../api/axiosInstance";
-import { usePlayer } from "../context/playerContext";
-import { toEmbedUrl } from "../utils/utils";
-import PlaylistDropdown from "./playlist/PlaylistDropdown";
-import { useAuth } from "../context/authContext";
-
-export interface SongItemData {
-  id: number;
-  title: string;
-  cover?: string | null;
-  genre?: string;
-  link?: string | null;
-  releasedBy?: string;
-  isLikedByCurrentUser?: boolean;
-}
-
-interface SongItemProps {
-  song: SongItemData;
-  /** Optional label shown before the artist, e.g. "Song" for search results */
-  label?: string;
-  /** Optional role badge for artist contributions, e.g. "PERFORMER" */
-  role?: string;
-  /** Optional index number for playlist/collection views */
-  index?: number;
-  /** Callback when the like button is clicked */
-  onLikeToggle?: (songId: number) => void;
-  /** Controlled: whether the playlist dropdown is open */
-  isDropdownOpen?: boolean;
-  /** Controlled: callback when dropdown should open/close */
-  onDropdownToggle?: (songId: number | null) => void;
-}
-
-const ROLE_COLORS: { [key: string]: string } = {
-  COMPOSER: "bg-purple-500/20 text-purple-300",
-  PERFORMER: "bg-blue-500/20 text-blue-300",
-  PRODUCER: "bg-green-500/20 text-green-300",
-  MAIN_VOCAL: "bg-pink-500/20 text-pink-300",
-};
-
-const SongItem = ({
-  song,
-  label,
-  role,
-  index,
-  onLikeToggle,
-  isDropdownOpen,
-  onDropdownToggle,
-}: SongItemProps) => {
-  const navigate = useNavigate();
-  const { play, currentSong } = usePlayer();
-  const { user } = useAuth();
-  const [internalOpen, setInternalOpen] = useState(false);
-  const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0 });
-  const [dropdownDirection, setDropdownDirection] = useState<"above" | "below">(
-    "below",
-  );
-  const buttonRef = useRef<HTMLButtonElement>(null);
-
-  const playlistOpen = isDropdownOpen ?? internalOpen;
-  const setPlaylistOpen = (open: boolean) => {
-    if (onDropdownToggle) {
-      onDropdownToggle(open ? song.id : null);
-    } else {
-      setInternalOpen(open);
-    }
-  };
-
-  const isPlaying = currentSong?.id === song.id;
-
-  const subtitleParts: string[] = [];
-  if (label) subtitleParts.push(label);
-  if (song.releasedBy) subtitleParts.push(song.releasedBy);
-  const subtitle = subtitleParts.join(" • ");
-
-  return (
-    <div
-      onClick={() => navigate(`/songs/${song.id}`)}
-      onMouseEnter={() => {
-        if (onDropdownToggle && !playlistOpen) {
-          onDropdownToggle(null);
-        }
-      }}
-      className="flex items-center gap-4 p-3 rounded-lg hover:bg-white/5 cursor-pointer transition-colors group"
-    >
-      {/* Optional index */}
-      {index != null && (
-        <span className="text-gray-500 font-medium w-8 text-center text-sm shrink-0">
-          {index}
-        </span>
-      )}
-
-      {/* Cover */}
-      <img
-        src={song.cover ? `${baseURL}/${song.cover}` : "/favicon.png"}
-        alt={song.title}
-        className="w-12 h-12 rounded object-cover shrink-0"
-        onError={(e) => {
-          (e.target as HTMLImageElement).src = "/favicon.png";
-        }}
-      />
-
-      {/* Title & subtitle */}
-      <div className="flex-1 min-w-0">
-        <p
-          className={`font-medium truncate ${
-            isPlaying ? "text-[#1db954]" : "text-white"
-          }`}
-        >
-          {song.title}
-        </p>
-        {subtitle && (
-          <p className="text-sm text-gray-400 truncate">{subtitle}</p>
-        )}
-      </div>
-
-      {/* Role badge (artist contributions) */}
-      {role && (
-        <span
-          className={`px-3 py-1 rounded-full text-xs font-medium hidden sm:block ${
-            ROLE_COLORS[role] || "bg-white/10 text-gray-300"
-          }`}
-        >
-          {role.replace("_", " ")}
-        </span>
-      )}
-
-      {/* Genre */}
-      {song.genre && (
-        <span className="text-xs text-gray-500 uppercase tracking-wider mr-2 hidden sm:block">
-          {song.genre}
-        </span>
-      )}
-
-      {/* Play button */}
-      {song.link && (
-        <button
-          onClick={(e) => {
-            e.stopPropagation();
-            play({
-              id: song.id,
-              title: song.title,
-              artist: song.releasedBy || "",
-              cover: song.cover,
-              embedUrl: toEmbedUrl(song.link!),
-            });
-          }}
-          className={`p-2 rounded-full transition-all cursor-pointer ${
-            isPlaying
-              ? "bg-white text-[#1db954] opacity-100"
-              : "bg-[#1db954] text-black hover:scale-110 opacity-0 group-hover:opacity-100"
-          }`}
-          aria-label={isPlaying ? "Now playing" : "Play song"}
-        >
-          {isPlaying ? (
-            <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
-              <path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z" />
-            </svg>
-          ) : (
-            <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
-              <path d="M8 5v14l11-7z" />
-            </svg>
-          )}
-        </button>
-      )}
-
-      {/* Like button */}
-      {user && onLikeToggle && (
-        <button
-          onClick={(e) => {
-            e.stopPropagation();
-            onLikeToggle(song.id);
-          }}
-          className="p-2 hover:bg-white/10 rounded-full transition-colors cursor-pointer"
-          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>
-      )}
-
-      {/* Three-dot menu */}
-      {user && (
-        <div className="relative">
-          <button
-            ref={buttonRef}
-            onClick={(e) => {
-              e.stopPropagation();
-              if (playlistOpen) {
-                setPlaylistOpen(false);
-              } else {
-                if (buttonRef.current) {
-                  const rect = buttonRef.current.getBoundingClientRect();
-                  const spaceBelow = window.innerHeight - rect.bottom;
-                  const dropdownHeight = 260;
-
-                  if (spaceBelow < dropdownHeight) {
-                    setDropdownDirection("above");
-                    setDropdownPosition({
-                      top: rect.top - 8,
-                      left: rect.right - 224,
-                    });
-                  } else {
-                    setDropdownDirection("below");
-                    setDropdownPosition({
-                      top: rect.bottom + 8,
-                      left: rect.right - 224,
-                    });
-                  }
-                }
-                setPlaylistOpen(true);
-              }
-            }}
-            className="p-2 hover:bg-white/10 rounded-full transition-colors cursor-pointer text-gray-400 hover:text-white"
-            aria-label="More options"
-          >
-            <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
-              <circle cx="12" cy="5" r="1.5" />
-              <circle cx="12" cy="12" r="1.5" />
-              <circle cx="12" cy="19" r="1.5" />
-            </svg>
-          </button>
-
-          <PlaylistDropdown
-            songId={song.id}
-            isOpen={playlistOpen}
-            onClose={() => setPlaylistOpen(false)}
-            position={dropdownPosition}
-            usePortal={true}
-            direction={dropdownDirection}
-          />
-        </div>
-      )}
-
-      {/* Three-dot menu */}
-    </div>
-  );
-};
-
-export default SongItem;
Index: frontend/src/components/playlist/CreatePlaylistModal.tsx
===================================================================
--- frontend/src/components/playlist/CreatePlaylistModal.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,174 +1,0 @@
-import { useState, useEffect } from "react";
-import { toast } from "react-toastify";
-import axiosInstance from "../../api/axiosInstance";
-import type { CreatePlaylistModalProps } from "../../utils/types";
-
-const CreatePlaylistModal = ({
-  isOpen,
-  onClose,
-  onSuccess,
-  songId,
-}: CreatePlaylistModalProps) => {
-  const [playlistName, setPlaylistName] = useState("");
-  const [isClosing, setIsClosing] = useState(false);
-  const [isOpening, setIsOpening] = useState(false);
-  const [isSubmitting, setIsSubmitting] = useState(false);
-  const [error, setError] = useState("");
-
-  useEffect(() => {
-    if (isOpen) {
-      setIsClosing(false);
-      setPlaylistName("");
-      setError("");
-      setIsOpening(true);
-      setTimeout(() => setIsOpening(false), 10);
-    }
-  }, [isOpen]);
-
-  const handleClose = () => {
-    setIsClosing(true);
-    setTimeout(() => {
-      onClose();
-      setIsClosing(false);
-    }, 200);
-  };
-
-  const handleSubmit = async (e: React.FormEvent) => {
-    e.preventDefault();
-    if (!playlistName.trim() || isSubmitting) return;
-
-    setIsSubmitting(true);
-    try {
-      await axiosInstance.post("/playlists", null, {
-        params: {
-          playlistName: playlistName.trim(),
-          ...(songId != null && { songId }),
-        },
-      });
-
-      toast.success("Playlist created successfully!");
-      await onSuccess();
-      handleClose();
-    } catch (err: any) {
-      setError(err?.response?.data?.error || "Failed to create playlist");
-    } finally {
-      setIsSubmitting(false);
-    }
-  };
-
-  if (!isOpen && !isClosing) return null;
-
-  return (
-    <div
-      className={`fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-50 px-4 transition-opacity duration-200 ${
-        isClosing || isOpening ? "opacity-0" : "opacity-100"
-      }`}
-      onClick={handleClose}
-    >
-      <div
-        className={`bg-[#181818] rounded-xl p-8 w-full max-w-md border border-white/10 transition-all duration-200 ${
-          isClosing || isOpening
-            ? "scale-95 opacity-0"
-            : "scale-100 opacity-100"
-        }`}
-        onClick={(e) => e.stopPropagation()}
-      >
-        <div className="flex justify-between items-center mb-6">
-          <h2 className="text-2xl font-bold text-white">Create Playlist</h2>
-          <button
-            onClick={handleClose}
-            className="text-gray-400 hover:text-white transition-colors cursor-pointer"
-            aria-label="Close modal"
-          >
-            <svg
-              className="w-6 h-6"
-              fill="none"
-              stroke="currentColor"
-              viewBox="0 0 24 24"
-            >
-              <path
-                strokeLinecap="round"
-                strokeLinejoin="round"
-                strokeWidth={2}
-                d="M6 18L18 6M6 6l12 12"
-              />
-            </svg>
-          </button>
-        </div>
-
-        <form onSubmit={handleSubmit} className="space-y-6">
-          <div>
-            <label
-              className="block text-sm font-medium text-gray-300 mb-2"
-              htmlFor="playlistName"
-            >
-              Playlist Name
-            </label>
-            <input
-              type="text"
-              id="playlistName"
-              autoFocus
-              className={`w-full bg-[#282828] border rounded-lg py-3 px-4 text-white placeholder-gray-500 focus:outline-none transition-all ${
-                error
-                  ? "border-red-500 focus:border-red-500 focus:ring-1 focus:ring-red-500"
-                  : "border-white/10 focus:border-[#1db954] focus:ring-1 focus:ring-[#1db954]"
-              }`}
-              placeholder="Enter playlist name"
-              value={playlistName}
-              onChange={(e) => {
-                setPlaylistName(e.target.value);
-              }}
-            />
-            <div
-              className={`overflow-hidden transition-all duration-200 ease-out ${
-                error ? "max-h-20 opacity-100 mt-2" : "max-h-0 opacity-0"
-              }`}
-            >
-              <p className="text-sm text-red-400 flex items-center gap-1.5">
-                <svg
-                  className="w-4 h-4 shrink-0"
-                  fill="currentColor"
-                  viewBox="0 0 20 20"
-                >
-                  <path
-                    fillRule="evenodd"
-                    d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z"
-                    clipRule="evenodd"
-                  />
-                </svg>
-                {error}
-              </p>
-            </div>
-          </div>
-
-          <div className="flex gap-3">
-            <button
-              type="button"
-              onClick={handleClose}
-              disabled={isSubmitting}
-              className="flex-1 py-3 bg-[#282828] rounded-full text-white font-semibold hover:bg-[#3a3a3a] transition-colors cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
-            >
-              Cancel
-            </button>
-            <button
-              type="submit"
-              disabled={!playlistName.trim() || isSubmitting}
-              className="flex-1 py-3 bg-[#1db954] rounded-full text-black font-semibold hover:bg-[#1ed760] transition-colors disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-[#1db954] cursor-pointer flex items-center justify-center gap-2"
-            >
-              {isSubmitting ? (
-                <>
-                  <div className="w-4 h-4 border-2 border-black/20 border-t-black rounded-full animate-spin"></div>
-                  Creating...
-                </>
-              ) : (
-                "Create"
-              )}
-            </button>
-          </div>
-        </form>
-      </div>
-    </div>
-  );
-};
-
-export default CreatePlaylistModal;
Index: frontend/src/components/playlist/PlaylistDropdown.tsx
===================================================================
--- frontend/src/components/playlist/PlaylistDropdown.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,267 +1,0 @@
-import { useEffect, useRef, useState } from "react";
-import { createPortal } from "react-dom";
-import axiosInstance from "../../api/axiosInstance";
-import { useCreatedPlaylists } from "../../context/playlistContext";
-import CreatePlaylistModal from "./CreatePlaylistModal";
-
-interface PlaylistDropdownProps {
-  songId: number;
-  isOpen: boolean;
-  onClose: () => void;
-  position?: { top: number; left: number };
-
-  usePortal?: boolean;
-
-  direction?: "above" | "below";
-}
-
-const PlaylistDropdown = ({
-  songId,
-  isOpen,
-  onClose,
-  position,
-  usePortal = false,
-  direction = "above",
-}: PlaylistDropdownProps) => {
-  const { createdPlaylists, refreshPlaylists } = useCreatedPlaylists();
-  const [containingPlaylistIds, setContainingPlaylistIds] = useState<number[]>(
-    [],
-  );
-  const [loading, setLoading] = useState(false);
-  const [processingIds, setProcessingIds] = useState<Set<number>>(new Set());
-  const [isModalOpen, setIsModalOpen] = useState(false);
-  const dropdownRef = useRef<HTMLDivElement>(null);
-
-  useEffect(() => {
-    if (isOpen && songId) {
-      const fetchPlaylistIds = async () => {
-        setLoading(true);
-        setContainingPlaylistIds([]);
-        try {
-          const response = await axiosInstance.get<number[]>(
-            `/playlists/song/${songId}`,
-          );
-          setContainingPlaylistIds(response.data);
-        } catch (error) {
-          console.error("Failed to fetch song presence:", error);
-        } finally {
-          setLoading(false);
-        }
-      };
-      fetchPlaylistIds();
-    } else {
-      setContainingPlaylistIds([]);
-    }
-  }, [isOpen, songId]);
-
-  useEffect(() => {
-    const handleClickOutside = (event: MouseEvent) => {
-      if (
-        dropdownRef.current &&
-        !dropdownRef.current.contains(event.target as Node)
-      ) {
-        onClose();
-      }
-    };
-
-    if (isOpen) {
-      document.addEventListener("mousedown", handleClickOutside);
-    }
-    return () => document.removeEventListener("mousedown", handleClickOutside);
-  }, [isOpen, onClose]);
-
-  const handleTogglePlaylist = async (playlistId: number, songId: number) => {
-    if (processingIds.has(playlistId)) return;
-
-    setProcessingIds((prev) => new Set(prev).add(playlistId));
-
-    try {
-      const response = await axiosInstance.post<{
-        playlistId: number;
-        isSongAddedToPlaylist: boolean;
-      }>(`/playlists/${playlistId}/song/${songId}`);
-
-      const { playlistId: returnedPlaylistId, isSongAddedToPlaylist } =
-        response.data;
-
-      if (isSongAddedToPlaylist) {
-        setContainingPlaylistIds((prev) =>
-          prev.includes(returnedPlaylistId)
-            ? prev
-            : [...prev, returnedPlaylistId],
-        );
-      } else {
-        setContainingPlaylistIds((prev) =>
-          prev.filter((id) => id !== returnedPlaylistId),
-        );
-      }
-    } catch (error) {
-      console.error("Failed to toggle playlist:", error);
-    } finally {
-      refreshPlaylists(true);
-      setTimeout(() => {
-        setProcessingIds((prev) => {
-          const next = new Set(prev);
-          next.delete(playlistId);
-          return next;
-        });
-      }, 500);
-    }
-  };
-
-  const handleCreateNew = () => {
-    onClose();
-    setIsModalOpen(true);
-  };
-
-  const handleModalSuccess = async () => {
-    await refreshPlaylists(false);
-  };
-
-  const inlinePositionClass =
-    direction === "below"
-      ? "absolute left-0 top-full mt-2"
-      : "absolute right-0 bottom-full mb-2";
-
-  const dropdownContent = !isOpen ? null : (
-    <div
-      ref={dropdownRef}
-      className={`${usePortal ? "fixed" : inlinePositionClass} w-56 bg-[#282828] rounded-lg shadow-2xl py-2 z-9999 border border-white/10 max-h-60 overflow-y-auto custom-scrollbar`}
-      style={
-        usePortal && position
-          ? {
-              top: position.top,
-              left: position.left,
-              transform:
-                direction === "below" ? undefined : "translateY(-100%)",
-            }
-          : undefined
-      }
-      onClick={(e) => e.stopPropagation()}
-    >
-      <div className="px-4 py-2 text-xs font-bold text-gray-400 uppercase tracking-wider border-b border-white/5 mb-1">
-        Add to playlist
-      </div>
-
-      {loading ? (
-        <div className="flex items-center justify-center py-4">
-          <div className="w-5 h-5 border-2 border-white/10 border-t-[#1db954] rounded-full animate-spin"></div>
-        </div>
-      ) : createdPlaylists && createdPlaylists.length > 0 ? (
-        createdPlaylists.map((playlist) => {
-          const isProcessing = processingIds.has(playlist.id);
-          const isChecked = containingPlaylistIds.includes(playlist.id);
-
-          return (
-            <label
-              key={playlist.id}
-              className={`flex items-center gap-1.5 px-4 py-2 hover:bg-white/10 transition-colors group/item ${
-                isProcessing ? "pointer-events-none" : "cursor-pointer"
-              }`}
-              onClick={(e) => e.stopPropagation()}
-            >
-              <div className="relative flex items-center justify-center  shrink-0">
-                <input
-                  type="checkbox"
-                  className="peer sr-only"
-                  checked={isChecked}
-                  disabled={isProcessing}
-                  onChange={() => handleTogglePlaylist(playlist.id, songId)}
-                />
-                <div
-                  className={`w-5 h-5 border-2 rounded bg-[#181818] transition-all ${
-                    isProcessing
-                      ? "border-[#1db954] animate-pulse"
-                      : isChecked
-                        ? "bg-[#1db954] border-[#1db954]"
-                        : "border-gray-500 text=wjot"
-                  }`}
-                >
-                  {isProcessing && (
-                    <div className="absolute inset-0 flex items-center justify-center">
-                      <div className="w-3 h-3 border-2 border-transparent border-t-[#1db954] rounded-full animate-spin"></div>
-                    </div>
-                  )}
-                </div>
-                <svg
-                  className={`absolute w-3 h-3 transition-opacity ${
-                    isChecked && !isProcessing ? "opacity-100" : "opacity-0"
-                  }`}
-                  fill="none"
-                  stroke="white"
-                  strokeWidth="3"
-                  viewBox="0 0 24 24"
-                >
-                  <path
-                    strokeLinecap="round"
-                    strokeLinejoin="round"
-                    d="M5 13l4 4L19 7"
-                  />
-                </svg>
-              </div>
-              <span
-                className={`text-sm truncate transition-all ${
-                  isProcessing
-                    ? "text-[#1db954] animate-pulse"
-                    : "text-gray-200 group-hover/item:text-white"
-                }`}
-              >
-                {playlist.name}
-              </span>
-            </label>
-          );
-        })
-      ) : (
-        <div className="px-4 py-3 text-sm text-gray-500 italic">
-          No playlists created
-        </div>
-      )}
-
-      <button
-        onClick={(e) => {
-          e.stopPropagation();
-          handleCreateNew();
-        }}
-        className="w-full text-left px-4 py-2 mt-1 text-sm text-[#1db954] hover:bg-white/5 transition-colors border-t border-white/5 flex items-center gap-2 font-medium cursor-pointer"
-      >
-        <svg
-          className="w-4 h-4"
-          fill="none"
-          stroke="currentColor"
-          viewBox="0 0 24 24"
-        >
-          <path
-            strokeLinecap="round"
-            strokeLinejoin="round"
-            strokeWidth={2}
-            d="M12 4v16m8-8H4"
-          />
-        </svg>
-        Create new playlist
-      </button>
-    </div>
-  );
-
-  const dropdown = dropdownContent
-    ? usePortal
-      ? createPortal(dropdownContent, document.body)
-      : dropdownContent
-    : null;
-
-  return (
-    <>
-      {dropdown}
-      {createPortal(
-        <CreatePlaylistModal
-          isOpen={isModalOpen}
-          onClose={() => setIsModalOpen(false)}
-          onSuccess={handleModalSuccess}
-          songId={songId}
-        />,
-        document.body,
-      )}
-    </>
-  );
-};
-
-export default PlaylistDropdown;
Index: frontend/src/components/search/AlbumResult.tsx
===================================================================
--- frontend/src/components/search/AlbumResult.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,38 +1,0 @@
-import { useNavigate } from "react-router-dom";
-import { baseURL } from "../../api/axiosInstance";
-import type { Album } from "../../utils/types";
-
-interface AlbumResultProps {
-	album: Album;
-}
-
-const AlbumResult = ({ album }: AlbumResultProps) => {
-	const navigate = useNavigate();
-
-	return (
-		<div
-			onClick={() => navigate(`/collection/album/${album.id}`)}
-			className="flex items-center gap-4 p-3 rounded-lg hover:bg-white/5 cursor-pointer transition-colors group"
-		>
-			<img
-				src={album.cover ? `${baseURL}/${album.cover}` : "/favicon.png"}
-				alt={album.title}
-				className="w-12 h-12 rounded object-cover"
-				onError={(e) => {
-					(e.target as HTMLImageElement).src = "/favicon.png";
-				}}
-			/>
-			<div className="flex-1 min-w-0">
-				<p className="text-white font-medium truncate">{album.title}</p>
-				<p className="text-sm text-gray-400 truncate">
-					Album • {album.releasedBy}
-				</p>
-			</div>
-			<span className="text-xs text-gray-500 uppercase tracking-wider">
-				{album.genre}
-			</span>
-		</div>
-	);
-};
-
-export default AlbumResult;
Index: frontend/src/components/search/SongResult.tsx
===================================================================
--- frontend/src/components/search/SongResult.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,26 +1,0 @@
-import axiosInstance from "../../api/axiosInstance";
-import type { Song } from "../../utils/types";
-import SongItem from "../SongItem";
-
-interface SongResultProps {
-	song: Song;
-	/** Propagate like state change upward if needed */
-	onLikeToggled?: (songId: number, isLiked: boolean) => void;
-}
-
-const SongResult = ({ song, onLikeToggled }: SongResultProps) => {
-	const handleLike = async (songId: number) => {
-		try {
-			const response = await axiosInstance.post(
-				`/musical-entity/${songId}/like`,
-			);
-			onLikeToggled?.(songId, response.data.isLiked);
-		} catch (err) {
-			console.error("Error toggling like:", err);
-		}
-	};
-
-	return <SongItem song={song} label="Song" onLikeToggle={handleLike} />;
-};
-
-export default SongResult;
Index: frontend/src/components/search/UserResult.tsx
===================================================================
--- frontend/src/components/search/UserResult.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,41 +1,0 @@
-import { useNavigate } from "react-router-dom";
-import { baseURL } from "../../api/axiosInstance";
-import type { BaseNonAdminUser } from "../../utils/types";
-
-interface UserResultProps {
-	user: BaseNonAdminUser;
-	label: "Artist" | "User";
-}
-
-const UserResult = ({ user, label }: UserResultProps) => {
-	const navigate = useNavigate();
-
-	return (
-		<div
-			onClick={() => navigate(`/users/${user.username}`)}
-			className="flex items-center gap-4 p-3 rounded-lg hover:bg-white/5 cursor-pointer transition-colors group"
-		>
-			{user.profilePhoto ? (
-				<img
-					src={`${baseURL}/${user.profilePhoto}`}
-					alt={user.username}
-					className="w-12 h-12 rounded-full object-cover"
-				/>
-			) : (
-				<div className="w-12 h-12 bg-blue-500 rounded-full flex items-center justify-center">
-					<span className="text-white text-lg font-semibold">
-						{user.username.charAt(0).toUpperCase()}
-					</span>
-				</div>
-			)}
-			<div className="flex-1 min-w-0">
-				<p className="text-white font-medium truncate">{user.fullName}</p>
-				<p className="text-sm text-gray-400 truncate">
-					{label} • @{user.username}
-				</p>
-			</div>
-		</div>
-	);
-};
-
-export default UserResult;
Index: frontend/src/components/userProfile/ArtistView.tsx
===================================================================
--- frontend/src/components/userProfile/ArtistView.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,158 +1,0 @@
-import { Disc3, Music } from "lucide-react";
-import { useState } from "react";
-import { useNavigate } from "react-router-dom";
-import { toast } from "react-toastify";
-import axiosInstance, { baseURL } from "../../api/axiosInstance";
-import type { ArtistContribution } from "../../utils/types";
-import SongItem from "../SongItem";
-import { useAuth } from "../../context/authContext";
-
-interface ArtistViewProps {
-  contributions: ArtistContribution[];
-}
-
-const ArtistView = ({ contributions }: ArtistViewProps) => {
-  const navigate = useNavigate();
-  const [items, setItems] = useState(contributions);
-  const [openDropdownSongId, setOpenDropdownSongId] = useState<number | null>(
-    null,
-  );
-
-  const albums = items.filter((c) => c.entityType === "ALBUM");
-  const songs = items.filter((c) => c.entityType === "SONG");
-
-  const getRoleColor = (role: string) => {
-    const colors: { [key: string]: string } = {
-      COMPOSER: "bg-purple-500/20 text-purple-300",
-      PERFORMER: "bg-blue-500/20 text-blue-300",
-      PRODUCER: "bg-green-500/20 text-green-300",
-      MAIN_VOCAL: "bg-pink-500/20 text-pink-300",
-    };
-    return colors[role] || "bg-white/10 text-gray-300";
-  };
-
-  const handleLike = async (id: number, title: string) => {
-    try {
-      const response = await axiosInstance.post(`/musical-entity/${id}/like`);
-      const data = response.data;
-
-      setItems((prevItems) =>
-        prevItems.map((item) =>
-          item.id === data.entityId
-            ? { ...item, isLikedByCurrentUser: data.isLiked }
-            : item,
-        ),
-      );
-      toast.success(
-        data.isLiked ? `Liked "${title}"` : `Removed "${title}" from likes`,
-      );
-    } catch (err: any) {
-      toast.error(err.response?.data?.error || "Failed to like the item");
-    }
-  };
-
-  return (
-    <div className="mt-8">
-      {albums.length > 0 && (
-        <div className="mb-12">
-          <div className="flex items-center gap-3 mb-6">
-            <Disc3 className="w-6 h-6 text-[#1db954]" />
-            <h2 className="text-2xl font-bold text-white">Albums</h2>
-          </div>
-          <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
-            {albums.map((album) => (
-              <div
-                key={album.id}
-                className="group cursor-pointer"
-                onClick={() => navigate(`/collection/album/${album.id}`)}
-              >
-                <div className="relative aspect-square rounded-lg mb-3 overflow-hidden shadow-md group-hover:shadow-xl transition-all duration-300 bg-[#181818]">
-                  <img
-                    src={
-                      album.cover ? `${baseURL}/${album.cover}` : "/favicon.png"
-                    }
-                    alt={album.title}
-                    className="w-full h-full object-cover"
-                    onError={(e) => {
-                      (e.target as HTMLImageElement).src = "/favicon.png";
-                    }}
-                  />
-
-                  <button
-                    className="absolute top-2 right-2 p-2 bg-black/70 hover:bg-black/90 rounded-full shadow-md transition-all duration-200 opacity-0 group-hover:opacity-100 cursor-pointer"
-                    title={album.isLikedByCurrentUser ? "Unlike" : "Like"}
-                    onClick={(e) => {
-                      e.stopPropagation();
-                      handleLike(album.id, album.title);
-                    }}
-                  >
-                    <svg
-                      className="w-5 h-5"
-                      fill={album.isLikedByCurrentUser ? "#ef4444" : "none"}
-                      stroke={
-                        album.isLikedByCurrentUser ? "#ef4444" : "#9ca3af"
-                      }
-                      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 className="absolute bottom-0 left-0 right-0 bg-linear-to-t from-black/80 to-transparent p-3">
-                    <span
-                      className={`text-xs px-2 py-1 rounded-full font-medium ${getRoleColor(album.role)}`}
-                    >
-                      {album.role.replace("_", " ")}
-                    </span>
-                  </div>
-                </div>
-                <h3 className="font-semibold text-sm line-clamp-2 text-white group-hover:text-[#1db954] transition-colors">
-                  {album.title}
-                </h3>
-              </div>
-            ))}
-          </div>
-        </div>
-      )}
-
-      {songs.length > 0 && (
-        <div className="mb-12">
-          <div className="flex items-center gap-3 mb-6">
-            <Music className="w-6 h-6 text-[#1db954]" />
-            <h2 className="text-2xl font-bold text-white">Songs</h2>
-          </div>
-          <div className="space-y-1">
-            {songs.map((song) => (
-              <SongItem
-                key={song.id}
-                song={{
-                  id: song.id,
-                  title: song.title,
-                  cover: song.cover,
-                  genre: song.genre,
-                  link: song.link,
-                  isLikedByCurrentUser: song.isLikedByCurrentUser,
-                }}
-                role={song.role}
-                onLikeToggle={() => handleLike(song.id, song.title)}
-                isDropdownOpen={openDropdownSongId === song.id}
-                onDropdownToggle={setOpenDropdownSongId}
-              />
-            ))}
-          </div>
-        </div>
-      )}
-
-      {contributions.length === 0 && (
-        <div className="flex flex-col items-center justify-center py-16 text-gray-500">
-          <Music className="w-20 h-20 mb-4 opacity-20" />
-          <p className="text-lg font-medium">No contributions yet</p>
-          <p className="text-sm mt-2">Start creating music to see it here</p>
-        </div>
-      )}
-    </div>
-  );
-};
-
-export default ArtistView;
Index: frontend/src/components/userProfile/ListenerView.tsx
===================================================================
--- frontend/src/components/userProfile/ListenerView.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,380 +1,0 @@
-import { Album, Bookmark, Heart, ListMusic, Music, Trash2 } from "lucide-react";
-import { useState } from "react";
-import { useNavigate, useParams } from "react-router-dom";
-import { toast } from "react-toastify";
-import axiosInstance, { baseURL } from "../../api/axiosInstance";
-import type { MusicalEntity, Playlist } from "../../utils/types";
-import SongItem from "../SongItem";
-import { useAuth } from "../../context/authContext";
-import { useCreatedPlaylists } from "../../context/playlistContext";
-
-interface ListenerViewProps {
-  likedEntities: MusicalEntity[] | [];
-  createdPlaylists: Playlist[] | [];
-  savedPlaylists: Playlist[] | [];
-}
-
-const ListenerView = ({
-  likedEntities,
-  createdPlaylists,
-  savedPlaylists,
-}: ListenerViewProps) => {
-  const navigate = useNavigate();
-  const { refreshPlaylists } = useCreatedPlaylists();
-  const { username: usernameParam } = useParams();
-  const { user: currentUser } = useAuth();
-  const [items, setItems] = useState(likedEntities);
-  const [createdItems, setCreatedItems] = useState(createdPlaylists);
-  const [savedItems, setSavedItems] = useState(savedPlaylists);
-  const [openDropdownSongId, setOpenDropdownSongId] = useState<number | null>(
-    null,
-  );
-
-  const likedSongs = items.filter((e) => e.type === "SONG");
-  const likedAlbums = items.filter((e) => e.type === "ALBUM");
-  const username = usernameParam || currentUser?.username;
-  const isOwnProfile = currentUser?.username === username;
-
-  const handleSavePlaylist = async (
-    e: React.MouseEvent,
-    playlistId: number,
-    playlistName: string,
-  ) => {
-    e.stopPropagation();
-
-    try {
-      const response = await axiosInstance.post(
-        `/playlists/${playlistId}/save`,
-      );
-      const data = response.data;
-
-      setCreatedItems((prevItems) =>
-        prevItems.map((p) =>
-          p.id === playlistId
-            ? { ...p, isSavedByCurrentUser: data.isSavedByCurrentUser }
-            : p,
-        ),
-      );
-
-      setSavedItems((prevItems) =>
-        prevItems.map((p) =>
-          p.id === playlistId
-            ? { ...p, isSavedByCurrentUser: data.isSavedByCurrentUser }
-            : p,
-        ),
-      );
-
-      if (isOwnProfile) {
-        if (data.isSavedByCurrentUser) {
-          const playlistToAdd = createdItems.find((p) => p.id === playlistId);
-          if (playlistToAdd && !savedItems.find((p) => p.id === playlistId)) {
-            setSavedItems((prevItems) => [
-              ...prevItems,
-              { ...playlistToAdd, isSavedByCurrentUser: true },
-            ]);
-          }
-        } else {
-          setSavedItems((prevItems) =>
-            prevItems.filter((p) => p.id !== playlistId),
-          );
-        }
-      }
-
-      toast.success(
-        data.isSavedByCurrentUser
-          ? `Saved "${playlistName}" to your library`
-          : `Removed "${playlistName}" from your library`,
-      );
-    } catch (err: any) {
-      toast.error(err.response?.data?.error || "Failed to save the playlist");
-    }
-  };
-
-  const handleDeletePlaylist = async (
-    e: React.MouseEvent,
-    playlistId: number,
-    playlistName: string,
-  ) => {
-    e.stopPropagation();
-
-    try {
-      await axiosInstance.delete(`/playlists/${playlistId}`);
-      refreshPlaylists(false);
-
-      setCreatedItems((prev) => prev.filter((p) => p.id !== playlistId));
-      toast.success(`Deleted "${playlistName}"`);
-    } catch (err: any) {
-      toast.error(err.response?.data?.error || "Failed to delete playlist");
-    }
-  };
-
-  const handleLike = async (id: number, title: string) => {
-    try {
-      const response = await axiosInstance.post(`/musical-entity/${id}/like`);
-      const data = response.data;
-
-      setItems((prevItems) =>
-        prevItems.map((item) =>
-          item.id === data.entityId
-            ? { ...item, isLikedByCurrentUser: data.isLiked }
-            : item,
-        ),
-      );
-
-      toast.success(
-        data.isLiked ? `Liked "${title}"` : `Removed "${title}" from likes`,
-      );
-    } catch (err: any) {
-      toast.error(err.response?.data?.error || "Failed to like the item");
-    }
-  };
-
-  return (
-    <div className="mt-8 space-y-12">
-      {createdItems && createdItems.length > 0 && (
-        <section>
-          <div className="flex items-center gap-3 mb-6">
-            <ListMusic className="w-6 h-6 text-[#1db954]" />
-            <h3 className="text-2xl font-bold text-white">Created Playlists</h3>
-            <span className="text-sm text-gray-500">
-              ({createdItems.length})
-            </span>
-          </div>
-
-          <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
-            {createdItems.map((playlist) => (
-              <div
-                key={playlist.id}
-                className="group cursor-pointer"
-                onClick={() => navigate(`/collection/playlist/${playlist.id}`)}
-              >
-                <div className="relative aspect-square rounded-lg overflow-hidden bg-[#181818] mb-3 shadow-md group-hover:shadow-xl transition-all">
-                  <img
-                    src={
-                      playlist.cover
-                        ? `${baseURL}/${playlist.cover}`
-                        : "/favicon.png"
-                    }
-                    alt={playlist.name}
-                    className="w-full h-full object-cover"
-                    onError={(e) => {
-                      (e.target as HTMLImageElement).src = "/favicon.png";
-                    }}
-                  />
-                  {isOwnProfile ? (
-                    <button
-                      onClick={(e) =>
-                        handleDeletePlaylist(e, playlist.id, playlist.name)
-                      }
-                      className="absolute top-2 right-2 p-2 bg-black/70 hover:bg-red-600/90 rounded-full shadow-md transition-all duration-200 opacity-0 group-hover:opacity-100 cursor-pointer"
-                      title="Delete playlist"
-                    >
-                      <Trash2 className="w-5 h-5 text-gray-400 hover:text-white transition-colors" />
-                    </button>
-                  ) : (
-                    currentUser?.username != playlist.creatorUsername && (
-                      <button
-                        onClick={(e) =>
-                          handleSavePlaylist(e, playlist.id, playlist.name)
-                        }
-                        className="absolute top-2 right-2 p-2 bg-black/70 hover:bg-black/90 rounded-full shadow-md transition-all duration-200 opacity-0 group-hover:opacity-100 cursor-pointer"
-                        title={
-                          playlist.isSavedByCurrentUser ? "Unsave" : "Save"
-                        }
-                      >
-                        <Bookmark
-                          className={`w-5 h-5 ${
-                            playlist.isSavedByCurrentUser
-                              ? "fill-[#1db954] text-[#1db954]"
-                              : "text-gray-400"
-                          }`}
-                        />
-                      </button>
-                    )
-                  )}
-                </div>
-                <p className="text-sm font-semibold text-white truncate group-hover:text-[#1db954] transition-colors">
-                  {playlist.name}
-                </p>
-                <p className="text-xs text-gray-400 truncate">
-                  {playlist.creatorName}
-                </p>
-              </div>
-            ))}
-          </div>
-        </section>
-      )}
-
-      {savedItems && savedItems.length > 0 && (
-        <section>
-          <div className="flex items-center gap-3 mb-6">
-            <Bookmark className="w-6 h-6 text-[#1db954] fill-[#1db954]" />
-            <h3 className="text-2xl font-bold text-white">Saved Playlists</h3>
-            <span className="text-sm text-gray-500">({savedItems.length})</span>
-          </div>
-
-          <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
-            {savedItems.map((playlist) => (
-              <div
-                key={playlist.id}
-                className="group cursor-pointer"
-                onClick={() => navigate(`/collection/playlist/${playlist.id}`)}
-              >
-                <div className="relative aspect-square rounded-lg overflow-hidden bg-[#181818] mb-3 shadow-md group-hover:shadow-xl transition-all">
-                  <img
-                    src={
-                      playlist.cover
-                        ? `${baseURL}/${playlist.cover}`
-                        : "/favicon.png"
-                    }
-                    alt={playlist.name}
-                    className="w-full h-full object-cover"
-                    onError={(e) => {
-                      (e.target as HTMLImageElement).src = "/favicon.png";
-                    }}
-                  />
-
-                  {currentUser?.username != playlist.creatorUsername && (
-                    <button
-                      onClick={(e) =>
-                        handleSavePlaylist(e, playlist.id, playlist.name)
-                      }
-                      className="absolute top-2 right-2 p-2 bg-black/70 hover:bg-black/90 rounded-full shadow-md transition-all duration-200 opacity-0 group-hover:opacity-100 cursor-pointer"
-                      title={playlist.isSavedByCurrentUser ? "Unsave" : "Save"}
-                    >
-                      <Bookmark
-                        className={`w-5 h-5 ${
-                          playlist.isSavedByCurrentUser
-                            ? "fill-[#1db954] text-[#1db954]"
-                            : "text-gray-400"
-                        }`}
-                      />
-                    </button>
-                  )}
-                </div>
-                <p className="text-sm font-semibold text-white truncate group-hover:text-[#1db954] transition-colors">
-                  {playlist.name}
-                </p>
-                <p className="text-xs text-gray-400 truncate">
-                  {playlist.creatorName}
-                </p>
-              </div>
-            ))}
-          </div>
-        </section>
-      )}
-
-      {likedSongs && likedSongs.length > 0 && (
-        <section>
-          <div className="flex items-center gap-3 mb-6">
-            <Heart className="w-6 h-6 text-red-500 fill-red-500" />
-            <h3 className="text-2xl font-bold text-white">Liked Songs</h3>
-            <span className="text-sm text-gray-500">
-              ({likedSongs?.length})
-            </span>
-          </div>
-
-          <div className="space-y-1">
-            {likedSongs.map((song, index) => (
-              <SongItem
-                key={song.id}
-                song={{
-                  id: song.id,
-                  title: song.title,
-                  cover: song.cover
-                    ? `${baseURL}/${song.cover}`
-                    : "/favicon.png",
-                  genre: song.genre,
-                  link: (song as any).link,
-                  releasedBy: song.releasedBy,
-                  isLikedByCurrentUser: song.isLikedByCurrentUser,
-                }}
-                index={index + 1}
-                onLikeToggle={() => handleLike(song.id, song.title)}
-                isDropdownOpen={openDropdownSongId === song.id}
-                onDropdownToggle={setOpenDropdownSongId}
-              />
-            ))}
-          </div>
-        </section>
-      )}
-
-      {likedAlbums && likedAlbums.length > 0 && (
-        <section>
-          <div className="flex items-center gap-3 mb-6">
-            <Album className="w-6 h-6 text-[#1db954]" />
-            <h3 className="text-2xl font-bold text-white">Liked Albums</h3>
-            <span className="text-sm text-gray-500">
-              ({likedAlbums.length})
-            </span>
-          </div>
-
-          <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
-            {likedAlbums.map((album) => (
-              <div
-                key={album.id}
-                className="group cursor-pointer"
-                onClick={() => navigate(`/collection/album/${album.id}`)}
-              >
-                <div className="relative aspect-square rounded-lg overflow-hidden bg-[#181818] mb-3 shadow-md group-hover:shadow-xl transition-all">
-                  <img
-                    src={
-                      album.cover ? `${baseURL}/${album.cover}` : "/favicon.png"
-                    }
-                    alt={album.title}
-                    className="w-full h-full object-cover"
-                    onError={(e) => {
-                      (e.target as HTMLImageElement).src = "/favicon.png";
-                    }}
-                  />
-
-                  <button
-                    onClick={(e) => {
-                      e.stopPropagation();
-                      handleLike(album.id, album.title);
-                    }}
-                    className="absolute top-2 right-2 p-2 bg-black/70 hover:bg-black/90 rounded-full shadow-md transition-all duration-200 opacity-0 group-hover:opacity-100 cursor-pointer"
-                    title={album.isLikedByCurrentUser ? "Unlike" : "Like"}
-                  >
-                    <svg
-                      className="w-5 h-5"
-                      fill={album.isLikedByCurrentUser ? "#ef4444" : "none"}
-                      stroke={
-                        album.isLikedByCurrentUser ? "#ef4444" : "#9ca3af"
-                      }
-                      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>
-                <p className="font-semibold text-sm text-white truncate group-hover:text-[#1db954] transition-colors">
-                  {album.title}
-                </p>
-                <p className="text-xs text-gray-400 truncate mt-1">
-                  {album.releasedBy}
-                </p>
-              </div>
-            ))}
-          </div>
-        </section>
-      )}
-
-      {likedEntities &&
-        likedEntities.length === 0 &&
-        (!createdItems || createdItems.length === 0) &&
-        (!savedItems || savedItems.length === 0) && (
-          <div className="flex flex-col items-center justify-center py-16 text-gray-500">
-            <Music className="w-20 h-20 mb-4 opacity-20" />
-            <p className="text-lg font-medium">Nothing here yet</p>
-            <p className="text-sm mt-2">
-              Start exploring music to build your collection
-            </p>
-          </div>
-        )}
-    </div>
-  );
-};
-
-export default ListenerView;
Index: frontend/src/components/userProfile/UserListModal.tsx
===================================================================
--- frontend/src/components/userProfile/UserListModal.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,98 +1,0 @@
-import { useEffect } from "react";
-import { useNavigate } from "react-router-dom";
-import { baseURL } from "../../api/axiosInstance";
-import { useAuth } from "../../context/authContext";
-import type { BaseNonAdminUser } from "../../utils/types";
-
-interface ModalProps {
-	title: string;
-	users: BaseNonAdminUser[];
-	onClose: () => void;
-	onFollowToggle: (targetUsername: string) => Promise<void>;
-}
-
-const UserListModal = ({
-	title,
-	users,
-	onClose,
-	onFollowToggle,
-}: ModalProps) => {
-	const navigate = useNavigate();
-	const { user } = useAuth();
-	useEffect(() => {
-		document.body.style.overflow = "hidden";
-		return () => {
-			document.body.style.overflow = "";
-		};
-	}, []);
-
-	return (
-		<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm">
-			<div className="bg-[#1a1a2e] border border-white/10 rounded-xl shadow-2xl w-full max-w-md max-h-[70vh] flex flex-col">
-				<div className="p-4 border-b border-white/10 flex justify-between items-center">
-					<h2 className="text-xl font-bold text-white">{title}</h2>
-					<button
-						onClick={onClose}
-						className="text-gray-400 hover:text-white text-2xl cursor-pointer transition-colors"
-					>
-						&times;
-					</button>
-				</div>
-
-				<div className="overflow-y-auto p-4 flex-1">
-					{users.length === 0 ? (
-						<p className="text-center text-gray-500 py-8">No users found.</p>
-					) : (
-						users.map((u) => (
-							<div
-								key={u.username}
-								className="flex items-center justify-between p-3 hover:bg-white/5 rounded-lg transition-colors"
-							>
-								<div
-									className="flex items-center gap-4 cursor-pointer flex-1"
-									onClick={() => {
-										onClose();
-										navigate(`/users/${u.username}`);
-									}}
-								>
-									<div className="w-10 h-10 rounded-full bg-[#282828] overflow-hidden shrink-0 flex items-center justify-center">
-										{u.profilePhoto ? (
-											<img
-												src={`${baseURL}/${u.profilePhoto}`}
-												className="w-full h-full object-cover"
-												alt=""
-											/>
-										) : (
-											<span className="text-[#1db954] font-bold">
-												{u.fullName.charAt(0)}
-											</span>
-										)}
-									</div>
-									<div>
-										<p className="font-semibold text-white">{u.fullName}</p>
-										<p className="text-sm text-gray-400">@{u.username}</p>
-									</div>
-								</div>
-								{user && user.username !== u.username && (
-									<button
-										onClick={() => onFollowToggle(u.username)}
-										className={`px-4 py-1.5 text-sm font-medium rounded-full transition-colors cursor-pointer ${
-											u.isFollowedByCurrentUser
-												? "bg-white/10 text-white hover:bg-white/20"
-												: "bg-[#1db954] text-black hover:bg-[#1ed760]"
-										}`}
-									>
-										{u.isFollowedByCurrentUser ? "Following" : "Follow"}
-									</button>
-								)}
-							</div>
-						))
-					)}
-				</div>
-			</div>
-			<div className="absolute inset-0 -z-10" onClick={onClose}></div>
-		</div>
-	);
-};
-
-export default UserListModal;
Index: frontend/src/context/authContext.tsx
===================================================================
--- frontend/src/context/authContext.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,63 +1,0 @@
-import {
-	createContext,
-	useContext,
-	useEffect,
-	useState,
-	type Dispatch,
-	type ReactNode,
-	type SetStateAction,
-} from "react";
-import axiosInstance, {
-	refreshTokenMethod,
-	scheduleTokenRefresh,
-} from "../api/axiosInstance";
-import { type User } from "../utils/types";
-
-interface AuthContextType {
-	user: User | undefined;
-	setUser: Dispatch<SetStateAction<User | undefined>>;
-	isAuthLoading: boolean;
-}
-
-const AuthContext = createContext<AuthContextType>({
-	user: undefined,
-	setUser: () => {},
-	isAuthLoading: false,
-});
-
-interface AuthProviderProps {
-	children: ReactNode;
-}
-
-export const AuthProvider = ({ children }: AuthProviderProps) => {
-	const [user, setUser] = useState<User | undefined>(undefined);
-	const [isAuthLoading, setIsAuthLoading] = useState(true);
-
-	useEffect(() => {
-		const fetchUserDetails = async () => {
-			try {
-				await refreshTokenMethod();
-				const response = await axiosInstance.get<{
-					tokenExpiresIn: number;
-					user: User;
-				}>("/auth/user");
-				setUser(response.data.user);
-				scheduleTokenRefresh(response.data.tokenExpiresIn);
-			} catch (error) {
-				setUser(undefined);
-			} finally {
-				setIsAuthLoading(false);
-			}
-		};
-
-		fetchUserDetails();
-	}, []);
-
-	return (
-		<AuthContext.Provider value={{ user, setUser, isAuthLoading }}>
-			{children}
-		</AuthContext.Provider>
-	);
-};
-
-export const useAuth = () => useContext(AuthContext);
Index: frontend/src/context/playerContext.tsx
===================================================================
--- frontend/src/context/playerContext.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,70 +1,0 @@
-import {
-	createContext,
-	useCallback,
-	useContext,
-	useState,
-	type ReactNode,
-} from "react";
-
-export interface PlayerSong {
-	id: number;
-	title: string;
-	artist: string;
-	cover?: string | null;
-	embedUrl: string;
-}
-
-interface PlayerContextType {
-	currentSong: PlayerSong | null;
-	isMinimized: boolean;
-	play: (song: PlayerSong) => void;
-	stop: () => void;
-	toggleMinimize: () => void;
-	isPlaying: boolean;
-}
-
-const PlayerContext = createContext<PlayerContextType>({
-	currentSong: null,
-	isMinimized: false,
-	isPlaying: false,
-	play: () => {},
-	stop: () => {},
-	toggleMinimize: () => {},
-});
-
-export const PlayerProvider = ({ children }: { children: ReactNode }) => {
-	const [currentSong, setCurrentSong] = useState<PlayerSong | null>(null);
-	const [isMinimized, setIsMinimized] = useState(true);
-	const [isPlaying, setIsPlaying] = useState(false);
-
-	const play = useCallback((song: PlayerSong) => {
-		setCurrentSong(song);
-		setIsPlaying(true);
-	}, []);
-
-	const stop = useCallback(() => {
-		setIsPlaying(false);
-		setCurrentSong(null);
-	}, []);
-
-	const toggleMinimize = useCallback(() => {
-		setIsMinimized((prev) => !prev);
-	}, []);
-
-	return (
-		<PlayerContext.Provider
-			value={{
-				currentSong,
-				isMinimized,
-				isPlaying,
-				play,
-				stop,
-				toggleMinimize,
-			}}
-		>
-			{children}
-		</PlayerContext.Provider>
-	);
-};
-
-export const usePlayer = () => useContext(PlayerContext);
Index: frontend/src/context/playlistContext.tsx
===================================================================
--- frontend/src/context/playlistContext.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,78 +1,0 @@
-import {
-  createContext,
-  useContext,
-  useEffect,
-  useState,
-  type Dispatch,
-  type ReactNode,
-  type SetStateAction,
-} from "react";
-import type { BasicPlaylist } from "../utils/types";
-import axiosInstance from "../api/axiosInstance";
-import { toast } from "react-toastify";
-import { getErrorMessage } from "../utils/error";
-import { useAuth } from "./authContext";
-interface PlaylistContextType {
-  createdPlaylists: BasicPlaylist[] | undefined;
-  setCreatedPlaylists: Dispatch<SetStateAction<BasicPlaylist[] | undefined>>;
-  isLoading: boolean;
-  refreshPlaylists: (addedSong: boolean) => Promise<void>;
-}
-
-interface PlaylistProviderProps {
-  children: ReactNode;
-}
-
-const PlaylistContext = createContext<PlaylistContextType>({
-  createdPlaylists: undefined,
-  setCreatedPlaylists: () => {},
-  isLoading: false,
-  refreshPlaylists: async (addedSong: boolean) => {},
-});
-
-const PlaylistProvider = ({ children }: PlaylistProviderProps) => {
-  const { user } = useAuth();
-  const [createdPlaylists, setCreatedPlaylists] = useState<
-    BasicPlaylist[] | undefined
-  >(undefined);
-  const [isLoading, setIsLoading] = useState(false);
-
-  const fetchCreatedPlaylists = async (addedSong: boolean) => {
-    if (!addedSong) {
-      setIsLoading(true);
-    }
-    try {
-      const data = await axiosInstance.get<BasicPlaylist[]>("/playlists/user");
-      setCreatedPlaylists(data.data);
-    } catch (error: any) {
-      toast.error(getErrorMessage(error));
-    } finally {
-      setIsLoading(false);
-    }
-  };
-
-  useEffect(() => {
-    if (user) {
-      fetchCreatedPlaylists(false);
-    } else {
-      setCreatedPlaylists(undefined);
-    }
-  }, [user]);
-
-  return (
-    <PlaylistContext.Provider
-      value={{
-        createdPlaylists,
-        setCreatedPlaylists,
-        isLoading,
-        refreshPlaylists: fetchCreatedPlaylists,
-      }}
-    >
-      {children}
-    </PlaylistContext.Provider>
-  );
-};
-
-export const useCreatedPlaylists = () => useContext(PlaylistContext);
-
-export default PlaylistProvider;
Index: frontend/src/main.tsx
===================================================================
--- frontend/src/main.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ frontend/src/main.tsx	(revision 15ec67f0faa204c0c5d0e1f4d4979ee8ff4fcd4a)
@@ -2,18 +2,9 @@
 import { createRoot } from "react-dom/client";
 import App from "./App.tsx";
-import { AuthProvider } from "./context/authContext.tsx";
-import { PlayerProvider } from "./context/playerContext.tsx";
 import "./index.css";
-import PlaylistProvider from "./context/playlistContext.tsx";
 
 createRoot(document.getElementById("root")!).render(
-  <StrictMode>
-    <AuthProvider>
-      <PlayerProvider>
-        <PlaylistProvider>
-          <App />
-        </PlaylistProvider>
-      </PlayerProvider>
-    </AuthProvider>
-  </StrictMode>,
+	<StrictMode>
+		<App />
+	</StrictMode>,
 );
Index: frontend/src/pages/AllUsers.tsx
===================================================================
--- frontend/src/pages/AllUsers.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,89 +1,0 @@
-import React, { useEffect, useState } from "react";
-import { useNavigate } from "react-router-dom";
-import axiosInstance from "../api/axiosInstance";
-import LoadingSpinner from "../components/LoadingSpinner";
-
-interface User {
-	username: string;
-	fullName: string;
-}
-
-const AllUsers = () => {
-	const [users, setUsers] = useState<User[]>([]);
-	const [searchedUser, setSearchedUser] = useState<string>("");
-	const [error, setError] = useState<string | null>(null);
-	const navigate = useNavigate();
-
-	useEffect(() => {
-		const fetchUsers = async () => {
-			const response = axiosInstance.get("/users/na/all");
-			setUsers((await response).data);
-		};
-		fetchUsers();
-	}, []);
-
-	const handleUserClick = (username: string) => {
-		navigate(`/users/${username}`);
-	};
-
-	const handleSearch = async (e: React.FormEvent) => {
-		e.preventDefault();
-		try {
-			const response = await axiosInstance.get(`/users/na/search`, {
-				params: { name: searchedUser },
-			});
-			setUsers(response.data);
-		} catch (err: any) {
-			const errorMessage = err.response?.data?.error || "Search failed";
-			setError(errorMessage);
-		}
-	};
-
-	if (users.length == 0) {
-		return <LoadingSpinner />;
-	}
-	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>
-		);
-	}
-
-	return (
-		<div className="container mx-auto p-6">
-			<h1 className="text-3xl font-bold mb-6">All Users</h1>
-			<form onSubmit={handleSearch} className="flex gap-2 mb-10">
-				<input
-					type="text"
-					value={searchedUser}
-					onChange={(e) => setSearchedUser(e.target.value)}
-					className="border p-2 rounded w-full"
-					placeholder="Search for a user..."
-				/>
-				<button
-					type="submit"
-					className="bg-blue-600 text-white px-6 py-2 rounded hover:bg-blue-700 transition-colors"
-				>
-					Search
-				</button>
-			</form>
-
-			<div className="grid gap-4">
-				{users.map((u) => (
-					<div
-						key={u.username}
-						onClick={() => handleUserClick(u.username)}
-						className="bg-white shadow-md rounded-lg p-4 hover:shadow-lg hover:bg-gray-50 cursor-pointer transition-all"
-					>
-						<h2 className="text-xl font-semibold">{u.fullName}</h2>
-						<p className="text-gray-600">@{u.username}</p>
-					</div>
-				))}
-			</div>
-		</div>
-	);
-};
-
-export default AllUsers;
Index: frontend/src/pages/LandingPage.tsx
===================================================================
--- frontend/src/pages/LandingPage.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,504 +1,0 @@
-import { useEffect, useState } from "react";
-import { useNavigate } from "react-router-dom";
-import axiosInstance, { baseURL } from "../api/axiosInstance";
-import PlaylistDropdown from "../components/playlist/PlaylistDropdown";
-import AlbumResult from "../components/search/AlbumResult";
-import SongResult from "../components/search/SongResult";
-import UserResult from "../components/search/UserResult";
-import { useAuth } from "../context/authContext";
-import { usePlayer } from "../context/playerContext";
-import type {
-	Album,
-	BaseNonAdminUser,
-	SearchCategory,
-	Song,
-} from "../utils/types";
-import { toEmbedUrl } from "../utils/utils";
-
-const CATEGORIES: { value: SearchCategory; label: string }[] = [
-	{ value: "songs", label: "Songs" },
-	{ value: "albums", label: "Albums" },
-	{ value: "artists", label: "Artists" },
-	{ value: "users", label: "Users" },
-];
-
-const LandingPage = () => {
-	const navigate = useNavigate();
-	const { play, currentSong } = usePlayer();
-	const { user } = useAuth();
-	const [songs, setSongs] = useState<Song[]>([]);
-	const [loading, setLoading] = useState<boolean>(true);
-
-	const [searchInput, setSearchInput] = useState("");
-	const [activeQuery, setActiveQuery] = useState("");
-	const [searchCategory, setSearchCategory] = useState<SearchCategory>("songs");
-	const [searchResults, setSearchResults] = useState<unknown[]>([]);
-	const [searchLoading, setSearchLoading] = useState(false);
-	const [hasSearched, setHasSearched] = useState(false);
-
-	const [openPlaylistDropdown, setOpenPlaylistDropdown] = useState<
-		number | null
-	>(null);
-
-	useEffect(() => {
-		const fetchSongs = async () => {
-			try {
-				const response = await axiosInstance.get("/songs/top");
-				setSongs(response.data);
-			} catch (error) {
-				console.error("Error fetching songs:", error);
-			} finally {
-				setLoading(false);
-			}
-		};
-		fetchSongs();
-	}, []);
-
-	const toggleLike = async (songId: number) => {
-		try {
-			await axiosInstance.post(`/musical-entity/${songId}/like`);
-			setSongs((prevSongs) =>
-				prevSongs.map((song) =>
-					song.id === songId
-						? { ...song, isLikedByCurrentUser: !song.isLikedByCurrentUser }
-						: song,
-				),
-			);
-		} catch (error) {
-			console.error("Error toggling like:", error);
-		}
-	};
-
-	const togglePlaylistDropdown = (songId: number) => {
-		if (openPlaylistDropdown === songId) {
-			setOpenPlaylistDropdown(null);
-		} else {
-			setOpenPlaylistDropdown(songId);
-		}
-	};
-
-	const performSearch = async (query: string, category: SearchCategory) => {
-		if (!query.trim()) return;
-
-		setSearchLoading(true);
-		setHasSearched(true);
-		setActiveQuery(query);
-		setSearchCategory(category);
-
-		try {
-			let endpoint = "";
-			switch (category) {
-				case "songs":
-					endpoint = `/songs/search?q=${encodeURIComponent(query)}`;
-					break;
-				case "albums":
-					endpoint = `/albums/search?q=${encodeURIComponent(query)}`;
-					break;
-				case "artists":
-					endpoint = `/users/search?type=ARTIST&q=${encodeURIComponent(query)}`;
-					break;
-				case "users":
-					endpoint = `/users/search?type=LISTENER&q=${encodeURIComponent(query)}`;
-					break;
-			}
-
-			const response = await axiosInstance.get(endpoint);
-			setSearchResults(response.data);
-		} catch (error) {
-			console.error("Search error:", error);
-			setSearchResults([]);
-		} finally {
-			setSearchLoading(false);
-		}
-	};
-
-	const handleSearch = () => {
-		performSearch(searchInput, searchCategory);
-	};
-
-	const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
-		if (e.key === "Enter") {
-			handleSearch();
-		}
-	};
-
-	const handleCategorySwitch = (category: SearchCategory) => {
-		performSearch(activeQuery, category);
-	};
-
-	const clearSearch = () => {
-		setSearchInput("");
-		setActiveQuery("");
-		setHasSearched(false);
-		setSearchResults([]);
-	};
-
-	const renderResults = () => {
-		if (searchLoading) {
-			return (
-				<div className="flex justify-center py-12">
-					<div className="w-10 h-10 border-4 border-white/10 border-t-[#1db954] rounded-full animate-spin"></div>
-				</div>
-			);
-		}
-
-		if (searchResults.length === 0) {
-			return (
-				<div className="text-center py-12 text-gray-400">
-					<p className="text-lg">
-						No {searchCategory} found for "{activeQuery}"
-					</p>
-				</div>
-			);
-		}
-
-		return (
-			<div className="divide-y divide-white/5">
-				{searchResults.map((result, index) => {
-					switch (searchCategory) {
-						case "songs":
-							return (
-								<SongResult key={(result as Song).id} song={result as Song} />
-							);
-						case "albums":
-							return (
-								<AlbumResult
-									key={(result as Album).id}
-									album={result as Album}
-								/>
-							);
-						case "artists":
-							return (
-								<UserResult
-									key={(result as BaseNonAdminUser).username ?? index}
-									user={result as BaseNonAdminUser}
-									label="Artist"
-								/>
-							);
-						case "users":
-							return (
-								<UserResult
-									key={(result as BaseNonAdminUser).username ?? index}
-									user={result as BaseNonAdminUser}
-									label="User"
-								/>
-							);
-					}
-				})}
-			</div>
-		);
-	};
-
-	return (
-		<div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] text-white flex">
-			<div className="flex-1">
-				<div className="p-8">
-					<div className="max-w-7xl mx-auto">
-						{/* Search Bar */}
-						<div className="mb-8 flex flex-col md:flex-row gap-3">
-							<div className="flex flex-1 gap-0">
-								{/* Category Dropdown */}
-								<select
-									value={searchCategory}
-									onChange={(e) =>
-										setSearchCategory(e.target.value as SearchCategory)
-									}
-									className="bg-[#282828] border border-white/10 border-r-0 rounded-l-full py-2 px-4 text-white text-sm focus:outline-none focus:border-[#1db954] appearance-none cursor-pointer"
-								>
-									{CATEGORIES.map((cat) => (
-										<option key={cat.value} value={cat.value}>
-											{cat.label}
-										</option>
-									))}
-								</select>
-
-								{/* Search Input */}
-								<input
-									type="text"
-									placeholder={`Search ${searchCategory}...`}
-									value={searchInput}
-									onChange={(e) => setSearchInput(e.target.value)}
-									onKeyDown={handleKeyDown}
-									className="flex-1 bg-[#282828] border border-white/10 border-r-0 py-2 px-4 text-white focus:outline-none focus:border-[#1db954] focus:ring-1 focus:ring-[#1db954] transition-all"
-								/>
-
-								{/* Search Button */}
-								<button
-									onClick={handleSearch}
-									className="bg-[#1db954] hover:bg-[#1ed760] text-black font-medium px-6 rounded-r-full transition-colors flex items-center gap-2 cursor-pointer"
-								>
-									<svg
-										className="w-5 h-5"
-										fill="none"
-										stroke="currentColor"
-										viewBox="0 0 24 24"
-									>
-										<path
-											strokeLinecap="round"
-											strokeLinejoin="round"
-											strokeWidth={2}
-											d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
-										/>
-									</svg>
-									<span className="hidden sm:inline">Search</span>
-								</button>
-							</div>
-						</div>
-
-						{/* Search Results Section */}
-						{hasSearched ? (
-							<div>
-								<div className="flex items-center justify-between mb-4">
-									<h2 className="text-2xl font-bold text-white">
-										Results for "{activeQuery}"
-									</h2>
-									<button
-										onClick={clearSearch}
-										className="text-sm text-gray-400 hover:text-white transition-colors"
-									>
-										Clear search
-									</button>
-								</div>
-
-								{/* Quick category switch buttons */}
-								<div className="flex gap-2 mb-6">
-									{CATEGORIES.map((cat) => (
-										<button
-											key={cat.value}
-											onClick={() => handleCategorySwitch(cat.value)}
-											className={`px-4 py-1.5 rounded-full text-sm font-medium transition-colors cursor-pointer ${
-												searchCategory === cat.value
-													? "bg-[#1db954] text-black"
-													: "bg-white/10 text-white hover:bg-white/20"
-											}`}
-										>
-											{cat.label}
-										</button>
-									))}
-								</div>
-
-								{/* Results list */}
-								<div className="bg-[#1a1a2e]/50 rounded-xl overflow-hidden">
-									{renderResults()}
-								</div>
-							</div>
-						) : (
-							/* Default song grid */
-							<>
-								<div className="mb-8 border-b border-white/10 pb-6">
-									<h1 className="text-5xl font-bold mb-3 pb-1 bg-linear-to-r from-[#1db954] to-[#1ed760] bg-clip-text text-transparent">
-										Top Songs
-									</h1>
-									<p className="text-xl text-gray-400">
-										Listen to the newest tracks on FinkWave
-									</p>
-								</div>
-
-								{loading ? (
-									<div className="flex flex-col items-center justify-center min-h-[40vh] gap-6">
-										<div className="w-12 h-12 border-4 border-white/10 border-t-[#1db954] rounded-full animate-spin"></div>
-										<p className="text-xl text-gray-400">Loading songs...</p>
-									</div>
-								) : (
-									<div className="grid grid-cols-[repeat(auto-fill,minmax(220px,1fr))] gap-8 py-4">
-										{songs.map((song) => (
-											<div
-												key={song.id}
-												onClick={() => navigate(`/songs/${song.id}`)}
-												onMouseEnter={() => {
-													if (
-														openPlaylistDropdown !== null &&
-														openPlaylistDropdown !== song.id
-													) {
-														setOpenPlaylistDropdown(null);
-													}
-												}}
-												className="bg-[#282828] rounded-xl cursor-pointer shadow-lg transition-all duration-300 ease-in-out hover:-translate-y-2 hover:shadow-2xl group relative"
-											>
-												<div className="relative w-full pt-[100%] overflow-hidden bg-[#181818] rounded-t-xl">
-													<img
-														src={
-															song.cover
-																? `${baseURL}/${song.cover}`
-																: "/favicon.png"
-														}
-														alt={song.title}
-														className="absolute top-0 left-0 w-full h-full object-cover"
-														onError={(e) => {
-															(e.target as HTMLImageElement).src =
-																"/favicon.png";
-														}}
-													/>
-													<div className="absolute top-0 left-0 w-full h-full bg-black/60 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-300">
-														{song.link ? (
-															<button
-																onClick={(e) => {
-																	e.stopPropagation();
-																	play({
-																		id: song.id,
-																		title: song.title,
-																		artist: song.releasedBy,
-																		cover: song.cover,
-																		embedUrl: toEmbedUrl(song.link!),
-																	});
-																}}
-																className={`w-14 h-14 rounded-full flex items-center justify-center text-xl shadow-[0_4px_12px_rgba(29,185,84,0.5)] transition-all cursor-pointer ${
-																	currentSong?.id === song.id
-																		? "bg-white text-[#1db954]"
-																		: "bg-[#1db954] text-black hover:scale-105"
-																}`}
-																aria-label={
-																	currentSong?.id === song.id
-																		? "Now playing"
-																		: "Play song"
-																}
-															>
-																{currentSong?.id === song.id ? (
-																	<svg
-																		className="w-6 h-6"
-																		fill="currentColor"
-																		viewBox="0 0 24 24"
-																	>
-																		<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z" />
-																	</svg>
-																) : (
-																	<svg
-																		className="w-6 h-6"
-																		fill="currentColor"
-																		viewBox="0 0 24 24"
-																	>
-																		<path d="M8 5v14l11-7z" />
-																	</svg>
-																)}
-															</button>
-														) : (
-															<div className="w-14 h-14 rounded-full bg-[#1db954] flex items-center justify-center text-xl text-black shadow-[0_4px_12px_rgba(29,185,84,0.5)]">
-																▶
-															</div>
-														)}
-													</div>
-												</div>
-												<div className="p-4">
-													<h3 className="text-lg font-semibold mb-2 text-white overflow-hidden text-ellipsis whitespace-nowrap">
-														{song.title}
-													</h3>
-													{song.album && (
-														<p
-															onClick={(e) => {
-																e.stopPropagation();
-																if (song.albumId) {
-																	navigate(`/collection/album/${song.albumId}`);
-																}
-															}}
-															className={`text-sm text-gray-400 mb-3 overflow-hidden text-ellipsis whitespace-nowrap ${
-																song.albumId
-																	? "hover:underline cursor-pointer hover:text-white"
-																	: ""
-															}`}
-														>
-															{song.album}
-														</p>
-													)}
-													<p
-														onClick={(e) => {
-															e.stopPropagation();
-															if (song.artistUsername) {
-																navigate(`/users/${song.artistUsername}`);
-															}
-														}}
-														className={`text-sm text-gray-400 mb-3 overflow-hidden text-ellipsis whitespace-nowrap ${
-															song.artistUsername
-																? "hover:underline cursor-pointer hover:text-white"
-																: ""
-														}`}
-													>
-														{song.releasedBy}
-													</p>
-													{user && (
-														<div className="flex items-center justify-between mt-4 pt-3 border-t border-white/10">
-															{/* Like button */}
-															<button
-																onClick={(e) => {
-																	e.stopPropagation();
-																	toggleLike(song.id);
-																}}
-																className="text-gray-400 hover:text-[#1db954] transition-colors cursor-pointer"
-																aria-label={
-																	song.isLikedByCurrentUser
-																		? "Unlike song"
-																		: "Like song"
-																}
-															>
-																{song.isLikedByCurrentUser ? (
-																	<svg
-																		className="w-6 h-6 fill-[#1db954]"
-																		viewBox="0 0 24 24"
-																	>
-																		<path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
-																	</svg>
-																) : (
-																	<svg
-																		className="w-6 h-6"
-																		fill="none"
-																		stroke="currentColor"
-																		viewBox="0 0 24 24"
-																	>
-																		<path
-																			strokeLinecap="round"
-																			strokeLinejoin="round"
-																			strokeWidth={2}
-																			d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
-																		/>
-																	</svg>
-																)}
-															</button>
-
-															{/* Add to playlist button */}
-															<div className="relative">
-																<button
-																	onClick={(e) => {
-																		e.stopPropagation();
-																		togglePlaylistDropdown(song.id);
-																	}}
-																	className="text-gray-400 hover:text-[#1db954] transition-colors cursor-pointer"
-																	aria-label="Add to playlist"
-																>
-																	<svg
-																		className="w-6 h-6"
-																		fill="none"
-																		stroke="currentColor"
-																		viewBox="0 0 24 24"
-																	>
-																		<path
-																			strokeLinecap="round"
-																			strokeLinejoin="round"
-																			strokeWidth={2}
-																			d="M12 4v16m8-8H4"
-																		/>
-																	</svg>
-																</button>
-
-																<PlaylistDropdown
-																	songId={song.id}
-																	isOpen={openPlaylistDropdown === song.id}
-																	onClose={() => setOpenPlaylistDropdown(null)}
-																	direction="above"
-																/>
-															</div>
-														</div>
-													)}
-												</div>
-											</div>
-										))}
-									</div>
-								)}
-							</>
-						)}
-					</div>
-				</div>
-			</div>
-		</div>
-	);
-};
-
-export default LandingPage;
Index: frontend/src/pages/Login.tsx
===================================================================
--- frontend/src/pages/Login.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,109 +1,0 @@
-import { useState } from "react";
-import { Link, useNavigate } from "react-router-dom";
-import { toast } from "react-toastify";
-import axiosInstance, { scheduleTokenRefresh } from "../api/axiosInstance";
-import { useAuth } from "../context/authContext";
-import type { User } from "../utils/types";
-
-const Login = () => {
-	const [username, setUsername] = useState("");
-	const [password, setPassword] = useState("");
-	const [error, setError] = useState<string | null>(null);
-	const { setUser } = useAuth();
-	const navigate = useNavigate();
-
-	const handleLogin = async (e: React.FormEvent) => {
-		e.preventDefault();
-		try {
-			const response = await axiosInstance.post<{
-				user: User;
-				tokenExpiresIn: number;
-			}>("/auth/login", { username, password });
-			scheduleTokenRefresh(response.data.tokenExpiresIn);
-			setUser(response.data.user);
-			navigate("/");
-			toast.success("Login successful!");
-		} catch (error: any) {
-			const errorMessage =
-				error.response?.data?.error ||
-				"Login failed. Please check your credentials.";
-			setError(`Login failed: ${errorMessage}`);
-		}
-	};
-	return (
-		<div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] flex items-center justify-center px-4">
-			<div className="w-full max-w-md">
-				<div className="text-center mb-8">
-					<h1 className="text-4xl font-extrabold text-white mb-2">
-						Welcome Back
-					</h1>
-					<p className="text-gray-400">Log in to continue to FinkWave</p>
-				</div>
-
-				<form
-					onSubmit={handleLogin}
-					className="bg-[#181818] rounded-xl p-8 space-y-6"
-				>
-					{error && (
-						<div className="bg-red-500/10 border border-red-500/20 rounded-lg p-3">
-							<p className="text-red-400 text-sm">{error}</p>
-						</div>
-					)}
-
-					<div>
-						<label
-							className="block text-sm font-medium text-gray-300 mb-2"
-							htmlFor="username"
-						>
-							Username
-						</label>
-						<input
-							type="text"
-							id="username"
-							className="w-full bg-[#282828] border border-white/10 rounded-lg py-3 px-4 text-white placeholder-gray-500 focus:outline-none focus:border-[#1db954] focus:ring-1 focus:ring-[#1db954] transition-all"
-							placeholder="Enter your username"
-							value={username}
-							onChange={(e) => setUsername(e.target.value)}
-						/>
-					</div>
-
-					<div>
-						<label
-							className="block text-sm font-medium text-gray-300 mb-2"
-							htmlFor="password"
-						>
-							Password
-						</label>
-						<input
-							type="password"
-							id="password"
-							className="w-full bg-[#282828] border border-white/10 rounded-lg py-3 px-4 text-white placeholder-gray-500 focus:outline-none focus:border-[#1db954] focus:ring-1 focus:ring-[#1db954] transition-all"
-							placeholder="Enter your password"
-							value={password}
-							onChange={(e) => setPassword(e.target.value)}
-						/>
-					</div>
-
-					<button
-						type="submit"
-						className="w-full py-3 bg-[#1db954] rounded-full text-black font-semibold hover:bg-[#1ed760] transition-colors cursor-pointer"
-					>
-						Log In
-					</button>
-
-					<p className="text-center text-sm text-gray-400">
-						Don't have an account?{" "}
-						<Link
-							to="/register"
-							className="text-[#1db954] hover:underline font-medium"
-						>
-							Sign up
-						</Link>
-					</p>
-				</form>
-			</div>
-		</div>
-	);
-};
-
-export default Login;
Index: frontend/src/pages/MusicalCollection.tsx
===================================================================
--- frontend/src/pages/MusicalCollection.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,257 +1,0 @@
-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<CollectionView | null>(null);
-  const [isLoading, setIsLoading] = useState(true);
-  const [error, setError] = useState<string | null>(null);
-  const [openDropdownSongId, setOpenDropdownSongId] = useState<number | null>(
-    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 (
-      <div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] flex items-center justify-center">
-        <div className="flex flex-col items-center gap-4">
-          <div className="w-12 h-12 border-4 border-white/10 border-t-[#1db954] rounded-full animate-spin" />
-          <p className="text-gray-400 text-lg">Loading collection…</p>
-        </div>
-      </div>
-    );
-  }
-
-  if (error) {
-    return (
-      <div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] flex items-center justify-center">
-        <div className="text-center">
-          <p className="text-red-400 text-xl mb-4">{error}</p>
-          <Link to="/" className="text-[#1db954] hover:underline text-sm">
-            ← Back to Home
-          </Link>
-        </div>
-      </div>
-    );
-  }
-
-  if (!collection) return null;
-
-  return (
-    <div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] text-white">
-      <div className="max-w-5xl mx-auto px-6 py-10">
-        {/* Back link */}
-        <Link
-          to="/"
-          className="inline-flex items-center gap-1 text-gray-400 hover:text-white text-sm mb-8 transition-colors"
-        >
-          <svg
-            className="w-4 h-4"
-            fill="none"
-            stroke="currentColor"
-            viewBox="0 0 24 24"
-          >
-            <path
-              strokeLinecap="round"
-              strokeLinejoin="round"
-              strokeWidth={2}
-              d="M15 19l-7-7 7-7"
-            />
-          </svg>
-          Back to Home
-        </Link>
-
-        {/* Hero section */}
-        <div className="flex flex-col md:flex-row gap-8 mb-10">
-          {/* Cover art */}
-          <div className="w-full md:w-72 shrink-0">
-            <div className="relative w-full pt-[100%] rounded-xl overflow-hidden shadow-2xl bg-[#181818]">
-              <img
-                src={
-                  collection.cover
-                    ? `${baseURL}/${collection.cover}`
-                    : "/favicon.png"
-                }
-                alt={collection.title}
-                className="absolute inset-0 w-full h-full object-cover"
-                onError={(e) => {
-                  (e.target as HTMLImageElement).src = "/favicon.png";
-                }}
-              />
-            </div>
-          </div>
-
-          {/* Collection info */}
-          <div className="flex flex-col justify-end gap-3 min-w-0">
-            <span className="text-xs uppercase tracking-widest text-gray-400 font-medium">
-              {collection.genre ? `${collection.genre} • ` : ""}
-              {collection.type === "PLAYLIST" ? "Playlist" : "Album"}
-            </span>
-            <h1 className="text-4xl md:text-5xl font-extrabold leading-tight truncate">
-              {collection.title}
-            </h1>
-
-            <p className="text-xl text-gray-300 font-semibold">
-              {collection.releasedBy}
-            </p>
-
-            {collection.songs && (
-              <p className="text-sm text-gray-500">
-                {collection.songs.length} song
-                {collection.songs.length !== 1 ? "s" : ""}
-              </p>
-            )}
-
-            {/* Action buttons */}
-            <div className="flex items-center gap-3 mt-4">
-              {type === "album" && (
-                <button
-                  onClick={toggleCollectionLike}
-                  className={`flex items-center gap-2 px-5 py-3 rounded-full text-sm font-semibold transition-colors cursor-pointer ${
-                    collection.isLikedByCurrentUser
-                      ? "bg-[#1db954] text-black"
-                      : "bg-white/10 text-white hover:bg-white/20"
-                  }`}
-                >
-                  <svg
-                    className="w-5 h-5"
-                    fill={
-                      collection.isLikedByCurrentUser ? "currentColor" : "none"
-                    }
-                    stroke="currentColor"
-                    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>
-                  {collection.isLikedByCurrentUser ? "Liked" : "Like"}
-                </button>
-              )}
-            </div>
-          </div>
-        </div>
-
-        {/* Songs list */}
-        <div className="border-t border-white/10 pt-6">
-          <h2 className="text-2xl font-bold mb-4">Songs</h2>
-
-          {collection.songs && collection.songs.length > 0 ? (
-            <div className="space-y-1">
-              {collection.songs.map((song, index) => (
-                <SongItem
-                  key={song.id}
-                  song={song}
-                  index={index + 1}
-                  onLikeToggle={() => toggleLike(song.id)}
-                  isDropdownOpen={openDropdownSongId === song.id}
-                  onDropdownToggle={setOpenDropdownSongId}
-                />
-              ))}
-            </div>
-          ) : (
-            <div className="text-center py-12 text-gray-400">
-              <p className="text-lg">No songs available</p>
-            </div>
-          )}
-        </div>
-      </div>
-    </div>
-  );
-};
-
-export default MusicalCollection;
Index: frontend/src/pages/MySongs.tsx
===================================================================
--- frontend/src/pages/MySongs.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,257 +1,0 @@
-import { useEffect, useState } from "react";
-import { Link, useNavigate } from "react-router-dom";
-import axiosInstance, { baseURL } from "../api/axiosInstance";
-import { useAuth } from "../context/authContext";
-import type { CatalogItem } from "../utils/types";
-
-const MySongs = () => {
-	const { user } = useAuth();
-	const navigate = useNavigate();
-	const [artistCatalog, setArtistCatalog] = useState<CatalogItem[]>([]);
-	const [loading, setLoading] = useState(true);
-	const [activeTab, setActiveTab] = useState<"singles" | "albums">("singles");
-
-	useEffect(() => {
-		const fetchArtistCatalog = async () => {
-			try {
-				setLoading(true);
-				const response =
-					await axiosInstance.get<CatalogItem[]>("/songs/catalog");
-				const data = response.data;
-				setArtistCatalog(data);
-			} catch (error) {
-				console.error("Error fetching music:", error);
-			} finally {
-				setLoading(false);
-			}
-		};
-
-		if (user?.isArtist) {
-			fetchArtistCatalog();
-		}
-	}, [user]);
-
-	if (!user?.isArtist) {
-		return (
-			<div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] flex items-center justify-center">
-				<div className="text-center">
-					<p className="text-red-400 text-xl mb-4">
-						You need to be an artist to access this page.
-					</p>
-					<Link to="/" className="text-[#1db954] hover:underline text-sm">
-						← Back to Home
-					</Link>
-				</div>
-			</div>
-		);
-	}
-
-	if (loading) {
-		return (
-			<div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] flex items-center justify-center">
-				<div className="flex flex-col items-center gap-4">
-					<div className="w-12 h-12 border-4 border-white/10 border-t-[#1db954] rounded-full animate-spin" />
-					<p className="text-gray-400 text-lg">Loading your music…</p>
-				</div>
-			</div>
-		);
-	}
-
-	return (
-		<div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] text-white">
-			<div className="max-w-6xl mx-auto px-6 py-10">
-				{/* Header */}
-				<div className="flex flex-col md:flex-row md:items-center justify-between gap-4 mb-8">
-					<div>
-						<h1 className="text-4xl font-extrabold mb-2">My Music</h1>
-						<p className="text-gray-400">Manage your songs and albums</p>
-					</div>
-					<button
-						onClick={() => navigate("/publish")}
-						className="flex items-center gap-2 px-6 py-3 bg-[#1db954] text-black rounded-full font-semibold hover:bg-[#1ed760] hover:scale-105 transition-all cursor-pointer"
-					>
-						<svg
-							className="w-5 h-5"
-							fill="none"
-							stroke="currentColor"
-							viewBox="0 0 24 24"
-						>
-							<path
-								strokeLinecap="round"
-								strokeLinejoin="round"
-								strokeWidth={2}
-								d="M12 4v16m8-8H4"
-							/>
-						</svg>
-						Publish New
-					</button>
-				</div>
-
-				{/* Tabs */}
-				<div className="flex gap-1 mb-8 bg-[#181818] rounded-lg p-1 w-fit">
-					<button
-						onClick={() => setActiveTab("singles")}
-						className={`px-6 py-2.5 rounded-md text-sm font-medium transition-colors cursor-pointer ${
-							activeTab === "singles"
-								? "bg-[#282828] text-white"
-								: "text-gray-400 hover:text-white"
-						}`}
-					>
-						Singles (
-						{artistCatalog.filter((item) => item.type === "SONG").length})
-					</button>
-					<button
-						onClick={() => setActiveTab("albums")}
-						className={`px-6 py-2.5 rounded-md text-sm font-medium transition-colors cursor-pointer ${
-							activeTab === "albums"
-								? "bg-[#282828] text-white"
-								: "text-gray-400 hover:text-white"
-						}`}
-					>
-						Albums (
-						{artistCatalog.filter((item) => item.type === "ALBUM").length})
-					</button>
-				</div>
-
-				{/* Content */}
-				{activeTab === "singles" ? (
-					<div className="space-y-2">
-						{artistCatalog.filter((item) => item.type === "SONG").length ===
-						0 ? (
-							<div className="text-center py-16">
-								<svg
-									className="w-16 h-16 mx-auto text-gray-600 mb-4"
-									fill="none"
-									stroke="currentColor"
-									viewBox="0 0 24 24"
-								>
-									<path
-										strokeLinecap="round"
-										strokeLinejoin="round"
-										strokeWidth={1.5}
-										d="M9 19V6l12-3v13M9 19c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zm12-3c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zM9 10l12-3"
-									/>
-								</svg>
-								<p className="text-gray-400 text-lg mb-4">
-									You haven't published any singles yet
-								</p>
-								<button
-									onClick={() => navigate("/publish")}
-									className="text-[#1db954] hover:underline"
-								>
-									Publish your first song
-								</button>
-							</div>
-						) : (
-							artistCatalog
-								.filter((item) => item.type === "SONG")
-								.map((song, index) => (
-									<div
-										key={song.id}
-										className="flex items-center gap-4 p-4 rounded-lg hover:bg-white/5 transition-colors group"
-									>
-										<span className="w-8 text-center text-gray-500 text-sm">
-											{index + 1}
-										</span>
-										<img
-											src={
-												song.cover ? `${baseURL}/${song.cover}` : "/favicon.png"
-											}
-											alt={song.title}
-											className="w-12 h-12 rounded object-cover"
-											onError={(e) => {
-												(e.target as HTMLImageElement).src = "/favicon.png";
-											}}
-										/>
-										<div className="flex-1 min-w-0">
-											<Link
-												to={`/songs/${song.id}`}
-												className="text-white font-medium hover:underline truncate block"
-											>
-												{song.title}
-											</Link>
-											<p className="text-gray-400 text-sm">{song.genre}</p>
-										</div>
-										<p className="text-gray-400 text-sm">{song.releaseDate}</p>
-									</div>
-								))
-						)}
-					</div>
-				) : (
-					<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
-						{artistCatalog.filter((item) => item.type === "ALBUM").length ===
-						0 ? (
-							<div className="col-span-full text-center py-16">
-								<svg
-									className="w-16 h-16 mx-auto text-gray-600 mb-4"
-									fill="none"
-									stroke="currentColor"
-									viewBox="0 0 24 24"
-								>
-									<path
-										strokeLinecap="round"
-										strokeLinejoin="round"
-										strokeWidth={1.5}
-										d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"
-									/>
-								</svg>
-								<p className="text-gray-400 text-lg mb-4">
-									You haven't published any albums yet
-								</p>
-								<button
-									onClick={() => navigate("/publish")}
-									className="text-[#1db954] hover:underline"
-								>
-									Publish your first album
-								</button>
-							</div>
-						) : (
-							artistCatalog
-								.filter((item) => item.type === "ALBUM")
-								.map((album) => (
-									<Link
-										key={album.id}
-										to={`/collection/album/${album.id}`}
-										className="bg-[#181818] rounded-xl p-4 hover:bg-[#282828] transition-colors group"
-									>
-										<div className="relative w-full pt-[100%] rounded-lg overflow-hidden mb-4 bg-[#282828]">
-											<img
-												src={
-													album.cover
-														? `${baseURL}/${album.cover}`
-														: "/favicon.png"
-												}
-												alt={album.title}
-												className="absolute inset-0 w-full h-full object-cover"
-												onError={(e) => {
-													(e.target as HTMLImageElement).src = "/favicon.png";
-												}}
-											/>
-											<div className="absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
-												<div className="w-12 h-12 bg-[#1db954] rounded-full flex items-center justify-center shadow-xl transform translate-y-2 group-hover:translate-y-0 transition-transform">
-													<svg
-														className="w-6 h-6 text-black"
-														fill="currentColor"
-														viewBox="0 0 24 24"
-													>
-														<path d="M8 5v14l11-7z" />
-													</svg>
-												</div>
-											</div>
-										</div>
-										<h3 className="font-semibold text-white truncate mb-1">
-											{album.title}
-										</h3>
-										<p className="text-gray-400 text-sm">{album.genre}</p>
-										<p className="text-gray-400 text-sm">{album.releaseDate}</p>
-									</Link>
-								))
-						)}
-					</div>
-				)}
-			</div>
-		</div>
-	);
-};
-
-export default MySongs;
Index: frontend/src/pages/Nav.tsx
===================================================================
--- frontend/src/pages/Nav.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,156 +1,0 @@
-import { useEffect, useRef, useState } from "react";
-import { Link } from "react-router-dom";
-import { toast } from "react-toastify";
-import axiosInstance, { baseURL } from "../api/axiosInstance";
-import Logo from "../assets/logo-finkwave.png";
-import { useAuth } from "../context/authContext";
-
-interface NavProps {
-	isSidebarOpen?: boolean;
-	onToggleSidebar?: () => void;
-}
-
-const Nav = ({ isSidebarOpen = false, onToggleSidebar }: NavProps) => {
-	const { user, setUser, isAuthLoading } = useAuth();
-	const [isDropdownOpen, setIsDropdownOpen] = useState(false);
-	const dropdownRef = useRef<HTMLDivElement>(null);
-
-	const handleLogout = async (e: React.MouseEvent<HTMLButtonElement>) => {
-		e.preventDefault();
-		try {
-			await axiosInstance.post("/auth/logout");
-			setUser(undefined);
-			setIsDropdownOpen(false);
-			window.location.href = "/";
-			// toast.success("Logout successful!");
-		} catch (error) {
-			console.error("Logout failed:", error);
-			toast.error("Logout failed!");
-		}
-	};
-
-	useEffect(() => {
-		const handleClickOutside = (event: MouseEvent) => {
-			if (
-				dropdownRef.current &&
-				!dropdownRef.current.contains(event.target as Node)
-			) {
-				setIsDropdownOpen(false);
-			}
-		};
-
-		document.addEventListener("mousedown", handleClickOutside);
-		return () => {
-			document.removeEventListener("mousedown", handleClickOutside);
-		};
-	}, []);
-
-	return (
-		<div
-			className={`bg-gray-800 p-4 flex justify-between items-center fixed top-0 right-0 z-50 transition-all duration-300 ${
-				isSidebarOpen ? "left-64" : "left-0"
-			}`}
-		>
-			<div className="flex items-center gap-4">
-				{onToggleSidebar && user && (
-					<button
-						onClick={onToggleSidebar}
-						className="text-white hover:text-[#1db954] transition-colors p-2 cursor-pointer"
-						aria-label="Toggle sidebar"
-					>
-						<svg
-							className="w-6 h-6"
-							fill="none"
-							stroke="currentColor"
-							viewBox="0 0 24 24"
-						>
-							<path
-								strokeLinecap="round"
-								strokeLinejoin="round"
-								strokeWidth={2}
-								d="M4 6h16M4 12h16M4 18h16"
-							/>
-						</svg>
-					</button>
-				)}
-				<Link to="/" className="text-white text-lg font-semibold">
-					<img src={Logo} alt="Finkwave Logo" className="h-12 w-auto" />
-				</Link>
-			</div>
-
-			<div className="flex items-center space-x-4">
-				{!isAuthLoading && (
-					<div className="flex items-center space-x-3">
-						{user?.isArtist && (
-							<Link
-								to="/my-songs"
-								className="text-white hover:text-[#1db954] px-4 py-2 text-sm font-medium transition-colors"
-							>
-								My Songs
-							</Link>
-						)}
-						{user ? (
-							<div className="relative" ref={dropdownRef}>
-								<button
-									onClick={() => setIsDropdownOpen(!isDropdownOpen)}
-									className="focus:outline-none focus:ring-2 focus:ring-blue-500 rounded-full"
-								>
-									{user.profilePhoto ? (
-										<img
-											src={`${baseURL}/${user.profilePhoto}`}
-											alt={`${user.username}'s profile`}
-											className="w-10 h-10 rounded-full object-cover cursor-pointer hover:ring-2 hover:ring-blue-400 transition-all"
-										/>
-									) : (
-										<div className="w-10 h-10 bg-blue-500 rounded-full flex items-center justify-center cursor-pointer hover:ring-2 hover:ring-blue-400 transition-all">
-											<span className="text-white text-lg font-semibold">
-												{user.username.charAt(0).toUpperCase()}
-											</span>
-										</div>
-									)}
-								</button>
-
-								{isDropdownOpen && (
-									<div className="absolute right-0 mt-2 w-48 bg-gray-700 rounded-lg shadow-lg py-1 z-50">
-										<Link
-											to="/me"
-											className="block px-4 py-2 text-sm text-white hover:bg-gray-600 transition-colors"
-											onClick={() => setIsDropdownOpen(false)}
-										>
-											Account
-										</Link>
-										<button
-											onClick={handleLogout}
-											className="w-full text-left px-4 py-2 text-sm text-white hover:bg-gray-600 transition-colors"
-										>
-											Log out
-										</button>
-									</div>
-								)}
-							</div>
-						) : (
-							<div className="flex items-center space-x-4">
-								<Link
-									to="/login"
-									className="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg text-sm 
-                                    font-medium transition-colors duration-200 cursor-pointer"
-								>
-									Login
-								</Link>
-								<Link
-									to="/register"
-									className="bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded-lg text-sm
-                                    font-medium transition-colors duration-200 cursor-pointer"
-								>
-									Register
-								</Link>
-							</div>
-						)}
-					</div>
-				)}
-			</div>
-		</div>
-	);
-};
-
-export default Nav;
Index: frontend/src/pages/PublishSong.tsx
===================================================================
--- frontend/src/pages/PublishSong.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,1041 +1,0 @@
-import { useCallback, useEffect, useRef, useState } from "react";
-import { Link, useNavigate } from "react-router-dom";
-import { toast } from "react-toastify";
-import axiosInstance from "../api/axiosInstance";
-import { useAuth } from "../context/authContext";
-import { GENRE_OPTIONS, ROLE_OPTIONS } from "../utils/consts";
-import type {
-	ArtistSearchResult,
-	Contributor,
-	SongEntry,
-} from "../utils/types";
-
-const MAX_CONTRIBUTORS = 5;
-const MAX_ALBUM_SONGS = 20;
-
-const PublishSong = () => {
-	const { user } = useAuth();
-	const navigate = useNavigate();
-
-	// Form state
-	const [releaseType, setReleaseType] = useState<"single" | "album">("single");
-	const [title, setTitle] = useState("");
-	const [genre, setGenre] = useState("");
-	const [link, setLink] = useState("");
-	const [coverFile, setCoverFile] = useState<File | null>(null);
-	const [coverPreview, setCoverPreview] = useState<string | null>(null);
-	const [contributors, setContributors] = useState<Contributor[]>([]);
-	const [isSubmitting, setIsSubmitting] = useState(false);
-
-	// Album-specific state
-	const [albumSongs, setAlbumSongs] = useState<SongEntry[]>([
-		{ title: "", link: "", contributors: [] },
-	]);
-
-	// Contributor search state
-	const [contributorSearch, setContributorSearch] = useState("");
-	const [searchResults, setSearchResults] = useState<ArtistSearchResult[]>([]);
-	const [isSearching, setIsSearching] = useState(false);
-	const [showSearchDropdown, setShowSearchDropdown] = useState(false);
-	const [selectedContributorRole, setSelectedContributorRole] = useState(
-		ROLE_OPTIONS[0].value,
-	);
-	const searchDropdownRef = useRef<HTMLDivElement>(null);
-	const searchTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
-
-	// Album song contributor search state
-	const [albumSongContributorSearch, setAlbumSongContributorSearch] = useState<{
-		[key: number]: string;
-	}>({});
-	const [albumSongSearchResults, setAlbumSongSearchResults] = useState<{
-		[key: number]: ArtistSearchResult[];
-	}>({});
-	const [albumSongShowDropdown, setAlbumSongShowDropdown] = useState<{
-		[key: number]: boolean;
-	}>({});
-	const [albumSongSelectedRole, setAlbumSongSelectedRole] = useState<{
-		[key: number]: string;
-	}>({});
-
-	// Cleanup cover preview URL on unmount
-	useEffect(() => {
-		return () => {
-			if (coverPreview) {
-				URL.revokeObjectURL(coverPreview);
-			}
-		};
-	}, [coverPreview]);
-
-	// Click outside handler for search dropdown
-	useEffect(() => {
-		const handleClickOutside = (event: MouseEvent) => {
-			if (
-				searchDropdownRef.current &&
-				!searchDropdownRef.current.contains(event.target as Node)
-			) {
-				setShowSearchDropdown(false);
-			}
-		};
-		document.addEventListener("mousedown", handleClickOutside);
-		return () => document.removeEventListener("mousedown", handleClickOutside);
-	}, []);
-
-	// Search for artists (mock implementation)
-	const searchArtists = useCallback(async (query: string) => {
-		if (!query.trim()) {
-			setSearchResults([]);
-			return;
-		}
-
-		setIsSearching(true);
-		try {
-			const response = await axiosInstance.get(
-				`/users/search?type=ARTIST&q=${encodeURIComponent(query)}&limit=5`,
-			);
-			const filtered = response.data.filter(
-				(artist: ArtistSearchResult) =>
-					artist.fullName.toLowerCase().includes(query.toLowerCase()) ||
-					artist.username.toLowerCase().includes(query.toLowerCase()),
-			);
-			setSearchResults(filtered);
-		} catch (error) {
-			console.error("Error searching artists:", error);
-			setSearchResults([]);
-		} finally {
-			setIsSearching(false);
-		}
-	}, []);
-
-	// Debounced search
-	const handleContributorSearchChange = (value: string) => {
-		setContributorSearch(value);
-		setShowSearchDropdown(true);
-
-		if (searchTimeoutRef.current) {
-			clearTimeout(searchTimeoutRef.current);
-		}
-
-		searchTimeoutRef.current = setTimeout(() => {
-			searchArtists(value);
-		}, 300);
-	};
-
-	// Add contributor
-	const handleAddContributor = (artist: ArtistSearchResult) => {
-		if (contributors.length >= MAX_CONTRIBUTORS) {
-			toast.error(`Maximum ${MAX_CONTRIBUTORS} contributors allowed`);
-			return;
-		}
-
-		if (contributors.some((c) => c.id === artist.id)) {
-			toast.error("This contributor is already added");
-			return;
-		}
-
-		setContributors([
-			...contributors,
-			{
-				id: artist.id,
-				fullName: artist.fullName,
-				role: selectedContributorRole,
-			},
-		]);
-		setContributorSearch("");
-		setSearchResults([]);
-		setShowSearchDropdown(false);
-	};
-
-	// Remove contributor
-	const handleRemoveContributor = (id: number) => {
-		setContributors(contributors.filter((c) => c.id !== id));
-	};
-
-	// Handle cover file
-	const handleCoverChange = (e: React.ChangeEvent<HTMLInputElement>) => {
-		const file = e.target.files?.[0];
-		if (file) {
-			if (file.size > 2 * 1024 * 1024) {
-				toast.error("Max file size is 5MB");
-				return;
-			}
-			if (!file.type.startsWith("image/")) {
-				toast.error("Only images allowed");
-				return;
-			}
-			if (coverPreview) {
-				URL.revokeObjectURL(coverPreview);
-			}
-			setCoverFile(file);
-			setCoverPreview(URL.createObjectURL(file));
-		}
-	};
-
-	const handleRemoveCover = () => {
-		if (coverPreview) {
-			URL.revokeObjectURL(coverPreview);
-		}
-		setCoverFile(null);
-		setCoverPreview(null);
-	};
-
-	// Album song handlers
-	const handleAddAlbumSong = () => {
-		if (albumSongs.length >= MAX_ALBUM_SONGS) {
-			toast.error(`Maximum ${MAX_ALBUM_SONGS} songs per album`);
-			return;
-		}
-		setAlbumSongs([...albumSongs, { title: "", link: "", contributors: [] }]);
-	};
-
-	const handleRemoveAlbumSong = (index: number) => {
-		if (albumSongs.length === 1) {
-			toast.error("Album must have at least one song");
-			return;
-		}
-		setAlbumSongs(albumSongs.filter((_, i) => i !== index));
-	};
-
-	const handleAlbumSongChange = (
-		index: number,
-		field: keyof SongEntry,
-		value: string | Contributor[],
-	) => {
-		const updated = [...albumSongs];
-		updated[index] = { ...updated[index], [field]: value };
-		setAlbumSongs(updated);
-	};
-
-	// Album song contributor search
-	const handleAlbumSongContributorSearch = useCallback(
-		async (index: number, query: string) => {
-			setAlbumSongContributorSearch((prev) => ({ ...prev, [index]: query }));
-			setAlbumSongShowDropdown((prev) => ({ ...prev, [index]: true }));
-
-			if (!query.trim()) {
-				setAlbumSongSearchResults((prev) => ({ ...prev, [index]: [] }));
-				return;
-			}
-
-			// TODO: replace with api call
-			const response = await axiosInstance.get(
-				`/users/search?type=ARTIST&q=${encodeURIComponent(query)}&limit=5`,
-			);
-			const filtered = response.data.filter(
-				(artist: ArtistSearchResult) =>
-					artist.fullName.toLowerCase().includes(query.toLowerCase()) ||
-					artist.username.toLowerCase().includes(query.toLowerCase()),
-			);
-			setAlbumSongSearchResults((prev) => ({ ...prev, [index]: filtered }));
-		},
-		[],
-	);
-
-	const handleAddAlbumSongContributor = (
-		songIndex: number,
-		artist: ArtistSearchResult,
-	) => {
-		const song = albumSongs[songIndex];
-		if (song.contributors.length >= MAX_CONTRIBUTORS) {
-			toast.error(`Maximum ${MAX_CONTRIBUTORS} contributors per song`);
-			return;
-		}
-
-		if (song.contributors.some((c) => c.id === artist.id)) {
-			toast.error("This contributor is already added");
-			return;
-		}
-
-		const role = albumSongSelectedRole[songIndex] || ROLE_OPTIONS[0].value;
-		const newContributor: Contributor = {
-			id: artist.id,
-			fullName: artist.fullName,
-			role,
-		};
-
-		handleAlbumSongChange(songIndex, "contributors", [
-			...song.contributors,
-			newContributor,
-		]);
-		setAlbumSongContributorSearch((prev) => ({ ...prev, [songIndex]: "" }));
-		setAlbumSongSearchResults((prev) => ({ ...prev, [songIndex]: [] }));
-		setAlbumSongShowDropdown((prev) => ({ ...prev, [songIndex]: false }));
-	};
-
-	const handleRemoveAlbumSongContributor = (songIndex: number, id: number) => {
-		const song = albumSongs[songIndex];
-		handleAlbumSongChange(
-			songIndex,
-			"contributors",
-			song.contributors.filter((c) => c.id !== id),
-		);
-	};
-
-	const handleSubmit = async (e: React.FormEvent) => {
-		e.preventDefault();
-
-		if (!title.trim()) {
-			toast.error("Please enter a title");
-			return;
-		}
-		if (!genre) {
-			toast.error("Please select a genre");
-			return;
-		}
-
-		if (releaseType === "single") {
-			if (!link.trim()) {
-				toast.error("Please enter a song link");
-				return;
-			}
-		} else {
-			for (let i = 0; i < albumSongs.length; i++) {
-				if (!albumSongs[i].title.trim()) {
-					toast.error(`Please enter a title for song ${i + 1}`);
-					return;
-				}
-				if (!albumSongs[i].link.trim()) {
-					toast.error(`Please enter a link for song ${i + 1}`);
-					return;
-				}
-			}
-		}
-
-		setIsSubmitting(true);
-
-		try {
-			const formData = new FormData();
-			formData.append("title", title);
-			formData.append("genre", genre);
-			if (coverFile) formData.append("cover", coverFile);
-
-			// Helper to append contributors in indexed format for Spring @ModelAttribute
-			const appendContributors = (
-				formData: FormData,
-				contributors: Contributor[],
-				prefix: string,
-			) => {
-				contributors.forEach((c, i) => {
-					formData.append(`${prefix}[${i}].id`, c.id.toString());
-					formData.append(`${prefix}[${i}].artistName`, c.fullName);
-					formData.append(`${prefix}[${i}].role`, c.role);
-				});
-			};
-
-			if (releaseType === "album") {
-				// Append album songs in indexed format
-				albumSongs.forEach((song, songIndex) => {
-					formData.append(`albumSongs[${songIndex}].title`, song.title);
-					formData.append(`albumSongs[${songIndex}].link`, song.link);
-					// Append nested contributors for each song
-					song.contributors.forEach((c, contribIndex) => {
-						formData.append(
-							`albumSongs[${songIndex}].contributors[${contribIndex}].id`,
-							c.id.toString(),
-						);
-						formData.append(
-							`albumSongs[${songIndex}].contributors[${contribIndex}].artistName`,
-							c.fullName,
-						);
-						formData.append(
-							`albumSongs[${songIndex}].contributors[${contribIndex}].role`,
-							c.role,
-						);
-					});
-				});
-				await axiosInstance.post("/musical-entity/publish/album", formData, {
-					headers: { "Content-Type": "multipart/form-data" },
-				});
-			} else {
-				formData.append("link", link);
-				appendContributors(formData, contributors, "contributors");
-				await axiosInstance.post("/musical-entity/publish/song", formData, {
-					headers: { "Content-Type": "multipart/form-data" },
-				});
-			}
-
-			toast.success(
-				releaseType === "single"
-					? "Song published successfully!"
-					: "Album published successfully!",
-			);
-			navigate("/my-songs");
-		} catch (error) {
-			console.error("Error publishing:", error);
-			toast.error("Failed to publish. Please try again.");
-		} finally {
-			setIsSubmitting(false);
-		}
-	};
-
-	if (!user?.isArtist) {
-		return (
-			<div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] flex items-center justify-center">
-				<div className="text-center">
-					<p className="text-red-400 text-xl mb-4">
-						You need to be an artist to publish music.
-					</p>
-					<Link to="/" className="text-[#1db954] hover:underline text-sm">
-						← Back to Home
-					</Link>
-				</div>
-			</div>
-		);
-	}
-
-	return (
-		<div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] text-white">
-			<div className="max-w-3xl mx-auto px-6 py-10">
-				{/* Back link */}
-				<Link
-					to="/my-songs"
-					className="inline-flex items-center gap-1 text-gray-400 hover:text-white text-sm mb-8 transition-colors"
-				>
-					<svg
-						className="w-4 h-4"
-						fill="none"
-						stroke="currentColor"
-						viewBox="0 0 24 24"
-					>
-						<path
-							strokeLinecap="round"
-							strokeLinejoin="round"
-							strokeWidth={2}
-							d="M15 19l-7-7 7-7"
-						/>
-					</svg>
-					Back to My Songs
-				</Link>
-
-				{/* Header */}
-				<h1 className="text-4xl font-extrabold mb-8">Publish New Music</h1>
-
-				<form onSubmit={handleSubmit} className="space-y-8">
-					{/* Release Type Selection */}
-					<div className="bg-[#181818] rounded-xl p-6">
-						<h2 className="text-lg font-semibold mb-4">
-							What are you releasing?
-						</h2>
-						<div className="flex gap-4">
-							<label
-								className={`flex-1 flex items-center justify-center gap-3 p-4 rounded-lg border-2 cursor-pointer transition-all ${
-									releaseType === "single"
-										? "border-[#1db954] bg-[#1db954]/10"
-										: "border-white/10 hover:border-white/20"
-								}`}
-							>
-								<input
-									type="radio"
-									name="releaseType"
-									value="single"
-									checked={releaseType === "single"}
-									onChange={() => setReleaseType("single")}
-									className="hidden"
-								/>
-								<svg
-									className={`w-8 h-8 ${releaseType === "single" ? "text-[#1db954]" : "text-gray-400"}`}
-									fill="none"
-									stroke="currentColor"
-									viewBox="0 0 24 24"
-								>
-									<path
-										strokeLinecap="round"
-										strokeLinejoin="round"
-										strokeWidth={1.5}
-										d="M9 19V6l12-3v13M9 19c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zm12-3c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2z"
-									/>
-								</svg>
-								<div>
-									<p className="font-medium">Single</p>
-									<p className="text-sm text-gray-400">One song</p>
-								</div>
-							</label>
-
-							<label
-								className={`flex-1 flex items-center justify-center gap-3 p-4 rounded-lg border-2 cursor-pointer transition-all ${
-									releaseType === "album"
-										? "border-[#1db954] bg-[#1db954]/10"
-										: "border-white/10 hover:border-white/20"
-								}`}
-							>
-								<input
-									type="radio"
-									name="releaseType"
-									value="album"
-									checked={releaseType === "album"}
-									onChange={() => setReleaseType("album")}
-									className="hidden"
-								/>
-								<svg
-									className={`w-8 h-8 ${releaseType === "album" ? "text-[#1db954]" : "text-gray-400"}`}
-									fill="none"
-									stroke="currentColor"
-									viewBox="0 0 24 24"
-								>
-									<path
-										strokeLinecap="round"
-										strokeLinejoin="round"
-										strokeWidth={1.5}
-										d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"
-									/>
-								</svg>
-								<div>
-									<p className="font-medium">Album</p>
-									<p className="text-sm text-gray-400">Multiple songs</p>
-								</div>
-							</label>
-						</div>
-					</div>
-
-					{/* Basic Info */}
-					<div className="bg-[#181818] rounded-xl p-6 space-y-6">
-						<h2 className="text-lg font-semibold">
-							{releaseType === "single" ? "Song Details" : "Album Details"}
-						</h2>
-
-						{/* Title */}
-						<div>
-							<label
-								htmlFor="title"
-								className="block text-sm font-medium text-gray-300 mb-2"
-							>
-								{releaseType === "single" ? "Song Title" : "Album Name"} *
-							</label>
-							<input
-								type="text"
-								id="title"
-								value={title}
-								onChange={(e) => setTitle(e.target.value)}
-								placeholder={
-									releaseType === "single"
-										? "Enter song title"
-										: "Enter album name"
-								}
-								className="w-full bg-[#282828] border border-white/10 rounded-lg py-3 px-4 text-white placeholder-gray-500 focus:outline-none focus:border-[#1db954] focus:ring-1 focus:ring-[#1db954] transition-all"
-							/>
-						</div>
-
-						{/* Genre */}
-						<div>
-							<label
-								htmlFor="genre"
-								className="block text-sm font-medium text-gray-300 mb-2"
-							>
-								Genre *
-							</label>
-							<select
-								id="genre"
-								value={genre}
-								onChange={(e) => setGenre(e.target.value)}
-								className="w-full bg-[#282828] border border-white/10 rounded-lg py-3 px-4 text-white focus:outline-none focus:border-[#1db954] focus:ring-1 focus:ring-[#1db954] transition-all appearance-none cursor-pointer"
-							>
-								<option value="">Select a genre</option>
-								{GENRE_OPTIONS.map((g) => (
-									<option key={g} value={g}>
-										{g}
-									</option>
-								))}
-							</select>
-						</div>
-
-						{/* Cover Art */}
-						<div>
-							<label className="block text-sm font-medium text-gray-300 mb-2">
-								Cover Art (optional)
-							</label>
-							<div className="flex items-start gap-4">
-								{coverPreview ? (
-									<div className="relative">
-										<img
-											src={coverPreview}
-											alt="Cover preview"
-											className="w-32 h-32 rounded-lg object-cover"
-										/>
-										<button
-											type="button"
-											onClick={handleRemoveCover}
-											className="absolute -top-2 -right-2 w-6 h-6 bg-red-500 rounded-full flex items-center justify-center text-white hover:bg-red-600 transition-colors"
-										>
-											<svg
-												className="w-4 h-4"
-												fill="none"
-												stroke="currentColor"
-												viewBox="0 0 24 24"
-											>
-												<path
-													strokeLinecap="round"
-													strokeLinejoin="round"
-													strokeWidth={2}
-													d="M6 18L18 6M6 6l12 12"
-												/>
-											</svg>
-										</button>
-									</div>
-								) : (
-									<label
-										htmlFor="cover"
-										className="w-32 h-32 rounded-lg border-2 border-dashed border-white/20 flex flex-col items-center justify-center cursor-pointer hover:border-[#1db954] transition-colors"
-									>
-										<svg
-											className="w-8 h-8 text-gray-400 mb-2"
-											fill="none"
-											stroke="currentColor"
-											viewBox="0 0 24 24"
-										>
-											<path
-												strokeLinecap="round"
-												strokeLinejoin="round"
-												strokeWidth={1.5}
-												d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
-											/>
-										</svg>
-										<span className="text-xs text-gray-400">Upload</span>
-									</label>
-								)}
-								<input
-									type="file"
-									id="cover"
-									accept="image/*"
-									onChange={handleCoverChange}
-									className="hidden"
-								/>
-								<div className="text-sm text-gray-400">
-									<p>Recommended: 1400x1400px</p>
-									<p>Max size: 5MB</p>
-									<p>JPG, PNG, or WebP</p>
-								</div>
-							</div>
-						</div>
-
-						{/* Single: Link */}
-						{releaseType === "single" && (
-							<div>
-								<label
-									htmlFor="link"
-									className="block text-sm font-medium text-gray-300 mb-2"
-								>
-									Song Link (YouTube) *
-								</label>
-								<input
-									type="url"
-									id="link"
-									value={link}
-									onChange={(e) => setLink(e.target.value)}
-									placeholder="https://www.youtube.com/watch?v=..."
-									className="w-full bg-[#282828] border border-white/10 rounded-lg py-3 px-4 text-white placeholder-gray-500 focus:outline-none focus:border-[#1db954] focus:ring-1 focus:ring-[#1db954] transition-all"
-								/>
-							</div>
-						)}
-					</div>
-
-					{/* Single: Contributors */}
-					{releaseType === "single" && (
-						<div className="bg-[#181818] rounded-xl p-6 space-y-4">
-							<div className="flex items-center justify-between">
-								<h2 className="text-lg font-semibold">
-									Contributors (optional)
-								</h2>
-								<span className="text-sm text-gray-400">
-									{contributors.length}/{MAX_CONTRIBUTORS}
-								</span>
-							</div>
-
-							{/* Added contributors */}
-							{contributors.length > 0 && (
-								<div className="flex flex-wrap gap-2 mb-4">
-									{contributors.map((contributor) => (
-										<div
-											key={contributor.id}
-											className="flex items-center gap-2 bg-[#282828] rounded-full py-1.5 px-3"
-										>
-											<span className="text-sm">{contributor.fullName}</span>
-											<span className="text-xs text-gray-400">
-												(
-												{
-													ROLE_OPTIONS.find((r) => r.value === contributor.role)
-														?.label
-												}
-												)
-											</span>
-											<button
-												type="button"
-												onClick={() => handleRemoveContributor(contributor.id)}
-												className="text-gray-400 hover:text-red-400 transition-colors"
-											>
-												<svg
-													className="w-4 h-4"
-													fill="none"
-													stroke="currentColor"
-													viewBox="0 0 24 24"
-												>
-													<path
-														strokeLinecap="round"
-														strokeLinejoin="round"
-														strokeWidth={2}
-														d="M6 18L18 6M6 6l12 12"
-													/>
-												</svg>
-											</button>
-										</div>
-									))}
-								</div>
-							)}
-
-							{/* Add contributor */}
-							{contributors.length < MAX_CONTRIBUTORS && (
-								<div className="flex gap-3">
-									<select
-										value={selectedContributorRole}
-										onChange={(e) => setSelectedContributorRole(e.target.value)}
-										className="bg-[#282828] border border-white/10 rounded-lg py-2.5 px-3 text-white text-sm focus:outline-none focus:border-[#1db954] appearance-none cursor-pointer"
-									>
-										{ROLE_OPTIONS.map((role) => (
-											<option key={role.value} value={role.value}>
-												{role.label}
-											</option>
-										))}
-									</select>
-
-									<div className="flex-1 relative" ref={searchDropdownRef}>
-										<input
-											type="text"
-											value={contributorSearch}
-											onChange={(e) =>
-												handleContributorSearchChange(e.target.value)
-											}
-											onFocus={() => setShowSearchDropdown(true)}
-											placeholder="Search for an artist..."
-											className="w-full bg-[#282828] border border-white/10 rounded-lg py-2.5 px-4 text-white placeholder-gray-500 focus:outline-none focus:border-[#1db954] focus:ring-1 focus:ring-[#1db954] transition-all"
-										/>
-
-										{/* Search dropdown */}
-										{showSearchDropdown && contributorSearch && (
-											<div className="absolute top-full left-0 right-0 mt-1 bg-[#282828] border border-white/10 rounded-lg shadow-xl z-10 max-h-48 overflow-y-auto">
-												{isSearching ? (
-													<div className="p-3 text-center text-gray-400">
-														<div className="w-5 h-5 border-2 border-white/10 border-t-[#1db954] rounded-full animate-spin mx-auto" />
-													</div>
-												) : searchResults.length > 0 ? (
-													searchResults.map((artist) => (
-														<button
-															key={artist.id}
-															type="button"
-															onClick={() => handleAddContributor(artist)}
-															className="w-full text-left px-4 py-2.5 hover:bg-white/10 transition-colors flex items-center gap-3"
-														>
-															<div className="w-8 h-8 bg-gray-600 rounded-full flex items-center justify-center">
-																{artist.profilePhoto ? (
-																	<img
-																		src={artist.profilePhoto}
-																		alt={artist.fullName}
-																		className="w-full h-full rounded-full object-cover"
-																	/>
-																) : (
-																	<span className="text-xs">
-																		{artist.fullName.charAt(0).toUpperCase()}
-																	</span>
-																)}
-															</div>
-															<div>
-																<p className="text-sm font-medium">
-																	{artist.fullName}
-																</p>
-																<p className="text-xs text-gray-400">
-																	@{artist.username}
-																</p>
-															</div>
-														</button>
-													))
-												) : (
-													<div className="p-3 text-center text-gray-400 text-sm">
-														No artists found
-													</div>
-												)}
-											</div>
-										)}
-									</div>
-								</div>
-							)}
-						</div>
-					)}
-
-					{/* Album: Songs */}
-					{releaseType === "album" && (
-						<div className="bg-[#181818] rounded-xl p-6 space-y-6">
-							<div className="flex items-center justify-between">
-								<h2 className="text-lg font-semibold">Album Songs</h2>
-								<span className="text-sm text-gray-400">
-									{albumSongs.length}/{MAX_ALBUM_SONGS} songs
-								</span>
-							</div>
-
-							{albumSongs.map((song, index) => (
-								<div
-									key={index}
-									className="bg-[#282828] rounded-lg p-4 space-y-4"
-								>
-									<div className="flex items-center justify-between">
-										<h3 className="font-medium text-gray-300">
-											Song {index + 1}
-										</h3>
-										{albumSongs.length > 1 && (
-											<button
-												type="button"
-												onClick={() => handleRemoveAlbumSong(index)}
-												className="text-gray-400 hover:text-red-400 transition-colors"
-											>
-												<svg
-													className="w-5 h-5"
-													fill="none"
-													stroke="currentColor"
-													viewBox="0 0 24 24"
-												>
-													<path
-														strokeLinecap="round"
-														strokeLinejoin="round"
-														strokeWidth={2}
-														d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
-													/>
-												</svg>
-											</button>
-										)}
-									</div>
-
-									{/* Song title */}
-									<input
-										type="text"
-										value={song.title}
-										onChange={(e) =>
-											handleAlbumSongChange(index, "title", e.target.value)
-										}
-										placeholder="Song title"
-										className="w-full bg-[#1a1a2e] border border-white/10 rounded-lg py-2.5 px-4 text-white placeholder-gray-500 focus:outline-none focus:border-[#1db954] focus:ring-1 focus:ring-[#1db954] transition-all"
-									/>
-
-									{/* Song link */}
-									<input
-										type="url"
-										value={song.link}
-										onChange={(e) =>
-											handleAlbumSongChange(index, "link", e.target.value)
-										}
-										placeholder="Song link (YouTube)"
-										className="w-full bg-[#1a1a2e] border border-white/10 rounded-lg py-2.5 px-4 text-white placeholder-gray-500 focus:outline-none focus:border-[#1db954] focus:ring-1 focus:ring-[#1db954] transition-all"
-									/>
-
-									{/* Contributors */}
-									<div>
-										<div className="flex items-center justify-between mb-2">
-											<label className="text-sm text-gray-400">
-												Contributors (optional)
-											</label>
-											<span className="text-xs text-gray-500">
-												{song.contributors.length}/{MAX_CONTRIBUTORS}
-											</span>
-										</div>
-
-										{/* Added contributors */}
-										{song.contributors.length > 0 && (
-											<div className="flex flex-wrap gap-2 mb-3">
-												{song.contributors.map((contributor) => (
-													<div
-														key={contributor.id}
-														className="flex items-center gap-2 bg-[#1a1a2e] rounded-full py-1 px-2.5 text-sm"
-													>
-														<span>{contributor.fullName}</span>
-														<span className="text-xs text-gray-400">
-															(
-															{
-																ROLE_OPTIONS.find(
-																	(r) => r.value === contributor.role,
-																)?.label
-															}
-															)
-														</span>
-														<button
-															type="button"
-															onClick={() =>
-																handleRemoveAlbumSongContributor(
-																	index,
-																	contributor.id,
-																)
-															}
-															className="text-gray-400 hover:text-red-400 transition-colors"
-														>
-															<svg
-																className="w-3.5 h-3.5"
-																fill="none"
-																stroke="currentColor"
-																viewBox="0 0 24 24"
-															>
-																<path
-																	strokeLinecap="round"
-																	strokeLinejoin="round"
-																	strokeWidth={2}
-																	d="M6 18L18 6M6 6l12 12"
-																/>
-															</svg>
-														</button>
-													</div>
-												))}
-											</div>
-										)}
-
-										{/* Add contributor */}
-										{song.contributors.length < MAX_CONTRIBUTORS && (
-											<div className="flex gap-2">
-												<select
-													value={
-														albumSongSelectedRole[index] ||
-														ROLE_OPTIONS[0].value
-													}
-													onChange={(e) =>
-														setAlbumSongSelectedRole((prev) => ({
-															...prev,
-															[index]: e.target.value,
-														}))
-													}
-													className="bg-[#1a1a2e] border border-white/10 rounded-lg py-2 px-2.5 text-white text-sm focus:outline-none focus:border-[#1db954] appearance-none cursor-pointer"
-												>
-													{ROLE_OPTIONS.map((role) => (
-														<option key={role.value} value={role.value}>
-															{role.label}
-														</option>
-													))}
-												</select>
-
-												<div className="flex-1 relative">
-													<input
-														type="text"
-														value={albumSongContributorSearch[index] || ""}
-														onChange={(e) =>
-															handleAlbumSongContributorSearch(
-																index,
-																e.target.value,
-															)
-														}
-														onFocus={() =>
-															setAlbumSongShowDropdown((prev) => ({
-																...prev,
-																[index]: true,
-															}))
-														}
-														placeholder="Search artist..."
-														className="w-full bg-[#1a1a2e] border border-white/10 rounded-lg py-2 px-3 text-white text-sm placeholder-gray-500 focus:outline-none focus:border-[#1db954] transition-all"
-													/>
-
-													{/* Dropdown */}
-													{albumSongShowDropdown[index] &&
-														albumSongContributorSearch[index] && (
-															<div className="absolute top-full left-0 right-0 mt-1 bg-[#1a1a2e] border border-white/10 rounded-lg shadow-xl z-10 max-h-40 overflow-y-auto">
-																{(albumSongSearchResults[index] || []).length >
-																0 ? (
-																	albumSongSearchResults[index].map(
-																		(artist) => (
-																			<button
-																				key={artist.id}
-																				type="button"
-																				onClick={() =>
-																					handleAddAlbumSongContributor(
-																						index,
-																						artist,
-																					)
-																				}
-																				className="w-full text-left px-3 py-2 hover:bg-white/10 transition-colors flex items-center gap-2"
-																			>
-																				<div className="w-6 h-6 bg-gray-600 rounded-full flex items-center justify-center text-xs">
-																					{artist.fullName
-																						.charAt(0)
-																						.toUpperCase()}
-																				</div>
-																				<span className="text-sm">
-																					{artist.fullName}
-																				</span>
-																			</button>
-																		),
-																	)
-																) : (
-																	<div className="p-2 text-center text-gray-400 text-sm">
-																		No artists found
-																	</div>
-																)}
-															</div>
-														)}
-												</div>
-											</div>
-										)}
-									</div>
-								</div>
-							))}
-
-							{/* Add song button */}
-							{albumSongs.length < MAX_ALBUM_SONGS && (
-								<button
-									type="button"
-									onClick={handleAddAlbumSong}
-									className="w-full py-3 border-2 border-dashed border-white/20 rounded-lg text-gray-400 hover:text-white hover:border-[#1db954] transition-all flex items-center justify-center gap-2"
-								>
-									<svg
-										className="w-5 h-5"
-										fill="none"
-										stroke="currentColor"
-										viewBox="0 0 24 24"
-									>
-										<path
-											strokeLinecap="round"
-											strokeLinejoin="round"
-											strokeWidth={2}
-											d="M12 4v16m8-8H4"
-										/>
-									</svg>
-									Add Another Song
-								</button>
-							)}
-						</div>
-					)}
-
-					{/* Submit */}
-					<div className="flex gap-4">
-						<button
-							type="button"
-							onClick={() => navigate("/my-songs")}
-							className="flex-1 py-3 px-6 border border-white/20 rounded-full text-white font-semibold hover:bg-white/5 transition-colors cursor-pointer"
-						>
-							Cancel
-						</button>
-						<button
-							type="submit"
-							disabled={isSubmitting}
-							className="flex-1 py-3 px-6 bg-[#1db954] rounded-full text-black font-semibold hover:bg-[#1ed760] transition-colors disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer flex items-center justify-center gap-2"
-						>
-							{isSubmitting ? (
-								<>
-									<div className="w-5 h-5 border-2 border-black/30 border-t-black rounded-full animate-spin" />
-									Publishing...
-								</>
-							) : (
-								<>
-									<svg
-										className="w-5 h-5"
-										fill="none"
-										stroke="currentColor"
-										viewBox="0 0 24 24"
-									>
-										<path
-											strokeLinecap="round"
-											strokeLinejoin="round"
-											strokeWidth={2}
-											d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"
-										/>
-									</svg>
-									Publish {releaseType === "single" ? "Song" : "Album"}
-								</>
-							)}
-						</button>
-					</div>
-				</form>
-			</div>
-		</div>
-	);
-};
-
-export default PublishSong;
Index: frontend/src/pages/Register.tsx
===================================================================
--- frontend/src/pages/Register.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,359 +1,0 @@
-import { useEffect, useState } from "react";
-import { Link, useNavigate } from "react-router-dom";
-import { toast } from "react-toastify";
-import axiosInstance, { scheduleTokenRefresh } from "../api/axiosInstance";
-import { useAuth } from "../context/authContext";
-import type { User, UserRegisterType } from "../utils/types";
-
-const Register = () => {
-	const { setUser } = useAuth();
-	const [username, setUsername] = useState("");
-	const [password, setPassword] = useState("");
-	const [fullname, setFullname] = useState("");
-	const [userType, setUserType] = useState<UserRegisterType[]>([]);
-	const [email, setEmail] = useState("");
-	const [profilePhotoFile, setProfilePhotoFile] = useState<File | null>(null);
-	const [previewProfilePhoto, setPreviewProfilePhoto] = useState<string | null>(
-		null,
-	);
-	const [error, setError] = useState<string | null>(null);
-
-	const navigate = useNavigate();
-
-	useEffect(() => {
-		return () => {
-			if (previewProfilePhoto) {
-				URL.revokeObjectURL(previewProfilePhoto);
-			}
-		};
-	}, [previewProfilePhoto]);
-
-	const handleRemoveFile = () => {
-		if (previewProfilePhoto) {
-			URL.revokeObjectURL(previewProfilePhoto);
-		}
-		setProfilePhotoFile(null);
-		setPreviewProfilePhoto(null);
-	};
-
-	const handleRegister = async (e: React.FormEvent) => {
-		e.preventDefault();
-		if (profilePhotoFile && profilePhotoFile.size > 5 * 1024 * 1024) {
-			toast.error("Max file size is 5MB");
-			return;
-		}
-
-		if (
-			username === "" ||
-			password === "" ||
-			fullname === "" ||
-			email === "" ||
-			userType.length === 0
-		) {
-			setError("Please fill in all required fields.");
-			return;
-		}
-		if (profilePhotoFile && !profilePhotoFile.type.startsWith("image/")) {
-			toast.error("Only images allowed");
-			return;
-		}
-		const formData = new FormData();
-		if (profilePhotoFile) formData.append("profilePhoto", profilePhotoFile);
-		formData.append("username", username);
-		formData.append("fullname", fullname);
-		formData.append("email", email);
-		formData.append("password", password);
-		userType.forEach((type) => formData.append("userType", type));
-
-		try {
-			const response = await axiosInstance.post<{
-				user: User;
-				tokenExpiresIn: number;
-			}>("/auth/register", formData);
-			scheduleTokenRefresh(response.data.tokenExpiresIn);
-			setUser(response.data.user);
-			navigate("/");
-			toast.success("Registration successful!");
-		} catch (error: any) {
-			const errorMessage = error.response?.data?.error || "Please try again.";
-			setError(`Registration failed: ${errorMessage}`);
-		}
-	};
-
-	return (
-		<div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] flex items-center justify-center px-4 py-10">
-			<div className="w-full max-w-md">
-				<div className="text-center mb-8">
-					<h1 className="text-4xl font-extrabold text-white mb-2">
-						Create Account
-					</h1>
-					<p className="text-gray-400">Join FinkWave and discover music</p>
-				</div>
-
-				<form
-					className="bg-[#181818] rounded-xl p-8 space-y-6"
-					onSubmit={handleRegister}
-				>
-					{error && (
-						<div className="bg-red-500/10 border border-red-500/20 rounded-lg p-3">
-							<p className="text-red-400 text-sm">{error}</p>
-						</div>
-					)}
-
-					<div>
-						<label
-							className="block text-sm font-medium text-gray-300 mb-2"
-							htmlFor="username"
-						>
-							Username *
-						</label>
-						<input
-							type="text"
-							id="username"
-							className="w-full bg-[#282828] border border-white/10 rounded-lg py-3 px-4 text-white placeholder-gray-500 focus:outline-none focus:border-[#1db954] focus:ring-1 focus:ring-[#1db954] transition-all"
-							placeholder="Choose a username"
-							value={username}
-							onChange={(e) => setUsername(e.target.value)}
-						/>
-					</div>
-
-					<div>
-						<label
-							className="block text-sm font-medium text-gray-300 mb-2"
-							htmlFor="password"
-						>
-							Password *
-						</label>
-						<input
-							type="password"
-							id="password"
-							className="w-full bg-[#282828] border border-white/10 rounded-lg py-3 px-4 text-white placeholder-gray-500 focus:outline-none focus:border-[#1db954] focus:ring-1 focus:ring-[#1db954] transition-all"
-							placeholder="Create a password"
-							value={password}
-							onChange={(e) => setPassword(e.target.value)}
-						/>
-					</div>
-
-					<div>
-						<label
-							className="block text-sm font-medium text-gray-300 mb-2"
-							htmlFor="fullName"
-						>
-							Full Name *
-						</label>
-						<input
-							type="text"
-							id="fullName"
-							className="w-full bg-[#282828] border border-white/10 rounded-lg py-3 px-4 text-white placeholder-gray-500 focus:outline-none focus:border-[#1db954] focus:ring-1 focus:ring-[#1db954] transition-all"
-							placeholder="Enter your full name"
-							value={fullname}
-							onChange={(e) => setFullname(e.target.value)}
-						/>
-					</div>
-
-					<div>
-						<label
-							className="block text-sm font-medium text-gray-300 mb-2"
-							htmlFor="email"
-						>
-							Email *
-						</label>
-						<input
-							type="email"
-							id="email"
-							className="w-full bg-[#282828] border border-white/10 rounded-lg py-3 px-4 text-white placeholder-gray-500 focus:outline-none focus:border-[#1db954] focus:ring-1 focus:ring-[#1db954] transition-all"
-							placeholder="Enter your email"
-							value={email}
-							onChange={(e) => setEmail(e.target.value)}
-						/>
-					</div>
-
-					<div>
-						<label className="block text-sm font-medium text-gray-300 mb-3">
-							I want to be a... *
-						</label>
-						<div className="flex gap-3">
-							<label
-								className={`flex-1 flex items-center justify-center gap-2 p-3 rounded-lg border-2 cursor-pointer transition-all ${
-									userType.includes("ARTIST")
-										? "border-[#1db954] bg-[#1db954]/10"
-										: "border-white/10 hover:border-white/20"
-								}`}
-							>
-								<input
-									type="checkbox"
-									value="ARTIST"
-									checked={userType.includes("ARTIST")}
-									onChange={(e) => {
-										if (e.target.checked) {
-											setUserType((prev) => [...prev, "ARTIST"]);
-										} else {
-											setUserType((prev) =>
-												prev.filter((type) => type !== "ARTIST"),
-											);
-										}
-									}}
-									className="hidden"
-								/>
-								<svg
-									className={`w-5 h-5 ${userType.includes("ARTIST") ? "text-[#1db954]" : "text-gray-400"}`}
-									fill="none"
-									stroke="currentColor"
-									viewBox="0 0 24 24"
-								>
-									<path
-										strokeLinecap="round"
-										strokeLinejoin="round"
-										strokeWidth={1.5}
-										d="M9 19V6l12-3v13M9 19c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zm12-3c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2z"
-									/>
-								</svg>
-								<span
-									className={`text-sm font-medium ${userType.includes("ARTIST") ? "text-white" : "text-gray-400"}`}
-								>
-									Artist
-								</span>
-							</label>
-
-							<label
-								className={`flex-1 flex items-center justify-center gap-2 p-3 rounded-lg border-2 cursor-pointer transition-all ${
-									userType.includes("LISTENER")
-										? "border-[#1db954] bg-[#1db954]/10"
-										: "border-white/10 hover:border-white/20"
-								}`}
-							>
-								<input
-									type="checkbox"
-									value="LISTENER"
-									checked={userType.includes("LISTENER")}
-									onChange={(e) => {
-										if (e.target.checked) {
-											setUserType((prev) => [...prev, "LISTENER"]);
-										} else {
-											setUserType((prev) =>
-												prev.filter((type) => type !== "LISTENER"),
-											);
-										}
-									}}
-									className="hidden"
-								/>
-								<svg
-									className={`w-5 h-5 ${userType.includes("LISTENER") ? "text-[#1db954]" : "text-gray-400"}`}
-									fill="none"
-									stroke="currentColor"
-									viewBox="0 0 24 24"
-								>
-									<path
-										strokeLinecap="round"
-										strokeLinejoin="round"
-										strokeWidth={1.5}
-										d="M15.536 8.464a5 5 0 010 7.072M12 12h.01M18.364 5.636a9 9 0 010 12.728M5.636 18.364a9 9 0 010-12.728"
-									/>
-								</svg>
-								<span
-									className={`text-sm font-medium ${userType.includes("LISTENER") ? "text-white" : "text-gray-400"}`}
-								>
-									Listener
-								</span>
-							</label>
-						</div>
-					</div>
-
-					{/* Profile Photo - PublishSong style */}
-					<div>
-						<label className="block text-sm font-medium text-gray-300 mb-2">
-							Profile Photo (optional)
-						</label>
-						<div className="flex items-center justify-start gap-4">
-							{previewProfilePhoto ? (
-								<div className="relative">
-									<img
-										src={previewProfilePhoto}
-										alt="Profile Preview"
-										className="w-24 h-24 rounded-full object-cover"
-									/>
-									<button
-										type="button"
-										onClick={handleRemoveFile}
-										className="absolute -top-2 -right-2 w-6 h-6 bg-red-500 rounded-full flex items-center justify-center text-white hover:bg-red-600 transition-colors"
-									>
-										<svg
-											className="w-4 h-4"
-											fill="none"
-											stroke="currentColor"
-											viewBox="0 0 24 24"
-										>
-											<path
-												strokeLinecap="round"
-												strokeLinejoin="round"
-												strokeWidth={2}
-												d="M6 18L18 6M6 6l12 12"
-											/>
-										</svg>
-									</button>
-								</div>
-							) : (
-								<label
-									htmlFor="profilePhoto"
-									className="w-24 h-24 rounded-full border-2 border-dashed border-white/20 flex flex-col items-center justify-center cursor-pointer hover:border-[#1db954] transition-colors"
-								>
-									<svg
-										className="w-8 h-8 text-gray-400 mb-1"
-										fill="none"
-										stroke="currentColor"
-										viewBox="0 0 24 24"
-									>
-										<path
-											strokeLinecap="round"
-											strokeLinejoin="round"
-											strokeWidth={1.5}
-											d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
-										/>
-									</svg>
-									<span className="text-xs text-gray-400">Upload</span>
-								</label>
-							)}
-							<input
-								type="file"
-								accept="image/*"
-								id="profilePhoto"
-								className="hidden"
-								onChange={(e) => {
-									if (e.target.files && e.target.files[0]) {
-										setProfilePhotoFile(e.target.files[0]);
-										setPreviewProfilePhoto(
-											URL.createObjectURL(e.target.files[0]),
-										);
-									}
-								}}
-							/>
-							<div className="text-sm text-gray-400 pt-2">
-								<p>Max size: 2MB</p>
-								<p>JPG, PNG, or WebP</p>
-							</div>
-						</div>
-					</div>
-
-					<button
-						type="submit"
-						className="w-full py-3 bg-[#1db954] rounded-full text-black font-semibold hover:bg-[#1ed760] transition-colors cursor-pointer"
-					>
-						Create Account
-					</button>
-
-					<p className="text-center text-sm text-gray-400">
-						Already have an account?{" "}
-						<Link
-							to="/login"
-							className="text-[#1db954] hover:underline font-medium"
-						>
-							Log in
-						</Link>
-					</p>
-				</form>
-			</div>
-		</div>
-	);
-};
-
-export default Register;
Index: frontend/src/pages/SongDetail.tsx
===================================================================
--- frontend/src/pages/SongDetail.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,595 +1,0 @@
-import { useEffect, useState } from "react";
-import { Link, useParams } from "react-router-dom";
-import { toast } from "react-toastify";
-import axiosInstance, { baseURL } from "../api/axiosInstance";
-import PlaylistDropdown from "../components/playlist/PlaylistDropdown";
-import { useAuth } from "../context/authContext";
-import { usePlayer } from "../context/playerContext";
-import type { SongDetail as SongDetailType } from "../utils/types";
-import { toEmbedUrl } from "../utils/utils";
-
-const ROLE_LABELS: Record<string, string> = {
-	MAIN_VOCAL: "Main Vocal",
-	FEATURED: "Featured",
-	PRODUCER: "Producer",
-	SONGWRITER: "Songwriter",
-	COMPOSER: "Composer",
-	MIXER: "Mixer",
-	ENGINEER: "Engineer",
-};
-
-const formatRole = (role: string): string => {
-	return ROLE_LABELS[role] || role.replace(/_/g, " ");
-};
-
-const renderStars = (grade: number) => {
-	return (
-		<div className="flex gap-0.5">
-			{[1, 2, 3, 4, 5].map((star) => (
-				<svg
-					key={star}
-					className={`w-4 h-4 ${star <= grade ? "text-yellow-400" : "text-gray-600"}`}
-					fill="currentColor"
-					viewBox="0 0 20 20"
-				>
-					<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
-				</svg>
-			))}
-		</div>
-	);
-};
-
-const SongDetail = () => {
-	const { id } = useParams<{ id: string }>();
-	const { user } = useAuth();
-	const { play, currentSong } = usePlayer();
-	const [song, setSong] = useState<SongDetailType | null>(null);
-	const [loading, setLoading] = useState(true);
-	const [error, setError] = useState<string | null>(null);
-	const [showReviewModal, setShowReviewModal] = useState(false);
-	const [reviewRating, setReviewRating] = useState(0);
-	const [reviewComment, setReviewComment] = useState("");
-	const [hoverRating, setHoverRating] = useState(0);
-	const [showPlaylistDropdown, setShowPlaylistDropdown] = useState(false);
-	console.log(user);
-	useEffect(() => {
-		const fetchSong = async () => {
-			try {
-				setLoading(true);
-				const response = await axiosInstance.get(`/songs/${id}/details`);
-				setSong(response.data);
-			} catch (err) {
-				console.error("Error fetching song details:", err);
-				setError("Failed to load song details.");
-			} finally {
-				setLoading(false);
-			}
-		};
-		if (id) fetchSong();
-	}, [id]);
-
-	const handleSubmitReview = async () => {
-		if (reviewRating === 0) {
-			// todo: replace with toast
-			alert("Please select a rating");
-			return;
-		}
-		try {
-			await axiosInstance.post(`reviews/${song?.id}`, {
-				grade: reviewRating,
-				comment: reviewComment,
-			});
-			const response = await axiosInstance.get(`/songs/${id}/details`);
-			setSong(response.data);
-		} catch (err) {
-			// todo: replace with toast
-			console.error("Error submitting review:", err);
-		} finally {
-			setShowReviewModal(false);
-			setReviewRating(0);
-			setReviewComment("");
-			setHoverRating(0);
-		}
-	};
-
-	const deleteReview = async () => {
-		try {
-			await axiosInstance.delete(`reviews/${song?.id}`);
-			const response = await axiosInstance.get(`/songs/${id}/details`);
-			setSong(response.data);
-		} catch (err) {
-			toast.error("Failed to delete review");
-			console.error("Error deleting review:", err);
-		}
-	};
-
-	const toggleLike = async () => {
-		if (!song) return;
-		try {
-			await axiosInstance.post(`/musical-entity/${song.id}/like`);
-			setSong((prev) =>
-				prev
-					? { ...prev, isLikedByCurrentUser: !prev.isLikedByCurrentUser }
-					: prev,
-			);
-		} catch (err) {
-			toast.error("Failed to toggle like");
-			console.error("Error toggling like:", err);
-		}
-	};
-
-	if (loading) {
-		return (
-			<div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] flex items-center justify-center">
-				<div className="flex flex-col items-center gap-4">
-					<div className="w-12 h-12 border-4 border-white/10 border-t-[#1db954] rounded-full animate-spin" />
-					<p className="text-gray-400 text-lg">Loading song…</p>
-				</div>
-			</div>
-		);
-	}
-
-	if (error || !song) {
-		return (
-			<div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] flex items-center justify-center">
-				<div className="text-center">
-					<p className="text-red-400 text-xl mb-4">
-						{error ?? "Song not found"}
-					</p>
-					<Link to="/" className="text-[#1db954] hover:underline text-sm">
-						← Back to Home
-					</Link>
-				</div>
-			</div>
-		);
-	}
-
-	const otherContributors = song.contributions.filter(
-		(c) => c.artistName !== song.releasedBy,
-	);
-
-	const avgRating =
-		song.reviews.length > 0
-			? (
-					song.reviews.reduce((sum, r) => sum + r.grade, 0) /
-					song.reviews.length
-				).toFixed(1)
-			: null;
-
-	return (
-		<div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] text-white">
-			<div className="max-w-5xl mx-auto px-6 py-10">
-				{/* Back link */}
-				<Link
-					to="/"
-					className="inline-flex items-center gap-1 text-gray-400 hover:text-white text-sm mb-8 transition-colors"
-				>
-					<svg
-						className="w-4 h-4"
-						fill="none"
-						stroke="currentColor"
-						viewBox="0 0 24 24"
-					>
-						<path
-							strokeLinecap="round"
-							strokeLinejoin="round"
-							strokeWidth={2}
-							d="M15 19l-7-7 7-7"
-						/>
-					</svg>
-					Back to Home
-				</Link>
-
-				{/* Hero section */}
-				<div className="flex flex-col md:flex-row gap-8 mb-10">
-					{/* Cover art */}
-					<div className="w-full md:w-72 shrink-0">
-						<div className="relative w-full pt-[100%] rounded-xl overflow-hidden shadow-2xl bg-[#181818]">
-							<img
-								src={song.cover ? `${baseURL}/${song.cover}` : "/favicon.png"}
-								alt={song.title}
-								className="absolute inset-0 w-full h-full object-cover"
-								onError={(e) => {
-									(e.target as HTMLImageElement).src = "/favicon.png";
-								}}
-							/>
-						</div>
-					</div>
-
-					{/* Song info */}
-					<div className="flex flex-col justify-end gap-3 min-w-0">
-						<span className="text-xs uppercase tracking-widest text-gray-400 font-medium">
-							{song.genre} • Song
-						</span>
-						<h1 className="text-4xl md:text-5xl font-extrabold leading-tight truncate">
-							{song.title}
-						</h1>
-
-						{/* Main artist */}
-						<p className="text-xl text-gray-300 font-semibold">
-							{song.releasedBy}
-						</p>
-
-						{/* Album */}
-						{song.album && (
-							<p className="text-sm text-gray-500">
-								Album: <span className="text-gray-300">{song.album}</span>
-							</p>
-						)}
-
-						{/* Rating summary */}
-						{avgRating && (
-							<div className="flex items-center gap-2 mt-1">
-								{renderStars(Math.round(Number(avgRating)))}
-								<span className="text-sm text-gray-400">
-									{avgRating} · {song.reviews.length}{" "}
-									{song.reviews.length === 1 ? "review" : "reviews"}
-								</span>
-							</div>
-						)}
-
-						{/* Action buttons */}
-						<div className="flex items-center gap-3 mt-4">
-							{/* Play button */}
-							{song.link && (
-								<button
-									onClick={() =>
-										play({
-											id: song.id,
-											title: song.title,
-											artist: song.releasedBy,
-											cover: song.cover,
-											embedUrl: toEmbedUrl(song.link!),
-										})
-									}
-									className={`flex items-center gap-2 px-6 py-3 rounded-full text-sm font-semibold transition-all cursor-pointer ${
-										currentSong?.id === song.id
-											? "bg-white text-[#1db954]"
-											: "bg-[#1db954] text-black hover:bg-[#1ed760] hover:scale-105"
-									}`}
-								>
-									{currentSong?.id === song.id ? (
-										<>
-											<svg
-												className="w-5 h-5"
-												fill="currentColor"
-												viewBox="0 0 24 24"
-											>
-												<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z" />
-											</svg>
-											Now Playing
-										</>
-									) : (
-										<>
-											<svg
-												className="w-5 h-5"
-												fill="currentColor"
-												viewBox="0 0 24 24"
-											>
-												<path d="M8 5v14l11-7z" />
-											</svg>
-											Play Song
-										</>
-									)}
-								</button>
-							)}
-
-							{user && (
-								<>
-									<button
-										onClick={toggleLike}
-										className={`flex items-center gap-2 px-5 py-3 rounded-full text-sm font-semibold transition-colors cursor-pointer ${
-											song.isLikedByCurrentUser
-												? "bg-[#1db954] text-black"
-												: "bg-white/10 text-white hover:bg-white/20"
-										}`}
-									>
-										{song.isLikedByCurrentUser ? (
-											<svg
-												className="w-5 h-5"
-												fill="currentColor"
-												viewBox="0 0 24 24"
-											>
-												<path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
-											</svg>
-										) : (
-											<svg
-												className="w-5 h-5"
-												fill="none"
-												stroke="currentColor"
-												viewBox="0 0 24 24"
-											>
-												<path
-													strokeLinecap="round"
-													strokeLinejoin="round"
-													strokeWidth={2}
-													d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
-												/>
-											</svg>
-										)}
-										{song.isLikedByCurrentUser ? "Liked" : "Like"}
-									</button>
-
-									{/* Add to Playlist button */}
-									<div className="relative">
-										<button
-											onClick={() => setShowPlaylistDropdown((prev) => !prev)}
-											className="flex items-center gap-2 px-5 py-3 rounded-full text-sm font-semibold bg-white/10 text-white hover:bg-white/20 transition-colors cursor-pointer"
-										>
-											<svg
-												className="w-5 h-5"
-												fill="none"
-												stroke="currentColor"
-												viewBox="0 0 24 24"
-											>
-												<path
-													strokeLinecap="round"
-													strokeLinejoin="round"
-													strokeWidth={2}
-													d="M12 4v16m8-8H4"
-												/>
-											</svg>
-											Add to Playlist
-										</button>
-
-										<PlaylistDropdown
-											songId={song.id}
-											isOpen={showPlaylistDropdown}
-											onClose={() => setShowPlaylistDropdown(false)}
-											direction="below"
-										/>
-									</div>
-								</>
-							)}
-						</div>
-					</div>
-				</div>
-
-				{/* Credits / Contributions */}
-				{song.contributions.length > 0 && (
-					<section className="mb-10">
-						<h2 className="text-2xl font-bold mb-4">Credits</h2>
-						<div className="bg-[#1a1a2e]/60 rounded-xl p-5 divide-y divide-white/5">
-							{/* Main artist first */}
-							{song.contributions
-								.filter((c) => c.artistName === song.releasedBy)
-								.map((c, i) => (
-									<div
-										key={`main-${i}`}
-										className="flex items-center justify-between py-3 first:pt-0 last:pb-0"
-									>
-										<div className="flex items-center gap-3">
-											<div className="w-10 h-10 bg-[#1db954] rounded-full flex items-center justify-center text-black font-bold text-sm">
-												{c.artistName.charAt(0).toUpperCase()}
-											</div>
-											<div>
-												<p className="text-white font-semibold text-lg">
-													{c.artistName}
-												</p>
-											</div>
-										</div>
-										<span className="text-sm text-gray-400 bg-white/5 px-3 py-1 rounded-full">
-											{formatRole(c.role)}
-										</span>
-									</div>
-								))}
-
-							{/* Other contributors */}
-							{otherContributors.map((c, i) => (
-								<div
-									key={`contrib-${i}`}
-									className="flex items-center justify-between py-3 first:pt-0 last:pb-0"
-								>
-									<div className="flex items-center gap-3">
-										<div className="w-9 h-9 bg-white/10 rounded-full flex items-center justify-center text-white font-medium text-sm">
-											{c.artistName.charAt(0).toUpperCase()}
-										</div>
-										<p className="text-gray-300 font-medium">{c.artistName}</p>
-									</div>
-									<span className="text-sm text-gray-500 bg-white/5 px-3 py-1 rounded-full">
-										{formatRole(c.role)}
-									</span>
-								</div>
-							))}
-						</div>
-					</section>
-				)}
-
-				{/* Reviews */}
-				<section>
-					<div className="flex items-center justify-between mb-4">
-						<h2 className="text-2xl font-bold">
-							Reviews
-							{song.reviews.length > 0 && (
-								<span className="text-base font-normal text-gray-500 ml-2">
-									({song.reviews.length})
-								</span>
-							)}
-						</h2>
-						{user != null && (
-							<button
-								onClick={() => setShowReviewModal(true)}
-								className="flex items-center gap-2 bg-[#1db954] hover:bg-[#1ed760] text-black text-sm font-semibold px-4 py-2 rounded-full transition-colors cursor-pointer"
-							>
-								<svg
-									className="w-4 h-4"
-									fill="none"
-									stroke="currentColor"
-									viewBox="0 0 24 24"
-								>
-									<path
-										strokeLinecap="round"
-										strokeLinejoin="round"
-										strokeWidth={2}
-										d="M12 4v16m8-8H4"
-									/>
-								</svg>
-								Add Review
-							</button>
-						)}
-					</div>
-
-					{song.reviews.length === 0 ? (
-						<div className="bg-[#1a1a2e]/60 rounded-xl p-10 text-center">
-							<p className="text-gray-500 text-lg">No reviews yet.</p>
-							<p className="text-gray-600 text-sm mt-1">
-								Be the first to share your thoughts!
-							</p>
-						</div>
-					) : (
-						<div className="space-y-4">
-							{song.reviews.map((review) => (
-								<div
-									key={`${review.id.listenerId}-${review.id.musicalEntityId}`}
-									className="bg-[#1a1a2e]/60 rounded-xl p-5 hover:bg-[#1a1a2e]/80 transition-colors"
-								>
-									<div className="flex items-start justify-between mb-2">
-										<div className="flex items-center gap-3">
-											<div className="w-9 h-9 bg-blue-500/20 rounded-full flex items-center justify-center">
-												<span className="text-blue-400 font-semibold text-sm">
-													{review.author.charAt(0).toUpperCase()}
-												</span>
-											</div>
-											<div>
-												<p className="text-white font-medium">
-													{review.author}
-												</p>
-												{renderStars(review.grade)}
-											</div>
-										</div>
-										{user?.username === review.authorUsername && (
-											<button
-												onClick={deleteReview}
-												className="text-gray-500 hover:text-red-400 transition-colors p-2 rounded-lg hover:bg-red-400/10 cursor-pointer"
-												title="Delete review"
-											>
-												<svg
-													className="w-5 h-5"
-													fill="none"
-													stroke="currentColor"
-													viewBox="0 0 24 24"
-												>
-													<path
-														strokeLinecap="round"
-														strokeLinejoin="round"
-														strokeWidth={2}
-														d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
-													/>
-												</svg>
-											</button>
-										)}
-									</div>
-									<p className="text-gray-300 text-sm leading-relaxed mt-3 pl-12">
-										{review.comment}
-									</p>
-								</div>
-							))}
-						</div>
-					)}
-				</section>
-			</div>
-
-			{/* Review Modal */}
-			{showReviewModal && (
-				<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/70 backdrop-blur-sm">
-					<div className="bg-[#1a1a2e] rounded-2xl p-6 max-w-md w-full shadow-2xl">
-						<div className="flex items-center justify-between mb-6">
-							<h3 className="text-2xl font-bold">Add Review</h3>
-							<button
-								onClick={() => {
-									setShowReviewModal(false);
-									setReviewRating(0);
-									setReviewComment("");
-									setHoverRating(0);
-								}}
-								className="text-gray-400 hover:text-white transition-colors cursor-pointer"
-							>
-								<svg
-									className="w-6 h-6"
-									fill="none"
-									stroke="currentColor"
-									viewBox="0 0 24 24"
-								>
-									<path
-										strokeLinecap="round"
-										strokeLinejoin="round"
-										strokeWidth={2}
-										d="M6 18L18 6M6 6l12 12"
-									/>
-								</svg>
-							</button>
-						</div>
-
-						{/* Star Rating */}
-						<div className="mb-6">
-							<label className="block text-sm font-medium mb-3">
-								Rating <span className="text-red-400">*</span>
-							</label>
-							<div className="flex gap-2">
-								{[1, 2, 3, 4, 5].map((star) => (
-									<button
-										key={star}
-										onClick={() => setReviewRating(star)}
-										onMouseEnter={() => setHoverRating(star)}
-										onMouseLeave={() => setHoverRating(0)}
-										className="transition-transform hover:scale-110 cursor-pointer"
-									>
-										<svg
-											className={`w-10 h-10 ${
-												star <= (hoverRating || reviewRating)
-													? "text-yellow-400"
-													: "text-gray-600"
-											}`}
-											fill="currentColor"
-											viewBox="0 0 20 20"
-										>
-											<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
-										</svg>
-									</button>
-								))}
-							</div>
-						</div>
-
-						{/* Comment */}
-						<div className="mb-6">
-							<label className="block text-sm font-medium mb-2">
-								Comment <span className="text-gray-500">(optional)</span>
-							</label>
-							<textarea
-								value={reviewComment}
-								onChange={(e) => setReviewComment(e.target.value)}
-								placeholder="Share your thoughts about this song..."
-								rows={4}
-								className="w-full bg-[#0f0f1e] border border-white/10 rounded-lg px-4 py-3 text-white placeholder-gray-500 focus:outline-none focus:border-[#1db954] transition-colors resize-none"
-							/>
-						</div>
-
-						{/* Actions */}
-						<div className="flex gap-3 justify-end">
-							<button
-								onClick={() => {
-									setShowReviewModal(false);
-									setReviewRating(0);
-									setReviewComment("");
-									setHoverRating(0);
-								}}
-								className="px-5 py-2.5 rounded-full text-sm font-semibold bg-white/10 hover:bg-white/20 transition-colors cursor-pointer"
-							>
-								Cancel
-							</button>
-							<button
-								onClick={handleSubmitReview}
-								disabled={reviewRating === 0}
-								className="px-5 py-2.5 rounded-full text-sm font-semibold bg-[#1db954] hover:bg-[#1ed760] text-black transition-colors disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
-							>
-								Submit
-							</button>
-						</div>
-					</div>
-				</div>
-			)}
-		</div>
-	);
-};
-
-export default SongDetail;
Index: frontend/src/pages/UserDetail.tsx
===================================================================
--- frontend/src/pages/UserDetail.tsx	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,339 +1,0 @@
-import { useEffect, useState } from "react";
-import { Link, useNavigate, useParams } from "react-router-dom";
-import axiosInstance, { baseURL } from "../api/axiosInstance";
-import LoadingSpinner from "../components/LoadingSpinner";
-import ArtistView from "../components/userProfile/ArtistView";
-import ListenerView from "../components/userProfile/ListenerView";
-import UserListModal from "../components/userProfile/UserListModal";
-import { useAuth } from "../context/authContext";
-import { getErrorMessage } from "../utils/error";
-import type {
-  ArtistContribution,
-  BaseNonAdminUser,
-  MusicalEntity,
-  Playlist,
-} from "../utils/types";
-
-interface FollowStatus {
-  isFollowing: boolean;
-  followerCount: number;
-  followingCount: number;
-}
-
-interface Artist extends BaseNonAdminUser {
-  userType: "ARTIST";
-  contributions: ArtistContribution[];
-}
-interface Listener extends BaseNonAdminUser {
-  userType: "LISTENER";
-  likedEntities: MusicalEntity[];
-  createdPlaylists: Playlist[];
-  savedPlaylists: Playlist[];
-}
-
-type UserProfile = Artist | Listener;
-
-const UserDetail = () => {
-  const { username: usernameParam } = useParams();
-  const { user: currentUser } = useAuth();
-
-  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);
-
-  const username = usernameParam || currentUser?.username;
-  const isOwnProfile = currentUser?.username === username;
-
-  if (!usernameParam && !currentUser) {
-    return (
-      <div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] flex items-center justify-center">
-        <div className="text-center">
-          <p className="text-red-400 text-xl mb-4">
-            You must be logged in to view your profile.
-          </p>
-          <button
-            onClick={() => navigate("/login")}
-            className="text-[#1db954] hover:underline text-sm cursor-pointer"
-          >
-            Go to Login
-          </button>
-        </div>
-      </div>
-    );
-  }
-
-  const handleFollow = async () => {
-    if (!user) return;
-
-    setIsFollowing(true);
-    try {
-      const response = await axiosInstance.post<FollowStatus>(
-        `/users/na/${username}/follow`,
-      );
-      setUser((prev) => {
-        if (!prev) return null;
-        return {
-          ...prev,
-          isFollowedByCurrentUser: response.data.isFollowing,
-          followers: response.data.followerCount,
-          following: response.data.followingCount,
-        };
-      });
-    } catch (err: any) {
-      setError(getErrorMessage(err));
-    } finally {
-      setIsFollowing(false);
-    }
-  };
-
-  const handleFollowInModal = async (targetUsername: string) => {
-    try {
-      const response = await axiosInstance.post<FollowStatus>(
-        `/users/na/${targetUsername}/follow`,
-      );
-
-      setModalUsers((prevUsers) =>
-        prevUsers.map((u) =>
-          u.username === targetUsername
-            ? { ...u, isFollowedByCurrentUser: response.data.isFollowing }
-            : u,
-        ),
-      );
-    } catch (err: any) {
-      setError(getErrorMessage(err));
-    }
-  };
-
-  const displayFollowers = async () => {
-    setIsLoadingModal(true);
-    try {
-      const response = await axiosInstance.get(
-        `/users/na/${username}/followers`,
-      );
-      setModalUsers(response.data);
-      setModalTitle("Followers");
-      setShowModal(true);
-    } catch (err) {
-      setError(getErrorMessage(err));
-    } finally {
-      setIsLoadingModal(false);
-    }
-  };
-  const displayFollowing = async () => {
-    setIsLoadingModal(true);
-    try {
-      const response = await axiosInstance.get(
-        `/users/na/${username}/following`,
-      );
-      setModalUsers(response.data);
-      setModalTitle("Following");
-      setShowModal(true);
-    } catch (err: any) {
-      setError(getErrorMessage(err));
-    } finally {
-      setIsLoadingModal(false);
-    }
-  };
-
-  useEffect(() => {
-    const fetchUser = async () => {
-      setError(null);
-      setUser(null);
-      try {
-        const response = await axiosInstance.get(`/users/na/${username}`);
-
-        setUser(response.data);
-      } catch (err: any) {
-        setError(getErrorMessage(err));
-      }
-    };
-    fetchUser();
-  }, [username]);
-
-  if (error) {
-    return (
-      <div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] flex items-center justify-center">
-        <div className="text-center">
-          <p className="text-red-400 text-xl mb-4">{error}</p>
-          <Link to="/" className="text-[#1db954] hover:underline text-sm">
-            ← Back to Home
-          </Link>
-        </div>
-      </div>
-    );
-  }
-
-  if (!user) {
-    return <LoadingSpinner />;
-  }
-
-  return (
-    <div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] text-white">
-      {isLoadingModal && (
-        <div className="fixed inset-0 z-40 bg-black/50 backdrop-blur-sm flex items-center justify-center">
-          <div className="w-10 h-10 border-4 border-white/10 border-t-[#1db954] rounded-full animate-spin" />
-        </div>
-      )}
-
-      <div className="max-w-5xl mx-auto px-6 py-10">
-        {/* Back link */}
-        <Link
-          to="/"
-          className="inline-flex items-center gap-1 text-gray-400 hover:text-white text-sm mb-8 transition-colors"
-        >
-          <svg
-            className="w-4 h-4"
-            fill="none"
-            stroke="currentColor"
-            viewBox="0 0 24 24"
-          >
-            <path
-              strokeLinecap="round"
-              strokeLinejoin="round"
-              strokeWidth={2}
-              d="M15 19l-7-7 7-7"
-            />
-          </svg>
-          Back to Home
-        </Link>
-
-        {/* Hero section */}
-        <div className="flex flex-col md:flex-row gap-8 mb-10">
-          {/* Profile photo */}
-          <div className="w-full md:w-48 shrink-0">
-            <div className="relative w-48 h-48 rounded-full overflow-hidden shadow-2xl bg-[#181818] mx-auto md:mx-0">
-              {user.profilePhoto ? (
-                <img
-                  src={`${baseURL}/${user.profilePhoto}`}
-                  alt={user.fullName}
-                  className="w-full h-full object-cover"
-                />
-              ) : (
-                <div className="w-full h-full bg-linear-to-br from-[#1db954] to-[#1ed760] flex items-center justify-center text-white text-5xl font-bold">
-                  {user.fullName.charAt(0).toUpperCase()}
-                </div>
-              )}
-            </div>
-          </div>
-
-          {/* User info */}
-          <div className="flex flex-col justify-end gap-3 min-w-0">
-            <span className="text-xs uppercase tracking-widest text-gray-400 font-medium">
-              {user.userType === "ARTIST" ? "Artist" : "Listener"} • Profile
-            </span>
-            <h1 className="text-4xl md:text-5xl font-extrabold leading-tight">
-              {user.fullName}
-            </h1>
-            <p className="text-gray-400">@{user.username}</p>
-
-            {/* Stats */}
-            <div className="flex items-center gap-6 mt-2">
-              <div
-                className={`${user.userType === "LISTENER" ? "cursor-pointer hover:text-white" : ""} transition-colors`}
-                onClick={
-                  user.userType === "LISTENER" ? displayFollowers : undefined
-                }
-              >
-                <span className="text-xl font-bold text-white">
-                  {user.followers}
-                </span>
-                <span className="text-sm text-gray-400 ml-1">Followers</span>
-              </div>
-              <div
-                className={`${user.userType === "LISTENER" ? "cursor-pointer hover:text-white" : ""} transition-colors`}
-                onClick={
-                  user.userType === "LISTENER" ? displayFollowing : undefined
-                }
-              >
-                <span className="text-xl font-bold text-white">
-                  {user.following}
-                </span>
-                <span className="text-sm text-gray-400 ml-1">Following</span>
-              </div>
-            </div>
-
-            {/* Follow button - hidden on own profile */}
-            {currentUser && !isOwnProfile && (
-              <div className="mt-4">
-                <button
-                  onClick={handleFollow}
-                  disabled={isFollowing}
-                  className={`flex items-center gap-2 px-6 py-3 rounded-full text-sm font-semibold transition-all cursor-pointer ${
-                    isFollowing
-                      ? "bg-gray-700 text-gray-400 cursor-not-allowed"
-                      : user.isFollowedByCurrentUser
-                        ? "bg-white/10 text-white hover:bg-white/20"
-                        : "bg-[#1db954] text-black hover:bg-[#1ed760] hover:scale-105"
-                  }`}
-                >
-                  {user.isFollowedByCurrentUser ? (
-                    <>
-                      <svg
-                        className="w-5 h-5"
-                        fill="none"
-                        stroke="currentColor"
-                        viewBox="0 0 24 24"
-                      >
-                        <path
-                          strokeLinecap="round"
-                          strokeLinejoin="round"
-                          strokeWidth={2}
-                          d="M5 13l4 4L19 7"
-                        />
-                      </svg>
-                      Following
-                    </>
-                  ) : (
-                    <>
-                      <svg
-                        className="w-5 h-5"
-                        fill="none"
-                        stroke="currentColor"
-                        viewBox="0 0 24 24"
-                      >
-                        <path
-                          strokeLinecap="round"
-                          strokeLinejoin="round"
-                          strokeWidth={2}
-                          d="M12 4v16m8-8H4"
-                        />
-                      </svg>
-                      Follow
-                    </>
-                  )}
-                </button>
-              </div>
-            )}
-          </div>
-        </div>
-
-        {/* Content */}
-        {user.userType === "ARTIST" ? (
-          <ArtistView contributions={user.contributions} />
-        ) : (
-          <ListenerView
-            likedEntities={user.likedEntities}
-            createdPlaylists={user.createdPlaylists}
-            savedPlaylists={user.savedPlaylists}
-          />
-        )}
-
-        {showModal && (
-          <UserListModal
-            title={modalTitle}
-            users={modalUsers}
-            onClose={() => setShowModal(false)}
-            onFollowToggle={handleFollowInModal}
-          />
-        )}
-      </div>
-    </div>
-  );
-};
-
-export default UserDetail;
Index: frontend/src/utils/consts.ts
===================================================================
--- frontend/src/utils/consts.ts	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,34 +1,0 @@
-export const ROLE_OPTIONS = [
-	{ value: "FEATURED", label: "Featured" },
-	{ value: "PRODUCER", label: "Producer" },
-	{ value: "SONGWRITER", label: "Songwriter" },
-	{ value: "COMPOSER", label: "Composer" },
-	{ value: "MIXER", label: "Mixer" },
-	{ value: "ENGINEER", label: "Engineer" },
-];
-
-export const GENRE_OPTIONS = [
-	"Pop",
-	"Rock",
-	"Hip-Hop",
-	"R&B",
-	"Electronic",
-	"Jazz",
-	"Classical",
-	"Country",
-	"Folk",
-	"Latin",
-	"Metal",
-	"Punk",
-	"Indie",
-	"Alternative",
-	"Blues",
-	"Soul",
-	"Reggae",
-	"Funk",
-	"Disco",
-	"House",
-	"Techno",
-	"Ambient",
-	"Other",
-];
Index: frontend/src/utils/error.ts
===================================================================
--- frontend/src/utils/error.ts	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,4 +1,0 @@
-export const getErrorMessage = (err: any) => {
-  const errorMessage = err.response?.data?.error || "Failed to fetch user";
-  return errorMessage;
-};
Index: frontend/src/utils/types.ts
===================================================================
--- frontend/src/utils/types.ts	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,147 +1,0 @@
-export interface User {
-  username: string;
-  fullName: string;
-  email?: string;
-  profilePhoto?: string | null;
-  isAdmin: boolean;
-  isArtist: boolean;
-}
-
-export interface ArtistContribution {
-  id: number;
-  title: string;
-  genre: string;
-  role: string;
-  entityType: string;
-  isLikedByCurrentUser: boolean;
-  cover?: string | null;
-  link?: string | null;
-}
-
-export interface MusicalEntity {
-  id: number;
-  title: string;
-  genre: string;
-  type: string;
-  releasedBy: string;
-  artistUsername?: string;
-  cover?: string | null;
-  isLikedByCurrentUser?: boolean;
-}
-
-export interface Song extends MusicalEntity {
-  type: "SONG";
-  album?: string;
-  albumId?: number;
-  link?: string;
-}
-
-export interface Album extends MusicalEntity {
-  type: "ALBUM";
-  songs: Song[];
-}
-
-export interface Playlist {
-  id: number;
-  name: string;
-  cover: string;
-  creatorName: string;
-  creatorUsername: string;
-  songsInPlaylist: Song[];
-  isSavedByCurrentUser: boolean;
-}
-
-export interface BaseNonAdminUser {
-  username: string;
-  fullName: string;
-  userType: string;
-  profilePhoto: string;
-  followers: number;
-  following: number;
-  isFollowedByCurrentUser: boolean;
-}
-
-export type UserRegisterType = "ARTIST" | "LISTENER";
-
-export type SearchCategory = "songs" | "albums" | "artists" | "users";
-
-export interface SidebarProps {
-  isOpen: boolean;
-  onClose: () => void;
-}
-
-export interface CreatePlaylistModalProps {
-  isOpen: boolean;
-  onClose: () => void;
-  onSuccess: () => void | Promise<void>;
-  songId?: number | null;
-}
-
-export interface SongContribution {
-  artistName: string;
-  role: string;
-}
-
-export interface SongReview {
-  id: {
-    listenerId: number;
-    musicalEntityId: number;
-  };
-  author: string;
-  authorUsername: string;
-  grade: number;
-  comment: string;
-}
-
-export interface SongDetail extends MusicalEntity {
-  type: "SONG";
-  album?: string | null;
-  link?: string | null;
-  contributions: SongContribution[];
-  reviews: SongReview[];
-}
-
-export interface BasicSong {
-  id: number;
-  title: string;
-  artist: string;
-  artistUsername?: string;
-  cover?: string;
-  link?: string;
-  album?: string;
-  albumId?: number;
-}
-
-export interface BasicPlaylist {
-  id: number;
-  name: string;
-  songCount: number;
-}
-
-export interface CatalogItem {
-  id: number;
-  title: string;
-  genre: string;
-  cover: string | null;
-  type: "SONG" | "ALBUM";
-  releaseDate: string;
-}
-
-export interface Contributor {
-  id: number;
-  fullName: string;
-  role: string;
-}
-
-export interface ArtistSearchResult {
-  id: number;
-  username: string;
-  fullName: string;
-  profilePhoto?: string;
-}
-
-export interface SongEntry {
-  title: string;
-  link: string;
-  contributors: Contributor[];
-}
Index: frontend/src/utils/utils.ts
===================================================================
--- frontend/src/utils/utils.ts	(revision 947fcaadc3ddb75ae7bee1ae398ae0f43c988c1e)
+++ 	(revision )
@@ -1,21 +1,0 @@
-export const toEmbedUrl = (url: string): string => {
-	try {
-		const parsed = new URL(url);
-		// youtube.com/watch?v=ID
-		if (
-			(parsed.hostname === "www.youtube.com" ||
-				parsed.hostname === "youtube.com") &&
-			parsed.searchParams.has("v")
-		) {
-			return `https://www.youtube.com/embed/${parsed.searchParams.get("v")}`;
-		}
-		// youtu.be/ID
-		if (parsed.hostname === "youtu.be") {
-			return `https://www.youtube.com/embed${parsed.pathname}`;
-		}
-		// already an embed URL or other provider – return as-is
-		return url;
-	} catch {
-		return url;
-	}
-};
