160 lines
4.1 KiB
TypeScript
160 lines
4.1 KiB
TypeScript
import React, { useEffect, useRef } from "react";
|
|
import {
|
|
View,
|
|
Text,
|
|
StyleSheet,
|
|
Animated,
|
|
Easing,
|
|
} from "react-native";
|
|
import { Ionicons } from "@react-native-vector-icons/ionicons";
|
|
import colors from "../components/colors";
|
|
import CustomModal from "../components/common/CustomModal";
|
|
|
|
interface ContributionProps {
|
|
data: any;
|
|
visible: boolean;
|
|
onClose: () => void;
|
|
onConfirm: () => void;
|
|
}
|
|
|
|
const ContributionDetails: React.FC<ContributionProps> = ({
|
|
data,
|
|
visible,
|
|
onClose,
|
|
onConfirm,
|
|
}) => {
|
|
// Animations
|
|
const fadeAnim = useRef(new Animated.Value(0)).current;
|
|
const slideAnim = useRef(new Animated.Value(50)).current;
|
|
const scaleAnim = useRef(new Animated.Value(0.9)).current;
|
|
|
|
useEffect(() => {
|
|
if (visible) {
|
|
Animated.parallel([
|
|
Animated.timing(fadeAnim, {
|
|
toValue: 1,
|
|
duration: 600,
|
|
useNativeDriver: true,
|
|
}),
|
|
Animated.timing(slideAnim, {
|
|
toValue: 0,
|
|
duration: 600,
|
|
easing: Easing.out(Easing.exp),
|
|
useNativeDriver: true,
|
|
}),
|
|
Animated.spring(scaleAnim, {
|
|
toValue: 1,
|
|
friction: 6,
|
|
useNativeDriver: true,
|
|
}),
|
|
]).start();
|
|
} else {
|
|
fadeAnim.setValue(0);
|
|
slideAnim.setValue(50);
|
|
scaleAnim.setValue(0.9);
|
|
}
|
|
}, [visible]);
|
|
|
|
return (
|
|
<CustomModal visible={visible} onClose={onClose} onConfirm={onConfirm} confirmButton={colors.pastelOrange} confirmTextColor={colors.black} elevation={5}>
|
|
{/* Header */}
|
|
<Animated.View
|
|
style={[
|
|
styles.header,
|
|
{ opacity: fadeAnim, transform: [{ translateY: slideAnim }] },
|
|
]}
|
|
>
|
|
<Ionicons name="wallet-outline" size={32} color={colors.black} />
|
|
<Text style={styles.headerTitle}>Contribution Summary</Text>
|
|
</Animated.View>
|
|
|
|
{/* Contribution Info Card */}
|
|
<Animated.View
|
|
style={[
|
|
styles.card,
|
|
{ transform: [{ scale: scaleAnim }], opacity: fadeAnim },
|
|
]}
|
|
>
|
|
<Text style={styles.label}>Base Amount</Text>
|
|
<Text style={styles.value}>₹{data?.baseAmount}</Text>
|
|
{
|
|
data?.alreadyPaid ? <Text style={styles?.valueHighlight}>Already Paid Amount</Text> :
|
|
<View>
|
|
<Text style={styles.label}>Total Payable</Text>
|
|
<Text style={styles.valueHighlight}>₹{data?.totalPayable}</Text>
|
|
</View>}
|
|
|
|
|
|
<Text style={styles.label}>Due Date</Text>
|
|
<Text style={styles.value}>{data?.dueDate}</Text>
|
|
|
|
<Text style={styles.label}>Cycle End</Text>
|
|
<Text style={styles.value}>{data?.cycleEnd}</Text>
|
|
</Animated.View>
|
|
|
|
{/* Extra Details */}
|
|
<Animated.View
|
|
style={[
|
|
styles.card,
|
|
{ transform: [{ translateY: slideAnim }], opacity: fadeAnim },
|
|
]}
|
|
>
|
|
<Text style={styles.label}>Cycle Number</Text>
|
|
<Text style={styles.value}>{data?.cycleNumber}</Text>
|
|
|
|
<Text style={styles.label}>Late Fee Mode</Text>
|
|
<Text style={styles.value}>{data?.lateFeeMode}</Text>
|
|
|
|
<Text style={styles.label}>Late Fee Value</Text>
|
|
<Text style={styles.value}>₹{data?.lateFeeValue}</Text>
|
|
|
|
<Text style={styles.label}>Effective Late Fee</Text>
|
|
<Text style={styles.value}>₹{data?.effectiveLateFee}</Text>
|
|
</Animated.View>
|
|
</CustomModal>
|
|
);
|
|
};
|
|
|
|
export default ContributionDetails;
|
|
|
|
const styles = StyleSheet.create({
|
|
header: {
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
marginBottom: 24,
|
|
},
|
|
headerTitle: {
|
|
fontSize: 22,
|
|
fontWeight: "700",
|
|
marginLeft: 10,
|
|
},
|
|
card: {
|
|
backgroundColor: "#fff",
|
|
padding: 16,
|
|
borderRadius: 16,
|
|
marginBottom: 16,
|
|
shadowColor: "#000",
|
|
shadowOpacity: 0.08,
|
|
shadowOffset: { width: 0, height: 3 },
|
|
shadowRadius: 6,
|
|
elevation: 3,
|
|
},
|
|
label: {
|
|
fontSize: 13,
|
|
color: "#6b7280",
|
|
marginTop: 6,
|
|
},
|
|
value: {
|
|
fontSize: 15,
|
|
fontWeight: "500",
|
|
color: "#374151",
|
|
marginBottom: 6,
|
|
},
|
|
valueHighlight: {
|
|
fontSize: 18,
|
|
fontWeight: "700",
|
|
color: colors.black,
|
|
marginBottom: 10,
|
|
},
|
|
});
|