import { useEffect, useState } from 'react' import { X, Check, UserPlus } from 'lucide-react' import { journeyApi, authApi } from '../../api/client' import { useTranslation } from '../../i18n' import { useToast } from '../shared/Toast' export default function ContributorInviteDialog({ journeyId, existingUserIds, onClose, onInvited }: { journeyId: number existingUserIds: number[] onClose: () => void onInvited: () => void }) { const { t } = useTranslation() const [users, setUsers] = useState<{ id: number; username: string; email: string; avatar?: string | null }[]>([]) const [search, setSearch] = useState('') const [selectedUserId, setSelectedUserId] = useState(null) const [role, setRole] = useState<'editor' | 'viewer'>('viewer') const [sending, setSending] = useState(false) const toast = useToast() useEffect(() => { authApi.listUsers().then(d => setUsers(d.users || [])).catch(() => {}) }, []) const filtered = users.filter(u => { if (existingUserIds.includes(u.id)) return false if (!search) return true const q = search.toLowerCase() return u.username.toLowerCase().includes(q) || u.email.toLowerCase().includes(q) }) const handleInvite = async () => { if (!selectedUserId) return setSending(true) try { await journeyApi.addContributor(journeyId, selectedUserId, role) toast.success(t('journey.contributors.added')) onInvited() } catch { toast.error(t('journey.contributors.addFailed')) } finally { setSending(false) } } return (

{t('journey.contributors.invite')}

{/* Search */}
setSearch(e.target.value)} placeholder={t('journey.contributors.searchPlaceholder')} className="w-full px-3 py-2 border border-zinc-200 dark:border-zinc-700 rounded-lg text-[13px] bg-white dark:bg-zinc-800 text-zinc-900 dark:text-white outline-none focus:border-zinc-400 dark:focus:border-zinc-500" />
{/* User list */}
{filtered.length === 0 && (

{t('journey.contributors.noUsers')}

)} {filtered.map(u => (
setSelectedUserId(u.id)} className={`flex items-center gap-2.5 p-2.5 rounded-lg cursor-pointer transition-all ${ selectedUserId === u.id ? 'bg-zinc-100 dark:bg-zinc-800 border border-zinc-900 dark:border-white' : 'hover:bg-zinc-50 dark:hover:bg-zinc-800 border border-transparent' }`} >
{u.username[0].toUpperCase()}
{u.username}
{u.email}
{selectedUserId === u.id && (
)}
))}
{/* Role selector */}
{(['viewer', 'editor'] as const).map(r => ( ))}
) }