feat: complete phase 2 UX improvements
CI and Deploy / test (push) Successful in 2m42s
CI and Deploy / deploy (push) Failing after 9s

This commit is contained in:
cesnimda
2026-07-30 21:35:52 +02:00
parent 173187dcbb
commit 56fed05d70
26 changed files with 1979 additions and 12283 deletions
+9 -8
View File
@@ -21,7 +21,7 @@ type AuthConfig = {
requireEmailVerification: boolean;
};
export default function LoginPage() {
export default function LoginPage({ initialMode = "login" }: { initialMode?: "login" | "register" }) {
const { toast } = useToast();
const { t } = useI18n();
const navigate = useNavigate();
@@ -40,7 +40,7 @@ export default function LoginPage() {
const [resendingVerification, setResendingVerification] = useState(false);
const [verificationResent, setVerificationResent] = useState(false);
const [fieldErrors, setFieldErrors] = useState<{ email?: string; password?: string; confirmPassword?: string }>({});
const [registerMode, setRegisterMode] = useState(false);
const [registerMode, setRegisterMode] = useState(initialMode === "register");
const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
@@ -132,7 +132,7 @@ export default function LoginPage() {
>
<Paper sx={{ width: "min(520px, 100%)", p: 4, borderRadius: 4, border: "none", boxShadow: "0px 1px 2px 0px rgba(15,23,42,0.04), 0px 8px 24px -12px rgba(15,23,42,0.12)" }}>
<Typography variant="h5" sx={{ fontWeight: 900, mb: 0.5 }}>
{t("signInTitle")}
{registerMode ? t("createAccount") : t("signInTitle")}
</Typography>
<Typography sx={{ color: "text.secondary", mb: 2 }}>
{cfg?.requireAuth ? t("authRequired") : t("authOptional")}
@@ -146,11 +146,11 @@ export default function LoginPage() {
/>
) : (
<>
<Tabs value={tab} onChange={(_, v) => setTab(v)} sx={{ mb: 2 }}>
{initialMode === "login" ? <Tabs value={tab} onChange={(_, v) => setTab(v)} sx={{ mb: 2 }}>
<Tab label={t("emailAndPassword")} />
<Tab label={t("google")} />
<Tab label={t("microsoft")} />
</Tabs>
</Tabs> : null}
{tab === 0 && (
<Box
@@ -158,6 +158,7 @@ export default function LoginPage() {
onSubmit={(e) => { e.preventDefault(); void submit(registerMode ? "register" : "login"); }}
sx={{ display: "flex", flexDirection: "column", gap: 1.5 }}
>
{registerMode && cfg && !allowReg ? <Alert severity="info">Registration is currently unavailable.</Alert> : null}
{cfg?.requireEmailVerification && emailNotVerified && (
<Alert
severity="warning"
@@ -230,20 +231,20 @@ export default function LoginPage() {
)}
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 1, mt: 1, flexWrap: "wrap" }}>
{allowReg && (
{(allowReg || initialMode === "register") && (
<Button
type="button"
variant="text"
size="small"
disableRipple
disabled={loading}
onClick={() => { setRegisterMode((v) => !v); setFieldErrors({}); }}
onClick={() => { if (initialMode === "register") navigate("/login"); else setRegisterMode((v) => !v); setFieldErrors({}); }}
sx={{ px: 0, minWidth: 0, fontWeight: 700 }}
>
{registerMode ? t("backToLogin") : t("createAccount")}
</Button>
)}
<Button type="submit" variant="contained" disableRipple disabled={loading} sx={{ ml: "auto" }}>
<Button type="submit" variant="contained" disableRipple disabled={loading || (registerMode && cfg !== null && !allowReg)} sx={{ ml: "auto" }}>
{registerMode ? t("createAccount") : t("signInTitle")}
</Button>
</Box>