From d5c0d4fcc5cda672bc8631db40f9f0eb905553d8 Mon Sep 17 00:00:00 2001 From: Anh Le Date: Tue, 8 Aug 2023 11:32:26 +0700 Subject: [PATCH 1/4] feat: changePassword, resetPassword, forgotPassword apis --- .../rn-api/src/models/user/PasswordModel.js | 12 +++ packages/rn-api/src/navigation/RouteKey.js | 3 + .../rn-api/src/navigation/ScreenService.js | 14 ++- .../rn-api/src/navigation/StackNavigation.js | 15 +++ .../AuthComponent/ChangePasswordScreen.js | 97 ++++++++++++++++++ .../AuthComponent/ForgotPasswordScreen.js | 67 +++++++++++++ .../src/screens/AuthComponent/LoginScreen.js | 98 ++++++++++++++++++- .../AuthComponent/ResetPasswordScreen.js | 94 ++++++++++++++++++ .../rn-api/src/screens/AuthComponent/index.js | 3 + packages/rn-api/src/services/api/api.js | 22 +++++ packages/rn-api/src/store/constants/user.js | 19 ++++ packages/rn-api/src/store/reducers/user.js | 22 +++++ packages/rn-api/src/store/saga/user.js | 52 ++++++++++ 13 files changed, 514 insertions(+), 4 deletions(-) create mode 100644 packages/rn-api/src/models/user/PasswordModel.js create mode 100644 packages/rn-api/src/screens/AuthComponent/ChangePasswordScreen.js create mode 100644 packages/rn-api/src/screens/AuthComponent/ForgotPasswordScreen.js create mode 100644 packages/rn-api/src/screens/AuthComponent/ResetPasswordScreen.js create mode 100644 packages/rn-api/src/store/constants/user.js diff --git a/packages/rn-api/src/models/user/PasswordModel.js b/packages/rn-api/src/models/user/PasswordModel.js new file mode 100644 index 0000000..c8d400e --- /dev/null +++ b/packages/rn-api/src/models/user/PasswordModel.js @@ -0,0 +1,12 @@ +export default class PasswordModel { + constructor(data) { + this.data = data + } + + static parseFromJson = payload => { + const obj = new PasswordModel() + const {data} = payload + obj.data = data + return obj + } +} diff --git a/packages/rn-api/src/navigation/RouteKey.js b/packages/rn-api/src/navigation/RouteKey.js index 88f37de..17a5471 100644 --- a/packages/rn-api/src/navigation/RouteKey.js +++ b/packages/rn-api/src/navigation/RouteKey.js @@ -4,6 +4,9 @@ export default { LoginScreen: 'LoginScreen', SignUpScreen: 'SignUpScreen', HomeScreen: 'HomeScreen', + ForgotPasswordScreen: 'ForgotPasswordScreen', + ResetPasswordScreen: 'ResetPasswordScreen', + ChangePasswordScreen: 'ChangePasswordScreen', /** Stack */ AuthStack: 'AuthStack', diff --git a/packages/rn-api/src/navigation/ScreenService.js b/packages/rn-api/src/navigation/ScreenService.js index f3a2bbc..b39775b 100644 --- a/packages/rn-api/src/navigation/ScreenService.js +++ b/packages/rn-api/src/navigation/ScreenService.js @@ -1,5 +1,11 @@ import RouteKey from './RouteKey' -import {SignUpScreen, LoginScreen} from '../screens' +import { + SignUpScreen, + LoginScreen, + ForgotPasswordScreen, + ResetPasswordScreen, + ChangePasswordScreen, +} from '../screens' // Screen Import import HomeScreen from '../screens/HomeComponent/HomeScreen' import {colors} from '../themes' @@ -13,6 +19,12 @@ export const screenMatch = screen => { return SignUpScreen case RouteKey.HomeScreen: return HomeScreen + case RouteKey.ForgotPasswordScreen: + return ForgotPasswordScreen + case RouteKey.ResetPasswordScreen: + return ResetPasswordScreen + case RouteKey.ChangePasswordScreen: + return ChangePasswordScreen default: return '' } diff --git a/packages/rn-api/src/navigation/StackNavigation.js b/packages/rn-api/src/navigation/StackNavigation.js index f769ce9..4cfcfc1 100644 --- a/packages/rn-api/src/navigation/StackNavigation.js +++ b/packages/rn-api/src/navigation/StackNavigation.js @@ -36,6 +36,21 @@ export const AuthNavigator = () => ( component={screenMatch(RouteKey.SignUpScreen)} options={optionsMatch} /> + + + ) diff --git a/packages/rn-api/src/screens/AuthComponent/ChangePasswordScreen.js b/packages/rn-api/src/screens/AuthComponent/ChangePasswordScreen.js new file mode 100644 index 0000000..f32ce4e --- /dev/null +++ b/packages/rn-api/src/screens/AuthComponent/ChangePasswordScreen.js @@ -0,0 +1,97 @@ +import React, {useCallback, useReducer} from 'react' +import {ScreenContainer} from '../../components/ScreenContainer' +import {Text, StyleSheet, View, TouchableOpacity} from 'react-native' +import PasswordInput from '../../components/InputPassword' +import {responsiveHeight} from '../../themes/metrics' +import {colors} from '../../themes' +import {useDispatch} from 'react-redux' +import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view' +import {userActions} from '../../store/reducers' + +export const ChangePasswordScreen = () => { + const dispatch = useDispatch() + const [inputValue, setInputValue] = useReducer((prev, next) => ({...prev, ...next}), { + newPassword: '', + confirmPassword: '', + oldPassword: '', + }) + + const onSaveChangePassword = useCallback(() => { + dispatch( + userActions.changePasswordHandle({ + newPassword: inputValue.newPassword, + confirmPassword: inputValue.confirmPassword, + oldPassword: inputValue.oldPassword, + }), + ) + }, [inputValue, dispatch]) + + const onChangeNewPass = useCallback(text => { + setInputValue({newPassword: text}) + }, []) + + const onChangePassword = useCallback(text => { + setInputValue({confirmPassword: text}) + }, []) + + const onChangeOldPassword = useCallback(text => { + setInputValue({oldPassword: text}) + }, []) + + return ( + + + Change Password + + + + + + + + + SAVE + + + + ) +} + +const styles = StyleSheet.create({ + container: { + padding: responsiveHeight(10), + alignItems: 'center', + }, + titleText: { + fontSize: responsiveHeight(25), + fontWeight: '600', + marginVertical: responsiveHeight(20), + }, + passwordSection: { + marginTop: responsiveHeight(10), + }, + button: { + backgroundColor: colors.primary, + width: '100%', + height: responsiveHeight(40), + marginTop: responsiveHeight(10), + alignItems: 'center', + justifyContent: 'center', + borderRadius: 10, + }, + forgotPassword: { + fontSize: responsiveHeight(18), + marginVertical: responsiveHeight(10), + alignSelf: 'flex-end', + color: colors.primary, + textDecorationLine: 'underline', + }, +}) diff --git a/packages/rn-api/src/screens/AuthComponent/ForgotPasswordScreen.js b/packages/rn-api/src/screens/AuthComponent/ForgotPasswordScreen.js new file mode 100644 index 0000000..65ecb13 --- /dev/null +++ b/packages/rn-api/src/screens/AuthComponent/ForgotPasswordScreen.js @@ -0,0 +1,67 @@ +import React, {useCallback, useReducer} from 'react' +import {ScreenContainer} from '../../components/ScreenContainer' +import {Text, StyleSheet, TouchableOpacity} from 'react-native' +import {responsiveHeight} from '../../themes/metrics' +import {colors} from '../../themes' +import {useDispatch} from 'react-redux' +import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view' +import {userActions} from '../../store/reducers' +import InputWIthLabel from '../../components/InputWIthLabel' + +export const ForgotPasswordScreen = () => { + const dispatch = useDispatch() + const [inputValue, setInputValue] = useReducer((prev, next) => ({...prev, ...next}), { + email: '', + }) + + const onForgotPassword = useCallback(() => { + dispatch(userActions.forgotPasswordHandle({email: inputValue.email})) + }, [inputValue, dispatch]) + + const onChangeEmail = useCallback(text => { + setInputValue({email: text}) + }, []) + + return ( + + + Forgot Password + + + SAVE + + + + ) +} + +const styles = StyleSheet.create({ + container: { + padding: responsiveHeight(10), + alignItems: 'center', + }, + titleText: { + fontSize: responsiveHeight(25), + fontWeight: '600', + marginVertical: responsiveHeight(20), + }, + passwordSection: { + marginTop: responsiveHeight(10), + }, + button: { + backgroundColor: colors.primary, + width: '100%', + height: responsiveHeight(40), + marginTop: responsiveHeight(10), + alignItems: 'center', + justifyContent: 'center', + borderRadius: 10, + }, + forgotPassword: { + fontSize: responsiveHeight(18), + marginVertical: responsiveHeight(10), + alignSelf: 'flex-end', + color: colors.primary, + textDecorationLine: 'underline', + }, +}) diff --git a/packages/rn-api/src/screens/AuthComponent/LoginScreen.js b/packages/rn-api/src/screens/AuthComponent/LoginScreen.js index 51a044e..8cdaa0d 100644 --- a/packages/rn-api/src/screens/AuthComponent/LoginScreen.js +++ b/packages/rn-api/src/screens/AuthComponent/LoginScreen.js @@ -1,4 +1,96 @@ -import React from 'react' -import {ScreenContainer} from '../../components' +import React, {useCallback, useReducer} from 'react' +import {ScreenContainer} from '../../components/ScreenContainer' +import {Text, StyleSheet, View, TouchableOpacity} from 'react-native' +import PasswordInput from '../../components/InputPassword' +import {responsiveHeight} from '../../themes/metrics' +import {colors} from '../../themes' +import {useDispatch} from 'react-redux' +import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view' +import {userActions} from '../../store/reducers' +import {navigate} from '../../navigation/NavigationService' +import RouteKey from '../../navigation/RouteKey' +import InputWIthLabel from '../../components/InputWIthLabel' -export const LoginScreen = () => +export const LoginScreen = () => { + const dispatch = useDispatch() + const [inputValue, setInputValue] = useReducer((prev, next) => ({...prev, ...next}), { + email: '', + password: '', + }) + + const onPressLogin = useCallback(() => { + dispatch(userActions.userLogin()) + }, [dispatch]) + + const onChangeEmail = useCallback(text => { + setInputValue({email: text}) + }, []) + + const onChangePassword = useCallback(text => { + setInputValue({password: text}) + }, []) + + return ( + + + Login Screen + + + + + { + navigate(RouteKey.ChangePasswordScreen) + }}> + Change Password + + { + navigate(RouteKey.ForgotPasswordScreen) + }}> + Forgot Password + + { + navigate(RouteKey.ResetPasswordScreen) + }}> + Reset Password + + + SAVE + + + + ) +} + +const styles = StyleSheet.create({ + container: { + padding: responsiveHeight(10), + alignItems: 'center', + }, + titleText: { + fontSize: responsiveHeight(25), + fontWeight: '600', + marginVertical: responsiveHeight(20), + }, + passwordSection: { + marginTop: responsiveHeight(10), + }, + button: { + backgroundColor: colors.primary, + width: '100%', + height: responsiveHeight(40), + marginTop: responsiveHeight(10), + alignItems: 'center', + justifyContent: 'center', + borderRadius: 10, + }, + forgotPassword: { + fontSize: responsiveHeight(18), + marginVertical: responsiveHeight(10), + alignSelf: 'flex-end', + color: colors.primary, + textDecorationLine: 'underline', + }, +}) diff --git a/packages/rn-api/src/screens/AuthComponent/ResetPasswordScreen.js b/packages/rn-api/src/screens/AuthComponent/ResetPasswordScreen.js new file mode 100644 index 0000000..55ea9bc --- /dev/null +++ b/packages/rn-api/src/screens/AuthComponent/ResetPasswordScreen.js @@ -0,0 +1,94 @@ +import React, {useCallback, useReducer} from 'react' +import {ScreenContainer} from '../../components/ScreenContainer' +import {Text, StyleSheet, View, TouchableOpacity} from 'react-native' +import PasswordInput from '../../components/InputPassword' +import {responsiveHeight} from '../../themes/metrics' +import {colors} from '../../themes' +import {useDispatch} from 'react-redux' +import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view' +import {userActions} from '../../store/reducers' +import InputWIthLabel from '../../components/InputWIthLabel' + +export const ResetPasswordScreen = () => { + const dispatch = useDispatch() + const [inputValue, setInputValue] = useReducer((prev, next) => ({...prev, ...next}), { + newPassword: '', + confirmPassword: '', + email: '', + }) + + const onResetPassword = useCallback(() => { + dispatch( + userActions.resetPasswordHandle({ + newPassword: inputValue.newPassword, + confirmPassword: inputValue.confirmPassword, + email: inputValue.email, + }), + ) + }, [inputValue, dispatch]) + + const onChangeNewPass = useCallback(text => { + setInputValue({newPassword: text}) + }, []) + + const onChangePassword = useCallback(text => { + setInputValue({confirmPassword: text}) + }, []) + + const onChangeEmail = useCallback(text => { + setInputValue({email: text}) + }, []) + + return ( + + + Reset Password + + + + + + + + + SAVE + + + + ) +} + +const styles = StyleSheet.create({ + container: { + padding: responsiveHeight(10), + alignItems: 'center', + }, + titleText: { + fontSize: responsiveHeight(25), + fontWeight: '600', + marginVertical: responsiveHeight(20), + }, + passwordSection: { + marginTop: responsiveHeight(10), + }, + button: { + backgroundColor: colors.primary, + width: '100%', + height: responsiveHeight(40), + marginTop: responsiveHeight(10), + alignItems: 'center', + justifyContent: 'center', + borderRadius: 10, + }, + forgotPassword: { + fontSize: responsiveHeight(18), + marginVertical: responsiveHeight(10), + alignSelf: 'flex-end', + color: colors.primary, + textDecorationLine: 'underline', + }, +}) diff --git a/packages/rn-api/src/screens/AuthComponent/index.js b/packages/rn-api/src/screens/AuthComponent/index.js index c270443..4cb9c73 100644 --- a/packages/rn-api/src/screens/AuthComponent/index.js +++ b/packages/rn-api/src/screens/AuthComponent/index.js @@ -1,2 +1,5 @@ export * from './LoginScreen' export * from './SignUpScreen' +export * from './ChangePasswordScreen' +export * from './ResetPasswordScreen' +export * from './ForgotPasswordScreen' diff --git a/packages/rn-api/src/services/api/api.js b/packages/rn-api/src/services/api/api.js index 7d93721..0ac5cdc 100644 --- a/packages/rn-api/src/services/api/api.js +++ b/packages/rn-api/src/services/api/api.js @@ -1,4 +1,26 @@ +import Config from 'react-native-config' +// eslint-disable-next-line import/no-cycle +import {postRequest} from '../networking/index' +import PasswordModel from '../../models/user/PasswordModel' + export const AUTH_API = { // ADD ENDPOINT REFRESH TOKEN HERE refreshToken: 'api/refreshToken', } + +const baseURL = Config.API_URL + +export async function changePassword(body) { + const rs = await postRequest(`${baseURL}/Account/changepassword`, body) + return PasswordModel.parseFromJson(rs) +} + +export async function forgotPassword(body) { + const rs = await postRequest(`${baseURL}/Account/forgotpassword`, body) + return PasswordModel.parseFromJson(rs) +} + +export async function resetPassword(body) { + const rs = await postRequest(`${baseURL}/Account/resetpassword`, body) + return PasswordModel.parseFromJson(rs) +} diff --git a/packages/rn-api/src/store/constants/user.js b/packages/rn-api/src/store/constants/user.js new file mode 100644 index 0000000..7f932b5 --- /dev/null +++ b/packages/rn-api/src/store/constants/user.js @@ -0,0 +1,19 @@ +import {actionTypes} from '../actionTypes' + +const USER_LOGIN_ACTIONS = actionTypes('USER_LOGIN_ACTIONS') + +const UPDATE_USER_INFO_ACTIONS = actionTypes('UPDATE_USER_INFO_ACTIONS') + +const CHANGE_PASSWORD_ACTIONS = actionTypes('CHANGE_PASSWORD_ACTIONS') + +const FORGOT_PASSWORD_ACTIONS = actionTypes('FORGOT_PASSWORD_ACTIONS') + +const RESET_PASSWORD_ACTIONS = actionTypes('RESET_PASSWORD_ACTIONS') + +export const USER_CONSTANTS_ACTIONS = { + USER_LOGIN_ACTIONS, + UPDATE_USER_INFO_ACTIONS, + CHANGE_PASSWORD_ACTIONS, + FORGOT_PASSWORD_ACTIONS, + RESET_PASSWORD_ACTIONS, +} diff --git a/packages/rn-api/src/store/reducers/user.js b/packages/rn-api/src/store/reducers/user.js index be39fac..1a0775c 100644 --- a/packages/rn-api/src/store/reducers/user.js +++ b/packages/rn-api/src/store/reducers/user.js @@ -1,4 +1,5 @@ import {createSlice} from '@reduxjs/toolkit' +import {USER_CONSTANTS_ACTIONS} from '../constants/user' export const userInitialState = { userInfo: {}, @@ -14,12 +15,33 @@ export const userSlice = createSlice({ userLogin: () => {}, userSignUp: () => {}, logout(state) {}, + [USER_CONSTANTS_ACTIONS.CHANGE_PASSWORD_ACTIONS.HANDLER]: () => {}, + [USER_CONSTANTS_ACTIONS.CHANGE_PASSWORD_ACTIONS.SUCCESS]: () => {}, + [USER_CONSTANTS_ACTIONS.CHANGE_PASSWORD_ACTIONS.FAILURE]: () => {}, + [USER_CONSTANTS_ACTIONS.FORGOT_PASSWORD_ACTIONS.HANDLER]: () => {}, + [USER_CONSTANTS_ACTIONS.FORGOT_PASSWORD_ACTIONS.SUCCESS]: () => {}, + [USER_CONSTANTS_ACTIONS.FORGOT_PASSWORD_ACTIONS.FAILURE]: () => {}, + [USER_CONSTANTS_ACTIONS.RESET_PASSWORD_ACTIONS.HANDLER]: () => {}, + [USER_CONSTANTS_ACTIONS.RESET_PASSWORD_ACTIONS.SUCCESS]: () => {}, + [USER_CONSTANTS_ACTIONS.RESET_PASSWORD_ACTIONS.FAILURE]: () => {}, }, extraReducers: builder => {}, }) export const userActions = { ...userSlice.actions, + userLoginHandle: userSlice.actions[USER_CONSTANTS_ACTIONS.USER_LOGIN_ACTIONS.HANDLER], + userLoginSuccess: userSlice.actions[USER_CONSTANTS_ACTIONS.USER_LOGIN_ACTIONS.SUCCESS], + userLoginFailure: userSlice.actions[USER_CONSTANTS_ACTIONS.USER_LOGIN_ACTIONS.FAILURE], + changePasswordHandle: userSlice.actions[USER_CONSTANTS_ACTIONS.CHANGE_PASSWORD_ACTIONS.HANDLER], + changePasswordSuccess: userSlice.actions[USER_CONSTANTS_ACTIONS.CHANGE_PASSWORD_ACTIONS.SUCCESS], + changePasswordFailure: userSlice.actions[USER_CONSTANTS_ACTIONS.CHANGE_PASSWORD_ACTIONS.FAILURE], + forgotPasswordHandle: userSlice.actions[USER_CONSTANTS_ACTIONS.FORGOT_PASSWORD_ACTIONS.HANDLER], + forgotPasswordSuccess: userSlice.actions[USER_CONSTANTS_ACTIONS.FORGOT_PASSWORD_ACTIONS.SUCCESS], + forgotPasswordFailure: userSlice.actions[USER_CONSTANTS_ACTIONS.FORGOT_PASSWORD_ACTIONS.FAILURE], + resetPasswordHandle: userSlice.actions[USER_CONSTANTS_ACTIONS.RESET_PASSWORD_ACTIONS.HANDLER], + resetPasswordSuccess: userSlice.actions[USER_CONSTANTS_ACTIONS.RESET_PASSWORD_ACTIONS.SUCCESS], + resetPasswordFailure: userSlice.actions[USER_CONSTANTS_ACTIONS.RESET_PASSWORD_ACTIONS.FAILURE], } export default userSlice.reducer diff --git a/packages/rn-api/src/store/saga/user.js b/packages/rn-api/src/store/saga/user.js index 5a7a47b..66e9504 100644 --- a/packages/rn-api/src/store/saga/user.js +++ b/packages/rn-api/src/store/saga/user.js @@ -2,6 +2,7 @@ import {takeLatest, delay, put} from 'redux-saga/effects' import {appActions, userActions} from '../reducers' import RouteKey from '../../navigation/RouteKey' import {Toast} from '../../components' +import {changePassword, forgotPassword, resetPassword} from '../../services/api/api' function* userLoginSaga(action) { try { @@ -27,6 +28,54 @@ function* userSignUpSaga(action) { } } +function* userChangePasswordSaga(action) { + try { + yield put(appActions.setShowGlobalIndicator(true)) + const res = yield changePassword(action.body) + if (res?.isSuccess === true) { + yield put(userActions.changePasswordSuccess(res)) + Toast.success('SUCCESSFULLY') + // TODO: + } + } catch (e) { + Toast.error(e.message) + } finally { + yield put(appActions.setShowGlobalIndicator(false)) + } +} + +function* userForgotPasswordSaga(action) { + try { + yield put(appActions.setShowGlobalIndicator(true)) + const res = yield forgotPassword(action.body) + if (res?.isSuccess === true) { + yield put(userActions.forgotPasswordSuccess(res)) + Toast.success('SUCCESSFULLY') + // TODO: + } + } catch (e) { + Toast.error(e.message) + } finally { + yield put(appActions.setShowGlobalIndicator(false)) + } +} + +function* userResetPasswordSaga(action) { + try { + yield put(appActions.setShowGlobalIndicator(true)) + const res = yield resetPassword(action.body) + if (res?.isSuccess === true) { + yield put(userActions.resetPasswordSuccess(res)) + Toast.success('SUCCESSFULLY') + // TODO: + } + } catch (e) { + Toast.error(e.message) + } finally { + yield put(appActions.setShowGlobalIndicator(false)) + } +} + function* userLogout() { try { } catch (e) {} @@ -36,4 +85,7 @@ export default [ takeLatest(userActions.userLogin.type, userLoginSaga), takeLatest(userActions.userSignUp.type, userSignUpSaga), takeLatest(userActions.logout.type, userLogout), + takeLatest(userActions.changePasswordHandle, userChangePasswordSaga), + takeLatest(userActions.forgotPasswordHandle, userForgotPasswordSaga), + takeLatest(userActions.resetPasswordHandle, userResetPasswordSaga), ] From 9b6cafc5157c433f50cb6933f1d218e84124d82d Mon Sep 17 00:00:00 2001 From: Anh Le Date: Tue, 8 Aug 2023 11:45:42 +0700 Subject: [PATCH 2/4] chore: update basic UI --- .../src/screens/AuthComponent/ForgotPasswordScreen.js | 9 ++++++--- packages/rn-api/src/screens/AuthComponent/LoginScreen.js | 4 ++-- .../src/screens/AuthComponent/ResetPasswordScreen.js | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/rn-api/src/screens/AuthComponent/ForgotPasswordScreen.js b/packages/rn-api/src/screens/AuthComponent/ForgotPasswordScreen.js index 65ecb13..11ae73a 100644 --- a/packages/rn-api/src/screens/AuthComponent/ForgotPasswordScreen.js +++ b/packages/rn-api/src/screens/AuthComponent/ForgotPasswordScreen.js @@ -6,7 +6,7 @@ import {colors} from '../../themes' import {useDispatch} from 'react-redux' import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view' import {userActions} from '../../store/reducers' -import InputWIthLabel from '../../components/InputWIthLabel' +import InputWithLabel from '../../components/InputWithLabel' export const ForgotPasswordScreen = () => { const dispatch = useDispatch() @@ -24,9 +24,9 @@ export const ForgotPasswordScreen = () => { return ( - + Forgot Password - + SAVE @@ -40,6 +40,9 @@ const styles = StyleSheet.create({ padding: responsiveHeight(10), alignItems: 'center', }, + contentSection: { + width: '100%', + }, titleText: { fontSize: responsiveHeight(25), fontWeight: '600', diff --git a/packages/rn-api/src/screens/AuthComponent/LoginScreen.js b/packages/rn-api/src/screens/AuthComponent/LoginScreen.js index 8cdaa0d..9651d95 100644 --- a/packages/rn-api/src/screens/AuthComponent/LoginScreen.js +++ b/packages/rn-api/src/screens/AuthComponent/LoginScreen.js @@ -9,7 +9,7 @@ import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view' import {userActions} from '../../store/reducers' import {navigate} from '../../navigation/NavigationService' import RouteKey from '../../navigation/RouteKey' -import InputWIthLabel from '../../components/InputWIthLabel' +import InputWithLabel from '../../components/InputWithLabel' export const LoginScreen = () => { const dispatch = useDispatch() @@ -34,7 +34,7 @@ export const LoginScreen = () => { Login Screen - + diff --git a/packages/rn-api/src/screens/AuthComponent/ResetPasswordScreen.js b/packages/rn-api/src/screens/AuthComponent/ResetPasswordScreen.js index 55ea9bc..6fac08a 100644 --- a/packages/rn-api/src/screens/AuthComponent/ResetPasswordScreen.js +++ b/packages/rn-api/src/screens/AuthComponent/ResetPasswordScreen.js @@ -7,7 +7,7 @@ import {colors} from '../../themes' import {useDispatch} from 'react-redux' import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view' import {userActions} from '../../store/reducers' -import InputWIthLabel from '../../components/InputWIthLabel' +import InputWithLabel from '../../components/InputWithLabel' export const ResetPasswordScreen = () => { const dispatch = useDispatch() @@ -52,7 +52,7 @@ export const ResetPasswordScreen = () => { /> - + SAVE From 527c30a5d7fea535ff62f82361197795471fce39 Mon Sep 17 00:00:00 2001 From: Anh Le Date: Wed, 9 Aug 2023 11:07:53 +0700 Subject: [PATCH 3/4] feat: update apis logic --- packages/rn-api/src/models/user/PasswordModel.js | 11 ++++++----- .../screens/AuthComponent/ForgotPasswordScreen.js | 14 ++++++-------- packages/rn-api/src/store/saga/user.js | 6 +++--- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/packages/rn-api/src/models/user/PasswordModel.js b/packages/rn-api/src/models/user/PasswordModel.js index c8d400e..21a5424 100644 --- a/packages/rn-api/src/models/user/PasswordModel.js +++ b/packages/rn-api/src/models/user/PasswordModel.js @@ -1,12 +1,13 @@ export default class PasswordModel { - constructor(data) { + constructor(message, errorCode, data, isSuccess) { + this.message = message + this.errorCode = errorCode this.data = data + this.isSuccess = isSuccess } static parseFromJson = payload => { - const obj = new PasswordModel() - const {data} = payload - obj.data = data - return obj + const {message, errorCode, data, isSuccess} = payload + return new PasswordModel(message, errorCode, data, isSuccess) } } diff --git a/packages/rn-api/src/screens/AuthComponent/ForgotPasswordScreen.js b/packages/rn-api/src/screens/AuthComponent/ForgotPasswordScreen.js index 11ae73a..862380c 100644 --- a/packages/rn-api/src/screens/AuthComponent/ForgotPasswordScreen.js +++ b/packages/rn-api/src/screens/AuthComponent/ForgotPasswordScreen.js @@ -1,4 +1,4 @@ -import React, {useCallback, useReducer} from 'react' +import React, {useCallback, useState} from 'react' import {ScreenContainer} from '../../components/ScreenContainer' import {Text, StyleSheet, TouchableOpacity} from 'react-native' import {responsiveHeight} from '../../themes/metrics' @@ -10,23 +10,21 @@ import InputWithLabel from '../../components/InputWithLabel' export const ForgotPasswordScreen = () => { const dispatch = useDispatch() - const [inputValue, setInputValue] = useReducer((prev, next) => ({...prev, ...next}), { - email: '', - }) + const [email, setEmail] = useState('') const onForgotPassword = useCallback(() => { - dispatch(userActions.forgotPasswordHandle({email: inputValue.email})) - }, [inputValue, dispatch]) + dispatch(userActions.forgotPasswordHandle({email})) + }, [email, dispatch]) const onChangeEmail = useCallback(text => { - setInputValue({email: text}) + setEmail(text) }, []) return ( Forgot Password - + SAVE diff --git a/packages/rn-api/src/store/saga/user.js b/packages/rn-api/src/store/saga/user.js index 66e9504..296c35b 100644 --- a/packages/rn-api/src/store/saga/user.js +++ b/packages/rn-api/src/store/saga/user.js @@ -31,7 +31,7 @@ function* userSignUpSaga(action) { function* userChangePasswordSaga(action) { try { yield put(appActions.setShowGlobalIndicator(true)) - const res = yield changePassword(action.body) + const res = yield changePassword(action.payload) if (res?.isSuccess === true) { yield put(userActions.changePasswordSuccess(res)) Toast.success('SUCCESSFULLY') @@ -47,7 +47,7 @@ function* userChangePasswordSaga(action) { function* userForgotPasswordSaga(action) { try { yield put(appActions.setShowGlobalIndicator(true)) - const res = yield forgotPassword(action.body) + const res = yield forgotPassword(action.payload) if (res?.isSuccess === true) { yield put(userActions.forgotPasswordSuccess(res)) Toast.success('SUCCESSFULLY') @@ -63,7 +63,7 @@ function* userForgotPasswordSaga(action) { function* userResetPasswordSaga(action) { try { yield put(appActions.setShowGlobalIndicator(true)) - const res = yield resetPassword(action.body) + const res = yield resetPassword(action.payload) if (res?.isSuccess === true) { yield put(userActions.resetPasswordSuccess(res)) Toast.success('SUCCESSFULLY') From 98262352cd0b2a87cdd223dc5c70330ef06e5902 Mon Sep 17 00:00:00 2001 From: Anh Le Date: Thu, 10 Aug 2023 11:56:53 +0700 Subject: [PATCH 4/4] chore: fix comments --- packages/rn-api/src/components/InputPassword.js | 4 +--- .../rn-api/src/components/InputWIthLabel.js | 4 +--- packages/rn-api/src/components/index.js | 2 ++ packages/rn-api/src/models/ApiResponseModel.js | 13 +++++++++++++ packages/rn-api/src/models/index.js | 2 ++ .../rn-api/src/models/user/PasswordModel.js | 17 +++++++++++------ packages/rn-api/src/models/user/index.js | 1 + .../AuthComponent/ChangePasswordScreen.js | 6 ++---- .../AuthComponent/ForgotPasswordScreen.js | 6 ++---- .../src/screens/AuthComponent/LoginScreen.js | 7 ++----- .../AuthComponent/ResetPasswordScreen.js | 7 ++----- packages/rn-api/src/services/api/api.js | 2 +- 12 files changed, 40 insertions(+), 31 deletions(-) create mode 100644 packages/rn-api/src/models/ApiResponseModel.js create mode 100644 packages/rn-api/src/models/index.js create mode 100644 packages/rn-api/src/models/user/index.js diff --git a/packages/rn-api/src/components/InputPassword.js b/packages/rn-api/src/components/InputPassword.js index 51536ad..4f23aea 100644 --- a/packages/rn-api/src/components/InputPassword.js +++ b/packages/rn-api/src/components/InputPassword.js @@ -4,7 +4,7 @@ import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityI import {responsiveHeight} from '../themes/metrics' import TextInputView from './TextInputView' -const PasswordInput = props => { +export const PasswordInput = props => { const {style, title, onChangeText, value, defaultValue, ...rest} = props const [showPassword, setShowPassword] = useState(false) @@ -59,5 +59,3 @@ const styles = StyleSheet.create({ height: responsiveHeight(40), }, }) - -export default React.memo(PasswordInput) diff --git a/packages/rn-api/src/components/InputWIthLabel.js b/packages/rn-api/src/components/InputWIthLabel.js index 89a7575..707792b 100644 --- a/packages/rn-api/src/components/InputWIthLabel.js +++ b/packages/rn-api/src/components/InputWIthLabel.js @@ -3,7 +3,7 @@ import React from 'react' import {responsiveHeight} from '../themes/metrics' import TextInputView from './TextInputView' -const InputWithLabel = props => { +export const InputWithLabel = props => { const {title, style, onChangeText, value, defaultValue, ...rest} = props return ( @@ -35,5 +35,3 @@ const styles = StyleSheet.create({ borderRadius: 5, }, }) - -export default React.memo(InputWithLabel) diff --git a/packages/rn-api/src/components/index.js b/packages/rn-api/src/components/index.js index d6c5faa..1b58bec 100644 --- a/packages/rn-api/src/components/index.js +++ b/packages/rn-api/src/components/index.js @@ -4,3 +4,5 @@ export * from './IndicatorDialog' export * from './Row' export * from './ScreenContainer' export * from './Toast' +export * from './InputWithLabel' +export * from './InputPassword' diff --git a/packages/rn-api/src/models/ApiResponseModel.js b/packages/rn-api/src/models/ApiResponseModel.js new file mode 100644 index 0000000..55ea64f --- /dev/null +++ b/packages/rn-api/src/models/ApiResponseModel.js @@ -0,0 +1,13 @@ +export class ApiResponseModel { + constructor(message, errorCode, data, isSuccess) { + this.message = message + this.errorCode = errorCode + this.data = data + this.isSuccess = isSuccess + } + + static parseFromJson = payload => { + const {message, errorCode, data, isSuccess} = payload + return new ApiResponseModel(message, errorCode, data, isSuccess) + } +} diff --git a/packages/rn-api/src/models/index.js b/packages/rn-api/src/models/index.js new file mode 100644 index 0000000..c88c24e --- /dev/null +++ b/packages/rn-api/src/models/index.js @@ -0,0 +1,2 @@ +export * from './user' +export * from './ApiResponseModel' diff --git a/packages/rn-api/src/models/user/PasswordModel.js b/packages/rn-api/src/models/user/PasswordModel.js index 21a5424..c2ebdc3 100644 --- a/packages/rn-api/src/models/user/PasswordModel.js +++ b/packages/rn-api/src/models/user/PasswordModel.js @@ -1,13 +1,18 @@ -export default class PasswordModel { +import {ApiResponseModel} from '../ApiResponseModel' + +export class PasswordModel extends ApiResponseModel { constructor(message, errorCode, data, isSuccess) { - this.message = message - this.errorCode = errorCode - this.data = data - this.isSuccess = isSuccess + super(message, errorCode, data, isSuccess) } static parseFromJson = payload => { const {message, errorCode, data, isSuccess} = payload - return new PasswordModel(message, errorCode, data, isSuccess) + + // Customize the 'data' property in PasswordModel + const customizedData = { + password: data?.password ?? '', + } + + return new PasswordModel(message, errorCode, customizedData, isSuccess) } } diff --git a/packages/rn-api/src/models/user/index.js b/packages/rn-api/src/models/user/index.js new file mode 100644 index 0000000..7c72b56 --- /dev/null +++ b/packages/rn-api/src/models/user/index.js @@ -0,0 +1 @@ +export * from './PasswordModel' diff --git a/packages/rn-api/src/screens/AuthComponent/ChangePasswordScreen.js b/packages/rn-api/src/screens/AuthComponent/ChangePasswordScreen.js index f32ce4e..d2572af 100644 --- a/packages/rn-api/src/screens/AuthComponent/ChangePasswordScreen.js +++ b/packages/rn-api/src/screens/AuthComponent/ChangePasswordScreen.js @@ -1,9 +1,7 @@ import React, {useCallback, useReducer} from 'react' -import {ScreenContainer} from '../../components/ScreenContainer' +import {ScreenContainer, PasswordInput} from '../../components' import {Text, StyleSheet, View, TouchableOpacity} from 'react-native' -import PasswordInput from '../../components/InputPassword' -import {responsiveHeight} from '../../themes/metrics' -import {colors} from '../../themes' +import {responsiveHeight, colors} from '../../themes' import {useDispatch} from 'react-redux' import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view' import {userActions} from '../../store/reducers' diff --git a/packages/rn-api/src/screens/AuthComponent/ForgotPasswordScreen.js b/packages/rn-api/src/screens/AuthComponent/ForgotPasswordScreen.js index 862380c..f32b6fe 100644 --- a/packages/rn-api/src/screens/AuthComponent/ForgotPasswordScreen.js +++ b/packages/rn-api/src/screens/AuthComponent/ForgotPasswordScreen.js @@ -1,12 +1,10 @@ import React, {useCallback, useState} from 'react' -import {ScreenContainer} from '../../components/ScreenContainer' +import {ScreenContainer, InputWithLabel} from '../../components' import {Text, StyleSheet, TouchableOpacity} from 'react-native' -import {responsiveHeight} from '../../themes/metrics' -import {colors} from '../../themes' +import {responsiveHeight, colors} from '../../themes' import {useDispatch} from 'react-redux' import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view' import {userActions} from '../../store/reducers' -import InputWithLabel from '../../components/InputWithLabel' export const ForgotPasswordScreen = () => { const dispatch = useDispatch() diff --git a/packages/rn-api/src/screens/AuthComponent/LoginScreen.js b/packages/rn-api/src/screens/AuthComponent/LoginScreen.js index 9651d95..9b39df9 100644 --- a/packages/rn-api/src/screens/AuthComponent/LoginScreen.js +++ b/packages/rn-api/src/screens/AuthComponent/LoginScreen.js @@ -1,15 +1,12 @@ import React, {useCallback, useReducer} from 'react' -import {ScreenContainer} from '../../components/ScreenContainer' +import {ScreenContainer, InputWithLabel, PasswordInput} from '../../components' import {Text, StyleSheet, View, TouchableOpacity} from 'react-native' -import PasswordInput from '../../components/InputPassword' -import {responsiveHeight} from '../../themes/metrics' -import {colors} from '../../themes' +import {responsiveHeight, colors} from '../../themes' import {useDispatch} from 'react-redux' import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view' import {userActions} from '../../store/reducers' import {navigate} from '../../navigation/NavigationService' import RouteKey from '../../navigation/RouteKey' -import InputWithLabel from '../../components/InputWithLabel' export const LoginScreen = () => { const dispatch = useDispatch() diff --git a/packages/rn-api/src/screens/AuthComponent/ResetPasswordScreen.js b/packages/rn-api/src/screens/AuthComponent/ResetPasswordScreen.js index 6fac08a..d153f5f 100644 --- a/packages/rn-api/src/screens/AuthComponent/ResetPasswordScreen.js +++ b/packages/rn-api/src/screens/AuthComponent/ResetPasswordScreen.js @@ -1,13 +1,10 @@ import React, {useCallback, useReducer} from 'react' -import {ScreenContainer} from '../../components/ScreenContainer' +import {ScreenContainer, InputWithLabel, PasswordInput} from '../../components' import {Text, StyleSheet, View, TouchableOpacity} from 'react-native' -import PasswordInput from '../../components/InputPassword' -import {responsiveHeight} from '../../themes/metrics' -import {colors} from '../../themes' +import {responsiveHeight, colors} from '../../themes' import {useDispatch} from 'react-redux' import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view' import {userActions} from '../../store/reducers' -import InputWithLabel from '../../components/InputWithLabel' export const ResetPasswordScreen = () => { const dispatch = useDispatch() diff --git a/packages/rn-api/src/services/api/api.js b/packages/rn-api/src/services/api/api.js index 0ac5cdc..7ed3d2b 100644 --- a/packages/rn-api/src/services/api/api.js +++ b/packages/rn-api/src/services/api/api.js @@ -1,7 +1,7 @@ import Config from 'react-native-config' // eslint-disable-next-line import/no-cycle import {postRequest} from '../networking/index' -import PasswordModel from '../../models/user/PasswordModel' +import {PasswordModel} from '../../models' export const AUTH_API = { // ADD ENDPOINT REFRESH TOKEN HERE