From 080f1b57cd29d1ad35e5b3ec77a8ac6b32727374 Mon Sep 17 00:00:00 2001 From: Abin Toppo Date: Wed, 28 Jan 2026 16:08:19 +0530 Subject: [PATCH] commit --- ( | 0 String(v).toUpperCase() | 0 col.toLowerCase().includes(k.toLowerCase())) | 0 src/Axios/Axios.ts | 4 +- src/Constant/NavigationString.tsx | 3 +- src/Navigation/MainStack.jsx | 2 + src/Screens/Auction/LiveAuction.tsx | 30 +- src/Screens/Auction/LiveAuctionTile.tsx | 10 +- src/Screens/Auction/Modal/AuctionDetail.tsx | 31 +- src/Screens/Auction/PurchaseAuction.tsx | 3 +- src/Screens/Auction/PurchaseAuctionList.tsx | 4 +- src/Screens/Auction/PurchaseAuctionTile.tsx | 8 +- src/Screens/Auction/PurchaseList.tsx | 1 + src/Screens/Auction/types/types.tsx | 1 + src/Screens/Profile/ProfileTab.tsx | 3 +- src/Screens/Ragistration/StageThree.tsx | 11 +- .../ragistrationStages/StageOne.tsx | 1 + src/Screens/Splash/Splash.tsx | 11 +- .../Component/EnvelopeCExcelPreview.tsx | 504 +++++++++--------- src/Screens/Tender/LiveTender.tsx | 4 +- src/Screens/Tender/LiveTenderDetail.tsx | 17 +- src/Screens/Tender/LiveTenderTile.tsx | 11 +- src/Screens/index.ts | 5 +- src/Services/BBPS/apis.ts | 4 + state.token.token) | 0 25 files changed, 354 insertions(+), 314 deletions(-) create mode 100644 ( create mode 100644 String(v).toUpperCase() create mode 100644 col.toLowerCase().includes(k.toLowerCase())) create mode 100644 state.token.token) diff --git a/( b/( new file mode 100644 index 0000000..e69de29 diff --git a/String(v).toUpperCase() b/String(v).toUpperCase() new file mode 100644 index 0000000..e69de29 diff --git a/col.toLowerCase().includes(k.toLowerCase())) b/col.toLowerCase().includes(k.toLowerCase())) new file mode 100644 index 0000000..e69de29 diff --git a/src/Axios/Axios.ts b/src/Axios/Axios.ts index 9956946..0dc18bd 100644 --- a/src/Axios/Axios.ts +++ b/src/Axios/Axios.ts @@ -11,7 +11,7 @@ export const apiCall = async ( ): Promise => { try { const token: any = store.getState().token.token; - +console.log("api payload", data) const response = await axios({ method, url, @@ -22,7 +22,7 @@ export const apiCall = async ( 'Content-Type': contentType || 'application/json', }, }); - +console.log("api response",response) return response.data; } catch (error: any) { const errorMessage = error?.response?.data?.error; diff --git a/src/Constant/NavigationString.tsx b/src/Constant/NavigationString.tsx index 869fef8..ce1f201 100644 --- a/src/Constant/NavigationString.tsx +++ b/src/Constant/NavigationString.tsx @@ -23,6 +23,7 @@ const NavigationString = { Profile:'Profile', ViewTenderDetail:'ViewTenderDetail', ResetPassword:'ResetPassword', - KycWebViewScreen:'KycWebViewScreen' + KycWebViewScreen:'KycWebViewScreen', + StageThreeScreen:'StageThree' } export default NavigationString \ No newline at end of file diff --git a/src/Navigation/MainStack.jsx b/src/Navigation/MainStack.jsx index d52706e..52d99a2 100644 --- a/src/Navigation/MainStack.jsx +++ b/src/Navigation/MainStack.jsx @@ -48,6 +48,8 @@ export default function MainStack() { + + ); } diff --git a/src/Screens/Auction/LiveAuction.tsx b/src/Screens/Auction/LiveAuction.tsx index 28c900b..4c15bbe 100644 --- a/src/Screens/Auction/LiveAuction.tsx +++ b/src/Screens/Auction/LiveAuction.tsx @@ -15,37 +15,24 @@ import Skeleton from '../../Component/Skelton/Skelton'; const LiveAuction = () => { const Dispatch = useDispatch() + const user = useSelector((state: any) => state.token?.token); const onEndReachedCalledDuringMomentum = useRef(true); const SelectedPurchaseList = useSelector((state: any) => state.selectPurchaseAuction); const [showRefreshBanner, setShowRefreshBanner] = useState(false); const [allBoolean, setAllBoolean] = useState({ liveAuctionData: [], isLoading: false }) const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading, isRefetching, refetch, isPending }: any = useFetchLiveAuction(); - + console.log("object----",data,) // My Methods - const getMyAuction = async () => { - try { - setAllBoolean(prev => ({ ...prev, isLoading: true })) - const res = await apiCall('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( ({ item, index }: any) => { + console.log("item core ",item) const isPurchase = SelectedPurchaseList.findIndex((prev: any) => prev.auctionNumber === item.auctionNumber) return { } }, [isRefetching]); - useEffect(() => { - if (data?.result?.length > 0) { - getMyAuction() - } - }, [data]) if (isLoading) { return ; @@ -141,9 +123,9 @@ const LiveAuction = () => { )} { - isPending || allBoolean.isLoading ? : + isPending ? : = ({ purchaseEnd, auctionFees, auctionNumber, + isPurchasedByContractor }) => { + console.log("1",data) const [showDetail, setShowDetail] = React.useState(false); const purchaseEnded = moment().isAfter(moment(purchaseEnd, 'DD-MM-YYYY HH:mm:ss')); @@ -80,12 +82,12 @@ const LiveAuctionTile: React.FC = ({ styles.mainButton, purchaseEnded ? styles.btnDisabled - : !data.active ? { backgroundColor: 'lightgray' } : isPurchased + : isPurchasedByContractor ? { backgroundColor: 'lightgray' } : isPurchased ? styles.btnPurchased : styles.btnActive, ]} onPress={onPurchasePress} - disabled={purchaseEnded ? true : data.active ? false : true} + disabled={purchaseEnded ? true : !isPurchasedByContractor ? false : true} > = ({ 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'} - {!purchaseEnded && ( + {!purchaseEnded && !isPurchasedByContractor && ( )} diff --git a/src/Screens/Auction/Modal/AuctionDetail.tsx b/src/Screens/Auction/Modal/AuctionDetail.tsx index 2b10fbe..1156011 100644 --- a/src/Screens/Auction/Modal/AuctionDetail.tsx +++ b/src/Screens/Auction/Modal/AuctionDetail.tsx @@ -20,6 +20,7 @@ const AuctionFullDetail: React.FC = ({ visible, onClose, data }) => { const [allBoolean, setAllBoolean] = useState({ showItemDetail: false, selectedItem: {}, fileLoading: false }); const { data: auctionDocuments } = useGetAucitonDocument({ auctionId: data?.auctionId }) const { mutate } = useAuctionItem() + console.log("jkjkjk",auctionData) const formatDate = (date?: string) => { if (!date) return '-'; @@ -156,18 +157,42 @@ const AuctionFullDetail: React.FC = ({ visible, onClose, data }) => { Auction Purchase (Start) - {formatDate(data?.auctionDispatchDate)} + {formatDate( + auctionData?.auctionStatus === "Amended" ? auctionData?.amendedkeyDates.auctionPurchase.startDateTime : auctionData?.keyDates.auctionPurchase.startDateTime)} - Purchase Deadline (End) - {formatDate(data?.keyDates?.auctionPurchase?.startDateTime)} + Purchase Purchase (End) + {formatDate( + auctionData?.auctionStatus === "Amended" ? auctionData?.amendedkeyDates.auctionPurchase.endDateTime : auctionData?.keyDates.auctionPurchase.endDateTime)} + + + + + + + Bidding Start (Start) + {formatDate( + auctionData?.auctionStatus === "Amended" ? auctionData?.amendedkeyDates.auctionBidding.startDateTime : auctionData?.keyDates.auctionBidding.startDateTime)} + + + + + + + + Bidding Deadline (End) + {formatDate( + auctionData?.auctionStatus === "Amended" ? auctionData?.amendedkeyDates.auctionBidding.endDateTime : auctionData?.keyDates.auctionBidding.endDateTime)} + + + {/* 4. Item Table Section */} diff --git a/src/Screens/Auction/PurchaseAuction.tsx b/src/Screens/Auction/PurchaseAuction.tsx index 3e346c7..576d2d2 100644 --- a/src/Screens/Auction/PurchaseAuction.tsx +++ b/src/Screens/Auction/PurchaseAuction.tsx @@ -35,8 +35,9 @@ const PurchaseAuction = () => { } function isAuctionEnd(item: any): boolean { + console.log("item wih power ",item) 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; diff --git a/src/Screens/Auction/PurchaseAuctionList.tsx b/src/Screens/Auction/PurchaseAuctionList.tsx index 8b678e6..390acec 100644 --- a/src/Screens/Auction/PurchaseAuctionList.tsx +++ b/src/Screens/Auction/PurchaseAuctionList.tsx @@ -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 { InsideHeader, Loader } from '../../Component/Index'; import colors from '../../Constant/Color'; @@ -79,7 +79,7 @@ const PurchaseAuctionList = () => { } }, onError: (error) => { - console.log(error, "================purchse Error"); + // console.log(error, "================purchse Error"); } }) diff --git a/src/Screens/Auction/PurchaseAuctionTile.tsx b/src/Screens/Auction/PurchaseAuctionTile.tsx index 578cb5b..c49fdb5 100644 --- a/src/Screens/Auction/PurchaseAuctionTile.tsx +++ b/src/Screens/Auction/PurchaseAuctionTile.tsx @@ -10,7 +10,7 @@ const PurchaseAuctionTile = ({ item, onPressDetails, onStartBidding, buttonEnabl const [showDetail, setShowDetail] = React.useState(false); const scale = useSharedValue(1); const elevation = useSharedValue(8); - + console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", item); const animatedStyle = useAnimatedStyle(() => { return { transform: [{ scale: scale.value }], @@ -73,14 +73,14 @@ const PurchaseAuctionTile = ({ item, onPressDetails, onStartBidding, buttonEnabl Bidding Start: {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' ).format('DD MMM YYYY, hh:mm A')} Bidding Ends: {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' ).format('DD MMM YYYY, hh:mm A')} @@ -92,7 +92,7 @@ const PurchaseAuctionTile = ({ item, onPressDetails, onStartBidding, buttonEnabl Remaining Time {buttonEnable && !isAuctionEnd ? ( ) : ( --:--:-- diff --git a/src/Screens/Auction/PurchaseList.tsx b/src/Screens/Auction/PurchaseList.tsx index 32b6498..32f6cc3 100644 --- a/src/Screens/Auction/PurchaseList.tsx +++ b/src/Screens/Auction/PurchaseList.tsx @@ -38,6 +38,7 @@ useEffect(() => { {/* Cards */} {SelectedPurchaseList.map((item: any, index: any) => { + console.log("item nn", item); const expanded = expandedIndex === index; return ( = ({ } try { - await updateProfileMutation.mutateAsync(formData); + const result = await updateProfileMutation.mutateAsync(formData); + console.log("UserProfile ",result) Alert.alert('Success', 'Profile updated successfully'); onSuccess(); onClose(); diff --git a/src/Screens/Ragistration/StageThree.tsx b/src/Screens/Ragistration/StageThree.tsx index 0dcef32..a9b1737 100644 --- a/src/Screens/Ragistration/StageThree.tsx +++ b/src/Screens/Ragistration/StageThree.tsx @@ -19,6 +19,7 @@ import MyInput from '../../Component/MyInput'; import { showToast } from '../../Constant/ShowDailog'; import { STAGETHREE } from '../../Services/BBPS/ApiUrls'; import { useContractorStageThreeSubmit } from '../../Services/BBPS/Hooks'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; type Company = { @@ -37,7 +38,7 @@ type StageThreeRouteParams = { const StageThreeScreen = () => { const route = useRoute>(); const navigation = useNavigation(); - + const insets = useSafeAreaInsets() const [company, setCompany] = useState([ { director: '', @@ -71,7 +72,7 @@ const StageThreeScreen = () => { ]); }; - console.log("first company route : ", route); + const handleSubmit = async () => { setLoading(true); try { @@ -119,8 +120,8 @@ const StageThreeScreen = () => { }; return ( - - 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 + + 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 = ({ setSelectedOrg, selectedOrg }) => { + console.log("masterdata",allOrganizations,allMsmeOrgs,allSocialCategories,contractorClassItems,selectedOrg !== 8) const [selectedAllMSME, setSelectedAllMSME] = useState() const [open, setOpen] = useState(false) diff --git a/src/Screens/Splash/Splash.tsx b/src/Screens/Splash/Splash.tsx index 372d556..c912403 100644 --- a/src/Screens/Splash/Splash.tsx +++ b/src/Screens/Splash/Splash.tsx @@ -49,9 +49,16 @@ const Splash: React.FC = () => { 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') { - navigation.replace('StageThree', params); + + navigation.replace(NavigationString.StageThreeScreen, params); return; } diff --git a/src/Screens/Tender/Component/EnvelopeCExcelPreview.tsx b/src/Screens/Tender/Component/EnvelopeCExcelPreview.tsx index f108a52..aafcb91 100644 --- a/src/Screens/Tender/Component/EnvelopeCExcelPreview.tsx +++ b/src/Screens/Tender/Component/EnvelopeCExcelPreview.tsx @@ -1,285 +1,285 @@ 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 * as XLSX from 'xlsx'; import axios from 'axios'; import { useSelector } from 'react-redux'; -import { InsideHeader } from '../../../Component/Index'; import colors from '../../../Constant/Color'; import { GET_ENVELOPE_C, SUBMIT_ENVELOPE_C_UPLOAD } from '../../../Services/BBPS/ApiUrls'; import { useNavigation } from '@react-navigation/native'; +/* -------------------- UTILS -------------------- */ -// Excel column keys -const QTY_KEY = '__EMPTY_1'; -const RATE_KEY = '__EMPTY_2'; -const VALUE_KEY = '__EMPTY_3'; -const TOTAL_LABEL = 'TOTAL'; +// Convert ArrayBuffer → Base64 +const arrayBufferToBase64 = (buffer: ArrayBuffer) => { + let binary = ''; + const bytes = new Uint8Array(buffer); + for (let i = 0; i < bytes.length; i++) { + binary += String.fromCharCode(bytes[i]); + } + return global.btoa(binary); +}; -const EnvelopeCExcelPreview = (tenderData: any) => { - const token = useSelector((state: any) => state.token.token); - const navigation = useNavigation() as any; - const [data, setData] = useState([]); - const [columns, setColumns] = useState([]); - const [loading, setLoading] = useState(false); -console.log("kllkl",tenderData) - useEffect(() => { - loadExcelFromApi(); - }, []); +// Find column dynamically by keywords +const findColumnKey = (columns: string[], keywords: string[]) => + columns.find(col => + keywords.some(k => col.toLowerCase().includes(k.toLowerCase())) + ); - // ArrayBuffer → Base64 - const arrayBufferToBase64 = (buffer: ArrayBuffer) => { - let binary = ''; - const bytes = new Uint8Array(buffer); - for (let i = 0; i < bytes.length; i++) { - binary += String.fromCharCode(bytes[i]); +// Detect TOTAL row (any column contains TOTAL) +const isTotalRow = (row: any) => + Object.values(row).some(v => String(v).toUpperCase() === 'TOTAL'); + +/* -------------------- COMPONENT -------------------- */ + +const EnvelopeCExcelPreview = (props: any) => { + const tenderData = props; + const token = useSelector((state: any) => state.token.token); + const navigation = useNavigation() as any; + + const [data, setData] = useState([]); + const [columns, setColumns] = useState([]); + 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 calculateTotal = (rows: any[]) => - rows.reduce((sum, row) => { - if (typeof row['DEMO DEPARTEMENT'] !== 'number') return sum; - const val = Number(row[VALUE_KEY]); - return sum + (isNaN(val) ? 0 : val); - }, 0); + const base64 = arrayBufferToBase64(response.data); + const workbook = XLSX.read(base64, { type: 'base64' }); + const sheet = workbook.Sheets[workbook.SheetNames[0]]; + const rows: any[] = XLSX.utils.sheet_to_json(sheet, { defval: '' }); - // LOAD EXCEL - const loadExcelFromApi = async () => { - try { - setLoading(true); + setColumns(Object.keys(rows[0] || {})); + setData(rows); - const response = await axios.get(`${GET_ENVELOPE_C}${tenderData?.tenderId?.tenderId}`, { - responseType: 'arraybuffer', - headers: { - Authentication: `Bearer ${token.token}`, - }, - }); - console.log("excel response",response) + } catch (e) { + Alert.alert('Error', 'Failed to load Excel'); + } finally { + setLoading(false); + } + }; - const base64 = arrayBufferToBase64(response.data); - const workbook = XLSX.read(base64, { type: 'base64' }); - const sheet = workbook.Sheets[workbook.SheetNames[0]]; - const rows: any[] = XLSX.utils.sheet_to_json(sheet, { defval: '' }); + /* -------------------- UPDATE CELL -------------------- */ - setColumns(Object.keys(rows[0] || {})); - setData(rows); + const updateCell = (rowIndex: number, key: string, value: string) => { + const updated = [...data]; + const row = updated[rowIndex]; - await RNFS.writeFile( - `${RNFS.DocumentDirectoryPath}/envelopeC.xlsx`, - base64, - 'base64' - ); - } catch (e) { - Alert.alert('Error', 'Failed to load Excel'); - } finally { - setLoading(false); - } - }; + if (isTotalRow(row)) return; - // UPDATE CELL (QTY / RATE) + AUTO VALUE + AUTO TOTAL - const updateCell = (rowIndex: number, key: string, value: string) => { - const updated = [...data]; - const row = updated[rowIndex]; + const qtyKey:any = findColumnKey(columns, ['qty', 'quantity']); + const rateKey:any = findColumnKey(columns, ['rate', 'price']); + const valueKey = findColumnKey(columns, ['value', 'amount', 'total']); - // TOTAL row locked - if (row['DEMO DEPARTEMENT'] === TOTAL_LABEL) return; + if (key === qtyKey || key === rateKey) { + row[key] = value; - // Allow only QTY & RATE edit - if (key === QTY_KEY || key === RATE_KEY) { - row[key] = value; + const qty = Number(row[qtyKey]); + const rate = Number(row[rateKey]); - const qty = Number(row[QTY_KEY]); - const rate = Number(row[RATE_KEY]); - - // 🔥 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 ( - - - - ); + if (valueKey) { + row[valueKey] = + !isNaN(qty) && !isNaN(rate) ? qty * rate : 0; + } } + // 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 ( - - - - - {/* HEADER */} - - {columns.map(col => ( - - {col} - - ))} - - - {/* DATA */} - - {data.map((row, rowIndex) => ( - - {columns.map(key => { - const isTotal = row['DEMO DEPARTEMENT'] === TOTAL_LABEL; - const isEditable = - !isTotal && (key === QTY_KEY || key === RATE_KEY); - - return ( - - updateCell(rowIndex, key, text) - } - /> - ); - })} - - ))} - - - - - {tenderData?.buttonEnable && - Save Updated Excel - } - + + + ); + } + + const qtyKey = findColumnKey(columns, ['qty', 'quantity']); + const rateKey = findColumnKey(columns, ['rate', 'price']); + const valueKey = findColumnKey(columns, ['value', 'amount', 'total']); + + return ( + + + + {/* HEADER */} + + {columns.map(col => ( + {col} + ))} + + + {/* DATA */} + + {data.map((row, rowIndex) => ( + + {columns.map(key => { + const editable = + !isTotalRow(row) && (key === qtyKey || key === rateKey); + + return ( + + updateCell(rowIndex, key, text) + } + /> + ); + })} + + ))} + + + + + {tenderData?.buttonEnable && ( + + Save Updated Excel + + )} + + ); }; export default EnvelopeCExcelPreview; +/* -------------------- STYLES -------------------- */ + const styles = StyleSheet.create({ - container: { flex: 1, backgroundColor: '#fff' }, - loader: { flex: 1, justifyContent: 'center', alignItems: 'center' }, - title: { fontSize: 18, fontWeight: '700', marginBottom: 10 }, - row: { flexDirection: 'row' }, - headerCell: { - minWidth: 140, - padding: 10, - backgroundColor: '#f1f5f9', - borderWidth: 1, - fontWeight: '700', - }, - cell: { - minWidth: 140, - padding: 10, - borderWidth: 1, - borderColor: '#cbd5e1', - }, - valueCell: { - backgroundColor: '#f8fafc', - }, - totalCell: { - backgroundColor: '#e5e7eb', - fontWeight: '700', - }, - button: { - marginTop: 15, - backgroundColor: colors.primary, - padding: 14, - borderRadius: 8, - }, - buttonText: { - color: '#fff', - textAlign: 'center', - fontWeight: '600', - }, + container: { flex: 1, backgroundColor: '#fff' }, + loader: { flex: 1, justifyContent: 'center', alignItems: 'center' }, + row: { flexDirection: 'row' }, + headerCell: { + minWidth: 140, + padding: 10, + backgroundColor: '#f1f5f9', + borderWidth: 1, + fontWeight: '700', + }, + cell: { + minWidth: 140, + padding: 10, + borderWidth: 1, + borderColor: '#cbd5e1', + }, + valueCell: { + backgroundColor: '#f8fafc', + }, + totalCell: { + backgroundColor: '#e5e7eb', + fontWeight: '700', + }, + button: { + margin: 15, + backgroundColor: colors.primary, + padding: 14, + borderRadius: 8, + }, + buttonText: { + color: '#fff', + textAlign: 'center', + fontWeight: '600', + }, }); diff --git a/src/Screens/Tender/LiveTender.tsx b/src/Screens/Tender/LiveTender.tsx index 01a0268..0c56324 100644 --- a/src/Screens/Tender/LiveTender.tsx +++ b/src/Screens/Tender/LiveTender.tsx @@ -17,7 +17,7 @@ const LiveTender = () => { console.log("userdata",user) const SelectedPurchaseList = useSelector((state: any) => state.selectPurchaseTender); const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading, isRefetching, refetch }: any = useFetchLiveTender(); - + console.log("to show ",data) const [showRefreshBanner, setShowRefreshBanner] = useState(false); useEffect(() => { @@ -49,6 +49,8 @@ const LiveTender = () => { const renderItem = useCallback( ({ 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) return { const tender = route?.params; console.log("object---",tender) const { data } = useFetchLiveTenderById(tender?.tenderId); + console.log("huh",data) const [downloadingId, setDownloadingId] = useState(null); const insets = useSafeAreaInsets() if (!data?.data?.[0]) return null; @@ -198,38 +199,40 @@ const LiveTenderDetail = () => { diff --git a/src/Screens/Tender/LiveTenderTile.tsx b/src/Screens/Tender/LiveTenderTile.tsx index 453096d..a0de2d3 100644 --- a/src/Screens/Tender/LiveTenderTile.tsx +++ b/src/Screens/Tender/LiveTenderTile.tsx @@ -21,7 +21,7 @@ const LiveTenderTile: React.FC = ({ tenderNumber, }) => { 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' ? data.contractorId.split(',').map((id: any) => id.trim()) @@ -30,7 +30,10 @@ const LiveTenderTile: React.FC = ({ : []; const purchased = contractorIds.includes(String(contractorId)); - + console.log("item is ",data) +if(data.tenderStatus==="Amended"){ + +} return ( @@ -77,7 +80,7 @@ const LiveTenderTile: React.FC = ({ Deadline - {moment(purchaseEnd, 'DD-MM-YYYY HH:mm:ss').format('DD MMM, YY')} + {moment(purchaseEnd, 'YYYY-MM-DD HH:mm:ss').format('DD MMM, YY')} @@ -108,7 +111,7 @@ const LiveTenderTile: React.FC = ({ 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')} {(!purchaseEnded && !purchased) && ( diff --git a/src/Screens/index.ts b/src/Screens/index.ts index f09537b..acdb077 100644 --- a/src/Screens/index.ts +++ b/src/Screens/index.ts @@ -12,6 +12,7 @@ import Onboarding from "./Onboarding/Onboarding"; import ProfileTab from "./Profile/ProfileTab"; import Partnership from "./Ragistration/PartnerShip"; import Registration from "./Ragistration/Ragistration"; +import StageThreeScreen from "./Ragistration/StageThree"; import Signup from "./SignUp/SignUp"; import Splash from "./Splash/Splash"; import LiveTenderDetail from "./Tender/LiveTenderDetail"; @@ -46,6 +47,8 @@ const Screens = { ProfileTab, ViewTenderDetail, ResetPassword, - KycWebViewScreen + KycWebViewScreen, + StageThreeScreen + } export default Screens \ No newline at end of file diff --git a/src/Services/BBPS/apis.ts b/src/Services/BBPS/apis.ts index ef13f88..98dc496 100644 --- a/src/Services/BBPS/apis.ts +++ b/src/Services/BBPS/apis.ts @@ -26,6 +26,7 @@ type City = { id: number; name: string }; export const userLogin = async (payload: { emailAdd: string, password: string }): Promise => { try { + console.log("RES",payload) // const response = await axios.post(LOG_IN_URL, { ...payload, divice: "mobileApp" }); const response = await axios.post(TENDER_LOGIN, { ...payload, device: "mobileApp" }); return response.data; @@ -141,6 +142,7 @@ export const fetchLiveTender = async ({page, size}:{page:number, size:number}): } export const fetchContractorProfile = async (): Promise => { const data = await apiCall('get', `${GET_CONTRACTOR_PROFILE}`); + console.log("ContractorProfile data : ", data) return data.data } export const fetchTenderById = async (tenderId: string): Promise => { @@ -191,6 +193,7 @@ export const updateUserProfile = ( fullname: string } ): Promise => { + console.log("UserProfile",payload) return apiCall( 'put', CONTRACTOR_PROFILE_UPDATE, @@ -231,6 +234,7 @@ export const contractorStageThreeSubmit = ( export const contractorStageTwoSubmit = ( fileData: any ): Promise => { + console.log("contractorStageTwoSubmit",fileData) return apiCall( 'post', REJ_STAGE_TWO, diff --git a/state.token.token) b/state.token.token) new file mode 100644 index 0000000..e69de29