Skip to content
This repository has been archived by the owner on May 12, 2022. It is now read-only.

Commit

Permalink
Implemented final view for NativeAuth
Browse files Browse the repository at this point in the history
  • Loading branch information
dilan-dio4 committed Jun 4, 2021
1 parent ebf2c60 commit 1fb1174
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 10 deletions.
20 changes: 10 additions & 10 deletions src/ui/NativeAuth/NativeAuth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const { useEasybase } = require('easybase-react');

const DefaultSignIn = lazy(() => import('./pages/SignIn'));
const DefaultSignUp = lazy(() => import('./pages/SignUp'));
// const DefaultForgotPassword = lazy(() => import('./pages/ForgotPassword'));
const DefaultForgotPassword = lazy(() => import('./pages/ForgotPassword'));

export default function ({ customStyles, children, dictionary, signUpFields }: INativeAuth): JSX.Element {
const [currentPage, setCurrentPage] = useState<"SignIn" | "SignUp" | "ForgotPassword" | "ForgotPasswordConfirm">("SignIn");
Expand Down Expand Up @@ -56,15 +56,15 @@ export default function ({ customStyles, children, dictionary, signUpFields }: I
</Suspense>
)
case "ForgotPassword":
// return (
// <Suspense fallback={<Fragment />}>
// <DefaultForgotPassword
// setCurrentPage={setCurrentPage}
// dictionary={typeof dictionary === "object" ? { ...defaultDictionary, ...dictionary } : defaultDictionary}
// />
// </Suspense>
// )
return <React.Fragment />;
return (
<Suspense fallback={<Fragment />}>
<DefaultForgotPassword
setCurrentPage={setCurrentPage}
dictionary={typeof dictionary === "object" ? { ...defaultDictionary, ...dictionary } : defaultDictionary}
toast={toast}
/>
</Suspense>
)
default:
return <React.Fragment />;
}
Expand Down
174 changes: 174 additions & 0 deletions src/ui/NativeAuth/pages/ForgotPassword.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import React, { useState } from 'react';
import { useForm, Controller } from 'react-hook-form';
import { INativePage } from '../../uiTypes';
import { Form, HeaderText, View, Input, SpacerXL, SubmitButton, SpacerS, SecondaryButton, ErrorText, SecondaryText } from '../components';

const useEasybase = require('easybase-react');

export default function ({ setCurrentPage, dictionary, toast }: INativePage) {
const [onConfirm, setOnConfirm] = useState<boolean>(false);
const [forgottenUsername, setForgottenUsername] = useState<string | undefined>();
const { control, handleSubmit, reset, formState: { isSubmitting, errors } } = useForm();
const { forgotPassword, forgotPasswordConfirm } = useEasybase();

const onSubmit = async (formData: Record<string, string>) => {
if (!formData.email) {
return;
}

const forgotRes = await forgotPassword(formData.email, { greeting: "Hello user," });
if (forgotRes.success) {
setForgottenUsername(formData.email);
setOnConfirm(true);
toast('Check your email for a verification code')
} else {
if (forgotRes.errorCode === "RequestLimitExceeded") {
toast(dictionary.errorRequestLimitExceeded!);
} else if (forgotRes.errorCode === "BadFormat") {
reset();
toast(dictionary.errorBadInputFormat!);
} else if (forgotRes.errorCode === "NoUserExists") {
reset();
toast(dictionary.errorNoAccountFound!);
} else {
reset();
toast('Bad request');
}
}
}

const onConfirmSubmit = async (formData: Record<string, string>) => {
if (!formData.code || !formData.newPassword || !forgottenUsername) {
return;
}
const forgotConfirmRes = await forgotPasswordConfirm(formData.code, forgottenUsername, formData.newPassword)
if (forgotConfirmRes.success) {
setOnConfirm(false);
setForgottenUsername("");
setCurrentPage('SignIn');
toast('Password successfully changed')
} else {
if (forgotConfirmRes.errorCode === "BadPasswordLength") {
toast(dictionary.errorPasswordTooShort!);
} else if (forgotConfirmRes.errorCode === "BadFormat") {
reset();
toast(dictionary.errorBadInputFormat!);
} else if (forgotConfirmRes.errorCode === "NoUserExists") {
reset();
toast(dictionary.errorNoAccountFound!);
} else if (forgotConfirmRes.errorCode === "WrongVerificationCode") {
toast(dictionary.errorWrongVerificationCode!);
} else {
toast('Bad request');
}
}
}

const passwordReqs = {
minLength: {
value: 8,
message: "Password must be at least 8 characters long"
},
maxLength: {
value: 100,
message: "Password too long"
},
pattern: {
value: /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[a-zA-Z]).{7,}$/gm,
message: "Must contain a digit and uppercase and lowercase letters"
}
}

const codeReqs = {
minLength: {
value: 8,
message: "Incorrect code length"
}
}

if (!onConfirm) {
return (
<Form>
<View>
<HeaderText>{dictionary.forgotPasswordHeader}</HeaderText>
<SecondaryText>{dictionary.forgotPasswordSecondaryHeader}</SecondaryText>
</View>

<Controller
control={control}
render={({ field: { onChange, onBlur, value } }) => (
<Input
onBlur={onBlur}
onChangeText={value => onChange(value)}
value={value}
placeholder={dictionary.newEmailLabel}
editable={!isSubmitting}
keyboardType="email-address"
returnKeyType="default"
autoCompleteType="email"
autoCapitalize="none"
/>
)}
name="email"
defaultValue=""
/>

<View>
<SubmitButton onPress={handleSubmit(onSubmit)} disabled={isSubmitting} title={dictionary.forgotPasswordSubmitButton} />
<SpacerS />
<SecondaryButton onPress={(_: any) => setCurrentPage("SignIn")} disabled={isSubmitting} title={dictionary.backToSignIn} />
</View>
</Form>
)
} else {
return (
<Form>
<HeaderText>{dictionary.forgotPasswordConfirmHeader}</HeaderText>

<View>
<Controller
control={control}
render={({ field: { onChange, onBlur, value } }) => (
<Input
onBlur={onBlur}
onChangeText={value => onChange(value)}
value={value}
placeholder={dictionary.codeLabel}
editable={!isSubmitting}
returnKeyType="default"
autoCapitalize="characters"
/>
)}
name="code"
defaultValue=""
rules={codeReqs}
/>
<ErrorText value={errors.code?.message} />
<SpacerXL />
<Controller
control={control}
render={({ field: { onChange, onBlur, value } }) => (
<Input
onBlur={onBlur}
onChangeText={value => onChange(value)}
value={value}
placeholder={dictionary.forgotPasswordConfirmLabel}
editable={!isSubmitting}
returnKeyType="default"
secureTextEntry={true}
autoCompleteType="password"
autoCapitalize="none"
/>
)}
name="newPassword"
defaultValue=""
rules={passwordReqs}
/>
<ErrorText value={errors.newPassword?.message} />
</View>

<SubmitButton onPress={handleSubmit(onConfirmSubmit)} disabled={isSubmitting} title={dictionary.forgotPasswordConfirmSubmitButton} />
</Form>
)
}
}

0 comments on commit 1fb1174

Please sign in to comment.