MVP: Go daemon, password auth, persistent PTY terminals, React/xterm UI, PWA
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
190604247f
commit
436732dac0
@@ -0,0 +1,28 @@
|
||||
import { FormEvent, useState } from 'react'
|
||||
import { api } from './api'
|
||||
|
||||
export default function Login({ onLogin }: { onLogin: () => void }) {
|
||||
const [pw, setPw] = useState('')
|
||||
const [err, setErr] = useState('')
|
||||
const [busy, setBusy] = useState(false)
|
||||
|
||||
async function submit(e: FormEvent) {
|
||||
e.preventDefault()
|
||||
setBusy(true); setErr('')
|
||||
try { await api.login(pw); onLogin() }
|
||||
catch (e) { setErr(e instanceof Error ? e.message : 'login failed') }
|
||||
finally { setBusy(false) }
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="center">
|
||||
<form className="login" onSubmit={submit}>
|
||||
<h1>Hamlet</h1>
|
||||
<input type="password" autoFocus autoComplete="current-password" placeholder="password"
|
||||
value={pw} onChange={(e) => setPw(e.target.value)} />
|
||||
<button disabled={busy || !pw}>{busy ? '…' : 'Sign in'}</button>
|
||||
{err && <div className="error">{err}</div>}
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user