forked from mosip/esignet-signup
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ES-559 - UI Forgot Password Landing Page (mosip#49)
* feat: implement forgot password landing page * fix: remove popover for fullname * fix: fix fullname in specific lng validation * fix: fix phone number validation * fix: fix username label * fix: fix generate challenge payload * fix: add continue loading state --------- Co-authored-by: Bunsy <[email protected]> Signed-off-by: Sreang Rathanak <[email protected]>
- Loading branch information
1 parent
26eda5e
commit 8c10d23
Showing
41 changed files
with
760 additions
and
90 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { Outlet } from "react-router-dom"; | ||
|
||
import Footer from "~components/ui/footer"; | ||
import NavBar from "~components/ui/nav-bar"; | ||
|
||
export const AppLayout = () => { | ||
return ( | ||
<div className="flex min-h-screen flex-col"> | ||
<NavBar /> | ||
<div className="relative flex flex-grow flex-col"> | ||
<Outlet /> | ||
<Footer /> | ||
</div> | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
interface PageLayoutProps { | ||
children: React.ReactNode; | ||
} | ||
|
||
export const PageLayout = ({ children }: PageLayoutProps) => { | ||
return ( | ||
<div className="relative flex flex-1 items-center justify-center"> | ||
<img | ||
className="absolute left-1 top-1" | ||
src="/images/top.png" | ||
alt="top left background" | ||
/> | ||
<div className="z-10 w-full">{children}</div> | ||
<img | ||
className="absolute bottom-1 right-1" | ||
src="/images/bottom.png" | ||
alt="bottom right background" | ||
/> | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const Otp = () => { | ||
return <div>Otp</div>; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { Otp as default } from "./Otp"; |
3 changes: 3 additions & 0 deletions
3
signup-ui/src/pages/ResetPasswordPage/ResetPassword/ResetPassword.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const ResetPassword = () => { | ||
return <div>ResetPassword</div>; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { ResetPassword as default } from "./ResetPassword"; |
3 changes: 3 additions & 0 deletions
3
...up-ui/src/pages/ResetPasswordPage/ResetPasswordConfirmation/ResetPasswordConfirmation.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const ResetPasswordConfirmation = () => { | ||
return <div>ResetPasswordConfirmation</div>; | ||
}; |
1 change: 1 addition & 0 deletions
1
signup-ui/src/pages/ResetPasswordPage/ResetPasswordConfirmation/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { ResetPasswordConfirmation as default } from "./ResetPasswordConfirmation"; |
143 changes: 143 additions & 0 deletions
143
signup-ui/src/pages/ResetPasswordPage/ResetPasswordPage.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
import { useCallback, useMemo } from "react"; | ||
import { yupResolver } from "@hookform/resolvers/yup"; | ||
import { Resolver, useForm } from "react-hook-form"; | ||
import { useTranslation } from "react-i18next"; | ||
import * as yup from "yup"; | ||
|
||
import { Form } from "~components/ui/form"; | ||
import { ResetPasswordForm, SettingsDto } from "~typings/types"; | ||
|
||
import Otp from "./Otp"; | ||
import ResetPassword from "./ResetPassword"; | ||
import ResetPasswordConfirmation from "./ResetPasswordConfirmation"; | ||
import { ResetPasswordPopover } from "./ResetPasswordPopover"; | ||
import ResetPasswordStatus from "./ResetPasswordStatus"; | ||
import { | ||
criticalErrorSelector, | ||
ResetPasswordStep, | ||
stepSelector, | ||
useResetPasswordStore, | ||
} from "./useResetPasswordStore"; | ||
import UserInfo from "./UserInfo"; | ||
|
||
interface ResetPasswordPageProps { | ||
settings: SettingsDto; | ||
} | ||
|
||
export const ResetPasswordPage = ({ settings }: ResetPasswordPageProps) => { | ||
const { t } = useTranslation(); | ||
|
||
const { step, criticalError } = useResetPasswordStore( | ||
useCallback( | ||
(state) => ({ | ||
step: stepSelector(state), | ||
criticalError: criticalErrorSelector(state), | ||
}), | ||
[] | ||
) | ||
); | ||
|
||
const validationSchema = useMemo( | ||
() => [ | ||
// Step 1 - UserInfo | ||
yup.object({ | ||
username: yup | ||
.string() | ||
.required(t("username_validation")) | ||
.matches(/^[^0].*$/, t("username_validation")) | ||
.matches( | ||
new RegExp(settings.response.configs["identifier.pattern"]), | ||
t("username_validation") | ||
), | ||
fullname: yup | ||
.string() | ||
.required(t("full_name_validation")) | ||
.matches( | ||
new RegExp(settings.response.configs["fullname.pattern"]), | ||
t("full_name_in_lng_validation") | ||
), | ||
captchaToken: yup.string().required(t("captcha_token_validation")), | ||
}), | ||
// Step 2 - Otp | ||
yup.object({ | ||
otp: yup | ||
.string() | ||
.matches( | ||
new RegExp(`^\\d{${settings.response.configs["otp.length"]}}$`) | ||
), | ||
}), | ||
// Step 3 - ResetPassword | ||
yup.object({ | ||
newPassword: yup | ||
.string() | ||
.required(t("password_validation")) | ||
.matches( | ||
new RegExp(settings.response.configs["password.pattern"]), | ||
t("password_validation") | ||
), | ||
confirmNewPassword: yup | ||
.string() | ||
.matches( | ||
new RegExp(settings.response.configs["password.pattern"]), | ||
t("password_validation") | ||
) | ||
.oneOf([yup.ref("password")], t("password_validation_must_match")), | ||
}), | ||
// Step 4 - ResetPasswordStatus | ||
yup.object({}), | ||
// Step 5 - ResetPasswordConfirmation | ||
yup.object({}), | ||
], | ||
[settings, t] | ||
); | ||
|
||
const currentValidationSchema = validationSchema[step]; | ||
|
||
const resetPasswordFormDefaultValues: ResetPasswordForm = { | ||
username: "", | ||
fullname: "", | ||
captchaToken: "", | ||
otp: "", | ||
newPassword: "", | ||
confirmNewPassword: "", | ||
}; | ||
|
||
const methods = useForm<ResetPasswordForm>({ | ||
shouldUnregister: false, | ||
defaultValues: resetPasswordFormDefaultValues, | ||
resolver: yupResolver(currentValidationSchema) as unknown as Resolver< | ||
ResetPasswordForm, | ||
any | ||
>, | ||
mode: "onBlur", | ||
}); | ||
|
||
const getResetPasswordContent = (step: ResetPasswordStep) => { | ||
switch (step) { | ||
case ResetPasswordStep.UserInfo: | ||
return <UserInfo methods={methods} settings={settings} />; | ||
case ResetPasswordStep.Otp: | ||
return <Otp />; | ||
case ResetPasswordStep.ResetPassword: | ||
return <ResetPassword />; | ||
case ResetPasswordStep.ResetPasswordStatus: | ||
return <ResetPasswordStatus />; | ||
case ResetPasswordStep.ResetPasswordConfirmation: | ||
return <ResetPasswordConfirmation />; | ||
default: | ||
return "unknown step"; | ||
} | ||
}; | ||
|
||
return ( | ||
<> | ||
{criticalError && | ||
["invalid_transaction"].includes(criticalError.errorCode) && ( | ||
<ResetPasswordPopover /> | ||
)} | ||
<Form {...methods}> | ||
<form>{getResetPasswordContent(step)}</form> | ||
</Form> | ||
</> | ||
); | ||
}; |
29 changes: 29 additions & 0 deletions
29
signup-ui/src/pages/ResetPasswordPage/ResetPasswordPageContainer.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { PageLayout } from "~layouts/PageLayout"; | ||
|
||
import { Icons } from "~components/ui/icons"; | ||
import { Step, StepContent } from "~components/ui/step"; | ||
import { useSettings } from "~pages/shared/queries"; | ||
|
||
import { ResetPasswordPage } from "./ResetPasswordPage"; | ||
|
||
export const ResetPasswordPageContainer = () => { | ||
const { data: settings, isLoading } = useSettings(); | ||
|
||
if (isLoading || !settings) { | ||
return ( | ||
<PageLayout> | ||
<Step> | ||
<StepContent className="flex h-40 items-center justify-center"> | ||
<Icons.loader className="animate-spin text-primary" /> | ||
</StepContent> | ||
</Step> | ||
</PageLayout> | ||
); | ||
} | ||
|
||
return ( | ||
<PageLayout> | ||
<ResetPasswordPage settings={settings} /> | ||
</PageLayout> | ||
); | ||
}; |
Oops, something went wrong.