@fadyshawky/react-native-magic 2.0.4 → 2.0.5

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.
Files changed (110) hide show
  1. package/package.json +1 -1
  2. package/template/src/common/ImageResources.g.ts +33 -1
  3. package/template/src/common/components/Background.tsx +3 -1
  4. package/template/src/common/components/Container.tsx +1 -1
  5. package/template/src/common/components/OTPInput.tsx +3 -2
  6. package/template/src/common/components/PrimaryButton.tsx +23 -23
  7. package/template/src/common/components/PrimaryTextInput.tsx +189 -199
  8. package/template/src/common/components/RadioIcon.tsx +4 -4
  9. package/template/src/common/components/SafeText.tsx +41 -0
  10. package/template/src/common/components/SearchBar.tsx +19 -17
  11. package/template/src/common/components/TryAgain.tsx +3 -3
  12. package/template/src/common/localization/localization.ts +10 -0
  13. package/template/src/common/localization/translations/commonLocalization.ts +97 -0
  14. package/template/src/common/localization/translations/homeLocalization.ts +24 -0
  15. package/template/src/common/localization/translations/loginLocalization.ts +28 -2
  16. package/template/src/common/localization/translations/mainNavigationLocalization.ts +30 -0
  17. package/template/src/common/localization/translations/navigationLocalization.ts +48 -0
  18. package/template/src/common/localization/translations/otpLocalization.ts +28 -0
  19. package/template/src/common/localization/translations/passwordLocalization.ts +54 -0
  20. package/template/src/common/localization/translations/posLocalization.ts +196 -0
  21. package/template/src/common/utils/FeesCaalculation.tsx +37 -0
  22. package/template/src/common/utils/index.tsx +11 -0
  23. package/template/src/common/utils/printData.tsx +161 -0
  24. package/template/src/common/validations/errorValidations.ts +3 -2
  25. package/template/src/components/PrinterExample.js +226 -0
  26. package/template/src/core/api/serverHeaders.ts +62 -1
  27. package/template/src/core/store/Categories/categoryActions.ts +33 -0
  28. package/template/src/core/store/Categories/categorySlice.ts +75 -0
  29. package/template/src/core/store/Categories/categoryState.ts +41 -0
  30. package/template/src/core/store/Providers/providersActions.ts +102 -0
  31. package/template/src/core/store/Providers/providersSlice.ts +136 -0
  32. package/template/src/core/store/Providers/providersState.ts +37 -0
  33. package/template/src/core/store/Services/servicesActions.ts +191 -0
  34. package/template/src/core/store/Services/servicesSlice.ts +205 -0
  35. package/template/src/core/store/Services/servicesState.ts +466 -0
  36. package/template/src/core/store/app/appSlice.ts +13 -5
  37. package/template/src/core/store/app/appState.ts +10 -2
  38. package/template/src/core/store/rootReducer.ts +6 -1
  39. package/template/src/core/store/store.tsx +55 -2
  40. package/template/src/core/store/user/userActions.ts +164 -26
  41. package/template/src/core/store/user/userSlice.ts +193 -21
  42. package/template/src/core/store/user/userState.ts +148 -25
  43. package/template/src/core/theme/colors.ts +70 -94
  44. package/template/src/core/theme/commonConsts.ts +1 -1
  45. package/template/src/core/theme/commonSizes.ts +94 -119
  46. package/template/src/core/theme/commonStyles.ts +22 -22
  47. package/template/src/core/theme/fonts.ts +14 -13
  48. package/template/src/core/theme/themes.ts +75 -386
  49. package/template/src/core/theme/types.ts +15 -201
  50. package/template/src/core/utils/stringUtils.ts +114 -0
  51. package/template/src/modules/SunmiCard.js +212 -0
  52. package/template/src/modules/SunmiPrepaid.ts +122 -0
  53. package/template/src/navigation/AuthStack.tsx +8 -0
  54. package/template/src/navigation/HeaderComponents.tsx +76 -1
  55. package/template/src/navigation/MainNavigation.tsx +3 -1
  56. package/template/src/navigation/MainStack.tsx +130 -56
  57. package/template/src/navigation/TabBar.tsx +111 -59
  58. package/template/src/navigation/types.ts +24 -0
  59. package/template/src/screens/Categories/Categories.tsx +141 -0
  60. package/template/src/screens/Categories/hooks/useCategoriesData.ts +33 -0
  61. package/template/src/screens/Categories/types.ts +7 -0
  62. package/template/src/screens/Favorites/Favorites.tsx +130 -0
  63. package/template/src/screens/ForceChangePassword/ForceChangePasswordScreen.tsx +155 -0
  64. package/template/src/screens/History/History.tsx +430 -0
  65. package/template/src/screens/History/hooks/useHistoryData.ts +49 -0
  66. package/template/src/screens/History/types.ts +7 -0
  67. package/template/src/screens/InquiredBill/InquiredBill.tsx +443 -0
  68. package/template/src/screens/InquiredBill/hooks/useInquiredData.ts +91 -0
  69. package/template/src/screens/Login/Login.tsx +85 -85
  70. package/template/src/screens/OTP/OTPScreen.tsx +170 -0
  71. package/template/src/screens/PaymentConfirmation/PaymentConfirmation.tsx +326 -0
  72. package/template/src/screens/Providers/Providers.tsx +166 -0
  73. package/template/src/screens/Providers/hooks/useProvidersData.ts +33 -0
  74. package/template/src/screens/Providers/types.ts +7 -0
  75. package/template/src/screens/ReceiptScreen/ReceiptScreen.tsx +181 -0
  76. package/template/src/screens/ReceiptScreen/hooks/useReceiptData.ts +46 -0
  77. package/template/src/screens/ReceiptScreen/utils/utils.tsx +156 -0
  78. package/template/src/screens/Services/Services.tsx +144 -0
  79. package/template/src/screens/Services/hooks/useServicesData.ts +41 -0
  80. package/template/src/screens/SingleService/Components/FawryInputs.tsx +446 -0
  81. package/template/src/screens/SingleService/SingleService.tsx +229 -0
  82. package/template/src/screens/SingleService/hooks/useServiceData.ts +164 -0
  83. package/template/src/screens/home/Components/PayByCode.tsx +129 -0
  84. package/template/src/screens/home/HomeScreen.tsx +268 -77
  85. package/template/src/screens/home/hooks/useHomeData.ts +32 -38
  86. package/template/src/screens/index.tsx +24 -0
  87. package/template/src/screens/profile/Profile.tsx +290 -2
  88. package/template/src/services/SunmiPrinterInternal.js +268 -0
  89. package/template/src/types/sunmiPrepaid.d.ts +20 -0
  90. package/template/src/utils/SunmiPrinter.ts +442 -0
  91. package/template/src/utils/feesCalculator.ts +92 -0
  92. package/template/src/common/components/Stepper.tsx +0 -153
  93. package/template/src/common/components/Svg.tsx +0 -25
  94. package/template/src/common/hooks/useDebounce.ts +0 -17
  95. package/template/src/common/hooks/usePrevious.ts +0 -11
  96. package/template/src/common/localization/intlFormatter.ts +0 -37
  97. package/template/src/common/urls/emailUrl.ts +0 -20
  98. package/template/src/common/urls/mapUrl.ts +0 -22
  99. package/template/src/common/utils/listHandlers.ts +0 -30
  100. package/template/src/common/utils/serializeQueryParams.ts +0 -10
  101. package/template/src/common/validations/hooks/useDatesError.ts +0 -40
  102. package/template/src/common/validations/profileValidations.ts +0 -30
  103. package/template/src/core/theme/shadows.ts +0 -135
  104. package/template/src/navigation/TopTabBar.tsx +0 -77
  105. package/template/src/screens/Settings/Settings.tsx +0 -5
  106. package/template/src/screens/home/components/CarouselSection.tsx +0 -79
  107. package/template/src/screens/home/components/FeaturedCarousel.tsx +0 -128
  108. package/template/src/screens/main/Main.tsx +0 -5
  109. package/template/src/screens/registration/RegistrationScreen.tsx +0 -198
  110. package/template/src/screens/resetPassword/ForgotPasswordScreen.tsx +0 -129
@@ -1,79 +0,0 @@
1
- import React from 'react';
2
- import {
3
- Image,
4
- ImageStyle,
5
- ScrollView,
6
- StyleSheet,
7
- Text,
8
- TouchableOpacity,
9
- View,
10
- } from 'react-native';
11
- import {CommonSizes} from '../../../core/theme/commonSizes';
12
- import {CarouselItem} from '../types';
13
- import {PrimaryColors} from '../../../core/theme/colors';
14
-
15
- interface CarouselSectionProps {
16
- items: CarouselItem[];
17
- imageStyle?: ImageStyle;
18
- }
19
-
20
- export function CarouselSection({
21
- items,
22
- imageStyle,
23
- }: CarouselSectionProps): JSX.Element {
24
- return (
25
- <ScrollView
26
- horizontal
27
- showsHorizontalScrollIndicator={false}
28
- contentContainerStyle={styles.container}>
29
- {items.map((item, index) => (
30
- <TouchableOpacity
31
- key={item.id}
32
- style={styles.itemContainer}
33
- onPress={() => item.onPress?.(item)}>
34
- <Image
35
- source={{uri: item.imageUrl}}
36
- style={[styles.image, imageStyle]}
37
- />
38
- <View style={styles.textContainer}>
39
- <Text style={styles.title} numberOfLines={1}>
40
- {item.title}
41
- </Text>
42
- {item.subtitle && (
43
- <Text style={styles.subtitle} numberOfLines={1}>
44
- {item.subtitle}
45
- </Text>
46
- )}
47
- </View>
48
- </TouchableOpacity>
49
- ))}
50
- </ScrollView>
51
- );
52
- }
53
-
54
- const styles = StyleSheet.create({
55
- container: {
56
- paddingHorizontal: CommonSizes.spacing.large,
57
- },
58
- itemContainer: {
59
- marginRight: CommonSizes.spacing.medium,
60
- },
61
- image: {
62
- width: 200,
63
- height: 150,
64
- borderRadius: CommonSizes.borderRadius.medium,
65
- },
66
- textContainer: {
67
- marginTop: CommonSizes.spacing.small,
68
- },
69
- title: {
70
- fontSize: 16,
71
- fontWeight: '600',
72
- color: PrimaryColors.PlatinateBlue_700,
73
- },
74
- subtitle: {
75
- fontSize: 14,
76
- color: PrimaryColors.PlatinateBlue_700,
77
- marginTop: 2,
78
- },
79
- });
@@ -1,128 +0,0 @@
1
- import React, {useRef, useState} from 'react';
2
- import {
3
- Dimensions,
4
- FlatList,
5
- Image,
6
- StyleSheet,
7
- Text,
8
- TouchableOpacity,
9
- View,
10
- } from 'react-native';
11
- import {CommonSizes} from '../../../core/theme/commonSizes';
12
- import {CarouselItem} from '../types';
13
- import {NaturalColors, PrimaryColors} from '../../../core/theme/colors';
14
-
15
- const {width} = Dimensions.get('window');
16
- const ITEM_WIDTH = width * 0.85;
17
-
18
- interface FeaturedCarouselProps {
19
- items: CarouselItem[];
20
- }
21
-
22
- export function FeaturedCarousel({items}: FeaturedCarouselProps): JSX.Element {
23
- const [activeIndex, setActiveIndex] = useState(0);
24
- const flatListRef = useRef<FlatList>(null);
25
-
26
- const renderItem = ({item}: {item: CarouselItem}) => (
27
- <TouchableOpacity
28
- style={styles.itemContainer}
29
- onPress={() => item.onPress?.(item)}>
30
- <Image source={{uri: item.imageUrl}} style={styles.image} />
31
- <View style={styles.overlay}>
32
- <Text style={styles.title}>{item.title}</Text>
33
- {item.subtitle && <Text style={styles.subtitle}>{item.subtitle}</Text>}
34
- </View>
35
- </TouchableOpacity>
36
- );
37
-
38
- const renderDot = (index: number) => (
39
- <View
40
- key={index}
41
- style={[styles.dot, index === activeIndex && styles.activeDot]}
42
- />
43
- );
44
-
45
- const handleScroll = (event: any) => {
46
- const slideSize = event.nativeEvent.layoutMeasurement.width;
47
- const index = event.nativeEvent.contentOffset.x / slideSize;
48
- const roundIndex = Math.round(index);
49
- setActiveIndex(roundIndex);
50
- };
51
-
52
- return (
53
- <View>
54
- <FlatList
55
- ref={flatListRef}
56
- data={items}
57
- renderItem={renderItem}
58
- horizontal
59
- pagingEnabled
60
- showsHorizontalScrollIndicator={false}
61
- onScroll={handleScroll}
62
- snapToAlignment="center"
63
- decelerationRate="fast"
64
- snapToInterval={ITEM_WIDTH}
65
- contentContainerStyle={styles.listContainer}
66
- getItemLayout={(_, index) => ({
67
- length: ITEM_WIDTH,
68
- offset: ITEM_WIDTH * index,
69
- index,
70
- })}
71
- />
72
- <View style={styles.pagination}>
73
- {items.map((_, index) => renderDot(index))}
74
- </View>
75
- </View>
76
- );
77
- }
78
-
79
- const styles = StyleSheet.create({
80
- listContainer: {
81
- paddingHorizontal: (width - ITEM_WIDTH) / 2,
82
- },
83
- itemContainer: {
84
- width: ITEM_WIDTH,
85
- height: 250,
86
- },
87
- image: {
88
- width: '100%',
89
- height: '100%',
90
- borderRadius: CommonSizes.borderRadius.large,
91
- },
92
- overlay: {
93
- ...StyleSheet.absoluteFillObject,
94
- backgroundColor: 'rgba(0, 0, 0, 0.3)',
95
- borderRadius: CommonSizes.borderRadius.large,
96
- padding: CommonSizes.spacing.large,
97
- justifyContent: 'flex-end',
98
- },
99
- title: {
100
- fontSize: 20,
101
- fontWeight: '600',
102
- color: NaturalColors.grayScale_0,
103
- },
104
- subtitle: {
105
- fontSize: 16,
106
- color: NaturalColors.grayScale_0,
107
- marginTop: CommonSizes.spacing.small,
108
- },
109
- pagination: {
110
- flexDirection: 'row',
111
- justifyContent: 'center',
112
- alignItems: 'center',
113
- marginTop: CommonSizes.spacing.medium,
114
- },
115
- dot: {
116
- width: 8,
117
- height: 8,
118
- borderRadius: 4,
119
- backgroundColor: NaturalColors.grayScale_50,
120
- marginHorizontal: 4,
121
- },
122
- activeDot: {
123
- backgroundColor: PrimaryColors.PlatinateBlue_700,
124
- width: 12,
125
- height: 12,
126
- borderRadius: 6,
127
- },
128
- });
@@ -1,5 +0,0 @@
1
- import React from 'react';
2
-
3
- export function Main(): JSX.Element {
4
- return <></>;
5
- }
@@ -1,198 +0,0 @@
1
- import {useNavigation} from '@react-navigation/native';
2
- import type {NativeStackNavigationProp} from '@react-navigation/native-stack';
3
- import React, {useRef, useState} from 'react';
4
- import {
5
- NativeSyntheticEvent,
6
- StyleSheet,
7
- Text,
8
- TextInputFocusEventData,
9
- findNodeHandle,
10
- } from 'react-native';
11
- import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
12
- import {ButtonType} from '../../../types';
13
- import {PrimaryButton} from '../../common/components/PrimaryButton';
14
- import {PrimaryTextInput} from '../../common/components/PrimaryTextInput';
15
- import {localization} from '../../common/localization/localization';
16
- import {emptyValidation} from '../../common/validations/commonValidations';
17
- import {useInputError} from '../../common/validations/hooks/useInputError';
18
- import {
19
- emailValidations,
20
- fullNameValidations,
21
- } from '../../common/validations/profileValidations';
22
- import {useAppDispatch} from '../../core/store/reduxHelpers';
23
- import {userRegister} from '../../core/store/user/userActions';
24
- import {CommonSizes} from '../../core/theme/commonSizes';
25
- import {CommonStyles} from '../../core/theme/commonStyles';
26
- import type {RootStackParamList} from '../../navigation/types';
27
- import {NaturalColors, PrimaryColors} from '../../core/theme/colors';
28
-
29
- export default function RegistrationScreen(): JSX.Element {
30
- const dispatch = useAppDispatch();
31
- const navigation =
32
- useNavigation<NativeStackNavigationProp<RootStackParamList>>();
33
- const [loading, setLoading] = useState(false);
34
- const [formData, setFormData] = useState({
35
- fullName: '',
36
- email: '',
37
- password: '',
38
- confirmPassword: '',
39
- });
40
-
41
- const scroll = useRef<KeyboardAwareScrollView>(null);
42
-
43
- // Add validation hooks
44
- const {error: fullNameError, recheckValue: recheckFullName} = useInputError(
45
- formData.fullName,
46
- fullNameValidations,
47
- );
48
- const {error: emailError, recheckValue: recheckEmail} = useInputError(
49
- formData.email,
50
- emailValidations,
51
- );
52
- const {error: passwordError, recheckValue: recheckPassword} = useInputError(
53
- formData.password,
54
- emptyValidation,
55
- );
56
- const {error: confirmPasswordError, recheckValue: recheckConfirmPassword} =
57
- useInputError(formData.confirmPassword, emptyValidation);
58
-
59
- function scrollToInput(reactNode: any) {
60
- scroll.current?.scrollToFocusedInput(reactNode);
61
- }
62
-
63
- async function handleRegistration() {
64
- // Validate all fields
65
- const isFullNameValid = recheckFullName() === null;
66
- const isEmailValid = recheckEmail() === null;
67
- const isPasswordValid = recheckPassword() === null;
68
- const isConfirmPasswordValid = recheckConfirmPassword() === null;
69
-
70
- if (
71
- !isFullNameValid ||
72
- !isEmailValid ||
73
- !isPasswordValid ||
74
- !isConfirmPasswordValid
75
- ) {
76
- return;
77
- }
78
-
79
- if (formData.password !== formData.confirmPassword) {
80
- // Add error handling for password mismatch
81
- return;
82
- }
83
-
84
- setLoading(true);
85
- await dispatch(
86
- userRegister({
87
- fullName: formData.fullName,
88
- email: formData.email.toLowerCase(),
89
- password: formData.password,
90
- }),
91
- );
92
- setLoading(false);
93
- }
94
-
95
- const goToLogin = () => {
96
- navigation.navigate('Login');
97
- };
98
-
99
- return (
100
- <KeyboardAwareScrollView
101
- ref={scroll}
102
- resetScrollToCoords={{x: 0, y: 0}}
103
- scrollEnabled={true}
104
- enableOnAndroid={true}
105
- contentContainerStyle={styles.contentContainer}
106
- contentInsetAdjustmentBehavior={'automatic'}
107
- style={styles.container}>
108
- <Text style={CommonStyles.h1_semiBold}>
109
- {localization.login.registration.title}
110
- </Text>
111
-
112
- <PrimaryTextInput
113
- onFocus={(event: NativeSyntheticEvent<TextInputFocusEventData>) => {
114
- scrollToInput(findNodeHandle(event.target));
115
- }}
116
- value={formData.fullName}
117
- onChangeText={text => setFormData({...formData, fullName: text})}
118
- containerStyle={CommonStyles.textInputContainer}
119
- label={localization.login.registration.fullName}
120
- placeholder={localization.login.registration.fullName}
121
- error={fullNameError}
122
- />
123
-
124
- <PrimaryTextInput
125
- onFocus={(event: NativeSyntheticEvent<TextInputFocusEventData>) => {
126
- scrollToInput(findNodeHandle(event.target));
127
- }}
128
- autoCapitalize="none"
129
- value={formData.email}
130
- onChangeText={text => setFormData({...formData, email: text})}
131
- containerStyle={CommonStyles.textInputContainer}
132
- label={localization.login.registration.email}
133
- placeholder={localization.login.EnterEmail}
134
- error={emailError}
135
- />
136
-
137
- <PrimaryTextInput
138
- onFocus={(event: NativeSyntheticEvent<TextInputFocusEventData>) => {
139
- scrollToInput(findNodeHandle(event.target));
140
- }}
141
- secureTextEntry
142
- value={formData.password}
143
- onChangeText={text => setFormData({...formData, password: text})}
144
- containerStyle={CommonStyles.textInputContainer}
145
- label={localization.login.registration.password}
146
- placeholder={localization.login.EnterPassword}
147
- error={passwordError}
148
- />
149
-
150
- <PrimaryTextInput
151
- onFocus={(event: NativeSyntheticEvent<TextInputFocusEventData>) => {
152
- scrollToInput(findNodeHandle(event.target));
153
- }}
154
- secureTextEntry
155
- value={formData.confirmPassword}
156
- onChangeText={text => setFormData({...formData, confirmPassword: text})}
157
- containerStyle={CommonStyles.textInputContainer}
158
- label={localization.login.registration.confirmPassword}
159
- placeholder={localization.login.registration.confirmPassword}
160
- error={confirmPasswordError}
161
- />
162
-
163
- <PrimaryButton
164
- isLoading={loading}
165
- onPress={handleRegistration}
166
- label={localization.login.registration.register}
167
- type={ButtonType.solid}
168
- />
169
- <PrimaryButton
170
- onPress={goToLogin}
171
- label={localization.login.registration.alreadyHaveAccount}
172
- type={ButtonType.borderless}
173
- />
174
- </KeyboardAwareScrollView>
175
- );
176
- }
177
-
178
- const styles = StyleSheet.create({
179
- container: {
180
- flexGrow: 1,
181
- backgroundColor: NaturalColors.grayScale_0,
182
- borderTopRightRadius: CommonSizes.spacing.large,
183
- borderTopLeftRadius: CommonSizes.spacing.large,
184
- },
185
- contentContainer: {
186
- justifyContent: 'center',
187
- alignItems: 'center',
188
- paddingHorizontal: CommonSizes.spacing.large,
189
- paddingVertical: 26,
190
- gap: 16,
191
- },
192
- loginLink: {
193
- ...CommonStyles.normalText,
194
- color: PrimaryColors.PlatinateBlue_700,
195
- textAlign: 'center',
196
- marginTop: 16,
197
- },
198
- });
@@ -1,129 +0,0 @@
1
- import {useNavigation} from '@react-navigation/native';
2
- import type {NativeStackNavigationProp} from '@react-navigation/native-stack';
3
- import React, {useRef, useState} from 'react';
4
- import {
5
- NativeSyntheticEvent,
6
- StyleSheet,
7
- Text,
8
- TextInputFocusEventData,
9
- findNodeHandle,
10
- } from 'react-native';
11
- import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
12
- import {ButtonType} from '../../../types';
13
- import {PrimaryButton} from '../../common/components/PrimaryButton';
14
- import {PrimaryTextInput} from '../../common/components/PrimaryTextInput';
15
- import {localization} from '../../common/localization/localization';
16
- import {useInputError} from '../../common/validations/hooks/useInputError';
17
- import {emailValidations} from '../../common/validations/profileValidations';
18
- import {useAppDispatch} from '../../core/store/reduxHelpers';
19
- import {resetPassword} from '../../core/store/user/userActions';
20
- import {CommonSizes} from '../../core/theme/commonSizes';
21
- import {CommonStyles} from '../../core/theme/commonStyles';
22
- import type {RootStackParamList} from '../../navigation/types';
23
- import {NaturalColors, PrimaryColors} from '../../core/theme/colors';
24
-
25
- export default function ForgotPasswordScreen(): JSX.Element {
26
- const dispatch = useAppDispatch();
27
- const navigation =
28
- useNavigation<NativeStackNavigationProp<RootStackParamList>>();
29
- const [email, setEmail] = useState('');
30
- const [loading, setLoading] = useState(false);
31
-
32
- const scroll = useRef<KeyboardAwareScrollView>(null);
33
-
34
- const {error: emailError, recheckValue: recheckEmail} = useInputError(
35
- email,
36
- emailValidations,
37
- );
38
-
39
- function scrollToInput(reactNode: any) {
40
- scroll.current?.scrollToFocusedInput(reactNode);
41
- }
42
-
43
- async function handleResetPassword() {
44
- const isEmailValid = recheckEmail() === null;
45
- if (!isEmailValid) {
46
- return;
47
- }
48
-
49
- setLoading(true);
50
- await dispatch(resetPassword({email: email.toLowerCase()}));
51
- setLoading(false);
52
- }
53
-
54
- const goToLogin = () => {
55
- navigation.navigate('Login');
56
- };
57
-
58
- return (
59
- <KeyboardAwareScrollView
60
- ref={scroll}
61
- resetScrollToCoords={{x: 0, y: 0}}
62
- scrollEnabled={true}
63
- enableOnAndroid={true}
64
- contentContainerStyle={styles.contentContainer}
65
- contentInsetAdjustmentBehavior={'automatic'}
66
- style={styles.container}>
67
- <Text style={CommonStyles.h1_semiBold}>
68
- {localization.login.forgotPassword.title}
69
- </Text>
70
-
71
- <Text style={styles.description}>
72
- {localization.login.forgotPassword.description}
73
- </Text>
74
-
75
- <PrimaryTextInput
76
- onFocus={(event: NativeSyntheticEvent<TextInputFocusEventData>) => {
77
- scrollToInput(findNodeHandle(event.target));
78
- }}
79
- autoCapitalize="none"
80
- value={email}
81
- onChangeText={setEmail}
82
- containerStyle={CommonStyles.textInputContainer}
83
- label={localization.login.Email}
84
- placeholder={localization.login.EnterEmail}
85
- error={emailError}
86
- />
87
-
88
- <PrimaryButton
89
- isLoading={loading}
90
- onPress={handleResetPassword}
91
- label={localization.login.forgotPassword.resetPassword}
92
- type={ButtonType.solid}
93
- />
94
-
95
- <PrimaryButton
96
- onPress={goToLogin}
97
- label={localization.login.forgotPassword.backToLogin}
98
- type={ButtonType.borderless}
99
- />
100
- </KeyboardAwareScrollView>
101
- );
102
- }
103
-
104
- const styles = StyleSheet.create({
105
- container: {
106
- flexGrow: 1,
107
- backgroundColor: NaturalColors.grayScale_0,
108
- borderTopRightRadius: CommonSizes.spacing.large,
109
- borderTopLeftRadius: CommonSizes.spacing.large,
110
- },
111
- contentContainer: {
112
- justifyContent: 'center',
113
- alignItems: 'center',
114
- paddingHorizontal: CommonSizes.spacing.large,
115
- paddingVertical: 26,
116
- gap: 16,
117
- },
118
- description: {
119
- ...CommonStyles.normalText,
120
- textAlign: 'center',
121
- marginBottom: 8,
122
- },
123
- loginLink: {
124
- ...CommonStyles.normalText,
125
- color: PrimaryColors.PlatinateBlue_700,
126
- textAlign: 'center',
127
- marginTop: 16,
128
- },
129
- });