import { useState, useRef, useEffect, useMemo } from 'react'; import ReactDOM from 'react-dom'; import { useSpaceStore } from '../../stores/spaceStore'; import { useAuthStore } from '../../stores/authStore'; import { useUIStore } from '../../stores/uiStore'; export function TransferOwnershipModal({ spaceId, onClose }: { spaceId: string; onClose: () => void }) { const modalRef = useRef(null); const space = useSpaceStore((s) => s.spaces.find(sp => sp.id === spaceId)); const members = useSpaceStore((s) => s.members); const currentUserId = useAuthStore((s) => s.user?.id); const transferOwnership = useSpaceStore((s) => s.transferOwnership); const addToast = useUIStore((s) => s.addToast); const [search, setSearch] = useState(''); const [selectedUserId, setSelectedUserId] = useState(null); const [transferring, setTransferring] = useState(false); // Filter members: exclude self, filter by search const filteredMembers = useMemo(() => { const spaceMembers = members.filter(m => m.userId !== currentUserId); if (!search.trim()) return spaceMembers; const q = search.toLowerCase(); return spaceMembers.filter(m => m.user.displayName?.toLowerCase().includes(q) || m.user.username.toLowerCase().includes(q) ); }, [members, currentUserId, search]); const selectedMember = selectedUserId ? members.find(m => m.userId === selectedUserId) : null; // Close on click-outside and escape useEffect(() => { const handleClickOutside = (e: MouseEvent) => { if (modalRef.current && !modalRef.current.contains(e.target as Node)) { onClose(); } }; const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') { if (selectedUserId) { setSelectedUserId(null); } else { onClose(); } } }; document.addEventListener('mousedown', handleClickOutside); document.addEventListener('keydown', handleKeyDown); return () => { document.removeEventListener('mousedown', handleClickOutside); document.removeEventListener('keydown', handleKeyDown); }; }, [onClose, selectedUserId]); if (!space) return null; const handleTransfer = async () => { if (!selectedUserId) return; setTransferring(true); try { await transferOwnership(spaceId, selectedUserId); addToast(`Ownership transferred to ${selectedMember?.user.displayName || selectedMember?.user.username}`, 'success', 3000); onClose(); } catch (err) { addToast(err instanceof Error ? err.message : 'Failed to transfer ownership', 'warning', 3000); } finally { setTransferring(false); } }; return ReactDOM.createPortal(
{/* Header */}

Transfer Ownership

Choose a member to become the new owner of {space.name}

{selectedUserId && selectedMember ? ( /* Confirm step */

Transfer ownership of {space.name} to{' '} {selectedMember.user.displayName || selectedMember.user.username}?

You will become a regular member.

) : ( /* Member list */ <>
setSearch(e.target.value)} placeholder="Search members..." className="input-search w-full" autoFocus />
{filteredMembers.length === 0 ? (

No members found

) : ( filteredMembers.map((member) => { const avatarUrl = member.user.avatar ? (member.user.avatar.startsWith('http') || member.user.avatar.startsWith('/') ? member.user.avatar : `/api/uploads/${member.user.avatar}`) : null; return ( ); }) )}
)}
, document.body, ); }