commit
This commit is contained in:
+2
-2
@@ -11,7 +11,7 @@ export const apiCall = async <R, D = {}>(
|
|||||||
): Promise<R> => {
|
): Promise<R> => {
|
||||||
try {
|
try {
|
||||||
const token: any = store.getState().token.token;
|
const token: any = store.getState().token.token;
|
||||||
|
console.log("api payload", data)
|
||||||
const response = await axios({
|
const response = await axios({
|
||||||
method,
|
method,
|
||||||
url,
|
url,
|
||||||
@@ -22,7 +22,7 @@ export const apiCall = async <R, D = {}>(
|
|||||||
'Content-Type': contentType || 'application/json',
|
'Content-Type': contentType || 'application/json',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
console.log("api response",response)
|
||||||
return response.data;
|
return response.data;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const errorMessage = error?.response?.data?.error;
|
const errorMessage = error?.response?.data?.error;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ const NavigationString = {
|
|||||||
Profile:'Profile',
|
Profile:'Profile',
|
||||||
ViewTenderDetail:'ViewTenderDetail',
|
ViewTenderDetail:'ViewTenderDetail',
|
||||||
ResetPassword:'ResetPassword',
|
ResetPassword:'ResetPassword',
|
||||||
KycWebViewScreen:'KycWebViewScreen'
|
KycWebViewScreen:'KycWebViewScreen',
|
||||||
|
StageThreeScreen:'StageThree'
|
||||||
}
|
}
|
||||||
export default NavigationString
|
export default NavigationString
|
||||||
@@ -48,6 +48,8 @@ export default function MainStack() {
|
|||||||
<Stack.Screen name={NavigationString.ResetPassword} component={Screens.ResetPassword} options={option} />
|
<Stack.Screen name={NavigationString.ResetPassword} component={Screens.ResetPassword} options={option} />
|
||||||
<Stack.Screen name={NavigationString.ViewTenderDetail} component={Screens.ViewTenderDetail} options={option} />
|
<Stack.Screen name={NavigationString.ViewTenderDetail} component={Screens.ViewTenderDetail} options={option} />
|
||||||
<Stack.Screen name={NavigationString.KycWebViewScreen} component={Screens.KycWebViewScreen} options={option} />
|
<Stack.Screen name={NavigationString.KycWebViewScreen} component={Screens.KycWebViewScreen} options={option} />
|
||||||
|
<Stack.Screen name={NavigationString.StageThreeScreen} component={Screens.StageThreeScreen} options={option} />
|
||||||
|
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,37 +15,24 @@ import Skeleton from '../../Component/Skelton/Skelton';
|
|||||||
|
|
||||||
const LiveAuction = () => {
|
const LiveAuction = () => {
|
||||||
const Dispatch = useDispatch()
|
const Dispatch = useDispatch()
|
||||||
|
const user = useSelector((state: any) => state.token?.token);
|
||||||
const onEndReachedCalledDuringMomentum = useRef(true);
|
const onEndReachedCalledDuringMomentum = useRef(true);
|
||||||
const SelectedPurchaseList = useSelector((state: any) => state.selectPurchaseAuction);
|
const SelectedPurchaseList = useSelector((state: any) => state.selectPurchaseAuction);
|
||||||
const [showRefreshBanner, setShowRefreshBanner] = useState(false);
|
const [showRefreshBanner, setShowRefreshBanner] = useState(false);
|
||||||
const [allBoolean, setAllBoolean] = useState({ liveAuctionData: [], isLoading: false })
|
const [allBoolean, setAllBoolean] = useState({ liveAuctionData: [], isLoading: false })
|
||||||
const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading, isRefetching, refetch, isPending }: any = useFetchLiveAuction();
|
const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading, isRefetching, refetch, isPending }: any = useFetchLiveAuction();
|
||||||
|
console.log("object----",data,)
|
||||||
// My Methods
|
// My Methods
|
||||||
|
|
||||||
const getMyAuction = async () => {
|
|
||||||
try {
|
|
||||||
setAllBoolean(prev => ({ ...prev, isLoading: true }))
|
|
||||||
const res = await apiCall<any>('get', `${GET_MY_AUCTION}`,);
|
|
||||||
|
|
||||||
if (res?.statusCode === 200) {
|
|
||||||
const purchasedIds = new Set(res.data.map((item: any) => item.auctionId));
|
|
||||||
const filteredLive = data?.result.map((item: any) => ({ ...item, active: !purchasedIds.has(item.auctionId) }));
|
|
||||||
setAllBoolean(prev => ({ ...prev, liveAuctionData: filteredLive }));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('getMyAuction error', error);
|
|
||||||
} finally {
|
|
||||||
setAllBoolean(prev => ({ ...prev, isLoading: false }));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderItem = useCallback(
|
const renderItem = useCallback(
|
||||||
({ item, index }: any) => {
|
({ item, index }: any) => {
|
||||||
|
console.log("item core ",item)
|
||||||
const isPurchase = SelectedPurchaseList.findIndex((prev: any) => prev.auctionNumber === item.auctionNumber)
|
const isPurchase = SelectedPurchaseList.findIndex((prev: any) => prev.auctionNumber === item.auctionNumber)
|
||||||
return <LiveAuctionTile
|
return <LiveAuctionTile
|
||||||
data={item}
|
data={item}
|
||||||
index={index}
|
index={index}
|
||||||
|
isPurchasedByContractor={item.contractorId?.includes(String(user.contractorId))}
|
||||||
auctionId={item.auctionId}
|
auctionId={item.auctionId}
|
||||||
auctionDispatchDate={item.auctionDispatchDate}
|
auctionDispatchDate={item.auctionDispatchDate}
|
||||||
isPurchased={isPurchase !== -1 ? true : false}
|
isPurchased={isPurchase !== -1 ? true : false}
|
||||||
@@ -90,11 +77,6 @@ const LiveAuction = () => {
|
|||||||
}
|
}
|
||||||
}, [isRefetching]);
|
}, [isRefetching]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (data?.result?.length > 0) {
|
|
||||||
getMyAuction()
|
|
||||||
}
|
|
||||||
}, [data])
|
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return <Skelton />;
|
return <Skelton />;
|
||||||
@@ -141,9 +123,9 @@ const LiveAuction = () => {
|
|||||||
</Animated.View>
|
</Animated.View>
|
||||||
)}
|
)}
|
||||||
{
|
{
|
||||||
isPending || allBoolean.isLoading ? <Skeleton /> :
|
isPending ? <Skeleton /> :
|
||||||
<FlatList
|
<FlatList
|
||||||
data={allBoolean.liveAuctionData ?? []}
|
data={data?.result ?? []}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
showsVerticalScrollIndicator={false}
|
showsVerticalScrollIndicator={false}
|
||||||
contentContainerStyle={{ paddingBottom: 50, paddingTop: 10 }}
|
contentContainerStyle={{ paddingBottom: 50, paddingTop: 10 }}
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ const LiveAuctionTile: React.FC<LiveAuctionTileProps> = ({
|
|||||||
purchaseEnd,
|
purchaseEnd,
|
||||||
auctionFees,
|
auctionFees,
|
||||||
auctionNumber,
|
auctionNumber,
|
||||||
|
isPurchasedByContractor
|
||||||
}) => {
|
}) => {
|
||||||
|
console.log("1",data)
|
||||||
const [showDetail, setShowDetail] = React.useState(false);
|
const [showDetail, setShowDetail] = React.useState(false);
|
||||||
const purchaseEnded = moment().isAfter(moment(purchaseEnd, 'DD-MM-YYYY HH:mm:ss'));
|
const purchaseEnded = moment().isAfter(moment(purchaseEnd, 'DD-MM-YYYY HH:mm:ss'));
|
||||||
|
|
||||||
@@ -80,12 +82,12 @@ const LiveAuctionTile: React.FC<LiveAuctionTileProps> = ({
|
|||||||
styles.mainButton,
|
styles.mainButton,
|
||||||
purchaseEnded
|
purchaseEnded
|
||||||
? styles.btnDisabled
|
? styles.btnDisabled
|
||||||
: !data.active ? { backgroundColor: 'lightgray' } : isPurchased
|
: isPurchasedByContractor ? { backgroundColor: 'lightgray' } : isPurchased
|
||||||
? styles.btnPurchased
|
? styles.btnPurchased
|
||||||
: styles.btnActive,
|
: styles.btnActive,
|
||||||
]}
|
]}
|
||||||
onPress={onPurchasePress}
|
onPress={onPurchasePress}
|
||||||
disabled={purchaseEnded ? true : data.active ? false : true}
|
disabled={purchaseEnded ? true : !isPurchasedByContractor ? false : true}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
style={[
|
style={[
|
||||||
@@ -93,9 +95,9 @@ const LiveAuctionTile: React.FC<LiveAuctionTileProps> = ({
|
|||||||
isPurchased && !purchaseEnded ? { color: colors.white } : { color: '#fff' },
|
isPurchased && !purchaseEnded ? { color: colors.white } : { color: '#fff' },
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{purchaseEnded ? 'Expired' : !data.active ? 'Purchased' : isPurchased ? 'Remove' : 'Add to Cart'}
|
{purchaseEnded ? (isPurchasedByContractor ? 'Purchased' : 'Expired') : isPurchasedByContractor ? 'Purchased' : isPurchased ? 'Remove' : 'Add to Cart'}
|
||||||
</Text>
|
</Text>
|
||||||
{!purchaseEnded && (
|
{!purchaseEnded && !isPurchasedByContractor && (
|
||||||
<ArrowRight size={16} color={isPurchased ? colors.white : '#fff'} />
|
<ArrowRight size={16} color={isPurchased ? colors.white : '#fff'} />
|
||||||
)}
|
)}
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ const AuctionFullDetail: React.FC<Props> = ({ visible, onClose, data }) => {
|
|||||||
const [allBoolean, setAllBoolean] = useState({ showItemDetail: false, selectedItem: {}, fileLoading: false });
|
const [allBoolean, setAllBoolean] = useState({ showItemDetail: false, selectedItem: {}, fileLoading: false });
|
||||||
const { data: auctionDocuments } = useGetAucitonDocument({ auctionId: data?.auctionId })
|
const { data: auctionDocuments } = useGetAucitonDocument({ auctionId: data?.auctionId })
|
||||||
const { mutate } = useAuctionItem()
|
const { mutate } = useAuctionItem()
|
||||||
|
console.log("jkjkjk",auctionData)
|
||||||
|
|
||||||
const formatDate = (date?: string) => {
|
const formatDate = (date?: string) => {
|
||||||
if (!date) return '-';
|
if (!date) return '-';
|
||||||
@@ -156,18 +157,42 @@ const AuctionFullDetail: React.FC<Props> = ({ visible, onClose, data }) => {
|
|||||||
<View style={styles.iconCircle}><Clock size={16} color="#64748b" /></View>
|
<View style={styles.iconCircle}><Clock size={16} color="#64748b" /></View>
|
||||||
<View>
|
<View>
|
||||||
<Text style={styles.label}>Auction Purchase (Start)</Text>
|
<Text style={styles.label}>Auction Purchase (Start)</Text>
|
||||||
<Text style={styles.value}>{formatDate(data?.auctionDispatchDate)}</Text>
|
<Text style={styles.value}>{formatDate(
|
||||||
|
auctionData?.auctionStatus === "Amended" ? auctionData?.amendedkeyDates.auctionPurchase.startDateTime : auctionData?.keyDates.auctionPurchase.startDateTime)}</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.timelineConnector} />
|
<View style={styles.timelineConnector} />
|
||||||
<View style={styles.timelineRow}>
|
<View style={styles.timelineRow}>
|
||||||
<View style={[styles.iconCircle, { backgroundColor: '#fee2e2' }]}><Clock size={16} color="#ef4444" /></View>
|
<View style={[styles.iconCircle, { backgroundColor: '#fee2e2' }]}><Clock size={16} color="#ef4444" /></View>
|
||||||
<View>
|
<View>
|
||||||
<Text style={styles.label}>Purchase Deadline (End)</Text>
|
<Text style={styles.label}>Purchase Purchase (End)</Text>
|
||||||
<Text style={styles.value}>{formatDate(data?.keyDates?.auctionPurchase?.startDateTime)}</Text>
|
<Text style={styles.value}>{formatDate(
|
||||||
|
auctionData?.auctionStatus === "Amended" ? auctionData?.amendedkeyDates.auctionPurchase.endDateTime : auctionData?.keyDates.auctionPurchase.endDateTime)}</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
</View>
|
||||||
|
<View style={styles.timelineConnector} />
|
||||||
|
<View style={styles.timelineRow}>
|
||||||
|
<View style={styles.iconCircle}><Clock size={16} color="#64748b" /></View>
|
||||||
|
<View>
|
||||||
|
<Text style={styles.label}>Bidding Start (Start)</Text>
|
||||||
|
<Text style={styles.value}>{formatDate(
|
||||||
|
auctionData?.auctionStatus === "Amended" ? auctionData?.amendedkeyDates.auctionBidding.startDateTime : auctionData?.keyDates.auctionBidding.startDateTime)}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
</View>
|
||||||
|
<View style={styles.timelineConnector} />
|
||||||
|
<View style={styles.timelineRow}>
|
||||||
|
<View style={[styles.iconCircle, { backgroundColor: '#fee2e2' }]}><Clock size={16} color="#ef4444" /></View>
|
||||||
|
<View>
|
||||||
|
<Text style={styles.label}>Bidding Deadline (End)</Text>
|
||||||
|
<Text style={styles.value}>{formatDate(
|
||||||
|
auctionData?.auctionStatus === "Amended" ? auctionData?.amendedkeyDates.auctionBidding.endDateTime : auctionData?.keyDates.auctionBidding.endDateTime)}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
{/* 4. Item Table Section */}
|
{/* 4. Item Table Section */}
|
||||||
|
|||||||
@@ -35,8 +35,9 @@ const PurchaseAuction = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isAuctionEnd(item: any): boolean {
|
function isAuctionEnd(item: any): boolean {
|
||||||
|
console.log("item wih power ",item)
|
||||||
const now = moment();
|
const now = moment();
|
||||||
const end = moment(item?.keyDates?.auctionBidding?.endDateTime, format);
|
const end = moment(item.auctionStatus === "Amended" ? item?.amendedkeyDates?.auctionBidding?.endDateTime : item?.keyDates?.auctionBidding?.endDateTime, format);
|
||||||
|
|
||||||
if (!end.isValid()) return false;
|
if (!end.isValid()) return false;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { use, useEffect, useState } from 'react';
|
||||||
import { View, Text, FlatList, StyleSheet, TouchableOpacity, Alert } from 'react-native';
|
import { View, Text, FlatList, StyleSheet, TouchableOpacity, Alert } from 'react-native';
|
||||||
import { InsideHeader, Loader } from '../../Component/Index';
|
import { InsideHeader, Loader } from '../../Component/Index';
|
||||||
import colors from '../../Constant/Color';
|
import colors from '../../Constant/Color';
|
||||||
@@ -79,7 +79,7 @@ const PurchaseAuctionList = () => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.log(error, "================purchse Error");
|
// console.log(error, "================purchse Error");
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const PurchaseAuctionTile = ({ item, onPressDetails, onStartBidding, buttonEnabl
|
|||||||
const [showDetail, setShowDetail] = React.useState(false);
|
const [showDetail, setShowDetail] = React.useState(false);
|
||||||
const scale = useSharedValue(1);
|
const scale = useSharedValue(1);
|
||||||
const elevation = useSharedValue(8);
|
const elevation = useSharedValue(8);
|
||||||
|
console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", item);
|
||||||
const animatedStyle = useAnimatedStyle(() => {
|
const animatedStyle = useAnimatedStyle(() => {
|
||||||
return {
|
return {
|
||||||
transform: [{ scale: scale.value }],
|
transform: [{ scale: scale.value }],
|
||||||
@@ -73,14 +73,14 @@ const PurchaseAuctionTile = ({ item, onPressDetails, onStartBidding, buttonEnabl
|
|||||||
<Text style={styles.dateText}>
|
<Text style={styles.dateText}>
|
||||||
<Text style={styles.dateLabel}>Bidding Start: </Text>
|
<Text style={styles.dateLabel}>Bidding Start: </Text>
|
||||||
{moment(
|
{moment(
|
||||||
item?.keyDates?.auctionBidding?.startDateTime?.replace(' kk', ''),
|
item?.auctionStatus === "Amended" ? item?.amendedkeyDates?.auctionBidding?.startDateTime?.replace(' kk', '') : item?.keyDates?.auctionBidding?.startDateTime?.replace(' kk', ''),
|
||||||
'DD-MM-YYYY HH:mm:ss'
|
'DD-MM-YYYY HH:mm:ss'
|
||||||
).format('DD MMM YYYY, hh:mm A')}
|
).format('DD MMM YYYY, hh:mm A')}
|
||||||
</Text>
|
</Text>
|
||||||
<Text style={styles.dateText}>
|
<Text style={styles.dateText}>
|
||||||
<Text style={styles.dateLabel}>Bidding Ends: </Text>
|
<Text style={styles.dateLabel}>Bidding Ends: </Text>
|
||||||
{moment(
|
{moment(
|
||||||
item?.keyDates?.auctionBidding?.endDateTime?.replace(' kk', ''),
|
item?.auctionStatus === "Amended" ? item?.amendedkeyDates?.auctionBidding?.endDateTime?.replace(' kk', '') : item?.keyDates?.auctionBidding?.endDateTime?.replace(' kk', ''),
|
||||||
'DD-MM-YYYY HH:mm:ss'
|
'DD-MM-YYYY HH:mm:ss'
|
||||||
).format('DD MMM YYYY, hh:mm A')}
|
).format('DD MMM YYYY, hh:mm A')}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -92,7 +92,7 @@ const PurchaseAuctionTile = ({ item, onPressDetails, onStartBidding, buttonEnabl
|
|||||||
<Text style={styles.footerLabel}>Remaining Time</Text>
|
<Text style={styles.footerLabel}>Remaining Time</Text>
|
||||||
{buttonEnable && !isAuctionEnd ? (
|
{buttonEnable && !isAuctionEnd ? (
|
||||||
<CountdownTimer
|
<CountdownTimer
|
||||||
endDate={item.keyDates.auctionBidding.endDateTime}
|
endDate={item?.auctionStatus === "Amended" ? item?.amendedkeyDates?.auctionBidding?.endDateTime : item?.keyDates?.auctionBidding?.endDateTime}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Text style={styles.endedText}>--:--:--</Text>
|
<Text style={styles.endedText}>--:--:--</Text>
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ useEffect(() => {
|
|||||||
|
|
||||||
{/* Cards */}
|
{/* Cards */}
|
||||||
{SelectedPurchaseList.map((item: any, index: any) => {
|
{SelectedPurchaseList.map((item: any, index: any) => {
|
||||||
|
console.log("item nn", item);
|
||||||
const expanded = expandedIndex === index;
|
const expanded = expandedIndex === index;
|
||||||
return (
|
return (
|
||||||
<Animated.View
|
<Animated.View
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export interface LiveAuctionTileProps {
|
|||||||
isPurchased?: boolean;
|
isPurchased?: boolean;
|
||||||
auctionId?: any;
|
auctionId?: any;
|
||||||
auctionNumber?: any;
|
auctionNumber?: any;
|
||||||
|
isPurchasedByContractor?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface allBooleanProps {
|
export interface allBooleanProps {
|
||||||
|
|||||||
@@ -465,7 +465,8 @@ const EditProfileModal: React.FC<EditProfileModalProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await updateProfileMutation.mutateAsync(formData);
|
const result = await updateProfileMutation.mutateAsync(formData);
|
||||||
|
console.log("UserProfile ",result)
|
||||||
Alert.alert('Success', 'Profile updated successfully');
|
Alert.alert('Success', 'Profile updated successfully');
|
||||||
onSuccess();
|
onSuccess();
|
||||||
onClose();
|
onClose();
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import MyInput from '../../Component/MyInput';
|
|||||||
import { showToast } from '../../Constant/ShowDailog';
|
import { showToast } from '../../Constant/ShowDailog';
|
||||||
import { STAGETHREE } from '../../Services/BBPS/ApiUrls';
|
import { STAGETHREE } from '../../Services/BBPS/ApiUrls';
|
||||||
import { useContractorStageThreeSubmit } from '../../Services/BBPS/Hooks';
|
import { useContractorStageThreeSubmit } from '../../Services/BBPS/Hooks';
|
||||||
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
|
|
||||||
|
|
||||||
type Company = {
|
type Company = {
|
||||||
@@ -37,7 +38,7 @@ type StageThreeRouteParams = {
|
|||||||
const StageThreeScreen = () => {
|
const StageThreeScreen = () => {
|
||||||
const route = useRoute<RouteProp<{ params: StageThreeRouteParams }, 'params'>>();
|
const route = useRoute<RouteProp<{ params: StageThreeRouteParams }, 'params'>>();
|
||||||
const navigation = useNavigation<any>();
|
const navigation = useNavigation<any>();
|
||||||
|
const insets = useSafeAreaInsets()
|
||||||
const [company, setCompany] = useState<Company[]>([
|
const [company, setCompany] = useState<Company[]>([
|
||||||
{
|
{
|
||||||
director: '',
|
director: '',
|
||||||
@@ -71,7 +72,7 @@ const StageThreeScreen = () => {
|
|||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("first company route : ", route);
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
@@ -119,8 +120,8 @@ const StageThreeScreen = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={{ flex: 1 }}>
|
<View style={{ flex: 1 ,paddingHorizontal:10 }}>
|
||||||
<Text style={styles.heading}>Stage Three For {route.params?.orgType == '4' ? 'Public' : route.params?.orgType == '5' ? 'Private' : route.params?.orgType == '6' ? 'Limited Liability Partnership (LLP)' : route.params?.orgType} Organization</Text>
|
<Text style={[styles.heading,{marginTop:insets.top}]}>Stage Three For {route.params?.orgType == '4' ? 'Public' : route.params?.orgType == '5' ? 'Private' : route.params?.orgType == '6' ? 'Limited Liability Partnership (LLP)' : route.params?.orgType} Organization</Text>
|
||||||
<SafeAreaView style={{ flex: 1 }}>
|
<SafeAreaView style={{ flex: 1 }}>
|
||||||
<KeyboardAvoidingView
|
<KeyboardAvoidingView
|
||||||
style={{ flex: 1 }}
|
style={{ flex: 1 }}
|
||||||
@@ -225,7 +226,7 @@ const styles = StyleSheet.create({
|
|||||||
marginBottom: 10,
|
marginBottom: 10,
|
||||||
},
|
},
|
||||||
scrollContainer: {
|
scrollContainer: {
|
||||||
// backgroundColor: color.background,
|
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
},
|
},
|
||||||
addButton: {
|
addButton: {
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ const StageOne: React.FC<Props> = ({
|
|||||||
setSelectedOrg,
|
setSelectedOrg,
|
||||||
selectedOrg
|
selectedOrg
|
||||||
}) => {
|
}) => {
|
||||||
|
console.log("masterdata",allOrganizations,allMsmeOrgs,allSocialCategories,contractorClassItems,selectedOrg !== 8)
|
||||||
|
|
||||||
const [selectedAllMSME, setSelectedAllMSME] = useState()
|
const [selectedAllMSME, setSelectedAllMSME] = useState()
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
|
|||||||
@@ -49,9 +49,16 @@ const Splash: React.FC = () => {
|
|||||||
|
|
||||||
|
|
||||||
const routeByOrgType = (params: { otherId: any; orgType: any }) => {
|
const routeByOrgType = (params: { otherId: any; orgType: any }) => {
|
||||||
const orgType = String(params.orgType);
|
|
||||||
|
|
||||||
|
|
||||||
|
// const orgType = params.orgType;
|
||||||
|
const orgType = "7" as string; // For testing purpose
|
||||||
|
console.log("orgType value:", orgType);
|
||||||
|
console.log("orgType type:", typeof orgType);
|
||||||
if (orgType === '4' || orgType === '5' || orgType === '6') {
|
if (orgType === '4' || orgType === '5' || orgType === '6') {
|
||||||
navigation.replace('StageThree', params);
|
|
||||||
|
navigation.replace(NavigationString.StageThreeScreen, params);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,285 +1,285 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { View, Text, TextInput, ScrollView, TouchableOpacity, StyleSheet, ActivityIndicator, Alert, } from 'react-native';
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
ScrollView,
|
||||||
|
TouchableOpacity,
|
||||||
|
StyleSheet,
|
||||||
|
ActivityIndicator,
|
||||||
|
Alert,
|
||||||
|
} from 'react-native';
|
||||||
import RNFS from 'react-native-fs';
|
import RNFS from 'react-native-fs';
|
||||||
import * as XLSX from 'xlsx';
|
import * as XLSX from 'xlsx';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { InsideHeader } from '../../../Component/Index';
|
|
||||||
import colors from '../../../Constant/Color';
|
import colors from '../../../Constant/Color';
|
||||||
import { GET_ENVELOPE_C, SUBMIT_ENVELOPE_C_UPLOAD } from '../../../Services/BBPS/ApiUrls';
|
import { GET_ENVELOPE_C, SUBMIT_ENVELOPE_C_UPLOAD } from '../../../Services/BBPS/ApiUrls';
|
||||||
import { useNavigation } from '@react-navigation/native';
|
import { useNavigation } from '@react-navigation/native';
|
||||||
|
|
||||||
|
/* -------------------- UTILS -------------------- */
|
||||||
|
|
||||||
// Excel column keys
|
// Convert ArrayBuffer → Base64
|
||||||
const QTY_KEY = '__EMPTY_1';
|
const arrayBufferToBase64 = (buffer: ArrayBuffer) => {
|
||||||
const RATE_KEY = '__EMPTY_2';
|
let binary = '';
|
||||||
const VALUE_KEY = '__EMPTY_3';
|
const bytes = new Uint8Array(buffer);
|
||||||
const TOTAL_LABEL = 'TOTAL';
|
for (let i = 0; i < bytes.length; i++) {
|
||||||
|
binary += String.fromCharCode(bytes[i]);
|
||||||
|
}
|
||||||
|
return global.btoa(binary);
|
||||||
|
};
|
||||||
|
|
||||||
const EnvelopeCExcelPreview = (tenderData: any) => {
|
// Find column dynamically by keywords
|
||||||
const token = useSelector((state: any) => state.token.token);
|
const findColumnKey = (columns: string[], keywords: string[]) =>
|
||||||
const navigation = useNavigation() as any;
|
columns.find(col =>
|
||||||
const [data, setData] = useState<any[]>([]);
|
keywords.some(k => col.toLowerCase().includes(k.toLowerCase()))
|
||||||
const [columns, setColumns] = useState<string[]>([]);
|
);
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
console.log("kllkl",tenderData)
|
|
||||||
useEffect(() => {
|
|
||||||
loadExcelFromApi();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// ArrayBuffer → Base64
|
// Detect TOTAL row (any column contains TOTAL)
|
||||||
const arrayBufferToBase64 = (buffer: ArrayBuffer) => {
|
const isTotalRow = (row: any) =>
|
||||||
let binary = '';
|
Object.values(row).some(v => String(v).toUpperCase() === 'TOTAL');
|
||||||
const bytes = new Uint8Array(buffer);
|
|
||||||
for (let i = 0; i < bytes.length; i++) {
|
/* -------------------- COMPONENT -------------------- */
|
||||||
binary += String.fromCharCode(bytes[i]);
|
|
||||||
|
const EnvelopeCExcelPreview = (props: any) => {
|
||||||
|
const tenderData = props;
|
||||||
|
const token = useSelector((state: any) => state.token.token);
|
||||||
|
const navigation = useNavigation() as any;
|
||||||
|
|
||||||
|
const [data, setData] = useState<any[]>([]);
|
||||||
|
const [columns, setColumns] = useState<string[]>([]);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadExcelFromApi();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
/* -------------------- LOAD EXCEL -------------------- */
|
||||||
|
|
||||||
|
const loadExcelFromApi = async () => {
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
const response = await axios.get(
|
||||||
|
`${GET_ENVELOPE_C}${tenderData?.tenderId?.tenderId}`,
|
||||||
|
{
|
||||||
|
responseType: 'arraybuffer',
|
||||||
|
headers: {
|
||||||
|
Authentication: `Bearer ${token.token}`,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
return global.btoa(binary);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
// Calculate TOTAL VALUE
|
const base64 = arrayBufferToBase64(response.data);
|
||||||
const calculateTotal = (rows: any[]) =>
|
const workbook = XLSX.read(base64, { type: 'base64' });
|
||||||
rows.reduce((sum, row) => {
|
const sheet = workbook.Sheets[workbook.SheetNames[0]];
|
||||||
if (typeof row['DEMO DEPARTEMENT'] !== 'number') return sum;
|
const rows: any[] = XLSX.utils.sheet_to_json(sheet, { defval: '' });
|
||||||
const val = Number(row[VALUE_KEY]);
|
|
||||||
return sum + (isNaN(val) ? 0 : val);
|
|
||||||
}, 0);
|
|
||||||
|
|
||||||
// LOAD EXCEL
|
setColumns(Object.keys(rows[0] || {}));
|
||||||
const loadExcelFromApi = async () => {
|
setData(rows);
|
||||||
try {
|
|
||||||
setLoading(true);
|
|
||||||
|
|
||||||
const response = await axios.get(`${GET_ENVELOPE_C}${tenderData?.tenderId?.tenderId}`, {
|
} catch (e) {
|
||||||
responseType: 'arraybuffer',
|
Alert.alert('Error', 'Failed to load Excel');
|
||||||
headers: {
|
} finally {
|
||||||
Authentication: `Bearer ${token.token}`,
|
setLoading(false);
|
||||||
},
|
}
|
||||||
});
|
};
|
||||||
console.log("excel response",response)
|
|
||||||
|
|
||||||
const base64 = arrayBufferToBase64(response.data);
|
/* -------------------- UPDATE CELL -------------------- */
|
||||||
const workbook = XLSX.read(base64, { type: 'base64' });
|
|
||||||
const sheet = workbook.Sheets[workbook.SheetNames[0]];
|
|
||||||
const rows: any[] = XLSX.utils.sheet_to_json(sheet, { defval: '' });
|
|
||||||
|
|
||||||
setColumns(Object.keys(rows[0] || {}));
|
const updateCell = (rowIndex: number, key: string, value: string) => {
|
||||||
setData(rows);
|
const updated = [...data];
|
||||||
|
const row = updated[rowIndex];
|
||||||
|
|
||||||
await RNFS.writeFile(
|
if (isTotalRow(row)) return;
|
||||||
`${RNFS.DocumentDirectoryPath}/envelopeC.xlsx`,
|
|
||||||
base64,
|
|
||||||
'base64'
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
Alert.alert('Error', 'Failed to load Excel');
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// UPDATE CELL (QTY / RATE) + AUTO VALUE + AUTO TOTAL
|
const qtyKey:any = findColumnKey(columns, ['qty', 'quantity']);
|
||||||
const updateCell = (rowIndex: number, key: string, value: string) => {
|
const rateKey:any = findColumnKey(columns, ['rate', 'price']);
|
||||||
const updated = [...data];
|
const valueKey = findColumnKey(columns, ['value', 'amount', 'total']);
|
||||||
const row = updated[rowIndex];
|
|
||||||
|
|
||||||
// TOTAL row locked
|
if (key === qtyKey || key === rateKey) {
|
||||||
if (row['DEMO DEPARTEMENT'] === TOTAL_LABEL) return;
|
row[key] = value;
|
||||||
|
|
||||||
// Allow only QTY & RATE edit
|
const qty = Number(row[qtyKey]);
|
||||||
if (key === QTY_KEY || key === RATE_KEY) {
|
const rate = Number(row[rateKey]);
|
||||||
row[key] = value;
|
|
||||||
|
|
||||||
const qty = Number(row[QTY_KEY]);
|
if (valueKey) {
|
||||||
const rate = Number(row[RATE_KEY]);
|
row[valueKey] =
|
||||||
|
!isNaN(qty) && !isNaN(rate) ? qty * rate : 0;
|
||||||
// 🔥 Auto VALUE = QTY × RATE
|
}
|
||||||
row[VALUE_KEY] =
|
|
||||||
!isNaN(qty) && !isNaN(rate) ? qty * rate : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 🔥 Update TOTAL
|
|
||||||
const totalRowIndex = updated.findIndex(
|
|
||||||
r => r['DEMO DEPARTEMENT'] === TOTAL_LABEL
|
|
||||||
);
|
|
||||||
|
|
||||||
if (totalRowIndex !== -1) {
|
|
||||||
updated[totalRowIndex][VALUE_KEY] = calculateTotal(updated);
|
|
||||||
}
|
|
||||||
|
|
||||||
setData(updated);
|
|
||||||
};
|
|
||||||
|
|
||||||
// SAVE UPDATED EXCEL
|
|
||||||
const saveUpdatedExcel = async () => {
|
|
||||||
try {
|
|
||||||
setLoading(true);
|
|
||||||
|
|
||||||
const worksheet = XLSX.utils.json_to_sheet(data);
|
|
||||||
const workbook = XLSX.utils.book_new();
|
|
||||||
XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
|
|
||||||
|
|
||||||
// Generate binary string
|
|
||||||
const binary = XLSX.write(workbook, {
|
|
||||||
bookType: 'xlsx',
|
|
||||||
type: 'binary',
|
|
||||||
});
|
|
||||||
|
|
||||||
// Convert binary string to buffer
|
|
||||||
const buffer = new Uint8Array(binary.length);
|
|
||||||
for (let i = 0; i < binary.length; i++) {
|
|
||||||
buffer[i] = binary.charCodeAt(i) & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const filePath = `${RNFS.DocumentDirectoryPath}/envelopeC_updated.xlsx`;
|
|
||||||
|
|
||||||
// Write as binary
|
|
||||||
await RNFS.writeFile(filePath, buffer.toString(), 'ascii');
|
|
||||||
// const fileBinary = await RNFS.readFile(filePath, 'ascii');
|
|
||||||
|
|
||||||
// console.log('Excel binary content:', fileBinary);
|
|
||||||
// Alert.alert('Success', 'Excel saved successfully');
|
|
||||||
const formData = new FormData();
|
|
||||||
|
|
||||||
// requestDto payload
|
|
||||||
formData.append(
|
|
||||||
'requestDto',
|
|
||||||
JSON.stringify({
|
|
||||||
tenderId: tenderData?.tenderId?.tenderId,
|
|
||||||
deptId: tenderData?.tenderId?.deptId,
|
|
||||||
typesOfTender: tenderData?.tenderId?.typesOfTender,
|
|
||||||
fieldValue: '',
|
|
||||||
fieldValueInWord: 'zero',
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// binary file
|
|
||||||
formData.append('file', {
|
|
||||||
uri: `file://${filePath}`,
|
|
||||||
name: 'envelopeC_updated.xlsx',
|
|
||||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
||||||
});
|
|
||||||
|
|
||||||
const res = await axios.post(SUBMIT_ENVELOPE_C_UPLOAD, formData, {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'multipart/form-data',
|
|
||||||
Authentication: `Bearer ${token.token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
navigation.goBack();
|
|
||||||
console.log("res of updated excel file : ", res)
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
Alert.alert('Error', 'Save failed');
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (loading) {
|
|
||||||
return (
|
|
||||||
<View style={styles.loader}>
|
|
||||||
<ActivityIndicator size="large" />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recalculate TOTAL
|
||||||
|
const totalRowIndex = updated.findIndex(isTotalRow);
|
||||||
|
if (totalRowIndex !== -1 && valueKey) {
|
||||||
|
updated[totalRowIndex][valueKey] = updated.reduce((sum, r) => {
|
||||||
|
if (isTotalRow(r)) return sum;
|
||||||
|
const val = Number(r[valueKey]);
|
||||||
|
return sum + (isNaN(val) ? 0 : val);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
setData(updated);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -------------------- SAVE & UPLOAD EXCEL -------------------- */
|
||||||
|
|
||||||
|
const saveUpdatedExcel = async () => {
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
const worksheet = XLSX.utils.json_to_sheet(data);
|
||||||
|
const workbook = XLSX.utils.book_new();
|
||||||
|
XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
|
||||||
|
|
||||||
|
const binary = XLSX.write(workbook, {
|
||||||
|
bookType: 'xlsx',
|
||||||
|
type: 'binary',
|
||||||
|
});
|
||||||
|
|
||||||
|
const buffer = new Uint8Array(binary.length);
|
||||||
|
for (let i = 0; i < binary.length; i++) {
|
||||||
|
buffer[i] = binary.charCodeAt(i) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filePath = `${RNFS.DocumentDirectoryPath}/envelopeC_updated.xlsx`;
|
||||||
|
await RNFS.writeFile(filePath, buffer.toString(), 'ascii');
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append(
|
||||||
|
'requestDto',
|
||||||
|
JSON.stringify({
|
||||||
|
tenderId: tenderData?.tenderId?.tenderId,
|
||||||
|
deptId: tenderData?.tenderId?.deptId,
|
||||||
|
typesOfTender: tenderData?.tenderId?.typesOfTender,
|
||||||
|
fieldValue: '',
|
||||||
|
fieldValueInWord: 'zero',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
formData.append('file', {
|
||||||
|
uri: `file://${filePath}`,
|
||||||
|
name: 'envelopeC_updated.xlsx',
|
||||||
|
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||||
|
});
|
||||||
|
|
||||||
|
await axios.post(SUBMIT_ENVELOPE_C_UPLOAD, formData, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data',
|
||||||
|
Authentication: `Bearer ${token.token}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
navigation.goBack();
|
||||||
|
} catch (e) {
|
||||||
|
Alert.alert('Error', 'Save failed');
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -------------------- UI -------------------- */
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.loader}>
|
||||||
|
<ActivityIndicator size="large" />
|
||||||
<ScrollView horizontal contentContainerStyle={{ paddingHorizontal: 10, paddingTop: 20, backgroundColor: colors.white }}>
|
</View>
|
||||||
<View>
|
|
||||||
{/* HEADER */}
|
|
||||||
<View style={styles.row}>
|
|
||||||
{columns.map(col => (
|
|
||||||
<Text key={col} style={styles.headerCell}>
|
|
||||||
{col}
|
|
||||||
</Text>
|
|
||||||
))}
|
|
||||||
</View>
|
|
||||||
|
|
||||||
{/* DATA */}
|
|
||||||
<ScrollView style={{ maxHeight: 420 }}>
|
|
||||||
{data.map((row, rowIndex) => (
|
|
||||||
<View key={rowIndex} style={styles.row}>
|
|
||||||
{columns.map(key => {
|
|
||||||
const isTotal = row['DEMO DEPARTEMENT'] === TOTAL_LABEL;
|
|
||||||
const isEditable =
|
|
||||||
!isTotal && (key === QTY_KEY || key === RATE_KEY);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TextInput
|
|
||||||
key={key}
|
|
||||||
value={String(row[key])}
|
|
||||||
editable={isEditable}
|
|
||||||
keyboardType={
|
|
||||||
key === QTY_KEY || key === RATE_KEY
|
|
||||||
? 'numeric'
|
|
||||||
: 'default'
|
|
||||||
}
|
|
||||||
style={[
|
|
||||||
styles.cell,
|
|
||||||
isTotal && styles.totalCell,
|
|
||||||
key === VALUE_KEY && styles.valueCell,
|
|
||||||
]}
|
|
||||||
onChangeText={text =>
|
|
||||||
updateCell(rowIndex, key, text)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</View>
|
|
||||||
))}
|
|
||||||
</ScrollView>
|
|
||||||
</View>
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
{tenderData?.buttonEnable && <TouchableOpacity style={styles.button} onPress={saveUpdatedExcel}>
|
|
||||||
<Text style={styles.buttonText}>Save Updated Excel</Text>
|
|
||||||
</TouchableOpacity>}
|
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const qtyKey = findColumnKey(columns, ['qty', 'quantity']);
|
||||||
|
const rateKey = findColumnKey(columns, ['rate', 'price']);
|
||||||
|
const valueKey = findColumnKey(columns, ['value', 'amount', 'total']);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<ScrollView horizontal contentContainerStyle={{ padding: 10 }}>
|
||||||
|
<View>
|
||||||
|
{/* HEADER */}
|
||||||
|
<View style={styles.row}>
|
||||||
|
{columns.map(col => (
|
||||||
|
<Text key={col} style={styles.headerCell}>{col}</Text>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* DATA */}
|
||||||
|
<ScrollView style={{ maxHeight: 420 }}>
|
||||||
|
{data.map((row, rowIndex) => (
|
||||||
|
<View key={rowIndex} style={styles.row}>
|
||||||
|
{columns.map(key => {
|
||||||
|
const editable =
|
||||||
|
!isTotalRow(row) && (key === qtyKey || key === rateKey);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TextInput
|
||||||
|
key={key}
|
||||||
|
value={String(row[key])}
|
||||||
|
editable={editable}
|
||||||
|
keyboardType={editable ? 'numeric' : 'default'}
|
||||||
|
style={[
|
||||||
|
styles.cell,
|
||||||
|
isTotalRow(row) && styles.totalCell,
|
||||||
|
key === valueKey && styles.valueCell,
|
||||||
|
]}
|
||||||
|
onChangeText={text =>
|
||||||
|
updateCell(rowIndex, key, text)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
{tenderData?.buttonEnable && (
|
||||||
|
<TouchableOpacity style={styles.button} onPress={saveUpdatedExcel}>
|
||||||
|
<Text style={styles.buttonText}>Save Updated Excel</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default EnvelopeCExcelPreview;
|
export default EnvelopeCExcelPreview;
|
||||||
|
|
||||||
|
/* -------------------- STYLES -------------------- */
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: { flex: 1, backgroundColor: '#fff' },
|
container: { flex: 1, backgroundColor: '#fff' },
|
||||||
loader: { flex: 1, justifyContent: 'center', alignItems: 'center' },
|
loader: { flex: 1, justifyContent: 'center', alignItems: 'center' },
|
||||||
title: { fontSize: 18, fontWeight: '700', marginBottom: 10 },
|
row: { flexDirection: 'row' },
|
||||||
row: { flexDirection: 'row' },
|
headerCell: {
|
||||||
headerCell: {
|
minWidth: 140,
|
||||||
minWidth: 140,
|
padding: 10,
|
||||||
padding: 10,
|
backgroundColor: '#f1f5f9',
|
||||||
backgroundColor: '#f1f5f9',
|
borderWidth: 1,
|
||||||
borderWidth: 1,
|
fontWeight: '700',
|
||||||
fontWeight: '700',
|
},
|
||||||
},
|
cell: {
|
||||||
cell: {
|
minWidth: 140,
|
||||||
minWidth: 140,
|
padding: 10,
|
||||||
padding: 10,
|
borderWidth: 1,
|
||||||
borderWidth: 1,
|
borderColor: '#cbd5e1',
|
||||||
borderColor: '#cbd5e1',
|
},
|
||||||
},
|
valueCell: {
|
||||||
valueCell: {
|
backgroundColor: '#f8fafc',
|
||||||
backgroundColor: '#f8fafc',
|
},
|
||||||
},
|
totalCell: {
|
||||||
totalCell: {
|
backgroundColor: '#e5e7eb',
|
||||||
backgroundColor: '#e5e7eb',
|
fontWeight: '700',
|
||||||
fontWeight: '700',
|
},
|
||||||
},
|
button: {
|
||||||
button: {
|
margin: 15,
|
||||||
marginTop: 15,
|
backgroundColor: colors.primary,
|
||||||
backgroundColor: colors.primary,
|
padding: 14,
|
||||||
padding: 14,
|
borderRadius: 8,
|
||||||
borderRadius: 8,
|
},
|
||||||
},
|
buttonText: {
|
||||||
buttonText: {
|
color: '#fff',
|
||||||
color: '#fff',
|
textAlign: 'center',
|
||||||
textAlign: 'center',
|
fontWeight: '600',
|
||||||
fontWeight: '600',
|
},
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const LiveTender = () => {
|
|||||||
console.log("userdata",user)
|
console.log("userdata",user)
|
||||||
const SelectedPurchaseList = useSelector((state: any) => state.selectPurchaseTender);
|
const SelectedPurchaseList = useSelector((state: any) => state.selectPurchaseTender);
|
||||||
const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading, isRefetching, refetch }: any = useFetchLiveTender();
|
const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading, isRefetching, refetch }: any = useFetchLiveTender();
|
||||||
|
console.log("to show ",data)
|
||||||
const [showRefreshBanner, setShowRefreshBanner] = useState(false);
|
const [showRefreshBanner, setShowRefreshBanner] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -49,6 +49,8 @@ const LiveTender = () => {
|
|||||||
|
|
||||||
const renderItem = useCallback(
|
const renderItem = useCallback(
|
||||||
({ item, index }: any) => {
|
({ item, index }: any) => {
|
||||||
|
console.log("opopopopoopopopop",item.tenderNumber,item)
|
||||||
|
if(item.tenderStatus==="Cancelled") return null;
|
||||||
const isPurchase = SelectedPurchaseList.findIndex((prev: any) => prev.tenderId === item.tenderId)
|
const isPurchase = SelectedPurchaseList.findIndex((prev: any) => prev.tenderId === item.tenderId)
|
||||||
return <LiveTenderTile
|
return <LiveTenderTile
|
||||||
contractorId={user?.id}
|
contractorId={user?.id}
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ const LiveTenderDetail = () => {
|
|||||||
const tender = route?.params;
|
const tender = route?.params;
|
||||||
console.log("object---",tender)
|
console.log("object---",tender)
|
||||||
const { data } = useFetchLiveTenderById(tender?.tenderId);
|
const { data } = useFetchLiveTenderById(tender?.tenderId);
|
||||||
|
console.log("huh",data)
|
||||||
const [downloadingId, setDownloadingId] = useState<string | number | null>(null);
|
const [downloadingId, setDownloadingId] = useState<string | number | null>(null);
|
||||||
const insets = useSafeAreaInsets()
|
const insets = useSafeAreaInsets()
|
||||||
if (!data?.data?.[0]) return null;
|
if (!data?.data?.[0]) return null;
|
||||||
@@ -198,38 +199,40 @@ const LiveTenderDetail = () => {
|
|||||||
<InfoRow
|
<InfoRow
|
||||||
label="Purchase Start"
|
label="Purchase Start"
|
||||||
value={formatDateTime(
|
value={formatDateTime(
|
||||||
tenderData?.keydates?.tenderPurchaseDate?.startDateTime,
|
tender.tenderStatus === "Amended" ? tenderData?.tenderKeyDatesAmendment?.tenderPurchaseDate?.startDateTime : tenderData?.keydates?.tenderPurchaseDate?.startDateTime
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<InfoRow
|
<InfoRow
|
||||||
label="Purchase End"
|
label="Purchase End"
|
||||||
value={formatDateTime(
|
value={formatDateTime(
|
||||||
tenderData?.keydates?.tenderPurchaseDate?.endDateTime,
|
tender.tenderStatus === "Amended" ? tenderData?.tenderKeyDatesAmendment?.tenderPurchaseDate?.endDateTime : tenderData?.keydates?.tenderPurchaseDate?.endDateTime
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<InfoRow
|
<InfoRow
|
||||||
label="Bid Submission Start"
|
label="Bid Submission Start"
|
||||||
value={formatDateTime(
|
value={formatDateTime(
|
||||||
tenderData?.keydates?.bidSubmissionDate?.startDateTime,
|
tender.tenderStatus === "Amended" ? tenderData?.tenderKeyDatesAmendment?.bidSubmissionDate?.startDateTime : tenderData?.keydates?.bidSubmissionDate?.startDateTime
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<InfoRow
|
<InfoRow
|
||||||
label="Bid Submission End"
|
label="Bid Submission End"
|
||||||
value={formatDateTime(
|
value={formatDateTime(
|
||||||
tenderData?.keydates?.bidSubmissionDate?.endDateTime,
|
tender.tenderStatus === "Amended" ? tenderData?.tenderKeyDatesAmendment?.bidSubmissionDate?.endDateTime : tenderData?.keydates?.bidSubmissionDate?.endDateTime,
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<InfoRow
|
<InfoRow
|
||||||
label="Opening Envelope A"
|
label="Opening Envelope A"
|
||||||
value={formatDateTime(tenderData?.keydates?.openingEA)}
|
value={formatDateTime(
|
||||||
|
tender.tenderStatus === "Amended" ? tenderData?.tenderKeyDatesAmendment?.openingEA : tenderData?.keydates?.openingEA
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
<InfoRow
|
<InfoRow
|
||||||
label="Opening Envelope B"
|
label="Opening Envelope B"
|
||||||
value={formatDateTime(tenderData?.keydates?.openingEB)}
|
value={formatDateTime(tender.tenderStatus === "Amended" ? tenderData?.tenderKeyDatesAmendment?.openingEB : tenderData?.keydates?.openingEB)}
|
||||||
/>
|
/>
|
||||||
<InfoRow
|
<InfoRow
|
||||||
label="Opening Envelope C"
|
label="Opening Envelope C"
|
||||||
value={formatDateTime(tenderData?.keydates?.openingEC)}
|
value={formatDateTime(tender.tenderStatus === "Amended" ? tenderData?.tenderKeyDatesAmendment?.openingEC : tenderData?.keydates?.openingEC)}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</Section>
|
</Section>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const LiveTenderTile: React.FC<LiveTenderTileProps> = ({
|
|||||||
tenderNumber,
|
tenderNumber,
|
||||||
}) => {
|
}) => {
|
||||||
const navigation: any = useNavigation();
|
const navigation: any = useNavigation();
|
||||||
const purchaseEnded = !moment().isAfter(moment(purchaseEnd, 'DD-MM-YYYY HH:mm:ss'));
|
const purchaseEnded = moment().isAfter(moment(purchaseEnd, 'YYYY-MM-DD HH:mm:ss'));
|
||||||
|
|
||||||
const contractorIds = typeof data?.contractorId === 'string'
|
const contractorIds = typeof data?.contractorId === 'string'
|
||||||
? data.contractorId.split(',').map((id: any) => id.trim())
|
? data.contractorId.split(',').map((id: any) => id.trim())
|
||||||
@@ -30,7 +30,10 @@ const LiveTenderTile: React.FC<LiveTenderTileProps> = ({
|
|||||||
: [];
|
: [];
|
||||||
|
|
||||||
const purchased = contractorIds.includes(String(contractorId));
|
const purchased = contractorIds.includes(String(contractorId));
|
||||||
|
console.log("item is ",data)
|
||||||
|
if(data.tenderStatus==="Amended"){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.cardWrapper}>
|
<View style={styles.cardWrapper}>
|
||||||
@@ -77,7 +80,7 @@ const LiveTenderTile: React.FC<LiveTenderTileProps> = ({
|
|||||||
<View style={styles.infoTextGroup}>
|
<View style={styles.infoTextGroup}>
|
||||||
<Text style={styles.infoLabel}>Deadline</Text>
|
<Text style={styles.infoLabel}>Deadline</Text>
|
||||||
<Text style={[styles.infoValue, purchaseEnded && { color: '#ef4444' }]}>
|
<Text style={[styles.infoValue, purchaseEnded && { color: '#ef4444' }]}>
|
||||||
{moment(purchaseEnd, 'DD-MM-YYYY HH:mm:ss').format('DD MMM, YY')}
|
{moment(purchaseEnd, 'YYYY-MM-DD HH:mm:ss').format('DD MMM, YY')}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
@@ -108,7 +111,7 @@ const LiveTenderTile: React.FC<LiveTenderTileProps> = ({
|
|||||||
isPurchased && !purchaseEnded ? { color: colors.white } : { color: '#fff' },
|
isPurchased && !purchaseEnded ? { color: colors.white } : { color: '#fff' },
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{purchaseEnded ? 'Expired' : (purchased ? 'Purchased' : isPurchased ? 'Remove' : 'Add to Cart')}
|
{purchaseEnded ? (purchased ? 'Purchased' : 'Expired') : (purchased ? 'Purchased' : isPurchased ? 'Remove' : 'Add to Cart')}
|
||||||
</Text>
|
</Text>
|
||||||
{(!purchaseEnded && !purchased) && (
|
{(!purchaseEnded && !purchased) && (
|
||||||
<ArrowRight size={16} color={isPurchased ? colors.white : '#fff'} />
|
<ArrowRight size={16} color={isPurchased ? colors.white : '#fff'} />
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import Onboarding from "./Onboarding/Onboarding";
|
|||||||
import ProfileTab from "./Profile/ProfileTab";
|
import ProfileTab from "./Profile/ProfileTab";
|
||||||
import Partnership from "./Ragistration/PartnerShip";
|
import Partnership from "./Ragistration/PartnerShip";
|
||||||
import Registration from "./Ragistration/Ragistration";
|
import Registration from "./Ragistration/Ragistration";
|
||||||
|
import StageThreeScreen from "./Ragistration/StageThree";
|
||||||
import Signup from "./SignUp/SignUp";
|
import Signup from "./SignUp/SignUp";
|
||||||
import Splash from "./Splash/Splash";
|
import Splash from "./Splash/Splash";
|
||||||
import LiveTenderDetail from "./Tender/LiveTenderDetail";
|
import LiveTenderDetail from "./Tender/LiveTenderDetail";
|
||||||
@@ -46,6 +47,8 @@ const Screens = {
|
|||||||
ProfileTab,
|
ProfileTab,
|
||||||
ViewTenderDetail,
|
ViewTenderDetail,
|
||||||
ResetPassword,
|
ResetPassword,
|
||||||
KycWebViewScreen
|
KycWebViewScreen,
|
||||||
|
StageThreeScreen
|
||||||
|
|
||||||
}
|
}
|
||||||
export default Screens
|
export default Screens
|
||||||
@@ -26,6 +26,7 @@ type City = { id: number; name: string };
|
|||||||
|
|
||||||
export const userLogin = async (payload: { emailAdd: string, password: string }): Promise<any> => {
|
export const userLogin = async (payload: { emailAdd: string, password: string }): Promise<any> => {
|
||||||
try {
|
try {
|
||||||
|
console.log("RES",payload)
|
||||||
// const response = await axios.post(LOG_IN_URL, { ...payload, divice: "mobileApp" });
|
// const response = await axios.post(LOG_IN_URL, { ...payload, divice: "mobileApp" });
|
||||||
const response = await axios.post(TENDER_LOGIN, { ...payload, device: "mobileApp" });
|
const response = await axios.post(TENDER_LOGIN, { ...payload, device: "mobileApp" });
|
||||||
return response.data;
|
return response.data;
|
||||||
@@ -141,6 +142,7 @@ export const fetchLiveTender = async ({page, size}:{page:number, size:number}):
|
|||||||
}
|
}
|
||||||
export const fetchContractorProfile = async (): Promise<any> => {
|
export const fetchContractorProfile = async (): Promise<any> => {
|
||||||
const data = await apiCall<any>('get', `${GET_CONTRACTOR_PROFILE}`);
|
const data = await apiCall<any>('get', `${GET_CONTRACTOR_PROFILE}`);
|
||||||
|
console.log("ContractorProfile data : ", data)
|
||||||
return data.data
|
return data.data
|
||||||
}
|
}
|
||||||
export const fetchTenderById = async (tenderId: string): Promise<any> => {
|
export const fetchTenderById = async (tenderId: string): Promise<any> => {
|
||||||
@@ -191,6 +193,7 @@ export const updateUserProfile = (
|
|||||||
fullname: string
|
fullname: string
|
||||||
}
|
}
|
||||||
): Promise<any> => {
|
): Promise<any> => {
|
||||||
|
console.log("UserProfile",payload)
|
||||||
return apiCall<any>(
|
return apiCall<any>(
|
||||||
'put',
|
'put',
|
||||||
CONTRACTOR_PROFILE_UPDATE,
|
CONTRACTOR_PROFILE_UPDATE,
|
||||||
@@ -231,6 +234,7 @@ export const contractorStageThreeSubmit = (
|
|||||||
export const contractorStageTwoSubmit = (
|
export const contractorStageTwoSubmit = (
|
||||||
fileData: any
|
fileData: any
|
||||||
): Promise<any> => {
|
): Promise<any> => {
|
||||||
|
console.log("contractorStageTwoSubmit",fileData)
|
||||||
return apiCall<any>(
|
return apiCall<any>(
|
||||||
'post',
|
'post',
|
||||||
REJ_STAGE_TWO,
|
REJ_STAGE_TWO,
|
||||||
|
|||||||
Reference in New Issue
Block a user