152 lines
4.1 KiB
TypeScript
152 lines
4.1 KiB
TypeScript
import React, { useEffect, useRef } from 'react';
|
|
import {
|
|
View,
|
|
Text,
|
|
StyleSheet,
|
|
Animated,
|
|
Easing,
|
|
} from 'react-native';
|
|
import LucideIcon from '../components/common/LucideIcon';
|
|
import CustomModal from '../components/common/CustomModal';
|
|
import { responsiveFontSize } from 'react-native-responsive-dimensions';
|
|
import { useTheme } from '../hooks/ui/useTheme';
|
|
import FontsFamily from '../constents/FontsFamily';
|
|
|
|
interface ContributionProps {
|
|
data: any;
|
|
visible: boolean;
|
|
onClose: () => void;
|
|
onConfirm: () => void;
|
|
}
|
|
|
|
const ContributionDetails: React.FC<ContributionProps> = ({
|
|
data,
|
|
visible,
|
|
onClose,
|
|
onConfirm,
|
|
}) => {
|
|
const theme = useTheme();
|
|
|
|
// Animations
|
|
const fadeAnim = useRef(new Animated.Value(0)).current;
|
|
const slideAnim = useRef(new Animated.Value(20)).current;
|
|
|
|
useEffect(() => {
|
|
if (visible) {
|
|
Animated.parallel([
|
|
Animated.timing(fadeAnim, {
|
|
toValue: 1,
|
|
duration: 400,
|
|
useNativeDriver: true,
|
|
}),
|
|
Animated.timing(slideAnim, {
|
|
toValue: 0,
|
|
duration: 400,
|
|
easing: Easing.out(Easing.quad),
|
|
useNativeDriver: true,
|
|
}),
|
|
]).start();
|
|
} else {
|
|
fadeAnim.setValue(0);
|
|
slideAnim.setValue(20);
|
|
}
|
|
}, [visible]);
|
|
|
|
return (
|
|
<CustomModal
|
|
visible={visible}
|
|
onClose={onClose}
|
|
onConfirm={onConfirm}
|
|
confirmText="Contribute Now"
|
|
title="Contribution Summary"
|
|
>
|
|
<Animated.View style={{ opacity: fadeAnim, transform: [{ translateY: slideAnim }] }}>
|
|
{/* Info Card */}
|
|
<View style={[styles.card, { backgroundColor: theme.colors.background, borderColor: theme.colors.border }]}>
|
|
<View style={styles.headerRow}>
|
|
<LucideIcon name="wallet-outline" size={24} color={theme.colors.primary} />
|
|
<Text style={[styles.amount, { color: theme.colors.textPrimary }]}>₹{data?.totalPayable || data?.baseAmount}</Text>
|
|
</View>
|
|
|
|
<View style={styles.infoGrid}>
|
|
<InfoItem label="Base Amount" value={`₹${data?.baseAmount}`} />
|
|
<InfoItem label="Due Date" value={data?.dueDate} />
|
|
<InfoItem label="Cycle End" value={data?.cycleEnd} />
|
|
<InfoItem label="Late Fee" value={`₹${data?.effectiveLateFee || 0}`} />
|
|
</View>
|
|
</View>
|
|
|
|
{/* Status Card */}
|
|
<View style={[styles.miniCard, { backgroundColor: theme.colors.background, borderColor: theme.colors.border }]}>
|
|
<Text style={[styles.label, { color: theme.colors.textMuted }]}>Cycle {data?.cycleNumber}</Text>
|
|
{data?.alreadyPaid && (
|
|
<Text style={[styles.statusText, { color: theme.colors.primary }]}>Payment Already Completed</Text>
|
|
)}
|
|
</View>
|
|
</Animated.View>
|
|
</CustomModal>
|
|
);
|
|
};
|
|
|
|
const InfoItem = ({ label, value }: { label: string; value: string | number }) => {
|
|
const theme = useTheme();
|
|
return (
|
|
<View style={styles.infoItem}>
|
|
<Text style={[styles.label, { color: theme.colors.textMuted }]}>{label}</Text>
|
|
<Text style={[styles.value, { color: theme.colors.textSecondary }]}>{value}</Text>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
export default ContributionDetails;
|
|
|
|
const styles = StyleSheet.create({
|
|
card: {
|
|
padding: 20,
|
|
borderRadius: 16,
|
|
borderWidth: 1,
|
|
marginBottom: 12,
|
|
},
|
|
headerRow: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
gap: 12,
|
|
marginBottom: 20,
|
|
},
|
|
amount: {
|
|
fontSize: responsiveFontSize(2.8),
|
|
fontFamily: FontsFamily.nunitoBold,
|
|
},
|
|
infoGrid: {
|
|
flexDirection: 'row',
|
|
flexWrap: 'wrap',
|
|
gap: 16,
|
|
},
|
|
infoItem: {
|
|
width: '45%',
|
|
},
|
|
miniCard: {
|
|
padding: 16,
|
|
borderRadius: 12,
|
|
borderWidth: 1,
|
|
flexDirection: 'row',
|
|
justifyContent: 'space-between',
|
|
alignItems: 'center',
|
|
},
|
|
label: {
|
|
fontSize: responsiveFontSize(1.2),
|
|
fontFamily: FontsFamily.nunitoMedium,
|
|
textTransform: 'uppercase',
|
|
letterSpacing: 0.5,
|
|
},
|
|
value: {
|
|
fontSize: responsiveFontSize(1.6),
|
|
fontFamily: FontsFamily.nunitoBold,
|
|
marginTop: 2,
|
|
},
|
|
statusText: {
|
|
fontSize: responsiveFontSize(1.4),
|
|
fontFamily: FontsFamily.nunitoBold,
|
|
},
|
|
});
|