Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/GlobalExceptionHandler.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/GlobalExceptionHandler.java	(revision c1d2f0715ebdaf396e54dcc52c7463f8e0a280bd)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/GlobalExceptionHandler.java	(revision 6de2873a46d63a69e2d1d579335ac1f20e9ee5bf)
@@ -3,4 +3,6 @@
 import java.util.Map;
 
+import com.ukim.finki.develop.finkwave.exceptions.FollowException;
+import com.ukim.finki.develop.finkwave.exceptions.UserNotFoundException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,4 +35,20 @@
     }
 
+    @ExceptionHandler(UserNotFoundException.class)
+    public ResponseEntity<Map<String, String>> handleUserNotFound(UserNotFoundException ex) {
+        return ResponseEntity
+                .status(HttpStatus.BAD_REQUEST)
+                .body(Map.of("error", ex.getMessage()));
+    }
+
+    @ExceptionHandler(FollowException.class)
+    public ResponseEntity<Map<String, String>> handleSelfFollow(FollowException ex) {
+        return ResponseEntity
+                .status(HttpStatus.BAD_REQUEST)
+                .body(Map.of("error", ex.getMessage()));
+    }
+
+
+
     @ExceptionHandler(ResponseStatusException.class)
     public ResponseEntity<Map<String, String>> handleResponseStatusException(ResponseStatusException ex) {
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 c1d2f0715ebdaf396e54dcc52c7463f8e0a280bd)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/controller/NonAdminUserController.java	(revision 6de2873a46d63a69e2d1d579335ac1f20e9ee5bf)
@@ -2,4 +2,5 @@
 
 import com.ukim.finki.develop.finkwave.model.dto.NonAdminUserDTO;
+import com.ukim.finki.develop.finkwave.service.FollowService;
 import com.ukim.finki.develop.finkwave.service.NonAdminUserService;
 import lombok.RequiredArgsConstructor;
@@ -17,4 +18,5 @@
 
     private final NonAdminUserService nonAdminUserService;
+    private final FollowService followService;
 
     @GetMapping("/all")
@@ -32,3 +34,10 @@
         return ResponseEntity.ok(nonAdminUserService.searchUsers(name));
     }
+
+    @PostMapping("/follow/{id}")
+    public HttpEntity<NonAdminUserDTO>followUser(@PathVariable Long id){
+        followService.toggleFollow(id);
+
+        return ResponseEntity.ok(nonAdminUserService.getById(id));
+    }
 }
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/exceptions/FollowException.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/exceptions/FollowException.java	(revision 6de2873a46d63a69e2d1d579335ac1f20e9ee5bf)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/exceptions/FollowException.java	(revision 6de2873a46d63a69e2d1d579335ac1f20e9ee5bf)
@@ -0,0 +1,12 @@
+package com.ukim.finki.develop.finkwave.exceptions;
+
+import org.springframework.http.HttpStatus;
+
+public class FollowException extends RuntimeException{
+
+    public FollowException(String message){
+        super(message);
+    }
+
+
+}
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/Follow.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/Follow.java	(revision c1d2f0715ebdaf396e54dcc52c7463f8e0a280bd)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/Follow.java	(revision 6de2873a46d63a69e2d1d579335ac1f20e9ee5bf)
@@ -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 = "follows", schema = "project")
 public class Follow {
@@ -27,3 +29,9 @@
     private NonAdminUser followee;
 
+    public Follow(NonAdminUser follower,NonAdminUser followee){
+        this.follower=follower;
+        this.followee=followee;
+        this.id=new FollowId(follower.getId(),followee.getId());
+    }
+
 }
Index: finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/FollowId.java
===================================================================
--- finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/FollowId.java	(revision c1d2f0715ebdaf396e54dcc52c7463f8e0a280bd)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/model/FollowId.java	(revision 6de2873a46d63a69e2d1d579335ac1f20e9ee5bf)
@@ -3,5 +3,7 @@
 import jakarta.persistence.Column;
 import jakarta.persistence.Embeddable;
+import lombok.AllArgsConstructor;
 import lombok.Getter;
+import lombok.NoArgsConstructor;
 import lombok.Setter;
 import org.hibernate.Hibernate;
@@ -13,4 +15,6 @@
 @Setter
 @Embeddable
+@NoArgsConstructor
+@AllArgsConstructor
 public class FollowId implements Serializable {
     private static final long serialVersionUID = -915670330063692538L;
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 6de2873a46d63a69e2d1d579335ac1f20e9ee5bf)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/FollowService.java	(revision 6de2873a46d63a69e2d1d579335ac1f20e9ee5bf)
@@ -0,0 +1,46 @@
+package com.ukim.finki.develop.finkwave.service;
+
+import com.ukim.finki.develop.finkwave.exceptions.FollowException;
+import com.ukim.finki.develop.finkwave.exceptions.UserNotFoundException;
+import com.ukim.finki.develop.finkwave.model.Follow;
+import com.ukim.finki.develop.finkwave.model.FollowId;
+import com.ukim.finki.develop.finkwave.model.NonAdminUser;
+import com.ukim.finki.develop.finkwave.repository.FollowRepository;
+import com.ukim.finki.develop.finkwave.repository.NonAdminUserRepository;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@Service
+@AllArgsConstructor
+public class FollowService {
+
+    private final FollowRepository followRepository;
+    private final NonAdminUserRepository nonAdminUserRepository;
+    private final AuthService authService;
+
+
+    public boolean toggleFollow(Long id){
+        Long currentUserId=authService.getCurrentUserID();
+
+        if (currentUserId.equals(id)){
+            throw new FollowException("Cannot follow yourself");
+        }
+
+        FollowId followId=new FollowId(currentUserId,id);
+
+
+        if (followRepository.existsById(followId)){
+            followRepository.deleteById(followId);
+            return false;
+        }else{
+            NonAdminUser follower = nonAdminUserRepository.findById(currentUserId)
+                    .orElseThrow(UserNotFoundException::new);
+            NonAdminUser followee = nonAdminUserRepository.findById(id)
+                    .orElseThrow(UserNotFoundException::new);
+
+            followRepository.save(new Follow(follower, followee));
+            return true;
+        }
+
+    }
+}
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 c1d2f0715ebdaf396e54dcc52c7463f8e0a280bd)
+++ finkwave/src/main/java/com/ukim/finki/develop/finkwave/service/NonAdminUserService.java	(revision 6de2873a46d63a69e2d1d579335ac1f20e9ee5bf)
@@ -1,4 +1,5 @@
 package com.ukim.finki.develop.finkwave.service;
 
+import com.ukim.finki.develop.finkwave.exceptions.UserNotFoundException;
 import com.ukim.finki.develop.finkwave.model.*;
 import com.ukim.finki.develop.finkwave.model.dto.*;
@@ -66,5 +67,5 @@
     private NonAdminUserDTO getArtistProfile(Long artistId, Long followers,Long following) {
         Artist artist = artistRepository.findByIdWithUser(artistId)
-            .orElseThrow(() -> new RuntimeException("Artist not found with id: " + artistId));
+            .orElseThrow(()->new UserNotFoundException("Artist not found with id: " + artistId));
 
 
@@ -77,5 +78,5 @@
     private NonAdminUserDTO getListenerProfile(Long listenerId, Long followers,Long following) {
         Listener listener = listenerRepository.findByIdWithUser(listenerId)
-            .orElseThrow(() -> new RuntimeException("Listener not found with id: " + listenerId));
+            .orElseThrow(()->new UserNotFoundException("Listener not found with id: " + listenerId));
 
 
@@ -97,5 +98,5 @@
         List<NonAdminUser>nonAdminUsers=nonAdminUserRepository.searchByName(name);
         if (nonAdminUsers.isEmpty()){
-            throw new RuntimeException("No user found");
+            throw new UserNotFoundException("No users matched the criteria");
         }
 
Index: frontend/src/pages/UserDetailView.tsx
===================================================================
--- frontend/src/pages/UserDetailView.tsx	(revision c1d2f0715ebdaf396e54dcc52c7463f8e0a280bd)
+++ frontend/src/pages/UserDetailView.tsx	(revision 6de2873a46d63a69e2d1d579335ac1f20e9ee5bf)
@@ -5,116 +5,147 @@
 import ListenerView from "../components/userProfile/ListenerView";
 import type {
-	ArtistContributionDTO,
-	MusicalEntityDTO,
-	Playlist,
+  ArtistContributionDTO,
+  MusicalEntityDTO,
+  Playlist,
 } from "../utils/types";
 
 interface User {
-	id: number;
-	username: string;
-	fullName: string;
-	userType: string;
-	followers: number;
-	following: number;
-	isFollowedByCurrentUser: boolean;
+  id: number;
+  username: string;
+  fullName: string;
+  userType: string;
+  followers: number;
+  following: number;
+  isFollowedByCurrentUser: boolean;
 
-	musicalEntities?: {
-		contributions: ArtistContributionDTO[];
-	};
+  musicalEntities?: {
+    contributions: ArtistContributionDTO[];
+  };
 
-	likes?: {
-		likedEntities: MusicalEntityDTO[];
-	};
+  likes?: {
+    likedEntities: MusicalEntityDTO[];
+  };
 
-	createdPlaylists?: Playlist[];
+  createdPlaylists?: Playlist[];
 }
 
 const UserDetail = () => {
-	// user refers to the selected user NOT to the user from context
-	const { userId } = useParams();
-	const navigate = useNavigate();
-	const [user, setUser] = useState<User | null>(null);
-	const [error, setError] = useState<string | null>(null);
+  // user refers to the selected user NOT to the user from context
+  const { userId } = useParams();
+  const navigate = useNavigate();
+  const [user, setUser] = useState<User | null>(null);
+  const [error, setError] = useState<string | null>(null);
+  const [isFollowing, setIsFollowing] = useState(false);
 
-	useEffect(() => {
-		const fetchUser = async () => {
-			setError(null);
-			try {
-				const response = await axiosInstance.get(`/users/${userId}`);
+  const handleFollow = async () => {
+    if (!user) return;
 
-				setUser(response.data);
-			} catch (err: any) {
-				const errorMessage =
-					err.response?.data?.error || "Failed to fetch user";
-				setError(errorMessage);
-			}
-		};
-		fetchUser();
-	}, [userId]);
+    setIsFollowing(true);
+    try {
+      const response = await axiosInstance.post<User>(
+        `/users/follow/${userId}`,
+      );
+      setUser(response.data);
+    } catch (err: any) {
+      console.error(err.response?.data?.error);
+    } finally {
+      setIsFollowing(false);
+    }
+  };
 
-	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>
-		);
-	}
+  useEffect(() => {
+    const fetchUser = async () => {
+      setError(null);
+      try {
+        const response = await axiosInstance.get(`/users/${userId}`);
 
-	if (!user) return <div className="p-6">Loading...</div>;
+        setUser(response.data);
+      } catch (err: any) {
+        const errorMessage =
+          err.response?.data?.error || "Failed to fetch user";
+        setError(errorMessage);
+      }
+    };
+    fetchUser();
+  }, [userId]);
 
-	return (
-		<div className="container mx-auto p-6">
-			<button
-				onClick={() => navigate(-1)}
-				className="mb-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
-			>
-				← Back
-			</button>
+  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>
+    );
+  }
 
-			<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">
-							{user.fullName.charAt(0).toUpperCase()}
-						</div>
-					</div>
+  if (!user) return <div className="p-6">Loading...</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>
+  return (
+    <div className="container mx-auto p-6">
+      <button
+        onClick={() => navigate(-1)}
+        className="mb-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors duration-200"
+      >
+        ← Back
+      </button>
 
-						<div className="flex gap-6 mb-4 text-gray-700">
-							<div className="flex flex-col">
-								<span className="text-2xl font-bold">{user.followers}</span>
-								<span className="text-sm text-gray-500">Followers</span>
-							</div>
-							<div className="flex flex-col">
-								<span className="text-2xl font-bold">{user.following}</span>
-								<span className="text-sm text-gray-500">Following</span>
-							</div>
-						</div>
+      <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">
+              {user.fullName.charAt(0).toUpperCase()}
+            </div>
+          </div>
 
-						<button className="px-6 py-2 bg-blue-500 hover:bg-blue-600 text-white font-semibold rounded-lg shadow-md transition-colors duration-200 cursor-pointer">
-							{user.isFollowedByCurrentUser ? "Unfollow" : "Follow"}
-						</button>
-					</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>
 
-				{user.userType === "ARTIST" && user.musicalEntities?.contributions && (
-					<ArtistView contributions={user.musicalEntities.contributions} />
-				)}
+            <div className="flex gap-6 mb-4 text-gray-700">
+              <div className="flex flex-col">
+                <span className="text-2xl font-bold">{user.followers}</span>
+                <span className="text-sm text-gray-500">Followers</span>
+              </div>
+              <div className="flex flex-col">
+                <span className="text-2xl font-bold">{user.following}</span>
+                <span className="text-sm text-gray-500">Following</span>
+              </div>
+            </div>
 
-				{user.userType === "LISTENER" && user.likes?.likedEntities && (
-					<ListenerView
-						likedEntities={user.likes.likedEntities}
-						playlists={user.createdPlaylists}
-					/>
-				)}
-			</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"
+                }
+              `}
+            >
+              {user.isFollowedByCurrentUser ? "Unfollow" : "Follow"}
+            </button>
+          </div>
+        </div>
+
+        {user.userType === "ARTIST" && user.musicalEntities?.contributions && (
+          <ArtistView contributions={user.musicalEntities.contributions} />
+        )}
+
+        {user.userType === "LISTENER" && user.likes?.likedEntities && (
+          <ListenerView
+            likedEntities={user.likes.likedEntities}
+            playlists={user.createdPlaylists}
+          />
+        )}
+      </div>
+    </div>
+  );
 };
 
