Commit ed8c6b3c by asranov0003

feat: add recover password page

parent e599a481
import React from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import {
useAppDispatch,
useAppSelector,
type RootState,
} from "../../stores/store";
import { useForm } from "react-hook-form";
import { authRecover } from "../../stores/slices/authSlice";
import AuthHeader from "../Auth/AuthHeader";
import CInput from "../../components/CInput";
import CButton from "../../components/CButton";
interface IRecoverFormData {
login: string;
newPassword: string;
repeatPassword: string;
}
const RecoverPasswor: React.FC = () => {
const { t } = useTranslation();
const navigate = useNavigate();
const dispatch = useAppDispatch();
const { loadingRecover, errorRecover, successRecover } = useAppSelector(
(state: RootState) => state.auth
);
const {
register,
handleSubmit,
formState: { errors },
watch,
} = useForm<IRecoverFormData>();
const newPasswordValue = watch("newPassword");
const onSubmit = async (data: IRecoverFormData) => {
dispatch(authRecover(data));
};
return (
<div className="wrapper recover">
<AuthHeader back onBack={() => navigate("/settings")} />
<h2>{t("auth.passwordRecovery")}</h2>
<form className="auth__form" onSubmit={handleSubmit(onSubmit)}>
<CInput
label={`${t("auth.login")}`}
placeholder={`${t("auth.loginPlaceholder")}`}
{...register("login", { required: t("error.requiredField") })}
error={errors.login?.message as string}
/>
<CInput
label={`${t("auth.newPassword")}`}
placeholder={`${t("auth.newPasswordPlaceholder")}`}
type="password"
{...register("newPassword", { required: t("error.requiredField") })}
error={errors.newPassword?.message as string}
/>
<CInput
label={`${t("auth.repeatPassword")}`}
placeholder={`${t("auth.repeatPasswordPlaceholder")}`}
type="password"
{...register("repeatPassword", {
required: t("error.requiredField"),
validate: (value) =>
value === newPasswordValue || t("auth.passwordsDoNotMatch"),
})}
error={errors.repeatPassword?.message as string}
/>
{successRecover && (
<p className="text-success text-center">{successRecover}</p>
)}
{errorRecover && (
<p className="text-danger text-center">{errorRecover}</p>
)}
<CButton title={`${t("button.continue")}`} isLoading={loadingRecover} />
</form>
</div>
);
};
export default RecoverPasswor;
export { default } from "./RecoverPassword";
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.5rem; gap: 0.5rem;
text-decoration: none;
color: var(--text-color);
cursor: pointer; cursor: pointer;
} }
......
...@@ -12,6 +12,7 @@ import { useAppDispatch } from "../../stores/store"; ...@@ -12,6 +12,7 @@ import { useAppDispatch } from "../../stores/store";
import { logout } from "../../stores/slices/authSlice"; import { logout } from "../../stores/slices/authSlice";
import CModal from "../../components/CModal"; import CModal from "../../components/CModal";
import CButton from "../../components/CButton"; import CButton from "../../components/CButton";
import { Link } from "react-router-dom";
const Settings: React.FC = () => { const Settings: React.FC = () => {
const [isOpenLogoutModal, setIsOpenLogoutModal] = useState(false); const [isOpenLogoutModal, setIsOpenLogoutModal] = useState(false);
...@@ -64,10 +65,13 @@ const Settings: React.FC = () => { ...@@ -64,10 +65,13 @@ const Settings: React.FC = () => {
{t("settings.deleteAccount")} {t("settings.deleteAccount")}
</div> </div>
<div className="settings__content__action"> <Link
to={"/settings/recover-password"}
className="settings__content__action"
>
<IoKeyOutline className="settings__content__action__icon" />{" "} <IoKeyOutline className="settings__content__action__icon" />{" "}
{t("settings.recoverPassword")} {t("settings.recoverPassword")}
</div> </Link>
<div className="settings__content__action" onClick={toggleLogoutModal}> <div className="settings__content__action" onClick={toggleLogoutModal}>
<MdOutlineLogout className="settings__content__action__icon" />{" "} <MdOutlineLogout className="settings__content__action__icon" />{" "}
......
...@@ -28,6 +28,7 @@ import BlockApps from "../pages/BlockApps"; ...@@ -28,6 +28,7 @@ import BlockApps from "../pages/BlockApps";
import UsageLimits from "../pages/UsageLimits"; import UsageLimits from "../pages/UsageLimits";
import Terms from "../pages/Auth/Terms"; import Terms from "../pages/Auth/Terms";
import Privacy from "../pages/Auth/Privacy"; import Privacy from "../pages/Auth/Privacy";
import RecoverPassword from "../pages/RecoverPassword";
const Router: React.FC = () => { const Router: React.FC = () => {
const isAuthenticated = !!localStorage.getItem(`token-${TG_USER_ID}`); const isAuthenticated = !!localStorage.getItem(`token-${TG_USER_ID}`);
...@@ -129,6 +130,16 @@ const Router: React.FC = () => { ...@@ -129,6 +130,16 @@ const Router: React.FC = () => {
], ],
}, },
{ {
path: "/settings",
element: <ProtectedRoute element={<Outlet />} redirectTo="/" />,
children: [
{
path: "recover-password",
element: <RecoverPassword />,
},
],
},
{
path: "/pincode", path: "/pincode",
element: <Pincode />, element: <Pincode />,
}, },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment