'use client'; import { useState } from 'react'; import { storeSession } from '@/lib/authClient'; // v1.1.0 (ISS-107) — full-screen sign-in / create-account screen shown when no valid session is // stored. Both forms POST the same shape ({username, password}); login mints a session for an // existing account, register creates one first and then mints it. On success the sessionId goes // to localStorage (via storeSession) and onAuthed() flips the shell back in. interface SignInScreenProps { onAuthed: () => void; } export default function SignInScreen({ onAuthed }: SignInScreenProps) { const [error, setError] = useState(null); const [busy, setBusy] = useState(false); async function submit(e: React.FormEvent, path: '/api/login' | '/api/register') { e.preventDefault(); if (busy) return; setBusy(true); setError(null); try { const form = new FormData(e.currentTarget); const res = await fetch(path, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: String(form.get('username') ?? ''), password: String(form.get('password') ?? ''), }), cache: 'no-store', }); const data = (await res.json()) as { sessionId?: string; error?: string }; if (!res.ok || !data.sessionId) throw new Error(data.error ?? `HTTP ${res.status}`); storeSession(data.sessionId); onAuthed(); } catch (err) { setError(err instanceof Error ? err.message : String(err)); } finally { setBusy(false); } } return (

Flight Ops

{error !== null && (

{error}

)}
void submit(e, '/api/login')}>

or

void submit(e, '/api/register')}>
); }