UNPKG

@oxyhq/services

Version:

Reusable OxyHQ module to handle authentication, user management, karma system, device-based session management and more 🚀

636 lines (633 loc) • 20.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _reactNative = require("react-native"); var _OxyContext = require("../context/OxyContext"); var _fonts = require("../styles/fonts"); var _sonner = require("../../lib/sonner"); var _vectorIcons = require("@expo/vector-icons"); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } const BillingManagementScreen = ({ onClose, theme, navigate, goBack }) => { const { user } = (0, _OxyContext.useOxy)(); const [loading, setLoading] = (0, _react.useState)(true); const [paymentMethods, setPaymentMethods] = (0, _react.useState)([]); const [invoices, setInvoices] = (0, _react.useState)([]); const [processingPayment, setProcessingPayment] = (0, _react.useState)(false); const isDarkTheme = theme === 'dark'; const textColor = isDarkTheme ? '#FFFFFF' : '#000000'; const backgroundColor = isDarkTheme ? '#121212' : '#FFFFFF'; const secondaryBackgroundColor = isDarkTheme ? '#222222' : '#F5F5F5'; const borderColor = isDarkTheme ? '#444444' : '#E0E0E0'; const primaryColor = '#007AFF'; const successColor = '#30D158'; const warningColor = '#FF9500'; const dangerColor = '#FF3B30'; // Mock data const mockPaymentMethods = [{ id: 'pm_1', type: 'card', last4: '4242', brand: 'Visa', expiryMonth: 12, expiryYear: 2027, isDefault: true }, { id: 'pm_2', type: 'paypal', isDefault: false }]; const mockInvoices = [{ id: 'inv_1', date: '2024-12-01', amount: 19.99, currency: 'USD', status: 'paid', description: 'Pro Plan - Monthly' }, { id: 'inv_2', date: '2024-11-01', amount: 19.99, currency: 'USD', status: 'paid', description: 'Pro Plan - Monthly' }, { id: 'inv_3', date: '2024-10-01', amount: 19.99, currency: 'USD', status: 'paid', description: 'Pro Plan - Monthly' }]; (0, _react.useEffect)(() => { loadBillingData(); }, []); const loadBillingData = async () => { try { setLoading(true); // Simulate API calls await new Promise(resolve => setTimeout(resolve, 1000)); setPaymentMethods(mockPaymentMethods); setInvoices(mockInvoices); } catch (error) { console.error('Failed to load billing data:', error); _sonner.toast.error('Failed to load billing information'); } finally { setLoading(false); } }; const handleAddPaymentMethod = () => { _reactNative.Alert.alert('Add Payment Method', 'This would open a secure payment form to add a new payment method.', [{ text: 'OK' }]); }; const handleSetDefaultPaymentMethod = async methodId => { try { setPaymentMethods(prev => prev.map(method => ({ ...method, isDefault: method.id === methodId }))); _sonner.toast.success('Default payment method updated'); } catch (error) { _sonner.toast.error('Failed to update payment method'); } }; const handleRemovePaymentMethod = methodId => { _reactNative.Alert.alert('Remove Payment Method', 'Are you sure you want to remove this payment method?', [{ text: 'Cancel', style: 'cancel' }, { text: 'Remove', style: 'destructive', onPress: async () => { try { setPaymentMethods(prev => prev.filter(method => method.id !== methodId)); _sonner.toast.success('Payment method removed'); } catch (error) { _sonner.toast.error('Failed to remove payment method'); } } }]); }; const handleDownloadInvoice = invoice => { _sonner.toast.info('Invoice download would start here'); }; const getPaymentMethodIcon = method => { switch (method.type) { case 'card': return method.brand?.toLowerCase() === 'visa' ? 'card' : 'card-outline'; case 'paypal': return 'logo-paypal'; case 'bank': return 'business'; default: return 'card'; } }; const getPaymentMethodDisplay = method => { switch (method.type) { case 'card': return `${method.brand} •••• ${method.last4}`; case 'paypal': return 'PayPal'; case 'bank': return 'Bank Transfer'; default: return 'Unknown'; } }; const getStatusColor = status => { switch (status) { case 'paid': return successColor; case 'pending': return warningColor; case 'failed': return dangerColor; default: return textColor; } }; if (loading) { return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: [styles.container, { backgroundColor, justifyContent: 'center' }], children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, { size: "large", color: primaryColor }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.loadingText, { color: textColor }], children: "Loading billing information..." })] }); } return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: [styles.container, { backgroundColor }], children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: [styles.header, { borderBottomColor: borderColor }], children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, { style: styles.backButton, onPress: goBack, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "arrow-back", size: 24, color: textColor }) }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.headerTitle, { color: textColor }], children: "Billing Management" }), onClose && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, { style: styles.closeButton, onPress: onClose, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "close", size: 24, color: textColor }) })] }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, { style: styles.content, showsVerticalScrollIndicator: false, children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.section, children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.sectionHeader, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.sectionTitle, { color: textColor }], children: "Payment Methods" }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, { style: [styles.addButton, { backgroundColor: primaryColor }], onPress: handleAddPaymentMethod, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "add", size: 20, color: "#FFFFFF" }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: styles.addButtonText, children: "Add" })] })] }), paymentMethods.map(method => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: [styles.paymentMethodCard, { backgroundColor: secondaryBackgroundColor, borderColor }], children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.paymentMethodHeader, children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.paymentMethodInfo, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: getPaymentMethodIcon(method), size: 24, color: primaryColor, style: styles.paymentMethodIcon }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.paymentMethodName, { color: textColor }], children: getPaymentMethodDisplay(method) }), method.type === 'card' && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, { style: [styles.paymentMethodExpiry, { color: isDarkTheme ? '#BBBBBB' : '#666666' }], children: ["Expires ", method.expiryMonth, "/", method.expiryYear] }), method.isDefault && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: [styles.defaultBadge, { backgroundColor: successColor }], children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: styles.defaultText, children: "Default" }) })] })] }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.paymentMethodActions, children: [!method.isDefault && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, { style: [styles.actionButton, { borderColor }], onPress: () => handleSetDefaultPaymentMethod(method.id), children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.actionButtonText, { color: textColor }], children: "Set Default" }) }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, { style: [styles.actionButton, { borderColor: dangerColor }], onPress: () => handleRemovePaymentMethod(method.id), children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.actionButtonText, { color: dangerColor }], children: "Remove" }) })] })] }) }, method.id))] }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.section, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.sectionTitle, { color: textColor }], children: "Billing History" }), invoices.map(invoice => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: [styles.invoiceCard, { backgroundColor: secondaryBackgroundColor, borderColor }], children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.invoiceHeader, children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.invoiceInfo, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.invoiceDescription, { color: textColor }], children: invoice.description }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.invoiceDate, { color: isDarkTheme ? '#BBBBBB' : '#666666' }], children: new Date(invoice.date).toLocaleDateString() })] }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.invoiceAmount, children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, { style: [styles.invoicePrice, { color: textColor }], children: ["$", invoice.amount.toFixed(2)] }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: [styles.statusBadge, { backgroundColor: getStatusColor(invoice.status) }], children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: styles.statusText, children: invoice.status.toUpperCase() }) })] })] }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: styles.invoiceActions, children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, { style: [styles.downloadButton, { borderColor }], onPress: () => handleDownloadInvoice(invoice), children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "download", size: 16, color: primaryColor }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.downloadButtonText, { color: primaryColor }], children: "Download" })] }) })] }, invoice.id))] }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.section, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.sectionTitle, { color: textColor }], children: "Billing Information" }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: [styles.billingInfoCard, { backgroundColor: secondaryBackgroundColor, borderColor }], children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.billingInfoItem, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "business", size: 20, color: primaryColor }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.billingInfoContent, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.billingInfoLabel, { color: textColor }], children: "Billing Address" }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.billingInfoValue, { color: isDarkTheme ? '#BBBBBB' : '#666666' }], children: "Update your billing address" })] }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "chevron-forward", size: 20, color: isDarkTheme ? '#666666' : '#999999' }) })] }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.billingInfoItem, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "receipt", size: 20, color: primaryColor }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.billingInfoContent, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.billingInfoLabel, { color: textColor }], children: "Tax Information" }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.billingInfoValue, { color: isDarkTheme ? '#BBBBBB' : '#666666' }], children: "Manage tax settings" })] }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, { name: "chevron-forward", size: 20, color: isDarkTheme ? '#666666' : '#999999' }) })] })] })] }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: styles.bottomSpacing })] })] }); }; const styles = _reactNative.StyleSheet.create({ container: { flex: 1 }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 20, paddingTop: 20, paddingBottom: 16, borderBottomWidth: 1 }, backButton: { padding: 8 }, headerTitle: { fontSize: 20, fontWeight: '600', fontFamily: _fonts.fontFamilies.phuduSemiBold }, closeButton: { padding: 8 }, content: { flex: 1 }, section: { padding: 20 }, sectionHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }, sectionTitle: { fontSize: 20, fontWeight: 'bold', fontFamily: _fonts.fontFamilies.phuduBold }, addButton: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 12, paddingVertical: 8, borderRadius: 8 }, addButtonText: { color: '#FFFFFF', fontSize: 14, fontWeight: '600', marginLeft: 4 }, loadingText: { fontSize: 16, textAlign: 'center', marginTop: 16 }, paymentMethodCard: { borderRadius: 12, padding: 16, marginBottom: 12, borderWidth: 1 }, paymentMethodHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start' }, paymentMethodInfo: { flexDirection: 'row', alignItems: 'flex-start', flex: 1 }, paymentMethodIcon: { marginRight: 12, marginTop: 2 }, paymentMethodName: { fontSize: 16, fontWeight: '600', marginBottom: 4 }, paymentMethodExpiry: { fontSize: 14, marginBottom: 8 }, defaultBadge: { paddingHorizontal: 8, paddingVertical: 2, borderRadius: 4, alignSelf: 'flex-start' }, defaultText: { color: '#FFFFFF', fontSize: 12, fontWeight: '600' }, paymentMethodActions: { flexDirection: 'row', gap: 8 }, actionButton: { paddingHorizontal: 12, paddingVertical: 6, borderRadius: 6, borderWidth: 1 }, actionButtonText: { fontSize: 12, fontWeight: '600' }, invoiceCard: { borderRadius: 12, padding: 16, marginBottom: 12, borderWidth: 1 }, invoiceHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 12 }, invoiceInfo: { flex: 1 }, invoiceDescription: { fontSize: 16, fontWeight: '600', marginBottom: 4 }, invoiceDate: { fontSize: 14 }, invoiceAmount: { alignItems: 'flex-end' }, invoicePrice: { fontSize: 16, fontWeight: '600', marginBottom: 4 }, statusBadge: { paddingHorizontal: 8, paddingVertical: 2, borderRadius: 4 }, statusText: { color: '#FFFFFF', fontSize: 12, fontWeight: '600' }, invoiceActions: { flexDirection: 'row', justifyContent: 'flex-end' }, downloadButton: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 12, paddingVertical: 6, borderRadius: 6, borderWidth: 1 }, downloadButtonText: { fontSize: 12, fontWeight: '600', marginLeft: 4 }, billingInfoCard: { borderRadius: 12, borderWidth: 1, overflow: 'hidden' }, billingInfoItem: { flexDirection: 'row', alignItems: 'center', padding: 16, borderBottomWidth: 1, borderBottomColor: 'rgba(0, 0, 0, 0.05)' }, billingInfoContent: { flex: 1, marginLeft: 12 }, billingInfoLabel: { fontSize: 16, fontWeight: '600', marginBottom: 4 }, billingInfoValue: { fontSize: 14 }, bottomSpacing: { height: 40 } }); var _default = exports.default = BillingManagementScreen; //# sourceMappingURL=BillingManagementScreen.js.map