Ignore:
Timestamp:
02/10/26 21:58:39 (5 months ago)
Author:
Filip Gavrilovski <filipgavrilovski28@…>
Branches:
main
Children:
92db381
Parents:
0808ef2
Message:

refactor artist, collection, listener components to have similar style as other components; refactor some dto-s

File:
1 edited

Legend:

Unmodified
Added
Removed
  • frontend/src/pages/UserDetail.tsx

    r0808ef2 r1579b4f  
    11import { useEffect, useState } from "react";
    2 import { useNavigate, useParams } from "react-router-dom";
    3 import axiosInstance from "../api/axiosInstance";
     2import { Link, useNavigate, useParams } from "react-router-dom";
     3import axiosInstance, { baseURL } from "../api/axiosInstance";
    44import LoadingSpinner from "../components/LoadingSpinner";
    55import ArtistView from "../components/userProfile/ArtistView";
     
    3535
    3636const UserDetail = () => {
    37         // user refers to the selected user NOT to the user from context
    38         const baseURL = import.meta.env.VITE_API_BASE_URL;
    3937        const { username: usernameParam } = useParams();
    40         // sintaksava dole znaci zemi go user od auth context i preimenuvaj go vo currentUser, za da ne se izmesa so user-ot dole
    4138        const { user: currentUser } = useAuth();
    4239        const navigate = useNavigate();
     
    4946        const [isFollowing, setIsFollowing] = useState(false);
    5047
    51         // determine which username to use: URL param or current user's username
    5248        const username = usernameParam || currentUser?.username;
    53 
    54         // if we're on /me route and no user is logged in, show error
     49        const isOwnProfile = currentUser?.username === username;
     50
    5551        if (!usernameParam && !currentUser) {
    5652                return (
    57                         <div className="p-6 bg-red-50 border border-red-200 text-red-700 rounded-lg">
    58                                 <h2 className="font-bold">Authentication Required</h2>
    59                                 <p>You must be logged in to view your profile.</p>
    60                                 <button
    61                                         onClick={() => navigate("/login")}
    62                                         className="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors duration-200 cursor-pointer"
    63                                 >
    64                                         Go to Login
    65                                 </button>
     53                        <div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] flex items-center justify-center">
     54                                <div className="text-center">
     55                                        <p className="text-red-400 text-xl mb-4">
     56                                                You must be logged in to view your profile.
     57                                        </p>
     58                                        <button
     59                                                onClick={() => navigate("/login")}
     60                                                className="text-[#1db954] hover:underline text-sm cursor-pointer"
     61                                        >
     62                                                Go to Login
     63                                        </button>
     64                                </div>
    6665                        </div>
    6766                );
     
    9594                try {
    9695                        const response = await axiosInstance.post<FollowStatus>(
    97                                 `/users/na/${username}/follow`,
     96                                `/users/na/${targetUsername}/follow`,
    9897                        );
    9998
     
    105104                                ),
    106105                        );
    107 
    108                         // if (user && user.id === targetId) {
    109                         //   setUser((prev) => {
    110                         //     if (!prev) return null;
    111                         //     return {
    112                         //       ...prev,
    113                         //       isFollowedByCurrentUser: response.data.isFollowing,
    114                         //       followers: response.data.followerCount,
    115                         //     };
    116                         //   });
    117                         // }
    118106                } catch (err: any) {
    119107                        setError(handleError(err));
     
    157145                        try {
    158146                                const response = await axiosInstance.get(`/users/na/${username}`);
    159                                 console.log(response.data);
    160147                                setUser(response.data);
    161148                        } catch (err: any) {
     
    168155        if (error) {
    169156                return (
    170                         <div className="p-6 bg-red-50 border border-red-200 text-red-700 rounded-lg">
    171                                 <h2 className="font-bold">Error</h2>
    172                                 <p>{error}</p>
     157                        <div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] flex items-center justify-center">
     158                                <div className="text-center">
     159                                        <p className="text-red-400 text-xl mb-4">{error}</p>
     160                                        <Link to="/" className="text-[#1db954] hover:underline text-sm">
     161                                                ← Back to Home
     162                                        </Link>
     163                                </div>
    173164                        </div>
    174165                );
     
    180171
    181172        return (
    182                 <div className="container mx-auto p-6">
     173                <div className="min-h-screen bg-linear-to-br from-[#1e1e2e] to-[#0f0f1e] text-white">
    183174                        {isLoadingModal && (
    184                                 <div className="fixed inset-0 z-40 bg-black/30 backdrop-blur-sm flex items-center justify-center">
    185                                         <div className="flex items-center gap-3">
    186                                                 <div className="w-6 h-6 border-3 border-blue-500 border-t-transparent rounded-full animate-spin"></div>
    187                                         </div>
     175                                <div className="fixed inset-0 z-40 bg-black/50 backdrop-blur-sm flex items-center justify-center">
     176                                        <div className="w-10 h-10 border-4 border-white/10 border-t-[#1db954] rounded-full animate-spin" />
    188177                                </div>
    189178                        )}
    190                         <button
    191                                 onClick={() => navigate(-1)}
    192                                 className="mb-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors duration-200 cursor-pointer"
    193                         >
    194                                 ← Back
    195                         </button>
    196 
    197                         <div className="bg-white shadow-lg rounded-lg p-8">
    198                                 <div className="flex items-start gap-6 mb-8">
    199                                         <div className="shrink-0">
    200                                                 <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">
     179
     180                        <div className="max-w-5xl mx-auto px-6 py-10">
     181                                {/* Back link */}
     182                                <Link
     183                                        to="/"
     184                                        className="inline-flex items-center gap-1 text-gray-400 hover:text-white text-sm mb-8 transition-colors"
     185                                >
     186                                        <svg
     187                                                className="w-4 h-4"
     188                                                fill="none"
     189                                                stroke="currentColor"
     190                                                viewBox="0 0 24 24"
     191                                        >
     192                                                <path
     193                                                        strokeLinecap="round"
     194                                                        strokeLinejoin="round"
     195                                                        strokeWidth={2}
     196                                                        d="M15 19l-7-7 7-7"
     197                                                />
     198                                        </svg>
     199                                        Back to Home
     200                                </Link>
     201
     202                                {/* Hero section */}
     203                                <div className="flex flex-col md:flex-row gap-8 mb-10">
     204                                        {/* Profile photo */}
     205                                        <div className="w-full md:w-48 shrink-0">
     206                                                <div className="relative w-48 h-48 rounded-full overflow-hidden shadow-2xl bg-[#181818] mx-auto md:mx-0">
    201207                                                        {user.profilePhoto ? (
    202208                                                                <img
     
    206212                                                                />
    207213                                                        ) : (
    208                                                                 user.fullName.charAt(0).toUpperCase()
     214                                                                <div className="w-full h-full bg-linear-to-br from-[#1db954] to-[#1ed760] flex items-center justify-center text-white text-5xl font-bold">
     215                                                                        {user.fullName.charAt(0).toUpperCase()}
     216                                                                </div>
    209217                                                        )}
    210218                                                </div>
    211219                                        </div>
    212220
    213                                         <div className="flex-1">
    214                                                 <h1 className="text-4xl font-bold mb-2">{user.fullName}</h1>
    215                                                 <span className="inline-block px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm font-medium mb-4">
    216                                                         {user.userType}
     221                                        {/* User info */}
     222                                        <div className="flex flex-col justify-end gap-3 min-w-0">
     223                                                <span className="text-xs uppercase tracking-widest text-gray-400 font-medium">
     224                                                        {user.userType === "ARTIST" ? "Artist" : "Listener"} • Profile
    217225                                                </span>
    218 
    219                                                 <div className="flex gap-6 mb-4 text-gray-700">
     226                                                <h1 className="text-4xl md:text-5xl font-extrabold leading-tight">
     227                                                        {user.fullName}
     228                                                </h1>
     229                                                <p className="text-gray-400">@{user.username}</p>
     230
     231                                                {/* Stats */}
     232                                                <div className="flex items-center gap-6 mt-2">
    220233                                                        <div
    221                                                                 className={`flex flex-col ${user.userType == "LISTENER" ? "cursor-pointer" : "cursor-default"}`}
     234                                                                className={`${user.userType === "LISTENER" ? "cursor-pointer hover:text-white" : ""} transition-colors`}
    222235                                                                onClick={
    223236                                                                        user.userType === "LISTENER" ? displayFollowers : undefined
    224237                                                                }
    225238                                                        >
    226                                                                 <span className="text-2xl font-bold">{user.followers}</span>
    227                                                                 <span className="text-sm text-gray-500">Followers</span>
     239                                                                <span className="text-xl font-bold text-white">
     240                                                                        {user.followers}
     241                                                                </span>
     242                                                                <span className="text-sm text-gray-400 ml-1">Followers</span>
    228243                                                        </div>
    229244                                                        <div
    230                                                                 className={`flex flex-col ${user.userType == "LISTENER" ? "cursor-pointer" : "cursor-default"}`}
     245                                                                className={`${user.userType === "LISTENER" ? "cursor-pointer hover:text-white" : ""} transition-colors`}
    231246                                                                onClick={
    232247                                                                        user.userType === "LISTENER" ? displayFollowing : undefined
    233248                                                                }
    234249                                                        >
    235                                                                 <span className="text-2xl font-bold">{user.following}</span>
    236                                                                 <span className="text-sm text-gray-500">Following</span>
     250                                                                <span className="text-xl font-bold text-white">
     251                                                                        {user.following}
     252                                                                </span>
     253                                                                <span className="text-sm text-gray-400 ml-1">Following</span>
    237254                                                        </div>
    238255                                                </div>
    239256
    240                                                 <button
    241                                                         onClick={handleFollow}
    242                                                         disabled={isFollowing}
    243                                                         className={`
    244                 px-6 py-2 font-semibold rounded-lg shadow-md
    245                 transition-colors duration-200
    246                 ${
    247                                                                         isFollowing
    248                                                                                 ? "bg-gray-400 text-gray-200 cursor-not-allowed"
    249                                                                                 : user.isFollowedByCurrentUser
    250                                                                                         ? "bg-gray-200 text-gray-700 hover:bg-gray-300 cursor-pointer"
    251                                                                                         : "bg-blue-500 text-white hover:bg-blue-600 cursor-pointer"
    252                                                                 }
    253               `}
    254                                                 >
    255                                                         {user.isFollowedByCurrentUser ? "Unfollow" : "Follow"}
    256                                                 </button>
     257                                                {/* Follow button - hidden on own profile */}
     258                                                {!isOwnProfile && (
     259                                                        <div className="mt-4">
     260                                                                <button
     261                                                                        onClick={handleFollow}
     262                                                                        disabled={isFollowing}
     263                                                                        className={`flex items-center gap-2 px-6 py-3 rounded-full text-sm font-semibold transition-all cursor-pointer ${
     264                                                                                isFollowing
     265                                                                                        ? "bg-gray-700 text-gray-400 cursor-not-allowed"
     266                                                                                        : user.isFollowedByCurrentUser
     267                                                                                                ? "bg-white/10 text-white hover:bg-white/20"
     268                                                                                                : "bg-[#1db954] text-black hover:bg-[#1ed760] hover:scale-105"
     269                                                                        }`}
     270                                                                >
     271                                                                        {user.isFollowedByCurrentUser ? (
     272                                                                                <>
     273                                                                                        <svg
     274                                                                                                className="w-5 h-5"
     275                                                                                                fill="none"
     276                                                                                                stroke="currentColor"
     277                                                                                                viewBox="0 0 24 24"
     278                                                                                        >
     279                                                                                                <path
     280                                                                                                        strokeLinecap="round"
     281                                                                                                        strokeLinejoin="round"
     282                                                                                                        strokeWidth={2}
     283                                                                                                        d="M5 13l4 4L19 7"
     284                                                                                                />
     285                                                                                        </svg>
     286                                                                                        Following
     287                                                                                </>
     288                                                                        ) : (
     289                                                                                <>
     290                                                                                        <svg
     291                                                                                                className="w-5 h-5"
     292                                                                                                fill="none"
     293                                                                                                stroke="currentColor"
     294                                                                                                viewBox="0 0 24 24"
     295                                                                                        >
     296                                                                                                <path
     297                                                                                                        strokeLinecap="round"
     298                                                                                                        strokeLinejoin="round"
     299                                                                                                        strokeWidth={2}
     300                                                                                                        d="M12 4v16m8-8H4"
     301                                                                                                />
     302                                                                                        </svg>
     303                                                                                        Follow
     304                                                                                </>
     305                                                                        )}
     306                                                                </button>
     307                                                        </div>
     308                                                )}
    257309                                        </div>
    258310                                </div>
    259311
     312                                {/* Content */}
    260313                                {user.userType === "ARTIST" ? (
    261314                                        <ArtistView contributions={user.contributions} />
Note: See TracChangeset for help on using the changeset viewer.