From e5f13c81f45bd88958e381f87679b99176f558f0 Mon Sep 17 00:00:00 2001 From: Jaanu423 Date: Tue, 13 Jan 2026 16:03:47 +0530 Subject: [PATCH] app crash from fill b upload --- src/Axios/Axios.ts | 1 + src/Screens/Tender/ProceedToBidDetail.tsx | 54 ++++++++---- src/Screens/Tender/PurchaseTenderTile.tsx | 9 +- .../Tender/component/EditableExcel.tsx | 66 ++++++++++++--- .../Tender/tenderBidding/TenderBidding.tsx | 82 ++++++++++--------- src/Services/BBPS/ApiUrls.tsx | 10 ++- src/Services/BBPS/Hooks.ts | 11 ++- 7 files changed, 152 insertions(+), 81 deletions(-) diff --git a/src/Axios/Axios.ts b/src/Axios/Axios.ts index 0c18004..0716236 100644 --- a/src/Axios/Axios.ts +++ b/src/Axios/Axios.ts @@ -24,6 +24,7 @@ export const apiCall = async ( 'Content-Type': contentType || 'application/json', }, }); + return response.data; } catch (error: any) { const errorMessage = error?.response?.data?.error; diff --git a/src/Screens/Tender/ProceedToBidDetail.tsx b/src/Screens/Tender/ProceedToBidDetail.tsx index b9ec5ce..e16962f 100644 --- a/src/Screens/Tender/ProceedToBidDetail.tsx +++ b/src/Screens/Tender/ProceedToBidDetail.tsx @@ -1,24 +1,30 @@ -import { StyleSheet, Text, View, ScrollView, StatusBar, TouchableOpacity } from 'react-native' -import React from 'react' +import { StyleSheet, Text, View, ScrollView, StatusBar, TouchableOpacity, RefreshControl } from 'react-native' +import React, { useEffect } from 'react' import { InsideHeader } from '../../Component/Index' import colors from '../../Constant/Color' import { useNavigation, useRoute } from '@react-navigation/native' -import { useProceedToBid } from '../../Services/BBPS/Hooks' +import { useFetchTenderById, useProceedToBid } from '../../Services/BBPS/Hooks' const ProceedToBidDetail = () => { // Sample data based on your JSON - const route = useRoute() - const tenderData = route.params?.tender; - const {data, refetch} = useProceedToBid(tenderData?.tenderId); + const route = useRoute(); + const tenderDataId = route.params?.tender; + const { data, refetch } = useProceedToBid(tenderDataId?.tenderId); + const { data: tenderResponse , refetch:tenderRefetch}: any = useFetchTenderById(tenderDataId?.tenderId); + const tenderData = tenderResponse?.data; + const [refreshing, setRefreshing] = React.useState(false); - console.log("proceed to bid tender detail : ", tenderData) + console.log("proceed to bid tender detail : ", tenderDataId) + console.log("proceed to data detail : ", data) + console.log("tender data for updated : ", tenderData) const navigation = useNavigation() // Format date from array const handleStartBidding = () => { refetch(); if (data) { - navigation.navigate('TenderBidding', { tenderData: tenderData , bidData: data.data }); + console.log(" ppp",tenderData ,"ll",data) + navigation.navigate('TenderBidding', { tenderData: tenderData, bidData: data.data }); } } const formatDate = (dateArray: any[]) => { @@ -28,7 +34,7 @@ const ProceedToBidDetail = () => { }; // Status indicator component - const StatusIndicator = ({ status, label }) => ( + const StatusIndicator = ({ status, label }: { status: boolean; label: string }) => ( @@ -38,7 +44,7 @@ const ProceedToBidDetail = () => { ); // Envelope log card component - const EnvelopeLogCard = ({ log, title }) => ( + const EnvelopeLogCard = ({ log, title }: { log: any; title: string }) => ( {title} @@ -82,7 +88,7 @@ const ProceedToBidDetail = () => { ); // Information row component - const InfoRow = ({ label, value, isHighlighted = false }) => ( + const InfoRow = ({ label, value, isHighlighted = false }: { label: string; value: string; isHighlighted?: boolean }) => ( {label}: {value} @@ -90,7 +96,7 @@ const ProceedToBidDetail = () => { ); // Feature chip component - const FeatureChip = ({ label, enabled }) => ( + const FeatureChip = ({ label, enabled }: { label: string; enabled: boolean }) => ( {label} {enabled ? '✓' : '✗'} @@ -98,12 +104,32 @@ const ProceedToBidDetail = () => { ); + const onRefresh = async () => { + try { + setRefreshing(true); + await refetch(); + } finally { + setRefreshing(false); + } + }; + + useEffect(()=>{ + tenderRefetch() + },[tenderDataId?.tenderId]) + return ( - - + + }> {/* Tender Header Section */} diff --git a/src/Screens/Tender/PurchaseTenderTile.tsx b/src/Screens/Tender/PurchaseTenderTile.tsx index 30b79db..0971565 100644 --- a/src/Screens/Tender/PurchaseTenderTile.tsx +++ b/src/Screens/Tender/PurchaseTenderTile.tsx @@ -36,15 +36,8 @@ const PurchaseTenderTile = ({ const { data: tenderResponse, }: any = useFetchTenderById(item?.tenderId); const tender = tenderResponse?.data; - // console.log("item my : ", item) - - { - if (item?.nitNumber == 'TN/111') { - console.log("tender item : ", item?.nitNumber) - - } - } + console.log("tender for bid : ", tender) const handlePressIn = () => { scale.value = withTiming(0.97, { duration: 120 }); elevation.value = withTiming(3, { duration: 120 }); diff --git a/src/Screens/Tender/component/EditableExcel.tsx b/src/Screens/Tender/component/EditableExcel.tsx index d5b2a62..db4f684 100644 --- a/src/Screens/Tender/component/EditableExcel.tsx +++ b/src/Screens/Tender/component/EditableExcel.tsx @@ -6,7 +6,8 @@ import axios from 'axios'; import { useSelector } from 'react-redux'; import { InsideHeader } from '../../../Component/Index'; import colors from '../../../Constant/Color'; -import { SUBMIT_ENVELOPE_C } from '../../../Services/BBPS/ApiUrls'; +import { GET_ENVELOPE_C, SUBMIT_ENVELOPE_C_UPLOAD } from '../../../Services/BBPS/ApiUrls'; +import { useNavigation } from '@react-navigation/native'; // Excel column keys @@ -15,13 +16,13 @@ const RATE_KEY = '__EMPTY_2'; const VALUE_KEY = '__EMPTY_3'; const TOTAL_LABEL = 'TOTAL'; -const EnvelopeCExcelPreview = (tenderId:any) => { +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("tender id for excel : ", tenderId) useEffect(() => { loadExcelFromApi(); }, []); @@ -49,7 +50,7 @@ const EnvelopeCExcelPreview = (tenderId:any) => { try { setLoading(true); - const response = await axios.get(`${SUBMIT_ENVELOPE_C}${tenderId?.tenderId}`, { + const response = await axios.get(`${GET_ENVELOPE_C}${tenderData?.tenderId?.tenderId}`, { responseType: 'arraybuffer', headers: { Authentication: `Bearer ${token.token}`, @@ -117,25 +118,66 @@ const EnvelopeCExcelPreview = (tenderId:any) => { const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1'); - const base64 = XLSX.write(workbook, { + // Generate binary string + const binary = XLSX.write(workbook, { bookType: 'xlsx', - type: 'base64', + type: 'binary', }); - await RNFS.writeFile( - `${RNFS.DocumentDirectoryPath}/envelopeC_updated.xlsx`, - base64, - 'base64' + // 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', + }) ); - Alert.alert('Success', 'Excel saved with auto-calculation'); + // 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 ( @@ -230,7 +272,7 @@ const styles = StyleSheet.create({ }, button: { marginTop: 15, - backgroundColor: '#2563eb', + backgroundColor: colors.primary, padding: 14, borderRadius: 8, }, diff --git a/src/Screens/Tender/tenderBidding/TenderBidding.tsx b/src/Screens/Tender/tenderBidding/TenderBidding.tsx index 044f2ca..a3278d0 100644 --- a/src/Screens/Tender/tenderBidding/TenderBidding.tsx +++ b/src/Screens/Tender/tenderBidding/TenderBidding.tsx @@ -19,6 +19,8 @@ import { SUBMIT_ENVELOPE_A, SUBMIT_ENVELOPE_B, SUBMIT_ENVELOPE_FILE_A, SUBMIT_EN import { Fontisto } from '@react-native-vector-icons/fontisto'; import { apiCall } from '../../../Axios/Axios'; import EditableExcel from '../component/EditableExcel'; +import axios from 'axios'; +import { useSelector } from 'react-redux'; type EnvelopeType = 'A' | 'B' | 'C'; type EnvelopeFormState = { @@ -40,6 +42,7 @@ interface InfoRowProps { const TenderBidding = () => { const route = useRoute(); const navigation = useNavigation(); + const token = useSelector((state: any) => state.token.token); const [bidData] = useState(route.params?.tenderData || null); const tenderData: any = route.params?.bidData || null; @@ -209,7 +212,6 @@ const TenderBidding = () => { keyboardType="numeric" /> )} - this is envelope {activeEnvelope} ) : Envelop {activeEnvelope} unavailable} @@ -355,12 +357,12 @@ const TenderBidding = () => { console.log('Envelope A Payload:', payload); setLoading(true) if (envelopForm?.[activeEnvelope]?.[3]) { - handleSubmitEnvelopeFile() + handleSubmitEnvelopeFile(SUBMIT_ENVELOPE_FILE_A) return } try { - const res = await apiCall('post', SUBMIT_ENVELOPE_A, payload) + const res = await apiCall('post', SUBMIT_ENVELOPE_A, payload) as any console.log("res A envelop : ", res) ToastAndroid.show(res.message, ToastAndroid.SHORT) @@ -385,11 +387,11 @@ const TenderBidding = () => { if (envelopForm?.[activeEnvelope]?.[3]) { - handleSubmitEnvelopeFile() + handleSubmitEnvelopeFile(SUBMIT_ENVELOPE_FILE_B) return } try { - const res = await apiCall('post', SUBMIT_ENVELOPE_B, payload) + const res = await apiCall('post', SUBMIT_ENVELOPE_B, payload) as any console.log("res B envelop : ", res) ToastAndroid.show(res.message, ToastAndroid.SHORT) @@ -401,11 +403,10 @@ const TenderBidding = () => { } } - const handleSubmitEnvelopeFile = async () => { - + const handleSubmitEnvelopeFile = async (url: string) => { + console.log("url :: ", url) setLoadingUpload(true) const payload = buildEnvelopePayload(); - console.log(`Envelope file ${activeEnvelope} Payload:`, payload); try { const formData = new FormData(); @@ -414,26 +415,27 @@ const TenderBidding = () => { name: envelopForm?.[activeEnvelope]?.[3].name, type: envelopForm?.[activeEnvelope]?.[3].type, }); - formData.append('requestDto', payload) - - - console.log("reuestDto for fil doc : ", formData) - const res = await apiCall('post', activeEnvelope === 'B' ? SUBMIT_ENVELOPE_FILE_B : SUBMIT_ENVELOPE_FILE_A, payload) - console.log(`res file ${activeEnvelope} Payload:`, res) + // formData.append('requestDto', payload) + console.log("first token : ", token?.token) + formData.append('requestDto', JSON.stringify(payload)) + console.log("payload for fil doc : ", formData) + const res = await axios.post(url, formData, { + headers: { + Authentication: `Bearer ${token?.token}`, + 'Content-Type': 'multipart/form-data' + }, + }) as any; + console.log(`res file ${activeEnvelope} api response:`, res) ToastAndroid.show(res.message, ToastAndroid.SHORT) - // navigation.goBack() - } catch (error) { - console.log(`Envelope file ${activeEnvelope} error:`, error) + navigation.goBack() + } catch (error: any) { + console.log(`Envelope file ${activeEnvelope} error:`, error?.response || error.message || error); + ToastAndroid.show('Upload failed', ToastAndroid.SHORT); } finally { - setLoadingUpload(false) + setLoadingUpload(false); } } - const handleSubmitEnvelopeC = async () => { - Alert.alert('Info', 'Envelope C submission not implemented yet'); - } - - return ( @@ -473,7 +475,7 @@ const TenderBidding = () => { if (tenderData?.envelopeASubmittStatus) { setActiveEnvelope('B') } else { - Alert.alert('Info', 'First Fill Envelop A First') + Alert.alert('Info', 'Submit Envelop A First') } }} /> @@ -482,7 +484,13 @@ const TenderBidding = () => { setActiveEnvelope('C')} + onPress={() => { + if (tenderData?.envelopeBSubmittStatus) { + setActiveEnvelope('C') + } else { + Alert.alert('Info', 'Submit Envelop B First') + } + }} /> )} @@ -527,43 +535,43 @@ const TenderBidding = () => { ) : ( <> - + )} )} - {hasEnvelopes() ? ( + {hasEnvelopes() && activeEnvelope !== 'C' ? ( { if (!check) { - Alert.alert('Info', 'check first terms & condition') + Alert.alert('Info', 'check first terms & condition'); + return; } + if (activeEnvelope === 'A') { - handleSubmitEnvelopeA() - } - else if (activeEnvelope === 'B') { - handleSubmitEnvelopeB() - } - else { - handleSubmitEnvelopeC() + handleSubmitEnvelopeA(); + } else if (activeEnvelope === 'B') { + handleSubmitEnvelopeB(); } }} > - {loading ? 'Submitting...' : `Submit Bid (${activeEnvelope})`} + + {loading ? 'Submitting...' : `Submit Bid (${activeEnvelope})`} + ) : ( navigation.goBack()} - > Go Back )} + diff --git a/src/Services/BBPS/ApiUrls.tsx b/src/Services/BBPS/ApiUrls.tsx index a8f9c25..11d1d2a 100644 --- a/src/Services/BBPS/ApiUrls.tsx +++ b/src/Services/BBPS/ApiUrls.tsx @@ -69,9 +69,10 @@ const TENDER_LOGIN = `${BASE_URL}eproc/loginWithoutDecryption` const PROCEED_TO_BID = `${BASE_URL}tenderBidding/proceedToBid?tenderId=` const SUBMIT_ENVELOPE_A = `${BASE_URL}tenderBidding/getSaveEnvelopeAData` const SUBMIT_ENVELOPE_B = `${BASE_URL}tenderBidding/getSaveEnvelopeBData` -const SUBMIT_ENVELOPE_FILE_A = `${BASE_URL}tenderBidding/addDocumentsEnvelopeA?requestDto=` -const SUBMIT_ENVELOPE_FILE_B = `${BASE_URL}tenderBidding/addDocumentsEnvelopeB?requestDto=` -const SUBMIT_ENVELOPE_C = `${BASE_URL}eTendering/getEnvelopeCTemplate/tenderId?tenderId=` +const SUBMIT_ENVELOPE_FILE_A = `${BASE_URL}tenderBidding/addDocumentsEnvelopeA` +const SUBMIT_ENVELOPE_FILE_B = `https://procurelinc.in/EProcurementSB/tenderBidding/addDocumentsEnvelopeB` +const GET_ENVELOPE_C = `${BASE_URL}eTendering/getEnvelopeCTemplate/tenderId?tenderId=` +const SUBMIT_ENVELOPE_C_UPLOAD = `${BASE_URL}tenderBidding/getSaveEnvelopeCData` @@ -139,6 +140,7 @@ export { SUBMIT_ENVELOPE_B, SUBMIT_ENVELOPE_FILE_A, SUBMIT_ENVELOPE_FILE_B, - SUBMIT_ENVELOPE_C + GET_ENVELOPE_C, + SUBMIT_ENVELOPE_C_UPLOAD, }; diff --git a/src/Services/BBPS/Hooks.ts b/src/Services/BBPS/Hooks.ts index aea8494..cf2450a 100644 --- a/src/Services/BBPS/Hooks.ts +++ b/src/Services/BBPS/Hooks.ts @@ -104,13 +104,12 @@ export const useOfflineTenderPurchase = () => { }; export const useFetchTenderById = (tenderId: string) => { - return useQuery({ - queryKey: ['fetchTenderById', tenderId], - queryFn: () => fetchTenderById(tenderId) - - }); +return useQuery({ + queryKey: ['fetchTenderById', tenderId], + queryFn: () => fetchTenderById(tenderId), + enabled: !!tenderId, // prevents running with undefined id +}); } - export const useProceedToBid = (tenderId?: string) => { return useQuery({ queryKey: ['proceedToBid', tenderId],