@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
JavaScript
"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