@jescon-technologies/react-native-ui-kit 0.0.10 → 0.0.11

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.
@@ -0,0 +1,182 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import {
3
+ StyleSheet,
4
+ Dimensions,
5
+ View,
6
+ Modal,
7
+ Animated,
8
+ Easing,
9
+ Text,
10
+ Image,
11
+ Platform,
12
+ } from 'react-native';
13
+ import { normalize } from '../CommonStyle/componentStyle';
14
+ import { APIURL } from '../../../../../src/Common/apiConstants';
15
+
16
+ export default function Loader({
17
+ visible = true,
18
+ overlayColor = 'rgba(0,0,0,0.4)',
19
+ loaderColor = 'lightblue',
20
+ size = Platform.OS !== 'web' ? 30 : 50,
21
+ gifSource = { uri: `${APIURL}file/getCommonFile/image/heartpulse.gif` },
22
+ message = '',
23
+ messageStyle = {},
24
+ animationType = 'fade',
25
+ hasBackground = true,
26
+ borderRadius = 20,
27
+ shadow = true,
28
+ }) {
29
+ const [rotation] = useState(new Animated.Value(0));
30
+ const [pulse] = useState(new Animated.Value(1));
31
+ const [fade] = useState(new Animated.Value(0));
32
+
33
+ // Rotation animation
34
+ useEffect(() => {
35
+ if (!gifSource) { // Only animate if not using a GIF
36
+ Animated.loop(
37
+ Animated.timing(rotation, {
38
+ toValue: 1,
39
+ duration: 1500,
40
+ easing: Easing.linear,
41
+ useNativeDriver: true,
42
+ })
43
+ ).start();
44
+ }
45
+
46
+ // Pulse animation
47
+ Animated.loop(
48
+ Animated.sequence([
49
+ Animated.timing(pulse, {
50
+ toValue: 1.1,
51
+ duration: 800,
52
+ useNativeDriver: true,
53
+ }),
54
+ Animated.timing(pulse, {
55
+ toValue: 1,
56
+ duration: 800,
57
+ useNativeDriver: true,
58
+ }),
59
+ ])
60
+ ).start();
61
+
62
+ // Fade in animation
63
+ Animated.timing(fade, {
64
+ toValue: 1,
65
+ duration: 300,
66
+ useNativeDriver: true,
67
+ }).start();
68
+ }, []);
69
+
70
+ const spin = rotation.interpolate({
71
+ inputRange: [0, 1],
72
+ outputRange: ['0deg', '360deg'],
73
+ });
74
+
75
+ const loaderContent = gifSource ? (
76
+ <Image
77
+ style={[styles.icon_style, { width: normalize(size), height: normalize(size) }]}
78
+ source={gifSource}
79
+ resizeMode="contain"
80
+ />
81
+ ) : (
82
+ <Animated.View style={[
83
+ styles.defaultLoader,
84
+ {
85
+ borderColor: loaderColor,
86
+ transform: [{ rotate: spin }, { scale: pulse }],
87
+ width: normalize(size),
88
+ height: normalize(size),
89
+ borderWidth: normalize(size / 10),
90
+ },
91
+ ]}>
92
+ <View style={[
93
+ styles.innerCircle,
94
+ {
95
+ backgroundColor: loaderColor,
96
+ width: normalize(size / 2),
97
+ height: normalize(size / 2),
98
+ },
99
+ ]} />
100
+ </Animated.View>
101
+ );
102
+
103
+
104
+
105
+
106
+ return (
107
+ <Modal
108
+ animationType={animationType}
109
+ transparent={true}
110
+ visible={visible}
111
+ onRequestClose={() => { }}
112
+ >
113
+ <Animated.View style={[
114
+ styles.modalContainer,
115
+ {
116
+ backgroundColor: overlayColor,
117
+ opacity: fade,
118
+ },
119
+ ]}>
120
+ <Animated.View style={[
121
+ styles.loaderContainer,
122
+ {
123
+ backgroundColor: hasBackground ? 'white' : 'transparent',
124
+ borderRadius: normalize(borderRadius),
125
+ transform: [{ scale: pulse }],
126
+ ...(shadow && styles.shadowStyle),
127
+ },
128
+ ]}>
129
+ {loaderContent}
130
+ {message ? (
131
+ <Text style={[styles.messageText, messageStyle]}>
132
+ {message}
133
+ </Text>
134
+ ) : null}
135
+ </Animated.View>
136
+ </Animated.View>
137
+ </Modal>
138
+ );
139
+ }
140
+
141
+ const styles = StyleSheet.create({
142
+
143
+
144
+ modalContainer: {
145
+ flex: 1,
146
+ justifyContent: 'center',
147
+ alignItems: 'center',
148
+ },
149
+ loaderContainer: {
150
+ padding: normalize(20),
151
+ justifyContent: 'center',
152
+ alignItems: 'center',
153
+ },
154
+ icon_style: {
155
+ justifyContent: 'center',
156
+ alignItems: 'center',
157
+ },
158
+ defaultLoader: {
159
+ borderRadius: normalize(100),
160
+ justifyContent: 'center',
161
+ alignItems: 'center',
162
+ },
163
+ innerCircle: {
164
+ borderRadius: normalize(100),
165
+ },
166
+ messageText: {
167
+ marginTop: normalize(15),
168
+ fontSize: normalize(14),
169
+ color: '#555',
170
+ textAlign: 'center',
171
+ },
172
+ shadowStyle: {
173
+ shadowColor: '#000',
174
+ shadowOffset: {
175
+ width: 0,
176
+ height: 2,
177
+ },
178
+ shadowOpacity: 0.25,
179
+ shadowRadius: 3.84,
180
+ elevation: 5,
181
+ },
182
+ });
@@ -0,0 +1,336 @@
1
+ import React, { useState, useCallback, useMemo } from 'react';
2
+ import {
3
+ View,
4
+ Dimensions,
5
+ Text,
6
+ TouchableOpacity,
7
+ StyleSheet,
8
+ TextInput,
9
+ Platform,
10
+ TextStyle,
11
+ ViewStyle,
12
+ } from 'react-native';
13
+ import { Global } from '../../../../../src/Common/Global';
14
+ import { normalize } from '../CommonStyle/componentStyle';
15
+ import Svg, { Rect, Defs, LinearGradient, Stop } from 'react-native-svg';
16
+ import HIcons from '../Hoc/HIcons';
17
+ import CModalOverlay from './CModalOverlay';
18
+
19
+ // Type definitions
20
+ export type BackHandlerType = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
21
+
22
+ export interface BackHandlerButtons {
23
+ iconname?: string;
24
+ button1?: string;
25
+ button2?: string;
26
+ heading?: string;
27
+ }
28
+
29
+ export interface CBackHandlerProps {
30
+ type: BackHandlerType;
31
+ data?: any;
32
+ displaytext?: string;
33
+ displaybuttons?: BackHandlerButtons;
34
+ close?: (value: boolean) => void;
35
+ callBack: (text: string) => void;
36
+ }
37
+
38
+ interface ConfigObject {
39
+ iconname: string;
40
+ button1: string;
41
+ button2: string;
42
+ heading: string;
43
+ iconGroup?: number;
44
+ iconName?: string;
45
+ }
46
+
47
+ interface TextKeyMap {
48
+ [key: number]: string;
49
+ }
50
+
51
+ // Constants
52
+ const DEFAULT_MESSAGE = 'Do you want to exit ?';
53
+ const DEFAULT_HEADING = 'CONFIRMATION';
54
+
55
+ // Text key mapping
56
+ const TEXT_KEYS: Record<BackHandlerType, string> = {
57
+ 1: 'Please enter installation key to continue.',
58
+ 2: 'Please make sure data saved before verify, Are you sure you want to verify ?',
59
+ 3: 'Do you want share consent form?',
60
+ 4: 'Do you want to delete?',
61
+ 5: 'Hold On, Are you sure you want to exit without save ?',
62
+ 6: 'Hold on, Are you sure you want to log out ?',
63
+ 7: '', // Dynamic - will use props.displaytext
64
+ 8: '', // Dynamic - will use props.displaytext
65
+ };
66
+
67
+ // Configuration mapping
68
+ const CONFIG_MAP: Record<BackHandlerType, Omit<ConfigObject, 'iconGroup' | 'iconName'>> = {
69
+ 1: {
70
+ iconname: 'lock',
71
+ button1: 'CANCEL',
72
+ button2: 'CONFIRM',
73
+ heading: 'INSTALLATION KEY',
74
+ },
75
+ 2: {
76
+ iconname: 'save',
77
+ button1: 'No',
78
+ button2: 'VERIFY',
79
+ heading: 'VERIFICATION',
80
+ },
81
+ 3: {
82
+ iconname: 'file-invoice',
83
+ button1: 'No',
84
+ button2: 'Yes',
85
+ heading: 'DELETION',
86
+ },
87
+ 4: {
88
+ iconname: 'trash',
89
+ button1: 'No',
90
+ button2: 'Yes',
91
+ heading: 'DELETION',
92
+ },
93
+ 5: {
94
+ iconname: 'exclamation-triangle',
95
+ button1: 'No',
96
+ button2: 'Yes',
97
+ heading: 'EXIT WITHOUT SAVE ?',
98
+ },
99
+ 6: {
100
+ iconname: 'exclamation-triangle',
101
+ button1: 'No',
102
+ button2: 'Yes',
103
+ heading: 'LOG OUT',
104
+ },
105
+ 7: {
106
+ iconname: 'exclamation-triangle',
107
+ button1: 'No',
108
+ button2: 'Yes',
109
+ heading: 'SWITCH SCREEN WITHOUT SAVE ?',
110
+ },
111
+ 8: {
112
+ iconname: 'exclamation-triangle',
113
+ button1: 'No',
114
+ button2: 'Yes',
115
+ heading: 'CONFIRMATION',
116
+ },
117
+ };
118
+
119
+ export default function CBackHandler(props: CBackHandlerProps): React.JSX.Element {
120
+ const [overlay, setOverlay] = useState<boolean>(true);
121
+ const [text, onChangeText] = useState<string>('');
122
+
123
+ const getPopupContainerStyle = useCallback((): ViewStyle => {
124
+ const baseStyle = styles.overlayStyle as ViewStyle;
125
+ return Platform.OS === 'ios'
126
+ ? { ...baseStyle, top: normalize(60) }
127
+ : { ...baseStyle, bottom: 0 };
128
+ }, []);
129
+
130
+ const getTextKey = useCallback((key: BackHandlerType): string => {
131
+ if (key === 7 || key === 8) {
132
+ return props.displaytext || DEFAULT_MESSAGE;
133
+ }
134
+ return TEXT_KEYS[key] || DEFAULT_MESSAGE;
135
+ }, [props.displaytext]);
136
+
137
+ const getObject = useCallback((): ConfigObject => {
138
+ const baseConfig = { ...CONFIG_MAP[props.type] };
139
+
140
+ // Handle type 8 with custom buttons
141
+ if (props.type === 8 && props.displaybuttons) {
142
+ return {
143
+ iconname: props.displaybuttons.iconname || baseConfig.iconname,
144
+ button1: props.displaybuttons.button1 || baseConfig.button1,
145
+ button2: props.displaybuttons.button2 || baseConfig.button2,
146
+ heading: props.displaybuttons.heading || baseConfig.heading,
147
+ };
148
+ }
149
+
150
+ return baseConfig;
151
+ }, [props.type, props.displaybuttons]);
152
+
153
+ const getIconConfig = useCallback((): { group: number; name: string } => {
154
+ if (props.type === 6) {
155
+ return { group: 8, name: 'log-out-outline' };
156
+ }
157
+ const config = getObject();
158
+ return { group: 5, name: config.iconname };
159
+ }, [props.type, getObject]);
160
+
161
+ const getClose = useCallback((): void => {
162
+ setOverlay(false);
163
+ props.close?.(false);
164
+ }, [props.close]);
165
+
166
+ const handleConfirm = useCallback((): void => {
167
+ props.callBack(text);
168
+ }, [props.callBack, text]);
169
+
170
+ const config = getObject();
171
+ const iconConfig = getIconConfig();
172
+ const textKey = getTextKey(props.type);
173
+ const popupStyle = getPopupContainerStyle();
174
+
175
+ return (
176
+ <CModalOverlay
177
+ visible={overlay}
178
+ onClose={getClose}
179
+ closeOnTouchOutside={true}
180
+ containerStyle={styles.container}
181
+ childrenWrapperStyle={popupStyle}
182
+ >
183
+ <View style={styles.wrapper}>
184
+ {/* Icon + Message */}
185
+ <View style={styles.content}>
186
+ <HIcons.Icons
187
+ icongroup={iconConfig.group}
188
+ name={iconConfig.name}
189
+ size={normalize(70)}
190
+ color="#7575ed"
191
+ style={styles.icon}
192
+ />
193
+ <Text numberOfLines={3} style={styles.message}>
194
+ {textKey}
195
+ </Text>
196
+ </View>
197
+
198
+ {/* Input (only for type 1) */}
199
+ {props.type === 1 && (
200
+ <TextInput
201
+ style={styles.input}
202
+ placeholder="Enter key"
203
+ placeholderTextColor="#999"
204
+ keyboardType="default"
205
+ onChangeText={onChangeText}
206
+ value={text}
207
+ autoFocus={true}
208
+ />
209
+ )}
210
+
211
+ {/* Buttons */}
212
+ <View style={styles.buttonRow}>
213
+ <TouchableOpacity
214
+ onPress={getClose}
215
+ style={styles.cancelButton}
216
+ activeOpacity={0.7}
217
+ >
218
+ <Text style={styles.cancelButtonText}>{config.button1}</Text>
219
+ </TouchableOpacity>
220
+
221
+ <TouchableOpacity
222
+ onPress={handleConfirm}
223
+ style={styles.confirmButton}
224
+ activeOpacity={0.8}
225
+ >
226
+ <Svg height={normalize(35)} width="100%">
227
+ <Defs>
228
+ <LinearGradient id="grad" x1="0" y1="0" x2="1" y2="0">
229
+ <Stop offset="0" stopColor="#2f3ec1" stopOpacity={1} />
230
+ <Stop
231
+ offset="1"
232
+ stopColor={Global.AppTheme.primary_color}
233
+ stopOpacity={1}
234
+ />
235
+ </LinearGradient>
236
+ </Defs>
237
+ <Rect
238
+ x="0"
239
+ y="0"
240
+ width="100%"
241
+ height={normalize(35)}
242
+ fill="url(#grad)"
243
+ rx="5"
244
+ />
245
+ </Svg>
246
+ <Text style={styles.confirmButtonText}>{config.button2}</Text>
247
+ </TouchableOpacity>
248
+ </View>
249
+ </View>
250
+ </CModalOverlay>
251
+ );
252
+ }
253
+
254
+ const styles = StyleSheet.create({
255
+ container: {
256
+ width: '100%',
257
+ backgroundColor: 'rgba(97, 97, 97, 0)',
258
+ },
259
+ overlayStyle: {
260
+ position: 'absolute',
261
+ width: Dimensions.get('window').width,
262
+ height: Dimensions.get('window').height * 0.3,
263
+ borderTopLeftRadius: 15,
264
+ borderTopRightRadius: 15,
265
+ borderWidth: 2,
266
+ borderColor: 'darkblue',
267
+ backgroundColor: 'white', // Added for better visibility
268
+ },
269
+ wrapper: {
270
+ marginTop: normalize(-10),
271
+ width: Dimensions.get('window').width - 10,
272
+ flex: 1,
273
+ borderRadius: normalize(17),
274
+ backgroundColor: 'white', // Added for better visibility
275
+ },
276
+ content: {
277
+ alignItems: 'center',
278
+ flex: 1,
279
+ justifyContent: 'center',
280
+ },
281
+ icon: {
282
+ textAlign: 'center',
283
+ marginVertical: normalize(10),
284
+ opacity: 0.6,
285
+ },
286
+ message: {
287
+ color: 'black',
288
+ fontSize: normalize(14),
289
+ fontWeight: '400',
290
+ textAlign: 'center',
291
+ paddingHorizontal: normalize(10),
292
+ },
293
+ input: {
294
+ height: normalize(30),
295
+ padding: 5,
296
+ fontWeight: 'bold',
297
+ width: normalize(190),
298
+ alignSelf: 'center',
299
+ textAlign: 'center',
300
+ borderBottomColor: Global.AppTheme.primary_color,
301
+ borderBottomWidth: 3,
302
+ fontSize: normalize(14),
303
+ color: 'black',
304
+ },
305
+ buttonRow: {
306
+ flexDirection: 'row',
307
+ width: '100%',
308
+ justifyContent: 'space-evenly',
309
+ marginTop: normalize(10),
310
+ },
311
+ cancelButton: {
312
+ backgroundColor: '#d2d2d2',
313
+ borderRadius: 5,
314
+ width: '47%',
315
+ justifyContent: 'center',
316
+ alignItems: 'center',
317
+ height: normalize(35),
318
+ marginVertical: normalize(10),
319
+ },
320
+ cancelButtonText: {
321
+ fontSize: normalize(12),
322
+ color: 'black',
323
+ },
324
+ confirmButton: {
325
+ width: '47%',
326
+ justifyContent: 'center',
327
+ alignItems: 'center',
328
+ height: normalize(35),
329
+ marginVertical: normalize(10),
330
+ },
331
+ confirmButtonText: {
332
+ fontSize: normalize(12),
333
+ color: '#fff',
334
+ position: 'absolute',
335
+ },
336
+ });
@@ -78,7 +78,7 @@ export const AntDesign: React.FC<Props> = (props) => (
78
78
  /**
79
79
  * Default export object (same usage style as your JS version)
80
80
  */
81
- const Icons = {
81
+ const HIcons = {
82
82
  MaterialCommunityIcons,
83
83
  SimpleLineIcons,
84
84
  MaterialIcons,
@@ -94,4 +94,4 @@ const Icons = {
94
94
  AntDesign,
95
95
  };
96
96
 
97
- export default Icons;
97
+ export default HIcons;
@@ -0,0 +1,2 @@
1
+
2
+ export { useFocusEffect } from '../../../../../src/Navigation/PageNavigation';
@@ -0,0 +1 @@
1
+ export { useFocusEffect } from '../../../../../src/Navigation/PageNavigation';
@@ -0,0 +1 @@
1
+ export { useIsFocused } from '../../../../../src/Navigation/PageNavigation';
@@ -0,0 +1 @@
1
+ export { useIsFocused } from '../../../../../src/Navigation/PageNavigation';
@@ -0,0 +1,2 @@
1
+
2
+ export { useNavigation } from '../../../../../src/Navigation/PageNavigation';
@@ -0,0 +1 @@
1
+ export { useNavigation } from '../../../../../src/Navigation/PageNavigation';
@@ -1,2 +0,0 @@
1
-
2
- export { useFocusEffect } from './PageNavigation';
@@ -1 +0,0 @@
1
- export { useFocusEffect } from './PageNavigation';
@@ -1 +0,0 @@
1
- export { useIsFocused } from './PageNavigation';
@@ -1 +0,0 @@
1
- export { useIsFocused } from './PageNavigation';
@@ -1,2 +0,0 @@
1
-
2
- export { useNavigation } from './PageNavigation';
@@ -1 +0,0 @@
1
- export { useNavigation } from './PageNavigation';