diff --git a/src/App/routes/index.tsx b/src/App/routes/index.tsx
index de89600d..61d690ba 100644
--- a/src/App/routes/index.tsx
+++ b/src/App/routes/index.tsx
@@ -191,6 +191,19 @@ const login = customWrapRoute({
},
});
+const recoverAccount = customWrapRoute({
+ parent: rootLayout,
+ path: 'recover-account',
+ component: {
+ render: () => import('#views/RecoverAccount'),
+ props: {},
+ },
+ context: {
+ title: 'Recover Account',
+ visibility: 'is-not-authenticated',
+ },
+});
+
const wrappedRoutes = {
rootLayout,
homeLayout,
@@ -204,6 +217,7 @@ const wrappedRoutes = {
about,
pageNotFound,
login,
+ recoverAccount,
};
export const unwrappedRoutes = unwrapRoute(Object.values(wrappedRoutes));
diff --git a/src/views/Login/i18n.json b/src/views/Login/i18n.json
index 74132ad9..0e324515 100644
--- a/src/views/Login/i18n.json
+++ b/src/views/Login/i18n.json
@@ -1,7 +1,7 @@
{
"namespace": "login",
"strings": {
- "loginTitle":"IFRC GO - Login",
+ "loginTitle":"IFRC Alert-Hub - Login",
"loginHeader":"Login",
"loginSubHeader":"If you are staff, member or volunteer of the Red Cross Red Crescent Movement (National Societies, the IFRC and the ICRC) login with you email and password.",
"loginEmailUsername":"Email",
diff --git a/src/views/Login/index.tsx b/src/views/Login/index.tsx
index fd6f6727..3ac7edac 100644
--- a/src/views/Login/index.tsx
+++ b/src/views/Login/index.tsx
@@ -117,7 +117,7 @@ export function Component() {
diff --git a/src/views/RecoverAccount/i18n.json b/src/views/RecoverAccount/i18n.json
new file mode 100644
index 00000000..10fc1a6d
--- /dev/null
+++ b/src/views/RecoverAccount/i18n.json
@@ -0,0 +1,10 @@
+{
+ "namespace": "recoverAccount",
+ "strings": {
+ "pageTitle": "IFRC Alert-Hub - Recover Account",
+ "pageHeading": "Recover Account",
+ "pageDescription": "Enter the email/username you used during registration",
+ "emailInputLabel": "Email/Username",
+ "submitButtonLabel": "Submit recovery request"
+ }
+}
diff --git a/src/views/RecoverAccount/index.tsx b/src/views/RecoverAccount/index.tsx
new file mode 100644
index 00000000..af79b982
--- /dev/null
+++ b/src/views/RecoverAccount/index.tsx
@@ -0,0 +1,106 @@
+import { useMemo } from 'react';
+import {
+ Button,
+ TextInput,
+} from '@ifrc-go/ui';
+import { useTranslation } from '@ifrc-go/ui/hooks';
+import {
+ createSubmitHandler,
+ getErrorObject,
+ ObjectSchema,
+ requiredStringCondition,
+ useForm,
+} from '@togglecorp/toggle-form';
+
+import HCaptcha from '#components/Captcha';
+import Page from '#components/Page';
+
+import i18n from './i18n.json';
+import styles from './styles.module.css';
+
+interface FormFields {
+ email?: string;
+ captcha?: string;
+}
+
+const defaultFormValue: FormFields = {
+};
+
+type FormSchema = ObjectSchema
;
+type FormSchemaFields = ReturnType;
+
+const formSchema: FormSchema = {
+ fields: (): FormSchemaFields => ({
+ email: {
+ required: true,
+ requiredValidation: requiredStringCondition,
+ },
+ captcha: {
+ required: true,
+ requiredValidation: requiredStringCondition,
+ },
+ }),
+};
+
+// eslint-disable-next-line import/prefer-default-export
+export function Component() {
+ const strings = useTranslation(i18n);
+
+ const {
+ value: formValue,
+ error: formError,
+ setFieldValue,
+ setError,
+ validate,
+ } = useForm(formSchema, { value: defaultFormValue });
+
+ const handleFormSubmit = useMemo(
+ () => createSubmitHandler(
+ validate,
+ setError,
+ // FIXME: Add form submission logic here
+ () => {},
+ ),
+ [validate, setError],
+ );
+
+ const fieldError = getErrorObject(formError);
+
+ return (
+
+
+
+ );
+}
+Component.displayName = 'RecoverAccount';
diff --git a/src/views/RecoverAccount/styles.module.css b/src/views/RecoverAccount/styles.module.css
new file mode 100644
index 00000000..ed47a26b
--- /dev/null
+++ b/src/views/RecoverAccount/styles.module.css
@@ -0,0 +1,21 @@
+.recover-account {
+ .form {
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+ gap: var(--go-ui-spacing-lg);
+ margin: 0 auto;
+ max-width: var(--go-ui-width-content-max);
+
+ .submit-button {
+ align-self: center;
+ }
+
+ .actions {
+ display: flex;
+ flex-direction: column;
+ gap: var(--go-ui-spacing-lg);
+ align-items: center;
+ }
+ }
+}