import React, { useState, useEffect } from 'react'; import { StyleSheet, TextInput, TouchableOpacity, ActivityIndicator } from 'react-native'; import { View, Text, useTheme } from '@bettoredge/styles'; import { Ionicons } from '@expo/vector-icons'; import { formatCurrency } from '../helpers/formatting'; export interface CalcuttaBidInputProps { current_bid: number; min_bid: number; bid_increment: number; auction_type: 'sealed_bid' | 'live'; escrow_balance: number; existing_bid_amount?: number; onSubmit: (amount: number) => void | Promise; loading: boolean; disabled?: boolean; } export const CalcuttaBidInput: React.FC = ({ current_bid, min_bid, bid_increment, auction_type, escrow_balance, existing_bid_amount, onSubmit, loading, disabled, }) => { const { theme } = useTheme(); const minimumAllowed = auction_type === 'live' ? Math.max(Number(min_bid), Number(current_bid) + Number(bid_increment)) : Number(min_bid); const step = Number(bid_increment) > 0 ? Number(bid_increment) : 1; const available = escrow_balance; const isHighestBidder = existing_bid_amount != null && existing_bid_amount >= Number(current_bid) && Number(current_bid) > 0; const [raise, setRaise] = useState(0); const [error, setError] = useState(''); const [submitting, setSubmitting] = useState(false); // Total bid = minimum + raise const totalBid = minimumAllowed + raise; const canAfford = totalBid <= available; // Reset raise when minimum changes (new bid came in) useEffect(() => { setRaise(0); }, [minimumAllowed]); const handleSubmit = async () => { if (!canAfford) { setError(`Insufficient escrow. Available: ${formatCurrency(available)}`); return; } setSubmitting(true); setError(''); try { await onSubmit(totalBid); setRaise(0); } catch (e: any) { setError(e?.message || 'Failed to place bid'); } setSubmitting(false); }; const bumpUp = () => { const next = raise + step; if (minimumAllowed + next <= available) { setRaise(next); setError(''); } }; const bumpDown = () => { const next = raise - step; setRaise(Math.max(0, next)); setError(''); }; return ( {disabled ? ( Paused ) : isHighestBidder ? ( You're the highest bidder Your bid: {formatCurrency(existing_bid_amount)} ยท {formatCurrency(available)} available to raise ) : ( <> {/* Raise adjuster row */} {raise > 0 ? ( +{formatCurrency(raise)} more ) : ( Minimum bid )} {formatCurrency(totalBid)} available) ? 0.4 : 1 }]} onPress={bumpUp} disabled={minimumAllowed + raise + step > available} activeOpacity={0.7} > {/* Bid button */} {submitting ? ( ) : ( {existing_bid_amount ? 'Raise to' : 'Place Bid'} {formatCurrency(totalBid)} )} {/* Available */} {formatCurrency(available)} available )} {/* Error */} {error !== '' && ( {error} )} ); }; const styles = StyleSheet.create({ container: { paddingTop: 8, }, raiseRow: { flexDirection: 'row', alignItems: 'center', marginBottom: 8, }, adjustBtn: { width: 44, height: 44, borderRadius: 10, borderWidth: 1, alignItems: 'center', justifyContent: 'center', }, raiseDisplay: { flex: 1, alignItems: 'center', justifyContent: 'center', }, bidButton: { height: 46, borderRadius: 10, alignItems: 'center', justifyContent: 'center', }, highestBidder: { flexDirection: 'row', alignItems: 'center', padding: 14, borderRadius: 10, }, errorRow: { flexDirection: 'row', alignItems: 'center', marginTop: 6, padding: 8, borderRadius: 8, }, });