Index: frontend/src/App.tsx
===================================================================
--- frontend/src/App.tsx	(revision d2af1a6462831374bb635fedb32ad46c8129abf2)
+++ frontend/src/App.tsx	(revision 0792d02b326867cae564f7072133934be31d9dee)
@@ -51,5 +51,5 @@
       },
       {
-        path: "/users/:userId",
+        path: "/users/:username",
         element: <UserDetail />,
       },
Index: frontend/src/components/userProfile/ListenerView.tsx
===================================================================
--- frontend/src/components/userProfile/ListenerView.tsx	(revision d2af1a6462831374bb635fedb32ad46c8129abf2)
+++ frontend/src/components/userProfile/ListenerView.tsx	(revision 0792d02b326867cae564f7072133934be31d9dee)
@@ -4,12 +4,19 @@
 import axiosInstance from "../../api/axiosInstance";
 import { useState } from "react";
+
 interface ListenerViewProps {
   likedEntities: MusicalEntity[] | [];
-  playlists: Playlist[] | [];
+  createdPlaylists: Playlist[] | [];
+  savedPlaylists: Playlist[] | [];
 }
 
-const ListenerView = ({ likedEntities, playlists }: ListenerViewProps) => {
+const ListenerView = ({
+  likedEntities,
+  createdPlaylists,
+  savedPlaylists,
+}: ListenerViewProps) => {
   const navigate = useNavigate();
   const [items, setItems] = useState(likedEntities);
+  const [savedItems, setSavedItems] = useState(savedPlaylists);
   const [toast, setToast] = useState<{ message: string; show: boolean }>({
     message: "",
@@ -27,8 +34,29 @@
   const likedAlbums = items.filter((e) => e.type === "ALBUM");
 
-  const handleSavePlaylist = (e: React.MouseEvent, playlistId: number) => {
+  const handleSavePlaylist = async (
+    e: React.MouseEvent,
+    playlistId: number,
+    playlistName: string,
+  ) => {
     e.stopPropagation();
 
-    console.log("Save playlist:", playlistId);
+    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),
+      );
+
+      showToast(
+        data.isSaved
+          ? `Saved "${playlistName}"`
+          : `Removed "${playlistName}" from saved playlists`,
+      );
+    } catch (err: any) {
+      showToast(err.response?.data?.error || "Failed to save playlist");
+    }
   };
 
@@ -63,5 +91,6 @@
         </div>
       )}
-      {playlists && playlists.length > 0 && (
+
+      {createdPlaylists && createdPlaylists.length > 0 && (
         <section>
           <div className="flex items-center gap-3 mb-6">
@@ -70,9 +99,11 @@
               Created Playlists
             </h3>
-            <span className="text-sm text-gray-500">({playlists.length})</span>
+            <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">
-            {playlists.map((playlist) => (
+            {createdPlaylists.map((playlist) => (
               <div
                 key={playlist.id}
@@ -93,7 +124,8 @@
                   )}
 
-                  {/* Save button overlay */}
                   <button
-                    onClick={(e) => handleSavePlaylist(e, playlist.id)}
+                    onClick={(e) =>
+                      handleSavePlaylist(e, playlist.id, playlist.name)
+                    }
                     className="absolute top-2 right-2 p-2 bg-white/90 hover:bg-white rounded-full shadow-md transition-all duration-200 opacity-0 group-hover:opacity-100"
                     title={playlist.isSavedByCurrentUser ? "Unsave" : "Save"}
@@ -106,4 +138,56 @@
                       }`}
                     />
+                  </button>
+                </div>
+                <p className="text-sm font-semibold text-gray-900 truncate group-hover:text-blue-600 transition-colors">
+                  {playlist.name}
+                </p>
+                <p className="text-xs text-gray-500 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-blue-600 fill-blue-600" />
+            <h3 className="text-2xl font-bold text-gray-800">
+              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-gray-100 mb-3 shadow-md group-hover:shadow-lg transition-all">
+                  {playlist.cover ? (
+                    <img
+                      src={playlist.cover}
+                      alt={playlist.name}
+                      className="w-full h-full object-cover"
+                    />
+                  ) : (
+                    <div className="w-full h-full bg-gradient-to-br from-blue-400 to-purple-500 flex items-center justify-center">
+                      <ListMusic className="w-16 h-16 text-white opacity-30" />
+                    </div>
+                  )}
+
+                  <button
+                    onClick={(e) =>
+                      handleSavePlaylist(e, playlist.id, playlist.name)
+                    }
+                    className="absolute top-2 right-2 p-2 bg-white/90 hover:bg-white rounded-full shadow-md transition-all duration-200 opacity-0 group-hover:opacity-100"
+                    title="Unsave"
+                  >
+                    <Bookmark className="w-5 h-5 fill-blue-600 text-blue-600" />
                   </button>
                 </div>
@@ -234,5 +318,6 @@
       {likedEntities &&
         likedEntities.length === 0 &&
-        (!playlists || playlists.length === 0) && (
+        (!createdPlaylists || createdPlaylists.length === 0) &&
+        (!savedItems || savedItems.length === 0) && (
           <div className="flex flex-col items-center justify-center py-16 text-gray-400">
             <Music className="w-20 h-20 mb-4 opacity-20" />
Index: frontend/src/components/userProfile/UserListModal.tsx
===================================================================
--- frontend/src/components/userProfile/UserListModal.tsx	(revision d2af1a6462831374bb635fedb32ad46c8129abf2)
+++ frontend/src/components/userProfile/UserListModal.tsx	(revision 0792d02b326867cae564f7072133934be31d9dee)
@@ -6,5 +6,5 @@
   users: BaseNonAdminUser[];
   onClose: () => void;
-  onFollowToggle: (targetId: number) => Promise<void>;
+  onFollowToggle: (targetUsername: string) => Promise<void>;
 }
 
@@ -37,5 +37,5 @@
             users.map((u) => (
               <div
-                key={u.id}
+                key={u.username}
                 className="flex items-center justify-between p-3 hover:bg-gray-50 rounded-lg transition-colors"
               >
@@ -44,5 +44,5 @@
                   onClick={() => {
                     onClose();
-                    navigate(`/users/${u.id}`);
+                    navigate(`/users/${u.username}`);
                   }}
                 >
@@ -64,5 +64,5 @@
 
                 <button
-                  onClick={() => onFollowToggle(u.id)}
+                  onClick={() => onFollowToggle(u.username)}
                   className={`px-4 py-1 text-sm font-medium rounded-md transition-colors cursor-pointer ${
                     u.isFollowedByCurrentUser
Index: frontend/src/pages/AllUsers.tsx
===================================================================
--- frontend/src/pages/AllUsers.tsx	(revision d2af1a6462831374bb635fedb32ad46c8129abf2)
+++ frontend/src/pages/AllUsers.tsx	(revision 0792d02b326867cae564f7072133934be31d9dee)
@@ -4,84 +4,82 @@
 
 interface User {
-	id: number;
-	username: string;
-	fullName: string;
+  username: string;
+  fullName: string;
 }
 
 const AllUsers = () => {
-	const [users, setUsers] = useState<User[]>([]);
-	const [searchedUser, setSearchedUser] = useState<string>("");
-	const [error, setError] = useState<string | null>(null);
-	const navigate = useNavigate();
+  const [users, setUsers] = useState<User[]>([]);
+  const [searchedUser, setSearchedUser] = useState<string>("");
+  const [error, setError] = useState<string | null>(null);
+  const navigate = useNavigate();
 
-	useEffect(() => {
-		const fetchUsers = async () => {
-			const response = axiosInstance.get("/users/all");
-			setUsers((await response).data);
-		};
-		fetchUsers();
-	}, []);
+  useEffect(() => {
+    const fetchUsers = async () => {
+      const response = axiosInstance.get("/users/all");
+      setUsers((await response).data);
+    };
+    fetchUsers();
+  }, []);
 
-	const handleUserClick = (userId: number) => {
-		navigate(`/users/${userId}`);
-	};
+  const handleUserClick = (username: string) => {
+    navigate(`/users/${username}`);
+  };
 
-	const handleSearch = async (e: React.FormEvent) => {
-		e.preventDefault();
-		try {
-			const response = await axiosInstance.get(`/users/search`, {
-				params: { name: searchedUser },
-			});
-			setUsers(response.data);
-		} catch (err: any) {
-			const errorMessage = err.response?.data?.error || "Search failed";
-			setError(errorMessage);
-		}
-	};
+  const handleSearch = async (e: React.FormEvent) => {
+    e.preventDefault();
+    try {
+      const response = await axiosInstance.get(`/users/search`, {
+        params: { name: searchedUser },
+      });
+      setUsers(response.data);
+    } catch (err: any) {
+      const errorMessage = err.response?.data?.error || "Search failed";
+      setError(errorMessage);
+    }
+  };
 
-	if (users.length == 0) return <div className="p-6">Loading...</div>;
-	if (error) {
-		return (
-			<div className="p-6 bg-red-50 border border-red-200 text-red-700 rounded-lg">
-				<h2 className="font-bold">Error</h2>
-				<p>{error}</p>
-			</div>
-		);
-	}
+  if (users.length == 0) return <div className="p-6">Loading...</div>;
+  if (error) {
+    return (
+      <div className="p-6 bg-red-50 border border-red-200 text-red-700 rounded-lg">
+        <h2 className="font-bold">Error</h2>
+        <p>{error}</p>
+      </div>
+    );
+  }
 
-	return (
-		<div className="container mx-auto p-6">
-			<h1 className="text-3xl font-bold mb-6">All Users</h1>
-			<form onSubmit={handleSearch} className="flex gap-2 mb-10">
-				<input
-					type="text"
-					value={searchedUser}
-					onChange={(e) => setSearchedUser(e.target.value)}
-					className="border p-2 rounded w-full"
-					placeholder="Search for a user..."
-				/>
-				<button
-					type="submit"
-					className="bg-blue-600 text-white px-6 py-2 rounded hover:bg-blue-700 transition-colors"
-				>
-					Search
-				</button>
-			</form>
+  return (
+    <div className="container mx-auto p-6">
+      <h1 className="text-3xl font-bold mb-6">All Users</h1>
+      <form onSubmit={handleSearch} className="flex gap-2 mb-10">
+        <input
+          type="text"
+          value={searchedUser}
+          onChange={(e) => setSearchedUser(e.target.value)}
+          className="border p-2 rounded w-full"
+          placeholder="Search for a user..."
+        />
+        <button
+          type="submit"
+          className="bg-blue-600 text-white px-6 py-2 rounded hover:bg-blue-700 transition-colors"
+        >
+          Search
+        </button>
+      </form>
 
-			<div className="grid gap-4">
-				{users.map((u) => (
-					<div
-						key={u.id}
-						onClick={() => handleUserClick(u.id)}
-						className="bg-white shadow-md rounded-lg p-4 hover:shadow-lg hover:bg-gray-50 cursor-pointer transition-all"
-					>
-						<h2 className="text-xl font-semibold">{u.fullName}</h2>
-						<p className="text-gray-600">@{u.username}</p>
-						<p className="text-gray-600">{u.id}</p>
-					</div>
-				))}
-			</div>
-		</div>
-	);
+      <div className="grid gap-4">
+        {users.map((u) => (
+          <div
+            key={u.username}
+            onClick={() => handleUserClick(u.username)}
+            className="bg-white shadow-md rounded-lg p-4 hover:shadow-lg hover:bg-gray-50 cursor-pointer transition-all"
+          >
+            <h2 className="text-xl font-semibold">{u.fullName}</h2>
+            <p className="text-gray-600">@{u.username}</p>
+          </div>
+        ))}
+      </div>
+    </div>
+  );
 };
 
Index: frontend/src/pages/UserDetail.tsx
===================================================================
--- frontend/src/pages/UserDetail.tsx	(revision d2af1a6462831374bb635fedb32ad46c8129abf2)
+++ frontend/src/pages/UserDetail.tsx	(revision 0792d02b326867cae564f7072133934be31d9dee)
@@ -27,4 +27,5 @@
   likedEntities: MusicalEntity[];
   createdPlaylists: Playlist[];
+  savedPlaylists: Playlist[];
 }
 
@@ -34,5 +35,5 @@
   // user refers to the selected user NOT to the user from context
   const baseURL = import.meta.env.VITE_API_BASE_URL;
-  const { userId } = useParams();
+  const { username } = useParams();
   const navigate = useNavigate();
   const [user, setUser] = useState<UserProfile | null>(null);
@@ -50,5 +51,5 @@
     try {
       const response = await axiosInstance.post<FollowStatus>(
-        `/users/${userId}/follow`,
+        `/users/${username}/follow`,
       );
       setUser((prev) => {
@@ -68,13 +69,13 @@
   };
 
-  const handleFollowInModal = async (targetId: number) => {
+  const handleFollowInModal = async (targetUsername: string) => {
     try {
       const response = await axiosInstance.post<FollowStatus>(
-        `/users/${targetId}/follow`,
+        `/users/${username}/follow`,
       );
 
       setModalUsers((prevUsers) =>
         prevUsers.map((u) =>
-          u.id === targetId
+          u.username === targetUsername
             ? { ...u, isFollowedByCurrentUser: response.data.isFollowing }
             : u,
@@ -100,5 +101,5 @@
     setIsLoadingModal(true);
     try {
-      const response = await axiosInstance.get(`/users/${userId}/followers`);
+      const response = await axiosInstance.get(`/users/${username}/followers`);
       setModalUsers(response.data);
       setModalTitle("Followers");
@@ -113,5 +114,5 @@
     setIsLoadingModal(true);
     try {
-      const response = await axiosInstance.get(`/users/${userId}/following`);
+      const response = await axiosInstance.get(`/users/${username}/following`);
       setModalUsers(response.data);
       setModalTitle("Following");
@@ -128,5 +129,5 @@
       setError(null);
       try {
-        const response = await axiosInstance.get(`/users/${userId}`);
+        const response = await axiosInstance.get(`/users/${username}`);
         console.log(response.data);
         setUser(response.data);
@@ -136,5 +137,5 @@
     };
     fetchUser();
-  }, [userId]);
+  }, [username]);
 
   if (error) {
@@ -233,5 +234,6 @@
           <ListenerView
             likedEntities={user.likedEntities}
-            playlists={user.createdPlaylists}
+            createdPlaylists={user.createdPlaylists}
+            savedPlaylists={user.savedPlaylists}
           />
         )}
Index: frontend/src/utils/types.ts
===================================================================
--- frontend/src/utils/types.ts	(revision d2af1a6462831374bb635fedb32ad46c8129abf2)
+++ frontend/src/utils/types.ts	(revision 0792d02b326867cae564f7072133934be31d9dee)
@@ -44,5 +44,5 @@
 
 export interface BaseNonAdminUser {
-  id: number;
+  username: string;
   fullName: string;
   userType: string;
