Changeset 0792d02 for frontend/src/pages


Ignore:
Timestamp:
02/05/26 10:29:09 (5 months ago)
Author:
Dimitar Arsov <dimitararsov04@…>
Branches:
main
Children:
3de009b
Parents:
d2af1a6
Message:

show saved playlists by user

Location:
frontend/src/pages
Files:
2 edited

Legend:

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

    rd2af1a6 r0792d02  
    44
    55interface User {
    6         id: number;
    7         username: string;
    8         fullName: string;
     6  username: string;
     7  fullName: string;
    98}
    109
    1110const AllUsers = () => {
    12         const [users, setUsers] = useState<User[]>([]);
    13         const [searchedUser, setSearchedUser] = useState<string>("");
    14         const [error, setError] = useState<string | null>(null);
    15         const navigate = useNavigate();
     11  const [users, setUsers] = useState<User[]>([]);
     12  const [searchedUser, setSearchedUser] = useState<string>("");
     13  const [error, setError] = useState<string | null>(null);
     14  const navigate = useNavigate();
    1615
    17         useEffect(() => {
    18                 const fetchUsers = async () => {
    19                         const response = axiosInstance.get("/users/all");
    20                         setUsers((await response).data);
    21                 };
    22                 fetchUsers();
    23         }, []);
     16  useEffect(() => {
     17    const fetchUsers = async () => {
     18      const response = axiosInstance.get("/users/all");
     19      setUsers((await response).data);
     20    };
     21    fetchUsers();
     22  }, []);
    2423
    25         const handleUserClick = (userId: number) => {
    26                 navigate(`/users/${userId}`);
    27         };
     24  const handleUserClick = (username: string) => {
     25    navigate(`/users/${username}`);
     26  };
    2827
    29         const handleSearch = async (e: React.FormEvent) => {
    30                 e.preventDefault();
    31                 try {
    32                         const response = await axiosInstance.get(`/users/search`, {
    33                                 params: { name: searchedUser },
    34                         });
    35                         setUsers(response.data);
    36                 } catch (err: any) {
    37                         const errorMessage = err.response?.data?.error || "Search failed";
    38                         setError(errorMessage);
    39                 }
    40         };
     28  const handleSearch = async (e: React.FormEvent) => {
     29    e.preventDefault();
     30    try {
     31      const response = await axiosInstance.get(`/users/search`, {
     32        params: { name: searchedUser },
     33      });
     34      setUsers(response.data);
     35    } catch (err: any) {
     36      const errorMessage = err.response?.data?.error || "Search failed";
     37      setError(errorMessage);
     38    }
     39  };
    4140
    42         if (users.length == 0) return <div className="p-6">Loading...</div>;
    43         if (error) {
    44                 return (
    45                         <div className="p-6 bg-red-50 border border-red-200 text-red-700 rounded-lg">
    46                                 <h2 className="font-bold">Error</h2>
    47                                 <p>{error}</p>
    48                         </div>
    49                 );
    50         }
     41  if (users.length == 0) return <div className="p-6">Loading...</div>;
     42  if (error) {
     43    return (
     44      <div className="p-6 bg-red-50 border border-red-200 text-red-700 rounded-lg">
     45        <h2 className="font-bold">Error</h2>
     46        <p>{error}</p>
     47      </div>
     48    );
     49  }
    5150
    52         return (
    53                 <div className="container mx-auto p-6">
    54                         <h1 className="text-3xl font-bold mb-6">All Users</h1>
    55                         <form onSubmit={handleSearch} className="flex gap-2 mb-10">
    56                                 <input
    57                                         type="text"
    58                                         value={searchedUser}
    59                                         onChange={(e) => setSearchedUser(e.target.value)}
    60                                         className="border p-2 rounded w-full"
    61                                         placeholder="Search for a user..."
    62                                 />
    63                                 <button
    64                                         type="submit"
    65                                         className="bg-blue-600 text-white px-6 py-2 rounded hover:bg-blue-700 transition-colors"
    66                                 >
    67                                         Search
    68                                 </button>
    69                         </form>
     51  return (
     52    <div className="container mx-auto p-6">
     53      <h1 className="text-3xl font-bold mb-6">All Users</h1>
     54      <form onSubmit={handleSearch} className="flex gap-2 mb-10">
     55        <input
     56          type="text"
     57          value={searchedUser}
     58          onChange={(e) => setSearchedUser(e.target.value)}
     59          className="border p-2 rounded w-full"
     60          placeholder="Search for a user..."
     61        />
     62        <button
     63          type="submit"
     64          className="bg-blue-600 text-white px-6 py-2 rounded hover:bg-blue-700 transition-colors"
     65        >
     66          Search
     67        </button>
     68      </form>
    7069
    71                         <div className="grid gap-4">
    72                                 {users.map((u) => (
    73                                         <div
    74                                                 key={u.id}
    75                                                 onClick={() => handleUserClick(u.id)}
    76                                                 className="bg-white shadow-md rounded-lg p-4 hover:shadow-lg hover:bg-gray-50 cursor-pointer transition-all"
    77                                         >
    78                                                 <h2 className="text-xl font-semibold">{u.fullName}</h2>
    79                                                 <p className="text-gray-600">@{u.username}</p>
    80                                                 <p className="text-gray-600">{u.id}</p>
    81                                         </div>
    82                                 ))}
    83                         </div>
    84                 </div>
    85         );
     70      <div className="grid gap-4">
     71        {users.map((u) => (
     72          <div
     73            key={u.username}
     74            onClick={() => handleUserClick(u.username)}
     75            className="bg-white shadow-md rounded-lg p-4 hover:shadow-lg hover:bg-gray-50 cursor-pointer transition-all"
     76          >
     77            <h2 className="text-xl font-semibold">{u.fullName}</h2>
     78            <p className="text-gray-600">@{u.username}</p>
     79          </div>
     80        ))}
     81      </div>
     82    </div>
     83  );
    8684};
    8785
  • frontend/src/pages/UserDetail.tsx

    rd2af1a6 r0792d02  
    2727  likedEntities: MusicalEntity[];
    2828  createdPlaylists: Playlist[];
     29  savedPlaylists: Playlist[];
    2930}
    3031
     
    3435  // user refers to the selected user NOT to the user from context
    3536  const baseURL = import.meta.env.VITE_API_BASE_URL;
    36   const { userId } = useParams();
     37  const { username } = useParams();
    3738  const navigate = useNavigate();
    3839  const [user, setUser] = useState<UserProfile | null>(null);
     
    5051    try {
    5152      const response = await axiosInstance.post<FollowStatus>(
    52         `/users/${userId}/follow`,
     53        `/users/${username}/follow`,
    5354      );
    5455      setUser((prev) => {
     
    6869  };
    6970
    70   const handleFollowInModal = async (targetId: number) => {
     71  const handleFollowInModal = async (targetUsername: string) => {
    7172    try {
    7273      const response = await axiosInstance.post<FollowStatus>(
    73         `/users/${targetId}/follow`,
     74        `/users/${username}/follow`,
    7475      );
    7576
    7677      setModalUsers((prevUsers) =>
    7778        prevUsers.map((u) =>
    78           u.id === targetId
     79          u.username === targetUsername
    7980            ? { ...u, isFollowedByCurrentUser: response.data.isFollowing }
    8081            : u,
     
    100101    setIsLoadingModal(true);
    101102    try {
    102       const response = await axiosInstance.get(`/users/${userId}/followers`);
     103      const response = await axiosInstance.get(`/users/${username}/followers`);
    103104      setModalUsers(response.data);
    104105      setModalTitle("Followers");
     
    113114    setIsLoadingModal(true);
    114115    try {
    115       const response = await axiosInstance.get(`/users/${userId}/following`);
     116      const response = await axiosInstance.get(`/users/${username}/following`);
    116117      setModalUsers(response.data);
    117118      setModalTitle("Following");
     
    128129      setError(null);
    129130      try {
    130         const response = await axiosInstance.get(`/users/${userId}`);
     131        const response = await axiosInstance.get(`/users/${username}`);
    131132        console.log(response.data);
    132133        setUser(response.data);
     
    136137    };
    137138    fetchUser();
    138   }, [userId]);
     139  }, [username]);
    139140
    140141  if (error) {
     
    233234          <ListenerView
    234235            likedEntities={user.likedEntities}
    235             playlists={user.createdPlaylists}
     236            createdPlaylists={user.createdPlaylists}
     237            savedPlaylists={user.savedPlaylists}
    236238          />
    237239        )}
Note: See TracChangeset for help on using the changeset viewer.