UNPKG

omnipay-savings-sdk

Version:

Omnipay Savings SDK

177 lines (176 loc) 13.6 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const react_native_1 = require("react-native"); const SmartImage_1 = require("../Images/SmartImage"); const utils_1 = require("../../utils"); const Button_1 = require("../Button"); const currency_1 = __importDefault(require("../Input/currency")); const Text_1 = require("../Text"); const useHandleChangeNotrim_1 = __importDefault(require("../../hooks/useHandleChangeNotrim")); const info_1 = require("../Common/info"); const checkBox_1 = __importDefault(require("../RadioButton/checkBox")); const SDKConfigContext_1 = require("../../contexts/SDKConfigContext"); const modal_1 = require("../Common/modal"); const react_query_1 = require("@tanstack/react-query"); const actions_1 = require("../../services/actions"); const Notification_1 = __importDefault(require("../Feedback/Notification")); const WithdrawalDuration = (props) => { const { numberOfTimes, withdrawalLimit, containerStyle } = props; return ((0, jsx_runtime_1.jsxs)(react_native_1.View, Object.assign({ style: [ { paddingVertical: (0, utils_1.ms)(10), paddingHorizontal: (0, utils_1.ms)(10), rowGap: (0, utils_1.ms)(7.5), borderRadius: (0, utils_1.ms)(4), backgroundColor: utils_1.Colors.neutral0X, }, containerStyle, ] }, { children: [(0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(12), lineHeight: (0, utils_1.fontSz)(12 * 1.2), fontFamily: 'Gordita-Regular', fontWeight: "400", text: `${'Withdrawal this month'}`, color: utils_1.Colors.payLaterHeaderText, textAlign: 'center' }), (0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(12), lineHeight: (0, utils_1.fontSz)(12 * 1.2), fontFamily: 'Gordita-Medium', fontWeight: "900", text: `${numberOfTimes} out of ${withdrawalLimit || 3} times`, color: utils_1.Colors.payLaterHeaderText, textAlign: 'center' })] }))); }; const Withdraw = (props) => { var _a; const { visible, onClose, onPressContinue, resetPin, plan, withdrawalLimit, isLockedSavings, penaltyFeePercentage, isBeforeMaturity } = props; const [agreement, setAgreement] = (0, react_1.useState)(false); const [showSuccessNotification, setShowSuccessNotification] = (0, react_1.useState)(false); const { primaryColor, apiKey } = (0, SDKConfigContext_1.useSDKConfig)(); const queryClient = (0, react_query_1.useQueryClient)(); const [errors, setErrors] = (0, useHandleChangeNotrim_1.default)({ code: '', amount: '', }); const [details, setDetails] = (0, useHandleChangeNotrim_1.default)({ code: '', amount: '', }); const { code, amount } = details; const useableSavingsBalance = Number((_a = plan === null || plan === void 0 ? void 0 : plan.accountBalance) !== null && _a !== void 0 ? _a : 0); const withdrawalAmount = Number(amount); // Calculate penalty fee for early withdrawal from locked savings const penaltyFee = (isLockedSavings && isBeforeMaturity && penaltyFeePercentage) ? (withdrawalAmount * penaltyFeePercentage) / 100 : 0; const totalDeduction = withdrawalAmount + penaltyFee; const netAmountReceived = withdrawalAmount - penaltyFee; // Mutation for withdrawing from savings account const { mutate: withdrawSavings, isPending: isWithdrawPending, } = (0, react_query_1.useMutation)({ mutationFn: (params) => (0, actions_1.withdrawFromSavingsAccount)(apiKey, params), onSuccess: (response) => { if (response === null || response === void 0 ? void 0 : response.success) { queryClient.invalidateQueries({ queryKey: ['savingsDetails', plan === null || plan === void 0 ? void 0 : plan.savingsId, apiKey], }); queryClient.invalidateQueries({ queryKey: ['walletBalance', apiKey], }); queryClient.invalidateQueries({ queryKey: ['savingsListByCustomerId', apiKey], }); queryClient.invalidateQueries({ queryKey: ['totalAccountTransactionsByCustomerId', apiKey], }); setShowSuccessNotification(true); } }, onError: (error) => { console.error('Withdraw from savings account error:', error); }, }); function updateAmount(value) { setDetails('amount', value); const withdrawAmount = Number(value); const penalty = (isLockedSavings && isBeforeMaturity && penaltyFeePercentage) ? (withdrawAmount * penaltyFeePercentage) / 100 : 0; const total = withdrawAmount + penalty; if (total > useableSavingsBalance) { setErrors('amount', `Total deduction (₦${(0, utils_1.formatAsCurrency)(total)}) exceeds your balance of ${(0, utils_1.formatAsCurrency)(useableSavingsBalance)}`); } else { setErrors('amount', ''); } } function updateCode(value) { setDetails('code', value); setErrors('code', ''); } function updateAgreement() { setAgreement(!agreement); } const handleWithdraw = () => { if (!amount || Number(amount) <= 0) { return; } // Convert amount to kobo (multiply by 100) const amountInKobo = Math.round(Number(amount) * 100); withdrawSavings({ savingsId: plan === null || plan === void 0 ? void 0 : plan.savingsId, amount: amountInKobo, }); }; const handleSuccessNotificationClose = () => { setShowSuccessNotification(false); onClose(); }; // Calculate if user is about to cross the withdrawal limit (show warning only when crossing over) const isAboutToCrossLimit = Number(plan === null || plan === void 0 ? void 0 : plan.noOfWithdrawals) === (withdrawalLimit || 3); // Determine if withdrawal button should be disabled const isWithdrawDisabled = () => { // Basic validation if (!amount || Number(amount) <= 0 || errors.amount.length > 0) { return true; } // Check if user is about to cross withdrawal limit and needs to agree if (isAboutToCrossLimit && !agreement) { return true; } return false; }; return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(modal_1.Modal, Object.assign({ visible: visible && !showSuccessNotification, title: "Withdraw", onClose: onClose, footer: (0, jsx_runtime_1.jsx)(Button_1.Button, { title: !amount || Number(amount) <= 0 ? 'Withdraw' : `Withdraw ${(0, utils_1.formatAsCurrency)(Number(amount))}`, onPress: handleWithdraw, disabled: isWithdrawDisabled(), isLoading: isWithdrawPending }) }, { children: (0, jsx_runtime_1.jsxs)(react_native_1.View, Object.assign({ style: { paddingHorizontal: (0, utils_1.wp)(15), minHeight: isAboutToCrossLimit || isLockedSavings ? (0, utils_1.ms)(450) : (0, utils_1.ms)(350), // alignItems: 'center', } }, { children: [(0, jsx_runtime_1.jsx)(SmartImage_1.SmartImage, { source: utils_1.Images.completeTransaction, style: { width: (0, utils_1.ms)(48), height: (0, utils_1.ms)(48), alignSelf: 'center', } }), !isLockedSavings && ((0, jsx_runtime_1.jsx)(WithdrawalDuration, { numberOfTimes: String((plan === null || plan === void 0 ? void 0 : plan.noOfWithdrawals) || 0), containerStyle: { marginTop: (0, utils_1.ms)(10), alignSelf: 'center' }, withdrawalLimit: withdrawalLimit })), (0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(14), lineHeight: (0, utils_1.fontSz)(15.11), fontWeight: "400", text: `Withdraw from your ${plan === null || plan === void 0 ? void 0 : plan.accountName} Savings Account`, color: utils_1.Colors.completeTransactionTitle, textAlign: 'center', style: { paddingTop: (0, utils_1.ms)(30), paddingBottom: (0, utils_1.ms)(20), } }), (0, jsx_runtime_1.jsx)(currency_1.default, { value: amount, onChangeValue: (value) => { updateAmount(value); }, ignoreNegative: false, delimiter: ",", separator: ".", precision: 2, returnKeyType: "done", topComponent: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {}), walletAmount: useableSavingsBalance, paymentAmount: withdrawalAmount, onPressUseAllBalance: () => { setDetails('amount', String(useableSavingsBalance)); setErrors('amount', ''); }, onEndEditing: () => { }, onFocus: () => { }, label: 'Amount', showAsterisk: false, placeholder: '', balance: useableSavingsBalance, errorMsg: errors.amount || '', showUseAllBalance: useableSavingsBalance > 0, showCurrency: true }, useableSavingsBalance.toString()), isLockedSavings && isBeforeMaturity && penaltyFeePercentage && penaltyFeePercentage > 0 && withdrawalAmount > 0 && ((0, jsx_runtime_1.jsxs)(react_native_1.View, Object.assign({ style: { backgroundColor: utils_1.Colors.neutral0X, borderRadius: (0, utils_1.ms)(8), padding: (0, utils_1.ms)(16), marginTop: (0, utils_1.ms)(32), marginBottom: (0, utils_1.ms)(8), } }, { children: [(0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(13), fontFamily: "Gordita-Medium", fontWeight: "500", text: "Fee Breakdown", color: utils_1.Colors.completeTransactionTitle, style: { marginBottom: (0, utils_1.ms)(12) } }), (0, jsx_runtime_1.jsxs)(react_native_1.View, Object.assign({ style: { rowGap: (0, utils_1.ms)(8) } }, { children: [(0, jsx_runtime_1.jsxs)(react_native_1.View, Object.assign({ style: utils_1.globalStyles.rowBetween }, { children: [(0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(12), fontFamily: "Gordita-Regular", fontWeight: "400", text: "Withdrawal Amount", color: utils_1.Colors.payLaterHeaderText }), (0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(12), fontFamily: "Gordita-Medium", fontWeight: "500", text: (0, utils_1.formatAsCurrency)(withdrawalAmount), color: utils_1.Colors.completeTransactionTitle })] })), (0, jsx_runtime_1.jsxs)(react_native_1.View, Object.assign({ style: utils_1.globalStyles.rowBetween }, { children: [(0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(12), fontFamily: "Gordita-Regular", fontWeight: "400", text: `Early Withdrawal Fee (${penaltyFeePercentage}%)`, color: utils_1.Colors.payLaterHeaderText }), (0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(12), fontFamily: "Gordita-Medium", fontWeight: "500", text: `-${(0, utils_1.formatAsCurrency)(penaltyFee)}`, color: utils_1.Colors.debitRed })] })), (0, jsx_runtime_1.jsx)(react_native_1.View, { style: { height: 1, backgroundColor: utils_1.Colors.neutral20, marginVertical: (0, utils_1.ms)(4), } }), (0, jsx_runtime_1.jsxs)(react_native_1.View, Object.assign({ style: utils_1.globalStyles.rowBetween }, { children: [(0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(13), fontFamily: "Gordita-Medium", fontWeight: "600", text: "You'll Receive", color: utils_1.Colors.completeTransactionTitle }), (0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(14), fontFamily: "Gordita-Medium", fontWeight: "600", text: (0, utils_1.formatAsCurrency)(netAmountReceived), color: utils_1.Colors.creditGreen })] }))] }))] }))), isAboutToCrossLimit && ((0, jsx_runtime_1.jsx)(info_1.Info, { text: 'Withdrawal Limit Reached, Interest at stake', containerStyle: { marginBottom: (0, utils_1.ms)(16), marginTop: (0, utils_1.ms)(32) } })), isAboutToCrossLimit && ((0, jsx_runtime_1.jsx)(checkBox_1.default, { containerStyle: { marginBottom: (0, utils_1.ms)(20), marginTop: (0, utils_1.ms)(15) }, label: 'I agree to lose my interest on my next withdrawal.', selected: agreement, onPress: () => updateAgreement() }))] })) })), showSuccessNotification && ((0, jsx_runtime_1.jsx)(Notification_1.default, { title: "Withdrawal Successful", description: `Your main account balance has been credited with ${(0, utils_1.formatAsCurrency)(Number(netAmountReceived))}`, image: utils_1.Images.credited, buttonText: "Close", onButtonPress: handleSuccessNotificationClose }))] })); }; exports.default = Withdraw; const styles = react_native_1.StyleSheet.create({ textFoot: { fontFamily: 'Gordita-Regular', fontSize: (0, utils_1.fontSz)(16), color: utils_1.Colors.gray500, fontWeight: '400', }, resetPin: { fontFamily: 'Gordita-Medium', fontSize: (0, utils_1.fontSz)(16), fontWeight: '500', }, });