import React, { useState, useEffect } from 'react'; import { X, Search, UserPlus, Loader2, Shield, ShieldAlert } from 'lucide-react'; interface AddMemberModalProps { isOpen: boolean; onClose: () => void; tourId: string; } export const AddMemberModal: React.FC = ({ isOpen, onClose, tourId }) => { const [query, setQuery] = useState(''); const [users, setUsers] = useState([]); const [loading, setLoading] = useState(false); const [selectedUser, setSelectedUser] = useState(null); const [role, setRole] = useState<'OWNER' | 'MANAGER' | 'MEMBER' | 'MEMBER_NO_FINANCE' | 'VIEWER_ONLY'>('MEMBER'); const [submitting, setSubmitting] = useState(false); const [fetchError, setFetchError] = useState(''); const [submitError, setSubmitError] = useState(''); const fetchUsers = async () => { setLoading(true); setFetchError(''); try { const API_BASE = `http://${window.location.hostname}:3001`; const res = await fetch(`${API_BASE}/api/v1/users?q=${encodeURIComponent(query)}`, { headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` } }); if (!res.ok) throw new Error('Không thể tải danh sách người dùng'); const data = await res.json(); setUsers(data); } catch (err: any) { setFetchError(err.message || 'Không thể tải danh sách người dùng'); } finally { setLoading(false); } }; useEffect(() => { if (!isOpen) return; fetchUsers(); }, [isOpen]); useEffect(() => { if (!isOpen) { setQuery(''); setSelectedUser(null); setRole('MEMBER'); setFetchError(''); } }, [isOpen]); const handleAdd = async () => { if (!selectedUser) return; setSubmitting(true); try { const API_BASE = `http://${window.location.hostname}:3001`; const res = await fetch(`${API_BASE}/api/v1/tours/${tourId}/members`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${localStorage.getItem('token')}`, }, body: JSON.stringify({ userId: selectedUser, role }), }); if (!res.ok) { const data = await res.json(); throw new Error(data.message || 'Thêm thành viên thất bại'); } onClose(); } catch (err: any) { alert(err.message); } finally { setSubmitting(false); } }; if (!isOpen) return null; return (

Thêm thành viên

Chọn người dùng và phân quyền cho tour này.

setQuery(e.target.value)} onBlur={fetchUsers} />
{fetchError && (
{fetchError}
)} {loading ? (
) : (
{users.map((u) => { const isSelected = selectedUser === u.id; return ( ); })} {!loading && users.length === 0 && (
Không tìm thấy người dùng phù hợp
)}
)}
); };