import React, { memo, useCallback, useRef, useState } from 'react'; import { View, Text, TouchableOpacity, StyleSheet, Platform, TextInput, Alert } from 'react-native'; import Animated, { FadeInUp, Layout, interpolate, useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated'; import colors_const from '../../../Constant/Color'; import AuctionItemDetail from '../../Auction/Modal/AuctionItemDetail'; import MainStyle from '../../../Styles/MainStyle'; import { useTheme } from '../../../Hooks/useTheme'; import AppText from '../../../components/AppText'; import { Loader } from '../../../Component/Index'; import { useSelector } from 'react-redux'; import axios from 'axios'; import Variables from '../../../Constant/Variable'; import { showErrorAlert, showSuccessAlert } from '../../../Constant/ShowDailog'; const BiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid, SelectedAuction, allBoolean, setAllBoolean }: any) => { const { colors } = useTheme(); const styles = React.useMemo(() => makeStyles(colors), [colors]); const Token = useSelector((state: any) => state.token.token) const [showDetail, setShowDetail] = useState(false); const [value, setValue] = useState(`${item.bidAmount}`); const [allState, setAllState] = useState({ isLoading: false }) const isMin = bidValue <= item.bidAmount; // 🔒 Persist expand state safely const expandedRef = useRef(false); const animation = useSharedValue(0); const toggleExpand = useCallback(() => { expandedRef.current = !expandedRef.current; animation.value = withSpring(expandedRef.current ? 1 : 0, { damping: 15, stiffness: 140, }); }, []); const bodyStyle = useAnimatedStyle(() => ({ height: interpolate(animation.value, [0, 1], [0, 190]), opacity: interpolate(animation.value, [0, 0.5, 1], [0, 0, 1]), marginTop: interpolate(animation.value, [0, 1], [0, 15]), })); const bodyStyle2 = useAnimatedStyle(() => ({ height: interpolate(animation.value, [0, 1], [0, 100]), opacity: interpolate(animation.value, [0, 0.5, 1], [0, 0, 1]), marginTop: interpolate(animation.value, [0, 1], [0, 15]), })); const arrowStyle = useAnimatedStyle(() => ({ transform: [ { rotate: `${interpolate(animation.value, [0, 1], [0, 180])}deg`, }, ], })); const MAX_VALUE = Number(item.bidAmount); const handleChange = (text: string) => { let cleaned = text.replace(/[^0-9.]/g, ''); if ((cleaned.match(/\./g) || []).length > 1) return; setValue(cleaned); }; const oneTimePlaceBid = async () => { try { if (Number(value) < MAX_VALUE) { showErrorAlert("Enter the greather vlaue to current bid value") return false } setAllState((prev: any) => ({ ...prev, isLoading: true })) const payload = { itemId: item.id, bidAmount: Number(value), auctionId: SelectedAuction.auctionId, contractorId: Token.contractorId, fullName: Token.fullName, }; const res = await axios.post( `${Variables.socketUrl}bidding/placeBidForAuction`, [payload], { headers: { Authentication: `Bearer ${Token.token}` } } ); if (res.data.statusCode === 200) { showSuccessAlert(res.data.message); } setAllBoolean((prev: any) => ({ ...prev, reload: !prev.reload })) } catch (error) { if (axios.isAxiosError(error)) { showErrorAlert(error.response?.data.message) } else { console.log('UNKNOWN ERROR:', error); } } finally { setAllState((prev: any) => ({ ...prev, isLoading: false })) } } return ( { !showDetail ? {/* HEADER */} { setShowDetail(true) }} style={styles.cardHeader} > {item.productName} {/* auctionStartValueFigure */} Initial Amt : {item?.auctionStartValueFigure} {item.me ? 'LEADING' : 'LIVE'} ▼ {SelectedAuction?.auctionNumber} {/* PRICE INFO */} Current Bid ₹{item?.bidAmount || item.auctionStartValueFigure} Increment +₹{item.bidVariationValue} {/* COLLAPSIBLE BODY */} Set Your Bid {!allBoolean.oneTimeBid && − ₹ {bidValue} + } { (allBoolean.oneTimeBid || allBoolean.rebid) && ₹ } {(!allBoolean.rebid && item.contractorId == undefined) ? { allState.isLoading ? : Confirm Bid } : null} : { setShowDetail(false) }} visible={showDetail} /> } ) }; export default memo(BiddingCard); const makeStyles = (colors: any) => StyleSheet.create({ inputBox2: { flexDirection: 'row', alignItems: 'center', backgroundColor: colors.background, borderRadius: 12, height: 45, paddingHorizontal: 12, width: '100%', marginBottom: 20 }, currency2: { marginRight: 4, } as any, input: { flex: 1, fontSize: 18, fontWeight: '700', width: '100%' }, card: { borderRadius: 24, padding: 20, marginBottom: 16, borderWidth: 1, overflow: 'hidden', }, leadingCard: { borderWidth: 2, }, cardHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start', }, headerRight: { flexDirection: 'column', alignItems: 'center', gap: 8 }, productName: {} as any, itemIdText: { marginTop: 2 } as any, badge: { paddingHorizontal: 10, paddingVertical: 4, borderRadius: 8 }, liveBadge: { backgroundColor: `${colors.error}20` }, meBadge: { backgroundColor: `${colors.success}20` }, badgeText: { fontSize: 10 } as any, liveText: { color: colors.error }, meText: { color: colors.success }, arrow: { fontSize: 10 }, priceRow: { flexDirection: 'row', justifyContent: 'space-between', marginTop: 20 }, label: { textTransform: 'uppercase', } as any, mainPrice: {} as any, incrementText: {} as any, collapsibleContainer: { overflow: 'hidden' }, divider: { height: 1, backgroundColor: colors.border, marginVertical: 10 }, bidLabel: { marginBottom: 10 } as any, stepperContainer: { flexDirection: 'row', gap: 12, marginBottom: 20 }, stepBtn: { width: 45, height: 45, backgroundColor: colors.primary, borderRadius: 12, justifyContent: 'center', alignItems: 'center', }, disabledBtn: { backgroundColor: colors.border }, stepText: {} as any, inputBox: { flex: 1, height: 45, backgroundColor: colors.background, borderRadius: 12, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', }, currency: { marginRight: 4 } as any, bidValueText: {} as any, submitBtn: { height: 50, backgroundColor: colors.primary, borderRadius: 15, justifyContent: 'center', alignItems: 'center', }, submitBtnText: {} as any, });