updated code with dsc and device binding
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
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 from '../../../Constant/Color';
|
||||
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';
|
||||
@@ -11,6 +13,8 @@ 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}`);
|
||||
@@ -100,7 +104,7 @@ const BiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid, Selec
|
||||
!showDetail ? <Animated.View
|
||||
layout={Layout.springify()}
|
||||
entering={FadeInUp.delay(100)}
|
||||
style={[styles.card, styles.leadingCard, { borderColor: item.me ? '#22C55E' : 'red', backgroundColor: item.me ? "#F0FDF4" : '#fdf0f0ff' }]}
|
||||
style={[styles.card, item.me ? styles.leadingCard : undefined, { borderColor: item.me ? colors.success : colors.error, backgroundColor: item.me ? `${colors.success}10` : `${colors.error}10` }]}
|
||||
>
|
||||
{/* HEADER */}
|
||||
<TouchableOpacity
|
||||
@@ -109,28 +113,28 @@ const BiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid, Selec
|
||||
style={styles.cardHeader}
|
||||
>
|
||||
<View style={{ flex: 1 }}>
|
||||
<Text style={styles.productName}>{item.productName}</Text>
|
||||
<AppText variant="h4" color={colors.text} bold style={styles.productName as any}>{item.productName}</AppText>
|
||||
{/* auctionStartValueFigure */}
|
||||
<Text style={styles.itemIdText}>
|
||||
<AppText variant="caption" color={colors.textSecondary} style={styles.itemIdText as any}>
|
||||
Initial Amt : {item?.auctionStartValueFigure}
|
||||
</Text>
|
||||
</AppText>
|
||||
</View>
|
||||
|
||||
<TouchableOpacity style={styles.headerRight} onPress={toggleExpand}>
|
||||
<View style={[MainStyle.flexBetween, { gap: 10 }]}>
|
||||
<View style={[styles.badge, item.me ? styles.meBadge : styles.liveBadge]}>
|
||||
<Text style={[styles.badgeText, item.me ? styles.meText : styles.liveText]}>
|
||||
<AppText variant="caption" bold style={[styles.badgeText as any, item.me ? styles.meText : styles.liveText]}>
|
||||
{item.me ? 'LEADING' : 'LIVE'}
|
||||
</Text>
|
||||
</AppText>
|
||||
</View>
|
||||
|
||||
<Animated.Text style={[styles.arrow, arrowStyle]}>
|
||||
<Animated.Text style={[styles.arrow, { color: colors.textSecondary }, arrowStyle]}>
|
||||
▼
|
||||
</Animated.Text>
|
||||
</View>
|
||||
<Text style={styles.itemIdText}>
|
||||
<AppText variant="caption" color={colors.textSecondary} style={styles.itemIdText as any}>
|
||||
{SelectedAuction?.auctionNumber}
|
||||
</Text>
|
||||
</AppText>
|
||||
</TouchableOpacity>
|
||||
|
||||
</TouchableOpacity>
|
||||
@@ -138,15 +142,15 @@ const BiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid, Selec
|
||||
{/* PRICE INFO */}
|
||||
<View style={styles.priceRow}>
|
||||
<View>
|
||||
<Text style={styles.label}>Current Bid</Text>
|
||||
<Text style={styles.mainPrice}>₹{item?.bidAmount || item.auctionStartValueFigure}</Text>
|
||||
<AppText variant="caption" color={colors.textSecondary} semiBold style={styles.label as any}>Current Bid</AppText>
|
||||
<AppText variant="h2" color={colors.text} bold style={styles.mainPrice as any}>₹{item?.bidAmount || item.auctionStartValueFigure}</AppText>
|
||||
</View>
|
||||
|
||||
<View style={{ alignItems: 'flex-end' }}>
|
||||
<Text style={styles.label}>Increment</Text>
|
||||
<Text style={styles.incrementText}>
|
||||
<AppText variant="caption" color={colors.textSecondary} semiBold style={styles.label as any}>Increment</AppText>
|
||||
<AppText variant="body" color={colors.primary} bold style={styles.incrementText as any}>
|
||||
+₹{item.bidVariationValue}
|
||||
</Text>
|
||||
</AppText>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -154,7 +158,7 @@ const BiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid, Selec
|
||||
<Animated.View style={[styles.collapsibleContainer, (!allBoolean.rebid && item.contractorId == undefined) ? bodyStyle : bodyStyle2]}>
|
||||
<View style={styles.divider} />
|
||||
|
||||
<Text style={styles.bidLabel}>Set Your Bid</Text>
|
||||
<AppText variant="bodySmall" color={colors.textSecondary} semiBold style={styles.bidLabel as any}>Set Your Bid</AppText>
|
||||
|
||||
{!allBoolean.oneTimeBid && <View style={styles.stepperContainer}>
|
||||
<TouchableOpacity
|
||||
@@ -162,29 +166,29 @@ const BiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid, Selec
|
||||
disabled={isMin}
|
||||
style={[styles.stepBtn, isMin && styles.disabledBtn]}
|
||||
>
|
||||
<Text style={styles.stepText}>−</Text>
|
||||
<AppText variant="h3" color="#FFF" bold style={styles.stepText as any}>−</AppText>
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={styles.inputBox}>
|
||||
<Text style={styles.currency}>₹</Text>
|
||||
<Text style={styles.bidValueText}>{bidValue}</Text>
|
||||
<AppText variant="body" color={colors.textSecondary} bold style={styles.currency as any}>₹</AppText>
|
||||
<AppText variant="h4" color={colors.text} bold style={styles.bidValueText as any}>{bidValue}</AppText>
|
||||
</View>
|
||||
|
||||
<TouchableOpacity onPress={onIncrease} style={styles.stepBtn}>
|
||||
<Text style={styles.stepText}>+</Text>
|
||||
<AppText variant="h3" color="#FFF" bold style={styles.stepText as any}>+</AppText>
|
||||
</TouchableOpacity>
|
||||
</View>}
|
||||
{
|
||||
(allBoolean.oneTimeBid || allBoolean.rebid) && <View style={styles.inputBox2}>
|
||||
<Text style={styles.currency2}>₹</Text>
|
||||
<AppText variant="body" color={colors.textSecondary} bold style={styles.currency2 as any}>₹</AppText>
|
||||
|
||||
<TextInput
|
||||
value={value}
|
||||
onChangeText={handleChange}
|
||||
keyboardType="decimal-pad"
|
||||
placeholder="0.00"
|
||||
style={styles.input}
|
||||
placeholderTextColor="#94A3B8"
|
||||
style={[styles.input, { color: colors.text }]}
|
||||
placeholderTextColor={colors.textSecondary}
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
@@ -194,7 +198,7 @@ const BiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid, Selec
|
||||
onPress={(allBoolean.oneTimeBid || allBoolean.rebid) ? oneTimePlaceBid : onPlaceBid}
|
||||
>
|
||||
{
|
||||
allState.isLoading ? <Loader size='small' color={colors.white} /> : <Text style={styles.submitBtnText}>Confirm Bid</Text>
|
||||
allState.isLoading ? <Loader size='small' color="#FFF" /> : <AppText variant="button" color="#FFF" bold style={styles.submitBtnText as any}>Confirm Bid</AppText>
|
||||
}
|
||||
</TouchableOpacity> : null}
|
||||
</Animated.View>
|
||||
@@ -209,11 +213,11 @@ const BiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid, Selec
|
||||
|
||||
export default memo(BiddingCard);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
const makeStyles = (colors: any) => StyleSheet.create({
|
||||
inputBox2: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F1F5F9',
|
||||
backgroundColor: colors.background,
|
||||
borderRadius: 12,
|
||||
height: 45,
|
||||
paddingHorizontal: 12,
|
||||
@@ -221,39 +225,23 @@ const styles = StyleSheet.create({
|
||||
marginBottom: 20
|
||||
},
|
||||
currency2: {
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
color: '#64748B',
|
||||
marginRight: 4,
|
||||
},
|
||||
} as any,
|
||||
input: {
|
||||
flex: 1,
|
||||
fontSize: 18,
|
||||
fontWeight: '700',
|
||||
color: '#0F172A',
|
||||
width: '100%'
|
||||
},
|
||||
card: {
|
||||
backgroundColor: '#FFF',
|
||||
borderRadius: 24,
|
||||
padding: 20,
|
||||
marginBottom: 16,
|
||||
borderWidth: 1,
|
||||
borderColor: '#E2E8F0',
|
||||
overflow: 'hidden',
|
||||
...Platform.select({
|
||||
ios: {
|
||||
shadowColor: '#000',
|
||||
shadowOpacity: 0.05,
|
||||
shadowRadius: 10,
|
||||
},
|
||||
android: { elevation: 2 },
|
||||
}),
|
||||
},
|
||||
leadingCard: {
|
||||
borderColor: '#22C55E',
|
||||
borderWidth: 2,
|
||||
backgroundColor: '#F0FDF4',
|
||||
},
|
||||
cardHeader: {
|
||||
flexDirection: 'row',
|
||||
@@ -261,27 +249,24 @@ const styles = StyleSheet.create({
|
||||
alignItems: 'flex-start',
|
||||
},
|
||||
headerRight: { flexDirection: 'column', alignItems: 'center', gap: 8 },
|
||||
productName: { fontSize: 18, fontWeight: 'bold', color: '#1E293B' },
|
||||
itemIdText: { fontSize: 12, color: '#64748B', marginTop: 2 },
|
||||
productName: {} as any,
|
||||
itemIdText: { marginTop: 2 } as any,
|
||||
badge: { paddingHorizontal: 10, paddingVertical: 4, borderRadius: 8 },
|
||||
liveBadge: { backgroundColor: '#FEE2E2' },
|
||||
meBadge: { backgroundColor: '#BBF7D0' },
|
||||
badgeText: { fontSize: 10, fontWeight: '900' },
|
||||
liveText: { color: '#EF4444' },
|
||||
meText: { color: '#15803D' },
|
||||
arrow: { fontSize: 10, color: '#94A3B8' },
|
||||
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: {
|
||||
fontSize: 11,
|
||||
color: '#94A3B8',
|
||||
textTransform: 'uppercase',
|
||||
fontWeight: '600',
|
||||
},
|
||||
mainPrice: { fontSize: 22, fontWeight: '900', color: '#0F172A' },
|
||||
incrementText: { fontSize: 16, fontWeight: '700', color: '#3B82F6' },
|
||||
} as any,
|
||||
mainPrice: {} as any,
|
||||
incrementText: {} as any,
|
||||
collapsibleContainer: { overflow: 'hidden' },
|
||||
divider: { height: 1, backgroundColor: '#E2E8F0', marginVertical: 10 },
|
||||
bidLabel: { fontSize: 13, fontWeight: '600', color: '#475569', marginBottom: 10 },
|
||||
divider: { height: 1, backgroundColor: colors.border, marginVertical: 10 },
|
||||
bidLabel: { marginBottom: 10 } as any,
|
||||
stepperContainer: { flexDirection: 'row', gap: 12, marginBottom: 20 },
|
||||
stepBtn: {
|
||||
width: 45,
|
||||
@@ -291,19 +276,19 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
disabledBtn: { backgroundColor: '#CBD5E1' },
|
||||
stepText: { color: '#FFF', fontSize: 20, fontWeight: 'bold' },
|
||||
disabledBtn: { backgroundColor: colors.border },
|
||||
stepText: {} as any,
|
||||
inputBox: {
|
||||
flex: 1,
|
||||
height: 45,
|
||||
backgroundColor: '#F1F5F9',
|
||||
backgroundColor: colors.background,
|
||||
borderRadius: 12,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
currency: { fontSize: 16, fontWeight: 'bold', color: '#64748B', marginRight: 4 },
|
||||
bidValueText: { fontSize: 18, fontWeight: '800', color: '#0F172A' },
|
||||
currency: { marginRight: 4 } as any,
|
||||
bidValueText: {} as any,
|
||||
submitBtn: {
|
||||
height: 50,
|
||||
backgroundColor: colors.primary,
|
||||
@@ -311,5 +296,5 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
submitBtnText: { color: '#FFF', fontSize: 16, fontWeight: 'bold' },
|
||||
submitBtnText: {} as any,
|
||||
});
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
import React from 'react';
|
||||
import { View, StyleSheet, TouchableOpacity, ActivityIndicator } from 'react-native';
|
||||
import { ShieldCheck, X } from 'lucide-react-native';
|
||||
import { useTheme } from '../../../Hooks/useTheme';
|
||||
import AppText from '../../../components/AppText';
|
||||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
onClose: () => void;
|
||||
onConfirm: () => void;
|
||||
bidAmount: number;
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
const ConfirmBidModal = ({ visible, onClose, onConfirm, bidAmount, isLoading }: Props) => {
|
||||
const { colors, shadows } = useTheme();
|
||||
|
||||
if (!visible) return null;
|
||||
|
||||
return (
|
||||
<View style={styles.overlay}>
|
||||
<View style={[styles.modalCard, { backgroundColor: colors.surface, ...shadows.large }]}>
|
||||
|
||||
<TouchableOpacity style={[styles.closeBtn, { backgroundColor: colors.background }]} onPress={onClose} disabled={isLoading}>
|
||||
<X size={18} color={colors.textSecondary} strokeWidth={2.5} />
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={[styles.iconBox, { backgroundColor: `${colors.primary}15` }]}>
|
||||
<ShieldCheck size={32} color={colors.primary} strokeWidth={2} />
|
||||
</View>
|
||||
|
||||
<AppText variant="h3" color={colors.text} bold centered style={styles.title}>
|
||||
Confirm Your Bid
|
||||
</AppText>
|
||||
<AppText variant="body" color={colors.textSecondary} centered style={styles.subtitle}>
|
||||
Are you sure you want to place this bid? This action cannot be undone.
|
||||
</AppText>
|
||||
|
||||
<View style={[styles.amountBox, { backgroundColor: `${colors.primary}10`, borderColor: `${colors.primary}30` }]}>
|
||||
<AppText variant="caption" color={colors.primary} bold>
|
||||
BID AMOUNT
|
||||
</AppText>
|
||||
<AppText variant="h1" color={colors.primary} bold>
|
||||
₹{bidAmount?.toLocaleString('en-IN') || 0}
|
||||
</AppText>
|
||||
</View>
|
||||
|
||||
<View style={styles.btnRow}>
|
||||
<TouchableOpacity style={[styles.btn, styles.cancelBtn, { backgroundColor: colors.background }]} onPress={onClose} disabled={isLoading}>
|
||||
<AppText variant="button" color={colors.text} bold>Cancel</AppText>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity style={[styles.btn, styles.confirmBtn, { backgroundColor: colors.primary }]} onPress={onConfirm} disabled={isLoading}>
|
||||
{isLoading ? (
|
||||
<ActivityIndicator color="#fff" size="small" />
|
||||
) : (
|
||||
<AppText variant="button" color="#fff" bold>Submit Bid</AppText>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConfirmBidModal;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
overlay: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
backgroundColor: 'rgba(0,0,0,0.7)',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
padding: 24,
|
||||
zIndex: 9999,
|
||||
elevation: 9999,
|
||||
},
|
||||
modalCard: {
|
||||
width: '100%',
|
||||
borderRadius: 24,
|
||||
padding: 24,
|
||||
alignItems: 'center',
|
||||
},
|
||||
closeBtn: {
|
||||
position: 'absolute',
|
||||
top: 16,
|
||||
right: 16,
|
||||
width: 32,
|
||||
height: 32,
|
||||
borderRadius: 16,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
iconBox: {
|
||||
width: 64,
|
||||
height: 64,
|
||||
borderRadius: 32,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginBottom: 16,
|
||||
},
|
||||
title: {
|
||||
marginBottom: 8,
|
||||
},
|
||||
subtitle: {
|
||||
marginBottom: 24,
|
||||
paddingHorizontal: 10,
|
||||
},
|
||||
amountBox: {
|
||||
width: '100%',
|
||||
paddingVertical: 16,
|
||||
borderRadius: 16,
|
||||
borderWidth: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginBottom: 24,
|
||||
gap: 4,
|
||||
},
|
||||
btnRow: {
|
||||
flexDirection: 'row',
|
||||
gap: 12,
|
||||
width: '100%',
|
||||
},
|
||||
btn: {
|
||||
flex: 1,
|
||||
height: 50,
|
||||
borderRadius: 16,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
cancelBtn: {},
|
||||
confirmBtn: {},
|
||||
});
|
||||
@@ -1,105 +1,209 @@
|
||||
import React from 'react';
|
||||
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
|
||||
import { View, StyleSheet, TouchableOpacity } from 'react-native';
|
||||
import LottieView from 'lottie-react-native';
|
||||
import Animated, { FadeInUp } from 'react-native-reanimated';
|
||||
import colors from '../../../Constant/Color';
|
||||
import Animated, { FadeInDown, FadeInUp, ZoomIn } from 'react-native-reanimated';
|
||||
import { useTheme } from '../../../Hooks/useTheme';
|
||||
import AppText from '../../../components/AppText';
|
||||
import {
|
||||
ShieldCheck,
|
||||
CheckCircle2,
|
||||
FileText,
|
||||
Gavel,
|
||||
ArrowRight,
|
||||
} from 'lucide-react-native';
|
||||
|
||||
const STEPS = [
|
||||
{ icon: FileText, label: 'Documents Submitted', done: true },
|
||||
{ icon: ShieldCheck, label: 'EMD Verified', done: true },
|
||||
{ icon: Gavel, label: 'Ready to Bid', done: true },
|
||||
];
|
||||
|
||||
const EmdComplete = ({ onNext }: { onNext?: () => void }) => {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<LottieView
|
||||
source={require('../../../lottie/confetti.json')}
|
||||
autoPlay
|
||||
loop={true}
|
||||
style={styles.confetti}
|
||||
/>
|
||||
const { colors, spacing, shadows } = useTheme();
|
||||
|
||||
<LottieView
|
||||
source={require('../../../lottie/Success.json')}
|
||||
autoPlay
|
||||
loop={true}
|
||||
style={styles.success}
|
||||
/>
|
||||
return (
|
||||
<View style={[styles.root, { backgroundColor: colors.background }]}>
|
||||
|
||||
<Animated.Text entering={FadeInUp.delay(400).duration(700)} style={styles.title}>
|
||||
EMD Complete
|
||||
</Animated.Text>
|
||||
|
||||
<Animated.Text entering={FadeInUp.delay(700).duration(700)} style={styles.subText} >
|
||||
Your submission was successful
|
||||
</Animated.Text>
|
||||
{/* ── Center content ── */}
|
||||
<View style={styles.centerContent}>
|
||||
|
||||
<Animated.View entering={FadeInUp.delay(900).duration(700)} style={styles.nextWrapper} >
|
||||
<TouchableOpacity activeOpacity={0.85} style={styles.nextBtn} onPress={onNext} >
|
||||
<Text style={styles.nextText}>Next</Text>
|
||||
</TouchableOpacity>
|
||||
</Animated.View>
|
||||
</View>
|
||||
);
|
||||
{/* Success animation bubble */}
|
||||
<Animated.View entering={ZoomIn.delay(100).springify()} style={[styles.lottieBubble, { backgroundColor: `${colors.primary}12` }]}>
|
||||
<LottieView
|
||||
source={require('../../../lottie/Success.json')}
|
||||
autoPlay
|
||||
loop={false}
|
||||
style={styles.lottie}
|
||||
/>
|
||||
</Animated.View>
|
||||
|
||||
{/* Title */}
|
||||
<Animated.View entering={FadeInUp.delay(400).springify()} style={styles.titleBlock}>
|
||||
<AppText variant="h2" color={colors.text} bold centered>
|
||||
EMD Submitted!
|
||||
</AppText>
|
||||
<AppText variant="body" color={colors.textSecondary} centered style={styles.subtitle as any}>
|
||||
Your Earnest Money Deposit has been{'\n'}successfully recorded.
|
||||
</AppText>
|
||||
</Animated.View>
|
||||
|
||||
{/* ── Step Completion Chips ── */}
|
||||
<Animated.View entering={FadeInDown.delay(600).springify()} style={[styles.stepsCard,{backgroundColor: colors.surface, shadowColor: colors.shadow}]}>
|
||||
{STEPS.map((step, index) => (
|
||||
<React.Fragment key={index}>
|
||||
<View style={styles.stepRow}>
|
||||
<View style={[styles.stepIconBox, { backgroundColor: `${colors.success}18` }]}>
|
||||
<step.icon size={16} color={colors.success} strokeWidth={2} />
|
||||
</View>
|
||||
<AppText variant="bodySmall" color={colors.text} semiBold style={styles.stepLabel as any}>
|
||||
{step.label}
|
||||
</AppText>
|
||||
<CheckCircle2 size={18} color={colors.success} strokeWidth={2.5} />
|
||||
</View>
|
||||
{index < STEPS.length - 1 && (
|
||||
<View style={[styles.stepConnector, { backgroundColor: `${colors.success}30` }]} />
|
||||
)}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</Animated.View>
|
||||
|
||||
{/* ── Info badge ── */}
|
||||
<Animated.View
|
||||
entering={FadeInUp.delay(900).springify()}
|
||||
style={[styles.infoBadge, { backgroundColor: `${colors.primary}10`, borderColor: `${colors.primary}30` }]}
|
||||
>
|
||||
<AppText variant="caption" color={colors.primary} semiBold centered>
|
||||
🎉 You are now eligible to participate in the bidding process
|
||||
</AppText>
|
||||
</Animated.View>
|
||||
</View>
|
||||
|
||||
{/* ── Bottom CTA ── */}
|
||||
<Animated.View entering={FadeInUp.delay(1100).springify()} style={styles.bottomArea}>
|
||||
<TouchableOpacity
|
||||
style={[styles.ctaBtn, { backgroundColor: colors.primary, ...shadows.medium }]}
|
||||
onPress={onNext}
|
||||
activeOpacity={0.85}
|
||||
>
|
||||
<AppText variant="button" color="#fff" bold style={styles.ctaText as any}>
|
||||
Continue to Bidding
|
||||
</AppText>
|
||||
<ArrowRight size={18} color="#fff" strokeWidth={2.5} />
|
||||
</TouchableOpacity>
|
||||
</Animated.View>
|
||||
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default EmdComplete;
|
||||
|
||||
/* ---------------- Styles ---------------- */
|
||||
/* ─── Styles ─── */
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#F8FAFC',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
root: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
paddingVertical: 40,
|
||||
},
|
||||
|
||||
confetti: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
centerContent: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
paddingHorizontal: 24,
|
||||
gap: 24,
|
||||
width: '100%',
|
||||
},
|
||||
|
||||
success: {
|
||||
width: 220,
|
||||
height: 220,
|
||||
marginTop: -100
|
||||
},
|
||||
/* Lottie bubble */
|
||||
lottieBubble: {
|
||||
width: 160,
|
||||
height: 160,
|
||||
borderRadius: 80,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
lottie: {
|
||||
width: 130,
|
||||
height: 130,
|
||||
},
|
||||
|
||||
title: {
|
||||
marginTop: 16,
|
||||
fontSize: 24,
|
||||
fontWeight: '900',
|
||||
color: '#0F172A',
|
||||
letterSpacing: 0.5,
|
||||
},
|
||||
/* Title */
|
||||
titleBlock: {
|
||||
alignItems: 'center',
|
||||
gap: 8,
|
||||
},
|
||||
title: {
|
||||
letterSpacing: 0.3,
|
||||
} as any,
|
||||
subtitle: {
|
||||
lineHeight: 22,
|
||||
opacity: 0.75,
|
||||
} as any,
|
||||
|
||||
subText: {
|
||||
marginTop: 8,
|
||||
fontSize: 14,
|
||||
color: '#475569',
|
||||
},
|
||||
/* Steps */
|
||||
stepsCard: {
|
||||
width: '100%',
|
||||
borderRadius: 20,
|
||||
paddingVertical: 16,
|
||||
paddingHorizontal: 20,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 4 },
|
||||
shadowOpacity: 0.06,
|
||||
shadowRadius: 12,
|
||||
elevation: 4,
|
||||
},
|
||||
stepRow: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 12,
|
||||
},
|
||||
stepIconBox: {
|
||||
width: 34,
|
||||
height: 34,
|
||||
borderRadius: 10,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
stepLabel: {
|
||||
flex: 1,
|
||||
} as any,
|
||||
stepConnector: {
|
||||
width: 2,
|
||||
height: 14,
|
||||
marginLeft: 16,
|
||||
borderRadius: 1,
|
||||
marginVertical: 2,
|
||||
},
|
||||
|
||||
/* ---------- Floating Next Button ---------- */
|
||||
nextWrapper: {
|
||||
position: 'absolute',
|
||||
right: 20,
|
||||
bottom: 30,
|
||||
},
|
||||
/* Info badge */
|
||||
infoBadge: {
|
||||
width: '100%',
|
||||
borderRadius: 16,
|
||||
borderWidth: 1.2,
|
||||
paddingVertical: 12,
|
||||
paddingHorizontal: 16,
|
||||
},
|
||||
infoText: {
|
||||
lineHeight: 20,
|
||||
} as any,
|
||||
|
||||
nextBtn: {
|
||||
backgroundColor: colors.primary,
|
||||
paddingHorizontal: 26,
|
||||
paddingVertical: 14,
|
||||
borderRadius: 28,
|
||||
|
||||
shadowColor: colors.primary,
|
||||
shadowOffset: { width: 0, height: 8 },
|
||||
shadowOpacity: 0.35,
|
||||
shadowRadius: 14,
|
||||
elevation: 6,
|
||||
},
|
||||
|
||||
nextText: {
|
||||
color: '#FFFFFF',
|
||||
fontSize: 15,
|
||||
fontWeight: '800',
|
||||
letterSpacing: 0.4,
|
||||
},
|
||||
/* CTA */
|
||||
bottomArea: {
|
||||
width: '100%',
|
||||
paddingHorizontal: 24,
|
||||
},
|
||||
ctaBtn: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 8,
|
||||
paddingVertical: 16,
|
||||
borderRadius: 18,
|
||||
},
|
||||
ctaText: {
|
||||
letterSpacing: 0.5,
|
||||
} as any,
|
||||
});
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
import React from 'react';
|
||||
import { View, StyleSheet, TouchableOpacity } from 'react-native';
|
||||
import { LogOut, X } from 'lucide-react-native';
|
||||
import { useTheme } from '../../../Hooks/useTheme';
|
||||
import AppText from '../../../components/AppText';
|
||||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
onClose: () => void;
|
||||
onConfirm: () => void;
|
||||
}
|
||||
|
||||
const GoBackModal = ({ visible, onClose, onConfirm }: Props) => {
|
||||
const { colors, shadows } = useTheme();
|
||||
|
||||
if (!visible) return null;
|
||||
|
||||
return (
|
||||
<View style={styles.overlay}>
|
||||
<View style={[styles.modalCard, { backgroundColor: colors.surface, ...shadows.large }]}>
|
||||
|
||||
<TouchableOpacity style={[styles.closeBtn, { backgroundColor: colors.background }]} onPress={onClose}>
|
||||
<X size={18} color={colors.textSecondary} strokeWidth={2.5} />
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={[styles.iconBox, { backgroundColor: `${colors.error}15` }]}>
|
||||
<LogOut size={32} color={colors.error} strokeWidth={2} />
|
||||
</View>
|
||||
|
||||
<AppText variant="h3" color={colors.text} bold centered style={styles.title as any}>
|
||||
Leave Bidding?
|
||||
</AppText>
|
||||
<AppText variant="body" color={colors.textSecondary} centered style={styles.subtitle as any}>
|
||||
Are you sure you want to go back to the Dashboard? You can always return to this panel later.
|
||||
</AppText>
|
||||
|
||||
<View style={styles.btnRow}>
|
||||
<TouchableOpacity style={[styles.btn, styles.cancelBtn, { backgroundColor: colors.background }]} onPress={onClose}>
|
||||
<AppText variant="button" color={colors.text} bold>Stay</AppText>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity style={[styles.btn, styles.confirmBtn, { backgroundColor: colors.error }]} onPress={onConfirm}>
|
||||
<AppText variant="button" color="#fff" bold>Leave</AppText>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default GoBackModal;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
overlay: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
backgroundColor: 'rgba(0,0,0,0.7)',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
padding: 24,
|
||||
zIndex: 9999,
|
||||
elevation: 9999,
|
||||
},
|
||||
modalCard: {
|
||||
width: '100%',
|
||||
borderRadius: 24,
|
||||
padding: 24,
|
||||
alignItems: 'center',
|
||||
},
|
||||
closeBtn: {
|
||||
position: 'absolute',
|
||||
top: 16,
|
||||
right: 16,
|
||||
width: 32,
|
||||
height: 32,
|
||||
borderRadius: 16,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
iconBox: {
|
||||
width: 64,
|
||||
height: 64,
|
||||
borderRadius: 32,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginBottom: 16,
|
||||
},
|
||||
title: {
|
||||
marginBottom: 8,
|
||||
},
|
||||
subtitle: {
|
||||
marginBottom: 24,
|
||||
paddingHorizontal: 10,
|
||||
},
|
||||
btnRow: {
|
||||
flexDirection: 'row',
|
||||
gap: 12,
|
||||
width: '100%',
|
||||
},
|
||||
btn: {
|
||||
flex: 1,
|
||||
height: 50,
|
||||
borderRadius: 16,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
cancelBtn: {},
|
||||
confirmBtn: {},
|
||||
});
|
||||
@@ -1,9 +1,11 @@
|
||||
import React, { memo, useCallback, useRef, useState } from 'react';
|
||||
import { View, Text, TouchableOpacity, StyleSheet, Platform, TextInput } from 'react-native';
|
||||
import Animated, { FadeInUp, Layout, interpolate, useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated';
|
||||
import colors from '../../../Constant/Color';
|
||||
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 axios, { all } from 'axios';
|
||||
import Variables from '../../../Constant/Variable';
|
||||
import { useSelector } from 'react-redux';
|
||||
@@ -11,6 +13,8 @@ import { showErrorAlert, showSuccessAlert } from '../../../Constant/ShowDailog';
|
||||
import { Loader } from '../../../Component/Index';
|
||||
|
||||
const ReverseBiddingCard = ({ 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 [allState, setAllState] = useState({ isLoading: false })
|
||||
const [showDetail, setShowDetail] = useState(false);
|
||||
@@ -108,9 +112,10 @@ const ReverseBiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid
|
||||
entering={FadeInUp.delay(100)}
|
||||
style={[
|
||||
styles.card,
|
||||
item.me ? styles.leadingCard : undefined,
|
||||
{
|
||||
borderColor: item.me ? '#22C55E' : '#EF4444',
|
||||
backgroundColor: item.me ? '#F0FDF4' : '#FDF0F0',
|
||||
borderColor: item.me ? colors.success : colors.error,
|
||||
backgroundColor: item.me ? `${colors.success}10` : `${colors.error}10`,
|
||||
},
|
||||
]}
|
||||
>
|
||||
@@ -121,10 +126,10 @@ const ReverseBiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid
|
||||
style={styles.cardHeader}
|
||||
>
|
||||
<View style={{ flex: 1 }}>
|
||||
<Text style={styles.productName}>{item.productName}</Text>
|
||||
<Text style={styles.itemIdText}>
|
||||
<AppText variant="h4" color={colors.text} bold style={styles.productName as any}>{item.productName}</AppText>
|
||||
<AppText variant="caption" color={colors.textSecondary} style={styles.itemIdText as any}>
|
||||
Initial Amt : ₹{item.auctionStartValue}
|
||||
</Text>
|
||||
</AppText>
|
||||
</View>
|
||||
|
||||
<TouchableOpacity style={styles.headerRight} onPress={toggleExpand}>
|
||||
@@ -135,38 +140,40 @@ const ReverseBiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid
|
||||
item.me ? styles.meBadge : styles.liveBadge,
|
||||
]}
|
||||
>
|
||||
<Text
|
||||
<AppText
|
||||
variant="caption"
|
||||
bold
|
||||
style={[
|
||||
styles.badgeText,
|
||||
styles.badgeText as any,
|
||||
item.me ? styles.meText : styles.liveText,
|
||||
]}
|
||||
>
|
||||
{item.me ? 'LEADING' : 'LIVE'}
|
||||
</Text>
|
||||
</AppText>
|
||||
</View>
|
||||
|
||||
<Animated.Text style={[styles.arrow, arrowStyle]}>
|
||||
<Animated.Text style={[styles.arrow, { color: colors.textSecondary }, arrowStyle]}>
|
||||
▼
|
||||
</Animated.Text>
|
||||
</View>
|
||||
<Text style={styles.itemIdText}>
|
||||
<AppText variant="caption" color={colors.textSecondary} style={styles.itemIdText as any}>
|
||||
{SelectedAuction?.auctionNumber}
|
||||
</Text>
|
||||
</AppText>
|
||||
</TouchableOpacity>
|
||||
</TouchableOpacity>
|
||||
|
||||
{/* PRICE INFO */}
|
||||
<View style={styles.priceRow}>
|
||||
<View>
|
||||
<Text style={styles.label}>Current Bid</Text>
|
||||
<Text style={styles.mainPrice}>₹{item.bidAmount || item.auctionStartValue}</Text>
|
||||
<AppText variant="caption" color={colors.textSecondary} semiBold style={styles.label as any}>Current Bid</AppText>
|
||||
<AppText variant="h2" color={colors.text} bold style={styles.mainPrice as any}>₹{item.bidAmount || item.auctionStartValue}</AppText>
|
||||
</View>
|
||||
|
||||
<View style={{ alignItems: 'flex-end' }}>
|
||||
<Text style={styles.label}>Decrement</Text>
|
||||
<Text style={styles.incrementText}>
|
||||
<AppText variant="caption" color={colors.textSecondary} semiBold style={styles.label as any}>Decrement</AppText>
|
||||
<AppText variant="body" color={colors.primary} bold style={styles.incrementText as any}>
|
||||
-₹{item.emdAmount}
|
||||
</Text>
|
||||
</AppText>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -175,7 +182,7 @@ const ReverseBiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid
|
||||
<Animated.View style={[styles.collapsibleContainer, bodyStyle]}>
|
||||
<View style={styles.divider} />
|
||||
|
||||
<Text style={styles.bidLabel}>Set Your Bid</Text>
|
||||
<AppText variant="bodySmall" color={colors.textSecondary} semiBold style={styles.bidLabel as any}>Set Your Bid</AppText>
|
||||
|
||||
<View style={styles.stepperContainer}>
|
||||
{/* DECREASE */}
|
||||
@@ -187,25 +194,25 @@ const ReverseBiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid
|
||||
!canDecrease && styles.disabledBtn,
|
||||
]}
|
||||
>
|
||||
<Text style={styles.stepText}>−</Text>
|
||||
<AppText variant="h3" color="#FFF" bold style={styles.stepText as any}>−</AppText>
|
||||
</TouchableOpacity>}
|
||||
|
||||
{/* VALUE */}
|
||||
{!allBoolean.oneTimeBid && <View style={styles.inputBox}>
|
||||
<Text style={styles.currency}>₹</Text>
|
||||
<Text style={styles.bidValueText}>{bidValue}</Text>
|
||||
<AppText variant="body" color={colors.textSecondary} bold style={styles.currency as any}>₹</AppText>
|
||||
<AppText variant="h4" color={colors.text} bold style={styles.bidValueText as any}>{bidValue}</AppText>
|
||||
</View>}
|
||||
{
|
||||
(allBoolean.oneTimeBid || allBoolean.rebid) && <View style={styles.inputBox2}>
|
||||
<Text style={styles.currency2}>₹</Text>
|
||||
<AppText variant="body" color={colors.textSecondary} bold style={styles.currency2 as any}>₹</AppText>
|
||||
|
||||
<TextInput
|
||||
value={value}
|
||||
onChangeText={handleChange}
|
||||
keyboardType="decimal-pad"
|
||||
placeholder="0.00"
|
||||
style={styles.input}
|
||||
placeholderTextColor="#94A3B8"
|
||||
style={[styles.input, { color: colors.text }]}
|
||||
placeholderTextColor={colors.textSecondary}
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
@@ -219,7 +226,7 @@ const ReverseBiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid
|
||||
!canIncrease && styles.disabledBtn,
|
||||
]}
|
||||
>
|
||||
<Text style={styles.stepText}>+</Text>
|
||||
<AppText variant="h3" color="#FFF" bold style={styles.stepText as any}>+</AppText>
|
||||
</TouchableOpacity>}
|
||||
</View>
|
||||
|
||||
@@ -228,7 +235,7 @@ const ReverseBiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid
|
||||
onPress={(allBoolean.oneTimeBid || allBoolean.rebid) ? oneTimePlaceBid : onPlaceBid}
|
||||
>
|
||||
{
|
||||
allState.isLoading ? <Loader size='small' color={colors.white} /> : <Text style={styles.submitBtnText}>Confirm Bid</Text>
|
||||
allState.isLoading ? <Loader size='small' color="#FFF" /> : <AppText variant="button" color="#FFF" bold style={styles.submitBtnText as any}>Confirm Bid</AppText>
|
||||
}
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -265,50 +272,34 @@ const ReverseBiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid
|
||||
|
||||
export default ReverseBiddingCard;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
const makeStyles = (colors: any) => StyleSheet.create({
|
||||
inputBox2: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F1F5F9',
|
||||
backgroundColor: colors.background,
|
||||
borderRadius: 12,
|
||||
height: 45,
|
||||
paddingHorizontal: 12,
|
||||
width: '100%'
|
||||
},
|
||||
currency2: {
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
color: '#64748B',
|
||||
marginRight: 4,
|
||||
},
|
||||
} as any,
|
||||
input: {
|
||||
flex: 1,
|
||||
fontSize: 18,
|
||||
fontWeight: '700',
|
||||
color: '#0F172A',
|
||||
width: '100%'
|
||||
},
|
||||
card: {
|
||||
backgroundColor: '#FFF',
|
||||
borderRadius: 24,
|
||||
padding: 20,
|
||||
marginBottom: 16,
|
||||
borderWidth: 1,
|
||||
borderColor: '#E2E8F0',
|
||||
overflow: 'hidden',
|
||||
...Platform.select({
|
||||
ios: {
|
||||
shadowColor: '#000',
|
||||
shadowOpacity: 0.05,
|
||||
shadowRadius: 10,
|
||||
},
|
||||
android: { elevation: 2 },
|
||||
}),
|
||||
},
|
||||
leadingCard: {
|
||||
borderColor: '#22C55E',
|
||||
borderWidth: 2,
|
||||
backgroundColor: '#F0FDF4',
|
||||
},
|
||||
cardHeader: {
|
||||
flexDirection: 'row',
|
||||
@@ -316,27 +307,24 @@ const styles = StyleSheet.create({
|
||||
alignItems: 'flex-start',
|
||||
},
|
||||
headerRight: { flexDirection: 'column', alignItems: 'center', gap: 8 },
|
||||
productName: { fontSize: 18, fontWeight: 'bold', color: '#1E293B' },
|
||||
itemIdText: { fontSize: 12, color: '#64748B', marginTop: 2 },
|
||||
productName: {} as any,
|
||||
itemIdText: { marginTop: 2 } as any,
|
||||
badge: { paddingHorizontal: 10, paddingVertical: 4, borderRadius: 8 },
|
||||
liveBadge: { backgroundColor: '#FEE2E2' },
|
||||
meBadge: { backgroundColor: '#BBF7D0' },
|
||||
badgeText: { fontSize: 10, fontWeight: '900' },
|
||||
liveText: { color: '#EF4444' },
|
||||
meText: { color: '#15803D' },
|
||||
arrow: { fontSize: 10, color: '#94A3B8' },
|
||||
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: {
|
||||
fontSize: 11,
|
||||
color: '#94A3B8',
|
||||
textTransform: 'uppercase',
|
||||
fontWeight: '600',
|
||||
},
|
||||
mainPrice: { fontSize: 22, fontWeight: '900', color: '#0F172A' },
|
||||
incrementText: { fontSize: 16, fontWeight: '700', color: '#3B82F6' },
|
||||
} as any,
|
||||
mainPrice: {} as any,
|
||||
incrementText: {} as any,
|
||||
collapsibleContainer: { overflow: 'hidden' },
|
||||
divider: { height: 1, backgroundColor: '#E2E8F0', marginVertical: 10 },
|
||||
bidLabel: { fontSize: 13, fontWeight: '600', color: '#475569', marginBottom: 10 },
|
||||
divider: { height: 1, backgroundColor: colors.border, marginVertical: 10 },
|
||||
bidLabel: { marginBottom: 10 } as any,
|
||||
stepperContainer: { flexDirection: 'row', gap: 12, marginBottom: 20 },
|
||||
stepBtn: {
|
||||
width: 45,
|
||||
@@ -346,19 +334,19 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
disabledBtn: { backgroundColor: '#CBD5E1' },
|
||||
stepText: { color: '#FFF', fontSize: 20, fontWeight: 'bold' },
|
||||
disabledBtn: { backgroundColor: colors.border },
|
||||
stepText: {} as any,
|
||||
inputBox: {
|
||||
flex: 1,
|
||||
height: 45,
|
||||
backgroundColor: '#F1F5F9',
|
||||
backgroundColor: colors.background,
|
||||
borderRadius: 12,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
currency: { fontSize: 16, fontWeight: 'bold', color: '#64748B', marginRight: 4 },
|
||||
bidValueText: { fontSize: 18, fontWeight: '800', color: '#0F172A' },
|
||||
currency: { marginRight: 4 } as any,
|
||||
bidValueText: {} as any,
|
||||
submitBtn: {
|
||||
height: 50,
|
||||
backgroundColor: colors.primary,
|
||||
@@ -366,5 +354,5 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
submitBtnText: { color: '#FFF', fontSize: 16, fontWeight: 'bold' },
|
||||
submitBtnText: {} as any,
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState } from 'react'
|
||||
import { Modal, View, Text, StyleSheet, TextInput, TouchableOpacity, ScrollView } from 'react-native'
|
||||
import React, { useState, useMemo } from 'react'
|
||||
import { Modal, View, StyleSheet, TextInput, TouchableOpacity, ScrollView, Platform } from 'react-native'
|
||||
import { Formik } from 'formik'
|
||||
import * as Yup from 'yup'
|
||||
import { pick } from '@react-native-documents/picker'
|
||||
@@ -7,16 +7,20 @@ import { useSelector } from 'react-redux'
|
||||
import { apiCall } from '../../../Axios/Axios'
|
||||
import { TECHNICAL_DOCUMENT_SUBMIT, TECHNICAL_VALUE_SUBMIT } from '../../../Services/ApiCall/ApiUrls'
|
||||
import { Props } from '../Type/BidType'
|
||||
import colors from '../../../Constant/Color'
|
||||
import { Loader } from '../../../Component/Index'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import NavigationString from '../../../Constant/NavigationString'
|
||||
import { useTheme } from '../../../Hooks/useTheme'
|
||||
import AppText from '../../../components/AppText'
|
||||
import { Upload, FileText, X } from 'lucide-react-native'
|
||||
|
||||
const TemplateFormModal: React.FC<Props> = ({ visible, template, setAllBoolean }) => {
|
||||
if (!template) return null
|
||||
|
||||
const SelectedAuction = useSelector((state: any) => state.auction.auction)
|
||||
const Navigation: any = useNavigation()
|
||||
const { colors, spacing, typography } = useTheme()
|
||||
const styles = useMemo(() => makeStyles(colors, spacing, typography), [colors, spacing, typography])
|
||||
const [loading, setLoading] = useState(false)
|
||||
const initialValues = template?.labels?.reduce((acc: any, label: any) => {
|
||||
acc[label.labelName] = ''
|
||||
@@ -65,10 +69,10 @@ const TemplateFormModal: React.FC<Props> = ({ visible, template, setAllBoolean }
|
||||
if (label.labelType === '3') {
|
||||
return (
|
||||
<View key={label.labelName} style={styles.field}>
|
||||
<Text style={styles.label}>
|
||||
<AppText variant="caption" color={colors.textSecondary} style={styles.label as any}>
|
||||
{label.labelName}
|
||||
{label.mandatory && <Text style={styles.required}> *</Text>}
|
||||
</Text>
|
||||
{label.mandatory && <AppText variant="caption" color={colors.error}> *</AppText>}
|
||||
</AppText>
|
||||
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
@@ -79,18 +83,25 @@ const TemplateFormModal: React.FC<Props> = ({ visible, template, setAllBoolean }
|
||||
pickFile(label.labelName, setFieldValue)
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={[
|
||||
styles.fileText,
|
||||
value?.name && styles.fileSelected,
|
||||
]}
|
||||
>
|
||||
{value?.name || 'Upload PDF'}
|
||||
</Text>
|
||||
{value?.name ? (
|
||||
<View style={styles.fileSelectedRow}>
|
||||
<FileText size={14} color={colors.success} strokeWidth={2} />
|
||||
<AppText variant="caption" color={colors.text} bold style={{ flex: 1 } as any} numberOfLines={1}>
|
||||
{value.name}
|
||||
</AppText>
|
||||
</View>
|
||||
) : (
|
||||
<View style={styles.fileSelectedRow}>
|
||||
<Upload size={14} color={colors.textSecondary} strokeWidth={2} />
|
||||
<AppText variant="caption" color={colors.textSecondary}>
|
||||
Upload PDF
|
||||
</AppText>
|
||||
</View>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
|
||||
{showError && (
|
||||
<Text style={styles.errorText}>{error}</Text>
|
||||
<AppText variant="caption" color={colors.error} style={styles.errorText as any}>{error}</AppText>
|
||||
)}
|
||||
</View>
|
||||
)
|
||||
@@ -98,10 +109,10 @@ const TemplateFormModal: React.FC<Props> = ({ visible, template, setAllBoolean }
|
||||
|
||||
return (
|
||||
<View key={label.labelName} style={styles.field}>
|
||||
<Text style={styles.label}>
|
||||
<AppText variant="caption" color={colors.textSecondary} style={styles.label as any}>
|
||||
{label.labelName}
|
||||
{label.mandatory && <Text style={styles.required}> *</Text>}
|
||||
</Text>
|
||||
{label.mandatory && <AppText variant="caption" color={colors.error}> *</AppText>}
|
||||
</AppText>
|
||||
|
||||
<TextInput
|
||||
style={[
|
||||
@@ -109,7 +120,7 @@ const TemplateFormModal: React.FC<Props> = ({ visible, template, setAllBoolean }
|
||||
showError && styles.errorBorder,
|
||||
]}
|
||||
placeholder={`Enter ${label.labelName}`}
|
||||
placeholderTextColor="#9CA3AF"
|
||||
placeholderTextColor={colors.textSecondary}
|
||||
value={value}
|
||||
onChangeText={(text) =>
|
||||
setFieldValue(label.labelName, text)
|
||||
@@ -122,7 +133,7 @@ const TemplateFormModal: React.FC<Props> = ({ visible, template, setAllBoolean }
|
||||
/>
|
||||
|
||||
{showError && (
|
||||
<Text style={styles.errorText}>{error}</Text>
|
||||
<AppText variant="caption" color={colors.error} style={styles.errorText as any}>{error}</AppText>
|
||||
)}
|
||||
</View>
|
||||
)
|
||||
@@ -210,26 +221,26 @@ const TemplateFormModal: React.FC<Props> = ({ visible, template, setAllBoolean }
|
||||
|
||||
<View style={styles.header}>
|
||||
<View style={styles.headerLeft}>
|
||||
<Text style={styles.headerTitle}>Technical Documents</Text>
|
||||
<Text style={styles.headerSubtitle}>
|
||||
<AppText variant="h4" color={colors.text}>Technical Documents</AppText>
|
||||
<AppText variant="caption" color={colors.textSecondary}>
|
||||
Fill the form, Click save when you're done.
|
||||
</Text>
|
||||
</AppText>
|
||||
</View>
|
||||
|
||||
<TouchableOpacity onPress={onClose} style={styles.closeBtn}>
|
||||
<Text style={styles.closeText}>✕</Text>
|
||||
<X size={20} color={colors.textSecondary} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<ScrollView contentContainerStyle={styles.content}>
|
||||
|
||||
<View style={styles.card}>
|
||||
<Text style={styles.templateHeading}>Template</Text>
|
||||
<AppText variant="h3" color={colors.text} centered style={{ marginBottom: 16 } as any}>Template</AppText>
|
||||
|
||||
<View style={styles.templateBox}>
|
||||
<Text style={styles.templateName}>
|
||||
<AppText variant="bodySmall" color={colors.text} bold style={{ marginBottom: 12 } as any}>
|
||||
{template.templateName}
|
||||
</Text>
|
||||
</AppText>
|
||||
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
@@ -264,12 +275,12 @@ const TemplateFormModal: React.FC<Props> = ({ visible, template, setAllBoolean }
|
||||
{loading ? (
|
||||
<Loader
|
||||
size="small"
|
||||
color={colors.white}
|
||||
color="#fff"
|
||||
/>
|
||||
) : (
|
||||
<Text style={styles.submitText}>
|
||||
<AppText variant="button" color="#fff" bold style={styles.submitText as any}>
|
||||
Submit
|
||||
</Text>
|
||||
</AppText>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
@@ -287,129 +298,98 @@ const TemplateFormModal: React.FC<Props> = ({ visible, template, setAllBoolean }
|
||||
|
||||
export default TemplateFormModal
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
screen: {
|
||||
flex: 1,
|
||||
backgroundColor: '#F9FAFB',
|
||||
},
|
||||
header: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 14,
|
||||
backgroundColor: '#FFFFFF',
|
||||
borderBottomWidth: 1,
|
||||
borderColor: '#E5E7EB',
|
||||
},
|
||||
headerLeft: {
|
||||
flex: 1,
|
||||
},
|
||||
headerTitle: {
|
||||
fontSize: 16,
|
||||
fontWeight: '700',
|
||||
color: '#111827',
|
||||
},
|
||||
headerSubtitle: {
|
||||
fontSize: 12,
|
||||
color: '#6B7280',
|
||||
marginTop: 2,
|
||||
},
|
||||
closeBtn: {
|
||||
padding: 6,
|
||||
},
|
||||
closeText: {
|
||||
fontSize: 18,
|
||||
color: '#6B7280',
|
||||
},
|
||||
content: {
|
||||
paddingHorizontal: 16,
|
||||
},
|
||||
card: {
|
||||
backgroundColor: '#FFFFFF',
|
||||
borderColor: '#E5E7EB',
|
||||
paddingVertical: 20
|
||||
},
|
||||
templateHeading: {
|
||||
fontSize: 18,
|
||||
fontWeight: '700',
|
||||
textAlign: 'center',
|
||||
marginBottom: 16,
|
||||
color: '#111827',
|
||||
},
|
||||
|
||||
templateBox: {
|
||||
borderWidth: 1,
|
||||
borderColor: '#E5E7EB',
|
||||
borderRadius: 10,
|
||||
padding: 16,
|
||||
},
|
||||
templateName: {
|
||||
fontSize: 14,
|
||||
fontWeight: '700',
|
||||
color: '#111827',
|
||||
marginBottom: 12,
|
||||
},
|
||||
field: {
|
||||
marginBottom: 14,
|
||||
},
|
||||
label: {
|
||||
fontSize: 13,
|
||||
fontWeight: '600',
|
||||
color: '#374151',
|
||||
marginBottom: 6,
|
||||
},
|
||||
required: {
|
||||
color: '#EF4444',
|
||||
},
|
||||
input: {
|
||||
backgroundColor: '#FFFFFF',
|
||||
borderWidth: 1,
|
||||
borderColor: '#E5E7EB',
|
||||
borderRadius: 8,
|
||||
padding: 12,
|
||||
fontSize: 14,
|
||||
color: '#111827',
|
||||
},
|
||||
filePicker: {
|
||||
borderWidth: 1,
|
||||
borderColor: '#E5E7EB',
|
||||
borderRadius: 8,
|
||||
padding: 12,
|
||||
},
|
||||
fileText: {
|
||||
color: '#6B7280',
|
||||
fontSize: 14,
|
||||
},
|
||||
fileSelected: {
|
||||
color: '#111827',
|
||||
fontWeight: '600',
|
||||
},
|
||||
errorText: {
|
||||
color: '#EF4444',
|
||||
fontSize: 12,
|
||||
marginTop: 4,
|
||||
},
|
||||
errorBorder: {
|
||||
borderColor: '#EF4444',
|
||||
},
|
||||
submitRow: {
|
||||
marginTop: 20,
|
||||
alignItems: 'flex-end',
|
||||
height: 50
|
||||
},
|
||||
submitBtn: {
|
||||
backgroundColor: colors.primary,
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 22,
|
||||
borderRadius: 8,
|
||||
minWidth: 120,
|
||||
alignItems: 'center',
|
||||
},
|
||||
submitText: {
|
||||
color: '#FFFFFF',
|
||||
fontWeight: '700',
|
||||
fontSize: 14,
|
||||
},
|
||||
})
|
||||
|
||||
const makeStyles = (colors: any, spacing: any, typography: any) =>
|
||||
StyleSheet.create({
|
||||
screen: {
|
||||
flex: 1,
|
||||
backgroundColor: colors.background,
|
||||
},
|
||||
header: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 14,
|
||||
backgroundColor: colors.surface,
|
||||
borderBottomWidth: 1,
|
||||
borderColor: colors.border,
|
||||
},
|
||||
headerLeft: {
|
||||
flex: 1,
|
||||
},
|
||||
closeBtn: {
|
||||
padding: 8,
|
||||
backgroundColor: colors.overlay,
|
||||
borderRadius: 10,
|
||||
},
|
||||
content: {
|
||||
paddingHorizontal: 16,
|
||||
},
|
||||
card: {
|
||||
backgroundColor: colors.surface,
|
||||
borderRadius: 18,
|
||||
marginTop: spacing.m,
|
||||
padding: spacing.m,
|
||||
...Platform.select({
|
||||
ios: { shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.06, shadowRadius: 12 },
|
||||
android: { elevation: 3 },
|
||||
}),
|
||||
},
|
||||
templateBox: {
|
||||
borderWidth: 1,
|
||||
borderColor: colors.border,
|
||||
borderRadius: 14,
|
||||
padding: 16,
|
||||
},
|
||||
field: {
|
||||
marginBottom: 14,
|
||||
},
|
||||
label: {
|
||||
letterSpacing: 0.5,
|
||||
textTransform: 'uppercase',
|
||||
marginBottom: 6,
|
||||
} as any,
|
||||
input: {
|
||||
backgroundColor: colors.background,
|
||||
borderWidth: 1.2,
|
||||
borderColor: colors.border,
|
||||
borderRadius: 12,
|
||||
padding: 12,
|
||||
fontSize: 14,
|
||||
color: colors.text,
|
||||
},
|
||||
filePicker: {
|
||||
borderWidth: 1.2,
|
||||
borderColor: colors.border,
|
||||
backgroundColor: colors.background,
|
||||
borderRadius: 12,
|
||||
padding: 12,
|
||||
},
|
||||
fileSelectedRow: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 8,
|
||||
},
|
||||
errorText: {
|
||||
marginTop: 4,
|
||||
} as any,
|
||||
errorBorder: {
|
||||
borderColor: colors.error,
|
||||
},
|
||||
submitRow: {
|
||||
marginTop: 20,
|
||||
alignItems: 'flex-end',
|
||||
height: 50,
|
||||
},
|
||||
submitBtn: {
|
||||
backgroundColor: colors.primary,
|
||||
paddingVertical: 12,
|
||||
paddingHorizontal: 24,
|
||||
borderRadius: 14,
|
||||
minWidth: 120,
|
||||
alignItems: 'center',
|
||||
},
|
||||
submitText: {
|
||||
letterSpacing: 0.5,
|
||||
} as any,
|
||||
})
|
||||
|
||||
+586
-588
File diff suppressed because it is too large
Load Diff
@@ -1,52 +1,74 @@
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { View, FlatList, StyleSheet, Platform, Alert, BackHandler, Text } from 'react-native';
|
||||
import {
|
||||
View,
|
||||
FlatList,
|
||||
StyleSheet,
|
||||
Alert,
|
||||
BackHandler,
|
||||
} from 'react-native';
|
||||
import LottieView from 'lottie-react-native';
|
||||
import Animated, { FadeInDown } from 'react-native-reanimated';
|
||||
import { InsideHeader } from '../../Component/Index';
|
||||
import colors from '../../Constant/Color';
|
||||
import { useWebSocketService } from '../../socket/Socket';
|
||||
import Variables from '../../Constant/Variable';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { apiCall } from '../../Axios/Axios';
|
||||
import { AUCTION_ONE_TIME_BID, FORWARD_AUCTION_ITEM, GET_AUCTION_DETAILS, REVERSE_AUCTION_ITEM, SELECTED_AUCTION_ITEM } from '../../Services/ApiCall/ApiUrls';
|
||||
import {
|
||||
AUCTION_ONE_TIME_BID,
|
||||
FORWARD_AUCTION_ITEM,
|
||||
GET_AUCTION_DETAILS,
|
||||
REVERSE_AUCTION_ITEM,
|
||||
SELECTED_AUCTION_ITEM,
|
||||
} from '../../Services/ApiCall/ApiUrls';
|
||||
import BiddingCard from './Component/BiddingCard';
|
||||
import ConfirmBidModal from './Component/ConfirmBidModal';
|
||||
import GoBackModal from './Component/GoBackModal';
|
||||
import { CommonActions, useFocusEffect, useNavigation } from '@react-navigation/native';
|
||||
import NavigationString from '../../Constant/NavigationString';
|
||||
import CountdownTimer from '../../Component/Counter/CountdownTimer';
|
||||
import FontsFamily from '../../Constant/FontsFamily';
|
||||
import { useTheme } from '../../Hooks/useTheme';
|
||||
import AppText from '../../components/AppText';
|
||||
import { Gavel, Building2, Clock4 } from 'lucide-react-native';
|
||||
|
||||
const StartBidding = () => {
|
||||
const { colors, spacing, shadows } = useTheme();
|
||||
const SelectedAuction = useSelector((state: any) => state.auction.auction);
|
||||
const loginUser = useSelector((state: any) => state.token.token)
|
||||
const Navigation: any = useNavigation()
|
||||
const loginUser = useSelector((state: any) => state.token.token);
|
||||
const Navigation: any = useNavigation();
|
||||
|
||||
const [items, setItems] = useState<any>([]);
|
||||
const [bidValues, setBidValues] = useState<Record<number, number>>({});
|
||||
const [allBoolean, setAllBoolean] = useState({ showSuccess: false, showDialog: false, bidPayload: {}, oneTimeBid: false, rebid: false, reload: false })
|
||||
const [allBoolean, setAllBoolean] = useState({
|
||||
showSuccess: false,
|
||||
showDialog: false,
|
||||
showBackDialog: false,
|
||||
bidPayload: {} as any,
|
||||
oneTimeBid: false,
|
||||
rebid: false,
|
||||
reload: false,
|
||||
});
|
||||
|
||||
const { subscribe, createRoom, placeBid } = useWebSocketService(
|
||||
Variables.webSocketUrl,
|
||||
() => console.log('Connected!'),
|
||||
(error) => console.log('WebSocket Error:', error),
|
||||
(error: any) => console.log('WebSocket Error:', error),
|
||||
loginUser.token,
|
||||
);
|
||||
|
||||
const getAuction = async () => {
|
||||
const selectedRes = await apiCall<any>('get', GET_AUCTION_DETAILS, {}, { id: SelectedAuction.auctionId });
|
||||
if (selectedRes.statusCode == 200 && selectedRes.data.contractorId.length) {
|
||||
setAllBoolean((prev: any) => ({ ...prev, oneTimeBid: true }))
|
||||
if (selectedRes.statusCode === 200 && selectedRes.data.contractorId.length) {
|
||||
setAllBoolean(prev => ({ ...prev, oneTimeBid: true }));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const getOneTimeBidValue = async () => {
|
||||
try {
|
||||
const selectedRes = await apiCall<any>('get', AUCTION_ONE_TIME_BID, {}, { auctionId: SelectedAuction.auctionId });
|
||||
if (selectedRes.statusCode == 200) {
|
||||
return selectedRes.data
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
} catch (error) {
|
||||
return selectedRes.statusCode === 200 ? selectedRes.data : [];
|
||||
} catch { return []; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
const getAllAcutionItems = async () => {
|
||||
try {
|
||||
const payload = { auctionNumber: SelectedAuction.auctionNumber };
|
||||
@@ -58,87 +80,40 @@ const StartBidding = () => {
|
||||
}
|
||||
|
||||
const selectedRes = await apiCall<any>('get', SELECTED_AUCTION_ITEM, {}, payload);
|
||||
const uniqueArray: number[] = Array.from(new Set(selectedRes?.data || []));
|
||||
const filteredItems = auctionItem.filter(item => uniqueArray.includes(item.id));
|
||||
|
||||
const uniqueArray: number[] = Array.from(
|
||||
new Set(selectedRes?.data || [])
|
||||
);
|
||||
|
||||
const filteredItems = auctionItem.filter(item =>
|
||||
uniqueArray.includes(item.id)
|
||||
);
|
||||
|
||||
if (SelectedAuction.auctionCategories == 'Live') {
|
||||
if (SelectedAuction.auctionCategories === 'Live') {
|
||||
const result = await createRoom(SelectedAuction.auctionNumber);
|
||||
|
||||
subscribe(`/topic/room/${SelectedAuction.auctionNumber}`, data => {
|
||||
subscribe(`/topic/room/${SelectedAuction.auctionNumber}`, (data: any) => {
|
||||
console.log('🔥 BID UPDATE:', data);
|
||||
});
|
||||
const bidAmountMap2 = new Map<number, { bidAmount: number; contractorId: number }>();
|
||||
|
||||
(result || []).forEach((r: any) => {
|
||||
bidAmountMap2.set(r.auctionItemId, {
|
||||
bidAmount: r.bidAmount,
|
||||
contractorId: r.contractorId,
|
||||
});
|
||||
bidAmountMap2.set(r.auctionItemId, { bidAmount: r.bidAmount, contractorId: r.contractorId });
|
||||
});
|
||||
// Check One Time bid enable butoon
|
||||
if (SelectedAuction.auctionCategories != 'Live') {
|
||||
const myBid = result.find(
|
||||
(bid: any) => bid.contractorId === loginUser.contractorId
|
||||
);
|
||||
|
||||
if (myBid) {
|
||||
setAllBoolean((prev: any) => ({ ...prev, oneTimeBid: true }))
|
||||
}
|
||||
}
|
||||
|
||||
const bidAmountMap = new Map<number, number>();
|
||||
|
||||
(result || []).forEach((r: any) => {
|
||||
bidAmountMap.set(r.auctionItemId, r.bidAmount);
|
||||
});
|
||||
|
||||
const updatedFilteredItems = filteredItems.map(item => {
|
||||
const bidData = bidAmountMap2.get(item.id);
|
||||
return {
|
||||
...item,
|
||||
bidAmount: bidData?.bidAmount ?? item.auctionStartValueFigure,
|
||||
bidAvilable: bidData?.bidAmount ?? 0,
|
||||
me: bidData?.contractorId == loginUser.contractorId ? true : false
|
||||
me: bidData?.contractorId === loginUser.contractorId,
|
||||
};
|
||||
});
|
||||
|
||||
const initialBids: Record<number, number> = {};
|
||||
updatedFilteredItems.forEach(item => {
|
||||
initialBids[item.id] = item.bidAmount;
|
||||
});
|
||||
updatedFilteredItems.forEach(item => { initialBids[item.id] = item.bidAmount; });
|
||||
setBidValues(initialBids);
|
||||
setItems(updatedFilteredItems);
|
||||
} else {
|
||||
let result = []
|
||||
if (SelectedAuction.rebidAllowed) {
|
||||
setAllBoolean((prev: any) => ({ ...prev, rebid: true }))
|
||||
}
|
||||
|
||||
if (SelectedAuction.auctionCategories != 'Live') {
|
||||
result = await getOneTimeBidValue()
|
||||
}
|
||||
if (SelectedAuction.rebidAllowed) setAllBoolean(prev => ({ ...prev, rebid: true }));
|
||||
let result: any[] = [];
|
||||
if (SelectedAuction.auctionCategories !== 'Live') result = await getOneTimeBidValue();
|
||||
const bidMap = new Map<number, any>();
|
||||
|
||||
result.forEach((bid: any) => {
|
||||
bidMap.set(bid.auctionItemId, bid);
|
||||
});
|
||||
result.forEach((bid: any) => bidMap.set(bid.auctionItemId, bid));
|
||||
const mergedData = auctionItem.map((item: any) => {
|
||||
const bid = bidMap.get(item.id);
|
||||
|
||||
if (!bid) {
|
||||
return {
|
||||
...item,
|
||||
bidAmount: item.auctionStartValueFigure,
|
||||
contractorId: item.contractorId,
|
||||
};
|
||||
}
|
||||
|
||||
if (!bid) return { ...item, bidAmount: item.auctionStartValueFigure, contractorId: item.contractorId };
|
||||
return {
|
||||
...item,
|
||||
bidAmount: bid.bidAmount,
|
||||
@@ -150,56 +125,36 @@ const StartBidding = () => {
|
||||
};
|
||||
});
|
||||
const initialBids: Record<number, number> = {};
|
||||
mergedData.forEach(item => {
|
||||
initialBids[item.id] = item.bidAmount;
|
||||
});
|
||||
setBidValues(initialBids);
|
||||
setItems(mergedData)
|
||||
mergedData.forEach(item => { initialBids[item.id] = item.bidAmount; });
|
||||
setBidValues(initialBids);
|
||||
setItems(mergedData);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching auction items:', error);
|
||||
}
|
||||
};
|
||||
|
||||
subscribe(`/topic/room/${SelectedAuction.auctionNumber}`, async (message) => {
|
||||
|
||||
const result = message[message.length - 1]
|
||||
|
||||
const updatedBidItem = (prev: any[]) =>
|
||||
subscribe(`/topic/room/${SelectedAuction.auctionNumber}`, async (message: any) => {
|
||||
const result = message[message.length - 1];
|
||||
setItems((prev: any[]) =>
|
||||
prev.map(item =>
|
||||
item.id === result.auctionItemId
|
||||
? { ...item, bidAmount: result.bidAmount, me: result.contractorId == loginUser.contractorId ? true : false }
|
||||
: item
|
||||
);
|
||||
|
||||
setItems(updatedBidItem);
|
||||
|
||||
setBidValues(prev => ({
|
||||
...prev,
|
||||
[result.auctionItemId]: result.bidAmount,
|
||||
}));
|
||||
try {
|
||||
|
||||
} catch (err) {
|
||||
console.log('JSON parse error:', err);
|
||||
}
|
||||
? { ...item, bidAmount: result.bidAmount, me: result.contractorId === loginUser.contractorId }
|
||||
: item,
|
||||
),
|
||||
);
|
||||
setBidValues(prev => ({ ...prev, [result.auctionItemId]: result.bidAmount }));
|
||||
});
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (SelectedAuction.auctionCategories == 'One-time') {
|
||||
getAuction()
|
||||
}
|
||||
if (SelectedAuction.auctionCategories === 'One-time') getAuction();
|
||||
getAllAcutionItems();
|
||||
subscribe(`/topic/room/${SelectedAuction.auctionNumber}`, (data) => { });
|
||||
subscribe(`/topic/room/${SelectedAuction.auctionNumber}`, () => {});
|
||||
}, [allBoolean.reload]);
|
||||
|
||||
useEffect(() => {
|
||||
const initial: Record<number, number> = {};
|
||||
items.forEach((item: any) => {
|
||||
initial[item.id] = item.bidAmount + item.bidVariationValue;
|
||||
});
|
||||
items.forEach((item: any) => { initial[item.id] = item.bidAmount + item.bidVariationValue; });
|
||||
setBidValues(initial);
|
||||
}, []);
|
||||
|
||||
@@ -216,51 +171,14 @@ const StartBidding = () => {
|
||||
fullName: loginUser.fullName,
|
||||
roomId: SelectedAuction.auctionNumber,
|
||||
};
|
||||
setAllBoolean((prev: any) => ({ ...prev, bidPayload: payload, }));
|
||||
Alert.alert(
|
||||
'Confirm Bid',
|
||||
`Are you sure you want to place a bid of ₹${payload.bidAmount}?`,
|
||||
[
|
||||
{
|
||||
text: 'Cancel',
|
||||
style: 'cancel',
|
||||
},
|
||||
{
|
||||
text: 'Submit',
|
||||
onPress: () => {
|
||||
|
||||
placeBidSubmit(payload);
|
||||
},
|
||||
},
|
||||
],
|
||||
{ cancelable: true }
|
||||
);
|
||||
setAllBoolean(prev => ({ ...prev, bidPayload: payload, showDialog: true }));
|
||||
};
|
||||
|
||||
const placeBidSubmit = async (data: any) => {
|
||||
setAllBoolean(prev => ({ ...prev, showDialog: false }));
|
||||
try {
|
||||
const result: any = await placeBid(data);
|
||||
|
||||
if (result?.status && result.data) {
|
||||
const updatedBidItem = (prev: any[]) =>
|
||||
prev.map(item =>
|
||||
item.id === result.data.auctionItemId
|
||||
? { ...item, bidAmount: result.data.bidAmount, me: result.data?.contractorId == loginUser.contractorId ? true : false }
|
||||
: item
|
||||
);
|
||||
|
||||
// setItems(updatedBidItem);
|
||||
|
||||
|
||||
// setBidValues((prev: any) => ({
|
||||
// ...prev,
|
||||
// [result.data.auctionItemId]: {
|
||||
// ...prev[result.data.auctionItemId],
|
||||
// bidAmount: result.data.bidAmount,
|
||||
// },
|
||||
// }));
|
||||
getAllAcutionItems()
|
||||
}
|
||||
if (result?.status && result.data) getAllAcutionItems();
|
||||
} catch (error) {
|
||||
console.error('Error placing bid:', error);
|
||||
}
|
||||
@@ -269,55 +187,75 @@ const StartBidding = () => {
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
const onBackPress = () => {
|
||||
Alert.alert(
|
||||
'Confirm',
|
||||
'Do you want to go back to Dashboard?',
|
||||
[
|
||||
{ text: 'Cancel', style: 'cancel' },
|
||||
{
|
||||
text: 'Yes',
|
||||
onPress: () => {
|
||||
Navigation.dispatch(
|
||||
CommonActions.reset({
|
||||
index: 0,
|
||||
routes: [{ name: NavigationString.Home }],
|
||||
})
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
{ cancelable: true }
|
||||
);
|
||||
|
||||
return true; // block default back action
|
||||
setAllBoolean(prev => ({ ...prev, showBackDialog: true }));
|
||||
return true;
|
||||
};
|
||||
|
||||
const subscription = BackHandler.addEventListener(
|
||||
'hardwareBackPress',
|
||||
onBackPress
|
||||
);
|
||||
|
||||
return () => subscription.remove();
|
||||
}, [Navigation])
|
||||
const sub = BackHandler.addEventListener('hardwareBackPress', onBackPress);
|
||||
return () => sub.remove();
|
||||
}, [Navigation]),
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<InsideHeader title="Bidding Panel" showArrow />
|
||||
<View style={styles.container2}>
|
||||
<Text style={styles.title}>
|
||||
{SelectedAuction.deptName}
|
||||
</Text>
|
||||
const styles = makeStyles(colors, spacing, shadows);
|
||||
|
||||
<View style={styles.timerWrapper}>
|
||||
const biddingEndDate =
|
||||
SelectedAuction?.auctionStatus === 'Amended'
|
||||
? SelectedAuction?.amendedkeyDates?.auctionBidding?.endDateTime
|
||||
: SelectedAuction?.keyDates?.auctionBidding?.endDateTime;
|
||||
|
||||
return (
|
||||
<View style={styles.root}>
|
||||
<InsideHeader title="Bidding Panel" showArrow />
|
||||
|
||||
{/* ── Top Info Band ── */}
|
||||
<Animated.View entering={FadeInDown.springify()} style={styles.infoBand}>
|
||||
{/* Department row */}
|
||||
<View style={styles.deptRow}>
|
||||
<View style={[styles.deptIcon, { backgroundColor: `${colors.primary}15` }]}>
|
||||
<Building2 size={16} color={colors.primary} strokeWidth={2} />
|
||||
</View>
|
||||
<AppText variant="bodySmall" color={colors.text} bold numberOfLines={1} style={styles.deptName as any}>
|
||||
{SelectedAuction.deptName ?? 'Auction Department'}
|
||||
</AppText>
|
||||
</View>
|
||||
|
||||
{/* Timer card */}
|
||||
<View style={[styles.timerCard, { backgroundColor: `${colors.primary}10`, borderColor: `${colors.primary}25` }]}>
|
||||
<View style={styles.timerLabelRow}>
|
||||
<Clock4 size={13} color={colors.primary} strokeWidth={2} />
|
||||
<AppText variant="caption" color={colors.primary} bold style={styles.timerLabel as any}>
|
||||
BIDDING ENDS IN
|
||||
</AppText>
|
||||
</View>
|
||||
<CountdownTimer
|
||||
endDate={SelectedAuction.keyDates.auctionBidding.endDateTime}
|
||||
myStyle={{ fontSize: 30 }}
|
||||
size={30}
|
||||
endDate={biddingEndDate}
|
||||
myStyle={{ fontSize: 28, fontWeight: '900', color: colors.primary, letterSpacing: 1 }}
|
||||
size={28}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Auction chip */}
|
||||
<View style={styles.chipRow}>
|
||||
<View style={[styles.chip, { backgroundColor: `${colors.primary}12` }]}>
|
||||
<Gavel size={12} color={colors.primary} strokeWidth={2} />
|
||||
<AppText variant="caption" color={colors.primary} bold style={styles.chipText as any}>
|
||||
{SelectedAuction.auctionNumber}
|
||||
</AppText>
|
||||
</View>
|
||||
<View style={[styles.chip, { backgroundColor: SelectedAuction.auctionCategories === 'Live' ? `${colors.success}15` : `${colors.textSecondary}12` }]}>
|
||||
<View style={[styles.liveDot, { backgroundColor: SelectedAuction.auctionCategories === 'Live' ? colors.success : colors.textSecondary }]} />
|
||||
<AppText
|
||||
variant="caption"
|
||||
color={SelectedAuction.auctionCategories === 'Live' ? colors.success : colors.textSecondary}
|
||||
bold
|
||||
style={styles.chipText as any}
|
||||
>
|
||||
{SelectedAuction.auctionCategories ?? 'Auction'}
|
||||
</AppText>
|
||||
</View>
|
||||
</View>
|
||||
</Animated.View>
|
||||
|
||||
{/* ── Items List ── */}
|
||||
<FlatList
|
||||
data={items}
|
||||
keyExtractor={item => item.id.toString()}
|
||||
@@ -327,15 +265,17 @@ const StartBidding = () => {
|
||||
bidValue={bidValues[item.id] || 0}
|
||||
onIncrease={() => handleUpdate(item.id, item.bidVariationValue)}
|
||||
onDecrease={() => handleUpdate(item.id, -item.bidVariationValue)}
|
||||
onPlaceBid={() => { submitBid(item) }}
|
||||
onPlaceBid={() => submitBid(item)}
|
||||
SelectedAuction={SelectedAuction}
|
||||
allBoolean={allBoolean}
|
||||
setAllBoolean={setAllBoolean}
|
||||
/>
|
||||
)}
|
||||
contentContainerStyle={{ padding: 16, paddingBottom: 300 }}
|
||||
contentContainerStyle={styles.listContent}
|
||||
showsVerticalScrollIndicator={false}
|
||||
/>
|
||||
|
||||
{/* ── Success overlay ── */}
|
||||
{allBoolean.showSuccess && (
|
||||
<View style={styles.overlay}>
|
||||
<LottieView
|
||||
@@ -346,66 +286,117 @@ const StartBidding = () => {
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<ConfirmBidModal
|
||||
visible={allBoolean.showDialog}
|
||||
onClose={() => setAllBoolean(prev => ({ ...prev, showDialog: false }))}
|
||||
onConfirm={() => placeBidSubmit(allBoolean.bidPayload)}
|
||||
bidAmount={allBoolean.bidPayload?.bidAmount}
|
||||
/>
|
||||
|
||||
<GoBackModal
|
||||
visible={allBoolean.showBackDialog}
|
||||
onClose={() => setAllBoolean(prev => ({ ...prev, showBackDialog: false }))}
|
||||
onConfirm={() => {
|
||||
setAllBoolean(prev => ({ ...prev, showBackDialog: false }));
|
||||
Navigation.dispatch(
|
||||
CommonActions.reset({
|
||||
index: 0,
|
||||
routes: [{ name: NavigationString.Home }],
|
||||
})
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default StartBidding;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: { flex: 1, backgroundColor: colors.white },
|
||||
container2: {
|
||||
paddingHorizontal: 16,
|
||||
paddingTop: 12,
|
||||
paddingBottom: 8,
|
||||
},
|
||||
title: {
|
||||
fontSize: 18,
|
||||
fontFamily: FontsFamily.poppinsSemiBold,
|
||||
color: colors.black,
|
||||
marginBottom: 6,
|
||||
// textAlign:'center'
|
||||
},
|
||||
timerWrapper: {
|
||||
alignItems: 'center',
|
||||
},
|
||||
card: {
|
||||
backgroundColor: '#FFF',
|
||||
borderRadius: 24,
|
||||
padding: 20,
|
||||
marginBottom: 16,
|
||||
borderWidth: 1,
|
||||
borderColor: '#E2E8F0',
|
||||
overflow: 'hidden',
|
||||
...Platform.select({ ios: { shadowColor: '#000', shadowOpacity: 0.05, shadowRadius: 10 }, android: { elevation: 2 } }),
|
||||
},
|
||||
leadingCard: { borderColor: '#22C55E', borderWidth: 2, backgroundColor: '#F0FDF4' },
|
||||
cardHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start' },
|
||||
headerRight: { flexDirection: 'row', alignItems: 'center', gap: 8 },
|
||||
productName: { fontSize: 18, fontWeight: 'bold', color: '#1E293B' },
|
||||
itemIdText: { fontSize: 12, color: '#64748B', marginTop: 2 },
|
||||
badge: { paddingHorizontal: 10, paddingVertical: 4, borderRadius: 8 },
|
||||
liveBadge: { backgroundColor: '#FEE2E2' },
|
||||
meBadge: { backgroundColor: '#BBF7D0' },
|
||||
badgeText: { fontSize: 10, fontWeight: '900' },
|
||||
liveText: { color: '#EF4444' },
|
||||
meText: { color: '#15803D' },
|
||||
arrow: { fontSize: 10, color: '#94A3B8' },
|
||||
priceRow: { flexDirection: 'row', justifyContent: 'space-between', marginTop: 20 },
|
||||
label: { fontSize: 11, color: '#94A3B8', textTransform: 'uppercase', fontWeight: '600' },
|
||||
mainPrice: { fontSize: 22, fontWeight: '900', color: '#0F172A' },
|
||||
incrementText: { fontSize: 16, fontWeight: '700', color: '#3B82F6' },
|
||||
collapsibleContainer: { overflow: 'hidden' },
|
||||
divider: { height: 1, backgroundColor: '#E2E8F0', marginVertical: 10 },
|
||||
bidLabel: { fontSize: 13, fontWeight: '600', color: '#475569', marginBottom: 10 },
|
||||
stepperContainer: { flexDirection: 'row', gap: 12, marginBottom: 20 },
|
||||
stepBtn: { width: 45, height: 45, backgroundColor: colors.primary, borderRadius: 12, justifyContent: 'center', alignItems: 'center' },
|
||||
disabledBtn: { backgroundColor: '#CBD5E1' },
|
||||
stepText: { color: '#FFF', fontSize: 20, fontWeight: 'bold' },
|
||||
inputBox: { flex: 1, height: 45, backgroundColor: '#F1F5F9', borderRadius: 12, flexDirection: 'row', alignItems: 'center', justifyContent: 'center' },
|
||||
currency: { fontSize: 16, fontWeight: 'bold', color: '#64748B', marginRight: 4 },
|
||||
bidValueText: { fontSize: 18, fontWeight: '800', color: '#0F172A' },
|
||||
submitBtn: { height: 50, backgroundColor: colors.primary, borderRadius: 15, justifyContent: 'center', alignItems: 'center' },
|
||||
submitBtnText: { color: '#FFF', fontSize: 16, fontWeight: 'bold' },
|
||||
overlay: { ...StyleSheet.absoluteFillObject, backgroundColor: 'rgba(255,255,255,0.7)', justifyContent: 'center', alignItems: 'center', zIndex: 99 },
|
||||
});
|
||||
/* ─── Styles factory ─── */
|
||||
const makeStyles = (colors: any, spacing: any, shadows: any) =>
|
||||
StyleSheet.create({
|
||||
root: {
|
||||
flex: 1,
|
||||
backgroundColor: colors.background,
|
||||
},
|
||||
|
||||
/* Info band */
|
||||
infoBand: {
|
||||
backgroundColor: colors.surface,
|
||||
paddingHorizontal: spacing.m,
|
||||
paddingVertical: spacing.m,
|
||||
borderBottomWidth: StyleSheet.hairlineWidth,
|
||||
borderBottomColor: colors.border,
|
||||
gap: spacing.s,
|
||||
...shadows.light,
|
||||
},
|
||||
deptRow: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: spacing.s,
|
||||
},
|
||||
deptIcon: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 9,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
deptName: {
|
||||
flex: 1,
|
||||
} as any,
|
||||
|
||||
/* Timer */
|
||||
timerCard: {
|
||||
borderRadius: 16,
|
||||
borderWidth: 1.2,
|
||||
paddingVertical: spacing.m,
|
||||
paddingHorizontal: spacing.m,
|
||||
alignItems: 'center',
|
||||
gap: 4,
|
||||
},
|
||||
timerLabelRow: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 4,
|
||||
},
|
||||
timerLabel: {
|
||||
letterSpacing: 1.2,
|
||||
} as any,
|
||||
|
||||
/* Chips */
|
||||
chipRow: {
|
||||
flexDirection: 'row',
|
||||
gap: spacing.s,
|
||||
},
|
||||
chip: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 4,
|
||||
paddingHorizontal: spacing.s + 4,
|
||||
paddingVertical: 5,
|
||||
borderRadius: 20,
|
||||
},
|
||||
chipText: {
|
||||
letterSpacing: 0.3,
|
||||
} as any,
|
||||
liveDot: {
|
||||
width: 6,
|
||||
height: 6,
|
||||
borderRadius: 3,
|
||||
},
|
||||
|
||||
listContent: {
|
||||
padding: spacing.m,
|
||||
paddingBottom: 120,
|
||||
},
|
||||
|
||||
overlay: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
backgroundColor: colors.overlay,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
zIndex: 99,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -11,16 +11,21 @@ import { AUCTION_ONE_TIME_BID, GET_AUCTION_DETAILS, REVERSE_AUCTION_ITEM, SELECT
|
||||
import { CommonActions, useFocusEffect, useNavigation } from '@react-navigation/native';
|
||||
import NavigationString from '../../Constant/NavigationString';
|
||||
import CountdownTimer from '../../Component/Counter/CountdownTimer';
|
||||
import FontsFamily from '../../Constant/FontsFamily';
|
||||
import { useTheme } from '../../Hooks/useTheme';
|
||||
import AppText from '../../components/AppText';
|
||||
import ReverseBiddingCard from './Component/ReverseBiddingCard';
|
||||
import ConfirmBidModal from './Component/ConfirmBidModal';
|
||||
import GoBackModal from './Component/GoBackModal';
|
||||
|
||||
const StartReverseBidding = () => {
|
||||
const { colors } = useTheme();
|
||||
const styles = React.useMemo(() => makeStyles(colors), [colors]);
|
||||
const SelectedAuction = useSelector((state: any) => state.auction.auction);
|
||||
const loginUser = useSelector((state: any) => state.token.token)
|
||||
const Navigation: any = useNavigation()
|
||||
const [items, setItems] = useState<any>([]);
|
||||
const [bidValues, setBidValues] = useState<Record<number, number>>({});
|
||||
const [allBoolean, setAllBoolean] = useState({ showSuccess: false, showDialog: false, bidPayload: {}, oneTimeBid: false, rebid: false, reload: false })
|
||||
const [allBoolean, setAllBoolean] = useState({ showSuccess: false, showDialog: false, showBackDialog: false, bidPayload: {} as any, oneTimeBid: false, rebid: false, reload: false })
|
||||
const { subscribe, createRoom, placeBid } = useWebSocketService(
|
||||
Variables.webSocketUrl,
|
||||
() => console.log('Connected!'),
|
||||
@@ -216,27 +221,11 @@ const StartReverseBidding = () => {
|
||||
fullName: loginUser.fullName,
|
||||
roomId: SelectedAuction.auctionNumber,
|
||||
};
|
||||
setAllBoolean((prev: any) => ({ ...prev, bidPayload: payload, }));
|
||||
Alert.alert(
|
||||
'Confirm Bid',
|
||||
`Are you sure you want to place a bid of ₹${payload.bidAmount}?`,
|
||||
[
|
||||
{
|
||||
text: 'Cancel',
|
||||
style: 'cancel',
|
||||
},
|
||||
{
|
||||
text: 'Submit',
|
||||
onPress: () => {
|
||||
placeBidSubmit(payload);
|
||||
},
|
||||
},
|
||||
],
|
||||
{ cancelable: true }
|
||||
);
|
||||
setAllBoolean((prev: any) => ({ ...prev, bidPayload: payload, showDialog: true }));
|
||||
};
|
||||
|
||||
const placeBidSubmit = async (data: any) => {
|
||||
setAllBoolean((prev: any) => ({ ...prev, showDialog: false }));
|
||||
try {
|
||||
const result: any = await placeBid(data);
|
||||
|
||||
@@ -258,26 +247,7 @@ const StartReverseBidding = () => {
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
const onBackPress = () => {
|
||||
Alert.alert(
|
||||
'Confirm',
|
||||
'Do you want to go back to Dashboard?',
|
||||
[
|
||||
{ text: 'Cancel', style: 'cancel' },
|
||||
{
|
||||
text: 'Yes',
|
||||
onPress: () => {
|
||||
Navigation.dispatch(
|
||||
CommonActions.reset({
|
||||
index: 0,
|
||||
routes: [{ name: NavigationString.Home }],
|
||||
})
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
{ cancelable: true }
|
||||
);
|
||||
|
||||
setAllBoolean((prev: any) => ({ ...prev, showBackDialog: true }));
|
||||
return true; // block default back action
|
||||
};
|
||||
|
||||
@@ -294,9 +264,9 @@ const StartReverseBidding = () => {
|
||||
<View style={styles.container}>
|
||||
<InsideHeader title="Bidding Panel" showArrow />
|
||||
<View style={styles.container2}>
|
||||
<Text style={styles.title}>
|
||||
<AppText variant="h3" color={colors.text} bold style={styles.title as any}>
|
||||
{SelectedAuction.deptName}
|
||||
</Text>
|
||||
</AppText>
|
||||
|
||||
<View style={styles.timerWrapper}>
|
||||
<CountdownTimer
|
||||
@@ -335,66 +305,45 @@ const StartReverseBidding = () => {
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<ConfirmBidModal
|
||||
visible={allBoolean.showDialog}
|
||||
onClose={() => setAllBoolean(prev => ({ ...prev, showDialog: false }))}
|
||||
onConfirm={() => placeBidSubmit(allBoolean.bidPayload)}
|
||||
bidAmount={allBoolean.bidPayload?.bidAmount}
|
||||
/>
|
||||
|
||||
<GoBackModal
|
||||
visible={allBoolean.showBackDialog}
|
||||
onClose={() => setAllBoolean(prev => ({ ...prev, showBackDialog: false }))}
|
||||
onConfirm={() => {
|
||||
setAllBoolean(prev => ({ ...prev, showBackDialog: false }));
|
||||
Navigation.dispatch(
|
||||
CommonActions.reset({
|
||||
index: 0,
|
||||
routes: [{ name: NavigationString.Home }],
|
||||
})
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default StartReverseBidding;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: { flex: 1, backgroundColor: colors.white },
|
||||
const makeStyles = (colors: any) => StyleSheet.create({
|
||||
container: { flex: 1, backgroundColor: colors.background },
|
||||
container2: {
|
||||
paddingHorizontal: 16,
|
||||
paddingTop: 12,
|
||||
paddingBottom: 8,
|
||||
},
|
||||
title: {
|
||||
fontSize: 18,
|
||||
fontFamily: FontsFamily.poppinsSemiBold,
|
||||
color: colors.black,
|
||||
marginBottom: 6,
|
||||
// textAlign:'center'
|
||||
},
|
||||
} as any,
|
||||
timerWrapper: {
|
||||
alignItems: 'center',
|
||||
},
|
||||
card: {
|
||||
backgroundColor: '#FFF',
|
||||
borderRadius: 24,
|
||||
padding: 20,
|
||||
marginBottom: 16,
|
||||
borderWidth: 1,
|
||||
borderColor: '#E2E8F0',
|
||||
overflow: 'hidden',
|
||||
...Platform.select({ ios: { shadowColor: '#000', shadowOpacity: 0.05, shadowRadius: 10 }, android: { elevation: 2 } }),
|
||||
},
|
||||
leadingCard: { borderColor: '#22C55E', borderWidth: 2, backgroundColor: '#F0FDF4' },
|
||||
cardHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start' },
|
||||
headerRight: { flexDirection: 'row', alignItems: 'center', gap: 8 },
|
||||
productName: { fontSize: 18, fontWeight: 'bold', color: '#1E293B' },
|
||||
itemIdText: { fontSize: 12, color: '#64748B', marginTop: 2 },
|
||||
badge: { paddingHorizontal: 10, paddingVertical: 4, borderRadius: 8 },
|
||||
liveBadge: { backgroundColor: '#FEE2E2' },
|
||||
meBadge: { backgroundColor: '#BBF7D0' },
|
||||
badgeText: { fontSize: 10, fontWeight: '900' },
|
||||
liveText: { color: '#EF4444' },
|
||||
meText: { color: '#15803D' },
|
||||
arrow: { fontSize: 10, color: '#94A3B8' },
|
||||
priceRow: { flexDirection: 'row', justifyContent: 'space-between', marginTop: 20 },
|
||||
label: { fontSize: 11, color: '#94A3B8', textTransform: 'uppercase', fontWeight: '600' },
|
||||
mainPrice: { fontSize: 22, fontWeight: '900', color: '#0F172A' },
|
||||
incrementText: { fontSize: 16, fontWeight: '700', color: '#3B82F6' },
|
||||
collapsibleContainer: { overflow: 'hidden' },
|
||||
divider: { height: 1, backgroundColor: '#E2E8F0', marginVertical: 10 },
|
||||
bidLabel: { fontSize: 13, fontWeight: '600', color: '#475569', marginBottom: 10 },
|
||||
stepperContainer: { flexDirection: 'row', gap: 12, marginBottom: 20 },
|
||||
stepBtn: { width: 45, height: 45, backgroundColor: colors.primary, borderRadius: 12, justifyContent: 'center', alignItems: 'center' },
|
||||
disabledBtn: { backgroundColor: '#CBD5E1' },
|
||||
stepText: { color: '#FFF', fontSize: 20, fontWeight: 'bold' },
|
||||
inputBox: { flex: 1, height: 45, backgroundColor: '#F1F5F9', borderRadius: 12, flexDirection: 'row', alignItems: 'center', justifyContent: 'center' },
|
||||
currency: { fontSize: 16, fontWeight: 'bold', color: '#64748B', marginRight: 4 },
|
||||
bidValueText: { fontSize: 18, fontWeight: '800', color: '#0F172A' },
|
||||
submitBtn: { height: 50, backgroundColor: colors.primary, borderRadius: 15, justifyContent: 'center', alignItems: 'center' },
|
||||
submitBtnText: { color: '#FFF', fontSize: 16, fontWeight: 'bold' },
|
||||
overlay: { ...StyleSheet.absoluteFillObject, backgroundColor: 'rgba(255,255,255,0.7)', justifyContent: 'center', alignItems: 'center', zIndex: 99 },
|
||||
overlay: { ...StyleSheet.absoluteFillObject, backgroundColor: colors.overlay, justifyContent: 'center', alignItems: 'center', zIndex: 99 },
|
||||
});
|
||||
Reference in New Issue
Block a user