Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/AlbumController.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/AlbumController.java	(revision 694fc2568864281fe140fdc23e96cb6585170e74)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/AlbumController.java	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -6,8 +6,7 @@
 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;
 
 @RestController
@@ -15,5 +14,4 @@
 @RequestMapping("/albums")
 public class AlbumController {
-
     private final AlbumService albumService;
 
@@ -23,3 +21,8 @@
     }
 
+    @GetMapping("/search")
+    public HttpEntity<List<MusicalEntityDto>> searchAlbums(@RequestParam(name = "q") String searchTerm){
+        return ResponseEntity.ok(albumService.searchAlbums(searchTerm));
+    }
+
 }
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 694fc2568864281fe140fdc23e96cb6585170e74)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/NonAdminUserController.java	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -15,5 +15,5 @@
 @CrossOrigin("*")
 @RequiredArgsConstructor
-@RequestMapping("/users")
+@RequestMapping("/users/na/")
 public class NonAdminUserController {
 
@@ -27,10 +27,10 @@
 
     @GetMapping("/{username}")
-    public HttpEntity<NonAdminUserDto>getById(@PathVariable String username){
+    public HttpEntity<NonAdminUserDto>getNonAdminUserById(@PathVariable String username){
         return ResponseEntity.ok(nonAdminUserService.getNonAdminUserProfile(username));
     }
 
     @GetMapping("/search")
-    public HttpEntity<List<NonAdminUserDto>>searchUsers(@RequestParam String name){
+    public HttpEntity<List<NonAdminUserDto>>searchNonAdminUsers(@RequestParam String name){
         return ResponseEntity.ok(nonAdminUserService.searchUsers(name));
     }
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/SongController.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/SongController.java	(revision 694fc2568864281fe140fdc23e96cb6585170e74)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/SongController.java	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -10,4 +10,5 @@
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -18,12 +19,17 @@
 @AllArgsConstructor
 public class SongController {
-    private final SongRepository songRepository;
     private final AuthService authService;
     private final SongService songService;
 
-    @GetMapping
+    @GetMapping("/top")
     private HttpEntity<List<MusicalEntityDto>> getSongs(){
         Long userId = authService.getCurrentUserID();
         return ResponseEntity.ok(songService.getTopSongs(userId));
     }
+
+    @GetMapping("/search")
+    private HttpEntity<List<MusicalEntityDto>> searchSongs(
+            @RequestParam(name = "q") String searchTerm){
+        return ResponseEntity.ok(songService.searchSongs(null, searchTerm));
+    }
 }
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/TestController.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/TestController.java	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/TestController.java	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -0,0 +1,36 @@
+package com.ukim.finki.develop.finkwave.controller;
+
+import com.ukim.finki.develop.finkwave.model.MusicalEntity;
+import com.ukim.finki.develop.finkwave.model.User;
+import com.ukim.finki.develop.finkwave.model.dto.MusicalEntityDto;
+import com.ukim.finki.develop.finkwave.repository.SongRepository;
+import com.ukim.finki.develop.finkwave.repository.UserRepository;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@AllArgsConstructor
+@RequestMapping("/test")
+public class TestController {
+    private final SongRepository songRepository;
+    private final UserRepository userRepository;
+
+    @GetMapping("/search/{searchTerm}")
+    public HttpEntity<List<MusicalEntityDto>> searchSongsTest(@PathVariable String searchTerm){
+        return ResponseEntity.ok(songRepository.searchSongs(null, searchTerm));
+    }
+
+    @GetMapping("/search/u/{searchTerm}")
+    public HttpEntity<List<User>> searchUsersTest(@PathVariable String searchTerm){
+        return ResponseEntity.ok(userRepository.searchListeners(searchTerm));
+    }
+    @GetMapping("/search/a/{searchTerm}")
+    public HttpEntity<List<User>> searchArtistsTest(@PathVariable String searchTerm){
+        return ResponseEntity.ok(userRepository.searchArtists(searchTerm));
+    }
+}
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/UserController.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/UserController.java	(revision 694fc2568864281fe140fdc23e96cb6585170e74)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/UserController.java	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -2,11 +2,10 @@
 
 import com.ukim.finki.develop.finkwave.model.User;
+import com.ukim.finki.develop.finkwave.model.enums.UserType;
 import com.ukim.finki.develop.finkwave.service.UserService;
 import lombok.RequiredArgsConstructor;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.CrossOrigin;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
@@ -15,4 +14,5 @@
 @CrossOrigin("*")
 @RequiredArgsConstructor
+@RequestMapping("/users")
 public class UserController {
     private final UserService usersService;
@@ -23,4 +23,9 @@
     }
 
-
+    @GetMapping("/search")
+    public HttpEntity<List<User>> searchArtists(
+            @RequestParam(name = "type") UserType userType,
+            @RequestParam(name = "q") String searchTerm){
+        return ResponseEntity.ok(usersService.search(userType, searchTerm));
+    }
 }
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/repository/AlbumRepository.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/repository/AlbumRepository.java	(revision 694fc2568864281fe140fdc23e96cb6585170e74)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/repository/AlbumRepository.java	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -1,5 +1,8 @@
 package com.ukim.finki.develop.finkwave.repository;
 
+import com.ukim.finki.develop.finkwave.model.dto.MusicalEntityDto;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
 import org.springframework.stereotype.Repository;
 
@@ -12,3 +15,18 @@
 
     List<Album>findAllByIdIn(List<Long>ids);
+
+
+    @Query("""
+            SELECT NEW com.ukim.finki.develop.finkwave.model.dto.MusicalEntityDto(
+            a.id, me.title, me.genre, 'ALBUM', u.fullName, me.cover, FALSE )
+            FROM Album a
+            JOIN a.musicalEntities me
+            JOIN me.releasedBy rb
+            JOIN rb.nonAdminUser nau
+            JOIN nau.user u
+            WHERE me.title ILIKE %:searchTerm%
+            """
+    )
+    List<MusicalEntityDto> searchAlbums(@Param("currentUserId")Long currentUserId, @Param("searchTerm") String searchTerm);
+
 }
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/repository/SongRepository.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/repository/SongRepository.java	(revision 694fc2568864281fe140fdc23e96cb6585170e74)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/repository/SongRepository.java	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -15,62 +15,67 @@
 
 
-    @Query("SELECT NEW com.ukim.finki.develop.finkwave.model.dto.MusicalEntityDto(" +
-            "s.id, " +
-            "me.title, " +
-            "me.genre, " +
-            "'SONG', " +
-            "u.fullName, " +
-            "me.cover," +
-            "(CASE WHEN :currentUserId IS NOT NULL AND l.id IS NOT NULL THEN true ELSE false END)) " +
-            "FROM Song s " +
-            "JOIN s.musicalEntities me " +
-            "JOIN me.releasedBy a " +
-            "JOIN a.nonAdminUser nau " +
-            "JOIN nau.user u "+
-            "LEFT JOIN Like l ON l.musicalEntity.id = s.id AND l.listener.id = :currentUserId " +
-            "WHERE s.album.id = :albumId"
+    @Query("""
+            SELECT NEW com.ukim.finki.develop.finkwave.model.dto.MusicalEntityDto(
+                s.id, me.title, me.genre, 'SONG', u.fullName, me.cover,
+                (CASE WHEN :currentUserId IS NOT NULL AND l.id IS NOT NULL THEN true ELSE false END)
+            )
+            FROM Song s
+            JOIN s.musicalEntities me
+            JOIN me.releasedBy a
+            JOIN a.nonAdminUser nau
+            JOIN nau.user u
+            LEFT JOIN Like l ON l.musicalEntity.id = s.id AND l.listener.id = :currentUserId
+            WHERE s.album.id = :albumId
+            """
     )
     List<MusicalEntityDto>findSongsByAlbum(@Param("albumId") Long albumId, @Param("currentUserId")Long currentUserId);
 
 
-    @Query("SELECT NEW com.ukim.finki.develop.finkwave.model.dto.MusicalEntityDto(" +
-            "s.id, " +
-            "me.title, " +
-            "me.genre, " +
-            "'SONG', " +
-            "u.fullName, " +
-            "me.cover," +
-            "(CASE WHEN :currentUserId IS NOT NULL AND l.id IS NOT NULL THEN true ELSE false END)) " +
-            "FROM Song s "+
-            "JOIN s.musicalEntities me "+
-            "JOIN me.releasedBy a "+
-            "JOIN a.nonAdminUser nau "+
-            "JOIN nau.user u "+
-            "JOIN PlaylistSong ps ON ps.song.id=s.id "+
-            "LEFT JOIN Like l ON l.musicalEntity.id=s.id AND l.listener.id=:currentUserId "+
-            "WHERE ps.playlist.id=:playlistId")
+    @Query("""
+            SELECT NEW com.ukim.finki.develop.finkwave.model.dto.MusicalEntityDto(
+            s.id, me.title, me.genre, 'SONG', u.fullName, me.cover,
+            (CASE WHEN :currentUserId IS NOT NULL AND l.id IS NOT NULL THEN true ELSE false END))
+            FROM Song s
+            JOIN s.musicalEntities me
+            JOIN me.releasedBy a
+            JOIN a.nonAdminUser nau
+            JOIN nau.user u
+            JOIN PlaylistSong ps ON ps.song.id=s.id
+            LEFT JOIN Like l ON l.musicalEntity.id=s.id AND l.listener.id=:currentUserId
+            WHERE ps.playlist.id=:playlistId
+    """)
     List<MusicalEntityDto>findSongsByPlaylistId(@Param("playlistId")Long playlistId, @Param("currentUserId")Long currentUserId);
 
-    @Query("SELECT NEW com.ukim.finki.develop.finkwave.model.dto.MusicalEntityDto(" +
-            "s.id, " +
-            "me.title, " +
-            "me.genre, " +
-            "'SONG', " +
-            "u.fullName, " +
-            "me.cover," +
-            "FALSE ) " +
-//            "(CASE WHEN :currentUserId IS NOT NULL AND l.id IS NOT NULL THEN true ELSE false END)) " +
-//            "COUNT(*) " +
-            "FROM Song s "+
-            "JOIN s.musicalEntities me " +
-            "JOIN me.releasedBy a " +
-            "JOIN a.nonAdminUser nau "+
-            "JOIN nau.user u " +
-            "JOIN Listen l on l.song.id = s.id " +
-            "GROUP BY s.id, me.title, me.genre, u.fullName, me.cover " +
-            "ORDER BY count(*) desc "
+    @Query("""
+            SELECT NEW com.ukim.finki.develop.finkwave.model.dto.MusicalEntityDto(
+            s.id, me.title, me.genre, 'SONG', u.fullName, me.cover, FALSE)
+            FROM Song s
+            JOIN s.musicalEntities me
+            JOIN me.releasedBy a
+            JOIN a.nonAdminUser nau
+            JOIN nau.user u
+            JOIN Listen l on l.song.id = s.id
+            GROUP BY s.id, me.title, me.genre, u.fullName, me.cover
+            ORDER BY count(*) desc
+    """
     )
     // todo: handle likes, momentalno site se false za da raboti joinot
     // todo: add paging
     List<MusicalEntityDto> findTopByListens(@Param("currentUserId")Long currentUserId);
+
+
+    // todo: fix is liked by user, currently returns hard coded false
+    @Query("""
+            SELECT NEW com.ukim.finki.develop.finkwave.model.dto.MusicalEntityDto(
+            s.id, me.title, me.genre, 'SONG', u.fullName, me.cover, FALSE )
+            FROM Song s
+            JOIN s.musicalEntities me
+            JOIN me.releasedBy a
+            JOIN a.nonAdminUser nau
+            JOIN nau.user u
+            WHERE me.title ILIKE %:searchTerm%
+            """
+    )
+    List<MusicalEntityDto> searchSongs(@Param("currentUserId")Long currentUserId, @Param("searchTerm") String searchTerm);
+
 }
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/repository/UserRepository.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/repository/UserRepository.java	(revision 694fc2568864281fe140fdc23e96cb6585170e74)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/repository/UserRepository.java	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -3,6 +3,8 @@
 import com.ukim.finki.develop.finkwave.model.User;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
 import org.springframework.stereotype.Repository;
 
+import java.util.List;
 import java.util.Optional;
 
@@ -10,3 +12,18 @@
 public interface UserRepository extends JpaRepository<User, Long> {
     Optional<User> findByUsername(String username);
+
+
+    @Query("""
+        SELECT u from User u
+        WHERE (u.fullName ilike %:searchTerm% or u.username ilike %:searchTerm%)
+            and u.listener = true and u.artist = false 
+        """)
+    List<User> searchListeners(String searchTerm);
+
+    @Query("""
+        SELECT u from User u
+        WHERE (u.fullName ilike %:searchTerm% or u.username ilike %:searchTerm%)
+            and u.artist = true
+        """)
+    List<User> searchArtists(String searchTerm);
 }
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/AlbumService.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/AlbumService.java	(revision 694fc2568864281fe140fdc23e96cb6585170e74)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/AlbumService.java	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -39,5 +39,8 @@
         dto.setSongs(songsFromAlbum);
         return dto;
+    }
 
+    public List<MusicalEntityDto> searchAlbums(String searchTerm){
+        return albumRepository.searchAlbums(authService.getCurrentUserID(), searchTerm);
     }
 
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/SongService.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/SongService.java	(revision 694fc2568864281fe140fdc23e96cb6585170e74)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/SongService.java	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -16,3 +16,7 @@
         return songRepository.findTopByListens(userId);
     }
+
+    public List<MusicalEntityDto> searchSongs(Long userId, String searchTerm){
+        return songRepository.searchSongs(userId, searchTerm);
+    }
 }
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/UserService.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/UserService.java	(revision 694fc2568864281fe140fdc23e96cb6585170e74)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/UserService.java	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -2,4 +2,5 @@
 
 import com.ukim.finki.develop.finkwave.model.User;
+import com.ukim.finki.develop.finkwave.model.enums.UserType;
 import com.ukim.finki.develop.finkwave.repository.UserRepository;
 import lombok.AllArgsConstructor;
@@ -17,3 +18,14 @@
     }
 
+    // todo: add dto-s
+
+    public List<User> search(UserType userType, String searchTerm){
+
+        return switch (userType) {
+            case ARTIST -> usersRepository.searchArtists(searchTerm);
+            case LISTENER -> usersRepository.searchListeners(searchTerm);
+            case null -> throw new IllegalArgumentException("Invalid userType");
+        };
+    }
+
 }
Index: frontend/src/App.tsx
===================================================================
--- frontend/src/App.tsx	(revision 694fc2568864281fe140fdc23e96cb6585170e74)
+++ frontend/src/App.tsx	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -1,71 +1,83 @@
+import { useState } from "react";
 import { createBrowserRouter, Outlet, RouterProvider } from "react-router-dom";
 import { ToastContainer } from "react-toastify";
 import "react-toastify/dist/ReactToastify.css";
+import Sidebar from "./components/Sidebar";
 import AllUsers from "./pages/AllUsers";
 import LandingPage from "./pages/LandingPage";
 import Login from "./pages/Login";
+import MusicalCollection from "./pages/MusicalCollection";
 import Nav from "./pages/Nav";
 import Register from "./pages/Register";
 import UserDetail from "./pages/UserDetail";
-import MusicalCollection from "./pages/MusicalCollection";
 
 const Layout = () => {
-  return (
-    <div className="flex flex-col min-h-screen">
-      <Nav />
-      <ToastContainer
-        position="top-right"
-        autoClose={2000}
-        hideProgressBar={false}
-        newestOnTop={false}
-        closeOnClick
-        rtl={false}
-        pauseOnFocusLoss
-        draggable
-        pauseOnHover
-        theme="light"
-      />
-      <main className="grow">
-        <Outlet />
-      </main>
-    </div>
-  );
+	const [isSidebarOpen, setIsSidebarOpen] = useState(true);
+
+	return (
+		<div className="flex flex-col min-h-screen bg-[#121212]">
+			<Nav
+				isSidebarOpen={isSidebarOpen}
+				onToggleSidebar={() => setIsSidebarOpen(!isSidebarOpen)}
+			/>
+			<Sidebar isOpen={isSidebarOpen} onClose={() => setIsSidebarOpen(false)} />
+			<ToastContainer
+				position="top-right"
+				autoClose={2000}
+				hideProgressBar={false}
+				newestOnTop={false}
+				closeOnClick
+				rtl={false}
+				pauseOnFocusLoss
+				draggable
+				pauseOnHover
+				theme="light"
+			/>
+			<main
+				className={`grow transition-all duration-300 pt-20 ${
+					isSidebarOpen ? "ml-64" : "ml-0"
+				}`}
+			>
+				<Outlet />
+			</main>
+		</div>
+	);
 };
 
 const router = createBrowserRouter([
-  {
-    path: "",
-    element: <Layout />,
-    children: [
-      {
-        path: "/",
-        element: <LandingPage />,
-      },
-      {
-        path: "/login",
-        element: <Login />,
-      },
-      {
-        path: "/users",
-        element: <AllUsers />,
-      },
-      {
-        path: "/users/:username",
-        element: <UserDetail />,
-      },
-      {
-        path: "/register",
-        element: <Register />,
-      },
-      {
-        path: "/collection/:type/:id",
-        element: <MusicalCollection />,
-      },
-    ],
-  },
+	{
+		path: "",
+		element: <Layout />,
+		children: [
+			{
+				path: "/",
+				element: <LandingPage />,
+			},
+			{
+				path: "/login",
+				element: <Login />,
+			},
+			{
+				path: "/users",
+				element: <AllUsers />,
+			},
+			{
+				path: "/users/:username",
+				element: <UserDetail />,
+			},
+			{
+				path: "/register",
+				element: <Register />,
+			},
+			{
+				path: "/collection/:type/:id",
+				element: <MusicalCollection />,
+			},
+		],
+	},
 ]);
 
 function App() {
-  return <RouterProvider router={router} />;
+	return <RouterProvider router={router} />;
 }
 
Index: frontend/src/components/Sidebar.tsx
===================================================================
--- frontend/src/components/Sidebar.tsx	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
+++ frontend/src/components/Sidebar.tsx	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -0,0 +1,123 @@
+interface SidebarProps {
+	isOpen: boolean;
+	onClose: () => void;
+}
+
+const Sidebar = ({ isOpen, onClose }: SidebarProps) => {
+	// mock data for recently listened songs
+	const recentlyListened = [
+		{ id: 1, title: "Song One", artist: "Artist A", cover: "/favicon.png" },
+		{ id: 2, title: "Song Two", artist: "Artist B", cover: "/favicon.png" },
+		{ id: 3, title: "Song Three", artist: "Artist C", cover: "/favicon.png" },
+		{ id: 4, title: "Song Four", artist: "Artist D", cover: "/favicon.png" },
+		{ id: 5, title: "Song Five", artist: "Artist E", cover: "/favicon.png" },
+	];
+
+	// mock data for my playlists
+	const playlists = [
+		{ id: 1, name: "My Favorites", songCount: 25 },
+		{ id: 2, name: "Workout Mix", songCount: 18 },
+		{ id: 3, name: "Chill Vibes", songCount: 32 },
+		{ id: 4, name: "Party Hits", songCount: 45 },
+	];
+
+	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"
+							>
+								<img
+									src={song.cover}
+									alt={song.title}
+									className="w-10 h-10 rounded object-cover"
+								/>
+								<div className="flex-1 min-w-0">
+									<p className="text-sm font-medium text-white truncate">
+										{song.title}
+									</p>
+									<p className="text-xs text-gray-400 truncate">
+										{song.artist}
+									</p>
+								</div>
+							</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>
+	);
+};
+
+export default Sidebar;
Index: frontend/src/components/search/AlbumResult.tsx
===================================================================
--- frontend/src/components/search/AlbumResult.tsx	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
+++ frontend/src/components/search/AlbumResult.tsx	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -0,0 +1,31 @@
+import type { Album } from "../../utils/types";
+
+interface AlbumResultProps {
+	album: Album;
+}
+
+const AlbumResult = ({ album }: AlbumResultProps) => {
+	return (
+		<div className="flex items-center gap-4 p-3 rounded-lg hover:bg-white/5 cursor-pointer transition-colors group">
+			<img
+				src={album.cover || "/favicon.png"}
+				alt={album.title}
+				className="w-12 h-12 rounded object-cover"
+				onError={(e) => {
+					(e.target as HTMLImageElement).src = "/favicon.png";
+				}}
+			/>
+			<div className="flex-1 min-w-0">
+				<p className="text-white font-medium truncate">{album.title}</p>
+				<p className="text-sm text-gray-400 truncate">
+					Album • {album.releasedBy} • {album.songs?.length ?? 0} songs
+				</p>
+			</div>
+			<span className="text-xs text-gray-500 uppercase tracking-wider">
+				{album.genre}
+			</span>
+		</div>
+	);
+};
+
+export default AlbumResult;
Index: frontend/src/components/search/SongResult.tsx
===================================================================
--- frontend/src/components/search/SongResult.tsx	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
+++ frontend/src/components/search/SongResult.tsx	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -0,0 +1,31 @@
+import type { Song } from "../../utils/types";
+
+interface SongResultProps {
+	song: Song;
+}
+
+const SongResult = ({ song }: SongResultProps) => {
+	return (
+		<div className="flex items-center gap-4 p-3 rounded-lg hover:bg-white/5 cursor-pointer transition-colors group">
+			<img
+				src={song.cover || "/favicon.png"}
+				alt={song.title}
+				className="w-12 h-12 rounded object-cover"
+				onError={(e) => {
+					(e.target as HTMLImageElement).src = "/favicon.png";
+				}}
+			/>
+			<div className="flex-1 min-w-0">
+				<p className="text-white font-medium truncate">{song.title}</p>
+				<p className="text-sm text-gray-400 truncate">
+					Song • {song.releasedBy}
+				</p>
+			</div>
+			<span className="text-xs text-gray-500 uppercase tracking-wider">
+				{song.genre}
+			</span>
+		</div>
+	);
+};
+
+export default SongResult;
Index: frontend/src/components/search/UserResult.tsx
===================================================================
--- frontend/src/components/search/UserResult.tsx	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
+++ frontend/src/components/search/UserResult.tsx	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -0,0 +1,38 @@
+import { baseURL } from "../../api/axiosInstance";
+import type { BaseNonAdminUser } from "../../utils/types";
+
+interface UserResultProps {
+	user: BaseNonAdminUser;
+	label: "Artist" | "User";
+}
+
+const UserResult = ({ user, label }: UserResultProps) => {
+	return (
+		<div className="flex items-center gap-4 p-3 rounded-lg hover:bg-white/5 cursor-pointer transition-colors group">
+			{user.profilePhoto ? (
+				<img
+					src={`${baseURL}/${user.profilePhoto}`}
+					alt={user.username}
+					className="w-12 h-12 rounded-full object-cover"
+				/>
+			) : (
+				<div className="w-12 h-12 bg-blue-500 rounded-full flex items-center justify-center">
+					<span className="text-white text-lg font-semibold">
+						{user.username.charAt(0).toUpperCase()}
+					</span>
+				</div>
+			)}
+			<div className="flex-1 min-w-0">
+				<p className="text-white font-medium truncate">{user.fullName}</p>
+				<p className="text-sm text-gray-400 truncate">
+					{label} • @{user.username}
+				</p>
+			</div>
+			<div className="text-right text-xs text-gray-500">
+				<p>{user.followers} followers</p>
+			</div>
+		</div>
+	);
+};
+
+export default UserResult;
Index: frontend/src/components/userProfile/UserListModal.tsx
===================================================================
--- frontend/src/components/userProfile/UserListModal.tsx	(revision 694fc2568864281fe140fdc23e96cb6585170e74)
+++ frontend/src/components/userProfile/UserListModal.tsx	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -3,82 +3,82 @@
 
 interface ModalProps {
-  title: string;
-  users: BaseNonAdminUser[];
-  onClose: () => void;
-  onFollowToggle: (targetUsername: string) => Promise<void>;
+	title: string;
+	users: BaseNonAdminUser[];
+	onClose: () => void;
+	onFollowToggle: (targetUsername: string) => Promise<void>;
 }
 
 const UserListModal = ({
-  title,
-  users,
-  onClose,
-  onFollowToggle,
+	title,
+	users,
+	onClose,
+	onFollowToggle,
 }: ModalProps) => {
-  const navigate = useNavigate();
-  const baseURL = import.meta.env.VITE_API_BASE_URL;
+	const navigate = useNavigate();
+	const baseURL = import.meta.env.VITE_API_BASE_URL;
 
-  return (
-    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm">
-      <div className="bg-white rounded-xl shadow-2xl w-full max-w-md max-h-[70vh] flex flex-col">
-        <div className="p-4 border-b flex justify-between items-center">
-          <h2 className="text-xl font-bold">{title}</h2>
-          <button
-            onClick={onClose}
-            className="text-gray-500 hover:text-black text-2xl cursor-pointer"
-          >
-            &times;
-          </button>
-        </div>
+	return (
+		<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm">
+			<div className="bg-white rounded-xl shadow-2xl w-full max-w-md max-h-[70vh] flex flex-col">
+				<div className="p-4 border-b flex justify-between items-center">
+					<h2 className="text-xl font-bold">{title}</h2>
+					<button
+						onClick={onClose}
+						className="text-gray-500 hover:text-black text-2xl cursor-pointer"
+					>
+						&times;
+					</button>
+				</div>
 
-        <div className="overflow-y-auto p-4 flex-1">
-          {users.length === 0 ? (
-            <p className="text-center text-gray-500 py-8">No users found.</p>
-          ) : (
-            users.map((u) => (
-              <div
-                key={u.username}
-                className="flex items-center justify-between p-3 hover:bg-gray-50 rounded-lg transition-colors"
-              >
-                <div
-                  className="flex items-center gap-4 cursor-pointer flex-1"
-                  onClick={() => {
-                    onClose();
-                    navigate(`/users/${u.username}`);
-                  }}
-                >
-                  <div className="w-10 h-10 rounded-full bg-blue-100 overflow-hidden shrink-0 flex items-center justify-center">
-                    {u.profilePhoto ? (
-                      <img
-                        src={`${baseURL}/${u.profilePhoto}`}
-                        className="w-full h-full object-cover"
-                        alt=""
-                      />
-                    ) : (
-                      <span className="text-blue-600 font-bold">
-                        {u.fullName.charAt(0)}
-                      </span>
-                    )}
-                  </div>
-                  <p className="font-semibold text-gray-900">{u.fullName}</p>
-                </div>
+				<div className="overflow-y-auto p-4 flex-1">
+					{users.length === 0 ? (
+						<p className="text-center text-gray-500 py-8">No users found.</p>
+					) : (
+						users.map((u) => (
+							<div
+								key={u.username}
+								className="flex items-center justify-between p-3 hover:bg-gray-50 rounded-lg transition-colors"
+							>
+								<div
+									className="flex items-center gap-4 cursor-pointer flex-1"
+									onClick={() => {
+										onClose();
+										navigate(`/users/${u.username}`);
+									}}
+								>
+									<div className="w-10 h-10 rounded-full bg-blue-100 overflow-hidden shrink-0 flex items-center justify-center">
+										{u.profilePhoto ? (
+											<img
+												src={`${baseURL}/${u.profilePhoto}`}
+												className="w-full h-full object-cover"
+												alt=""
+											/>
+										) : (
+											<span className="text-blue-600 font-bold">
+												{u.fullName.charAt(0)}
+											</span>
+										)}
+									</div>
+									<p className="font-semibold text-gray-900">{u.fullName}</p>
+								</div>
 
-                <button
-                  onClick={() => onFollowToggle(u.username)}
-                  className={`px-4 py-1 text-sm font-medium rounded-md transition-colors cursor-pointer ${
-                    u.isFollowedByCurrentUser
-                      ? "bg-gray-200 text-gray-700 hover:bg-gray-300"
-                      : "bg-blue-500 text-white hover:bg-blue-600"
-                  }`}
-                >
-                  {u.isFollowedByCurrentUser ? "Unfollow" : "Follow"}
-                </button>
-              </div>
-            ))
-          )}
-        </div>
-      </div>
-      <div className="absolute inset-0 -z-10" onClick={onClose}></div>
-    </div>
-  );
+								<button
+									onClick={() => onFollowToggle(u.username)}
+									className={`px-4 py-1 text-sm font-medium rounded-md transition-colors cursor-pointer ${
+										u.isFollowedByCurrentUser
+											? "bg-gray-200 text-gray-700 hover:bg-gray-300"
+											: "bg-blue-500 text-white hover:bg-blue-600"
+									}`}
+								>
+									{u.isFollowedByCurrentUser ? "Unfollow" : "Follow"}
+								</button>
+							</div>
+						))
+					)}
+				</div>
+			</div>
+			<div className="absolute inset-0 -z-10" onClick={onClose}></div>
+		</div>
+	);
 };
 
Index: frontend/src/pages/AllUsers.tsx
===================================================================
--- frontend/src/pages/AllUsers.tsx	(revision 694fc2568864281fe140fdc23e96cb6585170e74)
+++ frontend/src/pages/AllUsers.tsx	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -4,82 +4,82 @@
 
 interface User {
-  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/na/all");
+			setUsers((await response).data);
+		};
+		fetchUsers();
+	}, []);
 
-  const handleUserClick = (username: string) => {
-    navigate(`/users/${username}`);
-  };
+	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/na/search`, {
+				params: { name: searchedUser },
+			});
+			setUsers(response.data);
+		} catch (err: any) {
+			const errorMessage = err.response?.data?.error || "Search failed";
+			setError(errorMessage);
+		}
+	};
 
-  if (users.length == 0) return <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.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>
-  );
+			<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/LandingPage.tsx
===================================================================
--- frontend/src/pages/LandingPage.tsx	(revision 694fc2568864281fe140fdc23e96cb6585170e74)
+++ frontend/src/pages/LandingPage.tsx	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -1,36 +1,38 @@
 import { useEffect, useState } from "react";
 import axiosInstance from "../api/axiosInstance";
-import type { Song } from "../utils/types";
-import Nav from "./Nav";
+import AlbumResult from "../components/search/AlbumResult";
+import SongResult from "../components/search/SongResult";
+import UserResult from "../components/search/UserResult";
+import type {
+	Album,
+	BaseNonAdminUser,
+	SearchCategory,
+	Song,
+} from "../utils/types";
+
+const CATEGORIES: { value: SearchCategory; label: string }[] = [
+	{ value: "songs", label: "Songs" },
+	{ value: "albums", label: "Albums" },
+	{ value: "artists", label: "Artists" },
+	{ value: "users", label: "Users" },
+];
 
 const LandingPage = () => {
 	const [songs, setSongs] = useState<Song[]>([]);
 	const [loading, setLoading] = useState<boolean>(true);
-	const [isSidebarOpen, setIsSidebarOpen] = useState<boolean>(true);
-
-	// mock data for recently listened songs
-	const recentlyListened = [
-		{ id: 1, title: "Song One", artist: "Artist A", cover: "/favicon.png" },
-		{ id: 2, title: "Song Two", artist: "Artist B", cover: "/favicon.png" },
-		{ id: 3, title: "Song Three", artist: "Artist C", cover: "/favicon.png" },
-		{ id: 4, title: "Song Four", artist: "Artist D", cover: "/favicon.png" },
-		{ id: 5, title: "Song Five", artist: "Artist E", cover: "/favicon.png" },
-	];
-
-	// mock data for my playlists
-	const playlists = [
-		{ id: 1, name: "My Favorites", songCount: 25 },
-		{ id: 2, name: "Workout Mix", songCount: 18 },
-		{ id: 3, name: "Chill Vibes", songCount: 32 },
-		{ id: 4, name: "Party Hits", songCount: 45 },
-	];
+
+	// search state
+	const [searchInput, setSearchInput] = useState("");
+	const [activeQuery, setActiveQuery] = useState("");
+	const [searchCategory, setSearchCategory] = useState<SearchCategory>("songs");
+	const [searchResults, setSearchResults] = useState<unknown[]>([]);
+	const [searchLoading, setSearchLoading] = useState(false);
+	const [hasSearched, setHasSearched] = useState(false);
 
 	useEffect(() => {
 		const fetchSongs = async () => {
 			try {
-				const response = await axiosInstance.get("/songs");
-				const data = response.data;
-				console.log("Fetched songs:", data);
-				setSongs(data);
+				const response = await axiosInstance.get("/songs/top");
+				setSongs(response.data);
 			} catch (error) {
 				console.error("Error fetching songs:", error);
@@ -42,123 +44,213 @@
 	}, []);
 
+	const performSearch = async (query: string, category: SearchCategory) => {
+		if (!query.trim()) return;
+
+		setSearchLoading(true);
+		setHasSearched(true);
+		setActiveQuery(query);
+		setSearchCategory(category);
+
+		try {
+			let endpoint = "";
+			switch (category) {
+				case "songs":
+					endpoint = `/songs/search?q=${encodeURIComponent(query)}`;
+					break;
+				case "albums":
+					endpoint = `/albums/search?q=${encodeURIComponent(query)}`;
+					break;
+				case "artists":
+					endpoint = `/users/search?type=ARTIST&q=${encodeURIComponent(query)}`;
+					break;
+				case "users":
+					endpoint = `/users/search?type=LISTENER&q=${encodeURIComponent(query)}`;
+					break;
+			}
+
+			const response = await axiosInstance.get(endpoint);
+			setSearchResults(response.data);
+		} catch (error) {
+			console.error("Search error:", error);
+			setSearchResults([]);
+		} finally {
+			setSearchLoading(false);
+		}
+	};
+
+	const handleSearch = () => {
+		performSearch(searchInput, searchCategory);
+	};
+
+	const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
+		if (e.key === "Enter") {
+			handleSearch();
+		}
+	};
+
+	const handleCategorySwitch = (category: SearchCategory) => {
+		performSearch(activeQuery, category);
+	};
+
+	const clearSearch = () => {
+		setSearchInput("");
+		setActiveQuery("");
+		setHasSearched(false);
+		setSearchResults([]);
+	};
+
+	const renderResults = () => {
+		if (searchLoading) {
+			return (
+				<div className="flex justify-center py-12">
+					<div className="w-10 h-10 border-4 border-white/10 border-t-[#1db954] rounded-full animate-spin"></div>
+				</div>
+			);
+		}
+
+		if (searchResults.length === 0) {
+			return (
+				<div className="text-center py-12 text-gray-400">
+					<p className="text-lg">
+						No {searchCategory} found for "{activeQuery}"
+					</p>
+				</div>
+			);
+		}
+
+		return (
+			<div className="divide-y divide-white/5">
+				{searchResults.map((result, index) => {
+					switch (searchCategory) {
+						case "songs":
+							return (
+								<SongResult key={(result as Song).id} song={result as Song} />
+							);
+						case "albums":
+							return (
+								<AlbumResult
+									key={(result as Album).id}
+									album={result as Album}
+								/>
+							);
+						case "artists":
+							return (
+								<UserResult
+									key={(result as BaseNonAdminUser).username ?? index}
+									user={result as BaseNonAdminUser}
+									label="Artist"
+								/>
+							);
+						case "users":
+							return (
+								<UserResult
+									key={(result as BaseNonAdminUser).username ?? index}
+									user={result as BaseNonAdminUser}
+									label="User"
+								/>
+							);
+					}
+				})}
+			</div>
+		);
+	};
+
 	return (
-		<>
-			<Nav
-				isSidebarOpen={isSidebarOpen}
-				onToggleSidebar={() => setIsSidebarOpen(!isSidebarOpen)}
-			/>
-			<div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] text-white flex pt-20">
-				{/* Sidebar */}
-				<div
-					className={`fixed left-0 top-0 h-full bg-[#121212] border-r border-white/10 transition-transform duration-300 ease-in-out z-100 ${
-						isSidebarOpen ? "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">
-							<h2 className="text-xl font-bold text-white">Library</h2>
-							<button
-								onClick={() => setIsSidebarOpen(false)}
-								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"
+		<div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] text-white flex">
+			<div className="flex-1">
+				<div className="p-8">
+					<div className="max-w-7xl mx-auto">
+						{/* Search Bar */}
+						<div className="mb-8 flex flex-col md:flex-row gap-3">
+							<div className="flex flex-1 gap-0">
+								{/* Category Dropdown */}
+								<select
+									value={searchCategory}
+									onChange={(e) =>
+										setSearchCategory(e.target.value as SearchCategory)
+									}
+									className="bg-[#282828] border border-white/10 border-r-0 rounded-l-full py-2 px-4 text-white text-sm focus:outline-none focus:border-[#1db954] appearance-none cursor-pointer"
 								>
-									<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"
+									{CATEGORIES.map((cat) => (
+										<option key={cat.value} value={cat.value}>
+											{cat.label}
+										</option>
+									))}
+								</select>
+
+								{/* Search Input */}
+								<input
+									type="text"
+									placeholder={`Search ${searchCategory}...`}
+									value={searchInput}
+									onChange={(e) => setSearchInput(e.target.value)}
+									onKeyDown={handleKeyDown}
+									className="flex-1 bg-[#282828] border border-white/10 border-r-0 py-2 px-4 text-white focus:outline-none focus:border-[#1db954] focus:ring-1 focus:ring-[#1db954] transition-all"
+								/>
+
+								{/* Search Button */}
+								<button
+									onClick={handleSearch}
+									className="bg-[#1db954] hover:bg-[#1ed760] text-black font-medium px-6 rounded-r-full transition-colors flex items-center gap-2"
+								>
+									<svg
+										className="w-5 h-5"
+										fill="none"
+										stroke="currentColor"
+										viewBox="0 0 24 24"
 									>
-										<img
-											src={song.cover}
-											alt={song.title}
-											className="w-10 h-10 rounded object-cover"
+										<path
+											strokeLinecap="round"
+											strokeLinejoin="round"
+											strokeWidth={2}
+											d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
 										/>
-										<div className="flex-1 min-w-0">
-											<p className="text-sm font-medium text-white truncate">
-												{song.title}
-											</p>
-											<p className="text-xs text-gray-400 truncate">
-												{song.artist}
-											</p>
-										</div>
-									</div>
-								))}
+									</svg>
+									<span className="hidden sm:inline">Search</span>
+								</button>
 							</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"
+						{/* Search Results Section */}
+						{hasSearched ? (
+							<div>
+								<div className="flex items-center justify-between mb-4">
+									<h2 className="text-2xl font-bold text-white">
+										Results for "{activeQuery}"
+									</h2>
+									<button
+										onClick={clearSearch}
+										className="text-sm text-gray-400 hover:text-white transition-colors"
 									>
-										<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>
-
-				{/* Main Content */}
-				<div
-					className={`flex-1 transition-all duration-300 ${
-						isSidebarOpen ? "ml-64" : "ml-0"
-					}`}
-				>
-					<div className="p-8">
-						{loading ? (
-							<div className="flex flex-col items-center justify-center min-h-[60vh] gap-6">
-								<div className="w-12 h-12 border-4 border-white/10 border-t-[#1db954] rounded-full animate-spin"></div>
-								<p className="text-xl text-gray-400">Loading songs...</p>
+										Clear search
+									</button>
+								</div>
+
+								{/* Quick category switch buttons */}
+								<div className="flex gap-2 mb-6">
+									{CATEGORIES.map((cat) => (
+										<button
+											key={cat.value}
+											onClick={() => handleCategorySwitch(cat.value)}
+											className={`px-4 py-1.5 rounded-full text-sm font-medium transition-colors ${
+												searchCategory === cat.value
+													? "bg-[#1db954] text-black"
+													: "bg-white/10 text-white hover:bg-white/20"
+											}`}
+										>
+											{cat.label}
+										</button>
+									))}
+								</div>
+
+								{/* Results list */}
+								<div className="bg-[#1a1a2e]/50 rounded-xl overflow-hidden">
+									{renderResults()}
+								</div>
 							</div>
 						) : (
-							<div className="max-w-7xl mx-auto">
-								<div className="mb-12 pb-6 border-b border-white/10">
+							/* Default song grid */
+							<>
+								<div className="mb-8 border-b border-white/10 pb-6">
 									<h1 className="text-5xl font-bold mb-3 pb-1 bg-linear-to-r from-[#1db954] to-[#1ed760] bg-clip-text text-transparent">
 										Top Songs
@@ -168,50 +260,54 @@
 									</p>
 								</div>
-								<div className="grid grid-cols-[repeat(auto-fill,minmax(220px,1fr))] gap-8 py-4">
-									{songs.map((song) => (
-										<div
-											key={song.id}
-											className="bg-[#282828] rounded-xl overflow-hidden cursor-pointer shadow-lg transition-all duration-300 ease-in-out hover:-translate-y-2 hover:shadow-2xl group"
-										>
-											<div className="relative w-full pt-[100%] overflow-hidden bg-[#181818]">
-												<img
-													src={song.cover || "/favicon.png"}
-													alt={song.title}
-													className="absolute top-0 left-0 w-full h-full object-cover"
-													onError={(e) => {
-														(e.target as HTMLImageElement).src = "/favicon.png";
-													}}
-												/>
-												<div className="absolute top-0 left-0 w-full h-full bg-black/60 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-300">
-													<div className="w-15 h-15 rounded-full bg-[#1db954] flex items-center justify-center text-2xl text-black shadow-[0_4px_12px_rgba(29,185,84,0.5)]">
-														▶
+
+								{loading ? (
+									<div className="flex flex-col items-center justify-center min-h-[40vh] gap-6">
+										<div className="w-12 h-12 border-4 border-white/10 border-t-[#1db954] rounded-full animate-spin"></div>
+										<p className="text-xl text-gray-400">Loading songs...</p>
+									</div>
+								) : (
+									<div className="grid grid-cols-[repeat(auto-fill,minmax(220px,1fr))] gap-8 py-4">
+										{songs.map((song) => (
+											<div
+												key={song.id}
+												className="bg-[#282828] rounded-xl overflow-hidden cursor-pointer shadow-lg transition-all duration-300 ease-in-out hover:-translate-y-2 hover:shadow-2xl group"
+											>
+												<div className="relative w-full pt-[100%] overflow-hidden bg-[#181818]">
+													<img
+														src={song.cover || "/favicon.png"}
+														alt={song.title}
+														className="absolute top-0 left-0 w-full h-full object-cover"
+														onError={(e) => {
+															(e.target as HTMLImageElement).src =
+																"/favicon.png";
+														}}
+													/>
+													<div className="absolute top-0 left-0 w-full h-full bg-black/60 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-300">
+														<div className="w-15 h-15 rounded-full bg-[#1db954] flex items-center justify-center text-2xl text-black shadow-[0_4px_12px_rgba(29,185,84,0.5)]">
+															▶
+														</div>
 													</div>
 												</div>
+												<div className="p-4 flex flex-col items-center">
+													<h3 className="text-lg font-semibold mb-2 text-white overflow-hidden text-ellipsis whitespace-nowrap">
+														{song.title}
+													</h3>
+													<p className="text-sm text-gray-400 mb-3 overflow-hidden text-ellipsis whitespace-nowrap">
+														{"<album>"}
+													</p>
+													<p className="text-sm text-gray-400 mb-3 overflow-hidden text-ellipsis whitespace-nowrap">
+														{song.releasedBy}
+													</p>
+												</div>
 											</div>
-											<div className="p-4 flex flex-col items-center">
-												<h3 className="text-lg font-semibold mb-2 text-white overflow-hidden text-ellipsis whitespace-nowrap">
-													{song.title}
-												</h3>
-												<p className="text-sm text-gray-400 mb-3 overflow-hidden text-ellipsis whitespace-nowrap">
-													{"<album>"}
-												</p>
-												<p className="text-sm text-gray-400 mb-3 overflow-hidden text-ellipsis whitespace-nowrap">
-													{song.releasedBy}
-												</p>
-												{/* <div className="inline-block bg-[#1db954]/20 px-3 py-1 rounded-xl border border-[#1db954]/40">
-													<span className="text-xs text-[#1db954] font-medium uppercase tracking-wider">
-														{song.genre}
-													</span>
-												</div> */}
-											</div>
-										</div>
-									))}
-								</div>
-							</div>
+										))}
+									</div>
+								)}
+							</>
 						)}
 					</div>
 				</div>
 			</div>
-		</>
+		</div>
 	);
 };
Index: frontend/src/pages/UserDetail.tsx
===================================================================
--- frontend/src/pages/UserDetail.tsx	(revision 694fc2568864281fe140fdc23e96cb6585170e74)
+++ frontend/src/pages/UserDetail.tsx	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -7,25 +7,25 @@
 import { handleError } from "../utils/error";
 import type {
-  MusicalEntity,
-  Playlist,
-  ArtistContribution,
-  BaseNonAdminUser,
+	ArtistContribution,
+	BaseNonAdminUser,
+	MusicalEntity,
+	Playlist,
 } from "../utils/types";
 
 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[];
 }
 
@@ -33,221 +33,225 @@
 
 const UserDetail = () => {
-  // user refers to the selected user NOT to the user from context
-  const baseURL = import.meta.env.VITE_API_BASE_URL;
-  const { username } = useParams();
-  const navigate = useNavigate();
-  const [user, setUser] = useState<UserProfile | null>(null);
-  const [error, setError] = useState<string | null>(null);
-  const [showModal, setShowModal] = useState(false);
-  const [modalTitle, setModalTitle] = useState("");
-  const [modalUsers, setModalUsers] = useState<any[]>([]);
-  const [isLoadingModal, setIsLoadingModal] = useState(false);
-  const [isFollowing, setIsFollowing] = useState(false);
-
-  const handleFollow = async () => {
-    if (!user) return;
-
-    setIsFollowing(true);
-    try {
-      const response = await axiosInstance.post<FollowStatus>(
-        `/users/${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/${username}/follow`,
-      );
-
-      setModalUsers((prevUsers) =>
-        prevUsers.map((u) =>
-          u.username === targetUsername
-            ? { ...u, isFollowedByCurrentUser: response.data.isFollowing }
-            : u,
-        ),
-      );
-
-      // if (user && user.id === targetId) {
-      //   setUser((prev) => {
-      //     if (!prev) return null;
-      //     return {
-      //       ...prev,
-      //       isFollowedByCurrentUser: response.data.isFollowing,
-      //       followers: response.data.followerCount,
-      //     };
-      //   });
-      // }
-    } catch (err: any) {
-      setError(handleError(err));
-    }
-  };
-
-  const displayFollowers = async () => {
-    setIsLoadingModal(true);
-    try {
-      const response = await axiosInstance.get(`/users/${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/${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/${username}`);
-        console.log(response.data);
-        setUser(response.data);
-      } catch (err: any) {
-        setError(handleError(err));
-      }
-    };
-    fetchUser();
-  }, [username]);
-
-  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 (!user) return <div className="p-6">Loading...</div>;
-
-  return (
-    <div className="container mx-auto p-6">
-      {isLoadingModal && (
-        <div className="fixed inset-0 z-40 bg-black/30 backdrop-blur-sm flex items-center justify-center">
-          <div className="flex items-center gap-3">
-            <div className="w-6 h-6 border-3 border-blue-500 border-t-transparent rounded-full animate-spin"></div>
-          </div>
-        </div>
-      )}
-      <button
-        onClick={() => navigate(-1)}
-        className="mb-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors duration-200 cursor-pointer"
-      >
-        ← Back
-      </button>
-
-      <div className="bg-white shadow-lg rounded-lg p-8">
-        <div className="flex items-start gap-6 mb-8">
-          <div className="shrink-0">
-            <div className="w-32 h-32 rounded-full bg-linear-to-br from-blue-400 to-purple-500 flex items-center justify-center text-white text-4xl font-bold shadow-lg overflow-hidden">
-              {user.profilePhoto ? (
-                <img
-                  src={`${baseURL}/${user.profilePhoto}`}
-                  alt={user.fullName}
-                  className="w-full h-full object-cover"
-                />
-              ) : (
-                user.fullName.charAt(0).toUpperCase()
-              )}
-            </div>
-          </div>
-
-          <div className="flex-1">
-            <h1 className="text-4xl font-bold mb-2">{user.fullName}</h1>
-            <span className="inline-block px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm font-medium mb-4">
-              {user.userType}
-            </span>
-
-            <div className="flex gap-6 mb-4 text-gray-700">
-              <div
-                className={`flex flex-col ${user.userType == "LISTENER" ? "cursor-pointer" : "cursor-default"}`}
-                onClick={
-                  user.userType === "LISTENER" ? displayFollowers : undefined
-                }
-              >
-                <span className="text-2xl font-bold">{user.followers}</span>
-                <span className="text-sm text-gray-500">Followers</span>
-              </div>
-              <div
-                className={`flex flex-col ${user.userType == "LISTENER" ? "cursor-pointer" : "cursor-default"}`}
-                onClick={
-                  user.userType === "LISTENER" ? displayFollowing : undefined
-                }
-              >
-                <span className="text-2xl font-bold">{user.following}</span>
-                <span className="text-sm text-gray-500">Following</span>
-              </div>
-            </div>
-
-            <button
-              onClick={handleFollow}
-              disabled={isFollowing}
-              className={`
+	// user refers to the selected user NOT to the user from context
+	const baseURL = import.meta.env.VITE_API_BASE_URL;
+	const { username } = useParams();
+	const navigate = useNavigate();
+	const [user, setUser] = useState<UserProfile | null>(null);
+	const [error, setError] = useState<string | null>(null);
+	const [showModal, setShowModal] = useState(false);
+	const [modalTitle, setModalTitle] = useState("");
+	const [modalUsers, setModalUsers] = useState<any[]>([]);
+	const [isLoadingModal, setIsLoadingModal] = useState(false);
+	const [isFollowing, setIsFollowing] = useState(false);
+
+	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/${username}/follow`,
+			);
+
+			setModalUsers((prevUsers) =>
+				prevUsers.map((u) =>
+					u.username === targetUsername
+						? { ...u, isFollowedByCurrentUser: response.data.isFollowing }
+						: u,
+				),
+			);
+
+			// if (user && user.id === targetId) {
+			//   setUser((prev) => {
+			//     if (!prev) return null;
+			//     return {
+			//       ...prev,
+			//       isFollowedByCurrentUser: response.data.isFollowing,
+			//       followers: response.data.followerCount,
+			//     };
+			//   });
+			// }
+		} 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}`);
+				console.log(response.data);
+				setUser(response.data);
+			} catch (err: any) {
+				setError(handleError(err));
+			}
+		};
+		fetchUser();
+	}, [username]);
+
+	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 (!user) return <div className="p-6">Loading...</div>;
+
+	return (
+		<div className="container mx-auto p-6">
+			{isLoadingModal && (
+				<div className="fixed inset-0 z-40 bg-black/30 backdrop-blur-sm flex items-center justify-center">
+					<div className="flex items-center gap-3">
+						<div className="w-6 h-6 border-3 border-blue-500 border-t-transparent rounded-full animate-spin"></div>
+					</div>
+				</div>
+			)}
+			<button
+				onClick={() => navigate(-1)}
+				className="mb-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors duration-200 cursor-pointer"
+			>
+				← Back
+			</button>
+
+			<div className="bg-white shadow-lg rounded-lg p-8">
+				<div className="flex items-start gap-6 mb-8">
+					<div className="shrink-0">
+						<div className="w-32 h-32 rounded-full bg-linear-to-br from-blue-400 to-purple-500 flex items-center justify-center text-white text-4xl font-bold shadow-lg overflow-hidden">
+							{user.profilePhoto ? (
+								<img
+									src={`${baseURL}/${user.profilePhoto}`}
+									alt={user.fullName}
+									className="w-full h-full object-cover"
+								/>
+							) : (
+								user.fullName.charAt(0).toUpperCase()
+							)}
+						</div>
+					</div>
+
+					<div className="flex-1">
+						<h1 className="text-4xl font-bold mb-2">{user.fullName}</h1>
+						<span className="inline-block px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm font-medium mb-4">
+							{user.userType}
+						</span>
+
+						<div className="flex gap-6 mb-4 text-gray-700">
+							<div
+								className={`flex flex-col ${user.userType == "LISTENER" ? "cursor-pointer" : "cursor-default"}`}
+								onClick={
+									user.userType === "LISTENER" ? displayFollowers : undefined
+								}
+							>
+								<span className="text-2xl font-bold">{user.followers}</span>
+								<span className="text-sm text-gray-500">Followers</span>
+							</div>
+							<div
+								className={`flex flex-col ${user.userType == "LISTENER" ? "cursor-pointer" : "cursor-default"}`}
+								onClick={
+									user.userType === "LISTENER" ? displayFollowing : undefined
+								}
+							>
+								<span className="text-2xl font-bold">{user.following}</span>
+								<span className="text-sm text-gray-500">Following</span>
+							</div>
+						</div>
+
+						<button
+							onClick={handleFollow}
+							disabled={isFollowing}
+							className={`
                 px-6 py-2 font-semibold rounded-lg shadow-md 
                 transition-colors duration-200
                 ${
-                  isFollowing
-                    ? "bg-gray-400 text-gray-200 cursor-not-allowed"
-                    : user.isFollowedByCurrentUser
-                      ? "bg-gray-200 text-gray-700 hover:bg-gray-300 cursor-pointer"
-                      : "bg-blue-500 text-white hover:bg-blue-600 cursor-pointer"
-                }
+									isFollowing
+										? "bg-gray-400 text-gray-200 cursor-not-allowed"
+										: user.isFollowedByCurrentUser
+											? "bg-gray-200 text-gray-700 hover:bg-gray-300 cursor-pointer"
+											: "bg-blue-500 text-white hover:bg-blue-600 cursor-pointer"
+								}
               `}
-            >
-              {user.isFollowedByCurrentUser ? "Unfollow" : "Follow"}
-            </button>
-          </div>
-        </div>
-
-        {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>
-  );
+						>
+							{user.isFollowedByCurrentUser ? "Unfollow" : "Follow"}
+						</button>
+					</div>
+				</div>
+
+				{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/types.ts
===================================================================
--- frontend/src/utils/types.ts	(revision 694fc2568864281fe140fdc23e96cb6585170e74)
+++ frontend/src/utils/types.ts	(revision cb4a1da079608fdb022036c90eb6e41f26046827)
@@ -55,2 +55,4 @@
 
 export type UserRegisterType = "ARTIST" | "LISTENER";
+
+export type SearchCategory = "songs" | "albums" | "artists" | "users";
