import { useState, useEffect } from 'react'; import { useAuth } from '../contexts/AuthContext.jsx'; import { api } from '../utils/api.js'; import { useToast } from '../contexts/ToastContext.jsx'; import Avatar from './Avatar.jsx'; export default function NewChatModal({ onClose, onCreated }) { const { user } = useAuth(); const toast = useToast(); const [tab, setTab] = useState('private'); // 'private' | 'public' const [name, setName] = useState(''); const [isReadonly, setIsReadonly] = useState(false); const [search, setSearch] = useState(''); const [users, setUsers] = useState([]); const [selected, setSelected] = useState([]); const [loading, setLoading] = useState(false); // True when exactly 1 user selected on private tab = direct message const isDirect = tab === 'private' && selected.length === 1; useEffect(() => { api.searchUsers('').then(({ users }) => setUsers(users)).catch(() => {}); }, []); useEffect(() => { if (search) { api.searchUsers(search).then(({ users }) => setUsers(users)).catch(() => {}); } }, [search]); const toggle = (u) => { if (u.id === user.id) return; setSelected(prev => prev.find(p => p.id === u.id) ? prev.filter(p => p.id !== u.id) : [...prev, u]); }; const handleCreate = async () => { if (tab === 'private' && selected.length === 0) return toast('Add at least one member', 'error'); if (tab === 'private' && selected.length > 1 && !name.trim()) return toast('Name required', 'error'); if (tab === 'public' && !name.trim()) return toast('Name required', 'error'); setLoading(true); try { let payload; if (isDirect) { // Direct message: no name, isDirect flag payload = { type: 'private', memberIds: selected.map(u => u.id), isDirect: true, }; } else { payload = { name: name.trim(), type: tab, memberIds: selected.map(u => u.id), isReadonly: tab === 'public' && isReadonly, }; } const { group } = await api.createGroup(payload); toast(isDirect ? 'Direct message started!' : `${tab === 'public' ? 'Public message' : 'Group message'} created!`, 'success'); onCreated(group); } catch (e) { toast(e.message, 'error'); } finally { setLoading(false); } }; // Placeholder for the name field const namePlaceholder = isDirect ? selected[0]?.name || '' : tab === 'public' ? 'e.g. Announcements' : 'e.g. Project Team'; return (
e.target === e.currentTarget && onClose()}>

Start a Chat

{user.role === 'admin' && (
)} {/* Message Name — hidden for direct (1-user) messages */} {!isDirect && (
setName(e.target.value)} placeholder={namePlaceholder} autoFocus={tab === 'public'} />
)} {/* Readonly toggle for public */} {tab === 'public' && user.role === 'admin' && ( )} {/* Member selector for private tab */} {tab === 'private' && ( <>
setSearch(e.target.value)} autoFocus />
{selected.length > 0 && (
{selected.map(u => ( {u.name} toggle(u)}>× ))}
)} {isDirect && (

A private two-person conversation. Select a second person to create a group instead.

)}
{users.filter(u => u.id !== user.id).map(u => ( ))}
)}
); }