app-expo-cli 1.0.5 → 1.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 (73) hide show
  1. package/package.json +1 -1
  2. package/src/copy-template.js +19 -1
  3. package/src/install-deps.js +6 -0
  4. package/template/assets/fonts/Inter_18pt-Black.ttf +0 -0
  5. package/template/assets/fonts/Inter_18pt-BlackItalic.ttf +0 -0
  6. package/template/assets/icon/index.ts +146 -0
  7. package/template/assets/images/about_us.png +0 -0
  8. package/template/assets/images/index.ts +6 -0
  9. package/template/assets/images/logo.png +0 -0
  10. package/template/assets/images/privacy_policy.png +0 -0
  11. package/template/assets/images/terms_and_conditions.png +0 -0
  12. package/template/src/app/_layout.tsx +3 -3
  13. package/template/src/app/auth/change_pass.tsx +18 -15
  14. package/template/src/app/auth/change_pass_modal.tsx +32 -51
  15. package/template/src/app/auth/forgot.tsx +74 -88
  16. package/template/src/app/auth/index.tsx +161 -192
  17. package/template/src/app/auth/opt_verify.tsx +93 -103
  18. package/template/src/app/auth/register.tsx +198 -260
  19. package/template/src/app/auth/reset_pass.tsx +102 -105
  20. package/template/src/app/index.tsx +70 -7
  21. package/template/src/app/modals/confirmation_logout_modal.tsx +0 -5
  22. package/template/src/app/modals/success_modal.tsx +28 -48
  23. package/template/src/app/settings/about_us.tsx +1 -1
  24. package/template/src/app/settings/privacy_policy.tsx +1 -1
  25. package/template/src/app/settings/terms_and_conditions.tsx +1 -1
  26. package/template/src/lib/DateTimePicker/DateTimePicker.tsx +63 -0
  27. package/template/src/lib/Empty/EmptyCard.tsx +67 -0
  28. package/template/src/lib/Error/GlobalErrorBoundary.tsx +111 -0
  29. package/template/src/lib/animate/AniImage.tsx +32 -0
  30. package/template/src/lib/backHeader/BackButton.tsx +62 -0
  31. package/template/src/lib/backHeader/BackWithCoponent.tsx +112 -0
  32. package/template/src/lib/backHeader/BackWithHeader.tsx +46 -0
  33. package/template/src/lib/backHeader/BackWithTitle.tsx +53 -0
  34. package/template/src/lib/buttons/IButton.tsx +69 -0
  35. package/template/src/lib/buttons/IwtButton.tsx +199 -0
  36. package/template/src/lib/buttons/Or.tsx +27 -0
  37. package/template/src/lib/buttons/SimpleButton.tsx +45 -0
  38. package/template/src/lib/buttons/TButton.tsx +70 -0
  39. package/template/src/lib/cards/Card.tsx +175 -0
  40. package/template/src/lib/cards/OptionSelect.tsx +44 -0
  41. package/template/src/lib/cards/SearchCard.tsx +35 -0
  42. package/template/src/lib/editor/TextEditor.tsx +81 -0
  43. package/template/src/lib/expend/ExpendComponent.tsx +36 -0
  44. package/template/src/lib/imageViewer/ImageViwer.tsx +332 -0
  45. package/template/src/lib/imageZoomer/ImageZoomer.tsx +104 -0
  46. package/template/src/lib/inputs/CheckBox.tsx +86 -0
  47. package/template/src/lib/inputs/InputText.tsx +232 -0
  48. package/template/src/lib/loader/GLoading.tsx +26 -0
  49. package/template/src/lib/loading/MLoading.tsx +14 -0
  50. package/template/src/lib/loading/SLoading.tsx +14 -0
  51. package/template/src/lib/modals/ActionModal.tsx +97 -0
  52. package/template/src/lib/modals/BottomModal.tsx +224 -0
  53. package/template/src/lib/modals/ConfrimationModal.tsx +116 -0
  54. package/template/src/lib/modals/DateModal.tsx +152 -0
  55. package/template/src/lib/modals/NormalModal.tsx +73 -0
  56. package/template/src/lib/modals/SideModal.tsx +57 -0
  57. package/template/src/lib/modals/Toaster.tsx +256 -0
  58. package/template/src/lib/payment/PaymentCardForD.tsx +47 -0
  59. package/template/src/lib/progressBar/ProgressBar.tsx +64 -0
  60. package/template/src/lib/tailwind.js +9 -0
  61. package/template/src/lib/ui/Avatar.tsx +55 -0
  62. package/template/src/redux/api-config/baseApi.ts +0 -22
  63. package/template/src/redux/interface/interface.ts +11 -193
  64. package/template/src/redux/store.ts +2 -2
  65. package/template/src/app/home/_layout.tsx +0 -29
  66. package/template/src/app/home/drawer/_layout.tsx +0 -27
  67. package/template/src/app/home/tabs/_layout.tsx +0 -75
  68. package/template/src/app/home/tabs/index.tsx +0 -11
  69. package/template/src/app/modals/payment_modal.tsx +0 -105
  70. package/template/src/hooks/useCheckLocation.ts +0 -36
  71. package/template/src/hooks/useDocPicker.ts +0 -83
  72. package/template/src/hooks/useSuggestionLocation.ts +0 -36
  73. package/template/src/hooks/useUploadProgress.ts +0 -127
@@ -0,0 +1,332 @@
1
+ import {
2
+ Alert,
3
+ Dimensions,
4
+ Image,
5
+ Modal,
6
+ PermissionsAndroid,
7
+ Platform,
8
+ Pressable,
9
+ StyleSheet,
10
+ Text,
11
+ TouchableOpacity,
12
+ View,
13
+ } from 'react-native';
14
+ import Animated, {
15
+ interpolate,
16
+ runOnJS,
17
+ useAnimatedStyle,
18
+ useSharedValue,
19
+ withSpring,
20
+ withTiming,
21
+ } from 'react-native-reanimated';
22
+ import {
23
+ Gesture,
24
+ GestureDetector,
25
+ GestureHandlerRootView,
26
+ } from 'react-native-gesture-handler';
27
+ import React, {useRef, useState} from 'react';
28
+
29
+ import RNFS from 'react-native-fs';
30
+
31
+ const {width: SCREEN_WIDTH, height: SCREEN_HEIGHT} = Dimensions.get('window');
32
+ interface ImageViewProps {
33
+ source: {uri: string}; // Image source (required)
34
+ style?: any; // Custom styles for the thumbnail
35
+ modalBackgroundStyle?: any; // Style for the modal background
36
+ headerStyle?: any; // Style for the header container
37
+ closeButtonStyle?: any; // Style for the close button text
38
+ onClose?: () => void; // Optional callback for the close button
39
+ onModalOpen?: () => void; // Optional callback for when the modal opens
40
+ animationConfig?: {
41
+ openDuration?: number;
42
+ closeDuration?: number;
43
+ }; // Customize animation durations
44
+ gesturesEnabled?: boolean; // Toggle gestures
45
+ aspectRatio?: number; // Allow customizable aspect ratio
46
+ doubleTapScale?: number; // Customize double-tap zoom scale
47
+ }
48
+
49
+ const ImageView: React.FC<ImageViewProps> = ({
50
+ source,
51
+ style,
52
+ modalBackgroundStyle,
53
+ headerStyle,
54
+ closeButtonStyle,
55
+ onClose,
56
+ onModalOpen,
57
+ animationConfig = {openDuration: 500, closeDuration: 300},
58
+ gesturesEnabled = true,
59
+ aspectRatio = 1,
60
+ doubleTapScale = 2,
61
+ }) => {
62
+ const [isModalVisible, setIsModalVisible] = useState(false);
63
+ const [origin, setOrigin] = useState({x: 0, y: 0, width: 0, height: 0});
64
+
65
+ const scale = useSharedValue(1);
66
+ const translateX = useSharedValue(0);
67
+ const translateY = useSharedValue(0);
68
+ const animatedOpacity = useSharedValue(1);
69
+ const animatedPosition = useSharedValue(0);
70
+
71
+ const ref = useRef<Image>(null);
72
+
73
+ const cumulativeTranslateX = useSharedValue(0);
74
+ const cumulativeTranslateY = useSharedValue(0);
75
+
76
+ const initialImageWidth = SCREEN_WIDTH;
77
+ const initialImageHeight = SCREEN_WIDTH / aspectRatio;
78
+
79
+ const calculateBounds = (scaleFactor: number) => {
80
+ 'worklet';
81
+ const scaledWidth = initialImageWidth * scaleFactor;
82
+ const scaledHeight = initialImageHeight * scaleFactor;
83
+
84
+ const maxTranslateX = Math.max((scaledWidth - SCREEN_WIDTH) / 2, 0);
85
+ const maxTranslateY = Math.max((scaledHeight - SCREEN_HEIGHT) / 2, 0);
86
+
87
+ return {maxTranslateX, maxTranslateY};
88
+ };
89
+
90
+ const clamp = (value: number, min: number, max: number) => {
91
+ 'worklet';
92
+ return Math.min(Math.max(value, min), max);
93
+ };
94
+
95
+ const doubleTapGesture = Gesture.Tap()
96
+ .numberOfTaps(2)
97
+ .onEnd(() => {
98
+ if (scale.value > 1) {
99
+ scale.value = withSpring(1);
100
+ translateX.value = withSpring(0);
101
+ translateY.value = withSpring(0);
102
+ cumulativeTranslateX.value = 0;
103
+ cumulativeTranslateY.value = 0;
104
+ } else {
105
+ scale.value = withSpring(doubleTapScale);
106
+ }
107
+ });
108
+
109
+ const pinchGesture = Gesture.Pinch()
110
+ .onUpdate(e => {
111
+ scale.value = Math.max(1, e.scale);
112
+ })
113
+ .onEnd(() => {
114
+ if (scale.value < 1) {
115
+ scale.value = withSpring(1);
116
+ }
117
+ });
118
+
119
+ const panGesture = Gesture.Pan()
120
+ .onUpdate(e => {
121
+ if (scale.value > 1) {
122
+ const {maxTranslateX, maxTranslateY} = calculateBounds(scale.value);
123
+
124
+ translateX.value = clamp(
125
+ e.translationX + cumulativeTranslateX.value,
126
+ -maxTranslateX,
127
+ maxTranslateX,
128
+ );
129
+ translateY.value = clamp(
130
+ e.translationY + cumulativeTranslateY.value,
131
+ -maxTranslateY,
132
+ maxTranslateY,
133
+ );
134
+ }
135
+ })
136
+ .onEnd(() => {
137
+ if (scale.value > 1) {
138
+ cumulativeTranslateX.value = translateX.value;
139
+ cumulativeTranslateY.value = translateY.value;
140
+ }
141
+ });
142
+
143
+ const combinedGesture = gesturesEnabled
144
+ ? Gesture.Simultaneous(
145
+ Gesture.Simultaneous(pinchGesture, panGesture),
146
+ doubleTapGesture,
147
+ )
148
+ : undefined;
149
+
150
+ const animatedImageStyle = useAnimatedStyle(() => {
151
+ 'worklet';
152
+ return {
153
+ opacity: animatedOpacity.value,
154
+ width: interpolate(
155
+ animatedPosition.value,
156
+ [0, 1],
157
+ [origin.width, initialImageWidth],
158
+ ),
159
+ height: interpolate(
160
+ animatedPosition.value,
161
+ [0, 1],
162
+ [origin.height, initialImageHeight],
163
+ ),
164
+ transform: [
165
+ {
166
+ translateX: interpolate(
167
+ animatedPosition.value,
168
+ [0, 1],
169
+ [origin.x + origin.width / 2 - SCREEN_WIDTH / 2, translateX.value],
170
+ ),
171
+ },
172
+ {
173
+ translateY: interpolate(
174
+ animatedPosition.value,
175
+ [0, 1],
176
+ [
177
+ origin.y + origin.height / 2 - SCREEN_HEIGHT / 2,
178
+ translateY.value,
179
+ ],
180
+ ),
181
+ },
182
+ {scale: scale.value},
183
+ ],
184
+ };
185
+ });
186
+
187
+ const animatedBackgroundStyle = useAnimatedStyle(() => {
188
+ 'worklet';
189
+ return {
190
+ opacity: animatedOpacity.value,
191
+ backgroundColor: 'black',
192
+ ...modalBackgroundStyle,
193
+ };
194
+ });
195
+
196
+ const handleOpenModal = () => {
197
+ ref.current?.measure((x, y, width, height, pageX, pageY) => {
198
+ setOrigin({x: pageX, y: pageY, width, height});
199
+ animatedPosition.value = 0;
200
+ animatedOpacity.value = 0;
201
+
202
+ setIsModalVisible(true);
203
+ onModalOpen?.();
204
+
205
+ animatedPosition.value = withTiming(1, {
206
+ duration: animationConfig.openDuration,
207
+ });
208
+ animatedOpacity.value = withTiming(1, {
209
+ duration: animationConfig.openDuration,
210
+ });
211
+ });
212
+ };
213
+
214
+ const handleCloseModal = () => {
215
+ 'worklet';
216
+ animatedOpacity.value = withTiming(
217
+ 0,
218
+ {duration: animationConfig.closeDuration},
219
+ () => {
220
+ // Use runOnJS to call non-worklet functions
221
+ runOnJS(setIsModalVisible)(false);
222
+ if (onClose) {
223
+ runOnJS(onClose)();
224
+ }
225
+ },
226
+ );
227
+ };
228
+
229
+ const handleDownload = async () => {
230
+ if (Platform.OS === 'android') {
231
+ const granted = await PermissionsAndroid.request(
232
+ PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
233
+ {
234
+ title: 'Storage Permission Required',
235
+ message: 'The app needs access to your storage to download images.',
236
+ },
237
+ );
238
+ if (granted !== PermissionsAndroid.RESULTS.GRANTED) {
239
+ Alert.alert(
240
+ 'Permission Denied',
241
+ 'Cannot download image without storage permission.',
242
+ );
243
+ return;
244
+ }
245
+ }
246
+
247
+ const fileName = source.uri.split('/').pop();
248
+ const path = `${RNFS.DownloadDirectoryPath}/${fileName}`;
249
+ try {
250
+ await RNFS.downloadFile({
251
+ fromUrl: source.uri,
252
+ toFile: path,
253
+ }).promise;
254
+ Alert.alert('Download Successful', 'Image downloaded successfully.');
255
+ } catch (error) {
256
+ Alert.alert(
257
+ 'Download Failed',
258
+ 'An error occurred while downloading the image.',
259
+ );
260
+ }
261
+ };
262
+
263
+ return (
264
+ <>
265
+ <Pressable onPress={handleOpenModal}>
266
+ <Image ref={ref} source={source} style={[style]} />
267
+ </Pressable>
268
+
269
+ <Modal
270
+ statusBarTranslucent
271
+ animationType="fade"
272
+ transparent
273
+ visible={isModalVisible}
274
+ onRequestClose={handleCloseModal}>
275
+ <GestureHandlerRootView style={styles.modalContainer}>
276
+ <Animated.View
277
+ style={[styles.modalBackground, animatedBackgroundStyle]}>
278
+ <View style={[styles.header, headerStyle]}>
279
+ <TouchableOpacity onPress={handleCloseModal}>
280
+ <Text style={[styles.closeButton, closeButtonStyle]}>
281
+ Close
282
+ </Text>
283
+ </TouchableOpacity>
284
+ <TouchableOpacity onPress={() => handleDownload()}>
285
+ <Text style={styles.downloadButton}>Download</Text>
286
+ </TouchableOpacity>
287
+ </View>
288
+ <GestureDetector gesture={combinedGesture}>
289
+ <Animated.Image
290
+ source={source}
291
+ style={[animatedImageStyle]}
292
+ resizeMode="cover"
293
+ />
294
+ </GestureDetector>
295
+ </Animated.View>
296
+ </GestureHandlerRootView>
297
+ </Modal>
298
+ </>
299
+ );
300
+ };
301
+
302
+ export default ImageView;
303
+
304
+ const styles = StyleSheet.create({
305
+ modalContainer: {
306
+ flex: 1,
307
+ },
308
+ modalBackground: {
309
+ flex: 1,
310
+ justifyContent: 'center',
311
+ alignItems: 'center',
312
+ },
313
+ header: {
314
+ position: 'absolute',
315
+ top: 50,
316
+ right: 20,
317
+ zIndex: 1,
318
+ flexDirection: 'row-reverse',
319
+ gap: 15,
320
+ },
321
+ closeButton: {
322
+ color: 'white',
323
+ fontSize: 18,
324
+ fontWeight: 'bold',
325
+ },
326
+ downloadButton: {
327
+ color: 'white',
328
+ fontSize: 18,
329
+ fontWeight: 'bold',
330
+ marginLeft: 15,
331
+ },
332
+ });
@@ -0,0 +1,104 @@
1
+ import Animated, {
2
+ clamp,
3
+ useAnimatedStyle,
4
+ useSharedValue,
5
+ withTiming,
6
+ } from "react-native-reanimated";
7
+ import { Gesture, GestureDetector } from "react-native-gesture-handler";
8
+
9
+ import { Dimensions } from "react-native";
10
+ import React from "react";
11
+
12
+ const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get("window");
13
+
14
+ interface ZoomableImageProps {
15
+ uri: string;
16
+ }
17
+
18
+ const ZoomableImage: React.FC<ZoomableImageProps> = ({ uri }) => {
19
+ const scale = useSharedValue(1);
20
+ const savedScale = useSharedValue(1);
21
+
22
+ const translateX = useSharedValue(0);
23
+ const translateY = useSharedValue(0);
24
+ const savedTranslateX = useSharedValue(0);
25
+ const savedTranslateY = useSharedValue(0);
26
+
27
+ const imageWidth = SCREEN_WIDTH;
28
+ const imageHeight = SCREEN_HEIGHT * 0.8;
29
+
30
+ const pinchGesture = Gesture.Pinch()
31
+ .onUpdate((event) => {
32
+ scale.value = clamp(savedScale.value * event.scale, 1, 5);
33
+ })
34
+ .onEnd(() => {
35
+ savedScale.value = scale.value;
36
+ });
37
+
38
+ const panGesture = Gesture.Pan()
39
+ .onUpdate((event) => {
40
+ if (scale.value > 1) {
41
+ // Limit pan to image bounds
42
+ const scaledWidth = imageWidth * scale.value;
43
+ const scaledHeight = imageHeight * scale.value;
44
+
45
+ const maxX = (scaledWidth - imageWidth) / 2;
46
+ const maxY = (scaledHeight - imageHeight) / 6;
47
+
48
+ translateX.value = clamp(
49
+ savedTranslateX.value + event.translationX,
50
+ -maxX,
51
+ maxX
52
+ );
53
+ translateY.value = clamp(
54
+ savedTranslateY.value + event.translationY,
55
+ -maxY,
56
+ maxY
57
+ );
58
+ }
59
+ })
60
+ .onEnd(() => {
61
+ savedTranslateX.value = translateX.value;
62
+ savedTranslateY.value = translateY.value;
63
+ });
64
+
65
+ const doubleTapGesture = Gesture.Tap()
66
+ .numberOfTaps(2)
67
+ .onEnd(() => {
68
+ const newScale = scale.value > 1 ? 1 : 2;
69
+ scale.value = withTiming(newScale);
70
+ savedScale.value = newScale;
71
+
72
+ translateX.value = withTiming(0);
73
+ translateY.value = withTiming(0);
74
+ savedTranslateX.value = 0;
75
+ savedTranslateY.value = 0;
76
+ });
77
+
78
+ const composedGesture = Gesture.Simultaneous(
79
+ doubleTapGesture,
80
+ Gesture.Simultaneous(pinchGesture, panGesture)
81
+ );
82
+
83
+ const animatedStyle = useAnimatedStyle(() => {
84
+ return {
85
+ transform: [
86
+ { translateX: translateX.value },
87
+ { translateY: translateY.value },
88
+ { scale: scale.value },
89
+ ],
90
+ };
91
+ });
92
+
93
+ return (
94
+ <GestureDetector gesture={composedGesture}>
95
+ <Animated.Image
96
+ source={{ uri }}
97
+ style={[{ width: imageWidth, height: imageHeight }, animatedStyle]}
98
+ resizeMode="contain"
99
+ />
100
+ </GestureDetector>
101
+ );
102
+ };
103
+
104
+ export default ZoomableImage;
@@ -0,0 +1,86 @@
1
+ import { Text, TouchableOpacity, View } from "react-native";
2
+
3
+ import React from "react";
4
+ import { SvgXml } from "react-native-svg";
5
+ import tw from "../tailwind";
6
+
7
+ interface CheckBoxProps {
8
+ onPress?: (version: boolean) => void;
9
+ color?: string;
10
+ iconColor?: string;
11
+ size?: number;
12
+ style?: any;
13
+ icon?: string;
14
+ title?: string;
15
+ titleStyle?: any;
16
+ containerStyle?: any;
17
+ checked?: boolean;
18
+ titleComponent?: React.ReactNode;
19
+ }
20
+
21
+ const defaultIcon = `<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="12" height="12" x="0" y="0" viewBox="0 0 520 520" style="enable-background:new 0 0 512 512" xml:space="preserve" class=""><g><path d="M239.987 460.841a10 10 0 0 1-7.343-3.213L34.657 243.463A10 10 0 0 1 42 226.675h95.3a10.006 10.006 0 0 1 7.548 3.439l66.168 76.124c7.151-15.286 20.994-40.738 45.286-71.752 35.912-45.85 102.71-113.281 216.994-174.153a10 10 0 0 1 10.85 16.712c-.436.341-44.5 35.041-95.212 98.6-46.672 58.49-108.714 154.13-139.243 277.6a10 10 0 0 1-9.707 7.6z" data-name="6-Check" fill="white" opacity="1" class=""></path></g></svg>`;
22
+
23
+ const CheckBox = ({
24
+ color,
25
+ iconColor,
26
+ size,
27
+ style,
28
+ icon,
29
+ checked = false,
30
+ onPress,
31
+ title,
32
+ titleStyle,
33
+ containerStyle,
34
+ titleComponent,
35
+ }: CheckBoxProps) => {
36
+ // This component renders a simple checkbox style
37
+
38
+ return (
39
+ <TouchableOpacity
40
+ style={[tw` flex-row items-center gap-2 `, containerStyle]}
41
+ onPress={() => {
42
+ onPress && onPress(!checked);
43
+ }}
44
+ >
45
+ <View
46
+ style={[
47
+ tw`w-5 h-5 border border-white rounded-md`,
48
+ {
49
+ backgroundColor: checked
50
+ ? color || tw.color("primary")
51
+ : "transparent",
52
+ justifyContent: "center",
53
+ alignItems: "center",
54
+ },
55
+ style,
56
+ ]}
57
+ >
58
+ {checked && icon ? (
59
+ <SvgXml xml={icon} width={size || 12} height={size || 12} />
60
+ ) : (
61
+ checked && (
62
+ <SvgXml xml={defaultIcon} width={size || 12} height={size || 12} />
63
+ )
64
+ )}
65
+ </View>
66
+
67
+ {
68
+ // Render title component if provided
69
+ titleComponent ? titleComponent : null
70
+ }
71
+
72
+ {title && !titleComponent ? (
73
+ <Text
74
+ style={[
75
+ tw`text-white text-sm leading-5 font-InterRegular `,
76
+ titleStyle,
77
+ ]}
78
+ >
79
+ {title}
80
+ </Text>
81
+ ) : null}
82
+ </TouchableOpacity>
83
+ );
84
+ };
85
+
86
+ export default CheckBox;