import { useState, useEffect } from 'react'; import { useToast } from '../contexts/ToastContext.jsx'; import { useAuth } from '../contexts/AuthContext.jsx'; import { api } from '../utils/api.js'; export default function AddChildAliasModal({ features = {}, onClose }) { const toast = useToast(); const { user: currentUser } = useAuth(); const loginType = features.loginType || 'guardian_only'; const isMixedAge = loginType === 'mixed_age'; // ── Guardian-only state (alias form) ────────────────────────────────────── const [aliases, setAliases] = useState([]); const [editingAlias, setEditingAlias] = useState(null); const [form, setForm] = useState({ firstName: '', lastName: '', dob: '', phone: '', email: '' }); const [avatarFile, setAvatarFile] = useState(null); const [saving, setSaving] = useState(false); // ── Mixed-age state (real minor users) ──────────────────────────────────── const [minorPlayers, setMinorPlayers] = useState([]); // available + already-mine const [selectedMinorId, setSelectedMinorId] = useState(''); const [addingMinor, setAddingMinor] = useState(false); // ── Partner state (shared) ──────────────────────────────────────────────── const [partner, setPartner] = useState(null); const [selectedPartnerId, setSelectedPartnerId] = useState(''); const [respondSeparately, setRespondSeparately] = useState(false); const [allUsers, setAllUsers] = useState([]); const [savingPartner, setSavingPartner] = useState(false); useEffect(() => { const loads = [api.getPartner(), api.searchUsers('')]; if (isMixedAge) { loads.push(api.getMinorPlayers()); } else { loads.push(api.getAliases()); } Promise.all(loads).then(([partnerRes, usersRes, thirdRes]) => { const p = partnerRes.partner || null; setPartner(p); setSelectedPartnerId(p?.id?.toString() || ''); setRespondSeparately(p?.respond_separately || false); setAllUsers((usersRes.users || []).filter(u => u.id !== currentUser?.id && !u.is_default_admin)); if (isMixedAge) { setMinorPlayers(thirdRes.users || []); } else { setAliases(thirdRes.aliases || []); } }).catch(() => {}); }, [isMixedAge]); // ── Helpers ─────────────────────────────────────────────────────────────── const set = k => e => setForm(p => ({ ...p, [k]: e.target.value })); const resetForm = () => { setEditingAlias(null); setForm({ firstName: '', lastName: '', dob: '', phone: '', email: '' }); setAvatarFile(null); }; const lbl = (text, required) => ( ); // ── Partner handlers ────────────────────────────────────────────────────── const handleSavePartner = async () => { setSavingPartner(true); try { if (!selectedPartnerId) { await api.removePartner(); setPartner(null); setRespondSeparately(false); if (!isMixedAge) { const { aliases: fresh } = await api.getAliases(); setAliases(fresh || []); resetForm(); } else { const { users: fresh } = await api.getMinorPlayers(); setMinorPlayers(fresh || []); } toast('Spouse/Partner/Co-Parent removed', 'success'); } else { const { partner: p } = await api.setPartner(parseInt(selectedPartnerId), respondSeparately); setPartner(p); setRespondSeparately(p?.respond_separately || false); if (!isMixedAge) { const { aliases: fresh } = await api.getAliases(); setAliases(fresh || []); } toast('Spouse/Partner/Co-Parent saved', 'success'); } } catch (e) { toast(e.message, 'error'); } finally { setSavingPartner(false); } }; // ── Guardian-only alias handlers ────────────────────────────────────────── const handleSelectAlias = (a) => { if (editingAlias?.id === a.id) { resetForm(); return; } setEditingAlias(a); setForm({ firstName: a.first_name || '', lastName: a.last_name || '', dob: a.date_of_birth ? a.date_of_birth.slice(0, 10) : '', phone: a.phone || '', email: a.email || '', }); setAvatarFile(null); }; const handleSaveAlias = async () => { if (!form.firstName.trim() || !form.lastName.trim()) return toast('First and last name required', 'error'); setSaving(true); try { if (editingAlias) { await api.updateAlias(editingAlias.id, { firstName: form.firstName.trim(), lastName: form.lastName.trim(), dateOfBirth: form.dob || null, phone: form.phone || null, email: form.email || null, }); if (avatarFile) await api.uploadAliasAvatar(editingAlias.id, avatarFile); toast('Child alias updated', 'success'); } else { const { alias } = await api.createAlias({ firstName: form.firstName.trim(), lastName: form.lastName.trim(), dateOfBirth: form.dob || null, phone: form.phone || null, email: form.email || null, }); if (avatarFile) await api.uploadAliasAvatar(alias.id, avatarFile); toast('Child alias added', 'success'); } const { aliases: fresh } = await api.getAliases(); setAliases(fresh || []); resetForm(); } catch (e) { toast(e.message, 'error'); } finally { setSaving(false); } }; const handleDeleteAlias = async (e, aliasId) => { e.stopPropagation(); try { await api.deleteAlias(aliasId); setAliases(prev => prev.filter(a => a.id !== aliasId)); if (editingAlias?.id === aliasId) resetForm(); toast('Child alias removed', 'success'); } catch (err) { toast(err.message, 'error'); } }; // ── Mixed-age minor handlers ────────────────────────────────────────────── const myMinors = minorPlayers.filter(u => u.guardian_user_id === currentUser?.id); const availableMinors = minorPlayers.filter(u => !u.guardian_user_id); const handleAddMinor = async () => { if (!selectedMinorId) return; setAddingMinor(true); try { await api.addGuardianChild(parseInt(selectedMinorId)); const { users: fresh } = await api.getMinorPlayers(); setMinorPlayers(fresh || []); setSelectedMinorId(''); toast('Child added and account activated', 'success'); } catch (e) { toast(e.message, 'error'); } finally { setAddingMinor(false); } }; const handleRemoveMinor = async (e, minorId) => { e.stopPropagation(); try { await api.removeGuardianChild(minorId); const { users: fresh } = await api.getMinorPlayers(); setMinorPlayers(fresh || []); toast('Child removed', 'success'); } catch (err) { toast(err.message, 'error'); } }; return (
No minor players available to link.
)} > )} {/* ── Guardian Only: alias form ── */} {!isMixedAge && ( <> {/* Existing aliases list */} {aliases.length > 0 && (