import { useState } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { getOwners, getTeams, deleteOwner, createOwner } from '../api/client'; import PageHeader from '../components/PageHeader'; import DataTable from '../components/DataTable'; import type { Column } from '../components/DataTable'; import ErrorState from '../components/ErrorState'; import { formatDateTime } from '../api/utils'; import type { Owner, Team } from '../api/types'; interface CreateOwnerModalProps { isOpen: boolean; onClose: () => void; onSuccess: () => void; isLoading: boolean; error: string | null; teamsData?: { data: Team[] }; } function CreateOwnerModal({ isOpen, onClose, onSuccess, isLoading, error, teamsData }: CreateOwnerModalProps) { const [name, setName] = useState(''); const [email, setEmail] = useState(''); const [teamId, setTeamId] = useState(''); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!name.trim() || !email.trim()) return; try { await createOwner({ name: name.trim(), email: email.trim(), team_id: teamId || undefined, }); setName(''); setEmail(''); setTeamId(''); onSuccess(); } catch (err) { console.error('Create owner error:', err); } }; if (!isOpen) return null; const teams = teamsData?.data || []; return (
e.stopPropagation()}>

Create Owner

{error &&
{error}
}
setName(e.target.value)} className="w-full bg-white border border-surface-border rounded px-3 py-2 text-sm text-ink focus:outline-none focus:border-brand-400" placeholder="e.g., Alice Smith" required />
setEmail(e.target.value)} className="w-full bg-white border border-surface-border rounded px-3 py-2 text-sm text-ink focus:outline-none focus:border-brand-400" placeholder="alice@example.com" required />
); } export default function OwnersPage() { const queryClient = useQueryClient(); const [showCreate, setShowCreate] = useState(false); const { data, isLoading, error, refetch } = useQuery({ queryKey: ['owners'], queryFn: () => getOwners(), }); const { data: teamsData } = useQuery({ queryKey: ['teams'], queryFn: () => getTeams(), }); const deleteMutation = useMutation({ mutationFn: deleteOwner, onSuccess: () => queryClient.invalidateQueries({ queryKey: ['owners'] }), onError: (err: Error) => alert(`Delete failed: ${err.message}`), }); const createMutation = useMutation({ mutationFn: createOwner, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['owners'] }); setShowCreate(false); }, }); const teamMap = new Map(); (teamsData?.data || []).forEach((t) => teamMap.set(t.id, t)); const columns: Column[] = [ { key: 'name', label: 'Owner', render: (o) => (
{o.name}
{o.id}
), }, { key: 'email', label: 'Email', render: (o) => {o.email || '\u2014'}, }, { key: 'team', label: 'Team', render: (o) => { const team = teamMap.get(o.team_id); return team ? {team.name} : {o.team_id || '\u2014'}; }, }, { key: 'created', label: 'Created', render: (o) => {formatDateTime(o.created_at)}, }, { key: 'actions', label: '', render: (o) => ( ), }, ]; return ( <> setShowCreate(true)} className="btn btn-primary"> + New Owner } />
{error ? ( refetch()} /> ) : ( )}
setShowCreate(false)} onSuccess={() => {}} isLoading={createMutation.isPending} error={createMutation.error ? (createMutation.error as Error).message : null} teamsData={teamsData} /> ); }