hyapp-admin-platform/external-admin/src/pages/ChangePasswordPage.jsx

87 lines
4.1 KiB
JavaScript

import Alert from "@mui/material/Alert";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Card from "@mui/material/Card";
import CardContent from "@mui/material/CardContent";
import Stack from "@mui/material/Stack";
import TextField from "@mui/material/TextField";
import Typography from "@mui/material/Typography";
import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { AppIdentity } from "@/shared/ui/AppIdentity.jsx";
import { useExternalAuth } from "../auth/ExternalAuthProvider.jsx";
import { useExternalI18n } from "../i18n/ExternalI18nProvider.jsx";
import { LanguageSwitcher } from "../i18n/LanguageSwitcher.jsx";
import { translateExternalError } from "../i18n/errors.js";
import { useExternalSessionBrand } from "../shared/useExternalSessionBrand.js";
export default function ChangePasswordPage() {
const { changePassword, logout, session } = useExternalAuth();
const { t } = useExternalI18n();
const [form, setForm] = useState({ confirmPassword: "", newPassword: "", oldPassword: "" });
const [error, setError] = useState("");
const [submitting, setSubmitting] = useState(false);
const navigate = useNavigate();
useExternalSessionBrand(session, t("app.title"));
const submit = async (event) => {
event.preventDefault();
if (!form.newPassword.trim()) {
setError(t("auth.passwordWhitespace"));
return;
}
if (form.newPassword.length < 8) {
setError(t("auth.passwordMinError"));
return;
}
if (form.newPassword !== form.confirmPassword) {
setError(t("auth.passwordMismatch"));
return;
}
setSubmitting(true);
setError("");
try {
await changePassword({ newPassword: form.newPassword, oldPassword: form.oldPassword });
navigate("/overview", { replace: true });
} catch (requestError) {
setError(translateExternalError(requestError, t, "auth.passwordChangedFailed"));
} finally {
setSubmitting(false);
}
};
const cancel = async () => {
await logout();
navigate("/login", { replace: true });
};
return (
<Box className="external-login-page">
<Card className="external-login-card" elevation={0}>
<CardContent>
<Stack sx={{ alignItems: "flex-end" }}><LanguageSwitcher /></Stack>
<Stack spacing={1.5} sx={{ alignItems: "center" }}>
<AppIdentity
appCode={session?.appCode}
appName={session?.appName || session?.appCode}
className="external-change-password-brand"
logoUrl={session?.logoUrl}
showLogoFallback={false}
size="large"
/>
<Typography component="h1" variant="h5">{t("auth.changePassword")}</Typography>
<Typography color="text.secondary">{session?.passwordChangeRequired ? t("auth.firstLoginChange") : session?.account}</Typography>
</Stack>
<Stack component="form" spacing={2} onSubmit={submit}>
{error ? <Alert severity="error">{error}</Alert> : null}
<TextField autoComplete="current-password" disabled={submitting} label={t("auth.currentPassword")} required type="password" value={form.oldPassword} onChange={(event) => setForm({ ...form, oldPassword: event.target.value })} />
<TextField autoComplete="new-password" disabled={submitting} helperText={t("auth.passwordMin")} label={t("auth.newPassword")} required type="password" value={form.newPassword} onChange={(event) => setForm({ ...form, newPassword: event.target.value })} />
<TextField autoComplete="new-password" disabled={submitting} label={t("auth.confirmNewPassword")} required type="password" value={form.confirmPassword} onChange={(event) => setForm({ ...form, confirmPassword: event.target.value })} />
<Stack direction="row" spacing={1}><Button disabled={submitting} fullWidth onClick={cancel} variant="outlined">{t("auth.logout")}</Button><Button disabled={submitting} fullWidth type="submit" variant="contained">{t("auth.savePassword")}</Button></Stack>
</Stack>
</CardContent>
</Card>
</Box>
);
}