Files
maternal-app/maternal-web/components/family/JoinFamilyDialog.tsx
andupetcu 286887440e Implement Family page with full backend integration
Features:
- Fetch and display family details and members
- Family share code with copy-to-clipboard functionality
- Invite family members via email with role selection
- Join another family using share code
- Remove family members with confirmation
- Visual indicators for current user
- Role-based chip colors (Parent/Caregiver/Viewer)
- Loading states and error handling
- Empty state when no members exist
- Success notifications via Snackbar

Components Created:
- components/family/InviteMemberDialog.tsx: Invite form with email and role
- components/family/JoinFamilyDialog.tsx: Join family via share code
- components/family/RemoveMemberDialog.tsx: Remove member confirmation

All features fully integrated with backend API using familiesApi

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-30 22:14:56 +03:00

96 lines
2.3 KiB
TypeScript

'use client';
import { useState, useEffect } from 'react';
import {
Dialog,
DialogTitle,
DialogContent,
DialogActions,
Button,
TextField,
Box,
Alert,
Typography,
} from '@mui/material';
import { JoinFamilyData } from '@/lib/api/families';
interface JoinFamilyDialogProps {
open: boolean;
onClose: () => void;
onSubmit: (data: JoinFamilyData) => Promise<void>;
isLoading?: boolean;
}
export function JoinFamilyDialog({
open,
onClose,
onSubmit,
isLoading = false,
}: JoinFamilyDialogProps) {
const [shareCode, setShareCode] = useState<string>('');
const [error, setError] = useState<string>('');
useEffect(() => {
if (open) {
setShareCode('');
setError('');
}
}, [open]);
const handleSubmit = async () => {
setError('');
// Validation
if (!shareCode.trim()) {
setError('Please enter a share code');
return;
}
try {
await onSubmit({ shareCode: shareCode.trim() });
onClose();
} catch (err: any) {
setError(err.message || 'Failed to join family');
}
};
return (
<Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth>
<DialogTitle>Join a Family</DialogTitle>
<DialogContent>
<Box sx={{ pt: 2, display: 'flex', flexDirection: 'column', gap: 2 }}>
{error && (
<Alert severity="error" onClose={() => setError('')}>
{error}
</Alert>
)}
<Typography variant="body2" color="text.secondary">
Enter the share code provided by the family administrator to join their family.
</Typography>
<TextField
label="Share Code"
value={shareCode}
onChange={(e) => setShareCode(e.target.value)}
fullWidth
required
autoFocus
disabled={isLoading}
placeholder="Enter family share code"
helperText="Ask a family member for their share code"
/>
</Box>
</DialogContent>
<DialogActions>
<Button onClick={onClose} disabled={isLoading}>
Cancel
</Button>
<Button onClick={handleSubmit} variant="contained" disabled={isLoading}>
{isLoading ? 'Joining...' : 'Join Family'}
</Button>
</DialogActions>
</Dialog>
);
}