fairsure-checkout-sdk 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.
Files changed (40) hide show
  1. package/dist/components/CardPayment.d.ts +18 -0
  2. package/dist/components/CardPayment.js +302 -0
  3. package/dist/components/Checkout.d.ts +9 -0
  4. package/dist/components/Checkout.js +520 -0
  5. package/dist/components/OTPInput.d.ts +17 -0
  6. package/dist/components/OTPInput.js +132 -0
  7. package/dist/components/PaymentMethodSelector.d.ts +12 -0
  8. package/dist/components/PaymentMethodSelector.js +67 -0
  9. package/dist/components/PaystackCheckout.d.ts +13 -0
  10. package/dist/components/PaystackCheckout.js +385 -0
  11. package/dist/components/PurchaseModal.d.ts +17 -0
  12. package/dist/components/PurchaseModal.js +415 -0
  13. package/dist/components/TransferPayment.d.ts +16 -0
  14. package/dist/components/TransferPayment.js +311 -0
  15. package/dist/components/USSDPayment.d.ts +21 -0
  16. package/dist/components/USSDPayment.js +316 -0
  17. package/dist/components/usePaymentCheckout.d.ts +61 -0
  18. package/dist/components/usePaymentCheckout.js +398 -0
  19. package/dist/context/CheckoutProvider.d.ts +5 -0
  20. package/dist/context/CheckoutProvider.js +16 -0
  21. package/dist/hooks/useCheckout.d.ts +1 -0
  22. package/dist/hooks/useCheckout.js +8 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.js +2 -0
  25. package/dist/types.d.ts +9 -0
  26. package/dist/types.js +1 -0
  27. package/fairsure-checkout-sdk-1.0.0.tgz +0 -0
  28. package/package.json +24 -0
  29. package/src/components/CardPayment.tsx +386 -0
  30. package/src/components/OTPInput.tsx +204 -0
  31. package/src/components/PaymentMethodSelector.tsx +99 -0
  32. package/src/components/PaystackCheckout.tsx +506 -0
  33. package/src/components/TransferPayment.tsx +372 -0
  34. package/src/components/USSDPayment.tsx +422 -0
  35. package/src/components/usePaymentCheckout.ts +441 -0
  36. package/src/context/CheckoutProvider.tsx +37 -0
  37. package/src/hooks/useCheckout.ts +11 -0
  38. package/src/index.ts +2 -0
  39. package/src/types.ts +9 -0
  40. package/tsconfig.json +22 -0
@@ -0,0 +1,311 @@
1
+ import { Ionicons } from "@expo/vector-icons";
2
+ import { ActivityIndicator, StyleSheet, Text, TouchableOpacity, View, } from "react-native";
3
+ export default function TransferPayment({ loading, amount, transferDetail, timeLeft, copied, handleCopy, formatAmount, formatTime, }) {
4
+ if (loading) {
5
+ return <ActivityIndicator size="large" color="#4F46E5"/>;
6
+ }
7
+ return (<View>
8
+ <View style={styles.transferBox}>
9
+ <Text style={styles.transferText}>
10
+ Transfer ₦{formatAmount(amount)} to the account below
11
+ </Text>
12
+
13
+ <View>
14
+ <TransferDetailItem label="Bank Name" value={transferDetail.bankName}/>
15
+
16
+ <View style={styles.transferDetail}>
17
+ <Text style={styles.transferLabel}>Account Number</Text>
18
+ <View style={styles.row}>
19
+ <Text style={styles.accountNumber}>
20
+ {transferDetail.accountNumber}
21
+ </Text>
22
+ <TouchableOpacity onPress={() => handleCopy(transferDetail.accountNumber)}>
23
+ <Ionicons name={copied ? "checkmark" : "copy-outline"} size={20} color="#4F46E5"/>
24
+ </TouchableOpacity>
25
+ </View>
26
+ </View>
27
+
28
+ <TransferDetailItem label="Account Name" value={transferDetail.accountName}/>
29
+ </View>
30
+ </View>
31
+
32
+ <View style={styles.transferNote}>
33
+ <Text style={styles.transferNoteText}>
34
+ <Text style={{ fontWeight: "bold" }}>Note:</Text> This account expires
35
+ in{" "}
36
+ <Text style={{
37
+ fontWeight: "bold",
38
+ color: timeLeft <= 10 * 60 ? "#FF0000" : "#4F46E5",
39
+ }}>
40
+ {formatTime(timeLeft)}
41
+ </Text>{" "}
42
+ minutes. Please click "I have sent the Money" button once you have
43
+ sent the money.
44
+ </Text>
45
+ </View>
46
+ </View>);
47
+ }
48
+ function TransferDetailItem({ label, value, }) {
49
+ return (<View style={styles.transferDetail}>
50
+ <Text style={styles.transferLabel}>{label}</Text>
51
+ <Text style={styles.transferValue}>{value}</Text>
52
+ </View>);
53
+ }
54
+ const styles = StyleSheet.create({
55
+ overlay: {
56
+ flex: 1,
57
+ backgroundColor: "rgba(0,0,0,0.5)",
58
+ justifyContent: "center",
59
+ },
60
+ modalContainer: {
61
+ position: "relative",
62
+ width: "90%",
63
+ alignSelf: "center",
64
+ borderRadius: 20,
65
+ height: "80%",
66
+ backgroundColor: "white",
67
+ },
68
+ otpContainer: {
69
+ width: "100%",
70
+ marginHorizontal: "auto",
71
+ marginTop: 20,
72
+ marginBottom: 40,
73
+ },
74
+ header: {
75
+ backgroundColor: "#6B21A8",
76
+ padding: 16,
77
+ borderTopLeftRadius: 20,
78
+ borderTopRightRadius: 20,
79
+ },
80
+ pinWrapper: {
81
+ flexDirection: "row",
82
+ alignItems: "center",
83
+ },
84
+ eyeButton: {
85
+ paddingHorizontal: 10,
86
+ },
87
+ eyeText: {
88
+ color: "#007AFF",
89
+ },
90
+ headerTop: {
91
+ flexDirection: "row",
92
+ justifyContent: "space-between",
93
+ alignItems: "flex-start",
94
+ marginBottom: 16,
95
+ },
96
+ headerTitle: { color: "white", fontSize: 24, fontWeight: "bold" },
97
+ headerSubtitle: { color: "#E0E7FF", fontSize: 14, marginTop: 4 },
98
+ closeBtn: {
99
+ backgroundColor: "rgba(255,255,255,0.2)",
100
+ borderRadius: 999,
101
+ padding: 8,
102
+ },
103
+ amountBox: {
104
+ backgroundColor: "rgba(255,255,255,0.2)",
105
+ borderRadius: 12,
106
+ padding: 8,
107
+ },
108
+ amountLabel: { color: "#E0E7FF", fontSize: 12, marginBottom: 4 },
109
+ amountText: { color: "white", fontSize: 20, fontWeight: "bold" },
110
+ scrollContainer: { flex: 1, marginBottom: 16 },
111
+ body: {
112
+ padding: 24,
113
+ backgroundColor: "white",
114
+ borderBottomLeftRadius: 20,
115
+ borderBottomRightRadius: 20,
116
+ },
117
+ paymentMethodsContainer: {
118
+ flexDirection: "row",
119
+ marginBottom: 24,
120
+ backgroundColor: "#F3F4F6",
121
+ padding: 4,
122
+ borderRadius: 12,
123
+ },
124
+ paymentMethod: {
125
+ flex: 1,
126
+ flexDirection: "row",
127
+ alignItems: "center",
128
+ justifyContent: "center",
129
+ paddingVertical: 12,
130
+ borderRadius: 12,
131
+ marginHorizontal: 4,
132
+ },
133
+ paymentMethodSelected: { backgroundColor: "white" },
134
+ paymentMethodText: { fontSize: 14, color: "#4B5563", marginLeft: 8 },
135
+ paymentMethodTextSelected: { color: "#4F46E5", fontWeight: "600" },
136
+ inputGroup: { marginBottom: 16 },
137
+ inputLabel: {
138
+ fontSize: 14,
139
+ fontWeight: "500",
140
+ color: "#374151",
141
+ marginBottom: 4,
142
+ },
143
+ inputWrapper: { position: "relative" },
144
+ input: {
145
+ width: "100%",
146
+ paddingHorizontal: 16,
147
+ paddingVertical: 12,
148
+ borderWidth: 1,
149
+ borderColor: "#D1D5DB",
150
+ borderRadius: 12,
151
+ backgroundColor: "white",
152
+ },
153
+ inputIcon: { position: "absolute", right: 16, top: 14 },
154
+ row: { flexDirection: "row", gap: 16, marginBottom: 12 },
155
+ flex1: { flex: 1 },
156
+ secureBox: {
157
+ flexDirection: "row",
158
+ alignItems: "center",
159
+ backgroundColor: "#F9FAFB",
160
+ padding: 12,
161
+ borderRadius: 12,
162
+ gap: 8,
163
+ marginBottom: 16,
164
+ },
165
+ secureText: { fontSize: 12, color: "#4B5563", flex: 1 },
166
+ transferBox: {
167
+ backgroundColor: "#EFF6FF",
168
+ borderWidth: 1,
169
+ borderColor: "#BFDBFE",
170
+ borderRadius: 12,
171
+ padding: 8,
172
+ marginBottom: 8,
173
+ },
174
+ transferText: {
175
+ fontSize: 14,
176
+ color: "#1E3A8A",
177
+ fontWeight: "500",
178
+ marginBottom: 12,
179
+ },
180
+ transferDetail: {
181
+ backgroundColor: "white",
182
+ borderRadius: 12,
183
+ padding: 8,
184
+ marginBottom: 12,
185
+ },
186
+ transferLabel: { fontSize: 10, color: "#4B5563", marginBottom: 4 },
187
+ transferValue: { fontWeight: "600", color: "#111827" },
188
+ accountNumber: {
189
+ fontWeight: "600",
190
+ color: "#111827",
191
+ fontSize: 16,
192
+ letterSpacing: 2,
193
+ flex: 1,
194
+ },
195
+ transferNote: {
196
+ backgroundColor: "#FEF3C7",
197
+ borderWidth: 1,
198
+ borderColor: "#FDE68A",
199
+ borderRadius: 12,
200
+ padding: 8,
201
+ },
202
+ transferNoteText: { fontSize: 14, color: "#78350F" },
203
+ dropdown: {
204
+ width: "100%",
205
+ paddingHorizontal: 16,
206
+ paddingVertical: 12,
207
+ borderWidth: 1,
208
+ borderColor: "#D1D5DB",
209
+ borderRadius: 12,
210
+ flexDirection: "row",
211
+ justifyContent: "space-between",
212
+ alignItems: "center",
213
+ },
214
+ dropdownText: { color: "#111827" },
215
+ dropdownPlaceholder: { color: "#9CA3AF" },
216
+ dropdownList: {
217
+ marginTop: 8,
218
+ backgroundColor: "white",
219
+ borderWidth: 1,
220
+ borderColor: "#E5E7EB",
221
+ borderRadius: 12,
222
+ overflow: "hidden",
223
+ maxHeight: 240,
224
+ },
225
+ dropdownItem: {
226
+ paddingVertical: 12,
227
+ paddingHorizontal: 16,
228
+ borderBottomWidth: 1,
229
+ borderBottomColor: "#F3F4F6",
230
+ },
231
+ dropdownItemText: { color: "#111827" },
232
+ ussdContainer: {
233
+ backgroundColor: "#E0E7FF", // bg-indigo-50
234
+ borderWidth: 1,
235
+ borderColor: "#C7D2FE", // border-indigo-200
236
+ borderRadius: 12, // rounded-xl
237
+ padding: 16, // p-4
238
+ marginBottom: 16,
239
+ },
240
+ ussdTitle: {
241
+ fontSize: 14, // text-sm
242
+ color: "#1E3A8A", // text-indigo-900
243
+ fontWeight: "500", // font-medium
244
+ marginBottom: 12, // mb-3
245
+ },
246
+ ussdCodeContainer: {
247
+ backgroundColor: "white", // bg-white
248
+ borderRadius: 12, // rounded-xl
249
+ padding: 16, // p-4
250
+ marginBottom: 12, // mb-3
251
+ },
252
+ ussdCodeRow: {
253
+ flexDirection: "row",
254
+ justifyContent: "space-between",
255
+ alignItems: "center",
256
+ },
257
+ ussdCodeText: {
258
+ fontFamily: "monospace", // font-mono
259
+ fontSize: 16, // text-base
260
+ fontWeight: "700", // font-bold
261
+ color: "#111827", // text-gray-900
262
+ flex: 1,
263
+ },
264
+ ussdCopyBtn: {
265
+ padding: 8, // p-2
266
+ },
267
+ ussdStepsLabel: {
268
+ fontSize: 14, // text-sm
269
+ color: "#1E3A8A", // text-indigo-900
270
+ fontWeight: "600", // font-semibold
271
+ marginBottom: 8, // mb-2
272
+ },
273
+ ussdStepsText: {
274
+ fontSize: 14, // text-sm
275
+ color: "#1E40AF", // text-indigo-800
276
+ },
277
+ payButton: {
278
+ display: "flex",
279
+ flexDirection: "row",
280
+ justifyContent: "center",
281
+ gap: 8,
282
+ width: "100%",
283
+ paddingVertical: 16, // py-4
284
+ borderRadius: 12, // rounded-xl
285
+ marginTop: 8, // mt-2
286
+ alignItems: "center",
287
+ },
288
+ payButtonActive: {
289
+ backgroundColor: "#4F46E5", // bg-indigo-600
290
+ },
291
+ payButtonDisabled: {
292
+ backgroundColor: "#D1D5DB", // bg-gray-300
293
+ },
294
+ payButtonText: {
295
+ color: "white",
296
+ fontWeight: "600",
297
+ fontSize: 18, // text-lg
298
+ textAlign: "center",
299
+ },
300
+ footer: {
301
+ flexDirection: "row",
302
+ justifyContent: "center",
303
+ alignItems: "center",
304
+ marginTop: 8, // mt-2
305
+ gap: 8, // supported in RN 0.71+, acts like Tailwind gap-2
306
+ },
307
+ footerText: {
308
+ fontSize: 14, // text-sm
309
+ color: "#6B7280", // text-gray-500
310
+ },
311
+ });
@@ -0,0 +1,21 @@
1
+ type UssdBank = {
2
+ name: string;
3
+ code: string;
4
+ };
5
+ type USSDPaymentProps = {
6
+ selectedBank: UssdBank | null;
7
+ setSelectedBank: (bank: UssdBank) => void;
8
+ ussString: {
9
+ ussdString: string;
10
+ codeRef: string;
11
+ amount: string;
12
+ };
13
+ showBankDropdown: boolean;
14
+ setShowBankDropdown: (show: boolean) => void;
15
+ ussdBanks: UssdBank[];
16
+ loading: boolean;
17
+ copied: boolean;
18
+ handleCopy: (text: string) => void;
19
+ };
20
+ export default function USSDPayment({ selectedBank, setSelectedBank, showBankDropdown, ussString, setShowBankDropdown, ussdBanks, loading, copied, handleCopy, }: USSDPaymentProps): import("react").JSX.Element;
21
+ export {};
@@ -0,0 +1,316 @@
1
+ import { Ionicons } from "@expo/vector-icons";
2
+ import { ActivityIndicator, ScrollView, StyleSheet, Text, TouchableOpacity, View, } from "react-native";
3
+ export default function USSDPayment({ selectedBank, setSelectedBank, showBankDropdown, ussString, setShowBankDropdown, ussdBanks, loading, copied, handleCopy, }) {
4
+ // console.log("USSSSSS", ussdBanks);
5
+ return (<View>
6
+ <View style={styles.inputGroup}>
7
+ <Text style={styles.inputLabel}>Select Your Bank</Text>
8
+ <TouchableOpacity onPress={() => setShowBankDropdown(!showBankDropdown)} style={styles.dropdown}>
9
+ <Text style={selectedBank ? styles.dropdownText : styles.dropdownPlaceholder}>
10
+ {(selectedBank === null || selectedBank === void 0 ? void 0 : selectedBank.name) || "Choose your bank"}
11
+ </Text>
12
+ <Ionicons name="chevron-down" size={20} color="#9CA3AF"/>
13
+ </TouchableOpacity>
14
+
15
+ {showBankDropdown && (<BankDropdown ussdBanks={ussdBanks} loading={loading} onSelectBank={(bank) => {
16
+ setSelectedBank(bank);
17
+ setShowBankDropdown(false);
18
+ }}/>)}
19
+ </View>
20
+
21
+ {selectedBank && (<USSDInstructions ussdCode={ussString.ussdString} copied={copied} loading={loading} handleCopy={handleCopy}/>)}
22
+ </View>);
23
+ }
24
+ function BankDropdown({ ussdBanks, loading, onSelectBank, }) {
25
+ return (<View style={styles.dropdownList}>
26
+ <ScrollView style={{ maxHeight: 240 }} nestedScrollEnabled keyboardShouldPersistTaps="handled" showsVerticalScrollIndicator>
27
+ {loading ? (<ActivityIndicator size="large" color="#4F46E5"/>) : ussdBanks.length === 0 ? (<Text style={styles.dropdownPlaceholder}>No banks available</Text>) : (ussdBanks.map((bank) => (<TouchableOpacity key={bank.code} onPress={() => onSelectBank(bank)} style={styles.dropdownItem}>
28
+ <Text style={styles.dropdownItemText}>{bank.name}</Text>
29
+ </TouchableOpacity>)))}
30
+ </ScrollView>
31
+ </View>);
32
+ }
33
+ function USSDInstructions({ ussdCode, copied, handleCopy, loading, }) {
34
+ return (<View style={styles.ussdContainer}>
35
+ <Text style={styles.ussdTitle}>
36
+ Dial the code below to complete payment
37
+ </Text>
38
+
39
+ <View style={styles.ussdCodeContainer}>
40
+ <View style={styles.row}>
41
+ <Text style={styles.ussdCodeText}>{ussdCode}</Text>
42
+ <TouchableOpacity onPress={() => handleCopy(ussdCode)}>
43
+ <Ionicons name={copied ? "checkmark" : "copy-outline"} size={20} color="#4F46E5"/>
44
+ </TouchableOpacity>
45
+ {loading && <ActivityIndicator size="small" color="#4F46E5"/>}
46
+ </View>
47
+ </View>
48
+
49
+ <View>
50
+ <Text style={styles.ussdCodeText}>Steps:</Text>
51
+ <Text style={styles.ussdStepsText}>
52
+ 1. Dial the USSD code on your phone{"\n"}
53
+ 2. Follow the prompts on your screen{"\n"}
54
+ 3. Authorize payment with your bank PIN
55
+ </Text>
56
+ </View>
57
+ </View>);
58
+ }
59
+ const styles = StyleSheet.create({
60
+ overlay: {
61
+ flex: 1,
62
+ backgroundColor: "rgba(0,0,0,0.5)",
63
+ justifyContent: "center",
64
+ },
65
+ modalContainer: {
66
+ position: "relative",
67
+ width: "90%",
68
+ alignSelf: "center",
69
+ borderRadius: 20,
70
+ height: "80%",
71
+ backgroundColor: "white",
72
+ },
73
+ otpContainer: {
74
+ width: "100%",
75
+ marginHorizontal: "auto",
76
+ marginTop: 20,
77
+ marginBottom: 40,
78
+ },
79
+ header: {
80
+ backgroundColor: "#6B21A8",
81
+ padding: 16,
82
+ borderTopLeftRadius: 20,
83
+ borderTopRightRadius: 20,
84
+ },
85
+ pinWrapper: {
86
+ flexDirection: "row",
87
+ alignItems: "center",
88
+ },
89
+ eyeButton: {
90
+ paddingHorizontal: 10,
91
+ },
92
+ eyeText: {
93
+ color: "#007AFF",
94
+ },
95
+ headerTop: {
96
+ flexDirection: "row",
97
+ justifyContent: "space-between",
98
+ alignItems: "flex-start",
99
+ marginBottom: 16,
100
+ },
101
+ headerTitle: { color: "white", fontSize: 24, fontWeight: "bold" },
102
+ headerSubtitle: { color: "#E0E7FF", fontSize: 14, marginTop: 4 },
103
+ closeBtn: {
104
+ backgroundColor: "rgba(255,255,255,0.2)",
105
+ borderRadius: 999,
106
+ padding: 8,
107
+ },
108
+ amountBox: {
109
+ backgroundColor: "rgba(255,255,255,0.2)",
110
+ borderRadius: 12,
111
+ padding: 8,
112
+ },
113
+ amountLabel: { color: "#E0E7FF", fontSize: 12, marginBottom: 4 },
114
+ amountText: { color: "white", fontSize: 20, fontWeight: "bold" },
115
+ scrollContainer: { flex: 1, marginBottom: 16 },
116
+ body: {
117
+ padding: 24,
118
+ backgroundColor: "white",
119
+ borderBottomLeftRadius: 20,
120
+ borderBottomRightRadius: 20,
121
+ },
122
+ paymentMethodsContainer: {
123
+ flexDirection: "row",
124
+ marginBottom: 24,
125
+ backgroundColor: "#F3F4F6",
126
+ padding: 4,
127
+ borderRadius: 12,
128
+ },
129
+ paymentMethod: {
130
+ flex: 1,
131
+ flexDirection: "row",
132
+ alignItems: "center",
133
+ justifyContent: "center",
134
+ paddingVertical: 12,
135
+ borderRadius: 12,
136
+ marginHorizontal: 4,
137
+ },
138
+ paymentMethodSelected: { backgroundColor: "white" },
139
+ paymentMethodText: { fontSize: 14, color: "#4B5563", marginLeft: 8 },
140
+ paymentMethodTextSelected: { color: "#4F46E5", fontWeight: "600" },
141
+ inputGroup: { marginBottom: 16 },
142
+ inputLabel: {
143
+ fontSize: 14,
144
+ fontWeight: "500",
145
+ color: "#374151",
146
+ marginBottom: 4,
147
+ },
148
+ inputWrapper: { position: "relative" },
149
+ input: {
150
+ width: "100%",
151
+ paddingHorizontal: 16,
152
+ paddingVertical: 12,
153
+ borderWidth: 1,
154
+ borderColor: "#D1D5DB",
155
+ borderRadius: 12,
156
+ backgroundColor: "white",
157
+ },
158
+ inputIcon: { position: "absolute", right: 16, top: 14 },
159
+ row: { flexDirection: "row", backgroundColor: "white", marginBottom: 12 },
160
+ flex1: { flex: 1 },
161
+ secureBox: {
162
+ flexDirection: "row",
163
+ alignItems: "center",
164
+ backgroundColor: "#F9FAFB",
165
+ padding: 12,
166
+ borderRadius: 12,
167
+ gap: 8,
168
+ marginBottom: 16,
169
+ },
170
+ secureText: { fontSize: 12, color: "#4B5563", flex: 1 },
171
+ transferBox: {
172
+ backgroundColor: "#EFF6FF",
173
+ borderWidth: 1,
174
+ borderColor: "#BFDBFE",
175
+ borderRadius: 12,
176
+ padding: 8,
177
+ marginBottom: 8,
178
+ },
179
+ transferText: {
180
+ fontSize: 14,
181
+ color: "#1E3A8A",
182
+ fontWeight: "500",
183
+ marginBottom: 12,
184
+ },
185
+ transferDetail: {
186
+ backgroundColor: "white",
187
+ borderRadius: 12,
188
+ padding: 8,
189
+ marginBottom: 12,
190
+ },
191
+ transferLabel: { fontSize: 10, color: "#4B5563", marginBottom: 4 },
192
+ transferValue: { fontWeight: "600", color: "#111827" },
193
+ accountNumber: {
194
+ fontWeight: "600",
195
+ color: "#111827",
196
+ fontSize: 16,
197
+ letterSpacing: 2,
198
+ flex: 1,
199
+ },
200
+ transferNote: {
201
+ backgroundColor: "#FEF3C7",
202
+ borderWidth: 1,
203
+ borderColor: "#FDE68A",
204
+ borderRadius: 12,
205
+ padding: 8,
206
+ },
207
+ transferNoteText: { fontSize: 14, color: "#78350F" },
208
+ dropdown: {
209
+ width: "100%",
210
+ paddingHorizontal: 16,
211
+ paddingVertical: 12,
212
+ borderWidth: 1,
213
+ borderColor: "#D1D5DB",
214
+ borderRadius: 12,
215
+ flexDirection: "row",
216
+ justifyContent: "space-between",
217
+ alignItems: "center",
218
+ },
219
+ dropdownText: { color: "#111827" },
220
+ dropdownPlaceholder: { color: "#9CA3AF" },
221
+ dropdownList: {
222
+ marginTop: 8,
223
+ backgroundColor: "white",
224
+ borderWidth: 1,
225
+ borderColor: "#E5E7EB",
226
+ borderRadius: 12,
227
+ overflow: "hidden",
228
+ maxHeight: 240,
229
+ },
230
+ dropdownItem: {
231
+ paddingVertical: 12,
232
+ paddingHorizontal: 16,
233
+ borderBottomWidth: 1,
234
+ borderBottomColor: "#F3F4F6",
235
+ },
236
+ dropdownItemText: { color: "#111827" },
237
+ ussdContainer: {
238
+ backgroundColor: "#E0E7FF", // bg-indigo-50
239
+ borderWidth: 1,
240
+ borderColor: "#C7D2FE", // border-indigo-200
241
+ borderRadius: 12, // rounded-xl
242
+ padding: 16, // p-4
243
+ marginBottom: 16,
244
+ },
245
+ ussdTitle: {
246
+ fontSize: 14, // text-sm
247
+ color: "#1E3A8A", // text-indigo-900
248
+ fontWeight: "500", // font-medium
249
+ marginBottom: 12, // mb-3
250
+ },
251
+ ussdCodeContainer: {
252
+ backgroundColor: "white", // bg-white
253
+ borderRadius: 12, // rounded-xl
254
+ padding: 12, // p-4
255
+ marginBottom: 12, // mb-3
256
+ },
257
+ ussdCodeRow: {
258
+ flexDirection: "row",
259
+ justifyContent: "space-between",
260
+ alignItems: "center",
261
+ },
262
+ ussdCodeText: {
263
+ fontFamily: "monospace", // font-mono
264
+ fontSize: 16, // text-base
265
+ fontWeight: "700", // font-bold
266
+ color: "#111827", // text-gray-900
267
+ flex: 1,
268
+ },
269
+ ussdCopyBtn: {
270
+ padding: 8, // p-2
271
+ },
272
+ ussdStepsLabel: {
273
+ fontSize: 14, // text-sm
274
+ color: "#1E3A8A", // text-indigo-900
275
+ fontWeight: "600", // font-semibold
276
+ marginBottom: 8, // mb-2
277
+ },
278
+ ussdStepsText: {
279
+ fontSize: 14, // text-sm
280
+ color: "#1E40AF", // text-indigo-800
281
+ },
282
+ payButton: {
283
+ display: "flex",
284
+ flexDirection: "row",
285
+ justifyContent: "center",
286
+ gap: 8,
287
+ width: "100%",
288
+ paddingVertical: 16, // py-4
289
+ borderRadius: 12, // rounded-xl
290
+ marginTop: 8, // mt-2
291
+ alignItems: "center",
292
+ },
293
+ payButtonActive: {
294
+ backgroundColor: "#4F46E5", // bg-indigo-600
295
+ },
296
+ payButtonDisabled: {
297
+ backgroundColor: "#D1D5DB", // bg-gray-300
298
+ },
299
+ payButtonText: {
300
+ color: "white",
301
+ fontWeight: "600",
302
+ fontSize: 18, // text-lg
303
+ textAlign: "center",
304
+ },
305
+ footer: {
306
+ flexDirection: "row",
307
+ justifyContent: "center",
308
+ alignItems: "center",
309
+ marginTop: 8, // mt-2
310
+ gap: 8, // supported in RN 0.71+, acts like Tailwind gap-2
311
+ },
312
+ footerText: {
313
+ fontSize: 14, // text-sm
314
+ color: "#6B7280", // text-gray-500
315
+ },
316
+ });