Skip to content

Commit

Permalink
Merge pull request #346 from COS301-SE-2024/feat/mobile/forgot-password
Browse files Browse the repository at this point in the history
Feat/mobile/forgot password
  • Loading branch information
KamogeloMoeketse authored Aug 27, 2024
2 parents 078e458 + 5c0b9bd commit 2f3fdbf
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 49 deletions.
19 changes: 8 additions & 11 deletions frontend/occupi-mobile4/screens/Login/CreatePassword.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import GuestLayout from '../../layouts/GuestLayout';
import { router } from 'expo-router';
import { styled } from '@gluestack-style/react';
import StyledExpoRouterLink from '../../components/StyledExpoRouterLink';
import { userResetPassword } from '@/utils/auth';

const StyledImage = styled(Image, {
props: {
Expand Down Expand Up @@ -86,26 +87,22 @@ export default function CreatePassword() {

const toast = useToast();

const onSubmit = (data: CreatePasswordSchemaType) => {
const onSubmit = async (data: CreatePasswordSchemaType) => {
if (data.password === data.confirmpassword) {
const response = await userResetPassword(data.password, data.confirmpassword);
toast.show({
placement: 'bottom right',
placement: 'top',
render: ({ id }) => {
return (
<Toast nativeID={id} variant="accent" action="success">
<ToastTitle>Password updated successfully</ToastTitle>
<ToastTitle>{response === "Successful login!" ? "Password updated successfully!" : response}</ToastTitle>
</Toast>
);
},
});

// Navigate screen to appropriate location
router.replace('/');

reset();
} else {
toast.show({
placement: 'bottom right',
placement: 'top',
render: ({ id }) => {
return (
<Toast nativeID={id} variant="accent" action="error">
Expand Down Expand Up @@ -288,7 +285,7 @@ export default function CreatePassword() {
},
}}
render={({ field: { onChange, onBlur, value } }) => (
<Input borderRadius="$full" backgroundColor="#f2f2f2">
<Input backgroundColor="#F3F3F3" borderColor="#F3F3F3" borderRadius="$xl" h={hp('6%')}>
<InputField
fontSize={wp('4%')}
placeholder="Password"
Expand Down Expand Up @@ -348,7 +345,7 @@ export default function CreatePassword() {
},
}}
render={({ field: { onChange, onBlur, value } }) => (
<Input borderRadius="$full" backgroundColor="#f2f2f2">
<Input backgroundColor="#F3F3F3" borderColor="#F3F3F3" borderRadius="$xl" h={hp('6%')}>
<InputField
fontSize={wp('4%')}
placeholder="Confirm Password"
Expand Down
22 changes: 12 additions & 10 deletions frontend/occupi-mobile4/screens/Login/ForgotPassword.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-nat
import { AlertTriangle } from 'lucide-react-native';
import StyledExpoRouterLink from '../../components/StyledExpoRouterLink';
import { useNavigation } from '@react-navigation/native';
import { userForgotPassword } from '@/utils/auth';

const forgotPasswordSchema = z.object({
email: z.string().min(1, 'Email is required').email(),
Expand All @@ -52,23 +53,24 @@ export default function ForgotPassword() {
});

const toast = useToast();
const navigation = useNavigation();

const onSubmit = (data: SignUpSchemaType) => {
toast.show({
placement: 'bottom right',
const onSubmit = async (data: SignUpSchemaType) => {
const response = await userForgotPassword(data.email);
console.log(response);
if (response === "Invalid email") {
toast.show({
placement: 'top',
render: ({ id }) => {
return (
<Toast nativeID={id} variant="accent" action="success">
<ToastTitle>OTP sent successfully </ToastTitle>
<Toast nativeID={id} variant="accent" action="warning">
<ToastTitle>This email does not have an account.</ToastTitle>
</Toast>
);
},
});
reset();

}
// Navigate to OTP Verification screen with email as a parameter
navigation.navigate('verify-otp', { email: data.email });
};

const handleKeyPress = () => {
Expand Down Expand Up @@ -232,7 +234,7 @@ export default function ForgotPassword() {
</FormControl>

<GradientButton
onPress={handleSubmit(onSubmit)}
onPress={handleSubmit(onSubmit())}
text="Send OTP"
/>
</View>
Expand Down
15 changes: 14 additions & 1 deletion frontend/occupi-mobile4/screens/Login/OtpVerification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Logo from '../../screens/Login/assets/images/Occupi/Occupi-gradient.png';
import StyledExpoRouterLink from '@/components/StyledExpoRouterLink';
import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen';
import { LinearGradient } from 'expo-linear-gradient';
import { VerifyUserOtpLogin, verifyUserOtpRegister } from '@/utils/auth';
import { verifyUserOtp, VerifyUserOtpLogin, verifyUserOtpRegister } from '@/utils/auth';

const OTPSchema = z.object({
OTP: z.string().min(6, 'OTP must be at least 6 characters in length'),
Expand Down Expand Up @@ -80,6 +80,19 @@ const OTPVerification = () => {
}
});
}
else if (state === 'reset_password') {
const response = await verifyUserOtp(email, pin);
toast.show({
placement: 'top',
render: ({ id }) => {
return (
<Toast nativeID={String(id)} variant="accent" action={response === 'OTP verified successfully!' ? 'success' : 'error'}>
<ToastTitle>{response}</ToastTitle>
</Toast>
);
}
});
}
else {
const response = await VerifyUserOtpLogin(email, pin);
toast.show({
Expand Down
2 changes: 0 additions & 2 deletions frontend/occupi-mobile4/screens/Login/SignIn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@ const SignInForm = () => {

const toast = useToast();



useEffect(() => {
checkBiometricAvailability();

Expand Down
3 changes: 1 addition & 2 deletions frontend/occupi-mobile4/screens/Login/SplashScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,7 @@ export default function SplashScreen() {
useEffect(() => {
const timer = setTimeout(() => {
setSelectedIndex(1); // Assuming Onboarding1 is at index 1

router.replace('/home'); // Navigate to Onboarding1 screen
router.replace('/login'); // Navigate to Onboarding1 screen
}, 5000); // 8 seconds

return () => clearTimeout(timer); // Clean up timer on component unmount
Expand Down
74 changes: 68 additions & 6 deletions frontend/occupi-mobile4/services/authservices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export async function verifyOtpRegister(req: VerifyOTPReq): Promise<LoginSuccess
}

export async function verifyOtplogin(req: VerifyOTPReq): Promise<LoginSuccess | Unsuccessful> {
console.log(req);
try {
const response = await axios.post("https://dev.occupi.tech/auth/verify-otp-mobile-login", req, {
headers: {
Expand All @@ -94,6 +95,72 @@ export async function verifyOtplogin(req: VerifyOTPReq): Promise<LoginSuccess |
}
}

export async function verifyOtp(req: VerifyOTPReq): Promise<LoginSuccess | Unsuccessful> {
console.log(req);
try {
const response = await axios.post("https://dev.occupi.tech/auth/verify-otp", req, {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
withCredentials: true
});
// console.log(response.data);
return response.data as LoginSuccess;
} catch (error) {
if (axios.isAxiosError(error) && error.response) {
// console.log(error.response.data);
return error.response.data as Unsuccessful;
} else {
throw error;
}
}
}

export async function forgotPassword(req: any): Promise<Success | Unsuccessful> {
try {
const response = await axios.post("https://dev.occupi.tech/auth/forgot-password", req, {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
withCredentials: true
});
console.log(response.data);
return response.data as Success;
} catch (error) {
if (axios.isAxiosError(error) && error.response) {
// console.log(error.response.data);
return error.response.data as Unsuccessful;
} else {
throw error;
}
}
}

export async function resetPassword(req: any): Promise<LoginSuccess | Unsuccessful> {
try {
const response = await axios.post("https://dev.occupi.tech/auth/reset-password-mobile-login", req, {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
withCredentials: true
});
console.log(response.data);
return response.data as Success;
} catch (error) {
if (axios.isAxiosError(error) && error.response) {
// console.log(error.response.data);
return error.response.data as Unsuccessful;
} else {
throw error;
}
}
}



export async function logout(): Promise<Success | Unsuccessful> {
let authToken = await SecureStore.getItemAsync('Token');
// console.log('token',authToken);
Expand All @@ -116,9 +183,4 @@ export async function logout(): Promise<Success | Unsuccessful> {
throw error;
}
}
}

// login({
// email: "boygenius31115@gmail.com",
// password: "Qwert@123"
// })
}
4 changes: 4 additions & 0 deletions frontend/occupi-mobile4/services/securestore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ export async function storeCheckInValue(value: boolean) {
await SecureStore.setItemAsync('CheckedIn', value.toString());
}

export async function storeOtp(value: string) {
await SecureStore.setItemAsync('Otp',value);
}

export async function getUserData() {
let result: string | null = await SecureStore.getItemAsync('UserData');
return result ? JSON.parse(result) : null;
Expand Down
Loading

0 comments on commit 2f3fdbf

Please sign in to comment.