UNPKG

@oxyhq/services

Version:

OxyHQ Expo/React Native SDK — UI components, screens, and native features

259 lines (249 loc) 9.44 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _reactNative = require("react-native"); var _index = require("../styles/index.js"); var _themeUtils = require("../utils/themeUtils.js"); var _GroupedPillButtons = _interopRequireDefault(require("../components/internal/GroupedPillButtons.js")); var _useThemeStyles = require("../hooks/useThemeStyles.js"); var _reactNativeQrcodeSvg = _interopRequireDefault(require("react-native-qrcode-svg")); var _index2 = require("../components/payment/index.js"); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } 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 getUniqueItemTypes = items => { const types = items.map(item => item.type); return Array.from(new Set(types)); }; const PaymentGatewayScreen = props => { const { navigate, goBack, theme, onPaymentResult, amount, currency = 'FAIR', onClose, paymentItems = [], description = '' } = props; // DEV ENFORCEMENT: Only allow one type of payment item if (process.env.NODE_ENV !== 'production' && paymentItems.length > 0) { const uniqueTypes = getUniqueItemTypes(paymentItems); if (uniqueTypes.length > 1) { throw new Error(`PaymentGatewayScreen: paymentItems contains mixed types (${uniqueTypes.join(', ')}). Only one type is allowed per payment.`); } } // Step states const [currentStep, setCurrentStep] = (0, _react.useState)(0); const [paymentMethod, setPaymentMethod] = (0, _react.useState)('card'); const [cardDetails, setCardDetails] = (0, _react.useState)({ number: '', expiry: '', cvv: '' }); const [isPaying, setIsPaying] = (0, _react.useState)(false); // Animations const fadeAnim = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current; const slideAnim = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current; const scaleAnim = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current; const progressAnim = (0, _react.useRef)(new _reactNative.Animated.Value(0.2)).current; const normalizedTheme = (0, _themeUtils.normalizeTheme)(theme); const colors = (0, _index.useThemeColors)(normalizedTheme); const themeStyles = (0, _useThemeStyles.useThemeStyles)(normalizedTheme); const styles = (0, _react.useMemo)(() => (0, _index2.createPaymentStyles)(colors), [colors]); // Determine if the payment is for a recurring item (subscription) const isRecurring = paymentItems.length > 0 && paymentItems[0].type === 'subscription'; // Filter payment methods: remove 'faircoin' if recurring const availablePaymentMethods = (0, _react.useMemo)(() => { if (isRecurring) { return _index2.PAYMENT_METHODS.filter(m => m.key !== 'faircoin'); } return _index2.PAYMENT_METHODS; }, [isRecurring]); // Animation transitions const animateTransition = (0, _react.useCallback)(nextStep => { _reactNative.Animated.timing(scaleAnim, { toValue: 0.95, duration: 150, useNativeDriver: _reactNative.Platform.OS !== 'web' }).start(); _reactNative.Animated.timing(fadeAnim, { toValue: 0, duration: 200, useNativeDriver: _reactNative.Platform.OS !== 'web' }).start(() => { setCurrentStep(nextStep); slideAnim.setValue(-50); scaleAnim.setValue(0.95); _reactNative.Animated.parallel([_reactNative.Animated.timing(fadeAnim, { toValue: 1, duration: 300, useNativeDriver: _reactNative.Platform.OS !== 'web' }), _reactNative.Animated.spring(slideAnim, { toValue: 0, tension: 80, friction: 8, useNativeDriver: _reactNative.Platform.OS !== 'web' }), _reactNative.Animated.spring(scaleAnim, { toValue: 1, tension: 80, friction: 8, useNativeDriver: _reactNative.Platform.OS !== 'web' })]).start(); }); }, [fadeAnim, slideAnim, scaleAnim]); const nextStep = (0, _react.useCallback)(() => { if (currentStep < 4) { _reactNative.Animated.timing(progressAnim, { toValue: (currentStep + 2) / 5, duration: 300, useNativeDriver: false }).start(); animateTransition(currentStep + 1); } }, [currentStep, progressAnim, animateTransition]); const prevStep = (0, _react.useCallback)(() => { if (currentStep > 0) { _reactNative.Animated.timing(progressAnim, { toValue: currentStep / 5, duration: 300, useNativeDriver: false }).start(); animateTransition(currentStep - 1); } }, [currentStep, progressAnim, animateTransition]); // Pay handler - TODO: Replace with actual payment API const handlePay = (0, _react.useCallback)(() => { setIsPaying(true); setTimeout(() => { setIsPaying(false); nextStep(); }, 1500); }, [nextStep]); const handleDone = (0, _react.useCallback)(() => { if (onPaymentResult) { onPaymentResult({ success: true }); } navigate?.('AccountOverview'); }, [onPaymentResult, navigate]); const handleClose = (0, _react.useCallback)(() => { if (onPaymentResult) { onPaymentResult({ success: false, error: 'cancelled' }); } if (onClose) { onClose(); } else if (goBack) { goBack(); } }, [onPaymentResult, onClose, goBack]); // Validate amount if (!amount || isNaN(Number(amount)) || Number(amount) <= 0) { return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.errorContainer, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, { style: styles.errorText, children: "Invalid or missing payment amount." }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_GroupedPillButtons.default, { buttons: [{ text: 'Close', onPress: handleClose, icon: 'close', variant: 'primary' }], colors: colors })] }); } // FairCoin address - TODO: Replace with dynamic address from backend const faircoinAddress = 'f1abc1234FAIRCOINADDRESS'; const { width: windowWidth } = (0, _reactNative.useWindowDimensions)(); const isMobile = windowWidth < 600; const qrSize = !isMobile ? Math.min(windowWidth * 0.3, 220) : Math.min(windowWidth * 0.8, 300); const animations = { fadeAnim, slideAnim, scaleAnim }; const renderCurrentStep = () => { switch (currentStep) { case 0: return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.PaymentSummaryStep, { paymentItems: paymentItems, amount: amount, currency: currency, description: description, colors: colors, animations: animations, onClose: handleClose, onNext: nextStep }); case 1: return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.PaymentMethodStep, { availablePaymentMethods: availablePaymentMethods, selectedMethod: paymentMethod, onSelectMethod: setPaymentMethod, colors: colors, animations: animations, onBack: prevStep, onNext: nextStep }); case 2: return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.PaymentDetailsStep, { paymentMethod: paymentMethod, cardDetails: cardDetails, onCardDetailsChange: setCardDetails, colors: colors, animations: animations, faircoinAddress: faircoinAddress, isMobile: isMobile, qrSize: qrSize, onBack: prevStep, onNext: nextStep, QRCodeComponent: _reactNativeQrcodeSvg.default }); case 3: return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.PaymentReviewStep, { amount: amount, currency: currency, paymentMethod: paymentMethod, cardDetails: cardDetails, colors: colors, animations: animations, isPaying: isPaying, onBack: prevStep, onPay: handlePay }); case 4: return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.PaymentSuccessStep, { colors: colors, animations: animations, onDone: handleDone }); default: return null; } }; return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: [styles.container, { backgroundColor: themeStyles.backgroundColor }], children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, { style: styles.content, showsVerticalScrollIndicator: false, children: renderCurrentStep() }) }); }; var _default = exports.default = PaymentGatewayScreen; //# sourceMappingURL=PaymentGatewayScreen.js.map