feat: complete phase 2 UX improvements
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user