| [2b08bed] | 1 | import { useNavigate } from "react-router-dom";
|
|---|
| [1579b4f] | 2 | import { baseURL } from "../../api/axiosInstance";
|
|---|
| [2b08bed] | 3 | import type { BaseNonAdminUser } from "../../utils/types";
|
|---|
| [d1ee039] | 4 | import { useEffect } from "react";
|
|---|
| [2b08bed] | 5 |
|
|---|
| 6 | interface ModalProps {
|
|---|
| [d1ee039] | 7 | title: string;
|
|---|
| 8 | users: BaseNonAdminUser[];
|
|---|
| 9 | onClose: () => void;
|
|---|
| 10 | onFollowToggle: (targetUsername: string) => Promise<void>;
|
|---|
| [2b08bed] | 11 | }
|
|---|
| 12 |
|
|---|
| 13 | const UserListModal = ({
|
|---|
| [d1ee039] | 14 | title,
|
|---|
| 15 | users,
|
|---|
| 16 | onClose,
|
|---|
| 17 | onFollowToggle,
|
|---|
| [2b08bed] | 18 | }: ModalProps) => {
|
|---|
| [d1ee039] | 19 | const navigate = useNavigate();
|
|---|
| 20 | useEffect(() => {
|
|---|
| 21 | document.body.style.overflow = "hidden";
|
|---|
| 22 | return () => {
|
|---|
| 23 | document.body.style.overflow = "";
|
|---|
| 24 | };
|
|---|
| 25 | }, []);
|
|---|
| [2b08bed] | 26 |
|
|---|
| [d1ee039] | 27 | return (
|
|---|
| 28 | <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm">
|
|---|
| 29 | <div className="bg-[#1a1a2e] border border-white/10 rounded-xl shadow-2xl w-full max-w-md max-h-[70vh] flex flex-col">
|
|---|
| 30 | <div className="p-4 border-b border-white/10 flex justify-between items-center">
|
|---|
| 31 | <h2 className="text-xl font-bold text-white">{title}</h2>
|
|---|
| 32 | <button
|
|---|
| 33 | onClick={onClose}
|
|---|
| 34 | className="text-gray-400 hover:text-white text-2xl cursor-pointer transition-colors"
|
|---|
| 35 | >
|
|---|
| 36 | ×
|
|---|
| 37 | </button>
|
|---|
| 38 | </div>
|
|---|
| [2b08bed] | 39 |
|
|---|
| [d1ee039] | 40 | <div className="overflow-y-auto p-4 flex-1">
|
|---|
| 41 | {users.length === 0 ? (
|
|---|
| 42 | <p className="text-center text-gray-500 py-8">No users found.</p>
|
|---|
| 43 | ) : (
|
|---|
| 44 | users.map((u) => (
|
|---|
| 45 | <div
|
|---|
| 46 | key={u.username}
|
|---|
| 47 | className="flex items-center justify-between p-3 hover:bg-white/5 rounded-lg transition-colors"
|
|---|
| 48 | >
|
|---|
| 49 | <div
|
|---|
| 50 | className="flex items-center gap-4 cursor-pointer flex-1"
|
|---|
| 51 | onClick={() => {
|
|---|
| 52 | onClose();
|
|---|
| 53 | navigate(`/users/${u.username}`);
|
|---|
| 54 | }}
|
|---|
| 55 | >
|
|---|
| 56 | <div className="w-10 h-10 rounded-full bg-[#282828] overflow-hidden shrink-0 flex items-center justify-center">
|
|---|
| 57 | {u.profilePhoto ? (
|
|---|
| 58 | <img
|
|---|
| 59 | src={`${baseURL}/${u.profilePhoto}`}
|
|---|
| 60 | className="w-full h-full object-cover"
|
|---|
| 61 | alt=""
|
|---|
| 62 | />
|
|---|
| 63 | ) : (
|
|---|
| 64 | <span className="text-[#1db954] font-bold">
|
|---|
| 65 | {u.fullName.charAt(0)}
|
|---|
| 66 | </span>
|
|---|
| 67 | )}
|
|---|
| 68 | </div>
|
|---|
| 69 | <div>
|
|---|
| 70 | <p className="font-semibold text-white">{u.fullName}</p>
|
|---|
| 71 | <p className="text-sm text-gray-400">@{u.username}</p>
|
|---|
| 72 | </div>
|
|---|
| 73 | </div>
|
|---|
| [2b08bed] | 74 |
|
|---|
| [d1ee039] | 75 | <button
|
|---|
| 76 | onClick={() => onFollowToggle(u.username)}
|
|---|
| 77 | className={`px-4 py-1.5 text-sm font-medium rounded-full transition-colors cursor-pointer ${
|
|---|
| 78 | u.isFollowedByCurrentUser
|
|---|
| 79 | ? "bg-white/10 text-white hover:bg-white/20"
|
|---|
| 80 | : "bg-[#1db954] text-black hover:bg-[#1ed760]"
|
|---|
| 81 | }`}
|
|---|
| 82 | >
|
|---|
| 83 | {u.isFollowedByCurrentUser ? "Following" : "Follow"}
|
|---|
| 84 | </button>
|
|---|
| 85 | </div>
|
|---|
| 86 | ))
|
|---|
| 87 | )}
|
|---|
| 88 | </div>
|
|---|
| 89 | </div>
|
|---|
| 90 | <div className="absolute inset-0 -z-10" onClick={onClose}></div>
|
|---|
| 91 | </div>
|
|---|
| 92 | );
|
|---|
| [2b08bed] | 93 | };
|
|---|
| 94 |
|
|---|
| 95 | export default UserListModal;
|
|---|