Files
Stirling-PDF/frontend/shared/auth/ui/EmailPasswordForm.tsx
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

149 lines
4.2 KiB
TypeScript
Raw Normal View History

import { useTranslation } from "react-i18next";
2026-06-22 17:22:36 +01:00
import "@shared/auth/ui/auth.css";
import { TextInput, PasswordInput, Button } from "@mantine/core";
2025-10-24 10:49:52 +01:00
2026-01-09 10:30:34 +00:00
// Force light mode styles for auth inputs
const authInputStyles = {
input: {
backgroundColor: "var(--auth-input-bg-light-only)",
color: "var(--auth-input-text-light-only)",
borderColor: "var(--auth-input-border-light-only)",
"&:focus": {
borderColor: "var(--auth-border-focus-light-only)",
2026-01-09 10:30:34 +00:00
},
},
label: {
color: "var(--auth-label-text-light-only)",
2026-01-09 10:30:34 +00:00
},
};
2025-10-24 10:49:52 +01:00
interface EmailPasswordFormProps {
email: string;
password: string;
setEmail: (email: string) => void;
setPassword: (password: string) => void;
mfaCode?: string;
setMfaCode?: (code: string) => void;
showMfaField?: boolean;
requiresMfa?: boolean;
onSubmit: () => void;
isSubmitting: boolean;
submitButtonText: string;
showPasswordField?: boolean;
2025-10-24 10:49:52 +01:00
fieldErrors?: {
email?: string;
password?: string;
mfaCode?: string;
};
2025-10-24 10:49:52 +01:00
}
export default function EmailPasswordForm({
email,
password,
setEmail,
setPassword,
mfaCode = "",
setMfaCode,
showMfaField = false,
requiresMfa = false,
2025-10-24 10:49:52 +01:00
onSubmit,
isSubmitting,
submitButtonText,
showPasswordField = true,
fieldErrors = {},
2025-10-24 10:49:52 +01:00
}: EmailPasswordFormProps) {
const { t } = useTranslation();
2025-10-24 10:49:52 +01:00
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
onSubmit();
};
2025-10-24 10:49:52 +01:00
return (
<form onSubmit={handleSubmit}>
<div className="auth-fields">
<div className="auth-field">
<TextInput
2025-10-24 10:49:52 +01:00
id="email"
label={t("login.username", "Username")}
2025-10-24 10:49:52 +01:00
type="text"
name="username"
autoComplete="username"
placeholder={t("login.enterUsername", "Enter username")}
2025-10-24 10:49:52 +01:00
value={email}
onChange={(e) => setEmail(e.target.value)}
error={fieldErrors.email}
classNames={{ label: "auth-label" }}
2026-01-09 10:30:34 +00:00
styles={authInputStyles}
autoFocus
2025-10-24 10:49:52 +01:00
/>
</div>
{showPasswordField && (
<div className="auth-field">
<PasswordInput
2025-10-24 10:49:52 +01:00
id="password"
2026-06-22 17:22:36 +01:00
label={t("login.password", "Password")}
2025-10-24 10:49:52 +01:00
name="current-password"
autoComplete="current-password"
2026-06-22 17:22:36 +01:00
placeholder={t("login.enterPassword", "Enter your password")}
2025-10-24 10:49:52 +01:00
value={password}
onChange={(e) => setPassword(e.target.value)}
error={fieldErrors.password}
classNames={{ label: "auth-label" }}
2026-01-09 10:30:34 +00:00
styles={authInputStyles}
2025-10-24 10:49:52 +01:00
/>
</div>
)}
{showMfaField && (
<div className="auth-field">
<TextInput
id="mfaCode"
2026-06-22 17:22:36 +01:00
label={t("login.mfaCode", "Authentication Code")}
type="text"
name="mfaCode"
autoComplete="one-time-code"
placeholder={t("login.enterMfaCode", "Enter 6-digit code")}
value={mfaCode}
inputMode="numeric"
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setMfaCode?.(e.target.value.replace(/\D/g, "").slice(0, 6))
}
pattern="[0-9]*"
maxLength={6}
minLength={6}
error={fieldErrors.mfaCode}
classNames={{ label: "auth-label" }}
styles={authInputStyles}
/>
</div>
)}
2025-10-24 10:49:52 +01:00
</div>
<Button
2025-10-24 10:49:52 +01:00
type="submit"
2026-04-17 10:50:16 +01:00
disabled={
isSubmitting ||
!email ||
(showPasswordField && !password) ||
(requiresMfa && !mfaCode.trim())
}
2025-10-24 10:49:52 +01:00
className="auth-button"
fullWidth
loading={isSubmitting}
2026-06-22 17:22:36 +01:00
styles={{
// Own the brand colour inline so the host app's Mantine primaryColor
// can't win over .auth-button (editor vs portal Mantine themes
// differ). The fallback keeps it red even if auth-theme.css is absent.
root: {
backgroundColor: "var(--auth-button-bg-light-only, #af3434)",
color: "var(--auth-button-text-light-only, #ffffff)",
},
}}
2025-10-24 10:49:52 +01:00
>
{submitButtonText}
</Button>
2025-10-24 10:49:52 +01:00
</form>
);
2025-10-24 10:49:52 +01:00
}