import { useState } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { motion, AnimatePresence } from 'framer-motion'; import { Plus, Pencil, Trash2, ArrowLeft } from 'lucide-react'; import { Link } from 'react-router-dom'; import { api, type Member } from '@/lib/api'; import { Button } from '@/components/ui/Button'; import { Input } from '@/components/ui/Input'; import { Modal } from '@/components/ui/Modal'; import { Avatar } from '@/components/ui/Avatar'; const PRESET_COLORS = [ '#6366f1', '#14b8a6', '#f43f5e', '#f59e0b', '#64748b', '#8b5cf6', '#ec4899', '#10b981', '#f97316', '#06b6d4', ]; interface MemberFormData { name: string; color: string; } function MemberForm({ initial, onSubmit, onCancel, loading, }: { initial?: MemberFormData; onSubmit: (data: MemberFormData) => void; onCancel: () => void; loading: boolean; }) { const [name, setName] = useState(initial?.name ?? ''); const [color, setColor] = useState(initial?.color ?? PRESET_COLORS[0]); return (
setName(e.target.value)} placeholder="Family member's name" autoFocus />

Color

{PRESET_COLORS.map((c) => (
setColor(e.target.value)} className="h-8 w-12 cursor-pointer rounded border border-theme bg-transparent" /> {color}
{/* Preview */} {name && (
{name}
)}
); } export default function MembersPage() { const qc = useQueryClient(); const [addOpen, setAddOpen] = useState(false); const [editTarget, setEditTarget] = useState(null); const [deleteTarget, setDeleteTarget] = useState(null); const { data: members = [], isLoading } = useQuery({ queryKey: ['members'], queryFn: () => api.get('/members').then((r) => r.data), }); const createMutation = useMutation({ mutationFn: (data: MemberFormData) => api.post('/members', data).then((r) => r.data), onSuccess: () => { qc.invalidateQueries({ queryKey: ['members'] }); setAddOpen(false); }, }); const updateMutation = useMutation({ mutationFn: ({ id, data }: { id: number; data: MemberFormData }) => api.put(`/members/${id}`, data).then((r) => r.data), onSuccess: () => { qc.invalidateQueries({ queryKey: ['members'] }); setEditTarget(null); }, }); const deleteMutation = useMutation({ mutationFn: (id: number) => api.delete(`/members/${id}`), onSuccess: () => { qc.invalidateQueries({ queryKey: ['members'] }); setDeleteTarget(null); }, }); return (
{/* Header */}

Family Members

{members.length} member{members.length !== 1 ? 's' : ''}

{/* Member list */} {isLoading ? (
{[1, 2, 3].map((i) => (
))}
) : members.length === 0 ? (
๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ

No family members yet

Add your family members to assign chores, events, and more.

) : (
{members.map((member) => (

{member.name}

{member.color}

))}
)} {/* Add modal */} setAddOpen(false)} title="Add Family Member"> createMutation.mutate(data)} onCancel={() => setAddOpen(false)} loading={createMutation.isPending} /> {/* Edit modal */} setEditTarget(null)} title="Edit Family Member"> {editTarget && ( updateMutation.mutate({ id: editTarget.id, data })} onCancel={() => setEditTarget(null)} loading={updateMutation.isPending} /> )} {/* Delete confirm modal */} setDeleteTarget(null)} title="Remove Member" size="sm"> {deleteTarget && (
{deleteTarget.name}

Removing this member won't delete their assigned chores or events โ€” those will simply become unassigned.

)}
); }