diff --git a/package-lock.json b/package-lock.json index 09f6b38..549c581 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@react-native-community/blur": "^4.4.1", "@react-native-documents/picker": "^11.0.3", "@react-native-masked-view/masked-view": "^0.3.2", + "@react-native-vector-icons/material-icons": "^12.4.0", "@react-navigation/bottom-tabs": "^7.9.0", "@react-navigation/native": "^7.1.26", "@react-navigation/stack": "^7.6.13", @@ -2884,6 +2885,132 @@ "react-native": ">=0.57" } }, + "node_modules/@react-native-vector-icons/common": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/@react-native-vector-icons/common/-/common-12.4.0.tgz", + "integrity": "sha512-t9W0q+AW7WH1Oj5aEg7wGNXDLZJb5sIVkAWo5qtad3PcbBADqoCdikRK/ToLK+xlB0TxjcuL0T74ogudMkYGeA==", + "license": "MIT", + "dependencies": { + "find-up": "^7.0.0", + "picocolors": "^1.1.1", + "plist": "^3.1.0" + }, + "bin": { + "rnvi-update-plist": "lib/commonjs/scripts/updatePlist.js" + }, + "engines": { + "node": ">=20.19.0 <21.0.0 || >=22.0.0" + }, + "peerDependencies": { + "@react-native-vector-icons/get-image": "^12.3.0", + "react": "*", + "react-native": "*" + }, + "peerDependenciesMeta": { + "@react-native-vector-icons/get-image": { + "optional": true + } + } + }, + "node_modules/@react-native-vector-icons/common/node_modules/find-up": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", + "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", + "license": "MIT", + "dependencies": { + "locate-path": "^7.2.0", + "path-exists": "^5.0.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@react-native-vector-icons/common/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@react-native-vector-icons/common/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@react-native-vector-icons/common/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@react-native-vector-icons/common/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/@react-native-vector-icons/common/node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@react-native-vector-icons/material-icons": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/@react-native-vector-icons/material-icons/-/material-icons-12.4.0.tgz", + "integrity": "sha512-R0C2BBoZZ5sjZJYLbFx1vfyYwfbOcBHRYzRHDKUlsCdplc34HLa0JyHYGMGx3q5xHAJB6Dl4N2cmZUVALuJ60w==", + "license": "MIT", + "dependencies": { + "@react-native-vector-icons/common": "^12.4.0" + }, + "engines": { + "node": ">= 18.0.0" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/@react-native/assets-registry": { "version": "0.79.0", "license": "MIT", @@ -4035,6 +4162,15 @@ "devOptional": true, "license": "MIT" }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.11", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz", + "integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/abort-controller": { "version": "3.0.0", "license": "MIT", @@ -10499,6 +10635,20 @@ "node": ">=8" } }, + "node_modules/plist": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", + "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "license": "MIT", @@ -12827,6 +12977,18 @@ "node": ">=4" } }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/universalify": { "version": "0.1.2", "devOptional": true, @@ -13220,6 +13382,15 @@ "node": ">=0.8" } }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "license": "MIT", + "engines": { + "node": ">=8.0" + } + }, "node_modules/xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", diff --git a/package.json b/package.json index 6cea752..152ba6e 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@react-native-community/blur": "^4.4.1", "@react-native-documents/picker": "^11.0.3", "@react-native-masked-view/masked-view": "^0.3.2", + "@react-native-vector-icons/material-icons": "^12.4.0", "@react-navigation/bottom-tabs": "^7.9.0", "@react-navigation/native": "^7.1.26", "@react-navigation/stack": "^7.6.13", diff --git a/src/Constant/Color.tsx b/src/Constant/Color.tsx index a936d45..4f3aa74 100644 --- a/src/Constant/Color.tsx +++ b/src/Constant/Color.tsx @@ -25,6 +25,7 @@ const colors = { border: '#E5E7EB', lightGray: '#F9FAFB', disabled: '#D1D5DB', + gray:'#b9babb', // Additional placeholder: '#9CA3AF', diff --git a/src/Constant/NavigationString.tsx b/src/Constant/NavigationString.tsx index bba18f9..6119437 100644 --- a/src/Constant/NavigationString.tsx +++ b/src/Constant/NavigationString.tsx @@ -21,6 +21,7 @@ const NavigationString = { LiveTenderDetail:'LiveTenderDetail', AuctionDetail: 'AuctionDetail', Profile:'Profile', + ViewTenderDetail:'ViewTenderDetail', KycWebViewScreen:'KycWebViewScreen' } export default NavigationString \ No newline at end of file diff --git a/src/Navigation/MainStack.jsx b/src/Navigation/MainStack.jsx index e88766b..4c171e5 100644 --- a/src/Navigation/MainStack.jsx +++ b/src/Navigation/MainStack.jsx @@ -8,7 +8,7 @@ import BottomTab from './Bottom'; export default function MainStack() { const Stack = createStackNavigator(); const option = { headerShown: false }; - const fadeTransition = { + const fadeTransition = { gestureDirection: 'horizontal', transitionSpec: { open: { animation: 'timing', config: { duration: 300 } }, @@ -46,7 +46,7 @@ export default function MainStack() { - + ); } diff --git a/src/Screens/Tender/LiveTender.tsx b/src/Screens/Tender/LiveTender.tsx index 2c0d946..01a0268 100644 --- a/src/Screens/Tender/LiveTender.tsx +++ b/src/Screens/Tender/LiveTender.tsx @@ -116,7 +116,7 @@ const LiveTender = () => { String(item.auctionId)} + keyExtractor={(item) => String(item.tenderId)} renderItem={renderItem} showsVerticalScrollIndicator={false} contentContainerStyle={{ paddingBottom: 50, paddingTop: 10 }} diff --git a/src/Screens/Tender/ProceedToBidDetail.tsx b/src/Screens/Tender/ProceedToBidDetail.tsx index 65e26ce..5944612 100644 --- a/src/Screens/Tender/ProceedToBidDetail.tsx +++ b/src/Screens/Tender/ProceedToBidDetail.tsx @@ -1,4 +1,4 @@ -import { StyleSheet, Text, View, ScrollView, StatusBar, TouchableOpacity, RefreshControl, ActivityIndicator } from 'react-native' +import { StyleSheet, Text, View, ScrollView, StatusBar, TouchableOpacity, RefreshControl, ActivityIndicator, Platform } from 'react-native' import React, { useCallback, useEffect } from 'react' import { InsideHeader } from '../../Component/Index' import colors from '../../Constant/Color' @@ -9,7 +9,7 @@ const ProceedToBidDetail = () => { // Sample data based on your JSON const route = useRoute(); const tenderDataId = route.params?.tender; - const { data, refetch,isRefetching } = useProceedToBid(tenderDataId?.tenderId); + const { data, refetch, isRefetching } = useProceedToBid(tenderDataId?.tenderId); const { data: tenderResponse, refetch: tenderRefetch }: any = useFetchTenderById(tenderDataId?.tenderId); const tenderData = tenderResponse?.data; const [refreshing, setRefreshing] = React.useState(false); @@ -22,11 +22,11 @@ const ProceedToBidDetail = () => { // Format date from array const handleStartBidding = () => { - setLoading(true); + setLoading(true); try { setLoading(true); - - navigation.navigate('TenderBidding', { tenderId:tenderDataId.tenderId}); + + navigation.navigate('TenderBidding', { tenderId: tenderDataId.tenderId }); } catch (error) { console.log("Error in starting bidding: ", error); @@ -183,9 +183,9 @@ const ProceedToBidDetail = () => { {tenderData?.envelopeA_Logs && ( Submission Logs - {tenderData?.envelopeA_Logs&& } - { tenderData?.envelopeB_Logs&&} - {tenderData?.envelopeC_Logs && } + {tenderData?.envelopeA_Logs && } + {tenderData?.envelopeB_Logs && } + {tenderData?.envelopeC_Logs && } )} @@ -259,12 +259,17 @@ const ProceedToBidDetail = () => { { tenderData?.proceedtoBid && !tenderData?.viewBid && tenderData?.biddingStatus && tenderData?.bidWithdrawStatus === false ? ( - + {loading ? : 'Start Bidding'} - ) : One time bidding is completed - } + ) : + // One time bidding is completed + navigation.navigate('ViewTenderDetail', tenderData)} style={[styles.actionButton, { borderColor: colors.primary, borderWidth: 1 }]}> + View Tender Bid Detail + + } + ) @@ -585,4 +590,19 @@ const styles = StyleSheet.create({ color: colors.darkGray, fontSize: 14, }, + actionButton: { + width: '100%', + height: 48, + borderRadius: 12, + justifyContent: 'center', + alignItems: 'center', + ...Platform.select({ + ios: { + shadowColor: '#000', + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.1, + shadowRadius: 4, + }, + }), + }, }); \ No newline at end of file diff --git a/src/Screens/Tender/PurchaseTenderTile.tsx b/src/Screens/Tender/PurchaseTenderTile.tsx index 2a6d0ff..ef9baa4 100644 --- a/src/Screens/Tender/PurchaseTenderTile.tsx +++ b/src/Screens/Tender/PurchaseTenderTile.tsx @@ -108,8 +108,6 @@ const PurchaseTenderTile = ({ item, onPressDetails }: any) => { onPress={() => { if (isLive) { navigation.navigate('ProceedToBidDetail', { tender }); - }else{ - navigation.navigate('LiveTenderDetail', tender) } }} activeOpacity={0.85} diff --git a/src/Screens/Tender/ViewTenderDetail.tsx b/src/Screens/Tender/ViewTenderDetail.tsx new file mode 100644 index 0000000..e915075 --- /dev/null +++ b/src/Screens/Tender/ViewTenderDetail.tsx @@ -0,0 +1,634 @@ +import { ScrollView, StyleSheet, Text, View, TouchableOpacity, SafeAreaView, Alert } from 'react-native' +import React from 'react' +import { InsideHeader } from '../../Component/Index' +import colors from '../../Constant/Color' +import { useFetchLiveTenderById, useFetchTenderBidDetailById, useFetchTenderById } from '../../Services/BBPS/Hooks' +import { useRoute } from '@react-navigation/native' +import { + Mail, + FileText, + CheckCircle, + AlertCircle, + Briefcase, + Calendar, + Download, + Folder, + Hash, + Receipt, + IndianRupee, + Building, + Tag, + Settings, + PlayCircle, + Square, + Type, + SpellCheck, + File, + Circle, + ArrowLeft, + FileSpreadsheet +} from 'lucide-react-native' +import ReactNativeBlobUtil from 'react-native-blob-util'; +import { GET_DOCID } from '../../Services/BBPS/ApiUrls' +import { useSelector } from 'react-redux' + +const ViewTenderDetail = () => { + const route: any = useRoute() + const { data: tenderResponse }: any = useFetchLiveTenderById(route?.params?.tenderId); + const tender = tenderResponse?.data; + + console.log("tender data : ", tender) + const { data } = useFetchTenderBidDetailById(route?.params?.tenderId) + const Token = useSelector((state: any) => state.token.token) + + console.log("dasdddddddddddddddddddd : ", data) + const formatDate = (dateArray: any) => { + if (!dateArray) return "N/A"; + const [year, month, day, hour, minute] = dateArray; + return `${day.toString().padStart(2, '0')}/${month.toString().padStart(2, '0')}/${year} ${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`; + }; + + const getLabelTypeText = (type: any) => { + switch (type) { + case 1: return "Text"; + case 2: return "Number"; + case 3: return "Document"; + case 4: return "Currency"; + default: return "Unknown"; + } + }; + + const renderInfoCard = (title: string, value: string, IconComponent: any) => ( + + + + {title} + + {value || "N/A"} + + ); + + const handleDownload = async (doc: any) => { + console.log("doc details : ", doc) + try { + const { dirs } = ReactNativeBlobUtil.fs; + const path = `${dirs.DownloadDir}/${doc?.documentFileName}.pdf`; + const downloadUrl = `${GET_DOCID}${doc?.docEnvelopeSeqId}`; + console.log("download url : ", downloadUrl) + const response = await ReactNativeBlobUtil.config({ + fileCache: true, + addAndroidDownloads: { + useDownloadManager: true, + notification: true, + path, + mime: 'application/pdf', + title: `${doc?.documentFileName}.pdf`, + description: 'Downloading document', + mediaScannable: true, + }, + }).fetch('GET', downloadUrl, { + Authentication:`Bearer ${Token?.token}`, + Accept: 'application/pdf', + }); + + const stat = await ReactNativeBlobUtil.fs.stat(path); + console.log('File size:', stat.size); + console.log("start : ", stat) + Alert.alert('Download complete', `File saved to: ${path}`); + console.log("file response : ", response) + } catch (error: any) { + Alert.alert('Error', error?.message || 'Something went wrong while downloading.'); + } + }; + + const renderEnvelopeSection = (title: string, data: any, isDocument = false) => { + if (!data || data.length === 0) return null; + + return ( + + + + {title} + + {data.map((item: any, index: number) => ( + + + + {item.labelNameA || item.labelNameB || "Document"} + + {item.labelMandatoryA || item.labelMandatoryB ? ( + Required + ) : null} + + + {item.fieldValue && ( + + + {item.fieldValue} + + )} + + {item.fieldValueInWord && ( + + + {item.fieldValueInWord} + + )} + + {item.documentFileName && ( + handleDownload(item)}> + + {item.documentFileName} + + + )} + + + + Type: {getLabelTypeText(item.labelTypeA || item.labelTypeB)} + + {item.docEnvelopeSeqId && ( + ID: {item.docEnvelopeSeqId} + )} + + + ))} + + ); + }; + + return ( + + + + + + {/* Status Banner */} + + {data?.status === "Success" ? ( + + ) : ( + + )} + + {data?.message} + Status: {data?.status} + + + + {/* Tender Overview */} + + + + Tender Overview + + + + + {renderInfoCard("Tender No.", data?.data?.tenderNumber, Hash)} + + + {renderInfoCard("NIT No.", data?.data?.nitNo, Receipt)} + {renderInfoCard("EMD Amount", `₹${data?.data?.emdInFig}`, IndianRupee)} + + + {renderInfoCard("PAC Value", `₹${data?.data?.pacValue}`, Building)} + {renderInfoCard("Type", data?.data?.typesOfTender, Tag)} + + + + {/* Work Description */} + + + + Work Description + + {data?.data?.nameofWork} + + + {/* Timeline */} + + + + Timeline + + + + + Start Date + + {formatDate(data?.data?.submittedStartDate)} + + + + + + + End Date + + {formatDate(data?.data?.submittedEndDate)} + + + + + + {/* Bid Options */} + + + + Bid Options + + + + Bid Withdrawal + {data?.data?.bidWithdraw} + + + Re-Bid + {data?.data?.reBid} + + + + + + {/* Envelope Sections */} + {data?.data?.showEA && renderEnvelopeSection("Envelope A", data?.data?.tenderEnvelopeAList)} + {data?.data?.showEB && renderEnvelopeSection("Envelope B", data?.data?.tenderEnvelopeBList)} + + {/* Envelope C - Document Section */} + {data?.data?.showEC && data?.data?.tenderEnvelopeCViewBidResDTO && ( + + + + Envelope C + + {data?.data?.tenderEnvelopeCViewBidResDTO.map((item: any, index: number) => ( + + + + + {item.documentFileName || "Document"} + + Department User ID: {item.deptUserId} + + {item.documentFileName && ( + + {/* */} + + )} + + ))} + + )} + + {/* Envelope Status Indicators */} + + + + + Envelope A + + + + Envelope B + + + + Envelope C + + + + + + + ) +} + +export default ViewTenderDetail + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: colors.white, + }, + container: { + flex: 1, + }, + scrollView: { + flex: 1, + }, + scrollContent: { + paddingBottom: 30, + }, + statusBanner: { + flexDirection: 'row', + alignItems: 'center', + padding: 16, + marginHorizontal: 16, + marginTop: 16, + borderRadius: 12, + backgroundColor: colors.successLight, + }, + successBanner: { + backgroundColor: colors.successLight, + }, + errorBanner: { + backgroundColor: colors.error, + }, + statusContent: { + flex: 1, + marginLeft: 12, + }, + statusTitle: { + fontSize: 14, + fontWeight: '600', + color: colors.darkText, + marginBottom: 4, + }, + statusSubtitle: { + fontSize: 12, + color: colors.gray, + }, + overviewSection: { + marginHorizontal: 16, + marginTop: 24, + }, + sectionHeader: { + flexDirection: 'row', + alignItems: 'center', + marginBottom: 20, + }, + sectionTitle: { + fontSize: 20, + fontWeight: '700', + color: colors.darkText, + marginLeft: 12, + }, + gridContainer: { + marginBottom: 20, + }, + gridRow: { + flexDirection: 'row', + justifyContent: 'space-between', + marginBottom: 12, + }, + infoCard: { + flex: 1, + backgroundColor: colors.white, + padding: 16, + borderRadius: 12, + marginHorizontal: 4, + borderWidth: 1, + borderColor: colors.lightGray, + }, + infoHeader: { + flexDirection: 'row', + alignItems: 'center', + marginBottom: 8, + }, + infoTitle: { + fontSize: 12, + fontWeight: '600', + color: colors.gray, + marginLeft: 8, + }, + infoValue: { + fontSize: 16, + fontWeight: '700', + color: colors.darkText, + }, + descriptionCard: { + backgroundColor: colors.white, + padding: 16, + borderRadius: 12, + borderWidth: 1, + borderColor: colors.lightGray, + marginBottom: 16, + }, + descriptionText: { + fontSize: 14, + color: colors.darkText, + lineHeight: 20, + marginTop: 8, + }, + timelineCard: { + backgroundColor: colors.white, + padding: 16, + borderRadius: 12, + borderWidth: 1, + borderColor: colors.lightGray, + marginBottom: 16, + }, + timelineRow: { + flexDirection: 'row', + alignItems: 'center', + marginTop: 12, + }, + timelineItem: { + flex: 1, + marginLeft: 12, + }, + timelineLabel: { + fontSize: 12, + color: colors.gray, + marginBottom: 4, + }, + timelineValue: { + fontSize: 14, + fontWeight: '600', + color: colors.darkText, + }, + optionsCard: { + backgroundColor: colors.primaryLight, + padding: 16, + borderRadius: 12, + borderWidth: 1, + borderColor: colors.lightGray, + marginBottom: 24, + }, + optionsGrid: { + flexDirection: 'row', + justifyContent: 'space-between', + marginTop: 12, + }, + optionBadge: { + flex: 1, + alignItems: 'center', + paddingVertical: 12, + borderRadius: 8, + marginHorizontal: 4, + }, + allowedBadge: { + backgroundColor: colors.successLight, + borderWidth: 1, + borderColor: colors.success, + }, + notAllowedBadge: { + backgroundColor: colors.error, + borderWidth: 1, + borderColor: colors.error, + }, + optionText: { + fontSize: 12, + color: colors.gray, + marginBottom: 4, + }, + optionStatus: { + fontSize: 14, + fontWeight: '700', + }, + envelopeSection: { + marginHorizontal: 16, + marginTop: 24, + }, + envelopeItem: { + backgroundColor: colors.white, + padding: 16, + borderRadius: 12, + borderWidth: 1, + borderColor: colors.lightGray, + marginBottom: 12, + }, + envelopeHeader: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + marginBottom: 12, + }, + labelName: { + fontSize: 16, + fontWeight: '700', + color: colors.darkText, + }, + mandatoryTag: { + fontSize: 12, + fontWeight: '600', + color: colors.error, + backgroundColor: colors.primaryHighlight, + paddingHorizontal: 8, + paddingVertical: 4, + borderRadius: 6, + }, + fieldRow: { + flexDirection: 'row', + alignItems: 'center', + marginTop: 8, + }, + fieldValue: { + fontSize: 14, + color: colors.darkText, + marginLeft: 8, + flex: 1, + }, + fieldValueInWord: { + fontSize: 13, + color: colors.gray, + fontStyle: 'italic', + marginLeft: 8, + flex: 1, + }, + documentButton: { + flexDirection: 'row', + alignItems: 'center', + backgroundColor: colors.primary, + padding: 12, + borderRadius: 8, + marginTop: 12, + }, + documentText: { + flex: 1, + fontSize: 14, + color: colors.white, + marginLeft: 12, + marginRight: 8, + }, + metaInfo: { + flexDirection: 'row', + justifyContent: 'space-between', + marginTop: 12, + paddingTop: 12, + borderTopWidth: 1, + borderTopColor: colors.lightGray, + }, + metaText: { + fontSize: 12, + color: colors.gray, + }, + documentCard: { + flexDirection: 'row', + alignItems: 'center', + backgroundColor: colors.white, + padding: 16, + borderRadius: 12, + borderWidth: 1, + borderColor: colors.lightGray, + marginBottom: 12, + }, + documentInfo: { + flex: 1, + marginLeft: 16, + }, + documentName: { + fontSize: 14, + fontWeight: '600', + color: colors.darkText, + marginBottom: 4, + }, + documentMeta: { + fontSize: 12, + color: colors.gray, + }, + downloadButton: { + padding: 8, + }, + envelopeStatusSection: { + marginHorizontal: 16, + marginTop: 24, + marginBottom: 30, + }, + statusGrid: { + flexDirection: 'row', + justifyContent: 'space-around', + }, + statusIndicator: { + alignItems: 'center', + }, + statusDot: { + width: 12, + height: 12, + borderRadius: 6, + marginBottom: 8, + }, + activeDot: { + backgroundColor: colors.success, + }, + inactiveDot: { + backgroundColor: colors.gray, + }, + statusText: { + fontSize: 12, + color: colors.gray, + }, +}) \ No newline at end of file diff --git a/src/Screens/index.ts b/src/Screens/index.ts index b37127a..00ef479 100644 --- a/src/Screens/index.ts +++ b/src/Screens/index.ts @@ -19,6 +19,7 @@ import ProceedToPurTender from "./Tender/ProceedToPurTender"; import PurchaseTenderList from "./Tender/PurchaseTenderList"; import Tender from "./Tender/Tender"; import TenderBidding from "./Tender/tenderBidding/TenderBidding"; +import ViewTenderDetail from "./Tender/ViewTenderDetail"; const Screens = { @@ -41,9 +42,8 @@ const Screens = { Registration, Partnership, LiveTenderDetail, - ProfileTab, + ProfileTab, , KycWebViewScreen - - + ViewTenderDetail } export default Screens \ No newline at end of file diff --git a/src/Services/BBPS/ApiUrls.tsx b/src/Services/BBPS/ApiUrls.tsx index 35ea9b5..e02aae6 100644 --- a/src/Services/BBPS/ApiUrls.tsx +++ b/src/Services/BBPS/ApiUrls.tsx @@ -84,6 +84,7 @@ const GET_ENVELOPE_C = `${BASE_URL}eTendering/getEnvelopeCTemplate/tenderId?tend const SUBMIT_ENVELOPE_C_UPLOAD = `${BASE_URL}tenderBidding/getSaveEnvelopeCData` const GET_CONTRACTOR_PROFILE =`${BASE_URL}contractor/getcontractorfulldetails` const ESETU_VARIFICATION = `${BASE_URL}tenderBidding/eSetuAdharVarification` +const TENDER_BID_DETAIL = `${BASE_URL}tenderBidding/viewToBid?tenderId=` @@ -163,6 +164,7 @@ export { SUBMIT_ENVELOPE_C_UPLOAD, GET_TENDER_BY_ID, GET_CONTRACTOR_PROFILE, - ESETU_VARIFICATION + ESETU_VARIFICATION, + TENDER_BID_DETAIL }; diff --git a/src/Services/BBPS/Hooks.ts b/src/Services/BBPS/Hooks.ts index dc42e80..88add72 100644 --- a/src/Services/BBPS/Hooks.ts +++ b/src/Services/BBPS/Hooks.ts @@ -1,5 +1,5 @@ import { useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query'; -import { contractorStageThreeSubmit, contractorStageTwoSubmit, fetchAuctionItem, fetchCityDropdown, fetchDashboard, fetchEmdCheck, fetchLiveAuction, fetchLiveTender, fetchMasterData, fetchPurchaseAuction, fetchPurchaseAuctionList, fetchPurchaseTender, fetchTenderById, getAuction, getDesignation, getRagistrationState, offlineAuctionPurchase, offlineTenderPurchase, partnerShipSubmit, proceedToBid, registerContractor, sendAadhaarOtp, submitEnvelopeA, submitEnvelopeB, uploadEnvelopeFile, userAuctionLogin, userLogin, verifyAadhaarOtp, verifyGstNumber, verifyPanHandler, viewAuctionDocumentDownload, viewAuctionDocuments, viewAuctionItemDocuments, fetchPurchaseAuctionPage, tenderDetails, fetchLiveTenderById, fetchContractorProfile, updateUserProfile, eSetuAdharVarification } from './apis'; +import { contractorStageThreeSubmit, contractorStageTwoSubmit, fetchAuctionItem, fetchCityDropdown, fetchDashboard, fetchEmdCheck, fetchLiveAuction, fetchLiveTender, fetchMasterData, fetchPurchaseAuction, fetchPurchaseAuctionList, fetchPurchaseTender, fetchTenderById, getAuction, getDesignation, getRagistrationState, offlineAuctionPurchase, offlineTenderPurchase, partnerShipSubmit, proceedToBid, registerContractor, sendAadhaarOtp, submitEnvelopeA, submitEnvelopeB, uploadEnvelopeFile, userAuctionLogin, userLogin, verifyAadhaarOtp, verifyGstNumber, verifyPanHandler, viewAuctionDocumentDownload, viewAuctionDocuments, viewAuctionItemDocuments, fetchPurchaseAuctionPage, tenderDetails, fetchLiveTenderById, fetchContractorProfile, updateUserProfile, eSetuAdharVarification, fetchTenderBidDetailById } from './apis'; // User @@ -175,6 +175,12 @@ export const useFetchTenderById = (tenderId: string) => { enabled: !!tenderId, // prevents running with undefined id }); } +export const useFetchTenderBidDetailById = (tenderId: string) => { + return useQuery({ + queryKey: ['fetchTenderBidDetailById', tenderId], + queryFn: () => fetchTenderBidDetailById(tenderId), + }); +} export const useProceedToBid = (tenderId?: string) => { return useQuery({ queryKey: ['proceedToBid', tenderId], diff --git a/src/Services/BBPS/apis.ts b/src/Services/BBPS/apis.ts index a5cc947..96655ac 100644 --- a/src/Services/BBPS/apis.ts +++ b/src/Services/BBPS/apis.ts @@ -1,6 +1,6 @@ import axios from "axios"; import { AUCTION_DOCUMENT_DOWNLOAD, DASHBOARD_COUNT, EMD_CHECK, FORARD_AUCTION_ITEM, GET_AUCTION_DETAILS, GET_MY_AUCTION, GET_MY_TENDER, GET_TENDER_DETAILS, LIVE_AUCTION, LIVE_TENDER, LOG_IN_URL, PROCEED_PURCHASE_AUCTION, PROCEED_TO_BID, PURCHASE_TENDER_OFFLINE, TENDER_LOGIN, PURCHASE_AUCTION_LIST, PURCHASE_OFFLINE_AUCTION, REVERSE_AUCTION_ITEM, VIEW_AUCTION_DOCUMENTS, VIEW_AUCTION_ITEM_DETAIL, STAGETHREE, REJ_STAGE_TWO, GETCONTRACTORBYSTATE, GET_MASTER_DATA, ALL_DESIGNATION, GET_REGISTRATION_STATE, PARTNER_API_ENDPOINT, SAVE_CONTRACTOR_STAGE1, VERIFY_GST, VERIFY_ADHAR, SEND_ADHAROTP, SUBMIT_ENVELOPE_FILE_B, SUBMIT_ENVELOPE_FILE_A, SUBMIT_ENVELOPE_A, SUBMIT_ENVELOPE_B, VERIFY_ORGPAN, PURCHASE_AUCTION_PAGE, GET_TENDER_BY_ID, GET_CONTRACTOR_PROFILE, CONTRACTOR_PROFILE_UPDATE, - ESETU_VARIFICATION } from "./ApiUrls"; + ESETU_VARIFICATION, TENDER_BID_DETAIL } from "./ApiUrls"; import { apiCall } from "../../Axios/Axios"; // User @@ -144,6 +144,13 @@ export const fetchTenderById = async (tenderId: string): Promise => { ); return data; }; +export const fetchTenderBidDetailById = async (tenderId: string): Promise => { + const data = await apiCall( + 'get', + `${TENDER_BID_DETAIL}${tenderId}` + ); + return data; +}; export const proceedToBid = async (tenderId: string): Promise => { const data = await apiCall(