Fix migration connection exhaustion and polish auth pages
Deploy / release (push) Skipped
Deploy / deploy (push) Successful in 1m49s

- apply-migrations.ts: use single shared connection instead of one per operation
- Increase MariaDB max_connections from 151 to 300 in server config
- home-login-form.tsx: replace hardcoded gray colors with theme variables
- register-form.tsx: add password strength meter, spinner, theme-aligned inputs
- login-form.tsx: add Discord/Google SVG icons, spinner, smoother 2FA animation
- page/register/login: apply premium animations (float, stagger, glow, gradient)
This commit is contained in:
openhands committed 2026-07-24 11:30:58 +02:00
1 parent a9f1f4f99d
commit f7f6e09174
7 files changed
+394 -303

No files matched your search

+68 -25
View File
@@ -69,12 +69,13 @@ export function HomeLoginForm({
return (
<form
onSubmit={onSubmit}
className="relative flex flex-col gap-6 rounded-lg bg-gray-100 p-3 dark:bg-gray-800"
className="relative flex flex-col gap-4"
>
<fieldset className="flex w-full flex-col gap-1">
<div className="space-y-1">
<label
htmlFor="login-username"
className="block font-semibold text-gray-700 dark:text-gray-200"
className="block text-xs font-bold uppercase tracking-wider"
style={{ color: "var(--color-text-muted)" }}
>
Username
</label>
@@ -83,17 +84,26 @@ export function HomeLoginForm({
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
placeholder=""
className="focus:ring-0 relative z-10 w-full rounded border-4 border-gray-200 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-200"
style={{ borderColor: "#e5e7eb", borderWidth: "4px" }}
required
placeholder="Your username"
autoComplete="username"
disabled={needs2fa}
className="w-full rounded-xl border-2 px-4 py-3 text-sm font-medium transition-all focus:outline-none disabled:opacity-50"
style={{
backgroundColor: "var(--color-background)",
color: "var(--color-text-readable)",
borderColor: needs2fa
? "color-mix(in srgb, var(--color-text-muted) 15%, transparent)"
: "color-mix(in srgb, var(--color-text-muted) 25%, transparent)",
}}
required
/>
</fieldset>
<fieldset className="flex w-full flex-col gap-1">
</div>
<div className="space-y-1">
<label
htmlFor="login-password"
className="block font-semibold text-gray-700 dark:text-gray-200"
className="block text-xs font-bold uppercase tracking-wider"
style={{ color: "var(--color-text-muted)" }}
>
Password
</label>
@@ -102,18 +112,27 @@ export function HomeLoginForm({
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder=""
className="focus:ring-0 relative z-10 w-full rounded border-4 border-gray-200 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-200"
style={{ borderColor: "#e5e7eb", borderWidth: "4px" }}
required
placeholder="Your password"
autoComplete="current-password"
disabled={needs2fa}
className="w-full rounded-xl border-2 px-4 py-3 text-sm font-medium transition-all focus:outline-none disabled:opacity-50"
style={{
backgroundColor: "var(--color-background)",
color: "var(--color-text-readable)",
borderColor: needs2fa
? "color-mix(in srgb, var(--color-text-muted) 15%, transparent)"
: "color-mix(in srgb, var(--color-text-muted) 25%, transparent)",
}}
required
/>
</fieldset>
</div>
{needs2fa ? (
<fieldset className="flex w-full flex-col gap-1">
<div className="space-y-1 animate-scale-in">
<label
htmlFor="login-2fa"
className="block font-semibold text-gray-700 dark:text-gray-200"
className="block text-xs font-bold uppercase tracking-wider"
style={{ color: "var(--color-text-muted)" }}
>
2FA Code
</label>
@@ -124,28 +143,52 @@ export function HomeLoginForm({
onChange={(e) => setCode(e.target.value)}
placeholder="Enter your 2FA code"
inputMode="numeric"
className="focus:ring-0 relative z-10 w-full rounded border-4 border-gray-200 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-200"
style={{ borderColor: "#e5e7eb", borderWidth: "4px" }}
autoComplete="one-time-code"
autoFocus
className="w-full rounded-xl border-2 px-4 py-3 text-sm font-medium transition-all focus:outline-none"
style={{
backgroundColor: "var(--color-background)",
color: "var(--color-text-readable)",
borderColor: "color-mix(in srgb, var(--color-primary) 30%, transparent)",
}}
/>
</fieldset>
</div>
) : (
<CaptchaWidget captcha={captcha} nonce={nonce} />
)}
{error ? (
<p className="m-0 text-center text-sm text-red-600 dark:text-red-400">
<p
className="animate-fade-in-up m-0 text-center text-sm font-semibold"
style={{ color: "var(--color-danger)" }}
>
{error}
</p>
) : null}
<button
type="submit"
disabled={pending}
className="w-full cursor-pointer rounded-md border-2 p-2 text-base font-semibold text-white transition-colors disabled:opacity-50"
className="w-full cursor-pointer rounded-xl font-extrabold text-sm py-3.5 transition-all duration-200 hover:scale-[1.02] active:scale-95 shadow-lg disabled:opacity-60"
style={{
backgroundColor: "#27a44d",
borderColor: "#34d399",
background: "var(--color-primary)",
color: "var(--color-primary-foreground)",
boxShadow: "0 4px 20px color-mix(in srgb, var(--color-primary) 30%, transparent)",
}}
>
{pending ? "Please wait..." : needs2fa ? "Verify" : "Login"}
{pending ? (
<span className="inline-flex items-center gap-2">
<svg className="animate-spin h-4 w-4" viewBox="0 0 24 24" fill="none">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
</svg>
Please wait...
</span>
) : needs2fa ? (
"Verify"
) : (
"Login"
)}
</button>
</form>
);