Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/MusicalEntityController.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/MusicalEntityController.java	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/MusicalEntityController.java	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -1,5 +1,5 @@
 package com.ukim.finki.develop.finkwave.controller;
 
-import com.ukim.finki.develop.finkwave.model.dto.LikeStatusDto;
+import com.ukim.finki.develop.finkwave.model.dto.statusDto.LikeStatusDto;
 import com.ukim.finki.develop.finkwave.model.dto.PublishAlbumRequestDto;
 import com.ukim.finki.develop.finkwave.model.dto.PublishSongRequestDto;
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/NonAdminUserController.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/NonAdminUserController.java	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/NonAdminUserController.java	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -1,5 +1,5 @@
 package com.ukim.finki.develop.finkwave.controller;
 
-import com.ukim.finki.develop.finkwave.model.dto.FollowStatusDto;
+import com.ukim.finki.develop.finkwave.model.dto.statusDto.FollowStatusDto;
 import com.ukim.finki.develop.finkwave.model.dto.NonAdminUserDto;
 import com.ukim.finki.develop.finkwave.service.FollowService;
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/PlaylistController.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/PlaylistController.java	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/PlaylistController.java	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -3,12 +3,10 @@
 import com.ukim.finki.develop.finkwave.model.dto.BasicPlaylistDto;
 import com.ukim.finki.develop.finkwave.model.dto.PlaylistDto;
+import com.ukim.finki.develop.finkwave.model.dto.statusDto.SavePlaylistStatusDto;
 import com.ukim.finki.develop.finkwave.service.PlaylistService;
 import lombok.AllArgsConstructor;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
@@ -30,3 +28,8 @@
     }
 
+    @PostMapping("/{id}/save")
+    public HttpEntity<SavePlaylistStatusDto>savePlaylist(@PathVariable Long id) throws Exception {
+        return ResponseEntity.ok(playlistService.savePlaylist(id));
+    }
+
 }
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/SavedPlaylist.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/SavedPlaylist.java	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/SavedPlaylist.java	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -3,4 +3,5 @@
 import jakarta.persistence.*;
 import lombok.Getter;
+import lombok.NoArgsConstructor;
 import lombok.Setter;
 import org.hibernate.annotations.OnDelete;
@@ -10,4 +11,5 @@
 @Setter
 @Entity
+@NoArgsConstructor
 @Table(name = "saved_playlists", schema = "project")
 public class SavedPlaylist {
@@ -27,3 +29,8 @@
     private Playlist playlist;
 
+    public SavedPlaylist( Listener listener, Playlist playlist) {
+        this.id=new SavedPlaylistId(listener.getId(),playlist.getId());
+        this.listener = listener;
+        this.playlist = playlist;
+    }
 }
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/SavedPlaylistId.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/SavedPlaylistId.java	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/SavedPlaylistId.java	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -4,4 +4,5 @@
 import jakarta.persistence.Embeddable;
 import lombok.Getter;
+import lombok.NoArgsConstructor;
 import lombok.Setter;
 import org.hibernate.Hibernate;
@@ -13,4 +14,5 @@
 @Setter
 @Embeddable
+@NoArgsConstructor
 public class SavedPlaylistId implements Serializable {
     private static final long serialVersionUID = 678748242066896235L;
@@ -20,4 +22,9 @@
     @Column(name = "playlist_id", nullable = false)
     private Long playlistId;
+
+    public SavedPlaylistId(Long listenerId, Long playlistId) {
+        this.listenerId = listenerId;
+        this.playlistId = playlistId;
+    }
 
     @Override
@@ -30,4 +37,6 @@
     }
 
+
+
     @Override
     public int hashCode() {
Index: nkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/FollowStatusDto.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/FollowStatusDto.java	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ 	(revision )
@@ -1,4 +1,0 @@
-package com.ukim.finki.develop.finkwave.model.dto;
-
-public record FollowStatusDto(boolean isFollowing, Long followerCount, Long followingCount)
-{ }
Index: nkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/LikeStatusDto.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/LikeStatusDto.java	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ 	(revision )
@@ -1,4 +1,0 @@
-package com.ukim.finki.develop.finkwave.model.dto;
-
-public record LikeStatusDto(Long entityId,Boolean isLiked, String type) {
-}
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/PlaylistDto.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/PlaylistDto.java	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/PlaylistDto.java	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -15,4 +15,5 @@
     private String cover;
     private String creatorName;
+    private String creatorUsername;
     private List<SongWithLinkDto>songsInPlaylist;
     private Boolean isSavedByCurrentUser;
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/statusDto/FollowStatusDto.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/statusDto/FollowStatusDto.java	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/statusDto/FollowStatusDto.java	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -0,0 +1,4 @@
+package com.ukim.finki.develop.finkwave.model.dto.statusDto;
+
+public record FollowStatusDto(boolean isFollowing, Long followerCount, Long followingCount)
+{ }
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/statusDto/LikeStatusDto.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/statusDto/LikeStatusDto.java	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/statusDto/LikeStatusDto.java	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -0,0 +1,4 @@
+package com.ukim.finki.develop.finkwave.model.dto.statusDto;
+
+public record LikeStatusDto(Long entityId,Boolean isLiked, String type) {
+}
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/statusDto/SavePlaylistStatusDto.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/statusDto/SavePlaylistStatusDto.java	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/dto/statusDto/SavePlaylistStatusDto.java	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -0,0 +1,4 @@
+package com.ukim.finki.develop.finkwave.model.dto.statusDto;
+
+public record SavePlaylistStatusDto(Long id, Boolean isSavedByCurrentUser) {
+}
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/FollowService.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/FollowService.java	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/FollowService.java	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -7,5 +7,5 @@
 import com.ukim.finki.develop.finkwave.model.FollowId;
 import com.ukim.finki.develop.finkwave.model.NonAdminUser;
-import com.ukim.finki.develop.finkwave.model.dto.FollowStatusDto;
+import com.ukim.finki.develop.finkwave.model.dto.statusDto.FollowStatusDto;
 import com.ukim.finki.develop.finkwave.model.dto.NonAdminUserDto;
 import com.ukim.finki.develop.finkwave.repository.ArtistRepository;
@@ -16,5 +16,4 @@
 import org.springframework.stereotype.Service;
 
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/LikeService.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/LikeService.java	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/LikeService.java	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -7,5 +7,5 @@
 import com.ukim.finki.develop.finkwave.model.Listener;
 import com.ukim.finki.develop.finkwave.model.MusicalEntity;
-import com.ukim.finki.develop.finkwave.model.dto.LikeStatusDto;
+import com.ukim.finki.develop.finkwave.model.dto.statusDto.LikeStatusDto;
 import com.ukim.finki.develop.finkwave.model.dto.MusicalEntityDto;
 import com.ukim.finki.develop.finkwave.repository.*;
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/NonAdminUserService.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/NonAdminUserService.java	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/NonAdminUserService.java	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -4,4 +4,5 @@
 import com.ukim.finki.develop.finkwave.model.*;
 import com.ukim.finki.develop.finkwave.model.dto.*;
+import com.ukim.finki.develop.finkwave.model.dto.statusDto.FollowStatusDto;
 import com.ukim.finki.develop.finkwave.repository.*;
 import com.ukim.finki.develop.finkwave.service.mappers.NonAdminUserMapper;
@@ -123,5 +124,5 @@
 
 
-    private PlaylistDto mapToPlaylistDto(Playlist p, Set<Long> savedBy) {
+    private PlaylistDto mapToPlaylistDto(Playlist p, Set<Long> visitorSavedPlaylistIds) {
         return new PlaylistDto(
                 p.getId(),
@@ -129,6 +130,7 @@
                 p.getCover(),
                 p.getCreatedBy().getNonAdminUser().getUser().getFullName(),
+                p.getCreatedBy().getNonAdminUser().getUser().getUsername(),
                 null,
-                savedBy.contains(p.getId())
+                visitorSavedPlaylistIds.contains(p.getId())
         );
     }
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/PlaylistService.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/PlaylistService.java	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/PlaylistService.java	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -2,16 +2,25 @@
 
 import com.ukim.finki.develop.finkwave.exceptions.PlaylistNotFoundException;
+import com.ukim.finki.develop.finkwave.exceptions.UserNotFoundException;
+import com.ukim.finki.develop.finkwave.model.Listener;
 import com.ukim.finki.develop.finkwave.model.Playlist;
+import com.ukim.finki.develop.finkwave.model.SavedPlaylist;
+import com.ukim.finki.develop.finkwave.model.SavedPlaylistId;
 import com.ukim.finki.develop.finkwave.model.dto.BasicPlaylistDto;
 import com.ukim.finki.develop.finkwave.model.dto.PlaylistDto;
 import com.ukim.finki.develop.finkwave.model.dto.SongWithLinkDto;
+import com.ukim.finki.develop.finkwave.model.dto.statusDto.SavePlaylistStatusDto;
+import com.ukim.finki.develop.finkwave.repository.ListenerRepository;
 import com.ukim.finki.develop.finkwave.repository.PlaylistRepository;
 import com.ukim.finki.develop.finkwave.repository.SavedPlaylistRepository;
 import com.ukim.finki.develop.finkwave.repository.SongRepository;
 import lombok.AllArgsConstructor;
+import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.server.ResponseStatusException;
 
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -19,5 +28,5 @@
 @Service
 @AllArgsConstructor
-@Transactional(readOnly = true)
+
 public class PlaylistService {
     private final PlaylistRepository playlistRepository;
@@ -25,4 +34,5 @@
     private final AuthService authService;
     private final SavedPlaylistRepository savedPlaylistRepository;
+    private final ListenerRepository listenerRepository;
 
     public List<Playlist>findByCreatorId(Long id){
@@ -45,4 +55,5 @@
                 playlist.getCover(),
                 playlist.getCreatedBy().getNonAdminUser().getUser().getFullName(),
+                playlist.getCreatedBy().getNonAdminUser().getUser().getUsername(),
                 songsInPlaylist,
                 savedIds.contains(playlist.getId())
@@ -52,10 +63,40 @@
 
     public List<BasicPlaylistDto> getBasicPlaylists(){
-        Long userId = authService.getCurrentUserID();
+        Long userId = authService.getCurrentUserIDOptional().orElse(null);
         return playlistRepository.getPlaylistsByIdIs(userId);
+    }
+
+    @Transactional
+    public SavePlaylistStatusDto savePlaylist(Long playlistId) throws Exception {
+        Long currentUserId=authService.getCurrentUserID();
+        SavedPlaylistId savedPlaylistId=new SavedPlaylistId(currentUserId,playlistId);
+        Playlist playlist=playlistRepository.findById(playlistId).orElseThrow(
+                ()->new PlaylistNotFoundException(playlistId)
+        );
+        if (playlist.getCreatedBy().getId().equals(currentUserId)) {
+            throw new ResponseStatusException(HttpStatus.BAD_REQUEST,"Cannot save playlist created by the current user!");
+        }
+
+
+
+        boolean isSaved;
+
+        if (savedPlaylistRepository.existsById(savedPlaylistId)){
+            savedPlaylistRepository.deleteById(savedPlaylistId);
+            isSaved=false;
+        }
+        else{
+            Listener listener=listenerRepository.findById(currentUserId).orElseThrow(
+                    ()->new UserNotFoundException("Listener not found")
+            );
+
+            savedPlaylistRepository.save(new SavedPlaylist(listener,playlist));
+            isSaved=true;
+        }
+        return new SavePlaylistStatusDto(playlistId,isSaved);
+
     }
 
 
 
-
 }
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/mappers/NonAdminUserMapper.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/mappers/NonAdminUserMapper.java	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/mappers/NonAdminUserMapper.java	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -7,4 +7,5 @@
 import com.ukim.finki.develop.finkwave.model.dto.*;
 import com.ukim.finki.develop.finkwave.model.NonAdminUser;
+import com.ukim.finki.develop.finkwave.model.dto.statusDto.FollowStatusDto;
 import org.springframework.stereotype.Component;
 
Index: frontend/src/components/Sidebar.tsx
===================================================================
--- frontend/src/components/Sidebar.tsx	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ frontend/src/components/Sidebar.tsx	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -1,219 +1,289 @@
 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 type { BasicPlaylist, BasicSong, SidebarProps } from "../utils/types";
+import type { BasicSong, SidebarProps } from "../utils/types";
 import { toEmbedUrl } from "../utils/utils";
+import { useCreatedPlaylists } from "../context/playlistContext";
+import CreatePlaylistModal from "./playlist/CreatePlaylistModal";
+import { getErrorMessage } from "../utils/error";
 
 const Sidebar = ({ isOpen, onClose }: SidebarProps) => {
-	const { user } = useAuth();
-	const navigate = useNavigate();
-	const { play, currentSong } = usePlayer();
-	const [recentlyListened, setRecentlyListened] = useState<BasicSong[]>([]);
-	const [playlists, setPlaylists] = useState<BasicPlaylist[]>([]);
-
-	useEffect(() => {
-		const fetchData = async () => {
-			try {
-				const data = await axiosInstance.get<BasicSong[]>("/songs/recent");
-				setRecentlyListened(data.data);
-			} catch (error) {
-				console.error("Error fetching recently listened songs:", error);
-				// todo: show toast
-			}
-			try {
-				const data =
-					await axiosInstance.get<BasicPlaylist[]>("/playlists/user");
-				setPlaylists(data.data);
-			} catch (error) {
-				console.error("Error fetching playlists:", error);
-				// todo: show toast
-			}
-		};
-		if (user) {
-			fetchData();
-		} else {
-			setRecentlyListened([]);
-			setPlaylists([]);
-		}
-	}, [user]);
-	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"
-						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>
-
-				{/* 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"
-										}`}
-										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">
-						{playlists.map((playlist) => (
-							<div
-								key={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>
-						))}
-					</div>
-				</div>
-			</div>
-		</div>
-	);
+  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 handleCreatePlaylist = async (playlistName: string) => {
+    try {
+      await axiosInstance.post("/playlists", { name: playlistName });
+      toast.success("Playlist created successfully!");
+      await refreshPlaylists();
+    } catch (error) {
+      toast.error(getErrorMessage(error));
+    }
+  };
+
+  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"
+              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"
+                          }`}
+                          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)}
+        onSubmit={handleCreatePlaylist}
+      />
+    </>
+  );
 };
 
Index: frontend/src/components/playlist/CreatePlaylistModal.tsx
===================================================================
--- frontend/src/components/playlist/CreatePlaylistModal.tsx	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
+++ frontend/src/components/playlist/CreatePlaylistModal.tsx	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -0,0 +1,119 @@
+import { useState, useEffect } from "react";
+import type { CreatePlaylistModalProps } from "../../utils/types";
+
+const CreatePlaylistModal = ({
+  isOpen,
+  onClose,
+  onSubmit,
+}: CreatePlaylistModalProps) => {
+  const [playlistName, setPlaylistName] = useState("");
+  const [isClosing, setIsClosing] = useState(false);
+  const [isOpening, setIsOpening] = useState(false);
+
+  useEffect(() => {
+    if (isOpen) {
+      setIsClosing(false);
+      setPlaylistName("");
+      setIsOpening(true);
+      setTimeout(() => setIsOpening(false), 10);
+    }
+  }, [isOpen]);
+
+  const handleClose = () => {
+    setIsClosing(true);
+    setTimeout(() => {
+      onClose();
+      setIsClosing(false);
+    }, 200);
+  };
+
+  const handleSubmit = (e: React.FormEvent) => {
+    e.preventDefault();
+    if (playlistName.trim()) {
+      onSubmit(playlistName.trim());
+      handleClose();
+    }
+  };
+
+  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 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 playlist name"
+              value={playlistName}
+              onChange={(e) => setPlaylistName(e.target.value)}
+            />
+          </div>
+
+          <div className="flex gap-3">
+            <button
+              type="button"
+              onClick={handleClose}
+              className="flex-1 py-3 bg-[#282828] rounded-full text-white font-semibold hover:bg-[#3a3a3a] transition-colors cursor-pointer"
+            >
+              Cancel
+            </button>
+            <button
+              type="submit"
+              disabled={!playlistName.trim()}
+              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"
+            >
+              Create
+            </button>
+          </div>
+        </form>
+      </div>
+    </div>
+  );
+};
+
+export default CreatePlaylistModal;
Index: frontend/src/components/userProfile/ListenerView.tsx
===================================================================
--- frontend/src/components/userProfile/ListenerView.tsx	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ frontend/src/components/userProfile/ListenerView.tsx	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -1,297 +1,343 @@
 import { Album, Bookmark, Heart, ListMusic, Music } from "lucide-react";
 import { useState } from "react";
-import { useNavigate } from "react-router-dom";
+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";
 
 interface ListenerViewProps {
-	likedEntities: MusicalEntity[] | [];
-	createdPlaylists: Playlist[] | [];
-	savedPlaylists: Playlist[] | [];
+  likedEntities: MusicalEntity[] | [];
+  createdPlaylists: Playlist[] | [];
+  savedPlaylists: Playlist[] | [];
 }
 
 const ListenerView = ({
-	likedEntities,
-	createdPlaylists,
-	savedPlaylists,
+  likedEntities,
+  createdPlaylists,
+  savedPlaylists,
 }: ListenerViewProps) => {
-	const navigate = useNavigate();
-	const [items, setItems] = useState(likedEntities);
-	const [savedItems, setSavedItems] = useState(savedPlaylists);
-
-	const likedSongs = items.filter((e) => e.type === "SONG");
-	const likedAlbums = items.filter((e) => e.type === "ALBUM");
-
-	const handleSavePlaylist = async (
-		e: React.MouseEvent,
-		playlistId: number,
-		playlistName: string,
-	) => {
-		e.stopPropagation();
-
-		try {
-			const response = await axiosInstance.post(`/playlist/${playlistId}/save`);
-			const data = response.data;
-
-			setSavedItems((prevItems) =>
-				data.isSaved
-					? [...prevItems, prevItems.find((p) => p.id === playlistId)!]
-					: prevItems.filter((p) => p.id !== playlistId),
-			);
-
-			toast.success(
-				data.isSaved
-					? `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 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">
-			{createdPlaylists && createdPlaylists.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">
-							({createdPlaylists.length})
-						</span>
-					</div>
-
-					<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
-						{createdPlaylists.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";
-										}}
-									/>
-
-									<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"
-										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";
-										}}
-									/>
-
-									<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"
-										title="Unsave"
-									>
-										<Bookmark className="w-5 h-5 fill-[#1db954] text-[#1db954]" />
-									</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)}
-							/>
-						))}
-					</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 &&
-				(!createdPlaylists || createdPlaylists.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>
-	);
+  const navigate = useNavigate();
+  const { username: usernameParam } = useParams();
+  const { user: currentUser } = useAuth();
+  const [items, setItems] = useState(likedEntities);
+  const [createdItems, setCreatedItems] = useState(createdPlaylists);
+  const [savedItems, setSavedItems] = useState(savedPlaylists);
+
+  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 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 &&
+                    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)}
+              />
+            ))}
+          </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>
+  );
 };
 
Index: frontend/src/context/playlistContext.tsx
===================================================================
--- frontend/src/context/playlistContext.tsx	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
+++ frontend/src/context/playlistContext.tsx	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -0,0 +1,76 @@
+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: () => Promise<void>;
+}
+
+interface PlaylistProviderProps {
+  children: ReactNode;
+}
+
+const PlaylistContext = createContext<PlaylistContextType>({
+  createdPlaylists: undefined,
+  setCreatedPlaylists: () => {},
+  isLoading: false,
+  refreshPlaylists: async () => {},
+});
+
+const PlaylistProvider = ({ children }: PlaylistProviderProps) => {
+  const { user } = useAuth();
+  const [createdPlaylists, setCreatedPlaylists] = useState<
+    BasicPlaylist[] | undefined
+  >(undefined);
+  const [isLoading, setIsLoading] = useState(false);
+
+  const fetchCreatedPlaylists = async () => {
+    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();
+    } 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 f5bc95e4a628b62884f4631d8a118a9790052953)
+++ frontend/src/main.tsx	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -5,12 +5,15 @@
 import { PlayerProvider } from "./context/playerContext.tsx";
 import "./index.css";
+import PlaylistProvider from "./context/playlistContext.tsx";
 
 createRoot(document.getElementById("root")!).render(
-	<StrictMode>
-		<AuthProvider>
-			<PlayerProvider>
-				<App />
-			</PlayerProvider>
-		</AuthProvider>
-	</StrictMode>,
+  <StrictMode>
+    <AuthProvider>
+      <PlayerProvider>
+        <PlaylistProvider>
+          <App />
+        </PlaylistProvider>
+      </PlayerProvider>
+    </AuthProvider>
+  </StrictMode>,
 );
Index: frontend/src/pages/MusicalCollection.tsx
===================================================================
--- frontend/src/pages/MusicalCollection.tsx	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ frontend/src/pages/MusicalCollection.tsx	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -3,249 +3,249 @@
 import axiosInstance, { baseURL } from "../api/axiosInstance";
 import SongItem from "../components/SongItem";
-import { handleError } from "../utils/error";
+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[];
+  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 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(handleError(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)}
-								/>
-							))}
-						</div>
-					) : (
-						<div className="text-center py-12 text-gray-400">
-							<p className="text-lg">No songs available</p>
-						</div>
-					)}
-				</div>
-			</div>
-		</div>
-	);
+  const { type, id } = useParams();
+  const [collection, setCollection] = useState<CollectionView | null>(null);
+  const [isLoading, setIsLoading] = useState(true);
+  const [error, setError] = useState<string | 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)}
+                />
+              ))}
+            </div>
+          ) : (
+            <div className="text-center py-12 text-gray-400">
+              <p className="text-lg">No songs available</p>
+            </div>
+          )}
+        </div>
+      </div>
+    </div>
+  );
 };
 
Index: frontend/src/pages/UserDetail.tsx
===================================================================
--- frontend/src/pages/UserDetail.tsx	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ frontend/src/pages/UserDetail.tsx	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -7,27 +7,28 @@
 import UserListModal from "../components/userProfile/UserListModal";
 import { useAuth } from "../context/authContext";
-import { handleError } from "../utils/error";
+import { getErrorMessage } from "../utils/error";
 import type {
-	ArtistContribution,
-	BaseNonAdminUser,
-	MusicalEntity,
-	Playlist,
+  ArtistContribution,
+  BaseNonAdminUser,
+  MusicalEntity,
+  Playlist,
 } from "../utils/types";
+import { useCreatedPlaylists } from "../context/playlistContext";
 
 interface FollowStatus {
-	isFollowing: boolean;
-	followerCount: number;
-	followingCount: number;
+  isFollowing: boolean;
+  followerCount: number;
+  followingCount: number;
 }
 
 interface Artist extends BaseNonAdminUser {
-	userType: "ARTIST";
-	contributions: ArtistContribution[];
+  userType: "ARTIST";
+  contributions: ArtistContribution[];
 }
 interface Listener extends BaseNonAdminUser {
-	userType: "LISTENER";
-	likedEntities: MusicalEntity[];
-	createdPlaylists: Playlist[];
-	savedPlaylists: Playlist[];
+  userType: "LISTENER";
+  likedEntities: MusicalEntity[];
+  createdPlaylists: Playlist[];
+  savedPlaylists: Playlist[];
 }
 
@@ -35,301 +36,305 @@
 
 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(handleError(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(handleError(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(handleError(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(handleError(err));
-		} finally {
-			setIsLoadingModal(false);
-		}
-	};
-
-	useEffect(() => {
-		const fetchUser = async () => {
-			setError(null);
-			try {
-				const response = await axiosInstance.get(`/users/na/${username}`);
-				setUser(response.data);
-			} catch (err: any) {
-				setError(handleError(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 */}
-						{!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>
-	);
+  const { username: usernameParam } = useParams();
+  const { user: currentUser } = useAuth();
+  const { createdPlaylists: currentUserCreatedPlaylists } =
+    useCreatedPlaylists();
+  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 */}
+            {!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>
+  );
 };
 
Index: frontend/src/utils/error.ts
===================================================================
--- frontend/src/utils/error.ts	(revision f5bc95e4a628b62884f4631d8a118a9790052953)
+++ frontend/src/utils/error.ts	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -1,3 +1,3 @@
-export const handleError = (err: any) => {
+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 f5bc95e4a628b62884f4631d8a118a9790052953)
+++ frontend/src/utils/types.ts	(revision 85512ff50bc46445db00d8c3ecea57616baddb36)
@@ -1,62 +1,63 @@
 export interface User {
-	username: string;
-	fullName: string;
-	email?: string;
-	profilePhoto?: string | null;
-	isAdmin: boolean;
-	isArtist: boolean;
+  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;
+  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;
+  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;
+  type: "SONG";
+  album?: string;
+  albumId?: number;
+  link?: string;
 }
 
 export interface Album extends MusicalEntity {
-	type: "ALBUM";
-	songs: Song[];
+  type: "ALBUM";
+  songs: Song[];
 }
 
 export interface Playlist {
-	id: number;
-	name: string;
-	cover: string;
-	creatorName: string;
-	songsInPlaylist: Song[];
-	isSavedByCurrentUser: boolean;
+  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;
+  username: string;
+  fullName: string;
+  userType: string;
+  profilePhoto: string;
+  followers: number;
+  following: number;
+  isFollowedByCurrentUser: boolean;
 }
 
@@ -66,74 +67,80 @@
 
 export interface SidebarProps {
-	isOpen: boolean;
-	onClose: () => void;
+  isOpen: boolean;
+  onClose: () => void;
+}
+
+export interface CreatePlaylistModalProps {
+  isOpen: boolean;
+  onClose: () => void;
+  onSubmit: (playlistName: string) => void;
 }
 
 export interface SongContribution {
-	artistName: string;
-	role: string;
+  artistName: string;
+  role: string;
 }
 
 export interface SongReview {
-	id: {
-		listenerId: number;
-		musicalEntityId: number;
-	};
-	author: string;
-	authorUsername: string;
-	grade: number;
-	comment: string;
+  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[];
+  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;
+  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;
+  id: number;
+  name: string;
+  songCount: number;
 }
 
 export interface CatalogItem {
-	id: number;
-	title: string;
-	genre: string;
-	cover: string | null;
-	type: "SONG" | "ALBUM";
-	releaseDate: string;
+  id: number;
+  title: string;
+  genre: string;
+  cover: string | null;
+  type: "SONG" | "ALBUM";
+  releaseDate: string;
 }
 
 export interface Contributor {
-	id: number;
-	fullName: string;
-	role: string;
+  id: number;
+  fullName: string;
+  role: string;
 }
 
 export interface ArtistSearchResult {
-	id: number;
-	username: string;
-	fullName: string;
-	profilePhoto?: string;
+  id: number;
+  username: string;
+  fullName: string;
+  profilePhoto?: string;
 }
 
 export interface SongEntry {
-	title: string;
-	link: string;
-	contributors: Contributor[];
+  title: string;
+  link: string;
+  contributors: Contributor[];
 }
