import { type FormEvent, useState } from 'react' import { toast } from 'sonner' import { Button } from '@/components/ui/button' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { api } from '@/lib/api' import { useAuth } from '@/store/auth' interface AuthResponse { token: string memberId: string } interface BootstrapResponse { token: string memberId: string organizationId: string } interface MeResponse { email: string memberships: { scopeType: string; scopeId: string; role: string }[] } export function LoginPage() { const setAuth = useAuth((state) => state.setAuth) const [mode, setMode] = useState<'login' | 'bootstrap'>('login') const [email, setEmail] = useState('') const [password, setPassword] = useState('') const [displayName, setDisplayName] = useState('') const [orgName, setOrgName] = useState('') const [busy, setBusy] = useState(false) async function submit(event: FormEvent) { event.preventDefault() setBusy(true) try { if (mode === 'bootstrap') { const result = await api.post('/api/identity/bootstrap', { organizationName: orgName, ownerEmail: email, ownerDisplayName: displayName, ownerPassword: password, }) setAuth(result.token, result.memberId, result.organizationId, email) } else { const result = await api.post('/api/identity/auth/login', { email, password }) setAuth(result.token, result.memberId, null, email) const me = await api.get('/api/identity/me') const org = me.memberships.find((m) => m.scopeType === 'Organization') setAuth(result.token, result.memberId, org?.scopeId ?? null, me.email) } } catch (err) { toast.error((err as Error).message) } finally { setBusy(false) } } return (
T TeamUp.AI
{mode === 'login' ? 'Sign in to your command center.' : 'Create the first owner of a new org.'}
{mode === 'bootstrap' && ( )} {mode === 'bootstrap' && ( )}
) } function LabeledInput(props: { id: string label: string value: string onChange: (value: string) => void type?: string }) { return (
props.onChange(event.target.value)} required />
) }