tahamajs/IE / Projects /front /src /components /messages /CreateGroupModal.tsx
tahamajs's picture
download
raw
4.83 kB
// components/GroupManagementModal.tsx
"use client";
import { useState, useEffect } from "react";
import api from "@/lib/api";
import { Group, GroupMember } from "@/types";
interface GroupManagementModalProps {
isOpen: boolean;
onClose: () => void;
group: Group;
currentUserId: number;
onUpdate: () => void;
}
export function GroupManagementModal({ isOpen, onClose, group, currentUserId, onUpdate }: GroupManagementModalProps) {
const [name, setName] = useState(group.name);
const [members, setMembers] = useState<GroupMember[]>([]);
const [search, setSearch] = useState("");
const [searchResults, setSearchResults] = useState<any[]>([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
if (isOpen) fetchMembers();
}, [isOpen, group]);
const fetchMembers = async () => {
try {
const res = await api.get(`/groups/${group.id}/members`);
setMembers(res.data);
} catch (err) {
console.error(err);
}
};
const searchUsers = async () => {
if (!search.trim()) return;
try {
const res = await api.get(`/users/search?q=${encodeURIComponent(search)}`);
const data = Array.isArray(res.data) ? res.data : res.data?.users || res.data?.result || [];
setSearchResults(data);
} catch (err) { console.error(err); }
};
const addMember = async (userId: number) => {
await api.post(`/groups/${group.id}/members`, { userId });
fetchMembers();
setSearch(""); setSearchResults([]);
};
const removeMember = async (userId: number) => {
await api.delete(`/groups/${group.id}/members/${userId}`);
fetchMembers();
};
const makeAdmin = async (userId: number) => {
await api.post(`/groups/${group.id}/admins/${userId}`);
fetchMembers();
};
const updateName = async () => {
await api.put(`/groups/${group.id}`, { name });
onUpdate();
};
const isAdmin = members.some(m => m.userId === currentUserId && m.isAdmin);
if (!isOpen) return null;
return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
<div className="bg-white dark:bg-gray-800 rounded-2xl w-full max-w-md p-6 shadow-xl max-h-[90vh] overflow-y-auto">
<div className="flex justify-between items-center mb-4">
<h2 className="text-xl font-bold">Manage Group: {group.name}</h2>
<button onClick={onClose} className="text-gray-500 hover:text-gray-700">✖</button>
</div>
<div className="space-y-4">
{isAdmin && (
<div className="flex gap-2">
<input
type="text" value={name} onChange={e => setName(e.target.value)}
className="flex-1 px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"
placeholder="Group name"
/>
<button onClick={updateName} className="btn btn-primary btn-sm">Rename</button>
</div>
)}
<div>
<h4 className="font-semibold mb-2">Members</h4>
<div className="space-y-2 max-h-60 overflow-y-auto">
{members.map(m => (
<div key={m.userId} className="flex justify-between items-center p-2 border-b">
<span>{m.username} {m.isAdmin && "(Admin)"}</span>
{isAdmin && m.userId !== currentUserId && (
<div className="flex gap-1">
{!m.isAdmin && (
<button onClick={() => makeAdmin(m.userId)} className="btn btn-secondary btn-sm">Make Admin</button>
)}
<button onClick={() => removeMember(m.userId)} className="btn btn-danger btn-sm">Remove</button>
</div>
)}
</div>
))}
</div>
</div>
{isAdmin && (
<div>
<h4 className="font-semibold mb-2">Add Member</h4>
<div className="flex gap-2">
<input
type="text" value={search} onChange={e => setSearch(e.target.value)}
className="flex-1 px-3 py-2 border rounded-lg"
placeholder="Search users..."
/>
<button onClick={searchUsers} className="btn btn-secondary btn-sm">Search</button>
</div>
<div className="mt-2 space-y-1">
{searchResults.map(u => (
<div key={u.id} className="flex justify-between items-center p-2 border-b">
<span>{u.username}</span>
<button onClick={() => addMember(u.id)} className="btn btn-primary btn-sm">Add</button>
</div>
))}
</div>
</div>
)}
</div>
</div>
</div>
);
}

Xet Storage Details

Size:
4.83 kB
·
Xet hash:
e2355b9736cd41c7a0fc786fdfb3dbfcd07595b815755ee2ac794a7bef7d98bc

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.