myke69's picture
Add files using upload-large-folder tool
3752e5d verified
Raw
History Blame Contribute Delete
2.04 kB
import React, { useState } from 'react'
import { setToken } from '../api.js'
export default function Login({ onSuccess }) {
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [error, setError] = useState(null)
const [busy, setBusy] = useState(false)
async function submit(e) {
e.preventDefault()
setBusy(true)
setError(null)
try {
const res = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password }),
})
if (!res.ok) throw new Error(res.status === 401 ? 'Wrong username or password' : `Login failed (${res.status})`)
const { token } = await res.json()
setToken(token)
onSuccess()
} catch (err) {
setError(err.message)
} finally {
setBusy(false)
}
}
return (
<div className="empty">
<form className="empty-card login-card" onSubmit={submit}>
<div className="brand login-brand">
<span className="brand-mark">§</span>
<strong>Contract Obligation &amp; Risk Extractor</strong>
</div>
<p className="muted">This workspace is password-protected. Contracts never leave this server.</p>
<input
type="text"
placeholder="Username"
autoComplete="username"
value={username}
autoFocus
onChange={(e) => setUsername(e.target.value)}
/>
<input
type="password"
placeholder="Password"
autoComplete="current-password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
{error && <div className="login-error">⚠ {error}</div>}
<button type="submit" className="upload-btn login-submit" disabled={busy || !username || !password}>
{busy ? 'Signing in…' : 'Sign in'}
</button>
</form>
</div>
)
}