@fadyshawky/react-native-magic 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +90 -55
- package/index.js +4 -0
- package/package.json +9 -3
- package/scripts/askPackageName.js +10 -5
- package/template/.env.development +8 -6
- package/template/.env.example +15 -5
- package/template/.env.production +8 -6
- package/template/.env.staging +8 -6
- package/template/.eslintrc.js +14 -0
- package/template/.husky/pre-commit +1 -0
- package/template/App.tsx +47 -16
- package/template/__tests__/App.test.tsx +28 -10
- package/template/babel.config.js +20 -1
- package/template/docs/ARCHITECTURE.md +40 -10
- package/template/docs/BEST_PRACTICES.md +10 -1
- package/template/docs/CUSTOMIZATION.md +118 -5
- package/template/docs/design-system.html +1164 -0
- package/template/docs/wireframes.html +411 -0
- package/template/index.js +10 -0
- package/template/jest.config.js +16 -1
- package/template/jest.setup.js +61 -0
- package/template/package-lock.json +12178 -8293
- package/template/package.json +53 -19
- package/template/react-native.config.js +3 -0
- package/template/resources/fonts/.gitkeep +0 -0
- package/template/scripts/ci-sync-env.cjs +71 -0
- package/template/src/assets/brand/logo-mark.svg +8 -0
- package/template/src/assets/brand/logo-mono.svg +9 -0
- package/template/src/assets/brand/logo-primary.svg +15 -0
- package/template/src/assets/brand/wordmark-dark.svg +18 -0
- package/template/src/common/components/AppBottomSheet.tsx +87 -0
- package/template/src/common/components/AppSwitch.tsx +75 -0
- package/template/src/common/components/AppTextInput.tsx +161 -0
- package/template/src/common/components/Avatar.tsx +75 -0
- package/template/src/common/components/Badge.tsx +66 -0
- package/template/src/common/components/CardScroller.tsx +58 -0
- package/template/src/common/components/Cards.tsx +13 -7
- package/template/src/common/components/Carousel.tsx +196 -0
- package/template/src/common/components/Checkbox.tsx +85 -0
- package/template/src/common/components/Chip.tsx +55 -0
- package/template/src/common/components/Dropdown.tsx +202 -0
- package/template/src/common/components/ErrorBoundary.tsx +82 -0
- package/template/src/common/components/FlatListWrapper.tsx +8 -8
- package/template/src/common/components/ListItem.tsx +90 -0
- package/template/src/common/components/LoadingComponent.tsx +8 -2
- package/template/src/common/components/Logo.tsx +77 -0
- package/template/src/common/components/ModalDialog.tsx +141 -0
- package/template/src/common/components/NetworkBanner.tsx +47 -0
- package/template/src/common/components/OTPInput.tsx +0 -1
- package/template/src/common/components/PrimaryButton.tsx +0 -14
- package/template/src/common/components/PrimaryTextInput.tsx +66 -130
- package/template/src/common/components/RadioGroup.tsx +95 -0
- package/template/src/common/components/SafeText.tsx +4 -3
- package/template/src/common/components/SearchBar.tsx +7 -5
- package/template/src/common/components/SegmentedControl.tsx +77 -0
- package/template/src/common/components/Skeleton.tsx +47 -0
- package/template/src/common/components/TryAgain.tsx +4 -2
- package/template/src/common/helpers/arrayHelpers.ts +2 -2
- package/template/src/common/helpers/defaultKeyIdExtractor.ts +1 -1
- package/template/src/common/helpers/regexHelpers.ts +1 -2
- package/template/src/common/helpers/stringsHelpers.ts +0 -1
- package/template/src/common/hooks/useBackHandler.ts +5 -2
- package/template/src/common/hooks/useEventRegister.ts +1 -1
- package/template/src/common/hooks/useFlatListActions.ts +1 -1
- package/template/src/common/hooks/useWhyDidYouUpdate.ts +1 -1
- package/template/src/common/localization/LocalizationProvider.tsx +1 -1
- package/template/src/common/localization/RTLInitializer.tsx +1 -1
- package/template/src/common/localization/dateFormatter.ts +0 -1
- package/template/src/common/localization/intlFormatter.ts +0 -1
- package/template/src/common/localization/localization.ts +2 -2
- package/template/src/common/localization/translations/homeLocalization.ts +14 -0
- package/template/src/common/localization/translations/loginLocalization.ts +8 -0
- package/template/src/common/localization/translations/mainNavigationLocalization.ts +2 -0
- package/template/src/common/localization/translations/profileLocalization.ts +16 -0
- package/template/src/common/utils/index.tsx +0 -6
- package/template/src/common/validations/commonValidations.ts +2 -2
- package/template/src/core/api/errorHandler.ts +1 -1
- package/template/src/core/api/responseHandlers.ts +1 -3
- package/template/src/core/api/serverHeaders.ts +61 -12
- package/template/src/core/notifications/notificationAuth.ts +6 -0
- package/template/src/core/notifications/notificationService.ts +125 -0
- package/template/src/core/notifications/routeFromNotificationData.ts +32 -0
- package/template/src/core/store/categories/categoriesActions.ts +25 -0
- package/template/src/core/store/categories/categoriesSlice.ts +51 -0
- package/template/src/core/store/categories/categoriesState.ts +19 -0
- package/template/src/core/store/rootReducer.ts +2 -0
- package/template/src/core/store/store.tsx +6 -1
- package/template/src/core/store/user/userActions.ts +75 -14
- package/template/src/core/store/user/userSlice.ts +49 -26
- package/template/src/core/store/user/userState.ts +6 -4
- package/template/src/core/theme/ThemeProvider.tsx +5 -3
- package/template/src/core/theme/brand.ts +50 -0
- package/template/src/core/theme/colors.ts +113 -99
- package/template/src/core/theme/commonConsts.ts +2 -2
- package/template/src/core/theme/commonStyles.ts +1 -1
- package/template/src/core/theme/themes.ts +2 -0
- package/template/src/core/theme/types.ts +4 -2
- package/template/src/core/utils/stringUtils.ts +1 -1
- package/template/src/design-system/index.ts +2 -0
- package/template/src/design-system/tokens/brand.ts +6 -0
- package/template/src/design-system/tokens/index.ts +3 -0
- package/template/src/design-system/tokens/palette.ts +4 -0
- package/template/src/design-system/tokens/typography-spacing.ts +2 -0
- package/template/src/navigation/AuthStack.tsx +1 -4
- package/template/src/navigation/HeaderComponents.tsx +6 -3
- package/template/src/navigation/MainStack.tsx +18 -6
- package/template/src/navigation/RootNavigation.tsx +4 -7
- package/template/src/navigation/TabBar.tsx +7 -6
- package/template/src/navigation/types.ts +10 -31
- package/template/src/screens/Login/Login.tsx +47 -47
- package/template/src/screens/OTP/OTPScreen.tsx +6 -9
- package/template/src/screens/components/ComponentsScreen.tsx +301 -0
- package/template/src/screens/home/HomeScreen.tsx +143 -1
- package/template/src/screens/home/hooks/useHomeData.ts +19 -5
- package/template/src/screens/index.tsx +1 -0
- package/template/src/screens/profile/Profile.tsx +139 -2
- package/template/src/screens/splash/Splash.tsx +44 -11
- package/template/src/sheetManager/sheets.tsx +1 -1
- package/template/tsconfig.json +14 -2
- package/template/types/globals.d.ts +43 -0
- package/template/types/index.ts +2 -6
- package/template/types/modules.d.ts +9 -0
- package/template/types/react-native-config.d.ts +0 -2
- package/.vscode/settings.json +0 -8
- package/CHANGELOG.md +0 -119
- package/CODE_OF_CONDUCT.md +0 -83
- package/CONTRIBUTING.md +0 -60
- package/local.properties +0 -1
- package/template/src/common/components/ImageCropPickerButton.tsx +0 -107
- package/template/src/common/components/PhotoTakingButton.tsx +0 -94
- package/template/src/common/helpers/imageHelpers.ts +0 -5
- package/template/src/common/helpers/inAppReviewHelper.ts +0 -30
- package/template/src/common/helpers/orientationHelpers.ts +0 -25
- package/template/src/common/helpers/shareHelpers.ts +0 -47
- package/template/src/common/utils/FeesCaalculation.tsx +0 -37
- package/template/src/common/utils/printData.tsx +0 -161
- package/template/src/common/validations/examples/TextInputWithValidation.tsx +0 -229
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {createNativeStackNavigator} from '@react-navigation/native-stack';
|
|
2
|
-
import {useTranslation} from '../common/localization/LocalizationProvider';
|
|
3
2
|
import {Login} from '../screens/Login/Login';
|
|
4
3
|
import {OTPScreen} from '../screens/OTP/OTPScreen';
|
|
5
4
|
import {Splash} from '../screens/splash/Splash';
|
|
@@ -7,8 +6,6 @@ import {Splash} from '../screens/splash/Splash';
|
|
|
7
6
|
const Stack = createNativeStackNavigator();
|
|
8
7
|
|
|
9
8
|
export function AuthStack() {
|
|
10
|
-
const t = useTranslation();
|
|
11
|
-
|
|
12
9
|
const AuthScreens = [
|
|
13
10
|
{
|
|
14
11
|
id: 'Splash',
|
|
@@ -35,7 +32,7 @@ export function AuthStack() {
|
|
|
35
32
|
|
|
36
33
|
return (
|
|
37
34
|
<Stack.Navigator
|
|
38
|
-
initialRouteName="
|
|
35
|
+
initialRouteName="Splash"
|
|
39
36
|
screenOptions={{animation: 'none'}}>
|
|
40
37
|
{AuthScreens.map(s => (
|
|
41
38
|
<Stack.Screen
|
|
@@ -20,7 +20,7 @@ export function HeaderBack({onPress}: {onPress: () => void}) {
|
|
|
20
20
|
<View style={styles.headerWithBack}>
|
|
21
21
|
<BackButton onPress={onPress} />
|
|
22
22
|
<Image source={0} style={styles.logo} />
|
|
23
|
-
<View style={
|
|
23
|
+
<View style={styles.spacer} />
|
|
24
24
|
</View>
|
|
25
25
|
);
|
|
26
26
|
}
|
|
@@ -30,13 +30,13 @@ export function HeaderButton({onPress}: {onPress: () => void}) {
|
|
|
30
30
|
<View style={styles.headerWithBack}>
|
|
31
31
|
<BackButton onPress={onPress} />
|
|
32
32
|
<View style={styles.logo} />
|
|
33
|
-
<View style={
|
|
33
|
+
<View style={styles.spacer} />
|
|
34
34
|
</View>
|
|
35
35
|
);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
export function WebViewHeader({
|
|
39
|
-
navigation,
|
|
39
|
+
navigation: _navigation,
|
|
40
40
|
}: {
|
|
41
41
|
navigation: NativeStackNavigationProp<RootStackParamList>;
|
|
42
42
|
}) {
|
|
@@ -95,6 +95,9 @@ const styles = StyleSheet.create({
|
|
|
95
95
|
position: 'absolute',
|
|
96
96
|
zIndex: 0,
|
|
97
97
|
},
|
|
98
|
+
spacer: {
|
|
99
|
+
width: 40,
|
|
100
|
+
},
|
|
98
101
|
backButton: {
|
|
99
102
|
width: 40,
|
|
100
103
|
height: 40,
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BottomTabBarProps,
|
|
3
|
+
createBottomTabNavigator,
|
|
4
|
+
} from '@react-navigation/bottom-tabs';
|
|
2
5
|
import React from 'react';
|
|
3
6
|
import {useTranslation} from '../common/localization/LocalizationProvider';
|
|
4
7
|
|
|
5
|
-
import {createNativeStackNavigator} from '@react-navigation/native-stack';
|
|
6
8
|
import {Profile} from '../screens';
|
|
9
|
+
import {ComponentsScreen} from '../screens/components/ComponentsScreen';
|
|
7
10
|
import {HomeScreen} from '../screens/home/HomeScreen';
|
|
8
11
|
import {TabBar} from './TabBar';
|
|
9
12
|
|
|
10
13
|
const Tab = createBottomTabNavigator();
|
|
11
|
-
|
|
14
|
+
|
|
15
|
+
const renderTabBar = (props: BottomTabBarProps) => <TabBar {...props} />;
|
|
12
16
|
|
|
13
17
|
export function AppMainNavigator() {
|
|
14
18
|
const t = useTranslation();
|
|
@@ -24,6 +28,16 @@ export function AppMainNavigator() {
|
|
|
24
28
|
selectedIcon: 0,
|
|
25
29
|
},
|
|
26
30
|
},
|
|
31
|
+
{
|
|
32
|
+
id: 'Components',
|
|
33
|
+
component: ComponentsScreen,
|
|
34
|
+
options: {
|
|
35
|
+
tabBarLabel: t('tabs.Components', 'mainNavigation'),
|
|
36
|
+
headerShown: false,
|
|
37
|
+
icon: 0,
|
|
38
|
+
selectedIcon: 0,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
27
41
|
{
|
|
28
42
|
id: 'Account',
|
|
29
43
|
component: Profile,
|
|
@@ -41,9 +55,7 @@ export function AppMainNavigator() {
|
|
|
41
55
|
initialRouteName="Main"
|
|
42
56
|
backBehavior="history"
|
|
43
57
|
detachInactiveScreens
|
|
44
|
-
tabBar={
|
|
45
|
-
return <TabBar {...props} />;
|
|
46
|
-
}}
|
|
58
|
+
tabBar={renderTabBar}
|
|
47
59
|
screenOptions={{
|
|
48
60
|
tabBarHideOnKeyboard: true,
|
|
49
61
|
}}>
|
|
@@ -5,23 +5,20 @@ import {RootStackParamList} from './types';
|
|
|
5
5
|
export const navigationRef = createNavigationContainerRef<RootStackParamList>();
|
|
6
6
|
|
|
7
7
|
export function navigate<T extends keyof RootStackParamList>(
|
|
8
|
-
name:
|
|
8
|
+
name: T,
|
|
9
9
|
params?: RootStackParamList[T],
|
|
10
10
|
) {
|
|
11
11
|
if (navigationRef.isReady()) {
|
|
12
|
-
|
|
13
|
-
navigationRef.current?.navigate(name, params);
|
|
12
|
+
(navigationRef.current as any)?.navigate(name as never, params as never);
|
|
14
13
|
}
|
|
15
14
|
}
|
|
16
15
|
|
|
17
|
-
//
|
|
16
|
+
// Reset the navigation stack to the main (authenticated) screen.
|
|
18
17
|
export const resetToHomeScreen = () => {
|
|
19
18
|
navigationRef.dispatch(
|
|
20
19
|
CommonActions.reset({
|
|
21
20
|
index: 0,
|
|
22
|
-
routes: [{name: '
|
|
21
|
+
routes: [{name: 'Main'}],
|
|
23
22
|
}),
|
|
24
23
|
);
|
|
25
24
|
};
|
|
26
|
-
|
|
27
|
-
// Call the function to reset the navigation stack and navigate to the "Home" screen
|
|
@@ -32,7 +32,7 @@ export function TabBar({state, descriptors, navigation}: BottomTabBarProps) {
|
|
|
32
32
|
const {theme} = useTheme();
|
|
33
33
|
const t = useTranslation();
|
|
34
34
|
const isRTL = useRTL();
|
|
35
|
-
const tabArray = ['Main', '
|
|
35
|
+
const tabArray = ['Main', 'Components', 'Account'];
|
|
36
36
|
|
|
37
37
|
// Create a copy of routes array to avoid modifying the original
|
|
38
38
|
const routesToRender = [...state.routes].filter(r =>
|
|
@@ -102,11 +102,7 @@ export function TabBar({state, descriptors, navigation}: BottomTabBarProps) {
|
|
|
102
102
|
onLongPress={onLongPress}
|
|
103
103
|
style={styles.tabButton}>
|
|
104
104
|
<Image
|
|
105
|
-
style={
|
|
106
|
-
width: scaleWidth(57),
|
|
107
|
-
height: scaleHeight(63),
|
|
108
|
-
resizeMode: 'contain',
|
|
109
|
-
}}
|
|
105
|
+
style={styles.tabIcon}
|
|
110
106
|
source={isFocused ? options.selectedIcon : options.icon}
|
|
111
107
|
/>
|
|
112
108
|
<RTLAwareText style={[theme.text.navBar]}>
|
|
@@ -139,6 +135,11 @@ const styles = StyleSheet.create({
|
|
|
139
135
|
flex: 1,
|
|
140
136
|
alignItems: 'center',
|
|
141
137
|
},
|
|
138
|
+
tabIcon: {
|
|
139
|
+
width: scaleWidth(57),
|
|
140
|
+
height: scaleHeight(63),
|
|
141
|
+
resizeMode: 'contain',
|
|
142
|
+
},
|
|
142
143
|
label: {},
|
|
143
144
|
labelFocused: {
|
|
144
145
|
color: PrimaryColors.PlatinateBlue_400,
|
|
@@ -1,35 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routes actually registered in the navigators:
|
|
3
|
+
* AuthStack → Splash, Login, OTP
|
|
4
|
+
* Main tabs → Main (Home), Account (Profile)
|
|
5
|
+
* Keep this in sync with AuthStack.tsx / MainStack.tsx when you add a screen.
|
|
6
|
+
*/
|
|
1
7
|
export type RootStackParamList = {
|
|
2
|
-
Home: undefined;
|
|
3
|
-
Details: {id: string};
|
|
4
|
-
Login: undefined;
|
|
5
|
-
Registration: undefined;
|
|
6
|
-
ForgotPassword: undefined;
|
|
7
|
-
Main: undefined;
|
|
8
|
-
Profile: undefined;
|
|
9
|
-
Settings: undefined;
|
|
10
8
|
Splash: undefined;
|
|
9
|
+
Login: undefined;
|
|
11
10
|
OTP: {phone?: string};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
InquiredBill: undefined;
|
|
16
|
-
Loading: undefined;
|
|
17
|
-
PaymentConfirmation: {
|
|
18
|
-
paymentData: {
|
|
19
|
-
amountToBePaid: string;
|
|
20
|
-
billInfo: any;
|
|
21
|
-
fees: number;
|
|
22
|
-
currencyCode: string;
|
|
23
|
-
billRec: {
|
|
24
|
-
BillingAcct: string;
|
|
25
|
-
BillerId: string;
|
|
26
|
-
BillTypeCode: number;
|
|
27
|
-
BillRefNumber: string;
|
|
28
|
-
BillStatus: string;
|
|
29
|
-
};
|
|
30
|
-
};
|
|
31
|
-
};
|
|
32
|
-
Categories: undefined;
|
|
33
|
-
Providers: {categoryID: string};
|
|
34
|
-
ReceiptScreen: {type: 'print' | 'history'; historyID?: string};
|
|
11
|
+
Main: undefined;
|
|
12
|
+
Components: undefined;
|
|
13
|
+
Account: undefined;
|
|
35
14
|
};
|
|
@@ -4,13 +4,16 @@ import React, {useRef, useState} from 'react';
|
|
|
4
4
|
import {StyleSheet} from 'react-native';
|
|
5
5
|
import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
|
|
6
6
|
import {ButtonType} from '../../../types';
|
|
7
|
+
import {AppTextInput} from '../../common/components/AppTextInput';
|
|
8
|
+
import {Chip} from '../../common/components/Chip';
|
|
7
9
|
import {Container} from '../../common/components/Container';
|
|
10
|
+
import {Logo} from '../../common/components/Logo';
|
|
8
11
|
import {PrimaryButton} from '../../common/components/PrimaryButton';
|
|
9
|
-
import {PrimaryTextInput} from '../../common/components/PrimaryTextInput';
|
|
10
12
|
import {RTLAwareText} from '../../common/components/RTLAwareText';
|
|
11
13
|
import {RTLAwareView} from '../../common/components/RTLAwareView';
|
|
14
|
+
import {Languages} from '../../common/localization/localization';
|
|
12
15
|
import {
|
|
13
|
-
|
|
16
|
+
useLocalization,
|
|
14
17
|
useTranslation,
|
|
15
18
|
} from '../../common/localization/LocalizationProvider';
|
|
16
19
|
import {phoneValidations} from '../../common/validations/authValidations';
|
|
@@ -19,7 +22,6 @@ import {useInputError} from '../../common/validations/hooks/useInputError';
|
|
|
19
22
|
import {useAppDispatch} from '../../core/store/reduxHelpers';
|
|
20
23
|
import {userLogin} from '../../core/store/user/userActions';
|
|
21
24
|
import {CommonSizes} from '../../core/theme/commonSizes';
|
|
22
|
-
import {Fonts} from '../../core/theme/fonts';
|
|
23
25
|
import {useTheme} from '../../core/theme/ThemeProvider';
|
|
24
26
|
import type {RootStackParamList} from '../../navigation/types';
|
|
25
27
|
|
|
@@ -33,7 +35,7 @@ export function Login(): JSX.Element {
|
|
|
33
35
|
const scroll = useRef<KeyboardAwareScrollView>(null);
|
|
34
36
|
const {theme} = useTheme();
|
|
35
37
|
const t = useTranslation();
|
|
36
|
-
const
|
|
38
|
+
const {currentLanguage, changeLanguage} = useLocalization();
|
|
37
39
|
|
|
38
40
|
const {error: phoneError, recheckValue: recheckPhone} = useInputError(
|
|
39
41
|
phone,
|
|
@@ -47,31 +49,27 @@ export function Login(): JSX.Element {
|
|
|
47
49
|
async function loginUser() {
|
|
48
50
|
const phoneValid = recheckPhone() === null;
|
|
49
51
|
const passwordValid = recheckPassword() === null;
|
|
50
|
-
|
|
51
52
|
if (!phoneValid || !passwordValid) {
|
|
52
53
|
return;
|
|
53
54
|
}
|
|
54
55
|
try {
|
|
55
56
|
setLoading(true);
|
|
56
|
-
const result = await dispatch(
|
|
57
|
-
userLogin({
|
|
58
|
-
phone: phone,
|
|
59
|
-
password,
|
|
60
|
-
}),
|
|
61
|
-
);
|
|
62
|
-
|
|
57
|
+
const result = await dispatch(userLogin({phone, password}));
|
|
63
58
|
if (userLogin.fulfilled.match(result)) {
|
|
64
|
-
navigation.navigate('OTP', {phone
|
|
59
|
+
navigation.navigate('OTP', {phone});
|
|
65
60
|
}
|
|
66
|
-
} catch
|
|
61
|
+
} catch {
|
|
67
62
|
} finally {
|
|
68
63
|
setLoading(false);
|
|
69
64
|
}
|
|
70
65
|
}
|
|
71
66
|
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
67
|
+
const toggleLanguage = () =>
|
|
68
|
+
changeLanguage(
|
|
69
|
+
currentLanguage === Languages.ar ? Languages.en : Languages.ar,
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const descriptionColor = {color: theme.colors.grayScale_200};
|
|
75
73
|
|
|
76
74
|
return (
|
|
77
75
|
<Container
|
|
@@ -83,41 +81,52 @@ export function Login(): JSX.Element {
|
|
|
83
81
|
withoutPadding
|
|
84
82
|
extendedBackground
|
|
85
83
|
backgroundColor={theme.colors.background_2}>
|
|
86
|
-
<
|
|
87
|
-
|
|
84
|
+
<RTLAwareView style={styles.topRow}>
|
|
85
|
+
<Chip
|
|
86
|
+
label={currentLanguage === Languages.ar ? 'العربية' : 'English'}
|
|
87
|
+
onPress={toggleLanguage}
|
|
88
|
+
/>
|
|
89
|
+
</RTLAwareView>
|
|
90
|
+
<RTLAwareView style={styles.logoWrap}>
|
|
91
|
+
<Logo size={72} variant="gradient" />
|
|
92
|
+
</RTLAwareView>
|
|
93
|
+
<RTLAwareText style={[theme.text.header3, styles.center]}>
|
|
88
94
|
{t('welcome', 'login')}
|
|
89
95
|
</RTLAwareText>
|
|
90
|
-
<
|
|
96
|
+
<RTLAwareText
|
|
97
|
+
style={[theme.text.bodyMediumRegular, styles.center, descriptionColor]}>
|
|
98
|
+
{t('welcome_description', 'login')}
|
|
99
|
+
</RTLAwareText>
|
|
100
|
+
<AppTextInput
|
|
101
|
+
label={t('phoneOrEmail', 'login')}
|
|
91
102
|
value={phone}
|
|
92
103
|
onChangeText={setPhone}
|
|
93
104
|
error={phoneError}
|
|
94
105
|
keyboardType="numeric"
|
|
95
106
|
placeholder={t('EnterPhone', 'login')}
|
|
96
107
|
/>
|
|
97
|
-
<
|
|
108
|
+
<AppTextInput
|
|
109
|
+
label={t('Password', 'login')}
|
|
98
110
|
value={password}
|
|
99
111
|
onChangeText={setPassword}
|
|
100
112
|
error={passwordError}
|
|
101
|
-
secureTextEntry
|
|
102
|
-
keyboardType="numeric"
|
|
113
|
+
secureTextEntry
|
|
103
114
|
placeholder={t('EnterPassword', 'login')}
|
|
104
115
|
/>
|
|
105
|
-
|
|
106
|
-
<RTLAwareView
|
|
107
|
-
style={{width: '100%', alignItems: isRTL ? 'flex-start' : 'flex-end'}}>
|
|
108
|
-
<PrimaryButton
|
|
109
|
-
label={t('forgetPassword', 'login')}
|
|
110
|
-
onPressIn={goToForgotPassword}
|
|
111
|
-
type={ButtonType.borderless}
|
|
112
|
-
/>
|
|
113
|
-
</RTLAwareView>
|
|
114
116
|
<PrimaryButton
|
|
115
|
-
label={t('
|
|
117
|
+
label={t('signIn', 'login')}
|
|
116
118
|
onPressIn={loginUser}
|
|
117
119
|
isLoading={loading}
|
|
118
120
|
disabled={loading}
|
|
119
121
|
type={ButtonType.solid}
|
|
120
122
|
/>
|
|
123
|
+
<RTLAwareView style={styles.helpWrap}>
|
|
124
|
+
<PrimaryButton
|
|
125
|
+
label={t('needHelp', 'login')}
|
|
126
|
+
type={ButtonType.borderless}
|
|
127
|
+
onPressIn={() => {}}
|
|
128
|
+
/>
|
|
129
|
+
</RTLAwareView>
|
|
121
130
|
</Container>
|
|
122
131
|
);
|
|
123
132
|
}
|
|
@@ -131,18 +140,9 @@ const styles = StyleSheet.create({
|
|
|
131
140
|
gap: CommonSizes.spacing.xl,
|
|
132
141
|
justifyContent: 'flex-start',
|
|
133
142
|
},
|
|
134
|
-
contentContainer: {
|
|
135
|
-
|
|
136
|
-
},
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
paddingHorizontal: CommonSizes.spacing.large,
|
|
140
|
-
gap: CommonSizes.spacing.large,
|
|
141
|
-
},
|
|
142
|
-
title: {
|
|
143
|
-
textAlign: 'center',
|
|
144
|
-
fontSize: CommonSizes.font.bodyLarge,
|
|
145
|
-
fontWeight: 'bold',
|
|
146
|
-
fontFamily: Fonts.regular,
|
|
147
|
-
},
|
|
143
|
+
contentContainer: {flexGrow: 1},
|
|
144
|
+
center: {textAlign: 'center'},
|
|
145
|
+
topRow: {flexDirection: 'row', justifyContent: 'flex-end'},
|
|
146
|
+
logoWrap: {alignItems: 'center'},
|
|
147
|
+
helpWrap: {alignItems: 'center'},
|
|
148
148
|
});
|
|
@@ -9,10 +9,7 @@ import {OTPInput} from '../../common/components/OTPInput';
|
|
|
9
9
|
import {PrimaryButton} from '../../common/components/PrimaryButton';
|
|
10
10
|
import {RTLAwareText} from '../../common/components/RTLAwareText';
|
|
11
11
|
import {RTLAwareView} from '../../common/components/RTLAwareView';
|
|
12
|
-
import {
|
|
13
|
-
useRTL,
|
|
14
|
-
useTranslation,
|
|
15
|
-
} from '../../common/localization/LocalizationProvider';
|
|
12
|
+
import {useTranslation} from '../../common/localization/LocalizationProvider';
|
|
16
13
|
import {useInputError} from '../../common/validations/hooks/useInputError';
|
|
17
14
|
import {useAppDispatch} from '../../core/store/reduxHelpers';
|
|
18
15
|
import {verifyOTP} from '../../core/store/user/userActions';
|
|
@@ -34,7 +31,6 @@ export function OTPScreen(): JSX.Element {
|
|
|
34
31
|
const {theme} = useTheme();
|
|
35
32
|
const {phone} = route.params as {phone: string};
|
|
36
33
|
const t = useTranslation();
|
|
37
|
-
const isRTL = useRTL();
|
|
38
34
|
|
|
39
35
|
const {error: otpError, recheckValue: recheckOTP} = useInputError(
|
|
40
36
|
otp,
|
|
@@ -51,7 +47,7 @@ export function OTPScreen(): JSX.Element {
|
|
|
51
47
|
try {
|
|
52
48
|
setLoading(true);
|
|
53
49
|
|
|
54
|
-
|
|
50
|
+
await dispatch(
|
|
55
51
|
verifyOTP({
|
|
56
52
|
verification_code: otp?.toString(),
|
|
57
53
|
mobile_number: phone,
|
|
@@ -59,7 +55,7 @@ export function OTPScreen(): JSX.Element {
|
|
|
59
55
|
scheme_id: 1,
|
|
60
56
|
}),
|
|
61
57
|
);
|
|
62
|
-
} catch
|
|
58
|
+
} catch {
|
|
63
59
|
} finally {
|
|
64
60
|
setLoading(false);
|
|
65
61
|
}
|
|
@@ -97,10 +93,10 @@ export function OTPScreen(): JSX.Element {
|
|
|
97
93
|
extendedBackground
|
|
98
94
|
backgroundColor={theme.colors.background_2}>
|
|
99
95
|
<HeaderBack onPress={() => navigation.goBack()} />
|
|
100
|
-
<RTLAwareText style={
|
|
96
|
+
<RTLAwareText style={[theme.text.header1, styles.center]}>
|
|
101
97
|
{t('title', 'otp')}
|
|
102
98
|
</RTLAwareText>
|
|
103
|
-
<RTLAwareText style={
|
|
99
|
+
<RTLAwareText style={[theme.text.body2, styles.center]}>
|
|
104
100
|
{t('subtitle', 'otp')}
|
|
105
101
|
</RTLAwareText>
|
|
106
102
|
<View style={styles.inputContainer}>
|
|
@@ -148,6 +144,7 @@ const styles = StyleSheet.create({
|
|
|
148
144
|
contentContainer: {
|
|
149
145
|
flexGrow: 1,
|
|
150
146
|
},
|
|
147
|
+
center: {textAlign: 'center'},
|
|
151
148
|
inputContainer: {
|
|
152
149
|
width: '100%',
|
|
153
150
|
marginTop: CommonSizes.spacing.large,
|