HTML 77.2%
TypeScript 10.5%
Python 9.6%
JavaScript 2.5%
1'use client';2import { useActionState } from 'react';3import { loginAction } from '@/lib/admin/actions';45/** Login form: posts the token to a server action; the token only ever travels in this request body and the httpOnly cookie. */6export function LoginForm({ hint }: { hint?: string | null }) {7 const [state, action, pending] = useActionState(loginAction, { error: null });8 return (9 <form action={action} className="mt-6 max-w-sm space-y-3">10 <label className="block">11 <span className="eyebrow block pb-1">Admin token</span>12 <input type="password" name="token" required autoComplete="off" autoFocus spellCheck={false} className="h-11 w-full border border-rule-strong bg-surface px-3 text-[16px] text-ink focus:border-accent focus:outline-none" />13 </label>14 <button type="submit" disabled={pending} className="inline-flex h-11 w-full items-center justify-center bg-ink px-4 text-sm font-medium text-canvas hover:opacity-90 disabled:opacity-60">15 {pending ? 'Checking…' : 'Sign in'}16 </button>17 {state?.error && (18 <p role="alert" className="text-sm text-danger">19 {state.error}20 </p>21 )}22 {!state?.error && hint && <p className="text-xs text-ink-3">{hint}</p>}23 <p className="text-xs text-ink-3">The token is validated against the API and kept in an httpOnly cookie for 12 hours. It is never sent to the browser.</p>24 </form>25 );26}27