'use client'; import { useState, useEffect } from 'react'; import { Box, Typography, Grid, Card, CardContent, Button, Avatar, Chip, CircularProgress, Alert, IconButton, Divider, Snackbar, } from '@mui/material'; import { PersonAdd, ContentCopy, People, Delete, GroupAdd } from '@mui/icons-material'; import { useAuth } from '@/lib/auth/AuthContext'; import { AppShell } from '@/components/layouts/AppShell/AppShell'; import { ProtectedRoute } from '@/components/common/ProtectedRoute'; import { familiesApi, Family, FamilyMember, InviteMemberData, JoinFamilyData } from '@/lib/api/families'; import { InviteMemberDialog } from '@/components/family/InviteMemberDialog'; import { JoinFamilyDialog } from '@/components/family/JoinFamilyDialog'; import { RemoveMemberDialog } from '@/components/family/RemoveMemberDialog'; import { motion } from 'framer-motion'; export default function FamilyPage() { const { user, refreshUser } = useAuth(); const [family, setFamily] = useState(null); const [members, setMembers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [inviteDialogOpen, setInviteDialogOpen] = useState(false); const [joinDialogOpen, setJoinDialogOpen] = useState(false); const [removeDialogOpen, setRemoveDialogOpen] = useState(false); const [memberToRemove, setMemberToRemove] = useState(null); const [actionLoading, setActionLoading] = useState(false); const [snackbar, setSnackbar] = useState({ open: false, message: '' }); // Get familyId from user const familyId = user?.families?.[0]?.familyId; useEffect(() => { if (familyId) { fetchFamilyData(); } else { setLoading(false); setError('No family found. Please complete onboarding first.'); } }, [familyId]); const fetchFamilyData = async () => { if (!familyId) return; try { setLoading(true); setError(''); const [familyData, membersData] = await Promise.all([ familiesApi.getFamily(familyId), familiesApi.getFamilyMembers(familyId), ]); setFamily(familyData); setMembers(membersData); } catch (err: any) { console.error('Failed to fetch family data:', err); setError(err.response?.data?.message || 'Failed to load family information'); } finally { setLoading(false); } }; const handleCopyCode = async () => { if (!family?.shareCode) return; try { await navigator.clipboard.writeText(family.shareCode); setSnackbar({ open: true, message: 'Share code copied to clipboard!' }); } catch (err) { setSnackbar({ open: true, message: 'Failed to copy share code' }); } }; const handleInviteMember = async (data: InviteMemberData) => { if (!familyId) { throw new Error('No family ID found'); } try { setActionLoading(true); await familiesApi.inviteMember(familyId, data); setSnackbar({ open: true, message: 'Invitation sent successfully!' }); await fetchFamilyData(); setInviteDialogOpen(false); } catch (err: any) { console.error('Failed to invite member:', err); throw new Error(err.response?.data?.message || 'Failed to send invitation'); } finally { setActionLoading(false); } }; const handleJoinFamily = async (data: JoinFamilyData) => { try { setActionLoading(true); await familiesApi.joinFamily(data); setSnackbar({ open: true, message: 'Successfully joined family!' }); await refreshUser(); await fetchFamilyData(); setJoinDialogOpen(false); } catch (err: any) { console.error('Failed to join family:', err); throw new Error(err.response?.data?.message || 'Failed to join family'); } finally { setActionLoading(false); } }; const handleRemoveClick = (member: FamilyMember) => { setMemberToRemove(member); setRemoveDialogOpen(true); }; const handleRemoveConfirm = async () => { if (!familyId || !memberToRemove) return; try { setActionLoading(true); await familiesApi.removeMember(familyId, memberToRemove.userId); setSnackbar({ open: true, message: 'Member removed successfully' }); await fetchFamilyData(); setRemoveDialogOpen(false); setMemberToRemove(null); } catch (err: any) { console.error('Failed to remove member:', err); setError(err.response?.data?.message || 'Failed to remove member'); } finally { setActionLoading(false); } }; const getRoleColor = (role: string): 'primary' | 'secondary' | 'default' | 'success' | 'warning' | 'info' => { switch (role) { case 'parent': return 'primary'; case 'caregiver': return 'secondary'; case 'viewer': return 'info'; default: return 'default'; } }; const isCurrentUser = (userId: string) => { return user?.id === userId; }; return ( Family Manage your family members and share access {error && ( setError('')}> {error} )} {loading ? ( ) : ( {/* Family Share Code */} {family && ( Family Share Code Share this code with family members to give them access to your family's data )} {/* Family Members */} Family Members ({members.length}) {members.length === 0 ? ( No family members yet Invite family members to collaborate on child care ) : ( {members.map((member, index) => ( {index > 0 && } {member.user?.name?.charAt(0).toUpperCase() || 'U'} {member.user?.name || 'Unknown User'} {isCurrentUser(member.userId) && ( )} {member.user?.email || 'No email'} {!isCurrentUser(member.userId) && ( handleRemoveClick(member)} color="error" > )} ))} )} )} setInviteDialogOpen(false)} onSubmit={handleInviteMember} isLoading={actionLoading} /> setJoinDialogOpen(false)} onSubmit={handleJoinFamily} isLoading={actionLoading} /> setRemoveDialogOpen(false)} onConfirm={handleRemoveConfirm} memberName={memberToRemove?.user?.name || ''} isLoading={actionLoading} /> setSnackbar({ ...snackbar, open: false })} message={snackbar.message} /> ); }