omnipay-savings-sdk
Version:
Omnipay Savings SDK
187 lines (186 loc) • 11.4 kB
JavaScript
"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 Text_1 = require("../Text");
const utils_1 = require("../../utils");
const currency_1 = __importDefault(require("../Input/currency"));
const Dropdown_1 = __importDefault(require("../Dropdown"));
const InterestRateTiers = ({ tiers, selectedDays, currentRate, onTierSelect, onDaysChange = () => { }, primaryColor, isLoading = false, minimumLockDurationDays, durationError = '', tierSelectionError = '', onSectionLayout, lockAmount, isInterestDisabled = false, selectedTier: parentSelectedTier = null, }) => {
const [showTierModal, setShowTierModal] = (0, react_1.useState)(false);
const [localSelectedTier, setLocalSelectedTier] = (0, react_1.useState)(null);
// Use parent's selectedTier if available, otherwise use local state
const selectedTier = parentSelectedTier || localSelectedTier;
// Find which tier contains the selected days
const getCurrentTier = () => {
return tiers.find(tier => selectedDays >= tier.minDays && selectedDays <= tier.maxDays);
};
const formatDurationText = (minDays, maxDays) => {
if (minDays === maxDays) {
return `${minDays} days`;
}
return `${minDays}-${maxDays} days`;
};
const formatTierDisplayText = (tier) => {
const rate = isInterestDisabled ? 0 : tier.interestRate;
const duration = formatDurationText(tier.minDays, tier.maxDays);
return `${duration} • ${rate}% per annum`;
};
// Calculate projected earnings based on amount, rate, and duration
const calculateProjectedEarnings = () => {
if (!lockAmount || !currentRate || !selectedDays || isInterestDisabled)
return 0;
const principal = lockAmount;
const annualRate = currentRate / 100;
const timeInYears = selectedDays / 365;
return principal * annualRate * timeInYears;
};
const handleTierSelection = (tier, isManualSelection = true) => {
setLocalSelectedTier(tier);
if (isManualSelection) {
setShowTierModal(false);
}
// Notify parent component about tier selection
onTierSelect(tier, isManualSelection);
// Reset days input only when manually selecting from dropdown
if (isManualSelection && onDaysChange) {
onDaysChange(0);
}
};
const handleDaysChange = (days) => {
if (onDaysChange) {
onDaysChange(days);
}
// Auto-select the appropriate tier based on entered days
if (days > 0) {
const matchingTier = tiers.find(tier => days >= tier.minDays && days <= tier.maxDays);
if (matchingTier && matchingTier.id !== (selectedTier === null || selectedTier === void 0 ? void 0 : selectedTier.id)) {
handleTierSelection(matchingTier, false); // false = auto-selection
}
}
};
if (isLoading) {
return ((0, jsx_runtime_1.jsx)(react_native_1.View, Object.assign({ style: styles.container }, { children: (0, jsx_runtime_1.jsx)(react_native_1.View, Object.assign({ style: styles.loadingContainer }, { children: (0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(14), fontFamily: "Gordita-Regular", fontWeight: "400", text: "Loading interest rates...", color: utils_1.Colors.inputBackgroundLight, textAlign: "center" }) })) })));
}
if (!tiers || tiers.length === 0) {
return null;
}
const currentTier = getCurrentTier();
const displayTier = selectedTier || currentTier;
// Calculate maximum days from all tiers
const maxDaysAvailable = Math.max(...tiers.map(tier => tier.maxDays));
return ((0, jsx_runtime_1.jsxs)(react_native_1.View, Object.assign({ style: styles.container }, { children: [(0, jsx_runtime_1.jsx)(Dropdown_1.default, { label: "How long do you want to lock for?", placeHolder: "Choose lock duration", value: displayTier ? formatTierDisplayText(displayTier) : '', onPress: () => setShowTierModal(true), showAsterisk: true, errorMsg: tierSelectionError, containerStyle: { marginBottom: (0, utils_1.ms)(24) } }), displayTier && ((0, jsx_runtime_1.jsx)(react_native_1.View, Object.assign({ style: styles.durationInputContainer, onLayout: onSectionLayout }, { children: (0, jsx_runtime_1.jsx)(currency_1.default, { value: selectedDays > 0 ? selectedDays.toString() : '', onChangeValue: (value) => {
const numericValue = Number(value);
// Limit input to maximum available range
if (numericValue <= maxDaysAvailable) {
handleDaysChange(numericValue);
}
}, ignoreNegative: false, delimiter: "", separator: "", precision: 0, containerStyle: { marginBottom: (0, utils_1.ms)(0) }, returnKeyType: "done", topComponent: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {}), walletAmount: 0, paymentAmount: selectedDays, onPressUseAllBalance: () => { }, onEndEditing: () => { }, onFocus: () => { }, label: `Lock Duration (${formatDurationText(displayTier.minDays, displayTier.maxDays)})`, showAsterisk: true, placeholder: `Enter days between ${displayTier.minDays} and ${displayTier.maxDays}`, balance: 0, wrapperStyle: {
borderColor: durationError ? utils_1.Colors.error : '#F4F4F4',
}, errorMsg: durationError, showUseAllBalance: false, showCurrency: false, hideBalance: true }) }))), (0, jsx_runtime_1.jsx)(react_native_1.Modal, Object.assign({ visible: showTierModal, transparent: true, animationType: "none", onRequestClose: () => setShowTierModal(false) }, { children: (0, jsx_runtime_1.jsx)(react_native_1.TouchableWithoutFeedback, Object.assign({ onPress: () => setShowTierModal(false) }, { children: (0, jsx_runtime_1.jsx)(react_native_1.View, Object.assign({ style: styles.modalOverlay }, { children: (0, jsx_runtime_1.jsx)(react_native_1.TouchableWithoutFeedback, Object.assign({ onPress: () => { } }, { children: (0, jsx_runtime_1.jsxs)(react_native_1.View, Object.assign({ style: styles.modalContent }, { children: [(0, jsx_runtime_1.jsx)(react_native_1.View, Object.assign({ style: styles.modalHeader }, { children: (0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(18), fontFamily: "Gordita-Medium", fontWeight: "500", text: "Choose Your Savings Duration", color: utils_1.Colors.headerText }) })), (0, jsx_runtime_1.jsx)(react_native_1.ScrollView, Object.assign({ style: styles.tiersList, showsVerticalScrollIndicator: false }, { children: tiers.map((tier) => ((0, jsx_runtime_1.jsxs)(react_native_1.TouchableOpacity, Object.assign({ style: [
styles.tierOption,
(displayTier === null || displayTier === void 0 ? void 0 : displayTier.id) === tier.id &&
styles.selectedTierOption,
], onPress: () => handleTierSelection(tier, true) }, { children: [(0, jsx_runtime_1.jsxs)(react_native_1.View, Object.assign({ style: styles.tierInfo }, { children: [(0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(16), fontFamily: "Gordita-Medium", fontWeight: "600", text: `${isInterestDisabled ? 0 : tier.interestRate}% per annum`, color: (displayTier === null || displayTier === void 0 ? void 0 : displayTier.id) === tier.id
? utils_1.Colors.primary
: utils_1.Colors.headerText }), (0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(14), fontFamily: "Gordita-Regular", fontWeight: "400", text: formatDurationText(tier.minDays, tier.maxDays), color: utils_1.Colors.inputBackgroundLight, style: { marginTop: (0, utils_1.ms)(4) } })] })), (displayTier === null || displayTier === void 0 ? void 0 : displayTier.id) === tier.id && ((0, jsx_runtime_1.jsx)(react_native_1.View, Object.assign({ style: styles.checkIcon }, { children: (0, jsx_runtime_1.jsx)(Text_1.Text, { fontSize: (0, utils_1.fontSz)(16), fontFamily: "Gordita-Medium", fontWeight: "600", text: "\u2713", color: utils_1.Colors.primary }) })))] }), tier.id))) }))] })) })) })) })) }))] })));
};
const styles = react_native_1.StyleSheet.create({
container: {
marginTop: (0, utils_1.ms)(16),
},
loadingContainer: {
paddingVertical: (0, utils_1.ms)(20),
alignItems: 'center',
},
durationInputContainer: {
marginBottom: (0, utils_1.ms)(16),
},
earningsCard: {
marginBottom: (0, utils_1.ms)(24),
backgroundColor: '#F8F9FA',
borderRadius: (0, utils_1.ms)(12),
paddingHorizontal: (0, utils_1.ms)(16),
paddingVertical: (0, utils_1.ms)(16),
borderWidth: (0, utils_1.ms)(1),
borderColor: '#E9ECEF',
},
earningsHeader: {
marginBottom: (0, utils_1.ms)(12),
},
earningsContent: {
gap: (0, utils_1.ms)(8),
},
earningsRow: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: (0, utils_1.ms)(4),
},
rateDisplay: {
flexDirection: 'row',
alignItems: 'baseline',
},
divider: {
height: (0, utils_1.ms)(1),
backgroundColor: '#E9ECEF',
marginVertical: (0, utils_1.ms)(8),
},
modalOverlay: {
flex: 1,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
justifyContent: 'flex-end',
},
modalContent: {
backgroundColor: utils_1.Colors.white,
borderTopLeftRadius: (0, utils_1.ms)(20),
borderTopRightRadius: (0, utils_1.ms)(20),
width: '100%',
maxHeight: '70%',
paddingBottom: (0, utils_1.ms)(20),
shadowColor: utils_1.Colors.shadowColor,
shadowOffset: { width: 0, height: -4 },
shadowOpacity: 0.25,
shadowRadius: 8,
elevation: 8,
},
modalHeader: {
paddingHorizontal: (0, utils_1.ms)(20),
paddingTop: (0, utils_1.ms)(20),
paddingBottom: (0, utils_1.ms)(16),
borderBottomWidth: 1,
borderBottomColor: '#E9ECEF',
},
tiersList: {
paddingHorizontal: (0, utils_1.ms)(20),
paddingTop: (0, utils_1.ms)(20),
maxHeight: (0, utils_1.ms)(400),
},
tierOption: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: (0, utils_1.ms)(16),
paddingHorizontal: (0, utils_1.ms)(16),
borderRadius: (0, utils_1.ms)(8),
marginBottom: (0, utils_1.ms)(8),
backgroundColor: '#F8F9FA',
borderWidth: (0, utils_1.ms)(1),
borderColor: '#E9ECEF',
},
selectedTierOption: {
backgroundColor: '#F0F8FF',
borderColor: utils_1.Colors.primary,
},
tierInfo: {
flex: 1,
},
checkIcon: {
marginLeft: (0, utils_1.ms)(12),
},
});
exports.default = InterestRateTiers;