omnipay-savings-sdk
Version:
Omnipay Savings SDK
171 lines (170 loc) • 8.04 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const jsx_runtime_1 = require("react/jsx-runtime");
const react_native_1 = require("react-native");
const Text_1 = require("../Text");
const utils_1 = require("../../utils");
const savingsCalculations_1 = require("../../utils/savingsCalculations");
const FlexibleInterestDisplay = ({ currentRate, savingsTarget, periodicSavingsAmount, selectedFrequency, startDate, endDate, isInterestDisabled = false, onSectionLayout, onAutoCalculate, }) => {
// Helper function to get days per frequency
const getFrequencyDays = (frequency) => {
const frequencyEnum = (0, utils_1.getFrequencyEnum)(frequency);
switch (frequencyEnum) {
case 1:
return 1; // Daily
case 2:
return 7; // Weekly
case 3:
return 30; // Monthly
case 4:
return 1; // On inflow (treat as daily for calculation)
default:
return 1;
}
};
// Calculate total savings period in days
const getSavingsPeriodDays = () => {
if (!startDate || !endDate)
return 0;
const timeDiff = endDate.getTime() - startDate.getTime();
return Math.ceil(timeDiff / (1000 * 3600 * 24));
};
// Calculate total amount that will be saved over the period
const calculateTotalSavingsAmount = () => {
if (!periodicSavingsAmount || !selectedFrequency || !startDate || !endDate)
return 0;
const periodDays = getSavingsPeriodDays();
const frequencyDays = getFrequencyDays(selectedFrequency);
const numberOfPeriods = Math.floor(periodDays / frequencyDays);
return periodicSavingsAmount * numberOfPeriods;
};
// Calculate projected earnings with compound interest (daily accrual, monthly compounding)
const calculateProjectedEarnings = () => {
if (!periodicSavingsAmount ||
!currentRate ||
isInterestDisabled ||
!startDate ||
!endDate)
return 0;
return (0, savingsCalculations_1.calculateProjectedInterestEarnings)({
periodicAmount: periodicSavingsAmount,
selectedFrequency,
startDate,
endDate,
annualInterestRate: currentRate,
isInterestDisabled,
});
};
// Auto-calculate required periodic amount to reach target with interest
const calculateRequiredPeriodicAmount = () => {
if (!savingsTarget || !selectedFrequency || !startDate || !endDate)
return 0;
return (0, savingsCalculations_1.calculateRequiredPeriodicAmountWithInterest)({
savingsTarget,
selectedFrequency,
startDate,
endDate,
annualInterestRate: currentRate,
isInterestDisabled,
});
};
// Calculate final balance including compound interest
const calculateFinalBalanceWithCompoundInterest = () => {
if (!periodicSavingsAmount || !selectedFrequency || !startDate || !endDate)
return 0;
return (0, savingsCalculations_1.calculateFinalBalanceWithCompoundInterest)({
periodicAmount: periodicSavingsAmount,
selectedFrequency,
startDate,
endDate,
annualInterestRate: currentRate,
isInterestDisabled,
});
};
// Check if we have enough data to show calculations
const hasCalculationData = periodicSavingsAmount > 0 && selectedFrequency && startDate && endDate;
const hasAutoCalculationData = savingsTarget > 0 &&
selectedFrequency &&
startDate &&
endDate &&
periodicSavingsAmount === 0;
const totalSavingsAmount = calculateTotalSavingsAmount();
const projectedEarnings = calculateProjectedEarnings();
const finalBalanceWithInterest = calculateFinalBalanceWithCompoundInterest();
const requiredPeriodicAmount = calculateRequiredPeriodicAmount();
const periodDays = getSavingsPeriodDays();
// Don't render if no relevant data
if (!hasCalculationData && !hasAutoCalculationData) {
return null;
}
return ((0, jsx_runtime_1.jsx)(react_native_1.View, Object.assign({ style: styles.container, onLayout: onSectionLayout }, { children: hasAutoCalculationData && ((0, jsx_runtime_1.jsxs)(react_native_1.View, Object.assign({ style: styles.autoCalculateSection }, { children: [(0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(12), fontFamily: "Gordita-Regular", fontWeight: "400", text: `To reach your target of ${(0, utils_1.formatAsCurrency)(savingsTarget)}, you need to save:`, color: utils_1.Colors.inputBackgroundLight, textAlign: "center", style: { marginBottom: (0, utils_1.ms)(12) } }), (0, jsx_runtime_1.jsxs)(react_native_1.View, Object.assign({ style: styles.autoCalculateResult }, { children: [(0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(18), fontFamily: "Gordita-Bold", fontWeight: "700", text: (0, utils_1.formatAsCurrency)(requiredPeriodicAmount), color: utils_1.Colors.headerText, textAlign: "center" }), (0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(12), fontFamily: "Gordita-Regular", fontWeight: "400", text: selectedFrequency.toLowerCase(), color: utils_1.Colors.inputBackgroundLight, textAlign: "center", style: { marginTop: (0, utils_1.ms)(4) } })] })), onAutoCalculate && ((0, jsx_runtime_1.jsx)(react_native_1.TouchableOpacity, Object.assign({ style: styles.autoCalculateButton, onPress: () => onAutoCalculate(requiredPeriodicAmount) }, { children: (0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(14), fontFamily: "Gordita-Medium", fontWeight: "500", text: "Use This Amount", color: utils_1.Colors.primary, textAlign: "center" }) })))] }))) })));
};
const styles = react_native_1.StyleSheet.create({
container: {
marginTop: (0, utils_1.ms)(0),
marginBottom: (0, utils_1.ms)(8),
},
earningsCard: {
backgroundColor: utils_1.Colors.white,
borderRadius: (0, utils_1.ms)(8),
borderWidth: 1,
borderColor: utils_1.Colors.gray200,
shadowColor: utils_1.Colors.shadowColor,
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 2,
marginTop: (0, utils_1.ms)(4),
},
earningsHeader: {
paddingHorizontal: (0, utils_1.ms)(16),
paddingTop: (0, utils_1.ms)(16),
paddingBottom: (0, utils_1.ms)(8),
},
earningsContent: {
paddingHorizontal: (0, utils_1.ms)(16),
paddingBottom: (0, utils_1.ms)(16),
},
earningsRow: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: (0, utils_1.ms)(8),
},
rateDisplay: {
flexDirection: 'row',
alignItems: 'baseline',
},
divider: {
height: 1,
backgroundColor: utils_1.Colors.gray200,
marginVertical: (0, utils_1.ms)(4),
},
autoCalculateSection: {
alignItems: 'center',
paddingVertical: (0, utils_1.ms)(16),
paddingHorizontal: (0, utils_1.ms)(16),
backgroundColor: utils_1.Colors.white,
borderRadius: (0, utils_1.ms)(8),
borderWidth: 1,
borderColor: utils_1.Colors.gray200,
shadowColor: utils_1.Colors.shadowColor,
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 2,
},
autoCalculateResult: {
alignItems: 'center',
marginBottom: (0, utils_1.ms)(16),
},
autoCalculateButton: {
backgroundColor: utils_1.Colors.lightPrimary,
paddingVertical: (0, utils_1.ms)(10),
paddingHorizontal: (0, utils_1.ms)(20),
borderRadius: (0, utils_1.ms)(6),
borderWidth: 1,
borderColor: utils_1.Colors.primary,
},
});
exports.default = FlexibleInterestDisplay;