@fadyshawky/react-native-magic 2.0.4 → 2.0.6

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 (80) hide show
  1. package/package.json +1 -1
  2. package/template/App.tsx +28 -19
  3. package/template/ios/reactnativemagic/AppDelegate.mm +5 -0
  4. package/template/src/common/components/Background.tsx +6 -4
  5. package/template/src/common/components/Container.tsx +6 -9
  6. package/template/src/common/components/OTPInput.tsx +3 -2
  7. package/template/src/common/components/PrimaryButton.tsx +23 -23
  8. package/template/src/common/components/PrimaryTextInput.tsx +189 -199
  9. package/template/src/common/components/RadioIcon.tsx +4 -4
  10. package/template/src/common/components/SafeText.tsx +41 -0
  11. package/template/src/common/components/SearchBar.tsx +19 -17
  12. package/template/src/common/components/TryAgain.tsx +3 -3
  13. package/template/src/common/localization/LocalizationProvider.tsx +14 -17
  14. package/template/src/common/localization/RTLInitializer.tsx +90 -0
  15. package/template/src/common/localization/localization.ts +8 -0
  16. package/template/src/common/localization/translations/commonLocalization.ts +33 -6
  17. package/template/src/common/localization/translations/emptyLocalization.ts +6 -2
  18. package/template/src/common/localization/translations/errorsLocalization.ts +33 -13
  19. package/template/src/common/localization/translations/homeLocalization.ts +6 -2
  20. package/template/src/common/localization/translations/loginLocalization.ts +32 -9
  21. package/template/src/common/localization/translations/mainNavigationLocalization.ts +30 -0
  22. package/template/src/common/localization/translations/navigationLocalization.ts +48 -0
  23. package/template/src/common/localization/translations/onboardingLocalization.ts +40 -9
  24. package/template/src/common/localization/translations/otpLocalization.ts +28 -0
  25. package/template/src/common/localization/translations/pagesLocalization.ts +13 -1
  26. package/template/src/common/localization/translations/passwordLocalization.ts +54 -0
  27. package/template/src/common/localization/translations/profileLocalization.ts +4 -4
  28. package/template/src/common/utils/FeesCaalculation.tsx +37 -0
  29. package/template/src/common/utils/index.tsx +11 -0
  30. package/template/src/common/utils/printData.tsx +161 -0
  31. package/template/src/common/validations/errorValidations.ts +3 -2
  32. package/template/src/core/api/serverHeaders.ts +62 -1
  33. package/template/src/core/store/Categories/categoryActions.ts +33 -0
  34. package/template/src/core/store/Categories/categorySlice.ts +75 -0
  35. package/template/src/core/store/Categories/categoryState.ts +41 -0
  36. package/template/src/core/store/Providers/providersActions.ts +102 -0
  37. package/template/src/core/store/Providers/providersSlice.ts +136 -0
  38. package/template/src/core/store/Providers/providersState.ts +37 -0
  39. package/template/src/core/store/Services/servicesActions.ts +191 -0
  40. package/template/src/core/store/Services/servicesSlice.ts +205 -0
  41. package/template/src/core/store/Services/servicesState.ts +466 -0
  42. package/template/src/core/store/app/appSlice.ts +13 -5
  43. package/template/src/core/store/app/appState.ts +10 -2
  44. package/template/src/core/store/rootReducer.ts +6 -1
  45. package/template/src/core/store/store.tsx +55 -2
  46. package/template/src/core/store/user/userActions.ts +164 -26
  47. package/template/src/core/store/user/userSlice.ts +193 -21
  48. package/template/src/core/store/user/userState.ts +148 -25
  49. package/template/src/core/theme/colors.ts +12 -0
  50. package/template/src/core/theme/themes.ts +1 -1
  51. package/template/src/core/utils/stringUtils.ts +114 -0
  52. package/template/src/navigation/AuthStack.tsx +8 -0
  53. package/template/src/navigation/HeaderComponents.tsx +52 -1
  54. package/template/src/navigation/MainNavigation.tsx +3 -1
  55. package/template/src/navigation/MainStack.tsx +39 -56
  56. package/template/src/navigation/TabBar.tsx +111 -59
  57. package/template/src/navigation/types.ts +24 -0
  58. package/template/src/screens/Login/Login.tsx +83 -85
  59. package/template/src/screens/OTP/OTPScreen.tsx +169 -0
  60. package/template/src/screens/home/Components/PayByCode.tsx +129 -0
  61. package/template/src/screens/home/HomeScreen.tsx +1 -103
  62. package/template/src/screens/home/hooks/useHomeData.ts +32 -38
  63. package/template/src/screens/index.tsx +24 -0
  64. package/template/src/common/components/Stepper.tsx +0 -153
  65. package/template/src/common/components/Svg.tsx +0 -25
  66. package/template/src/common/hooks/useDebounce.ts +0 -17
  67. package/template/src/common/hooks/usePrevious.ts +0 -11
  68. package/template/src/common/urls/emailUrl.ts +0 -20
  69. package/template/src/common/urls/mapUrl.ts +0 -22
  70. package/template/src/common/utils/listHandlers.ts +0 -30
  71. package/template/src/common/utils/serializeQueryParams.ts +0 -10
  72. package/template/src/common/validations/hooks/useDatesError.ts +0 -40
  73. package/template/src/common/validations/profileValidations.ts +0 -30
  74. package/template/src/navigation/TopTabBar.tsx +0 -77
  75. package/template/src/screens/Settings/Settings.tsx +0 -5
  76. package/template/src/screens/home/components/CarouselSection.tsx +0 -79
  77. package/template/src/screens/home/components/FeaturedCarousel.tsx +0 -128
  78. package/template/src/screens/main/Main.tsx +0 -5
  79. package/template/src/screens/registration/RegistrationScreen.tsx +0 -198
  80. package/template/src/screens/resetPassword/ForgotPasswordScreen.tsx +0 -129
@@ -0,0 +1,129 @@
1
+ import React, {useState} from 'react';
2
+ import {Modal, StyleSheet, View} from 'react-native';
3
+ import {RTLAwareView} from '../../../common/components/RTLAwareView';
4
+ import {CommonSizes} from '../../../core/theme/commonSizes';
5
+ import {PrimaryTextInput} from '../../../common/components/PrimaryTextInput';
6
+ import {useTheme} from '../../../core/theme/ThemeProvider';
7
+ import {PrimaryButton} from '../../../common/components/PrimaryButton';
8
+ import {ButtonType} from '../../../../types';
9
+ import {useAppDispatch} from '../../../core/store/reduxHelpers';
10
+ import {getServiceById} from '../../../core/store/Services/servicesActions';
11
+ import {getProviderById} from '../../../core/store/Providers/providersActions';
12
+ import {useNavigation} from '@react-navigation/native';
13
+ import {NativeStackNavigationProp} from '@react-navigation/native-stack';
14
+ import {RootStackParamList} from '../../../navigation/types';
15
+ import {useTranslation} from '../../../common/localization/LocalizationProvider';
16
+
17
+ export function PayByCode({
18
+ isVisible,
19
+ onClose,
20
+ }: {
21
+ isVisible: boolean;
22
+ onClose: () => void;
23
+ }): JSX.Element {
24
+ const {theme} = useTheme();
25
+ const t = useTranslation();
26
+ const [code, setCode] = useState('');
27
+ const [isLoading, setIsLoading] = useState(false);
28
+ const dispatch = useAppDispatch();
29
+ const navigation =
30
+ useNavigation<NativeStackNavigationProp<RootStackParamList>>();
31
+
32
+ const getService = async () => {
33
+ if (!code) {
34
+ return;
35
+ }
36
+ try {
37
+ setIsLoading(true);
38
+ const response = await dispatch(
39
+ getServiceById({data: {BillTypeCode: code}}),
40
+ );
41
+ if (response.type.includes('fulfilled')) {
42
+ const providerResponse = await dispatch(
43
+ getProviderById({
44
+ data: {BillerId: response.payload.service.BillerId},
45
+ }),
46
+ );
47
+ if (providerResponse.type.includes('fulfilled')) {
48
+ setCode('');
49
+ onClose();
50
+ setTimeout(() => {
51
+ navigation.navigate('SingleService', {
52
+ serviceID: undefined,
53
+ });
54
+ }, 200);
55
+ }
56
+ }
57
+ } catch (error) {
58
+ console.error(error);
59
+ } finally {
60
+ setIsLoading(false);
61
+ }
62
+ };
63
+
64
+ return (
65
+ <Modal
66
+ onRequestClose={onClose}
67
+ visible={isVisible}
68
+ transparent
69
+ style={styles.modal}>
70
+ <RTLAwareView
71
+ style={{
72
+ ...styles.container,
73
+ backgroundColor: theme.colors.surface,
74
+ borderWidth: 1,
75
+ borderColor: theme.colors.indigoBlue,
76
+ }}>
77
+ <PrimaryTextInput
78
+ value={code}
79
+ onChangeText={setCode}
80
+ placeholder={t('enterCode', 'home')}
81
+ />
82
+ <RTLAwareView
83
+ style={{
84
+ flexDirection: 'row',
85
+ alignItems: 'center',
86
+ justifyContent: 'space-between',
87
+ }}>
88
+ <PrimaryButton
89
+ disabled={isLoading}
90
+ isLoading={isLoading}
91
+ onPress={() => {
92
+ onClose();
93
+ setCode('');
94
+ }}
95
+ style={{width: '48%'}}
96
+ label={t('cancel', 'home')}
97
+ type={ButtonType.solid}
98
+ />
99
+ <PrimaryButton
100
+ disabled={isLoading}
101
+ isLoading={isLoading}
102
+ onPress={getService}
103
+ style={{width: '48%'}}
104
+ label={t('search', 'home')}
105
+ type={ButtonType.solid}
106
+ />
107
+ </RTLAwareView>
108
+ </RTLAwareView>
109
+ </Modal>
110
+ );
111
+ }
112
+
113
+ const styles = StyleSheet.create({
114
+ modal: {
115
+ flex: 1,
116
+ backgroundColor: 'red',
117
+ alignItems: 'center',
118
+ justifyContent: 'center',
119
+ },
120
+ container: {
121
+ width: '95%',
122
+ // minHeight: '40%',
123
+ alignSelf: 'center',
124
+ borderRadius: CommonSizes.borderRadius.large,
125
+ padding: CommonSizes.spacing.large,
126
+ gap: CommonSizes.spacing.large,
127
+ marginTop: '45%',
128
+ },
129
+ });
@@ -1,107 +1,5 @@
1
1
  import React from 'react';
2
- import {
3
- Dimensions,
4
- RefreshControl,
5
- ScrollView,
6
- StyleSheet,
7
- Text,
8
- View,
9
- } from 'react-native';
10
- import {NaturalColors} from '../../core/theme/colors';
11
- import {CommonSizes} from '../../core/theme/commonSizes';
12
- import {CommonStyles} from '../../core/theme/commonStyles';
13
- import {CarouselSection} from './components/CarouselSection';
14
- import {FeaturedCarousel} from './components/FeaturedCarousel';
15
- import {useHomeData} from './hooks/useHomeData';
16
-
17
- const {width} = Dimensions.get('window');
18
2
 
19
3
  export function HomeScreen(): JSX.Element {
20
- const {
21
- featuredItems,
22
- trendingItems,
23
- newItems,
24
- recommendedItems,
25
- isLoading,
26
- refreshData,
27
- } = useHomeData();
28
-
29
- return (
30
- <ScrollView
31
- style={styles.container}
32
- refreshControl={
33
- <RefreshControl refreshing={isLoading} onRefresh={refreshData} />
34
- }>
35
- <View style={styles.content}>
36
- {/* Featured Section */}
37
- <View style={styles.featuredSection}>
38
- <Text style={styles.sectionTitle}>Featured</Text>
39
- <FeaturedCarousel items={featuredItems} />
40
- </View>
41
-
42
- {/* Trending Section */}
43
- <View style={styles.carouselSection}>
44
- <Text style={styles.sectionTitle}>Trending Now</Text>
45
- <CarouselSection
46
- items={trendingItems}
47
- imageStyle={styles.trendingImage}
48
- />
49
- </View>
50
-
51
- {/* New Arrivals Section */}
52
- <View style={styles.carouselSection}>
53
- <Text style={styles.sectionTitle}>New Arrivals</Text>
54
- <CarouselSection
55
- items={newItems}
56
- imageStyle={styles.newArrivalsImage}
57
- />
58
- </View>
59
-
60
- {/* Recommended Section */}
61
- <View style={styles.carouselSection}>
62
- <Text style={styles.sectionTitle}>Recommended for You</Text>
63
- <CarouselSection
64
- items={recommendedItems}
65
- imageStyle={styles.recommendedImage}
66
- />
67
- </View>
68
- </View>
69
- </ScrollView>
70
- );
4
+ return <></>;
71
5
  }
72
-
73
- const styles = StyleSheet.create({
74
- container: {
75
- flex: 1,
76
- backgroundColor: NaturalColors.grayScale_0,
77
- },
78
- content: {
79
- paddingVertical: CommonSizes.spacing.medium,
80
- },
81
- featuredSection: {
82
- marginBottom: CommonSizes.spacing.large,
83
- },
84
- carouselSection: {
85
- marginBottom: CommonSizes.spacing.large,
86
- },
87
- sectionTitle: {
88
- ...CommonStyles.h2_semiBold,
89
- marginHorizontal: CommonSizes.spacing.large,
90
- marginBottom: CommonSizes.spacing.medium,
91
- },
92
- trendingImage: {
93
- width: width * 0.7,
94
- height: 200,
95
- borderRadius: CommonSizes.borderRadius.medium,
96
- },
97
- newArrivalsImage: {
98
- width: width * 0.5,
99
- height: 180,
100
- borderRadius: CommonSizes.borderRadius.medium,
101
- },
102
- recommendedImage: {
103
- width: width * 0.6,
104
- height: 160,
105
- borderRadius: CommonSizes.borderRadius.medium,
106
- },
107
- });
@@ -1,39 +1,34 @@
1
- import {useState, useEffect} from 'react';
2
- import {CarouselItem} from '../types';
3
-
1
+ import {useState} from 'react';
2
+ import {getCategories} from '../../../core/store/Categories/categoryActions';
3
+ import {clearSelectedCategory} from '../../../core/store/Categories/categorySlice';
4
+ import {getHomeProviders} from '../../../core/store/Providers/providersActions';
5
+ import {useAppDispatch, useAppSelector} from '../../../core/store/reduxHelpers';
6
+ import {RootState} from '../../../core/store/rootReducer';
7
+ import {getBalance} from '../../../core/store/user/userActions';
8
+ import {clearSelectedProvider} from '../../../core/store/Providers/providersSlice';
4
9
  export function useHomeData() {
5
10
  const [isLoading, setIsLoading] = useState(false);
6
- const [featuredItems, setFeaturedItems] = useState<CarouselItem[]>([]);
7
- const [trendingItems, setTrendingItems] = useState<CarouselItem[]>([]);
8
- const [newItems, setNewItems] = useState<CarouselItem[]>([]);
9
- const [recommendedItems, setRecommendedItems] = useState<CarouselItem[]>([]);
11
+ const dispatch = useAppDispatch();
12
+ const {categories, loadState} = useAppSelector(
13
+ (state: RootState) => state.categories,
14
+ );
15
+ const [isPayByCodeModalVisible, setIsPayByCodeModalVisible] = useState(false);
16
+ const {homeProviders} = useAppSelector((state: RootState) => state.providers);
17
+ const {user} = useAppSelector((state: RootState) => state.user);
10
18
 
11
19
  const fetchData = async () => {
12
20
  setIsLoading(true);
13
21
  try {
14
- // Simulate API calls
15
- // Replace with actual API calls in production
16
- setFeaturedItems([
17
- {
18
- id: '1',
19
- title: 'Featured Item 1',
20
- subtitle: 'Discover amazing features',
21
- imageUrl: 'https://picsum.photos/800/400',
22
- },
23
- // Add more items...
24
- ]);
25
-
26
- setTrendingItems([
27
- {
28
- id: '1',
29
- title: 'Trending Item 1',
30
- subtitle: 'Hot right now',
31
- imageUrl: 'https://picsum.photos/700/400',
32
- },
33
- // Add more items...
34
- ]);
35
-
36
- // Similar for newItems and recommendedItems...
22
+ const balance = await dispatch(getBalance());
23
+ if (balance.type.includes('fulfilled')) {
24
+ const categoryResponse = await dispatch(
25
+ getCategories({data: {limit: 30}}),
26
+ );
27
+ if (categoryResponse.type.includes('fulfilled')) {
28
+ const category_id = categoryResponse?.payload?.categories?.[0]?.id;
29
+ await dispatch(getHomeProviders({data: {category_id: category_id}}));
30
+ }
31
+ }
37
32
  } catch (error) {
38
33
  console.error('Error fetching home data:', error);
39
34
  } finally {
@@ -45,16 +40,15 @@ export function useHomeData() {
45
40
  fetchData();
46
41
  };
47
42
 
48
- useEffect(() => {
49
- fetchData();
50
- }, []);
51
-
52
43
  return {
53
44
  isLoading,
54
- featuredItems,
55
- trendingItems,
56
- newItems,
57
- recommendedItems,
58
45
  refreshData,
46
+ fetchData,
47
+ categories,
48
+ user,
49
+ homeProviders,
50
+ loadState,
51
+ isPayByCodeModalVisible,
52
+ setIsPayByCodeModalVisible,
59
53
  };
60
54
  }
@@ -0,0 +1,24 @@
1
+ // Authentication Screens
2
+ export {Login} from './Login/Login';
3
+ export {OTPScreen as OTP} from './OTP/OTPScreen';
4
+ export {ForceChangePasswordScreen as ForceChangePassword} from './ForceChangePassword/ForceChangePasswordScreen';
5
+
6
+ // Main Navigation Screens
7
+ export {HomeScreen as Home} from './home/HomeScreen';
8
+ export {Profile} from './profile/Profile';
9
+ export {Splash} from './splash/Splash';
10
+
11
+ // Service Related Screens
12
+ export {Categories} from './Categories/Categories';
13
+ export {Services} from './Services/Services';
14
+ export {SingleService} from './SingleService/SingleService';
15
+ export {Providers} from './Providers/Providers';
16
+ export {InquiredBill} from './InquiredBill/InquiredBill';
17
+ export {PaymentConfirmation} from './PaymentConfirmation/PaymentConfirmation';
18
+
19
+ // History and Receipt Screens
20
+ export {History} from './History/History';
21
+ export {Favorites} from './Favorites/Favorites';
22
+
23
+ // Device and Card Related Screens
24
+ export {ReceiptScreen} from './ReceiptScreen/ReceiptScreen';
@@ -1,153 +0,0 @@
1
- import React from 'react';
2
- import {View, Text, StyleSheet, Image, Pressable} from 'react-native';
3
- import {useTheme} from '../../core/theme/ThemeProvider';
4
- import {Theme} from '../../core/theme/types';
5
- import {PrimaryColors} from '../../core/theme/colors';
6
- import {ImageResources} from '../ImageResources.g';
7
-
8
- interface Step {
9
- title: string;
10
- }
11
-
12
- interface StepperProps {
13
- steps: Step[];
14
- currentStep: number;
15
- orientation?: 'horizontal' | 'vertical';
16
- onStepPress?: (index: number) => void;
17
- }
18
-
19
- const STEP_SIZE = 64;
20
-
21
- const Stepper: React.FC<StepperProps> = ({
22
- steps,
23
- currentStep,
24
- orientation = 'horizontal',
25
- onStepPress,
26
- }) => {
27
- const {theme} = useTheme();
28
- const isDarkMode = theme.mode === 'dark';
29
- const styles = createStyles(theme, orientation, isDarkMode);
30
-
31
- return (
32
- <View style={styles.container}>
33
- {steps.map((step, index) => {
34
- const isCompleted = index < currentStep;
35
- const isActive = index === currentStep;
36
- const isLastStep = index === steps.length - 1;
37
-
38
- const connectorStyle = [
39
- styles.connector,
40
- (isCompleted || isActive) && styles.connectorCompleted,
41
- ];
42
-
43
- return (
44
- <React.Fragment key={index}>
45
- <Pressable
46
- style={styles.stepContainer}
47
- onPress={() => onStepPress?.(index)}>
48
- <View
49
- style={[
50
- styles.circle,
51
- isCompleted && styles.circleCompleted,
52
- isActive && styles.circleActive,
53
- ]}>
54
- {isCompleted ? (
55
- <Image source={0} style={styles.icon} />
56
- ) : (
57
- <Text style={styles.stepNumber}>{index + 1}</Text>
58
- )}
59
- </View>
60
- <Text
61
- style={[
62
- styles.title,
63
- (isCompleted || isActive) && styles.titleActive,
64
- ]}>
65
- {step.title}
66
- </Text>
67
- </Pressable>
68
- {!isLastStep && <View style={connectorStyle} />}
69
- </React.Fragment>
70
- );
71
- })}
72
- </View>
73
- );
74
- };
75
-
76
- const createStyles = (
77
- theme: Theme,
78
- orientation: 'horizontal' | 'vertical',
79
- isDarkMode: boolean,
80
- ) =>
81
- StyleSheet.create({
82
- container: {
83
- flexDirection: orientation === 'horizontal' ? 'row' : 'column',
84
- alignItems: orientation === 'horizontal' ? 'flex-start' : 'stretch',
85
- },
86
- stepContainer: {
87
- alignItems: 'center',
88
- flex: orientation === 'horizontal' ? 1 : undefined,
89
- },
90
- circle: {
91
- width: STEP_SIZE,
92
- height: STEP_SIZE,
93
- borderRadius: STEP_SIZE / 2,
94
- borderWidth: 1,
95
- borderColor: isDarkMode
96
- ? theme.colors.grayScale_400
97
- : theme.colors.grayScale_50,
98
- justifyContent: 'center',
99
- alignItems: 'center',
100
- backgroundColor: 'transparent',
101
- },
102
- circleCompleted: {
103
- backgroundColor: PrimaryColors.PlatinateBlue_400,
104
- borderColor: PrimaryColors.PlatinateBlue_400,
105
- },
106
- circleActive: {
107
- borderColor: PrimaryColors.PlatinateBlue_400,
108
- },
109
- icon: {
110
- width: STEP_SIZE / 2,
111
- height: STEP_SIZE / 2,
112
- tintColor: theme.colors.grayScale_0,
113
- },
114
- stepNumber: {
115
- ...theme.text.bodyXLargeRegular,
116
- color: isDarkMode
117
- ? theme.colors.grayScale_400
118
- : theme.colors.grayScale_50,
119
- },
120
- title: {
121
- ...theme.text.bodyMediumRegular,
122
- marginTop: theme.spacing.small,
123
- color: isDarkMode
124
- ? theme.colors.grayScale_400
125
- : theme.colors.grayScale_50,
126
- },
127
- titleActive: {
128
- color: theme.colors.cetaceanBlue_700,
129
- },
130
- connector: {
131
- backgroundColor: isDarkMode
132
- ? theme.colors.grayScale_400
133
- : theme.colors.grayScale_50,
134
- ...(orientation === 'horizontal'
135
- ? {
136
- height: 1,
137
- flex: 1,
138
- marginHorizontal: -STEP_SIZE / 4,
139
- top: STEP_SIZE / 2,
140
- }
141
- : {
142
- width: 1,
143
- flex: 1,
144
- marginVertical: -STEP_SIZE / 4,
145
- left: '50%',
146
- }),
147
- },
148
- connectorCompleted: {
149
- backgroundColor: PrimaryColors.PlatinateBlue_400,
150
- },
151
- });
152
-
153
- export default Stepper;
@@ -1,25 +0,0 @@
1
- import * as React from 'react';
2
- import Svg, {G, Path, Defs, ClipPath, SvgProps} from 'react-native-svg';
3
-
4
- const SvgComponent: React.FC<SvgProps> = props => (
5
- <Svg width={'100%'} height={'100%'} fill="none" {...props}>
6
- <G clipPath="url(#a)">
7
- <Path fill="#F9FCFF" d="M0 0h428v925H0z" />
8
- <Path
9
- fill="#F3F2FF"
10
- d="M293.588 913.49c-11.664-7.299-22.732-17.683-25.003-31.28-1.327-8.116.619-16.401.321-24.632-1.302-34.39-41.04-60.387-36.303-94.477 3.225-23.054 26.005-38.157 48.084-45.307 22.079-7.15 46.135-9.803 65.558-22.544 11.677-7.647 20.94-18.492 32.704-26.016 31.368-20.054 78.287-8.983 97.328 23.023 13.438 22.55 13.203 50.707 8.916 76.621-7.313 43.969-24.299 113.518-59.201 144.845-32.956 29.629-98.321 21.076-132.404-.233Z"
11
- />
12
- <Path
13
- fill="#EEF8FF"
14
- d="M80.103-35.495c11.658 7.31 22.718 17.702 24.977 31.301 1.32 8.117-.633 16.4-.342 24.631 1.274 34.392 40.991 60.422 36.225 94.508-3.244 23.051-26.037 38.135-48.122 45.267-22.085 7.132-46.143 9.764-65.577 22.489-11.683 7.638-20.955 18.474-32.725 25.989-31.385 20.028-78.294 8.917-97.31-23.105-13.419-22.56-13.16-50.717-8.852-76.628C-104.272 64.994-87.228-4.54-52.301-35.838c32.98-29.602 98.34-20.994 132.404.343Z"
15
- />
16
- </G>
17
- <Defs>
18
- <ClipPath id="a">
19
- <Path fill="#fff" d="M0 0h428v925H0z" />
20
- </ClipPath>
21
- </Defs>
22
- </Svg>
23
- );
24
-
25
- export default SvgComponent;
@@ -1,17 +0,0 @@
1
- import {useEffect, useState} from 'react';
2
-
3
- export function useDebounce<T>(value: T, delay: number): T {
4
- const [debouncedValue, setDebouncedValue] = useState<T>(value);
5
-
6
- useEffect(() => {
7
- const handler = setTimeout(() => {
8
- setDebouncedValue(value);
9
- }, delay);
10
-
11
- return () => {
12
- clearTimeout(handler);
13
- };
14
- }, [value, delay]);
15
-
16
- return debouncedValue;
17
- }
@@ -1,11 +0,0 @@
1
- import {useEffect, useRef} from 'react';
2
-
3
- export function usePrevious<T>(value: T): T | undefined {
4
- const ref = useRef<T>();
5
-
6
- useEffect(() => {
7
- ref.current = value;
8
- }, [value]);
9
-
10
- return ref.current;
11
- }
@@ -1,20 +0,0 @@
1
- import {BaseUrlOpener} from './baseUrlOpener';
2
-
3
- export class EmailUrl extends BaseUrlOpener {
4
- constructor(private email: string | null) {
5
- super();
6
- }
7
-
8
- protected generateUrl(): string | null {
9
- if (this.email == null) {
10
- return null;
11
- } else {
12
- let url = this.email;
13
- if (!url.startsWith('mailto')) {
14
- url = 'mailto://' + url;
15
- }
16
-
17
- return url;
18
- }
19
- }
20
- }
@@ -1,22 +0,0 @@
1
- import {isIos} from '../../core/theme/commonConsts';
2
- import {BaseUrlOpener} from './baseUrlOpener';
3
-
4
- export class MapUrl extends BaseUrlOpener {
5
- constructor(
6
- private latitude: number,
7
- private longitude: number,
8
- private address: string,
9
- ) {
10
- super();
11
- }
12
-
13
- protected generateUrl(): string | null {
14
- if (isIos) {
15
- return `https://maps.apple.com/?q=${encodeURIComponent(
16
- this.address,
17
- )}&sll=${this.latitude},${this.longitude}`;
18
- } else {
19
- return `geo:${this.latitude}, ${this.longitude}`;
20
- }
21
- }
22
- }
@@ -1,30 +0,0 @@
1
- import {LoadState} from '../../../types';
2
- import {DEFAULT_PAGE_SIZE} from '../helpers/calculatePage';
3
-
4
- export function commonListFulfilledHandler<T>(
5
- loadState: LoadState,
6
- payloadList: T[],
7
- storedList: T[],
8
- ) {
9
- const newLoadState =
10
- payloadList.length >= DEFAULT_PAGE_SIZE
11
- ? LoadState.idle
12
- : LoadState.allIsLoaded;
13
-
14
- let newData: T[] = [];
15
-
16
- switch (loadState) {
17
- case LoadState.firstLoad:
18
- case LoadState.pullToRefresh:
19
- case LoadState.refreshing:
20
- newData = [...payloadList];
21
- break;
22
- case LoadState.loadingMore:
23
- newData = [...storedList].concat(payloadList);
24
- break;
25
- default:
26
- throw new Error(`LoadState ${loadState} is not valid in this context.`);
27
- }
28
-
29
- return {data: newData, error: null, loadState: newLoadState};
30
- }
@@ -1,10 +0,0 @@
1
- export function serializeQueryParams(obj: any): string {
2
- const str = [];
3
- for (const key in obj) {
4
- if (obj.hasOwnProperty(key) && obj[key] !== undefined) {
5
- str.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
6
- }
7
- }
8
-
9
- return str.join('&');
10
- }
@@ -1,40 +0,0 @@
1
- import {useCallback, useEffect, useRef, useState} from 'react';
2
- import {datesValidation} from '../commonValidations';
3
-
4
- export function useDatesError(
5
- fromDate: Date,
6
- toDate: Date,
7
- fromLabel: string,
8
- toLabel: string,
9
- currentField: 'from' | 'to',
10
- ) {
11
- const [error, setError] = useState<string | null>(null);
12
- const didMountRef = useRef(false);
13
-
14
- const recheckValue = useCallback(() => {
15
- const result = datesValidation(
16
- fromDate,
17
- toDate,
18
- fromLabel,
19
- toLabel,
20
- currentField,
21
- );
22
- setError(result);
23
-
24
- return result;
25
- }, [currentField, fromDate, fromLabel, toDate, toLabel]);
26
-
27
- useEffect(() => {
28
- if (didMountRef.current) {
29
- recheckValue();
30
- } else {
31
- didMountRef.current = true;
32
- }
33
- }, [recheckValue]);
34
-
35
- return {
36
- error,
37
- setError,
38
- recheckValue,
39
- };
40
- }