@airxpay/sdk-ui 1.0.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.
@@ -0,0 +1,210 @@
1
+ "use strict";
2
+ // components/common/FileUploader.tsx
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ const react_1 = __importDefault(require("react"));
41
+ const react_native_1 = require("react-native");
42
+ const react_native_paper_1 = require("react-native-paper");
43
+ const ImagePicker = __importStar(require("expo-image-picker"));
44
+ const FileUploader = ({ label, required = false, description, value, onUpload, onRemove, uploading = false, mode = 'test', accept = 'image/*', }) => {
45
+ const pickImage = async () => {
46
+ try {
47
+ const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
48
+ if (status !== 'granted') {
49
+ react_native_1.Alert.alert('Permission needed', 'Please grant camera roll permissions');
50
+ return;
51
+ }
52
+ const result = await ImagePicker.launchImageLibraryAsync({
53
+ mediaTypes: ImagePicker.MediaTypeOptions.Images,
54
+ allowsEditing: true,
55
+ aspect: [4, 3],
56
+ quality: 0.8,
57
+ });
58
+ if (!result.canceled && result.assets && result.assets[0]) {
59
+ onUpload(result.assets[0]);
60
+ }
61
+ }
62
+ catch (error) {
63
+ react_native_1.Alert.alert('Error', 'Failed to pick image');
64
+ }
65
+ };
66
+ const takePhoto = async () => {
67
+ try {
68
+ const { status } = await ImagePicker.requestCameraPermissionsAsync();
69
+ if (status !== 'granted') {
70
+ react_native_1.Alert.alert('Permission needed', 'Please grant camera permissions');
71
+ return;
72
+ }
73
+ const result = await ImagePicker.launchCameraAsync({
74
+ allowsEditing: true,
75
+ aspect: [4, 3],
76
+ quality: 0.8,
77
+ });
78
+ if (!result.canceled && result.assets && result.assets[0]) {
79
+ onUpload(result.assets[0]);
80
+ }
81
+ }
82
+ catch (error) {
83
+ react_native_1.Alert.alert('Error', 'Failed to take photo');
84
+ }
85
+ };
86
+ const showOptions = () => {
87
+ react_native_1.Alert.alert(`Upload ${label}`, 'Choose an option', [
88
+ { text: 'Take Photo', onPress: takePhoto },
89
+ { text: 'Choose from Gallery', onPress: pickImage },
90
+ { text: 'Cancel', style: 'cancel' }
91
+ ]);
92
+ };
93
+ const handleRemove = () => {
94
+ react_native_1.Alert.alert('Remove Document', `Are you sure you want to remove ${label}?`, [
95
+ { text: 'Cancel', style: 'cancel' },
96
+ { text: 'Remove', style: 'destructive', onPress: onRemove }
97
+ ]);
98
+ };
99
+ return (<react_native_1.View style={styles.container}>
100
+ <react_native_1.View style={styles.labelContainer}>
101
+ <react_native_1.Text style={styles.label}>
102
+ {label} {required && <react_native_1.Text style={styles.required}>*</react_native_1.Text>}
103
+ </react_native_1.Text>
104
+ {description && <react_native_1.Text style={styles.description}>{description}</react_native_1.Text>}
105
+ </react_native_1.View>
106
+
107
+ {value ? (<react_native_1.View style={styles.previewContainer}>
108
+ <react_native_1.Image source={{ uri: value }} style={styles.preview}/>
109
+ <react_native_1.View style={styles.previewActions}>
110
+ <react_native_1.TouchableOpacity onPress={showOptions} style={styles.changeButton}>
111
+ <react_native_1.Text style={styles.changeButtonText}>Change</react_native_1.Text>
112
+ </react_native_1.TouchableOpacity>
113
+ <react_native_1.TouchableOpacity onPress={handleRemove} style={styles.removeButton}>
114
+ <react_native_1.Text style={styles.removeButtonText}>Remove</react_native_1.Text>
115
+ </react_native_1.TouchableOpacity>
116
+ </react_native_1.View>
117
+ </react_native_1.View>) : (<react_native_1.TouchableOpacity style={styles.uploadArea} onPress={showOptions} disabled={uploading}>
118
+ {uploading ? (<react_native_paper_1.ActivityIndicator size="small" color="#0066CC"/>) : (<>
119
+ <react_native_1.Text style={styles.uploadIcon}>📎</react_native_1.Text>
120
+ <react_native_1.Text style={styles.uploadText}>Tap to upload</react_native_1.Text>
121
+ {mode === 'test' && (<react_native_1.Text style={styles.testModeHint}>(Test mode - simulated)</react_native_1.Text>)}
122
+ </>)}
123
+ </react_native_1.TouchableOpacity>)}
124
+ </react_native_1.View>);
125
+ };
126
+ const styles = react_native_1.StyleSheet.create({
127
+ container: {
128
+ marginBottom: 16,
129
+ },
130
+ labelContainer: {
131
+ marginBottom: 8,
132
+ },
133
+ label: {
134
+ fontSize: 14,
135
+ fontWeight: '500',
136
+ color: '#374151',
137
+ },
138
+ required: {
139
+ color: '#EF4444',
140
+ },
141
+ description: {
142
+ fontSize: 12,
143
+ color: '#6B7280',
144
+ marginTop: 2,
145
+ },
146
+ uploadArea: {
147
+ borderWidth: 2,
148
+ borderColor: '#E5E7EB',
149
+ borderStyle: 'dashed',
150
+ borderRadius: 8,
151
+ padding: 20,
152
+ alignItems: 'center',
153
+ justifyContent: 'center',
154
+ backgroundColor: '#F9FAFB',
155
+ },
156
+ uploadIcon: {
157
+ fontSize: 24,
158
+ marginBottom: 8,
159
+ },
160
+ uploadText: {
161
+ fontSize: 14,
162
+ color: '#6B7280',
163
+ },
164
+ testModeHint: {
165
+ fontSize: 10,
166
+ color: '#9CA3AF',
167
+ marginTop: 4,
168
+ },
169
+ previewContainer: {
170
+ borderWidth: 1,
171
+ borderColor: '#E5E7EB',
172
+ borderRadius: 8,
173
+ overflow: 'hidden',
174
+ },
175
+ preview: {
176
+ width: '100%',
177
+ height: 120,
178
+ resizeMode: 'cover',
179
+ },
180
+ previewActions: {
181
+ flexDirection: 'row',
182
+ borderTopWidth: 1,
183
+ borderTopColor: '#E5E7EB',
184
+ },
185
+ changeButton: {
186
+ flex: 1,
187
+ padding: 12,
188
+ alignItems: 'center',
189
+ backgroundColor: '#F9FAFB',
190
+ },
191
+ changeButtonText: {
192
+ color: '#0066CC',
193
+ fontSize: 14,
194
+ fontWeight: '500',
195
+ },
196
+ removeButton: {
197
+ flex: 1,
198
+ padding: 12,
199
+ alignItems: 'center',
200
+ backgroundColor: '#FEF2F2',
201
+ borderLeftWidth: 1,
202
+ borderLeftColor: '#E5E7EB',
203
+ },
204
+ removeButtonText: {
205
+ color: '#EF4444',
206
+ fontSize: 14,
207
+ fontWeight: '500',
208
+ },
209
+ });
210
+ exports.default = FileUploader;
@@ -0,0 +1,269 @@
1
+ "use strict";
2
+ // components/common/StepIndicator.tsx
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const react_1 = __importDefault(require("react"));
8
+ const react_native_1 = require("react-native");
9
+ const react_native_paper_1 = require("react-native-paper");
10
+ const expo_linear_gradient_1 = require("expo-linear-gradient");
11
+ const StepIndicator = ({ currentStep, steps, mode, isKycCompleted, isBankDetailsCompleted, }) => {
12
+ const getStepStatus = (stepId) => {
13
+ if (stepId < currentStep)
14
+ return 'completed';
15
+ if (stepId === currentStep)
16
+ return 'current';
17
+ return 'upcoming';
18
+ };
19
+ const getStepIcon = (stepId, status) => {
20
+ if (status === 'completed')
21
+ return 'check';
22
+ switch (stepId) {
23
+ case 1: return 'account';
24
+ case 2: return 'shield-account';
25
+ case 3: return 'bank';
26
+ case 4: return 'check-circle';
27
+ default: return 'circle';
28
+ }
29
+ };
30
+ const getStepColor = (status) => {
31
+ switch (status) {
32
+ case 'completed':
33
+ return '#10B981';
34
+ case 'current':
35
+ return '#0066CC';
36
+ default:
37
+ return '#9CA3AF';
38
+ }
39
+ };
40
+ const getStepLabel = (step) => {
41
+ if (mode === 'test' && step.id === 4)
42
+ return null;
43
+ return step.name;
44
+ };
45
+ return (<react_native_1.View style={styles.container}>
46
+ {/* Main Steps Row - Compact */}
47
+ <react_native_1.View style={styles.stepsRow}>
48
+ {steps.map((step, index) => {
49
+ const status = getStepStatus(step.id);
50
+ const color = getStepColor(status);
51
+ const icon = getStepIcon(step.id, status);
52
+ const label = getStepLabel(step);
53
+ // Don't show step 4 in test mode
54
+ if (mode === 'test' && step.id === 4)
55
+ return null;
56
+ // Don't show connector after last visible step
57
+ const isLastVisible = mode === 'test'
58
+ ? step.id === 3
59
+ : index === steps.length - 1;
60
+ return (<react_1.default.Fragment key={step.id}>
61
+ <react_native_1.View style={styles.stepItem}>
62
+ {/* Step Circle with Gradient or Color */}
63
+ {status === 'current' ? (<expo_linear_gradient_1.LinearGradient colors={['#0066CC', '#0099FF']} style={[styles.stepCircle, { shadowColor: color }]} start={{ x: 0, y: 0 }} end={{ x: 1, y: 1 }}>
64
+ <react_native_paper_1.IconButton icon={icon} size={14} iconColor="#FFFFFF"/>
65
+ </expo_linear_gradient_1.LinearGradient>) : (<react_native_1.View style={[
66
+ styles.stepCircle,
67
+ { backgroundColor: color },
68
+ status === 'completed' && styles.stepCircleCompleted
69
+ ]}>
70
+ <react_native_paper_1.IconButton icon={icon} size={14} iconColor="#FFFFFF"/>
71
+ </react_native_1.View>)}
72
+
73
+ {/* Step Label - Compact */}
74
+ {label && (<react_native_1.Text style={[
75
+ styles.stepLabel,
76
+ { color: status === 'upcoming' ? '#9CA3AF' : color }
77
+ ]}>
78
+ {label}
79
+ </react_native_1.Text>)}
80
+ </react_native_1.View>
81
+
82
+ {/* Connector - Only between visible steps */}
83
+ {!isLastVisible && (<react_native_1.View style={[
84
+ styles.stepConnector,
85
+ { backgroundColor: status === 'completed' ? '#10B981' : '#E5E7EB' }
86
+ ]}/>)}
87
+ </react_1.default.Fragment>);
88
+ })}
89
+ </react_native_1.View>
90
+
91
+ {/* Status Row - Compact Badges */}
92
+ <react_native_1.View style={styles.statusRow}>
93
+ {/* Mode Badge */}
94
+ <react_native_1.View style={[
95
+ styles.modeBadge,
96
+ mode === 'live' ? styles.liveBadge : styles.testBadge
97
+ ]}>
98
+ <react_native_paper_1.IconButton icon={mode === 'live' ? 'cloud' : 'flask'} size={12} iconColor={mode === 'live' ? '#DC2626' : '#92400E'}/>
99
+ <react_native_1.Text style={[
100
+ styles.modeText,
101
+ mode === 'live' ? styles.liveText : styles.testText
102
+ ]}>
103
+ {mode === 'live' ? 'LIVE' : 'TEST'}
104
+ </react_native_1.Text>
105
+ </react_native_1.View>
106
+
107
+ {/* KYC Status Badge */}
108
+ {isKycCompleted ? (<react_native_1.View style={[styles.statusBadge, styles.kycCompleted]}>
109
+ <react_native_paper_1.IconButton icon="check-circle" size={12} iconColor="#10B981"/>
110
+ <react_native_1.Text style={styles.kycText}>KYC Verified</react_native_1.Text>
111
+ </react_native_1.View>) : (<react_native_1.View style={[styles.statusBadge, styles.kycPending]}>
112
+ <react_native_paper_1.IconButton icon="clock-outline" size={12} iconColor="#D97706"/>
113
+ <react_native_1.Text style={styles.kycPendingText}>KYC Pending</react_native_1.Text>
114
+ </react_native_1.View>)}
115
+
116
+ {/* Bank Status Badge */}
117
+ {isBankDetailsCompleted ? (<react_native_1.View style={[styles.statusBadge, styles.bankCompleted]}>
118
+ <react_native_paper_1.IconButton icon="check-circle" size={12} iconColor="#10B981"/>
119
+ <react_native_1.Text style={styles.bankText}>Bank Added</react_native_1.Text>
120
+ </react_native_1.View>) : (<react_native_1.View style={[styles.statusBadge, styles.bankPending]}>
121
+ <react_native_paper_1.IconButton icon="clock-outline" size={12} iconColor="#D97706"/>
122
+ <react_native_1.Text style={styles.bankPendingText}>Bank Pending</react_native_1.Text>
123
+ </react_native_1.View>)}
124
+ </react_native_1.View>
125
+
126
+ {/* Test Mode Hint - Compact */}
127
+ {mode === 'test' && (<react_native_1.View style={styles.testHint}>
128
+ <react_native_paper_1.IconButton icon="information" size={12} iconColor="#92400E"/>
129
+ <react_native_1.Text style={styles.testHintText}>
130
+ KYC auto-approved in test mode
131
+ </react_native_1.Text>
132
+ </react_native_1.View>)}
133
+ </react_native_1.View>);
134
+ };
135
+ const styles = react_native_1.StyleSheet.create({
136
+ container: {
137
+ backgroundColor: '#FFFFFF',
138
+ paddingHorizontal: 12,
139
+ paddingVertical: 8,
140
+ borderBottomWidth: 1,
141
+ borderBottomColor: '#F3F4F6',
142
+ },
143
+ stepsRow: {
144
+ flexDirection: 'row',
145
+ alignItems: 'center',
146
+ justifyContent: 'space-between',
147
+ marginBottom: 8,
148
+ },
149
+ stepItem: {
150
+ alignItems: 'center',
151
+ flex: 1,
152
+ },
153
+ stepCircle: {
154
+ width: 28,
155
+ height: 28,
156
+ borderRadius: 14,
157
+ justifyContent: 'center',
158
+ alignItems: 'center',
159
+ marginBottom: 2,
160
+ elevation: 2,
161
+ shadowOffset: { width: 0, height: 1 },
162
+ shadowOpacity: 0.1,
163
+ shadowRadius: 2,
164
+ },
165
+ stepCircleCompleted: {
166
+ backgroundColor: '#10B981',
167
+ },
168
+ stepLabel: {
169
+ fontSize: 9,
170
+ fontWeight: '500',
171
+ textAlign: 'center',
172
+ },
173
+ stepConnector: {
174
+ height: 2,
175
+ flex: 1,
176
+ marginHorizontal: 2,
177
+ marginBottom: 16,
178
+ },
179
+ statusRow: {
180
+ flexDirection: 'row',
181
+ alignItems: 'center',
182
+ gap: 4,
183
+ flexWrap: 'wrap',
184
+ },
185
+ modeBadge: {
186
+ flexDirection: 'row',
187
+ alignItems: 'center',
188
+ paddingHorizontal: 6,
189
+ paddingVertical: 2,
190
+ borderRadius: 12,
191
+ marginRight: 4,
192
+ },
193
+ liveBadge: {
194
+ backgroundColor: '#FEE2E2',
195
+ },
196
+ testBadge: {
197
+ backgroundColor: '#FEF3C7',
198
+ },
199
+ modeText: {
200
+ fontSize: 9,
201
+ fontWeight: '600',
202
+ marginLeft: -2,
203
+ },
204
+ liveText: {
205
+ color: '#DC2626',
206
+ },
207
+ testText: {
208
+ color: '#92400E',
209
+ },
210
+ statusBadge: {
211
+ flexDirection: 'row',
212
+ alignItems: 'center',
213
+ paddingHorizontal: 6,
214
+ paddingVertical: 2,
215
+ borderRadius: 12,
216
+ },
217
+ kycCompleted: {
218
+ backgroundColor: '#D1FAE5',
219
+ },
220
+ kycPending: {
221
+ backgroundColor: '#FEF3C7',
222
+ },
223
+ bankCompleted: {
224
+ backgroundColor: '#D1FAE5',
225
+ },
226
+ bankPending: {
227
+ backgroundColor: '#FEF3C7',
228
+ },
229
+ kycText: {
230
+ fontSize: 9,
231
+ color: '#10B981',
232
+ fontWeight: '500',
233
+ marginLeft: -2,
234
+ },
235
+ kycPendingText: {
236
+ fontSize: 9,
237
+ color: '#D97706',
238
+ fontWeight: '500',
239
+ marginLeft: -2,
240
+ },
241
+ bankText: {
242
+ fontSize: 9,
243
+ color: '#10B981',
244
+ fontWeight: '500',
245
+ marginLeft: -2,
246
+ },
247
+ bankPendingText: {
248
+ fontSize: 9,
249
+ color: '#D97706',
250
+ fontWeight: '500',
251
+ marginLeft: -2,
252
+ },
253
+ testHint: {
254
+ flexDirection: 'row',
255
+ alignItems: 'center',
256
+ marginTop: 4,
257
+ backgroundColor: '#FEF3C7',
258
+ paddingHorizontal: 6,
259
+ paddingVertical: 2,
260
+ borderRadius: 12,
261
+ alignSelf: 'flex-start',
262
+ },
263
+ testHintText: {
264
+ fontSize: 8,
265
+ color: '#92400E',
266
+ marginLeft: -4,
267
+ },
268
+ });
269
+ exports.default = StepIndicator;