Merge branch 'main' of https://git.zeptic.in/rohit/Procurelinc into etenderMerge
This commit is contained in:
Generated
+73
-248
@@ -30,7 +30,7 @@
|
|||||||
"react-native": "0.79.0",
|
"react-native": "0.79.0",
|
||||||
"react-native-alert-notification": "^0.4.2",
|
"react-native-alert-notification": "^0.4.2",
|
||||||
"react-native-app-intro-slider": "^4.0.4",
|
"react-native-app-intro-slider": "^4.0.4",
|
||||||
"react-native-bouncy-checkbox": "^4.1.3",
|
"react-native-bouncy-checkbox": "^4.1.2",
|
||||||
"react-native-date-picker": "^5.0.13",
|
"react-native-date-picker": "^5.0.13",
|
||||||
"react-native-gesture-handler": "^2.30.0",
|
"react-native-gesture-handler": "^2.30.0",
|
||||||
"react-native-gifted-charts": "^1.4.70",
|
"react-native-gifted-charts": "^1.4.70",
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
"@babel/core": "^7.25.2",
|
"@babel/core": "^7.25.2",
|
||||||
"@babel/preset-env": "^7.25.3",
|
"@babel/preset-env": "^7.25.3",
|
||||||
"@babel/runtime": "^7.25.0",
|
"@babel/runtime": "^7.25.0",
|
||||||
"@react-native-community/cli": "^18.0.1",
|
"@react-native-community/cli": "18.0.0",
|
||||||
"@react-native-community/cli-platform-android": "18.0.0",
|
"@react-native-community/cli-platform-android": "18.0.0",
|
||||||
"@react-native-community/cli-platform-ios": "18.0.0",
|
"@react-native-community/cli-platform-ios": "18.0.0",
|
||||||
"@react-native/babel-preset": "0.79.0",
|
"@react-native/babel-preset": "0.79.0",
|
||||||
@@ -105,6 +105,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
|
||||||
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.27.1",
|
"@babel/code-frame": "^7.27.1",
|
||||||
"@babel/generator": "^7.28.5",
|
"@babel/generator": "^7.28.5",
|
||||||
@@ -136,6 +137,7 @@
|
|||||||
"integrity": "sha512-fcdRcWahONYo+JRnJg1/AekOacGvKx12Gu0qXJXFi2WBqQA1i7+O5PaxRB7kxE/Op94dExnCiiar6T09pvdHpA==",
|
"integrity": "sha512-fcdRcWahONYo+JRnJg1/AekOacGvKx12Gu0qXJXFi2WBqQA1i7+O5PaxRB7kxE/Op94dExnCiiar6T09pvdHpA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1",
|
"@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1",
|
||||||
"eslint-visitor-keys": "^2.1.0",
|
"eslint-visitor-keys": "^2.1.0",
|
||||||
@@ -2782,18 +2784,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native-community/cli": {
|
"node_modules/@react-native-community/cli": {
|
||||||
"version": "18.0.1",
|
"version": "18.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-18.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-18.0.0.tgz",
|
||||||
"integrity": "sha512-nEEYwfyP00j9i4nr/HhwPabDscoBhhCjxDBpcKERi2oTYHcBr3FTu9PV1gbeJCa4vRCHr6b6VgOcVTdy99NddQ==",
|
"integrity": "sha512-DyKptlG78XPFo7tDod+we5a3R+U9qjyhaVFbOPvH4pFNu5Dehewtol/srl44K6Cszq0aEMlAJZ3juk0W4WnOJA==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-community/cli-clean": "18.0.1",
|
"@react-native-community/cli-clean": "18.0.0",
|
||||||
"@react-native-community/cli-config": "18.0.1",
|
"@react-native-community/cli-config": "18.0.0",
|
||||||
"@react-native-community/cli-doctor": "18.0.1",
|
"@react-native-community/cli-doctor": "18.0.0",
|
||||||
"@react-native-community/cli-server-api": "18.0.1",
|
"@react-native-community/cli-server-api": "18.0.0",
|
||||||
"@react-native-community/cli-tools": "18.0.1",
|
"@react-native-community/cli-tools": "18.0.0",
|
||||||
"@react-native-community/cli-types": "18.0.1",
|
"@react-native-community/cli-types": "18.0.0",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
"commander": "^9.4.1",
|
"commander": "^9.4.1",
|
||||||
"deepmerge": "^4.3.0",
|
"deepmerge": "^4.3.0",
|
||||||
@@ -2812,58 +2815,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native-community/cli-clean": {
|
"node_modules/@react-native-community/cli-clean": {
|
||||||
"version": "18.0.1",
|
"version": "18.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-clean/-/cli-clean-18.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/cli-clean/-/cli-clean-18.0.0.tgz",
|
||||||
"integrity": "sha512-brXqk//lmA2Vs5lGq9YLhk7X4IYBSrDRte6t1AktouJpCrH4Tp1sl45yJDS2CHOi/OY1oOfI3kA61tXNX5a/5A==",
|
"integrity": "sha512-+k64EnJaMI5U8iNDF9AftHBJW+pO/isAhncEXuKRc6IjRtIh6yoaUIIf5+C98fgjfux7CNRZAMQIkPbZodv2Gw==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-community/cli-tools": "18.0.1",
|
"@react-native-community/cli-tools": "18.0.0",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
"execa": "^5.0.0",
|
"execa": "^5.0.0",
|
||||||
"fast-glob": "^3.3.2"
|
"fast-glob": "^3.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native-community/cli-clean/node_modules/@react-native-community/cli-tools": {
|
|
||||||
"version": "18.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-18.0.1.tgz",
|
|
||||||
"integrity": "sha512-WxWFXwfYhHR2eYiB4lkHZVC/PmIkRWeVHBQKmn0h1mecr3GrHYO4BzW1jpD5Xt6XZ9jojQ9wE5xrCqXjiMSAIQ==",
|
|
||||||
"devOptional": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@vscode/sudo-prompt": "^9.0.0",
|
|
||||||
"appdirsjs": "^1.2.4",
|
|
||||||
"chalk": "^4.1.2",
|
|
||||||
"execa": "^5.0.0",
|
|
||||||
"find-up": "^5.0.0",
|
|
||||||
"launch-editor": "^2.9.1",
|
|
||||||
"mime": "^2.4.1",
|
|
||||||
"ora": "^5.4.1",
|
|
||||||
"prompts": "^2.4.2",
|
|
||||||
"semver": "^7.5.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native-community/cli-clean/node_modules/semver": {
|
|
||||||
"version": "7.7.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
|
||||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
|
||||||
"devOptional": true,
|
|
||||||
"license": "ISC",
|
|
||||||
"bin": {
|
|
||||||
"semver": "bin/semver.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native-community/cli-config": {
|
"node_modules/@react-native-community/cli-config": {
|
||||||
"version": "18.0.1",
|
"version": "18.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-config/-/cli-config-18.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/cli-config/-/cli-config-18.0.0.tgz",
|
||||||
"integrity": "sha512-O4DDJVMx+DYfwEgF/6lB4hoI9sVjrYW6AlLqeJY/D2XH2e4yqK/Pr3SAi4sOMgvjvYZKzLHqIQVxx54v+LyMQA==",
|
"integrity": "sha512-GUGvyek06JRF4mfd9zXao9YQW4+H8ny69HznqNXVRtVSIIekFyjOpKQeSEzdcyqJEEa5gej22GOz1JCHMKBccg==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-community/cli-tools": "18.0.1",
|
"@react-native-community/cli-tools": "18.0.0",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
"cosmiconfig": "^9.0.0",
|
"cosmiconfig": "^9.0.0",
|
||||||
"deepmerge": "^4.3.0",
|
"deepmerge": "^4.3.0",
|
||||||
@@ -2875,7 +2846,7 @@
|
|||||||
"version": "18.0.0",
|
"version": "18.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-config-android/-/cli-config-android-18.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/cli-config-android/-/cli-config-android-18.0.0.tgz",
|
||||||
"integrity": "sha512-pgnhEO2cmOeb+bBFEBZFYjeFjDTqWoV0JTorTiugj9bb4RQRCl8cr35baVlBGhxAuaio3722CsJ9GRF1oHjP8w==",
|
"integrity": "sha512-pgnhEO2cmOeb+bBFEBZFYjeFjDTqWoV0JTorTiugj9bb4RQRCl8cr35baVlBGhxAuaio3722CsJ9GRF1oHjP8w==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-community/cli-tools": "18.0.0",
|
"@react-native-community/cli-tools": "18.0.0",
|
||||||
@@ -2888,7 +2859,7 @@
|
|||||||
"version": "18.0.0",
|
"version": "18.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-config-apple/-/cli-config-apple-18.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/cli-config-apple/-/cli-config-apple-18.0.0.tgz",
|
||||||
"integrity": "sha512-6edjTt3mlNMFBuB/Xd6u0O7GEkhJiKvQgmcoBH18FsNy5cpiHDwQsG8EWM5cHeINp1gMK845qq9fFsTko6gqyQ==",
|
"integrity": "sha512-6edjTt3mlNMFBuB/Xd6u0O7GEkhJiKvQgmcoBH18FsNy5cpiHDwQsG8EWM5cHeINp1gMK845qq9fFsTko6gqyQ==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-community/cli-tools": "18.0.0",
|
"@react-native-community/cli-tools": "18.0.0",
|
||||||
@@ -2897,50 +2868,18 @@
|
|||||||
"fast-glob": "^3.3.2"
|
"fast-glob": "^3.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native-community/cli-config/node_modules/@react-native-community/cli-tools": {
|
|
||||||
"version": "18.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-18.0.1.tgz",
|
|
||||||
"integrity": "sha512-WxWFXwfYhHR2eYiB4lkHZVC/PmIkRWeVHBQKmn0h1mecr3GrHYO4BzW1jpD5Xt6XZ9jojQ9wE5xrCqXjiMSAIQ==",
|
|
||||||
"devOptional": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@vscode/sudo-prompt": "^9.0.0",
|
|
||||||
"appdirsjs": "^1.2.4",
|
|
||||||
"chalk": "^4.1.2",
|
|
||||||
"execa": "^5.0.0",
|
|
||||||
"find-up": "^5.0.0",
|
|
||||||
"launch-editor": "^2.9.1",
|
|
||||||
"mime": "^2.4.1",
|
|
||||||
"ora": "^5.4.1",
|
|
||||||
"prompts": "^2.4.2",
|
|
||||||
"semver": "^7.5.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native-community/cli-config/node_modules/semver": {
|
|
||||||
"version": "7.7.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
|
||||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
|
||||||
"devOptional": true,
|
|
||||||
"license": "ISC",
|
|
||||||
"bin": {
|
|
||||||
"semver": "bin/semver.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native-community/cli-doctor": {
|
"node_modules/@react-native-community/cli-doctor": {
|
||||||
"version": "18.0.1",
|
"version": "18.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-doctor/-/cli-doctor-18.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/cli-doctor/-/cli-doctor-18.0.0.tgz",
|
||||||
"integrity": "sha512-B1UWpiVeJ45DX0ip1Et62knAHLzeA1B3XcTJu16PscednnNxV6GBH52kRUoWMsB8HQ8f9IWdFTol8LAp5Y0wwg==",
|
"integrity": "sha512-cD3LJfu2h2QSFmZai+fl7RrORKodd5XHSuB7Y9oF1zkebpRYN720vaUtK+GsepqBOElwKk5gl8uVolJ3j+xm8A==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-community/cli-config": "18.0.1",
|
"@react-native-community/cli-config": "18.0.0",
|
||||||
"@react-native-community/cli-platform-android": "18.0.1",
|
"@react-native-community/cli-platform-android": "18.0.0",
|
||||||
"@react-native-community/cli-platform-apple": "18.0.1",
|
"@react-native-community/cli-platform-apple": "18.0.0",
|
||||||
"@react-native-community/cli-platform-ios": "18.0.1",
|
"@react-native-community/cli-platform-ios": "18.0.0",
|
||||||
"@react-native-community/cli-tools": "18.0.1",
|
"@react-native-community/cli-tools": "18.0.0",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
"command-exists": "^1.2.8",
|
"command-exists": "^1.2.8",
|
||||||
"deepmerge": "^4.3.0",
|
"deepmerge": "^4.3.0",
|
||||||
@@ -2953,89 +2892,6 @@
|
|||||||
"yaml": "^2.2.1"
|
"yaml": "^2.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native-community/cli-doctor/node_modules/@react-native-community/cli-config-android": {
|
|
||||||
"version": "18.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-config-android/-/cli-config-android-18.0.1.tgz",
|
|
||||||
"integrity": "sha512-1wzmGLfS7qgzm0ZfwX/f6Lat/af8/UYdjwtb3ap6RfKNclvIoap0wN6uBeiANmLfk0/BhoG8K1vKtIPwlU/V1A==",
|
|
||||||
"devOptional": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@react-native-community/cli-tools": "18.0.1",
|
|
||||||
"chalk": "^4.1.2",
|
|
||||||
"fast-glob": "^3.3.2",
|
|
||||||
"fast-xml-parser": "^4.4.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native-community/cli-doctor/node_modules/@react-native-community/cli-config-apple": {
|
|
||||||
"version": "18.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-config-apple/-/cli-config-apple-18.0.1.tgz",
|
|
||||||
"integrity": "sha512-ybr1ZrOSd/Z+oCJ1qVSKVQauvneObTu3VjvYPhhrme7tUUSaYmd3iikaWonbKk5rVp+2WqOFR6Cy7XqVfwwG8A==",
|
|
||||||
"devOptional": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@react-native-community/cli-tools": "18.0.1",
|
|
||||||
"chalk": "^4.1.2",
|
|
||||||
"execa": "^5.0.0",
|
|
||||||
"fast-glob": "^3.3.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native-community/cli-doctor/node_modules/@react-native-community/cli-platform-android": {
|
|
||||||
"version": "18.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-18.0.1.tgz",
|
|
||||||
"integrity": "sha512-DCltVWDR7jfZZG5MXREVKG0fmIr1b0irEhmdkk/R87dG6HJ8tGXWXnAa4Kap8bx2v6lKFXDW5QxNecyyLCOkVw==",
|
|
||||||
"devOptional": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@react-native-community/cli-config-android": "18.0.1",
|
|
||||||
"@react-native-community/cli-tools": "18.0.1",
|
|
||||||
"chalk": "^4.1.2",
|
|
||||||
"execa": "^5.0.0",
|
|
||||||
"logkitty": "^0.7.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native-community/cli-doctor/node_modules/@react-native-community/cli-platform-apple": {
|
|
||||||
"version": "18.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-apple/-/cli-platform-apple-18.0.1.tgz",
|
|
||||||
"integrity": "sha512-7WxGXT/ui7VtyLVjx5rkYkkTMlbufI6p5BdRKjGp/zQDnDzs/0rle0JEHJxwgvs5VQnt+VOnHBMipkQAhydIqQ==",
|
|
||||||
"devOptional": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@react-native-community/cli-config-apple": "18.0.1",
|
|
||||||
"@react-native-community/cli-tools": "18.0.1",
|
|
||||||
"chalk": "^4.1.2",
|
|
||||||
"execa": "^5.0.0",
|
|
||||||
"fast-xml-parser": "^4.4.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native-community/cli-doctor/node_modules/@react-native-community/cli-platform-ios": {
|
|
||||||
"version": "18.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-18.0.1.tgz",
|
|
||||||
"integrity": "sha512-GtO1FB+xaz+vcHIdvl94AkD5B8Y+H8XHb6QwnYX+A3WwteGsHrR8iD/bLLcRtNPtLaAWMa/RgWJpgs4KG+eU4w==",
|
|
||||||
"devOptional": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@react-native-community/cli-platform-apple": "18.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native-community/cli-doctor/node_modules/@react-native-community/cli-tools": {
|
|
||||||
"version": "18.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-18.0.1.tgz",
|
|
||||||
"integrity": "sha512-WxWFXwfYhHR2eYiB4lkHZVC/PmIkRWeVHBQKmn0h1mecr3GrHYO4BzW1jpD5Xt6XZ9jojQ9wE5xrCqXjiMSAIQ==",
|
|
||||||
"devOptional": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@vscode/sudo-prompt": "^9.0.0",
|
|
||||||
"appdirsjs": "^1.2.4",
|
|
||||||
"chalk": "^4.1.2",
|
|
||||||
"execa": "^5.0.0",
|
|
||||||
"find-up": "^5.0.0",
|
|
||||||
"launch-editor": "^2.9.1",
|
|
||||||
"mime": "^2.4.1",
|
|
||||||
"ora": "^5.4.1",
|
|
||||||
"prompts": "^2.4.2",
|
|
||||||
"semver": "^7.5.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native-community/cli-doctor/node_modules/semver": {
|
"node_modules/@react-native-community/cli-doctor/node_modules/semver": {
|
||||||
"version": "7.7.3",
|
"version": "7.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
||||||
@@ -3053,7 +2909,7 @@
|
|||||||
"version": "18.0.0",
|
"version": "18.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-18.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-18.0.0.tgz",
|
||||||
"integrity": "sha512-3Y3RleN/des1C3oRS6s6fDvFYKN0KwsLrYFRpVx9vzdDnH1OGyFJOy4DbrruSPtdNiHUpvvHnOOxeLMj0+/tmw==",
|
"integrity": "sha512-3Y3RleN/des1C3oRS6s6fDvFYKN0KwsLrYFRpVx9vzdDnH1OGyFJOy4DbrruSPtdNiHUpvvHnOOxeLMj0+/tmw==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-community/cli-config-android": "18.0.0",
|
"@react-native-community/cli-config-android": "18.0.0",
|
||||||
@@ -3067,7 +2923,7 @@
|
|||||||
"version": "18.0.0",
|
"version": "18.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-apple/-/cli-platform-apple-18.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-apple/-/cli-platform-apple-18.0.0.tgz",
|
||||||
"integrity": "sha512-zD18gdP5Wr8BSLJ79xtHuPYcg2Vi/nL+WsGsPm7TZjzR5ZU2WbY/tZ+qTGVTQYhQaah+92sU+Dam7gStMrF/fA==",
|
"integrity": "sha512-zD18gdP5Wr8BSLJ79xtHuPYcg2Vi/nL+WsGsPm7TZjzR5ZU2WbY/tZ+qTGVTQYhQaah+92sU+Dam7gStMrF/fA==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-community/cli-config-apple": "18.0.0",
|
"@react-native-community/cli-config-apple": "18.0.0",
|
||||||
@@ -3081,20 +2937,20 @@
|
|||||||
"version": "18.0.0",
|
"version": "18.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-18.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-18.0.0.tgz",
|
||||||
"integrity": "sha512-05Nvkkre/4Gao1TYqyP1wGet8td1dAH0CLJKqLNl9Te6ihnrQ8/8OhjIna5xw0iEFr9An8VdLfaPu1Dgv2qAnQ==",
|
"integrity": "sha512-05Nvkkre/4Gao1TYqyP1wGet8td1dAH0CLJKqLNl9Te6ihnrQ8/8OhjIna5xw0iEFr9An8VdLfaPu1Dgv2qAnQ==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-community/cli-platform-apple": "18.0.0"
|
"@react-native-community/cli-platform-apple": "18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native-community/cli-server-api": {
|
"node_modules/@react-native-community/cli-server-api": {
|
||||||
"version": "18.0.1",
|
"version": "18.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-18.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-18.0.0.tgz",
|
||||||
"integrity": "sha512-ZRy2IjEM4ljP05bZcnXho0sCxVGI/9SkWkLuzXl+cRu/4I8vLRleihn2GJCopg82QHLLrajUCHhpDKE8NJWcRw==",
|
"integrity": "sha512-tdmGV7ZntYmzrXWheZNpAy6dVI2yrsX4sQH+xAzU7lCfKHk6J8GucxedduXnB5qBB4JgSrrbzg2RLNxv5v0S/Q==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-community/cli-tools": "18.0.1",
|
"@react-native-community/cli-tools": "18.0.0",
|
||||||
"body-parser": "^1.20.3",
|
"body-parser": "^1.20.3",
|
||||||
"compression": "^1.7.1",
|
"compression": "^1.7.1",
|
||||||
"connect": "^3.6.5",
|
"connect": "^3.6.5",
|
||||||
@@ -3106,43 +2962,11 @@
|
|||||||
"ws": "^6.2.3"
|
"ws": "^6.2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native-community/cli-server-api/node_modules/@react-native-community/cli-tools": {
|
|
||||||
"version": "18.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-18.0.1.tgz",
|
|
||||||
"integrity": "sha512-WxWFXwfYhHR2eYiB4lkHZVC/PmIkRWeVHBQKmn0h1mecr3GrHYO4BzW1jpD5Xt6XZ9jojQ9wE5xrCqXjiMSAIQ==",
|
|
||||||
"devOptional": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@vscode/sudo-prompt": "^9.0.0",
|
|
||||||
"appdirsjs": "^1.2.4",
|
|
||||||
"chalk": "^4.1.2",
|
|
||||||
"execa": "^5.0.0",
|
|
||||||
"find-up": "^5.0.0",
|
|
||||||
"launch-editor": "^2.9.1",
|
|
||||||
"mime": "^2.4.1",
|
|
||||||
"ora": "^5.4.1",
|
|
||||||
"prompts": "^2.4.2",
|
|
||||||
"semver": "^7.5.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native-community/cli-server-api/node_modules/semver": {
|
|
||||||
"version": "7.7.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
|
||||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
|
||||||
"devOptional": true,
|
|
||||||
"license": "ISC",
|
|
||||||
"bin": {
|
|
||||||
"semver": "bin/semver.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native-community/cli-tools": {
|
"node_modules/@react-native-community/cli-tools": {
|
||||||
"version": "18.0.0",
|
"version": "18.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-18.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-18.0.0.tgz",
|
||||||
"integrity": "sha512-oR6FcDEcSDYos79vZy4+Tj8jgAE0Xf5HEiRXMJFGISYLRx7tvslSaK8SodUOW9TZe2bCZOb5QSvj8zeMpORmxg==",
|
"integrity": "sha512-oR6FcDEcSDYos79vZy4+Tj8jgAE0Xf5HEiRXMJFGISYLRx7tvslSaK8SodUOW9TZe2bCZOb5QSvj8zeMpORmxg==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vscode/sudo-prompt": "^9.0.0",
|
"@vscode/sudo-prompt": "^9.0.0",
|
||||||
@@ -3161,7 +2985,7 @@
|
|||||||
"version": "7.7.3",
|
"version": "7.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
||||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
@@ -3171,34 +2995,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native-community/cli-types": {
|
"node_modules/@react-native-community/cli-types": {
|
||||||
"version": "18.0.1",
|
"version": "18.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-18.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-18.0.0.tgz",
|
||||||
"integrity": "sha512-pGxr/TSP9Xiw2+9TUn3OWLdcuI4+PJozPsCYZVTGWJ96X6Pv7YX/rNy4emIDkaWaFZ7IWgWXUA725KhEINSf3Q==",
|
"integrity": "sha512-J84+4IRXl8WlVdoe1maTD5skYZZO9CbQ6LNXEHx1kaZcFmvPZKfjsaxuyQ+8BsSqZnM2izOw8dEWnAp/Zuwb0w==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"joi": "^17.2.1"
|
"joi": "^17.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native-community/cli/node_modules/@react-native-community/cli-tools": {
|
|
||||||
"version": "18.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-18.0.1.tgz",
|
|
||||||
"integrity": "sha512-WxWFXwfYhHR2eYiB4lkHZVC/PmIkRWeVHBQKmn0h1mecr3GrHYO4BzW1jpD5Xt6XZ9jojQ9wE5xrCqXjiMSAIQ==",
|
|
||||||
"devOptional": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@vscode/sudo-prompt": "^9.0.0",
|
|
||||||
"appdirsjs": "^1.2.4",
|
|
||||||
"chalk": "^4.1.2",
|
|
||||||
"execa": "^5.0.0",
|
|
||||||
"find-up": "^5.0.0",
|
|
||||||
"launch-editor": "^2.9.1",
|
|
||||||
"mime": "^2.4.1",
|
|
||||||
"ora": "^5.4.1",
|
|
||||||
"prompts": "^2.4.2",
|
|
||||||
"semver": "^7.5.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native-community/cli/node_modules/semver": {
|
"node_modules/@react-native-community/cli/node_modules/semver": {
|
||||||
"version": "7.7.3",
|
"version": "7.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
||||||
@@ -3213,9 +3018,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native-documents/picker": {
|
"node_modules/@react-native-documents/picker": {
|
||||||
"version": "11.0.4",
|
"version": "11.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-documents/picker/-/picker-11.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-documents/picker/-/picker-11.0.3.tgz",
|
||||||
"integrity": "sha512-lbwcBwXMwZ5eTvNI6j/HqPjyB87moRCA8k7EoLCXF4KsLNt2jYDBXkUONX/WcMRMyQEaJPWB77W2zMCcRdX4jw==",
|
"integrity": "sha512-q+vQNT1NtZcFGwsDpTwMKNNcgOEq6foFDGlPQVt8H7KaEjCjC+wTGdXuVSe8JJr2uO9xZR6kJ7aRHReZ4XDRBw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "*",
|
"react": "*",
|
||||||
@@ -3227,6 +3032,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@react-native-masked-view/masked-view/-/masked-view-0.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-masked-view/masked-view/-/masked-view-0.3.2.tgz",
|
||||||
"integrity": "sha512-XwuQoW7/GEgWRMovOQtX3A4PrXhyaZm0lVUiY8qJDvdngjLms9Cpdck6SmGAUNqQwcj2EadHC1HwL0bEyoa/SQ==",
|
"integrity": "sha512-XwuQoW7/GEgWRMovOQtX3A4PrXhyaZm0lVUiY8qJDvdngjLms9Cpdck6SmGAUNqQwcj2EadHC1HwL0bEyoa/SQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": ">=16",
|
"react": ">=16",
|
||||||
"react-native": ">=0.57"
|
"react-native": ">=0.57"
|
||||||
@@ -3657,6 +3463,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.1.26.tgz",
|
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.1.26.tgz",
|
||||||
"integrity": "sha512-RhKmeD0E2ejzKS6z8elAfdfwShpcdkYY8zJzvHYLq+wv183BBcElTeyMLcIX6wIn7QutXeI92Yi21t7aUWfqNQ==",
|
"integrity": "sha512-RhKmeD0E2ejzKS6z8elAfdfwShpcdkYY8zJzvHYLq+wv183BBcElTeyMLcIX6wIn7QutXeI92Yi21t7aUWfqNQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/core": "^7.13.7",
|
"@react-navigation/core": "^7.13.7",
|
||||||
"escape-string-regexp": "^4.0.0",
|
"escape-string-regexp": "^4.0.0",
|
||||||
@@ -3948,6 +3755,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz",
|
||||||
"integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==",
|
"integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.21.3",
|
"@babel/core": "^7.21.3",
|
||||||
"@svgr/babel-preset": "8.1.0",
|
"@svgr/babel-preset": "8.1.0",
|
||||||
@@ -4281,6 +4089,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz",
|
||||||
"integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==",
|
"integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csstype": "^3.2.2"
|
"csstype": "^3.2.2"
|
||||||
}
|
}
|
||||||
@@ -4349,6 +4158,7 @@
|
|||||||
"integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==",
|
"integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/regexpp": "^4.10.0",
|
"@eslint-community/regexpp": "^4.10.0",
|
||||||
"@typescript-eslint/scope-manager": "7.18.0",
|
"@typescript-eslint/scope-manager": "7.18.0",
|
||||||
@@ -4383,6 +4193,7 @@
|
|||||||
"integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==",
|
"integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "7.18.0",
|
"@typescript-eslint/scope-manager": "7.18.0",
|
||||||
"@typescript-eslint/types": "7.18.0",
|
"@typescript-eslint/types": "7.18.0",
|
||||||
@@ -4614,6 +4425,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
@@ -5286,6 +5098,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"baseline-browser-mapping": "^2.9.0",
|
"baseline-browser-mapping": "^2.9.0",
|
||||||
"caniuse-lite": "^1.0.30001759",
|
"caniuse-lite": "^1.0.30001759",
|
||||||
@@ -6611,6 +6424,7 @@
|
|||||||
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
|
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
|
||||||
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
|
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.2.0",
|
"@eslint-community/eslint-utils": "^4.2.0",
|
||||||
"@eslint-community/regexpp": "^4.6.1",
|
"@eslint-community/regexpp": "^4.6.1",
|
||||||
@@ -8809,6 +8623,7 @@
|
|||||||
"integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
|
"integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jest/core": "^29.7.0",
|
"@jest/core": "^29.7.0",
|
||||||
"@jest/types": "^29.6.3",
|
"@jest/types": "^29.6.3",
|
||||||
@@ -11398,6 +11213,7 @@
|
|||||||
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
|
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"prettier": "bin-prettier.js"
|
"prettier": "bin-prettier.js"
|
||||||
},
|
},
|
||||||
@@ -11635,6 +11451,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz",
|
||||||
"integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==",
|
"integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@@ -11699,6 +11516,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.79.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.79.0.tgz",
|
||||||
"integrity": "sha512-fLG/zl/YF30TWTmp2bbo3flHSFGe4WTyVkb7/wJnMEC39jjXVSCxfDtvSUVavhCc03fA/RTkWWvlmg7NEJk7Vg==",
|
"integrity": "sha512-fLG/zl/YF30TWTmp2bbo3flHSFGe4WTyVkb7/wJnMEC39jjXVSCxfDtvSUVavhCc03fA/RTkWWvlmg7NEJk7Vg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jest/create-cache-key-function": "^29.7.0",
|
"@jest/create-cache-key-function": "^29.7.0",
|
||||||
"@react-native/assets-registry": "0.79.0",
|
"@react-native/assets-registry": "0.79.0",
|
||||||
@@ -11780,13 +11598,12 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/react-native-bouncy-checkbox": {
|
"node_modules/react-native-bouncy-checkbox": {
|
||||||
"version": "4.1.3",
|
"version": "4.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-bouncy-checkbox/-/react-native-bouncy-checkbox-4.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-bouncy-checkbox/-/react-native-bouncy-checkbox-4.1.2.tgz",
|
||||||
"integrity": "sha512-duS0gN2FuLpAdEPuurWW3G+f9QhKCQTc9R51aQwPYTT6d01B2lZ/yzyzYbpPAv9SY142oieeUZLufPyjuOx3Ww==",
|
"integrity": "sha512-hB7YwCGTNoMpTPOPiP+RWyQH35S6vxUbc7IGEW/Rqyp7GonEyhtqtthmxiphneRXnywMh8CZwND7OnvppJZscg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@freakycoder/react-native-bounceable": "^1.0.3",
|
"@freakycoder/react-native-bounceable": "^1.0.3"
|
||||||
"react-native-bouncy-checkbox": "^4.1.2"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-native-date-picker": {
|
"node_modules/react-native-date-picker": {
|
||||||
@@ -11804,6 +11621,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.30.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.30.0.tgz",
|
||||||
"integrity": "sha512-5YsnKHGa0X9C8lb5oCnKm0fLUPM6CRduvUUw2Bav4RIj/C3HcFh4RIUnF8wgG6JQWCL1//gRx4v+LVWgcIQdGA==",
|
"integrity": "sha512-5YsnKHGa0X9C8lb5oCnKm0fLUPM6CRduvUUw2Bav4RIj/C3HcFh4RIUnF8wgG6JQWCL1//gRx4v+LVWgcIQdGA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@egjs/hammerjs": "^2.0.17",
|
"@egjs/hammerjs": "^2.0.17",
|
||||||
"hoist-non-react-statics": "^3.3.0",
|
"hoist-non-react-statics": "^3.3.0",
|
||||||
@@ -11865,6 +11683,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz",
|
||||||
"integrity": "sha512-KflAXZcEg54PXkLyflaSZQ3PJp4uC4whM7nT/Uot9m0e/qxFV3p6uor1983D1YOBJbJN7rrWdqIjq0T42jOJyA==",
|
"integrity": "sha512-KflAXZcEg54PXkLyflaSZQ3PJp4uC4whM7nT/Uot9m0e/qxFV3p6uor1983D1YOBJbJN7rrWdqIjq0T42jOJyA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "*",
|
"react": "*",
|
||||||
"react-native": "*"
|
"react-native": "*"
|
||||||
@@ -11938,6 +11757,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.6.2.tgz",
|
||||||
"integrity": "sha512-4XGqMNj5qjUTYywJqpdWZ9IG8jgkS3h06sfVjfw5yZQZfWnRFXczi0GnYyFyCc2EBps/qFmoCH8fez//WumdVg==",
|
"integrity": "sha512-4XGqMNj5qjUTYywJqpdWZ9IG8jgkS3h06sfVjfw5yZQZfWnRFXczi0GnYyFyCc2EBps/qFmoCH8fez//WumdVg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "*",
|
"react": "*",
|
||||||
"react-native": "*"
|
"react-native": "*"
|
||||||
@@ -11948,6 +11768,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.12.0.tgz",
|
||||||
"integrity": "sha512-T2KL6RcDSYDRZswh9glRe600Hvaeq240U21eaqv0uxCNmJz05UeFc4YGQgbFPI8XsakPKx3HjNonItxElFy+QA==",
|
"integrity": "sha512-T2KL6RcDSYDRZswh9glRe600Hvaeq240U21eaqv0uxCNmJz05UeFc4YGQgbFPI8XsakPKx3HjNonItxElFy+QA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react-freeze": "^1.0.0",
|
"react-freeze": "^1.0.0",
|
||||||
"react-native-is-edge-to-edge": "^1.1.7",
|
"react-native-is-edge-to-edge": "^1.1.7",
|
||||||
@@ -11975,6 +11796,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.15.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.15.1.tgz",
|
||||||
"integrity": "sha512-ZUD1xwc3Hwo4cOmOLumjJVoc7lEf9oQFlHnLmgccLC19fNm6LVEdtB+Cnip6gEi0PG3wfvVzskViEtrySQP8Fw==",
|
"integrity": "sha512-ZUD1xwc3Hwo4cOmOLumjJVoc7lEf9oQFlHnLmgccLC19fNm6LVEdtB+Cnip6gEi0PG3wfvVzskViEtrySQP8Fw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"css-select": "^5.1.0",
|
"css-select": "^5.1.0",
|
||||||
"css-tree": "^1.1.3",
|
"css-tree": "^1.1.3",
|
||||||
@@ -12082,6 +11904,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
|
||||||
"integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
|
"integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/use-sync-external-store": "^0.0.6",
|
"@types/use-sync-external-store": "^0.0.6",
|
||||||
"use-sync-external-store": "^1.4.0"
|
"use-sync-external-store": "^1.4.0"
|
||||||
@@ -12142,7 +11965,8 @@
|
|||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
|
||||||
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
|
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/redux-persist": {
|
"node_modules/redux-persist": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
@@ -13619,6 +13443,7 @@
|
|||||||
"integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
|
"integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
|
|||||||
+1
-2
@@ -20,7 +20,7 @@ export const apiCall = async <R, D = {}>(
|
|||||||
data,
|
data,
|
||||||
params,
|
params,
|
||||||
// withCredentials: true,
|
// withCredentials: true,
|
||||||
baseURL: Variable.Main_Base,
|
// baseURL: Variable.Main_Base,
|
||||||
headers: {
|
headers: {
|
||||||
Authentication: `Bearer ${token?.token}`,
|
Authentication: `Bearer ${token?.token}`,
|
||||||
'Content-Type': contentType || 'application/json',
|
'Content-Type': contentType || 'application/json',
|
||||||
@@ -31,7 +31,6 @@ export const apiCall = async <R, D = {}>(
|
|||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const errorMessage = error?.response?.data?.error;
|
const errorMessage = error?.response?.data?.error;
|
||||||
{ error?.response?.data?.error && showErrorAlert(error?.response?.data?.error || '') }
|
{ error?.response?.data?.error && showErrorAlert(error?.response?.data?.error || '') }
|
||||||
console.log(errorMessage, '---------------url error');
|
|
||||||
|
|
||||||
if (error?.response?.status === 401) {
|
if (error?.response?.status === 401) {
|
||||||
store.dispatch(setToken({}));
|
store.dispatch(setToken({}));
|
||||||
|
|||||||
@@ -2,12 +2,15 @@ import React, { useEffect, useState, useCallback } from 'react';
|
|||||||
import { View, Text, StyleSheet } from 'react-native';
|
import { View, Text, StyleSheet } from 'react-native';
|
||||||
import colors from '../../Constant/Color';
|
import colors from '../../Constant/Color';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import LottieView from 'lottie-react-native';
|
||||||
|
|
||||||
interface CountdownTimerProps {
|
interface CountdownTimerProps {
|
||||||
endDate: string; // Expected format: "DD-MM-YYYY HH:mm:ss"
|
endDate: string;
|
||||||
|
myStyle?: any
|
||||||
|
size?: number // Expected format: "DD-MM-YYYY HH:mm:ss"
|
||||||
}
|
}
|
||||||
|
|
||||||
const CountdownTimer: React.FC<CountdownTimerProps> = React.memo(({ endDate }) => {
|
const CountdownTimer: React.FC<CountdownTimerProps> = React.memo(({ endDate, myStyle = {}, size = 20 }) => {
|
||||||
const calculateTimeLeft = useCallback(() => {
|
const calculateTimeLeft = useCallback(() => {
|
||||||
if (!endDate) return null;
|
if (!endDate) return null;
|
||||||
|
|
||||||
@@ -43,8 +46,14 @@ const CountdownTimer: React.FC<CountdownTimerProps> = React.memo(({ endDate }) =
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.timerText}>
|
<LottieView
|
||||||
{timeLeft.days}d {timeLeft.hours}h {timeLeft.minutes}m {timeLeft.seconds}s
|
source={require('../../lottie/clock.json')}
|
||||||
|
autoPlay
|
||||||
|
loop={true}
|
||||||
|
style={{ width: size, height: size, }}
|
||||||
|
/>
|
||||||
|
<Text style={[styles.timerText, myStyle]}>
|
||||||
|
{timeLeft.days}D {timeLeft.hours}H {timeLeft.minutes}M {timeLeft.seconds}S
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
@@ -58,15 +67,18 @@ const styles = StyleSheet.create({
|
|||||||
paddingVertical: 5,
|
paddingVertical: 5,
|
||||||
paddingHorizontal: 10,
|
paddingHorizontal: 10,
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
borderColor: colors.primary,
|
borderColor: colors.black,
|
||||||
borderRadius: 25,
|
borderRadius: 25,
|
||||||
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
|
|
||||||
},
|
},
|
||||||
timerText: {
|
timerText: {
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
color: colors.primary,
|
color: colors.black,
|
||||||
|
paddingLeft: 5
|
||||||
},
|
},
|
||||||
expiredText: {
|
expiredText: {
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ const InsideHeader: React.FC<HeaderProps> = ({ title, showArrow = false }) => {
|
|||||||
<Text style={styles.title}>{title}</Text>
|
<Text style={styles.title}>{title}</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<TouchableOpacity onPress={() => { navigation.navigate(NavigationString.Emd) }}>
|
<TouchableOpacity onPress={() => { navigation.navigate(NavigationString.Home) }}>
|
||||||
<Image
|
<Image
|
||||||
source={ImagePath.Icon.Logo2}
|
source={ImagePath.Icon.Logo2}
|
||||||
style={styles.logo}
|
style={styles.logo}
|
||||||
|
|||||||
@@ -0,0 +1,122 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Modal,
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TouchableOpacity,
|
||||||
|
StyleSheet,
|
||||||
|
Pressable,
|
||||||
|
} from 'react-native';
|
||||||
|
|
||||||
|
type ConfirmDialogProps = {
|
||||||
|
visible: boolean;
|
||||||
|
title?: string;
|
||||||
|
message: string;
|
||||||
|
confirmText?: string;
|
||||||
|
cancelText?: string;
|
||||||
|
onConfirm: () => void;
|
||||||
|
onClose: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ConfirmDialog: React.FC<ConfirmDialogProps> = ({
|
||||||
|
visible,
|
||||||
|
title = 'Confirm',
|
||||||
|
message,
|
||||||
|
confirmText = 'Confirm',
|
||||||
|
cancelText = 'Cancel',
|
||||||
|
onConfirm,
|
||||||
|
onClose,
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
visible={visible}
|
||||||
|
transparent
|
||||||
|
animationType="fade"
|
||||||
|
statusBarTranslucent
|
||||||
|
onRequestClose={onClose}
|
||||||
|
>
|
||||||
|
{/* Overlay (click to close) */}
|
||||||
|
<Pressable style={styles.overlay} onPress={onClose}>
|
||||||
|
{/* Stop propagation */}
|
||||||
|
<Pressable style={styles.container}>
|
||||||
|
{/* Title */}
|
||||||
|
<Text style={styles.title}>{title}</Text>
|
||||||
|
|
||||||
|
{/* Message */}
|
||||||
|
<Text style={styles.message}>{message}</Text>
|
||||||
|
|
||||||
|
{/* Actions */}
|
||||||
|
<View style={styles.actions}>
|
||||||
|
<TouchableOpacity style={styles.cancelBtn} onPress={onClose}>
|
||||||
|
<Text style={styles.cancelText}>{cancelText}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.confirmBtn}
|
||||||
|
onPress={() => {
|
||||||
|
onConfirm();
|
||||||
|
onClose();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={styles.confirmText}>{confirmText}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</Pressable>
|
||||||
|
</Pressable>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ConfirmDialog;
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
overlay: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
width: '85%',
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
borderRadius: 12,
|
||||||
|
padding: 20,
|
||||||
|
elevation: 5,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: '600',
|
||||||
|
marginBottom: 8,
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
fontSize: 15,
|
||||||
|
color: '#444',
|
||||||
|
textAlign: 'center',
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'flex-end',
|
||||||
|
},
|
||||||
|
cancelBtn: {
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
cancelText: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: '#666',
|
||||||
|
},
|
||||||
|
confirmBtn: {
|
||||||
|
backgroundColor: '#1f4b6dff',
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingHorizontal: 18,
|
||||||
|
borderRadius: 6,
|
||||||
|
},
|
||||||
|
confirmText: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: '500',
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -12,6 +12,8 @@ const NavigationString = {
|
|||||||
Emd: 'Emd',
|
Emd: 'Emd',
|
||||||
StartBidding: 'StartBidding',
|
StartBidding: 'StartBidding',
|
||||||
PurchaseAuctionList:'PurchaseAuctionList',
|
PurchaseAuctionList:'PurchaseAuctionList',
|
||||||
|
StartReverseBidding:'StartReverseBidding'
|
||||||
|
PurchaseAuctionList:'PurchaseAuctionList',
|
||||||
// tender
|
// tender
|
||||||
PurchaseTenderList:'PurchaseTenderList',
|
PurchaseTenderList:'PurchaseTenderList',
|
||||||
ProceedToPurTender:'ProceedToPurTender',
|
ProceedToPurTender:'ProceedToPurTender',
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ export default function MainStack() {
|
|||||||
<Stack.Screen name={NavigationString.ProceedToPurTender} component={Screens.ProceedToPurTender} options={option} />
|
<Stack.Screen name={NavigationString.ProceedToPurTender} component={Screens.ProceedToPurTender} options={option} />
|
||||||
<Stack.Screen name={NavigationString.TenderBidding} component={Screens.TenderBidding} options={option} />
|
<Stack.Screen name={NavigationString.TenderBidding} component={Screens.TenderBidding} options={option} />
|
||||||
<Stack.Screen name={NavigationString.ProceedToBidDetail} component={Screens.ProceedToBidDetail} options={option} />
|
<Stack.Screen name={NavigationString.ProceedToBidDetail} component={Screens.ProceedToBidDetail} options={option} />
|
||||||
|
<Stack.Screen name={NavigationString.StartReverseBidding} component={Screens.StartReverseBidding} options={option} />
|
||||||
|
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,17 +1,7 @@
|
|||||||
import React, { useState, useRef } from 'react';
|
import React, { useState, useRef } from 'react';
|
||||||
import {
|
import { View, Text, StyleSheet, TouchableOpacity, Animated, Dimensions } from 'react-native';
|
||||||
View,
|
|
||||||
Text,
|
|
||||||
StyleSheet,
|
|
||||||
TouchableOpacity,
|
|
||||||
Animated,
|
|
||||||
Dimensions,
|
|
||||||
} from 'react-native';
|
|
||||||
import { InsideHeader } from '../../Component/Index';
|
import { InsideHeader } from '../../Component/Index';
|
||||||
import {
|
import { useFetchLiveAuction, useFetchPurchaseAuction } from '../../Services/BBPS/Hooks';
|
||||||
useFetchLiveAuction,
|
|
||||||
useFetchPurchaseAuction,
|
|
||||||
} from '../../Services/BBPS/Hooks';
|
|
||||||
import colors from '../../Constant/Color';
|
import colors from '../../Constant/Color';
|
||||||
import LiveAuction from './LiveAuction';
|
import LiveAuction from './LiveAuction';
|
||||||
import PurchaseAuction from './PurchaseAuction';
|
import PurchaseAuction from './PurchaseAuction';
|
||||||
@@ -20,7 +10,6 @@ import { useNavigation } from '@react-navigation/native';
|
|||||||
import NavigationString from '../../Constant/NavigationString';
|
import NavigationString from '../../Constant/NavigationString';
|
||||||
import FontsFamily from '../../Constant/FontsFamily';
|
import FontsFamily from '../../Constant/FontsFamily';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
const { width } = Dimensions.get('screen')
|
|
||||||
const TAB_WIDTH = 140;
|
const TAB_WIDTH = 140;
|
||||||
const TAB_HEIGHT = 44;
|
const TAB_HEIGHT = 44;
|
||||||
|
|
||||||
@@ -30,7 +19,6 @@ const Auction = () => {
|
|||||||
const { data: purchaseAuctionData = {} } = useFetchPurchaseAuction();
|
const { data: purchaseAuctionData = {} } = useFetchPurchaseAuction();
|
||||||
const SelectedPurchaseList = useSelector((state: any) => state.selectPurchaseAuction);
|
const SelectedPurchaseList = useSelector((state: any) => state.selectPurchaseAuction);
|
||||||
|
|
||||||
|
|
||||||
const liveCount = Array.isArray(liveAuctionData?.result)
|
const liveCount = Array.isArray(liveAuctionData?.result)
|
||||||
? liveAuctionData?.pages[0]?.totalCount
|
? liveAuctionData?.pages[0]?.totalCount
|
||||||
: 0;
|
: 0;
|
||||||
@@ -101,7 +89,7 @@ const Auction = () => {
|
|||||||
</View>
|
</View>
|
||||||
{/* Cart */}
|
{/* Cart */}
|
||||||
<View>
|
<View>
|
||||||
{SelectedPurchaseList.length && <View style={{ borderWidth: 2, borderColor: colors.white, backgroundColor: colors.primaryLight, position: 'absolute', borderRadius: 50, zIndex: 20, right: 0, top: -10, paddingHorizontal:2 }}>
|
{SelectedPurchaseList.length && <View style={{ borderWidth: 2, borderColor: colors.white, backgroundColor: colors.primaryLight, position: 'absolute', borderRadius: 50, zIndex: 20, right: 0, top: -10, paddingHorizontal: 2 }}>
|
||||||
<Text style={{ fontSize: 12, color: colors.black }}>{SelectedPurchaseList.length}</Text>
|
<Text style={{ fontSize: 12, color: colors.black }}>{SelectedPurchaseList.length}</Text>
|
||||||
</View>}
|
</View>}
|
||||||
<TouchableOpacity style={{ padding: 10, backgroundColor: colors.primaryLight, borderRadius: 20 }} onPress={() => { Navigation.navigate(NavigationString.PurchaseList) }}>
|
<TouchableOpacity style={{ padding: 10, backgroundColor: colors.primaryLight, borderRadius: 20 }} onPress={() => { Navigation.navigate(NavigationString.PurchaseList) }}>
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ import { Skelton } from '../../Component/Index';
|
|||||||
import colors from '../../Constant/Color';
|
import colors from '../../Constant/Color';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { selectPurchaseAuctionSlice, togglePurchaseAuction } from '../../Redux/Slices/selectPurchaseAuction';
|
import { selectPurchaseAuctionSlice, togglePurchaseAuction } from '../../Redux/Slices/selectPurchaseAuction';
|
||||||
|
import { apiCall } from '../../Axios/Axios';
|
||||||
|
import { GET_MY_AUCTION, LIVE_AUCTION } from '../../Services/BBPS/ApiUrls';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
const LiveAuction = () => {
|
const LiveAuction = () => {
|
||||||
const navigation: any = useNavigation();
|
const navigation: any = useNavigation();
|
||||||
@@ -16,6 +19,7 @@ const LiveAuction = () => {
|
|||||||
const SelectedPurchaseList = useSelector((state: any) => state.selectPurchaseAuction);
|
const SelectedPurchaseList = useSelector((state: any) => state.selectPurchaseAuction);
|
||||||
const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading, isRefetching, refetch }: any = useFetchLiveAuction();
|
const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading, isRefetching, refetch }: any = useFetchLiveAuction();
|
||||||
const [showRefreshBanner, setShowRefreshBanner] = useState(false);
|
const [showRefreshBanner, setShowRefreshBanner] = useState(false);
|
||||||
|
const [allBoolean, setAllBoolean] = useState({ liveAuctionData: [] })
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isRefetching) {
|
if (isRefetching) {
|
||||||
@@ -64,6 +68,39 @@ const LiveAuction = () => {
|
|||||||
[SelectedPurchaseList]
|
[SelectedPurchaseList]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const getMyAuction = async () => {
|
||||||
|
try {
|
||||||
|
|
||||||
|
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), // false if match, true otherwise
|
||||||
|
}));
|
||||||
|
|
||||||
|
setAllBoolean(prev => ({
|
||||||
|
...prev,
|
||||||
|
liveAuctionData: filteredLive
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('getMyAuction error', error);
|
||||||
|
} finally {
|
||||||
|
setAllBoolean(prev => ({ ...prev, isLoading: false }));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (data?.result?.length > 0) {
|
||||||
|
getMyAuction()
|
||||||
|
}
|
||||||
|
}, [data])
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return <Skelton />;
|
return <Skelton />;
|
||||||
}
|
}
|
||||||
@@ -110,8 +147,8 @@ const LiveAuction = () => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<FlatList
|
<FlatList
|
||||||
data={data?.result ?? []}
|
data={allBoolean.liveAuctionData ?? []}
|
||||||
keyExtractor={(item) => String(item.auctionId)}
|
keyExtractor={(item: any) => String(item.auctionNumber)}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
showsVerticalScrollIndicator={false}
|
showsVerticalScrollIndicator={false}
|
||||||
contentContainerStyle={{ paddingBottom: 50, paddingTop: 10 }}
|
contentContainerStyle={{ paddingBottom: 50, paddingTop: 10 }}
|
||||||
|
|||||||
@@ -22,89 +22,93 @@ const LiveAuctionTile: React.FC<LiveAuctionTileProps> = ({
|
|||||||
return (
|
return (
|
||||||
<View style={styles.cardWrapper}>
|
<View style={styles.cardWrapper}>
|
||||||
{/* Status Tag */}
|
{/* Status Tag */}
|
||||||
<View
|
|
||||||
style={[
|
|
||||||
styles.statusTag,
|
|
||||||
{ backgroundColor: isPurchased ? colors.error : purchaseEnded ? '#94a3b8' : '#4ade80' },
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TouchableOpacity
|
{
|
||||||
style={styles.container}
|
!showDetail ?
|
||||||
activeOpacity={0.9}
|
<>
|
||||||
onPress={() => setShowDetail(true)}
|
<View
|
||||||
>
|
|
||||||
{/* Header */}
|
|
||||||
<View style={styles.header}>
|
|
||||||
<View style={styles.badge}>
|
|
||||||
<Tag size={14} color={colors.primary} />
|
|
||||||
<Text style={styles.badgeText}>#{auctionNumber}</Text>
|
|
||||||
</View>
|
|
||||||
<Text style={styles.priceText}>₹{auctionFees}</Text>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
{/* Work Title */}
|
|
||||||
<Text style={styles.workTitle} numberOfLines={2}>
|
|
||||||
{auctionOfWork ?? 'General Auction Work'}
|
|
||||||
</Text>
|
|
||||||
|
|
||||||
{/* Info Grid */}
|
|
||||||
<View style={styles.infoGrid}>
|
|
||||||
<View style={styles.infoItem}>
|
|
||||||
<Calendar size={16} color="#64748b" />
|
|
||||||
<View style={styles.infoTextGroup}>
|
|
||||||
<Text style={styles.infoLabel}>Start</Text>
|
|
||||||
<Text style={styles.infoValue}>{auctionDispatchDate ?? '-'}</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View style={styles.infoItem}>
|
|
||||||
<Calendar size={16} color={purchaseEnded ? "#ef4444" : "#22c55e"} />
|
|
||||||
<View style={styles.infoTextGroup}>
|
|
||||||
<Text style={styles.infoLabel}>Deadline</Text>
|
|
||||||
<Text style={[styles.infoValue, purchaseEnded && { color: '#ef4444' }]}>
|
|
||||||
{moment(purchaseEnd, 'DD-MM-YYYY HH:mm:ss').format('DD MMM, YY')}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
{/* Action Bar */}
|
|
||||||
<View style={styles.actionBar}>
|
|
||||||
<TouchableOpacity style={styles.iconBtn} onPress={() => setShowDetail(true)}>
|
|
||||||
<Info size={18} color={colors.primary} />
|
|
||||||
<Text style={styles.iconBtnText}>Details</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
|
|
||||||
<TouchableOpacity
|
|
||||||
style={[
|
|
||||||
styles.mainButton,
|
|
||||||
purchaseEnded
|
|
||||||
? styles.btnDisabled
|
|
||||||
: isPurchased
|
|
||||||
? styles.btnPurchased
|
|
||||||
: styles.btnActive,
|
|
||||||
]}
|
|
||||||
onPress={onPurchasePress}
|
|
||||||
disabled={purchaseEnded}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
style={[
|
style={[
|
||||||
styles.mainButtonText,
|
styles.statusTag,
|
||||||
isPurchased && !purchaseEnded ? { color: colors.white } : { color: '#fff' },
|
{ backgroundColor: isPurchased ? colors.error : purchaseEnded ? '#94a3b8' : '#4ade80' },
|
||||||
]}
|
]}
|
||||||
|
/>
|
||||||
|
<View
|
||||||
|
style={styles.container}
|
||||||
>
|
>
|
||||||
{purchaseEnded ? 'Expired' : isPurchased ? 'Remove' : 'Add to Cart'}
|
{/* Header */}
|
||||||
</Text>
|
<View style={styles.header}>
|
||||||
{!purchaseEnded && (
|
<TouchableOpacity style={styles.badge} onPress={() => setShowDetail(true)}>
|
||||||
<ArrowRight size={16} color={isPurchased ? colors.white : '#fff'} />
|
<Tag size={14} color={colors.primary} />
|
||||||
)}
|
<Text style={styles.badgeText}>#{auctionNumber}</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
<Text style={styles.priceText}>₹{auctionFees}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Work Title */}
|
||||||
|
<Text style={styles.workTitle} numberOfLines={2}>
|
||||||
|
{auctionOfWork ?? 'General Auction Work'}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
{/* Info Grid */}
|
||||||
|
<View style={styles.infoGrid}>
|
||||||
|
<View style={styles.infoItem}>
|
||||||
|
<Calendar size={16} color="#64748b" />
|
||||||
|
<View style={styles.infoTextGroup}>
|
||||||
|
<Text style={styles.infoLabel}>Start</Text>
|
||||||
|
<Text style={styles.infoValue}>{auctionDispatchDate ?? '-'}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.infoItem}>
|
||||||
|
<Calendar size={16} color={purchaseEnded ? "#ef4444" : "#22c55e"} />
|
||||||
|
<View style={styles.infoTextGroup}>
|
||||||
|
<Text style={styles.infoLabel}>Deadline</Text>
|
||||||
|
<Text style={[styles.infoValue, purchaseEnded && { color: '#ef4444' }]}>
|
||||||
|
{moment(purchaseEnd, 'DD-MM-YYYY HH:mm:ss').format('DD MMM, YY')}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Action Bar */}
|
||||||
|
<View style={styles.actionBar}>
|
||||||
|
<TouchableOpacity style={styles.iconBtn} onPress={() => setShowDetail(true)}>
|
||||||
|
<Info size={18} color={colors.primary} />
|
||||||
|
<Text style={styles.iconBtnText}>Details</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.mainButton,
|
||||||
|
purchaseEnded
|
||||||
|
? styles.btnDisabled
|
||||||
|
: !data.active ? { backgroundColor: 'lightgray' } : isPurchased
|
||||||
|
? styles.btnPurchased
|
||||||
|
: styles.btnActive,
|
||||||
|
]}
|
||||||
|
onPress={onPurchasePress}
|
||||||
|
disabled={purchaseEnded ? true : data.active ? false : true}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.mainButtonText,
|
||||||
|
isPurchased && !purchaseEnded ? { color: colors.white } : { color: '#fff' },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{purchaseEnded ? 'Expired' : !data.active ? 'Purchased' : isPurchased ? 'Remove' : 'Add to Cart'}
|
||||||
|
</Text>
|
||||||
|
{!purchaseEnded && (
|
||||||
|
<ArrowRight size={16} color={isPurchased ? colors.white : '#fff'} />
|
||||||
|
)}
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Auction Detail Modal */}
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
: <AuctionDetail visible={showDetail} data={data} onClose={() => setShowDetail(false)} />
|
||||||
|
}
|
||||||
|
|
||||||
{/* Auction Detail Modal */}
|
|
||||||
<AuctionDetail visible={showDetail} data={data} onClose={() => setShowDetail(false)} />
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,30 +1,8 @@
|
|||||||
import React, { memo, useState } from 'react';
|
import React, { memo, useState } from 'react';
|
||||||
import {
|
import { View, Text, StyleSheet, TouchableOpacity, ScrollView, SafeAreaView, Platform, StatusBar } from 'react-native';
|
||||||
View,
|
|
||||||
Text,
|
|
||||||
StyleSheet,
|
|
||||||
TouchableOpacity,
|
|
||||||
ScrollView,
|
|
||||||
SafeAreaView,
|
|
||||||
Platform,
|
|
||||||
StatusBar,
|
|
||||||
} from 'react-native';
|
|
||||||
import Modal from 'react-native-modal';
|
import Modal from 'react-native-modal';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import {
|
import { Briefcase, Calendar, FileText, Download, Eye, Layers, ArrowLeft, Clock } from 'lucide-react-native';
|
||||||
X,
|
|
||||||
Hash,
|
|
||||||
Briefcase,
|
|
||||||
Calendar,
|
|
||||||
CreditCard,
|
|
||||||
FileText,
|
|
||||||
Download,
|
|
||||||
Eye,
|
|
||||||
Layers,
|
|
||||||
ArrowLeft,
|
|
||||||
Info,
|
|
||||||
Clock
|
|
||||||
} from 'lucide-react-native';
|
|
||||||
import colors from '../../../Constant/Color';
|
import colors from '../../../Constant/Color';
|
||||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
import AuctionItemDetail from './AuctionItemDetail';
|
import AuctionItemDetail from './AuctionItemDetail';
|
||||||
@@ -69,13 +47,15 @@ const AuctionFullDetail: React.FC<Props> = ({ visible, onClose, data }) => {
|
|||||||
<Modal
|
<Modal
|
||||||
isVisible={visible}
|
isVisible={visible}
|
||||||
style={styles.fullModal}
|
style={styles.fullModal}
|
||||||
animationIn="slideInRight"
|
animationIn="fadeIn"
|
||||||
animationOut="slideOutRight"
|
animationOut="fadeOut"
|
||||||
useNativeDriver
|
animationInTiming={360}
|
||||||
hideModalContentWhileAnimating
|
animationOutTiming={280}
|
||||||
statusBarTranslucent
|
statusBarTranslucent
|
||||||
|
backdropColor="transparent"
|
||||||
|
backdropOpacity={0}
|
||||||
>
|
>
|
||||||
<SafeAreaView style={styles.safeArea}>
|
<View style={styles.safeArea}>
|
||||||
<StatusBar barStyle="dark-content" />
|
<StatusBar barStyle="dark-content" />
|
||||||
|
|
||||||
{/* Full Header */}
|
{/* Full Header */}
|
||||||
@@ -191,23 +171,25 @@ const AuctionFullDetail: React.FC<Props> = ({ visible, onClose, data }) => {
|
|||||||
</Text>
|
</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
<AuctionItemDetail data={{
|
|
||||||
productName: "sick sari",
|
<AuctionItemDetail
|
||||||
timeDuration: "112 YEAR",
|
data={{
|
||||||
category: "laundry",
|
productName: "sick sari",
|
||||||
subCategory: "sari",
|
timeDuration: "112 YEAR",
|
||||||
reservePriceFig: "120000",
|
category: "laundry",
|
||||||
reservePriceWords: "One Lakh Twenty Thousand",
|
subCategory: "sari",
|
||||||
auctionStartFig: "120000",
|
reservePriceFig: "120000",
|
||||||
auctionStartWords: "One Lakh Twenty Thousand",
|
reservePriceWords: "One Lakh Twenty Thousand",
|
||||||
bidVariationFig: "200",
|
auctionStartFig: "120000",
|
||||||
bidVariationWords: "Two Hundred",
|
auctionStartWords: "One Lakh Twenty Thousand",
|
||||||
emdFig: "2000",
|
bidVariationFig: "200",
|
||||||
emdWords: "Two Thousand",
|
bidVariationWords: "Two Hundred",
|
||||||
description: "Auction of cars",
|
emdFig: "2000",
|
||||||
documentName: "BBPS screens.pdf"
|
emdWords: "Two Thousand",
|
||||||
}} onClose={() => { setAllBoolean((prev: any) => ({ ...prev, showItemDetail: false })) }} visible={allBoolean.showItemDetail} />
|
description: "Auction of cars",
|
||||||
</SafeAreaView>
|
documentName: "BBPS screens.pdf"
|
||||||
|
}} onClose={() => { setAllBoolean((prev: any) => ({ ...prev, showItemDetail: false })) }} visible={allBoolean.showItemDetail} />
|
||||||
|
</View>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -79,13 +79,16 @@ const AuctionItemDetail: React.FC<Props> = ({ visible, onClose, data = ITEM_DUMM
|
|||||||
<Modal
|
<Modal
|
||||||
isVisible={visible}
|
isVisible={visible}
|
||||||
style={styles.fullModal}
|
style={styles.fullModal}
|
||||||
animationIn="slideInUp"
|
animationIn="fadeIn"
|
||||||
animationOut="slideOutDown"
|
animationOut="fadeOut"
|
||||||
backdropOpacity={1}
|
animationInTiming={360}
|
||||||
useNativeDriver
|
animationOutTiming={280}
|
||||||
statusBarTranslucent
|
statusBarTranslucent
|
||||||
|
backdropColor="transparent"
|
||||||
|
backdropOpacity={0}
|
||||||
|
useNativeDriver
|
||||||
>
|
>
|
||||||
<SafeAreaView style={styles.safeArea}>
|
<View style={styles.safeArea}>
|
||||||
|
|
||||||
{/* Navbar */}
|
{/* Navbar */}
|
||||||
<View style={[styles.header, { paddingTop: inset.top }]}>
|
<View style={[styles.header, { paddingTop: inset.top }]}>
|
||||||
@@ -171,7 +174,7 @@ const AuctionItemDetail: React.FC<Props> = ({ visible, onClose, data = ITEM_DUMM
|
|||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</SafeAreaView>
|
</View>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { SearchInput } from '../../Component/Serach/SeacrhInput';
|
|||||||
import { Skelton } from '../../Component/Index';
|
import { Skelton } from '../../Component/Index';
|
||||||
import { allBooleanProps } from './types/types';
|
import { allBooleanProps } from './types/types';
|
||||||
import FilterModal from './Modal/FilterModal';
|
import FilterModal from './Modal/FilterModal';
|
||||||
|
import NavigationString from '../../Constant/NavigationString';
|
||||||
|
|
||||||
|
|
||||||
const PurchaseAuction = () => {
|
const PurchaseAuction = () => {
|
||||||
@@ -51,11 +52,10 @@ const PurchaseAuction = () => {
|
|||||||
<PurchaseAuctionTile
|
<PurchaseAuctionTile
|
||||||
item={item}
|
item={item}
|
||||||
onPressDetails={() => {
|
onPressDetails={() => {
|
||||||
navigation.navigate('AuctionDetail', { item, onAddToPurchase: () => { }, routeFrom: 'PurchasedAuction' });
|
|
||||||
}}
|
}}
|
||||||
onStartBidding={() => {
|
onStartBidding={() => {
|
||||||
Dispatch(setAuction(item))
|
Dispatch(setAuction(item))
|
||||||
// navigation.navigate(NavigationString, { data: item })
|
navigation.navigate(NavigationString.Emd)
|
||||||
}}
|
}}
|
||||||
buttonEnable={isAuctionActive(item)}
|
buttonEnable={isAuctionActive(item)}
|
||||||
isAuctionEnd={isAuctionEnd(item)}
|
isAuctionEnd={isAuctionEnd(item)}
|
||||||
|
|||||||
@@ -3,8 +3,12 @@ import { View, Text, FlatList, StyleSheet, TouchableOpacity, Alert } from 'react
|
|||||||
import { InsideHeader, Loader } from '../../Component/Index';
|
import { InsideHeader, Loader } from '../../Component/Index';
|
||||||
import colors from '../../Constant/Color';
|
import colors from '../../Constant/Color';
|
||||||
import { CreditCard, Calendar, User, DollarSign, ArrowRight } from 'lucide-react-native';
|
import { CreditCard, Calendar, User, DollarSign, ArrowRight } from 'lucide-react-native';
|
||||||
import { useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { useOfflineAuctionPurchase } from '../../Services/BBPS/Hooks';
|
import { useOfflineAuctionPurchase } from '../../Services/BBPS/Hooks';
|
||||||
|
import { showSuccessAlert } from '../../Constant/ShowDailog';
|
||||||
|
import { clearPurchaseAuction } from '../../Redux/Slices/selectPurchaseAuction';
|
||||||
|
import { CommonActions, useNavigation } from '@react-navigation/native';
|
||||||
|
import NavigationString from '../../Constant/NavigationString';
|
||||||
|
|
||||||
const dummyAuctionList = [
|
const dummyAuctionList = [
|
||||||
{
|
{
|
||||||
@@ -46,6 +50,8 @@ const dummyAuctionList = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const PurchaseAuctionList = () => {
|
const PurchaseAuctionList = () => {
|
||||||
|
const Navigation = useNavigation()
|
||||||
|
const Dispatch = useDispatch()
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [list, setList] = useState(dummyAuctionList);
|
const [list, setList] = useState(dummyAuctionList);
|
||||||
const SelectedPurchaseList = useSelector((state: any) => state.selectPurchaseAuction);
|
const SelectedPurchaseList = useSelector((state: any) => state.selectPurchaseAuction);
|
||||||
@@ -81,7 +87,16 @@ const PurchaseAuctionList = () => {
|
|||||||
try {
|
try {
|
||||||
mutate(body, {
|
mutate(body, {
|
||||||
onSuccess: (res) => {
|
onSuccess: (res) => {
|
||||||
console.log(res, '---------------------purchsase response');
|
if (res.statusCode == 200) {
|
||||||
|
showSuccessAlert(res.message)
|
||||||
|
Dispatch(clearPurchaseAuction())
|
||||||
|
Navigation.dispatch(
|
||||||
|
CommonActions.reset({
|
||||||
|
index: 0,
|
||||||
|
routes: [{ name: NavigationString.Home }],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.log(error, "================purchse Error");
|
console.log(error, "================purchse Error");
|
||||||
@@ -165,16 +180,16 @@ const PurchaseAuctionList = () => {
|
|||||||
style={[styles.button, { marginLeft: 8 }]}
|
style={[styles.button, { marginLeft: 8 }]}
|
||||||
onPress={() => handlePurchase('offline')}
|
onPress={() => handlePurchase('offline')}
|
||||||
>
|
>
|
||||||
<Text style={styles.buttonText}>Purchase Offline</Text>
|
{
|
||||||
<ArrowRight size={18} color="#fff" style={{ marginLeft: 6 }} />
|
isPending ? <Loader size='small' color={colors.white} /> : <>
|
||||||
|
<Text style={styles.buttonText}>Purchase Offline</Text>
|
||||||
|
<ArrowRight size={18} color="#fff" style={{ marginLeft: 6 }} />
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{loading && (
|
|
||||||
<View style={styles.loadingOverlay}>
|
|
||||||
<Loader />
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,28 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import { View, Text, StyleSheet, TouchableOpacity, Platform } from 'react-native';
|
||||||
View,
|
import Animated, { FadeInUp, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
|
||||||
Text,
|
|
||||||
StyleSheet,
|
|
||||||
TouchableOpacity,
|
|
||||||
Platform,
|
|
||||||
} from 'react-native';
|
|
||||||
import Animated, {
|
|
||||||
FadeInUp,
|
|
||||||
useAnimatedStyle,
|
|
||||||
useSharedValue,
|
|
||||||
withTiming,
|
|
||||||
} from 'react-native-reanimated';
|
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import CountdownTimer from '../../Component/Counter/CountdownTimer';
|
import CountdownTimer from '../../Component/Counter/CountdownTimer';
|
||||||
import colors from '../../Constant/Color';
|
import colors from '../../Constant/Color';
|
||||||
|
import AuctionDetail from './Modal/AuctionDetail';
|
||||||
|
|
||||||
const PurchaseAuctionTile = ({
|
const PurchaseAuctionTile = ({ item, onPressDetails, onStartBidding, buttonEnable, isAuctionEnd }: any) => {
|
||||||
item,
|
const [showDetail, setShowDetail] = React.useState(false);
|
||||||
onPressDetails,
|
|
||||||
onStartBidding,
|
|
||||||
buttonEnable,
|
|
||||||
isAuctionEnd,
|
|
||||||
}: any) => {
|
|
||||||
const scale = useSharedValue(1);
|
const scale = useSharedValue(1);
|
||||||
const elevation = useSharedValue(8);
|
const elevation = useSharedValue(8);
|
||||||
|
|
||||||
@@ -43,232 +28,237 @@ const PurchaseAuctionTile = ({
|
|||||||
elevation.value = withTiming(8, { duration: 160 });
|
elevation.value = withTiming(8, { duration: 160 });
|
||||||
};
|
};
|
||||||
|
|
||||||
const statusColor = isAuctionEnd
|
const statusColor = isAuctionEnd ? '#EF4444' : buttonEnable ? colors.primary : '#94A3B8';
|
||||||
? '#EF4444'
|
|
||||||
: buttonEnable
|
|
||||||
? colors.primary
|
|
||||||
: '#94A3B8';
|
|
||||||
|
|
||||||
const lightStatusBg = isAuctionEnd
|
const lightStatusBg = isAuctionEnd ? '#FEF2F2' : buttonEnable ? '#EFF6FF' : '#F8FAFC';
|
||||||
? '#FEF2F2'
|
console.log(item?.keyDates?.auctionBidding?.endDateTime, 'kk');
|
||||||
: buttonEnable
|
|
||||||
? '#EFF6FF'
|
|
||||||
: '#F8FAFC';
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Animated.View
|
<View style={{ flex: 1 }}>
|
||||||
entering={FadeInUp.duration(400)}
|
{!showDetail ? <Animated.View
|
||||||
style={[styles.shadowContainer, animatedStyle]}
|
entering={FadeInUp.duration(400)}
|
||||||
>
|
style={[styles.shadowContainer, animatedStyle]}
|
||||||
<TouchableOpacity
|
|
||||||
activeOpacity={1}
|
|
||||||
onPress={onPressDetails}
|
|
||||||
onPressIn={handlePressIn}
|
|
||||||
onPressOut={handlePressOut}
|
|
||||||
style={styles.cardInternal}
|
|
||||||
>
|
>
|
||||||
<View style={[styles.statusAccent, { backgroundColor: statusColor }]} />
|
<TouchableOpacity
|
||||||
|
activeOpacity={1}
|
||||||
|
onPress={() => setShowDetail(true)}
|
||||||
|
onPressIn={handlePressIn}
|
||||||
|
onPressOut={handlePressOut}
|
||||||
|
style={styles.cardInternal}
|
||||||
|
>
|
||||||
|
<View style={[styles.statusAccent, { backgroundColor: statusColor }]} />
|
||||||
|
|
||||||
<View style={styles.mainInfo}>
|
<View style={styles.mainInfo}>
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<View style={styles.headerRow}>
|
<View style={styles.headerRow}>
|
||||||
<View>
|
<View>
|
||||||
<View style={[styles.statusBadge, { backgroundColor: lightStatusBg }]}>
|
<View style={[styles.statusBadge, { backgroundColor: lightStatusBg }]}>
|
||||||
<View style={[styles.statusDot, { backgroundColor: statusColor }]} />
|
<View style={[styles.statusDot, { backgroundColor: statusColor }]} />
|
||||||
<Text style={[styles.statusText, { color: statusColor }]}>
|
<Text style={[styles.statusText, { color: statusColor }]}>
|
||||||
{isAuctionEnd ? 'ENDED' : buttonEnable ? 'LIVE' : 'PENDING'}
|
{isAuctionEnd ? 'ENDED' : buttonEnable ? 'LIVE' : 'PENDING'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.title}>{item.auctionNumber}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.amountContainer}>
|
||||||
|
<Text style={styles.amount}>
|
||||||
|
₹{item.auctionFees?.toLocaleString()}
|
||||||
</Text>
|
</Text>
|
||||||
|
<Text style={styles.feeLabel}>Auction Fee</Text>
|
||||||
</View>
|
</View>
|
||||||
<Text style={styles.title}>{item.auctionNumber}</Text>
|
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.amountContainer}>
|
{/* Date */}
|
||||||
<Text style={styles.amount}>
|
<View style={styles.dateRow}>
|
||||||
₹{item.auctionFees?.toLocaleString()}
|
<Text style={styles.dateText}>
|
||||||
|
<Text style={styles.dateLabel}>Bidding Start: </Text>
|
||||||
|
{moment(
|
||||||
|
item?.keyDates?.auctionBidding?.startDateTime?.replace(' kk', ''),
|
||||||
|
'DD-MM-YYYY HH:mm:ss'
|
||||||
|
).format('DD MMM YYYY, hh:mm A')}
|
||||||
</Text>
|
</Text>
|
||||||
<Text style={styles.feeLabel}>Auction Fee</Text>
|
<Text style={styles.dateText}>
|
||||||
</View>
|
<Text style={styles.dateLabel}>Bidding Ends: </Text>
|
||||||
</View>
|
{moment(
|
||||||
|
item?.keyDates?.auctionBidding?.endDateTime?.replace(' kk', ''),
|
||||||
{/* Date */}
|
'DD-MM-YYYY HH:mm:ss'
|
||||||
<View style={styles.dateRow}>
|
).format('DD MMM YYYY, hh:mm A')}
|
||||||
<Text style={styles.dateText}>
|
|
||||||
<Text style={styles.dateLabel}>Bidding Ends: </Text>
|
|
||||||
{moment(item?.keyDates?.auctionBidding?.endDateTime).format(
|
|
||||||
'DD MMM, hh:mm A'
|
|
||||||
)}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
{/* Footer */}
|
|
||||||
<View style={styles.footer}>
|
|
||||||
<View style={styles.footerTop}>
|
|
||||||
<Text style={styles.footerLabel}>Remaining Time</Text>
|
|
||||||
{buttonEnable && !isAuctionEnd ? (
|
|
||||||
<CountdownTimer
|
|
||||||
endDate={item.keyDates.auctionBidding.endDateTime}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Text style={styles.endedText}>--:--:--</Text>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<TouchableOpacity
|
|
||||||
disabled={!buttonEnable}
|
|
||||||
onPress={onStartBidding}
|
|
||||||
activeOpacity={0.85}
|
|
||||||
style={[
|
|
||||||
styles.actionButton,
|
|
||||||
{ backgroundColor: statusColor },
|
|
||||||
!buttonEnable && styles.disabledButton,
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<Text style={styles.addText}>
|
|
||||||
{isAuctionEnd
|
|
||||||
? 'Bidding Closed'
|
|
||||||
: !buttonEnable
|
|
||||||
? 'Payment Required'
|
|
||||||
: 'Proceed to Start Bidding'}
|
|
||||||
</Text>
|
</Text>
|
||||||
</TouchableOpacity>
|
</View>
|
||||||
|
|
||||||
|
{/* Footer */}
|
||||||
|
<View style={styles.footer}>
|
||||||
|
<View style={styles.footerTop}>
|
||||||
|
<Text style={styles.footerLabel}>Remaining Time</Text>
|
||||||
|
{buttonEnable && !isAuctionEnd ? (
|
||||||
|
<CountdownTimer
|
||||||
|
endDate={item.keyDates.auctionBidding.endDateTime}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Text style={styles.endedText}>--:--:--</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
disabled={!buttonEnable}
|
||||||
|
onPress={onStartBidding}
|
||||||
|
activeOpacity={0.85}
|
||||||
|
style={[
|
||||||
|
styles.actionButton,
|
||||||
|
{ backgroundColor: statusColor },
|
||||||
|
!buttonEnable && styles.disabledButton,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Text style={styles.addText}>
|
||||||
|
{isAuctionEnd
|
||||||
|
? 'Bidding Closed'
|
||||||
|
: !buttonEnable
|
||||||
|
? 'Pending Bid'
|
||||||
|
: 'Proceed to Start Bidding'}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</TouchableOpacity>
|
||||||
</TouchableOpacity>
|
</Animated.View> :
|
||||||
</Animated.View>
|
<AuctionDetail visible={showDetail} data={item} onClose={() => setShowDetail(false)} />
|
||||||
|
}
|
||||||
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PurchaseAuctionTile;
|
export default PurchaseAuctionTile;
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
shadowContainer: {
|
shadowContainer: {
|
||||||
marginHorizontal: 5,
|
marginHorizontal: 5,
|
||||||
marginTop: 14,
|
marginTop: 14,
|
||||||
marginBottom: 6,
|
marginBottom: 6,
|
||||||
borderRadius: 16,
|
borderRadius: 16,
|
||||||
backgroundColor: '#fff',
|
backgroundColor: '#fff',
|
||||||
elevation: 8,
|
elevation: 8,
|
||||||
},
|
},
|
||||||
cardInternal: {
|
cardInternal: {
|
||||||
borderRadius: 16,
|
borderRadius: 16,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
backgroundColor: '#fff',
|
backgroundColor: '#fff',
|
||||||
},
|
},
|
||||||
statusAccent: {
|
statusAccent: {
|
||||||
width: 5,
|
width: 5,
|
||||||
height: '100%',
|
height: '100%',
|
||||||
},
|
},
|
||||||
mainInfo: {
|
mainInfo: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
padding: 16,
|
padding: 16,
|
||||||
},
|
},
|
||||||
headerRow: {
|
headerRow: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
alignItems: 'flex-start',
|
alignItems: 'flex-start',
|
||||||
marginBottom: 12,
|
marginBottom: 12,
|
||||||
},
|
},
|
||||||
statusBadge: {
|
statusBadge: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
paddingHorizontal: 8,
|
paddingHorizontal: 8,
|
||||||
paddingVertical: 3,
|
paddingVertical: 3,
|
||||||
borderRadius: 6,
|
borderRadius: 6,
|
||||||
marginBottom: 6,
|
marginBottom: 6,
|
||||||
alignSelf: 'flex-start',
|
alignSelf: 'flex-start',
|
||||||
},
|
},
|
||||||
statusDot: {
|
statusDot: {
|
||||||
width: 6,
|
width: 6,
|
||||||
height: 6,
|
height: 6,
|
||||||
borderRadius: 3,
|
borderRadius: 3,
|
||||||
marginRight: 5,
|
marginRight: 5,
|
||||||
},
|
},
|
||||||
statusText: {
|
statusText: {
|
||||||
fontSize: 10,
|
fontSize: 10,
|
||||||
fontWeight: '800',
|
fontWeight: '800',
|
||||||
letterSpacing: 0.5,
|
letterSpacing: 0.5,
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
fontWeight: '800',
|
fontWeight: '800',
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
color: '#1E293B',
|
color: '#1E293B',
|
||||||
},
|
},
|
||||||
amountContainer: {
|
amountContainer: {
|
||||||
alignItems: 'flex-end',
|
alignItems: 'flex-end',
|
||||||
},
|
},
|
||||||
amount: {
|
amount: {
|
||||||
fontWeight: '900',
|
fontWeight: '900',
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
color: '#0F172A',
|
color: '#0F172A',
|
||||||
},
|
},
|
||||||
feeLabel: {
|
feeLabel: {
|
||||||
fontSize: 10,
|
fontSize: 10,
|
||||||
color: '#64748B',
|
color: '#64748B',
|
||||||
fontWeight: '500',
|
fontWeight: '500',
|
||||||
},
|
},
|
||||||
dateRow: {
|
dateRow: {
|
||||||
backgroundColor: '#F8FAFC',
|
backgroundColor: '#F8FAFC',
|
||||||
paddingHorizontal: 10,
|
paddingHorizontal: 10,
|
||||||
paddingVertical: 8,
|
paddingVertical: 8,
|
||||||
borderRadius: 10,
|
borderRadius: 10,
|
||||||
marginBottom: 16,
|
marginBottom: 16,
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
borderColor: '#F1F5F9',
|
borderColor: '#F1F5F9',
|
||||||
},
|
},
|
||||||
dateText: {
|
dateText: {
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: '#334155',
|
color: '#334155',
|
||||||
fontWeight: '600',
|
fontWeight: '600',
|
||||||
},
|
},
|
||||||
dateLabel: {
|
dateLabel: {
|
||||||
fontWeight: '400',
|
fontWeight: '400',
|
||||||
color: '#64748B',
|
color: '#64748B',
|
||||||
},
|
},
|
||||||
footer: {
|
footer: {
|
||||||
borderTopWidth: 1,
|
borderTopWidth: 1,
|
||||||
borderTopColor: '#F1F5F9',
|
borderTopColor: '#F1F5F9',
|
||||||
paddingTop: 12,
|
paddingTop: 12,
|
||||||
},
|
},
|
||||||
footerTop: {
|
footerTop: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
marginBottom: 12,
|
marginBottom: 12,
|
||||||
},
|
},
|
||||||
footerLabel: {
|
footerLabel: {
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
fontWeight: '600',
|
fontWeight: '600',
|
||||||
color: '#94A3B8',
|
color: '#94A3B8',
|
||||||
textTransform: 'uppercase',
|
textTransform: 'uppercase',
|
||||||
},
|
},
|
||||||
endedText: {
|
endedText: {
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontWeight: '700',
|
fontWeight: '700',
|
||||||
color: '#CBD5E1',
|
color: '#CBD5E1',
|
||||||
},
|
},
|
||||||
actionButton: {
|
actionButton: {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: 48,
|
height: 48,
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
...Platform.select({
|
...Platform.select({
|
||||||
ios: {
|
ios: {
|
||||||
shadowColor: '#000',
|
shadowColor: '#000',
|
||||||
shadowOffset: { width: 0, height: 2 },
|
shadowOffset: { width: 0, height: 2 },
|
||||||
shadowOpacity: 0.1,
|
shadowOpacity: 0.1,
|
||||||
shadowRadius: 4,
|
shadowRadius: 4,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
disabledButton: {
|
disabledButton: {
|
||||||
backgroundColor: '#E2E8F0',
|
backgroundColor: '#E2E8F0',
|
||||||
},
|
},
|
||||||
addText: {
|
addText: {
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: '800',
|
fontWeight: '800',
|
||||||
letterSpacing: 0.2,
|
letterSpacing: 0.2,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,218 @@
|
|||||||
|
import React, { memo, useCallback, useRef } from 'react';
|
||||||
|
import { View, Text, TouchableOpacity, StyleSheet, Platform } from 'react-native';
|
||||||
|
import Animated, { FadeInUp, Layout, interpolate, useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated';
|
||||||
|
import colors from '../../../Constant/Color';
|
||||||
|
import AuctionItemDetail from '../../Auction/Modal/AuctionItemDetail';
|
||||||
|
import MainStyle from '../../../Styles/MainStyle';
|
||||||
|
|
||||||
|
const BiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid, SelectedAuction }: any) => {
|
||||||
|
const [showDetail, setShowDetail] = React.useState(false);
|
||||||
|
const isMin = bidValue <= item.bidAmount;
|
||||||
|
|
||||||
|
// 🔒 Persist expand state safely
|
||||||
|
const expandedRef = useRef(false);
|
||||||
|
const animation = useSharedValue(0);
|
||||||
|
|
||||||
|
const toggleExpand = useCallback(() => {
|
||||||
|
expandedRef.current = !expandedRef.current;
|
||||||
|
animation.value = withSpring(expandedRef.current ? 1 : 0, {
|
||||||
|
damping: 15,
|
||||||
|
stiffness: 140,
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const bodyStyle = useAnimatedStyle(() => ({
|
||||||
|
height: interpolate(animation.value, [0, 1], [0, 190]),
|
||||||
|
opacity: interpolate(animation.value, [0, 0.5, 1], [0, 0, 1]),
|
||||||
|
marginTop: interpolate(animation.value, [0, 1], [0, 15]),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const arrowStyle = useAnimatedStyle(() => ({
|
||||||
|
transform: [
|
||||||
|
{
|
||||||
|
rotate: `${interpolate(animation.value, [0, 1], [0, 180])}deg`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
{
|
||||||
|
!showDetail ? <Animated.View
|
||||||
|
layout={Layout.springify()}
|
||||||
|
entering={FadeInUp.delay(100)}
|
||||||
|
style={[styles.card, styles.leadingCard, { borderColor: item.me ? '#22C55E' : 'red', backgroundColor: item.me ? "#F0FDF4" : '#fdf0f0ff' }]}
|
||||||
|
>
|
||||||
|
{/* HEADER */}
|
||||||
|
<TouchableOpacity
|
||||||
|
activeOpacity={0.7}
|
||||||
|
onPress={() => { setShowDetail(true) }}
|
||||||
|
style={styles.cardHeader}
|
||||||
|
>
|
||||||
|
<View style={{ flex: 1 }}>
|
||||||
|
<Text style={styles.productName}>{item.productName}</Text>
|
||||||
|
{/* auctionStartValueFigure */}
|
||||||
|
<Text style={styles.itemIdText}>
|
||||||
|
Initial Amt : {item?.auctionStartValueFigure}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<TouchableOpacity style={styles.headerRight} onPress={toggleExpand}>
|
||||||
|
<View style={[MainStyle.flexBetween, { gap: 10 }]}>
|
||||||
|
<View style={[styles.badge, item.me ? styles.meBadge : styles.liveBadge]}>
|
||||||
|
<Text style={[styles.badgeText, item.me ? styles.meText : styles.liveText]}>
|
||||||
|
{item.me ? 'LEADING' : 'LIVE'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<Animated.Text style={[styles.arrow, arrowStyle]}>
|
||||||
|
▼
|
||||||
|
</Animated.Text>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.itemIdText}>
|
||||||
|
{SelectedAuction?.auctionNumber}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{/* PRICE INFO */}
|
||||||
|
<View style={styles.priceRow}>
|
||||||
|
<View>
|
||||||
|
<Text style={styles.label}>Current Bid</Text>
|
||||||
|
<Text style={styles.mainPrice}>₹{item?.bidAmount}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={{ alignItems: 'flex-end' }}>
|
||||||
|
<Text style={styles.label}>Increment</Text>
|
||||||
|
<Text style={styles.incrementText}>
|
||||||
|
+₹{item.bidVariationValue}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* COLLAPSIBLE BODY */}
|
||||||
|
<Animated.View style={[styles.collapsibleContainer, bodyStyle]}>
|
||||||
|
<View style={styles.divider} />
|
||||||
|
|
||||||
|
<Text style={styles.bidLabel}>Set Your Bid</Text>
|
||||||
|
|
||||||
|
<View style={styles.stepperContainer}>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={onDecrease}
|
||||||
|
disabled={isMin}
|
||||||
|
style={[styles.stepBtn, isMin && styles.disabledBtn]}
|
||||||
|
>
|
||||||
|
<Text style={styles.stepText}>−</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<View style={styles.inputBox}>
|
||||||
|
<Text style={styles.currency}>₹</Text>
|
||||||
|
<Text style={styles.bidValueText}>{bidValue}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<TouchableOpacity onPress={onIncrease} style={styles.stepBtn}>
|
||||||
|
<Text style={styles.stepText}>+</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.submitBtn}
|
||||||
|
onPress={onPlaceBid}
|
||||||
|
// activeOpacity={0.85}
|
||||||
|
|
||||||
|
>
|
||||||
|
<Text style={styles.submitBtnText}>Confirm Bid</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</Animated.View>
|
||||||
|
</Animated.View>
|
||||||
|
:
|
||||||
|
<AuctionItemDetail data={item} onClose={() => { setShowDetail(false) }} visible={showDetail} />
|
||||||
|
}
|
||||||
|
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(BiddingCard);
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
card: {
|
||||||
|
backgroundColor: '#FFF',
|
||||||
|
borderRadius: 24,
|
||||||
|
padding: 20,
|
||||||
|
marginBottom: 16,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: '#E2E8F0',
|
||||||
|
overflow: 'hidden',
|
||||||
|
...Platform.select({
|
||||||
|
ios: {
|
||||||
|
shadowColor: '#000',
|
||||||
|
shadowOpacity: 0.05,
|
||||||
|
shadowRadius: 10,
|
||||||
|
},
|
||||||
|
android: { elevation: 2 },
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
leadingCard: {
|
||||||
|
borderColor: '#22C55E',
|
||||||
|
borderWidth: 2,
|
||||||
|
backgroundColor: '#F0FDF4',
|
||||||
|
},
|
||||||
|
cardHeader: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
},
|
||||||
|
headerRight: { flexDirection: 'column', alignItems: 'center', gap: 8 },
|
||||||
|
productName: { fontSize: 18, fontWeight: 'bold', color: '#1E293B' },
|
||||||
|
itemIdText: { fontSize: 12, color: '#64748B', marginTop: 2 },
|
||||||
|
badge: { paddingHorizontal: 10, paddingVertical: 4, borderRadius: 8 },
|
||||||
|
liveBadge: { backgroundColor: '#FEE2E2' },
|
||||||
|
meBadge: { backgroundColor: '#BBF7D0' },
|
||||||
|
badgeText: { fontSize: 10, fontWeight: '900' },
|
||||||
|
liveText: { color: '#EF4444' },
|
||||||
|
meText: { color: '#15803D' },
|
||||||
|
arrow: { fontSize: 10, color: '#94A3B8' },
|
||||||
|
priceRow: { flexDirection: 'row', justifyContent: 'space-between', marginTop: 20 },
|
||||||
|
label: {
|
||||||
|
fontSize: 11,
|
||||||
|
color: '#94A3B8',
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
fontWeight: '600',
|
||||||
|
},
|
||||||
|
mainPrice: { fontSize: 22, fontWeight: '900', color: '#0F172A' },
|
||||||
|
incrementText: { fontSize: 16, fontWeight: '700', color: '#3B82F6' },
|
||||||
|
collapsibleContainer: { overflow: 'hidden' },
|
||||||
|
divider: { height: 1, backgroundColor: '#E2E8F0', marginVertical: 10 },
|
||||||
|
bidLabel: { fontSize: 13, fontWeight: '600', color: '#475569', marginBottom: 10 },
|
||||||
|
stepperContainer: { flexDirection: 'row', gap: 12, marginBottom: 20 },
|
||||||
|
stepBtn: {
|
||||||
|
width: 45,
|
||||||
|
height: 45,
|
||||||
|
backgroundColor: colors.primary,
|
||||||
|
borderRadius: 12,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
disabledBtn: { backgroundColor: '#CBD5E1' },
|
||||||
|
stepText: { color: '#FFF', fontSize: 20, fontWeight: 'bold' },
|
||||||
|
inputBox: {
|
||||||
|
flex: 1,
|
||||||
|
height: 45,
|
||||||
|
backgroundColor: '#F1F5F9',
|
||||||
|
borderRadius: 12,
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
currency: { fontSize: 16, fontWeight: 'bold', color: '#64748B', marginRight: 4 },
|
||||||
|
bidValueText: { fontSize: 18, fontWeight: '800', color: '#0F172A' },
|
||||||
|
submitBtn: {
|
||||||
|
height: 50,
|
||||||
|
backgroundColor: colors.primary,
|
||||||
|
borderRadius: 15,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
submitBtnText: { color: '#FFF', fontSize: 16, fontWeight: 'bold' },
|
||||||
|
});
|
||||||
@@ -0,0 +1,370 @@
|
|||||||
|
import React, { memo, useCallback, useRef, useState } from 'react';
|
||||||
|
import { View, Text, TouchableOpacity, StyleSheet, Platform, TextInput } from 'react-native';
|
||||||
|
import Animated, { FadeInUp, Layout, interpolate, useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated';
|
||||||
|
import colors from '../../../Constant/Color';
|
||||||
|
import AuctionItemDetail from '../../Auction/Modal/AuctionItemDetail';
|
||||||
|
import MainStyle from '../../../Styles/MainStyle';
|
||||||
|
import axios, { all } from 'axios';
|
||||||
|
import Variables from '../../../Constant/Variable';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
|
import { showErrorAlert, showSuccessAlert } from '../../../Constant/ShowDailog';
|
||||||
|
import { Loader } from '../../../Component/Index';
|
||||||
|
|
||||||
|
const ReverseBiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid, SelectedAuction, allBoolean, setAllBoolean }: any) => {
|
||||||
|
const Token = useSelector((state: any) => state.token.token)
|
||||||
|
const [allState, setAllState] = useState({ isLoading: false })
|
||||||
|
const [showDetail, setShowDetail] = useState(false);
|
||||||
|
const [value, setValue] = useState(`${item.bidAmount}`);
|
||||||
|
const canDecrease = bidValue > item.emdAmount;
|
||||||
|
const canIncrease = bidValue < item.bidAmount;
|
||||||
|
// Animation Part Rohit Start
|
||||||
|
|
||||||
|
const expandedRef = useRef(false);
|
||||||
|
const animation = useSharedValue(0);
|
||||||
|
|
||||||
|
const toggleExpand = useCallback(() => {
|
||||||
|
expandedRef.current = !expandedRef.current;
|
||||||
|
animation.value = withSpring(expandedRef.current ? 1 : 0, {
|
||||||
|
damping: 15,
|
||||||
|
stiffness: 140,
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const bodyStyle = useAnimatedStyle(() => ({
|
||||||
|
height: interpolate(animation.value, [0, 1], [0, 190]),
|
||||||
|
opacity: interpolate(animation.value, [0, 0.5, 1], [0, 0, 1]),
|
||||||
|
marginTop: interpolate(animation.value, [0, 1], [0, 15]),
|
||||||
|
}));
|
||||||
|
const bodyStyle2 = useAnimatedStyle(() => ({
|
||||||
|
height: interpolate(animation.value, [0, 1], [0, 100]),
|
||||||
|
opacity: interpolate(animation.value, [0, 0.5, 1], [0, 0, 1]),
|
||||||
|
marginTop: interpolate(animation.value, [0, 1], [0, 15]),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const arrowStyle = useAnimatedStyle(() => ({
|
||||||
|
transform: [
|
||||||
|
{
|
||||||
|
rotate: `${interpolate(animation.value, [0, 1], [0, 180])}deg`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Animation Part Rohit End
|
||||||
|
|
||||||
|
const MAX_VALUE = Number(item.auctionStartValue);
|
||||||
|
|
||||||
|
const handleChange = (text: string) => {
|
||||||
|
let cleaned = text.replace(/[^0-9.]/g, '');
|
||||||
|
if ((cleaned.match(/\./g) || []).length > 1) return;
|
||||||
|
if (cleaned === '') {
|
||||||
|
setValue('');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const numericValue = Number(cleaned);
|
||||||
|
if (numericValue < 0) return;
|
||||||
|
if (numericValue > MAX_VALUE) return;
|
||||||
|
setValue(cleaned);
|
||||||
|
};
|
||||||
|
|
||||||
|
const oneTimePlaceBid = async () => {
|
||||||
|
try {
|
||||||
|
setAllState((prev: any) => ({ ...prev, isLoading: true }))
|
||||||
|
const payload = {
|
||||||
|
itemId: item.id,
|
||||||
|
bidAmount: Number(value),
|
||||||
|
auctionId: SelectedAuction.auctionId,
|
||||||
|
contractorId: Token.contractorId,
|
||||||
|
fullName: Token.fullName,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const res = await axios.post(
|
||||||
|
`${Variables.socketUrl}bidding/placeBidForAuction`,
|
||||||
|
[payload],
|
||||||
|
{ headers: { Authentication: `Bearer ${Token.token}` } }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (res.data.statusCode === 200) {
|
||||||
|
showSuccessAlert(res.data.message);
|
||||||
|
}
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, reload: !prev.reload }))
|
||||||
|
} catch (error) {
|
||||||
|
if (axios.isAxiosError(error)) {
|
||||||
|
showErrorAlert(error.response?.data.message)
|
||||||
|
} else {
|
||||||
|
console.log('UNKNOWN ERROR:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
setAllState((prev: any) => ({ ...prev, isLoading: false }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
{!showDetail ? (
|
||||||
|
<Animated.View
|
||||||
|
layout={Layout.springify()}
|
||||||
|
entering={FadeInUp.delay(100)}
|
||||||
|
style={[
|
||||||
|
styles.card,
|
||||||
|
{
|
||||||
|
borderColor: item.me ? '#22C55E' : '#EF4444',
|
||||||
|
backgroundColor: item.me ? '#F0FDF4' : '#FDF0F0',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{/* HEADER */}
|
||||||
|
<TouchableOpacity
|
||||||
|
activeOpacity={0.7}
|
||||||
|
onPress={() => setShowDetail(true)}
|
||||||
|
style={styles.cardHeader}
|
||||||
|
>
|
||||||
|
<View style={{ flex: 1 }}>
|
||||||
|
<Text style={styles.productName}>{item.productName}</Text>
|
||||||
|
<Text style={styles.itemIdText}>
|
||||||
|
Initial Amt : ₹{item.auctionStartValue}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<TouchableOpacity style={styles.headerRight} onPress={toggleExpand}>
|
||||||
|
<View style={[MainStyle.flexBetween, { gap: 10 }]}>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.badge,
|
||||||
|
item.me ? styles.meBadge : styles.liveBadge,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.badgeText,
|
||||||
|
item.me ? styles.meText : styles.liveText,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{item.me ? 'LEADING' : 'LIVE'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<Animated.Text style={[styles.arrow, arrowStyle]}>
|
||||||
|
▼
|
||||||
|
</Animated.Text>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.itemIdText}>
|
||||||
|
{SelectedAuction?.auctionNumber}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{/* PRICE INFO */}
|
||||||
|
<View style={styles.priceRow}>
|
||||||
|
<View>
|
||||||
|
<Text style={styles.label}>Current Bid</Text>
|
||||||
|
<Text style={styles.mainPrice}>₹{item.bidAmount || item.auctionStartValue}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={{ alignItems: 'flex-end' }}>
|
||||||
|
<Text style={styles.label}>Decrement</Text>
|
||||||
|
<Text style={styles.incrementText}>
|
||||||
|
-₹{item.emdAmount}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* COLLAPSIBLE BODY */}
|
||||||
|
{/* <Animated.View style={[styles.collapsibleContainer, (allBoolean.oneTimeBid && allBoolean.rebid) ? bodyStyle : (allBoolean.oneTimeBid && !item.me) ? bodyStyle : bodyStyle2]}> */}
|
||||||
|
<Animated.View style={[styles.collapsibleContainer, bodyStyle]}>
|
||||||
|
<View style={styles.divider} />
|
||||||
|
|
||||||
|
<Text style={styles.bidLabel}>Set Your Bid</Text>
|
||||||
|
|
||||||
|
<View style={styles.stepperContainer}>
|
||||||
|
{/* DECREASE */}
|
||||||
|
{!allBoolean.oneTimeBid && <TouchableOpacity
|
||||||
|
onPress={onDecrease}
|
||||||
|
disabled={!canDecrease}
|
||||||
|
style={[
|
||||||
|
styles.stepBtn,
|
||||||
|
!canDecrease && styles.disabledBtn,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Text style={styles.stepText}>−</Text>
|
||||||
|
</TouchableOpacity>}
|
||||||
|
|
||||||
|
{/* VALUE */}
|
||||||
|
{!allBoolean.oneTimeBid && <View style={styles.inputBox}>
|
||||||
|
<Text style={styles.currency}>₹</Text>
|
||||||
|
<Text style={styles.bidValueText}>{bidValue}</Text>
|
||||||
|
</View>}
|
||||||
|
{
|
||||||
|
(allBoolean.oneTimeBid || allBoolean.rebid) && <View style={styles.inputBox2}>
|
||||||
|
<Text style={styles.currency2}>₹</Text>
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
value={value}
|
||||||
|
onChangeText={handleChange}
|
||||||
|
keyboardType="decimal-pad"
|
||||||
|
placeholder="0.00"
|
||||||
|
style={styles.input}
|
||||||
|
placeholderTextColor="#94A3B8"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
}
|
||||||
|
|
||||||
|
{/* INCREASE */}
|
||||||
|
{!allBoolean.oneTimeBid && <TouchableOpacity
|
||||||
|
onPress={onIncrease}
|
||||||
|
disabled={!canIncrease}
|
||||||
|
style={[
|
||||||
|
styles.stepBtn,
|
||||||
|
!canIncrease && styles.disabledBtn,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Text style={styles.stepText}>+</Text>
|
||||||
|
</TouchableOpacity>}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[styles.submitBtn]}
|
||||||
|
onPress={(allBoolean.oneTimeBid || allBoolean.rebid) ? oneTimePlaceBid : onPlaceBid}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
allState.isLoading ? <Loader size='small' color={colors.white} /> : <Text style={styles.submitBtnText}>Confirm Bid</Text>
|
||||||
|
}
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{/* {(allBoolean.oneTimeBid && allBoolean.rebid) ?
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[styles.submitBtn]}
|
||||||
|
onPress={(allBoolean.oneTimeBid || allBoolean.rebid) ? oneTimePlaceBid : onPlaceBid}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
allState.isLoading ? <Loader size='small' color={colors.white} /> : <Text style={styles.submitBtnText}>Confirm Bid</Text>
|
||||||
|
}
|
||||||
|
</TouchableOpacity> :
|
||||||
|
(allBoolean.oneTimeBid && !item.me) ? <TouchableOpacity
|
||||||
|
style={[styles.submitBtn]}
|
||||||
|
onPress={(allBoolean.oneTimeBid || allBoolean.rebid) ? oneTimePlaceBid : onPlaceBid}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
allState.isLoading ? <Loader size='small' color={colors.white} /> : <Text style={styles.submitBtnText}>Confirm Bid</Text>
|
||||||
|
}
|
||||||
|
</TouchableOpacity> : null
|
||||||
|
} */}
|
||||||
|
</Animated.View>
|
||||||
|
</Animated.View>
|
||||||
|
) : (
|
||||||
|
<AuctionItemDetail
|
||||||
|
data={item}
|
||||||
|
onClose={() => setShowDetail(false)}
|
||||||
|
visible={showDetail}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ReverseBiddingCard;
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
inputBox2: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: '#F1F5F9',
|
||||||
|
borderRadius: 12,
|
||||||
|
height: 45,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
width: '100%'
|
||||||
|
},
|
||||||
|
currency2: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: '#64748B',
|
||||||
|
marginRight: 4,
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
flex: 1,
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: '700',
|
||||||
|
color: '#0F172A',
|
||||||
|
width: '100%'
|
||||||
|
},
|
||||||
|
card: {
|
||||||
|
backgroundColor: '#FFF',
|
||||||
|
borderRadius: 24,
|
||||||
|
padding: 20,
|
||||||
|
marginBottom: 16,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: '#E2E8F0',
|
||||||
|
overflow: 'hidden',
|
||||||
|
...Platform.select({
|
||||||
|
ios: {
|
||||||
|
shadowColor: '#000',
|
||||||
|
shadowOpacity: 0.05,
|
||||||
|
shadowRadius: 10,
|
||||||
|
},
|
||||||
|
android: { elevation: 2 },
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
leadingCard: {
|
||||||
|
borderColor: '#22C55E',
|
||||||
|
borderWidth: 2,
|
||||||
|
backgroundColor: '#F0FDF4',
|
||||||
|
},
|
||||||
|
cardHeader: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
},
|
||||||
|
headerRight: { flexDirection: 'column', alignItems: 'center', gap: 8 },
|
||||||
|
productName: { fontSize: 18, fontWeight: 'bold', color: '#1E293B' },
|
||||||
|
itemIdText: { fontSize: 12, color: '#64748B', marginTop: 2 },
|
||||||
|
badge: { paddingHorizontal: 10, paddingVertical: 4, borderRadius: 8 },
|
||||||
|
liveBadge: { backgroundColor: '#FEE2E2' },
|
||||||
|
meBadge: { backgroundColor: '#BBF7D0' },
|
||||||
|
badgeText: { fontSize: 10, fontWeight: '900' },
|
||||||
|
liveText: { color: '#EF4444' },
|
||||||
|
meText: { color: '#15803D' },
|
||||||
|
arrow: { fontSize: 10, color: '#94A3B8' },
|
||||||
|
priceRow: { flexDirection: 'row', justifyContent: 'space-between', marginTop: 20 },
|
||||||
|
label: {
|
||||||
|
fontSize: 11,
|
||||||
|
color: '#94A3B8',
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
fontWeight: '600',
|
||||||
|
},
|
||||||
|
mainPrice: { fontSize: 22, fontWeight: '900', color: '#0F172A' },
|
||||||
|
incrementText: { fontSize: 16, fontWeight: '700', color: '#3B82F6' },
|
||||||
|
collapsibleContainer: { overflow: 'hidden' },
|
||||||
|
divider: { height: 1, backgroundColor: '#E2E8F0', marginVertical: 10 },
|
||||||
|
bidLabel: { fontSize: 13, fontWeight: '600', color: '#475569', marginBottom: 10 },
|
||||||
|
stepperContainer: { flexDirection: 'row', gap: 12, marginBottom: 20 },
|
||||||
|
stepBtn: {
|
||||||
|
width: 45,
|
||||||
|
height: 45,
|
||||||
|
backgroundColor: colors.primary,
|
||||||
|
borderRadius: 12,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
disabledBtn: { backgroundColor: '#CBD5E1' },
|
||||||
|
stepText: { color: '#FFF', fontSize: 20, fontWeight: 'bold' },
|
||||||
|
inputBox: {
|
||||||
|
flex: 1,
|
||||||
|
height: 45,
|
||||||
|
backgroundColor: '#F1F5F9',
|
||||||
|
borderRadius: 12,
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
currency: { fontSize: 16, fontWeight: 'bold', color: '#64748B', marginRight: 4 },
|
||||||
|
bidValueText: { fontSize: 18, fontWeight: '800', color: '#0F172A' },
|
||||||
|
submitBtn: {
|
||||||
|
height: 50,
|
||||||
|
backgroundColor: colors.primary,
|
||||||
|
borderRadius: 15,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
submitBtnText: { color: '#FFF', fontSize: 16, fontWeight: 'bold' },
|
||||||
|
});
|
||||||
@@ -0,0 +1,416 @@
|
|||||||
|
import React, { useState } from 'react'
|
||||||
|
import { Modal, View, Text, StyleSheet, TextInput, TouchableOpacity, ScrollView } from 'react-native'
|
||||||
|
import { Formik } from 'formik'
|
||||||
|
import * as Yup from 'yup'
|
||||||
|
import { pick } from '@react-native-documents/picker'
|
||||||
|
import { useSelector } from 'react-redux'
|
||||||
|
import { apiCall } from '../../../Axios/Axios'
|
||||||
|
import { TECHNICAL_DOCUMENT_SUBMIT, TECHNICAL_VALUE_SUBMIT } from '../../../Services/BBPS/ApiUrls'
|
||||||
|
import { Props } from '../Type/BidType'
|
||||||
|
import colors from '../../../Constant/Color'
|
||||||
|
import { Loader } from '../../../Component/Index'
|
||||||
|
import { useNavigation } from '@react-navigation/native'
|
||||||
|
import NavigationString from '../../../Constant/NavigationString'
|
||||||
|
|
||||||
|
const TemplateFormModal: React.FC<Props> = ({ visible, template, setAllBoolean }) => {
|
||||||
|
if (!template) return null
|
||||||
|
|
||||||
|
const SelectedAuction = useSelector((state: any) => state.auction.auction)
|
||||||
|
const Navigation: any = useNavigation()
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const initialValues = template.labels.reduce((acc: any, label: any) => {
|
||||||
|
acc[label.labelName] = ''
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
|
||||||
|
const validationSchema = Yup.object(
|
||||||
|
template.labels.reduce((acc: any, label: any) => {
|
||||||
|
if (label.mandatory) {
|
||||||
|
acc[label.labelName] =
|
||||||
|
label.labelType === '3'
|
||||||
|
? Yup.mixed().required(`${label.labelName} is required`)
|
||||||
|
: Yup.string().required(`${label.labelName} is required`)
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
)
|
||||||
|
|
||||||
|
const pickFile = async (fieldName: string, setFieldValue: any) => {
|
||||||
|
try {
|
||||||
|
const result = await pick({
|
||||||
|
type: ['application/pdf'],
|
||||||
|
allowMultiSelection: false,
|
||||||
|
})
|
||||||
|
const file = result[0]
|
||||||
|
setFieldValue(fieldName, {
|
||||||
|
name: file.name ?? 'document.pdf',
|
||||||
|
uri: file.uri,
|
||||||
|
type: 'application/pdf',
|
||||||
|
size: file.size,
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderInput = (
|
||||||
|
label: any,
|
||||||
|
value: any,
|
||||||
|
setFieldValue: any,
|
||||||
|
error?: string,
|
||||||
|
touched?: boolean
|
||||||
|
) => {
|
||||||
|
const showError = touched && error
|
||||||
|
|
||||||
|
if (label.labelType === '3') {
|
||||||
|
return (
|
||||||
|
<View key={label.labelName} style={styles.field}>
|
||||||
|
<Text style={styles.label}>
|
||||||
|
{label.labelName}
|
||||||
|
{label.mandatory && <Text style={styles.required}> *</Text>}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.filePicker,
|
||||||
|
showError && styles.errorBorder,
|
||||||
|
]}
|
||||||
|
onPress={() =>
|
||||||
|
pickFile(label.labelName, setFieldValue)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.fileText,
|
||||||
|
value?.name && styles.fileSelected,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{value?.name || 'Upload PDF'}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{showError && (
|
||||||
|
<Text style={styles.errorText}>{error}</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View key={label.labelName} style={styles.field}>
|
||||||
|
<Text style={styles.label}>
|
||||||
|
{label.labelName}
|
||||||
|
{label.mandatory && <Text style={styles.required}> *</Text>}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
style={[
|
||||||
|
styles.input,
|
||||||
|
showError && styles.errorBorder,
|
||||||
|
]}
|
||||||
|
placeholder={`Enter ${label.labelName}`}
|
||||||
|
placeholderTextColor="#9CA3AF"
|
||||||
|
value={value}
|
||||||
|
onChangeText={(text) =>
|
||||||
|
setFieldValue(label.labelName, text)
|
||||||
|
}
|
||||||
|
keyboardType={
|
||||||
|
label.labelType === '1' || label.labelType === '4'
|
||||||
|
? 'numeric'
|
||||||
|
: 'default'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{showError && (
|
||||||
|
<Text style={styles.errorText}>{error}</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onClose = () => {
|
||||||
|
setAllBoolean((prev: any) => ({
|
||||||
|
...prev,
|
||||||
|
technicalDocModalVisible: false,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSubmit = async (payload: any) => {
|
||||||
|
try {
|
||||||
|
const jsonBody = {
|
||||||
|
auctiontId: SelectedAuction.auctionId,
|
||||||
|
technicalDocumentTemplateId: payload.templateNameId,
|
||||||
|
labelValues: [] as any[],
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileFormData = new FormData()
|
||||||
|
let hasFile = false
|
||||||
|
|
||||||
|
Object.entries(payload.values).forEach(
|
||||||
|
([labelName, labelValue]: any) => {
|
||||||
|
if (typeof labelValue === 'object' && labelValue?.uri) {
|
||||||
|
hasFile = true
|
||||||
|
fileFormData.append(labelName, {
|
||||||
|
uri: labelValue.uri,
|
||||||
|
name: labelValue.name,
|
||||||
|
type: labelValue.type,
|
||||||
|
} as any)
|
||||||
|
} else {
|
||||||
|
jsonBody.labelValues.push({
|
||||||
|
labelName,
|
||||||
|
labelValue: String(labelValue),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const rs1: any = await apiCall('post', TECHNICAL_VALUE_SUBMIT, jsonBody)
|
||||||
|
|
||||||
|
|
||||||
|
if (hasFile) {
|
||||||
|
fileFormData.append(
|
||||||
|
'auctiontId',
|
||||||
|
String(SelectedAuction.auctionId)
|
||||||
|
)
|
||||||
|
fileFormData.append(
|
||||||
|
'technicalDocumentTemplateId',
|
||||||
|
String(payload.templateNameId)
|
||||||
|
)
|
||||||
|
|
||||||
|
const res2: any = await apiCall(
|
||||||
|
'post',
|
||||||
|
TECHNICAL_DOCUMENT_SUBMIT,
|
||||||
|
fileFormData,
|
||||||
|
{},
|
||||||
|
'multipart/form-data'
|
||||||
|
)
|
||||||
|
console.log(res2, '-------------res2');
|
||||||
|
if (rs1.statusCode == 200 && res2.statusCode == 200) {
|
||||||
|
Navigation.navigate(NavigationString.StartBidding)
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, technicalDocModalVisible: false }))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (rs1.statusCode == 200) {
|
||||||
|
Navigation.navigate(NavigationString.StartBidding)
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, technicalDocModalVisible: false }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
} finally {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal visible={visible} animationType="fade" transparent>
|
||||||
|
<View style={styles.screen}>
|
||||||
|
|
||||||
|
<View style={styles.header}>
|
||||||
|
<View style={styles.headerLeft}>
|
||||||
|
<Text style={styles.headerTitle}>Technical Documents</Text>
|
||||||
|
<Text style={styles.headerSubtitle}>
|
||||||
|
Fill the form, Click save when you're done.
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<TouchableOpacity onPress={onClose} style={styles.closeBtn}>
|
||||||
|
<Text style={styles.closeText}>✕</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<ScrollView contentContainerStyle={styles.content}>
|
||||||
|
|
||||||
|
<View style={styles.card}>
|
||||||
|
<Text style={styles.templateHeading}>Template</Text>
|
||||||
|
|
||||||
|
<View style={styles.templateBox}>
|
||||||
|
<Text style={styles.templateName}>
|
||||||
|
{template.templateName}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Formik
|
||||||
|
initialValues={initialValues}
|
||||||
|
validationSchema={validationSchema}
|
||||||
|
onSubmit={(values) => {
|
||||||
|
setLoading(true)
|
||||||
|
onSubmit({
|
||||||
|
templateNameId: template.templateNameId,
|
||||||
|
auctionIds: template.auctionIds,
|
||||||
|
values,
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{({ handleSubmit, values, errors, touched, setFieldValue }) => (
|
||||||
|
<>
|
||||||
|
{template.labels.map((label: any) =>
|
||||||
|
renderInput(
|
||||||
|
label,
|
||||||
|
values[label.labelName],
|
||||||
|
setFieldValue,
|
||||||
|
// errors[label.labelName],
|
||||||
|
// touched[label.labelName]
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
|
||||||
|
<View style={styles.submitRow}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.submitBtn}
|
||||||
|
onPress={() => handleSubmit()}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
{loading ? (
|
||||||
|
<Loader
|
||||||
|
size="small"
|
||||||
|
color={colors.white}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Text style={styles.submitText}>
|
||||||
|
Submit
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TemplateFormModal
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
screen: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: '#F9FAFB',
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
paddingVertical: 14,
|
||||||
|
backgroundColor: '#FFFFFF',
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderColor: '#E5E7EB',
|
||||||
|
},
|
||||||
|
headerLeft: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
headerTitle: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: '700',
|
||||||
|
color: '#111827',
|
||||||
|
},
|
||||||
|
headerSubtitle: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: '#6B7280',
|
||||||
|
marginTop: 2,
|
||||||
|
},
|
||||||
|
closeBtn: {
|
||||||
|
padding: 6,
|
||||||
|
},
|
||||||
|
closeText: {
|
||||||
|
fontSize: 18,
|
||||||
|
color: '#6B7280',
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
},
|
||||||
|
card: {
|
||||||
|
backgroundColor: '#FFFFFF',
|
||||||
|
borderColor: '#E5E7EB',
|
||||||
|
paddingVertical: 20
|
||||||
|
},
|
||||||
|
templateHeading: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: '700',
|
||||||
|
textAlign: 'center',
|
||||||
|
marginBottom: 16,
|
||||||
|
color: '#111827',
|
||||||
|
},
|
||||||
|
|
||||||
|
templateBox: {
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: '#E5E7EB',
|
||||||
|
borderRadius: 10,
|
||||||
|
padding: 16,
|
||||||
|
},
|
||||||
|
templateName: {
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: '700',
|
||||||
|
color: '#111827',
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
field: {
|
||||||
|
marginBottom: 14,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: '600',
|
||||||
|
color: '#374151',
|
||||||
|
marginBottom: 6,
|
||||||
|
},
|
||||||
|
required: {
|
||||||
|
color: '#EF4444',
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
backgroundColor: '#FFFFFF',
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: '#E5E7EB',
|
||||||
|
borderRadius: 8,
|
||||||
|
padding: 12,
|
||||||
|
fontSize: 14,
|
||||||
|
color: '#111827',
|
||||||
|
},
|
||||||
|
filePicker: {
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: '#E5E7EB',
|
||||||
|
borderRadius: 8,
|
||||||
|
padding: 12,
|
||||||
|
},
|
||||||
|
fileText: {
|
||||||
|
color: '#6B7280',
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
fileSelected: {
|
||||||
|
color: '#111827',
|
||||||
|
fontWeight: '600',
|
||||||
|
},
|
||||||
|
errorText: {
|
||||||
|
color: '#EF4444',
|
||||||
|
fontSize: 12,
|
||||||
|
marginTop: 4,
|
||||||
|
},
|
||||||
|
errorBorder: {
|
||||||
|
borderColor: '#EF4444',
|
||||||
|
},
|
||||||
|
submitRow: {
|
||||||
|
marginTop: 20,
|
||||||
|
alignItems: 'flex-end',
|
||||||
|
height:50
|
||||||
|
},
|
||||||
|
submitBtn: {
|
||||||
|
backgroundColor: colors.primary,
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingHorizontal: 22,
|
||||||
|
borderRadius: 8,
|
||||||
|
minWidth: 120,
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
submitText: {
|
||||||
|
color: '#FFFFFF',
|
||||||
|
fontWeight: '700',
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
+202
-46
@@ -1,37 +1,31 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { View, Text, FlatList, TouchableOpacity, StyleSheet, TextInput, Alert } from 'react-native';
|
import { View, Text, FlatList, TouchableOpacity, StyleSheet, TextInput, Alert } from 'react-native';
|
||||||
import { pick } from '@react-native-documents/picker';
|
import { pick } from '@react-native-documents/picker';
|
||||||
import Animated, { FadeInDown, FadeOutUp, Layout } from 'react-native-reanimated';
|
import Animated, { FadeInDown, FadeOutUp, Layout } from 'react-native-reanimated';
|
||||||
// import BouncyCheckbox from 'react-native-bouncy-checkbox';
|
// import BouncyCheckbox from 'react-native-bouncy-checkbox';
|
||||||
import { InsideHeader, Skelton } from '../../Component/Index';
|
import BouncyCheckbox from 'react-native-bouncy-checkbox';
|
||||||
|
import { InsideHeader, Loader, Skelton } from '../../Component/Index';
|
||||||
import colors from '../../Constant/Color';
|
import colors from '../../Constant/Color';
|
||||||
import EmdComplete from './Component/EmdComplete';
|
import EmdComplete from './Component/EmdComplete';
|
||||||
import NavigationString from '../../Constant/NavigationString';
|
import NavigationString from '../../Constant/NavigationString';
|
||||||
import { useNavigation } from '@react-navigation/native';
|
import { useNavigation } from '@react-navigation/native';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
|
import { useAuctionItem, useEmdCheck } from '../../Services/BBPS/Hooks';
|
||||||
|
import { apiCall } from '../../Axios/Axios';
|
||||||
|
import { AUCTION_ITEM_SUBMIT, CHECK_TECHNICAL_DOCUMENTAION, GET_TECHNICAL_DOCUMENTAION } from '../../Services/BBPS/ApiUrls';
|
||||||
|
import TemplateFormModal from './Component/TemplateFormModal';
|
||||||
|
import { SelectedItem } from './Type/BidType';
|
||||||
|
|
||||||
const DUMMY_AUCTION_ITEMS = [
|
|
||||||
{ id: 1, productName: 'Iron Scrap Lot A', emdAmount: 50000, itemDocumentName: null },
|
|
||||||
{ id: 2, productName: 'Steel Rods Lot B', emdAmount: 75000, itemDocumentName: 'old_emd.pdf' },
|
|
||||||
{ id: 3, productName: 'Copper Wire Lot C', emdAmount: 60000, itemDocumentName: null },
|
|
||||||
];
|
|
||||||
|
|
||||||
type SelectedItem = {
|
|
||||||
auctionItemId: number;
|
|
||||||
productImageName: string;
|
|
||||||
file: {
|
|
||||||
name: string;
|
|
||||||
uri: string;
|
|
||||||
type: string;
|
|
||||||
} | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const Emd = () => {
|
const Emd = () => {
|
||||||
const Navigation: any = useNavigation()
|
const Navigation: any = useNavigation()
|
||||||
|
const SelectedAuction = useSelector((state: any) => state.auction.auction)
|
||||||
const [selectedItems, setSelectedItems] = useState<SelectedItem[]>([]);
|
const [selectedItems, setSelectedItems] = useState<SelectedItem[]>([]);
|
||||||
const [acceptedPolicy, setAcceptedPolicy] = useState(false);
|
const [acceptedPolicy, setAcceptedPolicy] = useState(false);
|
||||||
const [isComplete, setIsComplete] = useState(false);
|
const [allBoolean, setAllBoolean] = useState({ isSubmitEmdLoading: false, isEmdComplete: false, auctionItems: [], technicalDocumentStatus: false, selectTemplate: {}, technicalDocModalVisible: false })
|
||||||
|
const { mutate } = useEmdCheck()
|
||||||
|
const { mutate: AuctionItemMutate, isPending } = useAuctionItem()
|
||||||
|
|
||||||
/* ---------------- Helpers ---------------- */
|
|
||||||
const isSelected = (id: number) => selectedItems.some(i => i.auctionItemId === id);
|
const isSelected = (id: number) => selectedItems.some(i => i.auctionItemId === id);
|
||||||
|
|
||||||
const toggleSelect = (item: any, checked: boolean) => {
|
const toggleSelect = (item: any, checked: boolean) => {
|
||||||
@@ -70,27 +64,6 @@ const Emd = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const handleSubmit = () => {
|
|
||||||
if (!acceptedPolicy) {
|
|
||||||
Alert.alert('Policy Required', 'Please accept terms');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectedItems.length === 0) {
|
|
||||||
Alert.alert('Select Item', 'Please select at least one item');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const item of selectedItems) {
|
|
||||||
if (!item.productImageName || !item.file) {
|
|
||||||
Alert.alert('Incomplete', 'Upload documents for all selected items');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('✅ SUBMITTED:', selectedItems);
|
|
||||||
setIsComplete(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ---------------- Render Item ---------------- */
|
/* ---------------- Render Item ---------------- */
|
||||||
const renderItem = ({ item }: any) => {
|
const renderItem = ({ item }: any) => {
|
||||||
@@ -141,6 +114,7 @@ const Emd = () => {
|
|||||||
updateSelectedItem(item.id, { productImageName: text })
|
updateSelectedItem(item.id, { productImageName: text })
|
||||||
}
|
}
|
||||||
style={styles.input}
|
style={styles.input}
|
||||||
|
placeholderTextColor={colors.lightText}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
@@ -163,19 +137,197 @@ const Emd = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Api calls
|
||||||
|
const getAuctionItem = async () => {
|
||||||
|
try {
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, isLoading: true }))
|
||||||
|
if (SelectedAuction.auctionPattern === 'Forward') {
|
||||||
|
const payload = { auctionNumber: SelectedAuction.auctionNumber, status: 'Forward' }
|
||||||
|
AuctionItemMutate(payload, {
|
||||||
|
onSuccess: (res) => {
|
||||||
|
if (res.statusCode == 200) {
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, auctionItems: Array.isArray(res?.data) ? res.data : [res.data] }))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onError: (err) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
} else if (SelectedAuction.auctionPattern === 'Reverse') {
|
||||||
|
const payload = { auctionNumber: SelectedAuction.auctionNumber, status: 'Reverse' }
|
||||||
|
AuctionItemMutate(payload, {
|
||||||
|
onSuccess: (res) => {
|
||||||
|
if (res.statusCode == 200) {
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, auctionItems: Array.isArray(res?.data) ? res.data : [res.data] }))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onError: (err) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log('Auction fetch error', error)
|
||||||
|
} finally {
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, isLoading: false }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTemplateDocumentation = async () => {
|
||||||
|
try {
|
||||||
|
if (SelectedAuction.technicalDocReq) {
|
||||||
|
const res = await apiCall<any>('get', CHECK_TECHNICAL_DOCUMENTAION, {}, { auctionId: SelectedAuction.auctionId })
|
||||||
|
|
||||||
|
if (res.data) {
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, technicalDocumentStatus: true }))
|
||||||
|
} else {
|
||||||
|
const res = await apiCall<any>('get', GET_TECHNICAL_DOCUMENTAION,)
|
||||||
|
const auctionIdToFind = String(SelectedAuction.auctionId);
|
||||||
|
const matchedObject = res.data.find((item: any) =>
|
||||||
|
item.auctionIds
|
||||||
|
.split(',')
|
||||||
|
.map((id: any) => id.trim())
|
||||||
|
.includes(auctionIdToFind)
|
||||||
|
);
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, selectTemplate: matchedObject, technicalDocModalVisible: true }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log('Auction fetch error', error)
|
||||||
|
} finally {
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, isLoading: false }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const AlreadyEmdCheck = async () => {
|
||||||
|
try {
|
||||||
|
mutate({ auctionNumber: SelectedAuction.auctionNumber }, {
|
||||||
|
onSuccess: (res => {
|
||||||
|
console.log(SelectedAuction.auctionNumber, res , SelectedAuction,'iiiiiiiiiiiiiiiiiiiiiiiii');
|
||||||
|
|
||||||
|
if (res.statusCode == 200) {
|
||||||
|
if (res.message == 'No EMD Documents') {
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, isEmdComplete: false }))
|
||||||
|
getAuctionItem()
|
||||||
|
} else {
|
||||||
|
if (!SelectedAuction.technicalDocReq) {
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, isEmdComplete: true, technicalDocumentStatus: true }))
|
||||||
|
} else {
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, isEmdComplete: true }))
|
||||||
|
getTemplateDocumentation()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
onError: (err) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.log('EMD Check Error:', error)
|
||||||
|
} finally {
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, isLoading: false }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, isSubmitEmdLoading: true }))
|
||||||
|
if (!acceptedPolicy) {
|
||||||
|
Alert.alert('Policy Required', 'Please accept terms');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedItems.length === 0) {
|
||||||
|
Alert.alert('Select Item', 'Please select at least one item');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const item of selectedItems) {
|
||||||
|
if (!item.productImageName || !item.file) {
|
||||||
|
Alert.alert('Incomplete', 'Upload documents for all selected items');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const formData = new FormData()
|
||||||
|
|
||||||
|
formData.append('auctionId', String(SelectedAuction.auctionId))
|
||||||
|
|
||||||
|
selectedItems.forEach((item: any) => {
|
||||||
|
formData.append(
|
||||||
|
'auctionItemId',
|
||||||
|
String(item.auctionItemId)
|
||||||
|
)
|
||||||
|
|
||||||
|
formData.append(
|
||||||
|
'productImageName',
|
||||||
|
item.productImageName
|
||||||
|
)
|
||||||
|
|
||||||
|
formData.append('files', {
|
||||||
|
uri: item.file.uri,
|
||||||
|
name: item.file.name,
|
||||||
|
type: item.file.type || 'application/pdf',
|
||||||
|
} as any)
|
||||||
|
})
|
||||||
|
|
||||||
|
const res = await apiCall<any>('post', AUCTION_ITEM_SUBMIT, formData, {}, 'multipart/form-data')
|
||||||
|
if (res.statusCode == 200) {
|
||||||
|
if (SelectedAuction.technicalDocReq) {
|
||||||
|
getTemplateDocumentation()
|
||||||
|
} else {
|
||||||
|
if (SelectedAuction.auctionPattern === 'Forward') {
|
||||||
|
Navigation.navigate(NavigationString.StartBidding)
|
||||||
|
} else {
|
||||||
|
Navigation.navigate(NavigationString.StartReverseBidding)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log('Submit error', error)
|
||||||
|
Alert.alert('Error', 'Failed to submit EMD')
|
||||||
|
} finally {
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, isSubmitEmdLoading: true }))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const EmdContinueHandle = async () => {
|
||||||
|
|
||||||
|
if (allBoolean.technicalDocumentStatus) {
|
||||||
|
if (SelectedAuction.auctionPattern === 'Forward') {
|
||||||
|
Navigation.navigate(NavigationString.StartBidding)
|
||||||
|
} else {
|
||||||
|
Navigation.navigate(NavigationString.StartReverseBidding)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
getTemplateDocumentation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
AlreadyEmdCheck()
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={{ flex: 1, backgroundColor: colors.white }}>
|
<View style={{ flex: 1, backgroundColor: colors.white }}>
|
||||||
<InsideHeader title="EMD Submission" showArrow />
|
<InsideHeader title="EMD Submission" showArrow />
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
|
{SelectedAuction.technicalDocReq && allBoolean.technicalDocModalVisible &&
|
||||||
|
<TemplateFormModal visible={allBoolean.technicalDocModalVisible} allBoolean={allBoolean} setAllBoolean={setAllBoolean} template={allBoolean.selectTemplate} />
|
||||||
|
}
|
||||||
|
|
||||||
{false ? (
|
{isPending ? (
|
||||||
<Skelton />
|
<Skelton />
|
||||||
) : true ? (
|
) : allBoolean.isEmdComplete ? (
|
||||||
<EmdComplete onNext={() => { Navigation.navigate(NavigationString.StartBidding) }} />
|
<EmdComplete onNext={EmdContinueHandle} />
|
||||||
) : <>
|
) : <>
|
||||||
<FlatList
|
<FlatList
|
||||||
data={DUMMY_AUCTION_ITEMS}
|
data={allBoolean.auctionItems}
|
||||||
keyExtractor={item => item.id.toString()}
|
keyExtractor={(item: any) => item.auctionId}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
contentContainerStyle={{ paddingBottom: 170 }}
|
contentContainerStyle={{ paddingBottom: 170 }}
|
||||||
/>
|
/>
|
||||||
@@ -200,7 +352,10 @@ const Emd = () => {
|
|||||||
onPress={handleSubmit}
|
onPress={handleSubmit}
|
||||||
disabled={!acceptedPolicy}
|
disabled={!acceptedPolicy}
|
||||||
>
|
>
|
||||||
<Text style={styles.submitText}>Submit EMD</Text>
|
{
|
||||||
|
allBoolean.isSubmitEmdLoading ? <Loader size='small' color={colors.white} /> : <Text style={styles.submitText}>Submit EMD</Text>
|
||||||
|
}
|
||||||
|
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
@@ -277,6 +432,7 @@ const styles = StyleSheet.create({
|
|||||||
padding: 12,
|
padding: 12,
|
||||||
backgroundColor: '#FFFFFF',
|
backgroundColor: '#FFFFFF',
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
|
color: colors.black
|
||||||
},
|
},
|
||||||
|
|
||||||
uploadBtn: {
|
uploadBtn: {
|
||||||
|
|||||||
@@ -1,154 +1,136 @@
|
|||||||
import React, { useEffect, useState, useCallback } from 'react';
|
import React, { useCallback, useEffect, useState } from 'react';
|
||||||
import {
|
import { View, FlatList, StyleSheet, Platform, Alert, BackHandler, Text } from 'react-native';
|
||||||
View,
|
|
||||||
Text,
|
|
||||||
FlatList,
|
|
||||||
TextInput,
|
|
||||||
TouchableOpacity,
|
|
||||||
StyleSheet,
|
|
||||||
Platform,
|
|
||||||
Alert,
|
|
||||||
} from 'react-native';
|
|
||||||
import LottieView from 'lottie-react-native';
|
import LottieView from 'lottie-react-native';
|
||||||
import Animated, {
|
|
||||||
FadeInUp,
|
|
||||||
useSharedValue,
|
|
||||||
useAnimatedStyle,
|
|
||||||
withSpring,
|
|
||||||
withTiming,
|
|
||||||
Layout,
|
|
||||||
interpolate,
|
|
||||||
} from 'react-native-reanimated';
|
|
||||||
import { InsideHeader } from '../../Component/Index';
|
import { InsideHeader } from '../../Component/Index';
|
||||||
import colors from '../../Constant/Color';
|
import colors from '../../Constant/Color';
|
||||||
|
import { useWebSocketService } from '../../socket/Socket';
|
||||||
|
import Variables from '../../Constant/Variable';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
|
import { apiCall } from '../../Axios/Axios';
|
||||||
|
import { FORWARD_AUCTION_ITEM, REVERSE_AUCTION_ITEM, SELECTED_AUCTION_ITEM } from '../../Services/BBPS/ApiUrls';
|
||||||
|
import BiddingCard from './Component/BiddingCard';
|
||||||
|
import { CommonActions, useFocusEffect, useNavigation } from '@react-navigation/native';
|
||||||
|
import NavigationString from '../../Constant/NavigationString';
|
||||||
|
import CountdownTimer from '../../Component/Counter/CountdownTimer';
|
||||||
|
import FontsFamily from '../../Constant/FontsFamily';
|
||||||
|
|
||||||
/* ---------------- Types ---------------- */
|
const StartBidding = () => {
|
||||||
interface AuctionItem {
|
const SelectedAuction = useSelector((state: any) => state.auction.auction);
|
||||||
id: number;
|
const loginUser = useSelector((state: any) => state.token.token)
|
||||||
productName: string;
|
const Navigation: any = useNavigation()
|
||||||
auctionStartValueFigure: number;
|
const [items, setItems] = useState<any>([]);
|
||||||
bidVariationValue: number;
|
const [bidValues, setBidValues] = useState<Record<number, number>>({});
|
||||||
bidAmount: number;
|
const [allBoolean, setAllBoolean] = useState({ showSuccess: false, showDialog: false, bidPayload: {} })
|
||||||
bidAvilable: number;
|
const { subscribe, createRoom, placeBid } = useWebSocketService(
|
||||||
me: boolean;
|
Variables.webSocketUrl,
|
||||||
}
|
() => console.log('Connected!'),
|
||||||
|
(error) => console.log('WebSocket Error:', error),
|
||||||
|
loginUser.token,
|
||||||
|
);
|
||||||
|
|
||||||
/* ---------------- Dummy Data ---------------- */
|
const getAllAcutionItems = async () => {
|
||||||
const DUMMY_AUCTION = { auctionNumber: 'AUC-2025-001' };
|
try {
|
||||||
const DUMMY_ITEMS: AuctionItem[] = [
|
const payload = { auctionNumber: SelectedAuction.auctionNumber };
|
||||||
{ id: 1, productName: 'Iron Scrap Lot', auctionStartValueFigure: 20000, bidVariationValue: 500, bidAmount: 20000, bidAvilable: 20000, me: false },
|
let auctionItem: any[] = [];
|
||||||
{ id: 2, productName: 'Steel Rod Bundle', auctionStartValueFigure: 35000, bidVariationValue: 1000, bidAmount: 35000, bidAvilable: 35000, me: true },
|
|
||||||
{ id: 3, productName: 'Copper Wire Roll', auctionStartValueFigure: 15000, bidVariationValue: 250, bidAmount: 15000, bidAvilable: 0, me: false },
|
|
||||||
];
|
|
||||||
|
|
||||||
/* ---------------- Bidding Card ---------------- */
|
if (SelectedAuction.auctionPattern === 'Forward') {
|
||||||
const BiddingCard = ({ item, bidValue, onIncrease, onDecrease, onPlaceBid }: any) => {
|
const res = await apiCall<any>('get', FORWARD_AUCTION_ITEM, {}, payload);
|
||||||
const [expanded, setExpanded] = useState(false);
|
if (res?.statusCode === 200) auctionItem = res.data || [];
|
||||||
const isMin = bidValue <= item.bidAmount;
|
} else {
|
||||||
|
const res = await apiCall<any>('get', REVERSE_AUCTION_ITEM, {}, payload);
|
||||||
|
if (res?.statusCode === 200) auctionItem = res.data || [];
|
||||||
|
}
|
||||||
|
|
||||||
const animation = useSharedValue(0);
|
const selectedRes = await apiCall<any>('get', SELECTED_AUCTION_ITEM, {}, payload);
|
||||||
|
console.log(selectedRes,'jhhhhhhhhhh');
|
||||||
|
|
||||||
const toggleExpand = () => {
|
const uniqueArray: number[] = Array.from(
|
||||||
setExpanded(!expanded);
|
new Set(selectedRes?.data || [])
|
||||||
animation.value = withSpring(expanded ? 0 : 1, { damping: 15 });
|
);
|
||||||
|
|
||||||
|
const filteredItems = auctionItem.filter(item =>
|
||||||
|
uniqueArray.includes(item.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const result = await createRoom(SelectedAuction.auctionNumber);
|
||||||
|
|
||||||
|
subscribe(`/topic/room/${SelectedAuction.auctionNumber}`, data => {
|
||||||
|
console.log('🔥 BID UPDATE:', data);
|
||||||
|
});
|
||||||
|
|
||||||
|
const bidAmountMap2 = new Map<number, { bidAmount: number; contractorId: number }>();
|
||||||
|
|
||||||
|
(result || []).forEach((r: any) => {
|
||||||
|
bidAmountMap2.set(r.auctionItemId, {
|
||||||
|
bidAmount: r.bidAmount,
|
||||||
|
contractorId: r.contractorId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const bidAmountMap = new Map<number, number>();
|
||||||
|
|
||||||
|
(result || []).forEach((r: any) => {
|
||||||
|
bidAmountMap.set(r.auctionItemId, r.bidAmount);
|
||||||
|
});
|
||||||
|
|
||||||
|
const updatedFilteredItems = filteredItems.map(item => {
|
||||||
|
const bidData = bidAmountMap2.get(item.id);
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
bidAmount: bidData?.bidAmount ?? item.auctionStartValueFigure,
|
||||||
|
bidAvilable: bidData?.bidAmount ?? 0,
|
||||||
|
me: bidData?.contractorId == loginUser.contractorId ? true : false
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const initialBids: Record<number, number> = {};
|
||||||
|
updatedFilteredItems.forEach(item => {
|
||||||
|
initialBids[item.id] = item.bidAmount;
|
||||||
|
});
|
||||||
|
setBidValues(initialBids);
|
||||||
|
setItems(updatedFilteredItems);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching auction items:', error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const bodyStyle = useAnimatedStyle(() => {
|
subscribe(`/topic/room/${SelectedAuction.auctionNumber}`, async (message) => {
|
||||||
return {
|
// console.log('RAW MESSAGE:', message[message.length - 1]);
|
||||||
height: interpolate(animation.value, [0, 1], [0, 190]),
|
const result = message[message.length - 1]
|
||||||
opacity: interpolate(animation.value, [0, 0.5, 1], [0, 0, 1]),
|
|
||||||
marginTop: interpolate(animation.value, [0, 1], [0, 15]),
|
const updatedBidItem = (prev: any[]) =>
|
||||||
};
|
prev.map(item =>
|
||||||
|
item.id === result.auctionItemId
|
||||||
|
? { ...item, bidAmount: result.bidAmount, me: result.contractorId == loginUser.contractorId ? true : false }
|
||||||
|
: item
|
||||||
|
);
|
||||||
|
|
||||||
|
setItems(updatedBidItem);
|
||||||
|
|
||||||
|
setBidValues(prev => ({
|
||||||
|
...prev,
|
||||||
|
[result.auctionItemId]: result.bidAmount,
|
||||||
|
}));
|
||||||
|
try {
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.log('JSON parse error:', err);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const arrowStyle = useAnimatedStyle(() => ({
|
useEffect(() => {
|
||||||
transform: [{ rotate: `${interpolate(animation.value, [0, 1], [0, 180])}deg` }],
|
getAllAcutionItems();
|
||||||
}));
|
subscribe(`/topic/room/${SelectedAuction.auctionNumber}`, (data) => { });
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
|
||||||
<Animated.View
|
|
||||||
layout={Layout.springify()}
|
|
||||||
entering={FadeInUp.delay(item.id * 100)}
|
|
||||||
style={[styles.card, item.me && styles.leadingCard]}
|
|
||||||
>
|
|
||||||
{/* Header - Always Visible */}
|
|
||||||
<TouchableOpacity
|
|
||||||
activeOpacity={0.7}
|
|
||||||
onPress={toggleExpand}
|
|
||||||
style={styles.cardHeader}
|
|
||||||
>
|
|
||||||
<View style={{ flex: 1 }}>
|
|
||||||
<Text style={styles.productName}>{item.productName}</Text>
|
|
||||||
<Text style={styles.itemIdText}>{DUMMY_AUCTION.auctionNumber}</Text>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View style={styles.headerRight}>
|
|
||||||
<View style={[styles.badge, item.me ? styles.meBadge : styles.liveBadge]}>
|
|
||||||
<Text style={[styles.badgeText, item.me ? styles.meText : styles.liveText]}>
|
|
||||||
{item.me ? 'LEADING' : 'LIVE'}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
<Animated.Text style={[styles.arrow, arrowStyle]}>▼</Animated.Text>
|
|
||||||
</View>
|
|
||||||
</TouchableOpacity>
|
|
||||||
|
|
||||||
{/* Main Price Info - Always Visible */}
|
|
||||||
<View style={styles.priceRow}>
|
|
||||||
<View>
|
|
||||||
<Text style={styles.label}>Current Bid</Text>
|
|
||||||
<Text style={styles.mainPrice}>₹{item.bidAmount.toLocaleString()}</Text>
|
|
||||||
</View>
|
|
||||||
<View style={{ alignItems: 'flex-end' }}>
|
|
||||||
<Text style={styles.label}>Increment</Text>
|
|
||||||
<Text style={styles.incrementText}>+₹{item.bidVariationValue}</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
{/* Collapsible Section */}
|
|
||||||
<Animated.View style={[styles.collapsibleContainer, bodyStyle]}>
|
|
||||||
<View style={styles.divider} />
|
|
||||||
|
|
||||||
<Text style={styles.bidLabel}>Set Your Bid</Text>
|
|
||||||
<View style={styles.stepperContainer}>
|
|
||||||
<TouchableOpacity
|
|
||||||
onPress={onDecrease}
|
|
||||||
disabled={isMin}
|
|
||||||
style={[styles.stepBtn, isMin && styles.disabledBtn]}
|
|
||||||
>
|
|
||||||
<Text style={styles.stepText}>−</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
|
|
||||||
<View style={styles.inputBox}>
|
|
||||||
<Text style={styles.currency}>₹</Text>
|
|
||||||
<Text style={styles.bidValueText}>{bidValue.toLocaleString()}</Text>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<TouchableOpacity onPress={onIncrease} style={styles.stepBtn}>
|
|
||||||
<Text style={styles.stepText}>+</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<TouchableOpacity
|
|
||||||
style={styles.submitBtn}
|
|
||||||
onPress={onPlaceBid}
|
|
||||||
activeOpacity={0.8}
|
|
||||||
>
|
|
||||||
<Text style={styles.submitBtnText}>Confirm Bid</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</Animated.View>
|
|
||||||
</Animated.View>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ---------------- Main Screen ---------------- */
|
|
||||||
const StartBidding = () => {
|
|
||||||
const [items, setItems] = useState<AuctionItem[]>(DUMMY_ITEMS);
|
|
||||||
const [bidValues, setBidValues] = useState<Record<number, number>>({});
|
|
||||||
const [showSuccess, setShowSuccess] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const initial: Record<number, number> = {};
|
const initial: Record<number, number> = {};
|
||||||
items.forEach(item => {
|
items.forEach((item: any) => {
|
||||||
initial[item.id] = item.bidAmount + item.bidVariationValue;
|
initial[item.id] = item.bidAmount + item.bidVariationValue;
|
||||||
});
|
});
|
||||||
setBidValues(initial);
|
setBidValues(initial);
|
||||||
@@ -158,38 +140,133 @@ const StartBidding = () => {
|
|||||||
setBidValues(prev => ({ ...prev, [id]: prev[id] + val }));
|
setBidValues(prev => ({ ...prev, [id]: prev[id] + val }));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePlaceBid = (item: AuctionItem) => {
|
const submitBid = async (item: any) => {
|
||||||
Alert.alert('Confirm', `Place bid for ₹${bidValues[item.id]}?`, [
|
const payload = {
|
||||||
{ text: 'No' },
|
itemId: item.id,
|
||||||
{
|
bidAmount: bidValues[item.id],
|
||||||
text: 'Yes, Bid',
|
auctionId: SelectedAuction.auctionId,
|
||||||
onPress: () => {
|
contractorId: loginUser.contractorId,
|
||||||
setItems(prev => prev.map(i => i.id === item.id ? { ...i, bidAmount: bidValues[item.id], me: true } : i));
|
fullName: loginUser.fullName,
|
||||||
setShowSuccess(true);
|
roomId: SelectedAuction.auctionNumber,
|
||||||
setTimeout(() => setShowSuccess(false), 2000);
|
};
|
||||||
}
|
setAllBoolean((prev: any) => ({ ...prev, bidPayload: payload, }));
|
||||||
}
|
Alert.alert(
|
||||||
]);
|
'Confirm Bid',
|
||||||
|
`Are you sure you want to place a bid of ₹${payload.bidAmount}?`,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
text: 'Cancel',
|
||||||
|
style: 'cancel',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Submit',
|
||||||
|
onPress: () => {
|
||||||
|
|
||||||
|
placeBidSubmit(payload);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
{ cancelable: true }
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const placeBidSubmit = async (data: any) => {
|
||||||
|
try {
|
||||||
|
const result: any = await placeBid(data);
|
||||||
|
|
||||||
|
if (result?.status && result.data) {
|
||||||
|
const updatedBidItem = (prev: any[]) =>
|
||||||
|
prev.map(item =>
|
||||||
|
item.id === result.data.auctionItemId
|
||||||
|
? { ...item, bidAmount: result.data.bidAmount, me: result.data?.contractorId == loginUser.contractorId ? true : false }
|
||||||
|
: item
|
||||||
|
);
|
||||||
|
|
||||||
|
// setItems(updatedBidItem);
|
||||||
|
|
||||||
|
|
||||||
|
// setBidValues((prev: any) => ({
|
||||||
|
// ...prev,
|
||||||
|
// [result.data.auctionItemId]: {
|
||||||
|
// ...prev[result.data.auctionItemId],
|
||||||
|
// bidAmount: result.data.bidAmount,
|
||||||
|
// },
|
||||||
|
// }));
|
||||||
|
getAllAcutionItems()
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error placing bid:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
const onBackPress = () => {
|
||||||
|
Alert.alert(
|
||||||
|
'Confirm',
|
||||||
|
'Do you want to go back to Dashboard?',
|
||||||
|
[
|
||||||
|
{ text: 'Cancel', style: 'cancel' },
|
||||||
|
{
|
||||||
|
text: 'Yes',
|
||||||
|
onPress: () => {
|
||||||
|
Navigation.dispatch(
|
||||||
|
CommonActions.reset({
|
||||||
|
index: 0,
|
||||||
|
routes: [{ name: NavigationString.Home }],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
{ cancelable: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
return true; // block default back action
|
||||||
|
};
|
||||||
|
|
||||||
|
const subscription = BackHandler.addEventListener(
|
||||||
|
'hardwareBackPress',
|
||||||
|
onBackPress
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => subscription.remove();
|
||||||
|
}, [Navigation])
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<InsideHeader title="Bidding Panel" showArrow />
|
<InsideHeader title="Bidding Panel" showArrow />
|
||||||
|
<View style={styles.container2}>
|
||||||
|
<Text style={styles.title}>
|
||||||
|
{SelectedAuction.deptName}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<View style={styles.timerWrapper}>
|
||||||
|
<CountdownTimer
|
||||||
|
endDate={SelectedAuction.keyDates.auctionBidding.endDateTime}
|
||||||
|
myStyle={{ fontSize: 30 }}
|
||||||
|
size={30}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
<FlatList
|
<FlatList
|
||||||
data={items}
|
data={items}
|
||||||
keyExtractor={item => item.id.toString()}
|
keyExtractor={item => item.id.toString()}
|
||||||
renderItem={({ item }) => (
|
renderItem={({ item, index }) => (
|
||||||
<BiddingCard
|
<BiddingCard
|
||||||
item={item}
|
item={{ ...item, index }}
|
||||||
bidValue={bidValues[item.id] || 0}
|
bidValue={bidValues[item.id] || 0}
|
||||||
onIncrease={() => handleUpdate(item.id, item.bidVariationValue)}
|
onIncrease={() => handleUpdate(item.id, item.bidVariationValue)}
|
||||||
onDecrease={() => handleUpdate(item.id, -item.bidVariationValue)}
|
onDecrease={() => handleUpdate(item.id, -item.bidVariationValue)}
|
||||||
onPlaceBid={() => handlePlaceBid(item)}
|
onPlaceBid={() => { submitBid(item) }}
|
||||||
|
SelectedAuction={SelectedAuction}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
contentContainerStyle={{ padding: 16 }}
|
contentContainerStyle={{ padding: 16 }}
|
||||||
/>
|
/>
|
||||||
{showSuccess && (
|
|
||||||
|
{allBoolean.showSuccess && (
|
||||||
<View style={styles.overlay}>
|
<View style={styles.overlay}>
|
||||||
<LottieView
|
<LottieView
|
||||||
source={require('../../lottie/Success.json')}
|
source={require('../../lottie/Success.json')}
|
||||||
@@ -205,9 +282,23 @@ const StartBidding = () => {
|
|||||||
|
|
||||||
export default StartBidding;
|
export default StartBidding;
|
||||||
|
|
||||||
/* ---------------- Modern Styles ---------------- */
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: { flex: 1, backgroundColor: colors.white },
|
container: { flex: 1, backgroundColor: colors.white },
|
||||||
|
container2: {
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
paddingTop: 12,
|
||||||
|
paddingBottom: 8,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontFamily: FontsFamily.poppinsSemiBold,
|
||||||
|
color: colors.black,
|
||||||
|
marginBottom: 6,
|
||||||
|
// textAlign:'center'
|
||||||
|
},
|
||||||
|
timerWrapper: {
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
card: {
|
card: {
|
||||||
backgroundColor: '#FFF',
|
backgroundColor: '#FFF',
|
||||||
borderRadius: 24,
|
borderRadius: 24,
|
||||||
|
|||||||
@@ -0,0 +1,401 @@
|
|||||||
|
import React, { useCallback, useEffect, useState } from 'react';
|
||||||
|
import { View, FlatList, StyleSheet, Platform, Alert, BackHandler, Text, ToastAndroid } from 'react-native';
|
||||||
|
import LottieView from 'lottie-react-native';
|
||||||
|
import { InsideHeader } from '../../Component/Index';
|
||||||
|
import colors from '../../Constant/Color';
|
||||||
|
import { useWebSocketService } from '../../socket/Socket';
|
||||||
|
import Variables from '../../Constant/Variable';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
|
import { apiCall } from '../../Axios/Axios';
|
||||||
|
import { AUCTION_ONE_TIME_BID, GET_AUCTION_DETAILS, REVERSE_AUCTION_ITEM, SELECTED_AUCTION_ITEM } from '../../Services/BBPS/ApiUrls';
|
||||||
|
import { CommonActions, useFocusEffect, useNavigation } from '@react-navigation/native';
|
||||||
|
import NavigationString from '../../Constant/NavigationString';
|
||||||
|
import CountdownTimer from '../../Component/Counter/CountdownTimer';
|
||||||
|
import FontsFamily from '../../Constant/FontsFamily';
|
||||||
|
import ReverseBiddingCard from './Component/ReverseBiddingCard';
|
||||||
|
|
||||||
|
const StartReverseBidding = () => {
|
||||||
|
const SelectedAuction = useSelector((state: any) => state.auction.auction);
|
||||||
|
const loginUser = useSelector((state: any) => state.token.token)
|
||||||
|
const Navigation: any = useNavigation()
|
||||||
|
const [items, setItems] = useState<any>([]);
|
||||||
|
const [bidValues, setBidValues] = useState<Record<number, number>>({});
|
||||||
|
const [allBoolean, setAllBoolean] = useState({ showSuccess: false, showDialog: false, bidPayload: {}, oneTimeBid: false, rebid: false, reload: false })
|
||||||
|
const { subscribe, createRoom, placeBid } = useWebSocketService(
|
||||||
|
Variables.webSocketUrl,
|
||||||
|
() => console.log('Connected!'),
|
||||||
|
(error) => console.log('WebSocket Error:', error),
|
||||||
|
loginUser.token,
|
||||||
|
);
|
||||||
|
const getAuction = async () => {
|
||||||
|
const selectedRes = await apiCall<any>('get', GET_AUCTION_DETAILS, {}, { id: SelectedAuction.auctionId });
|
||||||
|
if (selectedRes.statusCode == 200 && selectedRes.data.contractorId.length) {
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, oneTimeBid: true }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getOneTimeBidValue = async () => {
|
||||||
|
try {
|
||||||
|
const selectedRes = await apiCall<any>('get', AUCTION_ONE_TIME_BID, {}, { auctionId: SelectedAuction.auctionId });
|
||||||
|
if (selectedRes.statusCode == 200) {
|
||||||
|
return selectedRes.data
|
||||||
|
} else {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const getAllAcutionItems = async () => {
|
||||||
|
try {
|
||||||
|
const payload = { auctionNumber: SelectedAuction.auctionNumber };
|
||||||
|
let auctionItem: any[] = [];
|
||||||
|
|
||||||
|
if (SelectedAuction.auctionPattern === 'Reverse') {
|
||||||
|
const res = await apiCall<any>('get', REVERSE_AUCTION_ITEM, {}, payload);
|
||||||
|
if (res?.statusCode === 200) auctionItem = res.data || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedRes = await apiCall<any>('get', SELECTED_AUCTION_ITEM, {}, payload);
|
||||||
|
|
||||||
|
const uniqueArray: number[] = Array.from(
|
||||||
|
new Set(selectedRes?.data || [])
|
||||||
|
);
|
||||||
|
|
||||||
|
const filteredItems = auctionItem.filter(item =>
|
||||||
|
uniqueArray.includes(item.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (SelectedAuction.auctionCategories == 'Live') {
|
||||||
|
const result = await createRoom(SelectedAuction.auctionNumber);
|
||||||
|
|
||||||
|
subscribe(`/topic/room/${SelectedAuction.auctionNumber}`, data => {
|
||||||
|
console.log('🔥 BID UPDATE:', data);
|
||||||
|
});
|
||||||
|
const bidAmountMap2 = new Map<number, { bidAmount: number; contractorId: number }>();
|
||||||
|
|
||||||
|
(result || []).forEach((r: any) => {
|
||||||
|
bidAmountMap2.set(r.auctionItemId, {
|
||||||
|
bidAmount: r.bidAmount,
|
||||||
|
contractorId: r.contractorId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// Check One Time bid enable butoon
|
||||||
|
if (SelectedAuction.auctionCategories != 'Live') {
|
||||||
|
const myBid = result.find(
|
||||||
|
(bid: any) => bid.contractorId === loginUser.contractorId
|
||||||
|
);
|
||||||
|
|
||||||
|
if (myBid) {
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, oneTimeBid: true }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const bidAmountMap = new Map<number, number>();
|
||||||
|
|
||||||
|
(result || []).forEach((r: any) => {
|
||||||
|
bidAmountMap.set(r.auctionItemId, r.bidAmount);
|
||||||
|
});
|
||||||
|
|
||||||
|
const updatedFilteredItems = filteredItems.map(item => {
|
||||||
|
const bidData = bidAmountMap2.get(item.id);
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
bidAmount: bidData?.bidAmount ?? item.auctionStartValue,
|
||||||
|
bidAvilable: bidData?.bidAmount ?? 0,
|
||||||
|
me: bidData?.contractorId == loginUser.contractorId ? true : false
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const initialBids: Record<number, number> = {};
|
||||||
|
updatedFilteredItems.forEach(item => {
|
||||||
|
initialBids[item.id] = item.bidAmount;
|
||||||
|
});
|
||||||
|
setBidValues(initialBids);
|
||||||
|
setItems(updatedFilteredItems);
|
||||||
|
} else {
|
||||||
|
let result = []
|
||||||
|
if (SelectedAuction.rebidAllowed) {
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, rebid: true }))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SelectedAuction.auctionCategories != 'Live') {
|
||||||
|
result = await getOneTimeBidValue()
|
||||||
|
}
|
||||||
|
const bidMap = new Map<number, any>();
|
||||||
|
|
||||||
|
result.forEach((bid: any) => {
|
||||||
|
bidMap.set(bid.auctionItemId, bid);
|
||||||
|
});
|
||||||
|
const mergedData = auctionItem.map((item: any) => {
|
||||||
|
const bid = bidMap.get(item.id);
|
||||||
|
|
||||||
|
if (!bid) {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
bidAmount: item.auctionStartValue,
|
||||||
|
contractorId: item.contractorId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
bidAmount: bid.bidAmount,
|
||||||
|
bidId: bid.bidId,
|
||||||
|
contractorId: bid.contractorId,
|
||||||
|
contractorName: bid.contractorName,
|
||||||
|
me: bid.contractorId === loginUser.contractorId,
|
||||||
|
bidTime: bid.bidTime,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const initialBids: Record<number, number> = {};
|
||||||
|
mergedData.forEach(item => {
|
||||||
|
initialBids[item.id] = item.bidAmount;
|
||||||
|
});
|
||||||
|
setBidValues(initialBids);
|
||||||
|
setItems(mergedData)
|
||||||
|
setBidValues(initialBids);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching auction items:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
subscribe(`/topic/room/${SelectedAuction.auctionNumber}`, async (message) => {
|
||||||
|
|
||||||
|
const result = message[message.length - 1]
|
||||||
|
|
||||||
|
const updatedBidItem = (prev: any[]) =>
|
||||||
|
prev.map(item =>
|
||||||
|
item.id === result.auctionItemId
|
||||||
|
? { ...item, bidAmount: result.bidAmount, me: result.contractorId == loginUser.contractorId ? true : false }
|
||||||
|
: item
|
||||||
|
);
|
||||||
|
|
||||||
|
setItems(updatedBidItem);
|
||||||
|
|
||||||
|
setBidValues(prev => ({
|
||||||
|
...prev,
|
||||||
|
[result.auctionItemId]: result.bidAmount,
|
||||||
|
}));
|
||||||
|
try {
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.log('JSON parse error:', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (SelectedAuction.auctionCategories == 'One-time') {
|
||||||
|
getAuction()
|
||||||
|
}
|
||||||
|
getAllAcutionItems();
|
||||||
|
subscribe(`/topic/room/${SelectedAuction.auctionNumber}`, (data) => { });
|
||||||
|
}, [allBoolean.reload]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const initial: Record<number, number> = {};
|
||||||
|
items.forEach((item: any) => {
|
||||||
|
initial[item.id] = item.bidAmount + item.bidVariationValue;
|
||||||
|
});
|
||||||
|
setBidValues(initial);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleUpdate = (id: number, val: number) => {
|
||||||
|
setBidValues(prev => ({ ...prev, [id]: prev[id] + val }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const submitBid = async (item: any) => {
|
||||||
|
const payload = {
|
||||||
|
itemId: item.id,
|
||||||
|
bidAmount: bidValues[item.id],
|
||||||
|
auctionId: SelectedAuction.auctionId,
|
||||||
|
contractorId: loginUser.contractorId,
|
||||||
|
fullName: loginUser.fullName,
|
||||||
|
roomId: SelectedAuction.auctionNumber,
|
||||||
|
};
|
||||||
|
setAllBoolean((prev: any) => ({ ...prev, bidPayload: payload, }));
|
||||||
|
Alert.alert(
|
||||||
|
'Confirm Bid',
|
||||||
|
`Are you sure you want to place a bid of ₹${payload.bidAmount}?`,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
text: 'Cancel',
|
||||||
|
style: 'cancel',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Submit',
|
||||||
|
onPress: () => {
|
||||||
|
placeBidSubmit(payload);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
{ cancelable: true }
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const placeBidSubmit = async (data: any) => {
|
||||||
|
try {
|
||||||
|
const result: any = await placeBid(data);
|
||||||
|
console.log(result, 'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk');
|
||||||
|
|
||||||
|
if (result?.status && result.data) {
|
||||||
|
const updatedBidItem = (prev: any[]) =>
|
||||||
|
prev.map(item =>
|
||||||
|
item.id === result.data.auctionItemId
|
||||||
|
? { ...item, bidAmount: result.data.bidAmount, me: result.data?.contractorId == loginUser.contractorId ? true : false }
|
||||||
|
: item
|
||||||
|
);
|
||||||
|
|
||||||
|
getAllAcutionItems()
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error placing bid:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
const onBackPress = () => {
|
||||||
|
Alert.alert(
|
||||||
|
'Confirm',
|
||||||
|
'Do you want to go back to Dashboard?',
|
||||||
|
[
|
||||||
|
{ text: 'Cancel', style: 'cancel' },
|
||||||
|
{
|
||||||
|
text: 'Yes',
|
||||||
|
onPress: () => {
|
||||||
|
Navigation.dispatch(
|
||||||
|
CommonActions.reset({
|
||||||
|
index: 0,
|
||||||
|
routes: [{ name: NavigationString.Home }],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
{ cancelable: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
return true; // block default back action
|
||||||
|
};
|
||||||
|
|
||||||
|
const subscription = BackHandler.addEventListener(
|
||||||
|
'hardwareBackPress',
|
||||||
|
onBackPress
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => subscription.remove();
|
||||||
|
}, [Navigation])
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<InsideHeader title="Bidding Panel" showArrow />
|
||||||
|
<View style={styles.container2}>
|
||||||
|
<Text style={styles.title}>
|
||||||
|
{SelectedAuction.deptName}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<View style={styles.timerWrapper}>
|
||||||
|
<CountdownTimer
|
||||||
|
endDate={SelectedAuction.keyDates.auctionBidding.endDateTime}
|
||||||
|
myStyle={{ fontSize: 30 }}
|
||||||
|
size={30}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<FlatList
|
||||||
|
data={items}
|
||||||
|
keyExtractor={item => item.id.toString()}
|
||||||
|
renderItem={({ item, index }) => (
|
||||||
|
<ReverseBiddingCard
|
||||||
|
item={{ ...item, index }}
|
||||||
|
bidValue={bidValues[item.id] || 0}
|
||||||
|
onIncrease={() => handleUpdate(item.id, item.emdAmount)}
|
||||||
|
onDecrease={() => handleUpdate(item.id, -item.emdAmount)}
|
||||||
|
onPlaceBid={() => { submitBid(item) }}
|
||||||
|
SelectedAuction={SelectedAuction}
|
||||||
|
allBoolean={allBoolean}
|
||||||
|
setAllBoolean={setAllBoolean}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
contentContainerStyle={{ padding: 16 }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{allBoolean.showSuccess && (
|
||||||
|
<View style={styles.overlay}>
|
||||||
|
<LottieView
|
||||||
|
source={require('../../lottie/Success.json')}
|
||||||
|
autoPlay
|
||||||
|
loop={false}
|
||||||
|
style={{ width: 200, height: 200 }}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default StartReverseBidding;
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: { flex: 1, backgroundColor: colors.white },
|
||||||
|
container2: {
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
paddingTop: 12,
|
||||||
|
paddingBottom: 8,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontFamily: FontsFamily.poppinsSemiBold,
|
||||||
|
color: colors.black,
|
||||||
|
marginBottom: 6,
|
||||||
|
// textAlign:'center'
|
||||||
|
},
|
||||||
|
timerWrapper: {
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
card: {
|
||||||
|
backgroundColor: '#FFF',
|
||||||
|
borderRadius: 24,
|
||||||
|
padding: 20,
|
||||||
|
marginBottom: 16,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: '#E2E8F0',
|
||||||
|
overflow: 'hidden',
|
||||||
|
...Platform.select({ ios: { shadowColor: '#000', shadowOpacity: 0.05, shadowRadius: 10 }, android: { elevation: 2 } }),
|
||||||
|
},
|
||||||
|
leadingCard: { borderColor: '#22C55E', borderWidth: 2, backgroundColor: '#F0FDF4' },
|
||||||
|
cardHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start' },
|
||||||
|
headerRight: { flexDirection: 'row', alignItems: 'center', gap: 8 },
|
||||||
|
productName: { fontSize: 18, fontWeight: 'bold', color: '#1E293B' },
|
||||||
|
itemIdText: { fontSize: 12, color: '#64748B', marginTop: 2 },
|
||||||
|
badge: { paddingHorizontal: 10, paddingVertical: 4, borderRadius: 8 },
|
||||||
|
liveBadge: { backgroundColor: '#FEE2E2' },
|
||||||
|
meBadge: { backgroundColor: '#BBF7D0' },
|
||||||
|
badgeText: { fontSize: 10, fontWeight: '900' },
|
||||||
|
liveText: { color: '#EF4444' },
|
||||||
|
meText: { color: '#15803D' },
|
||||||
|
arrow: { fontSize: 10, color: '#94A3B8' },
|
||||||
|
priceRow: { flexDirection: 'row', justifyContent: 'space-between', marginTop: 20 },
|
||||||
|
label: { fontSize: 11, color: '#94A3B8', textTransform: 'uppercase', fontWeight: '600' },
|
||||||
|
mainPrice: { fontSize: 22, fontWeight: '900', color: '#0F172A' },
|
||||||
|
incrementText: { fontSize: 16, fontWeight: '700', color: '#3B82F6' },
|
||||||
|
collapsibleContainer: { overflow: 'hidden' },
|
||||||
|
divider: { height: 1, backgroundColor: '#E2E8F0', marginVertical: 10 },
|
||||||
|
bidLabel: { fontSize: 13, fontWeight: '600', color: '#475569', marginBottom: 10 },
|
||||||
|
stepperContainer: { flexDirection: 'row', gap: 12, marginBottom: 20 },
|
||||||
|
stepBtn: { width: 45, height: 45, backgroundColor: colors.primary, borderRadius: 12, justifyContent: 'center', alignItems: 'center' },
|
||||||
|
disabledBtn: { backgroundColor: '#CBD5E1' },
|
||||||
|
stepText: { color: '#FFF', fontSize: 20, fontWeight: 'bold' },
|
||||||
|
inputBox: { flex: 1, height: 45, backgroundColor: '#F1F5F9', borderRadius: 12, flexDirection: 'row', alignItems: 'center', justifyContent: 'center' },
|
||||||
|
currency: { fontSize: 16, fontWeight: 'bold', color: '#64748B', marginRight: 4 },
|
||||||
|
bidValueText: { fontSize: 18, fontWeight: '800', color: '#0F172A' },
|
||||||
|
submitBtn: { height: 50, backgroundColor: colors.primary, borderRadius: 15, justifyContent: 'center', alignItems: 'center' },
|
||||||
|
submitBtnText: { color: '#FFF', fontSize: 16, fontWeight: 'bold' },
|
||||||
|
overlay: { ...StyleSheet.absoluteFillObject, backgroundColor: 'rgba(255,255,255,0.7)', justifyContent: 'center', alignItems: 'center', zIndex: 99 },
|
||||||
|
});
|
||||||
@@ -15,4 +15,21 @@ export type allBooleanType = {
|
|||||||
activeItemId: number | null
|
activeItemId: number | null
|
||||||
acitveItemData: any
|
acitveItemData: any
|
||||||
timeEnd: boolean
|
timeEnd: boolean
|
||||||
}
|
}
|
||||||
|
export interface Props {
|
||||||
|
visible: boolean
|
||||||
|
setAllBoolean: any
|
||||||
|
allBoolean: any
|
||||||
|
template: any
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export type SelectedItem = {
|
||||||
|
auctionItemId: number;
|
||||||
|
productImageName: string;
|
||||||
|
file: {
|
||||||
|
name: string;
|
||||||
|
uri: string;
|
||||||
|
type: string;
|
||||||
|
} | null;
|
||||||
|
};
|
||||||
@@ -3,6 +3,7 @@ import PurchaseAuctionList from "./Auction/PurchaseAuctionList";
|
|||||||
import PurchaseList from "./Auction/PurchaseList";
|
import PurchaseList from "./Auction/PurchaseList";
|
||||||
import Emd from "./Bidding/Emd";
|
import Emd from "./Bidding/Emd";
|
||||||
import StartBidding from "./Bidding/StartBidding";
|
import StartBidding from "./Bidding/StartBidding";
|
||||||
|
import StartReverseBidding from "./Bidding/StartReverseBidding";
|
||||||
import Home from "./Home/Home";
|
import Home from "./Home/Home";
|
||||||
import Login from "./Login/Login";
|
import Login from "./Login/Login";
|
||||||
import Onboarding from "./Onboarding/Onboarding";
|
import Onboarding from "./Onboarding/Onboarding";
|
||||||
@@ -28,6 +29,7 @@ const Screens = {
|
|||||||
PurchaseTenderList,
|
PurchaseTenderList,
|
||||||
ProceedToPurTender,
|
ProceedToPurTender,
|
||||||
TenderBidding,
|
TenderBidding,
|
||||||
ProceedToBidDetail
|
ProceedToBidDetail,
|
||||||
|
StartReverseBidding
|
||||||
}
|
}
|
||||||
export default Screens
|
export default Screens
|
||||||
@@ -41,7 +41,7 @@ const GET_DOCID = `${BASE_URL}eTendering/download/docId?docId=`
|
|||||||
const DOWNLOAD_DOC = `${BASE_URL}eTendering/download/docId?docId=`
|
const DOWNLOAD_DOC = `${BASE_URL}eTendering/download/docId?docId=`
|
||||||
const TWO_FACTOR_AUTH = `${BASE_URL}contractor/two-factor-auth?status=`
|
const TWO_FACTOR_AUTH = `${BASE_URL}contractor/two-factor-auth?status=`
|
||||||
const AUCTION_LOGIN = `https://api.godemo.in/Auction/auction/loginWithoutDecryption`
|
const AUCTION_LOGIN = `https://api.godemo.in/Auction/auction/loginWithoutDecryption`
|
||||||
const GET_AUCTION_DETAILS = `${BASE_URL_Auction}api/auction/getAuction/id?id=`
|
const GET_AUCTION_DETAILS = `${BASE_URL_Auction}api/auction/getAuction/id`
|
||||||
const TANDER_PURCHASE_STATUS = `https://procurelinc.in/EProcurementSB/tenderPayment/transactionStatus?orderNo=`
|
const TANDER_PURCHASE_STATUS = `https://procurelinc.in/EProcurementSB/tenderPayment/transactionStatus?orderNo=`
|
||||||
const GET_MY_AUCTION = `${BASE_URL_Auction}api/auction/getMyAuction`
|
const GET_MY_AUCTION = `${BASE_URL_Auction}api/auction/getMyAuction`
|
||||||
const GET_MY_TENDER = "https://procurelinc.in/EProcurementSB/tenderBidding/getAllPurchasedTendersByConId"
|
const GET_MY_TENDER = "https://procurelinc.in/EProcurementSB/tenderBidding/getAllPurchasedTendersByConId"
|
||||||
@@ -62,6 +62,7 @@ const ITEM_DOCUMENT_DOWNLOAD = `${BASE_URL_Auction}api/auction/home/downloadDocu
|
|||||||
|
|
||||||
// Rohit
|
// Rohit
|
||||||
const DASHBOARD_COUNT = `${BASE_URL_Auction}api/auction/home/dashboard/counts`
|
const DASHBOARD_COUNT = `${BASE_URL_Auction}api/auction/home/dashboard/counts`
|
||||||
|
const AUCTION_ONE_TIME_BID =`${BASE_URL_Auction}api/bidding/getBidForAuction`
|
||||||
|
|
||||||
//tender
|
//tender
|
||||||
|
|
||||||
@@ -77,6 +78,7 @@ const SUBMIT_ENVELOPE_FILE_B = `${BASE_URL}tenderBidding/addDocumentsEnvelopeB?r
|
|||||||
export {
|
export {
|
||||||
// Rohit
|
// Rohit
|
||||||
DASHBOARD_COUNT,
|
DASHBOARD_COUNT,
|
||||||
|
AUCTION_ONE_TIME_BID,
|
||||||
ITEM_DOCUMENT_DOWNLOAD,
|
ITEM_DOCUMENT_DOWNLOAD,
|
||||||
ITEM_DETAIL,
|
ITEM_DETAIL,
|
||||||
TECHNICAL_DOCUMENT_SUBMIT,
|
TECHNICAL_DOCUMENT_SUBMIT,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query';
|
import { useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query';
|
||||||
|
import { fetchAuctionItem, fetchDashboard, fetchEmdCheck, fetchLiveAuction, fetchLiveTender, fetchPurchaseAuction, fetchPurchaseTender, offlineAuctionPurchase, userLogin } from './apis';
|
||||||
import { fetchDashboard, fetchLiveAuction, fetchLiveTender, fetchPurchaseAuction, fetchPurchaseTender, offlineAuctionPurchase, userLogin, offlineTenderPurchase, fetchTenderById, proceedToBid } from './apis';
|
import { fetchDashboard, fetchLiveAuction, fetchLiveTender, fetchPurchaseAuction, fetchPurchaseTender, offlineAuctionPurchase, userLogin, offlineTenderPurchase, fetchTenderById, proceedToBid } from './apis';
|
||||||
|
|
||||||
// User
|
// User
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { DASHBOARD_COUNT, 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 } from "./ApiUrls";
|
import { DASHBOARD_COUNT, EMD_CHECK, FORARD_AUCTION_ITEM, GET_MY_AUCTION, GET_MY_TENDER, GET_TENDER_DETAILS, LIVE_AUCTION, LIVE_TENDER, LOG_IN_URL, PROCEED_PURCHASE_AUCTION, PROCEED_TO_BID, PURCHASE_OFFLINE_AUCTION, PURCHASE_TENDER_OFFLINE, REVERSE_AUCTION_ITEM, TENDER_LOGIN } from "./ApiUrls";
|
||||||
import { apiCall } from "../../Axios/Axios";
|
import { apiCall } from "../../Axios/Axios";
|
||||||
|
|
||||||
// User
|
// User
|
||||||
@@ -31,8 +31,35 @@ export const fetchLiveAuction = async (payload: any): Promise<any> => {
|
|||||||
// Auction Purchase offline
|
// Auction Purchase offline
|
||||||
export const offlineAuctionPurchase = async (payload: any): Promise<any> => {
|
export const offlineAuctionPurchase = async (payload: any): Promise<any> => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.post(PROCEED_PURCHASE_AUCTION, payload);
|
const response = await apiCall<any>('post', `${PURCHASE_OFFLINE_AUCTION}`, payload);
|
||||||
return response.data;
|
return response;
|
||||||
|
} catch (error: any) {
|
||||||
|
throw error.response?.data || error.message;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// EMD
|
||||||
|
|
||||||
|
export const fetchEmdCheck = async (payload: any): Promise<any> => {
|
||||||
|
try {
|
||||||
|
const response = await apiCall<any>('get', `${EMD_CHECK}`, {}, payload);
|
||||||
|
return response;
|
||||||
|
} catch (error: any) {
|
||||||
|
throw error.response?.data || error.message;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const fetchAuctionItem = async (payload: any): Promise<any> => {
|
||||||
|
try {
|
||||||
|
if (payload.status == 'Reverse') {
|
||||||
|
const response = await apiCall<any>('get', `${REVERSE_AUCTION_ITEM}`, {}, payload);
|
||||||
|
return response;
|
||||||
|
} else {
|
||||||
|
const response = await apiCall<any>('get', `${FORARD_AUCTION_ITEM}`, {}, payload);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
throw error.response?.data || error.message;
|
throw error.response?.data || error.message;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
+10
-12
@@ -51,8 +51,8 @@ const reducer = (state: State, action: Action): State => {
|
|||||||
export const useWebSocketService = (
|
export const useWebSocketService = (
|
||||||
webSocketUrl: string,
|
webSocketUrl: string,
|
||||||
onConnectCallback: () => void,
|
onConnectCallback: () => void,
|
||||||
onErrorCallback: (error: string) => void
|
onErrorCallback: (error: string) => void,
|
||||||
) => {
|
Token: any) => {
|
||||||
const [state, dispatch] = useReducer(reducer, {
|
const [state, dispatch] = useReducer(reducer, {
|
||||||
client: null,
|
client: null,
|
||||||
subscriptions: new Map(),
|
subscriptions: new Map(),
|
||||||
@@ -84,7 +84,7 @@ export const useWebSocketService = (
|
|||||||
|
|
||||||
onConnect: () => {
|
onConnect: () => {
|
||||||
isConnected.current = true;
|
isConnected.current = true;
|
||||||
console.log('✅ WebSocket connected');
|
// console.log('✅ WebSocket connected');
|
||||||
|
|
||||||
// 🔁 Flush queued subscriptions
|
// 🔁 Flush queued subscriptions
|
||||||
pendingSubscriptions.current.forEach(sub =>
|
pendingSubscriptions.current.forEach(sub =>
|
||||||
@@ -111,7 +111,7 @@ export const useWebSocketService = (
|
|||||||
|
|
||||||
// 🧠 Queue if not connected
|
// 🧠 Queue if not connected
|
||||||
if (!client || !isConnected.current) {
|
if (!client || !isConnected.current) {
|
||||||
console.log('⏳ Queued subscription:', destination);
|
// console.log('⏳ Queued subscription:', destination);
|
||||||
pendingSubscriptions.current.push({ destination, callback });
|
pendingSubscriptions.current.push({ destination, callback });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -123,7 +123,6 @@ export const useWebSocketService = (
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const parsed = JSON.parse(message.body);
|
const parsed = JSON.parse(message.body);
|
||||||
console.log('📡 LIVE DATA:', parsed);
|
|
||||||
callback(parsed);
|
callback(parsed);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('❌ JSON parse error', e);
|
console.error('❌ JSON parse error', e);
|
||||||
@@ -151,7 +150,6 @@ export const useWebSocketService = (
|
|||||||
|
|
||||||
// ================= ROOM =================
|
// ================= ROOM =================
|
||||||
const createRoom = async (roomId: any) => {
|
const createRoom = async (roomId: any) => {
|
||||||
const Token = useSelector((prev: any) => prev.token.token)
|
|
||||||
if (!roomId) return;
|
if (!roomId) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -160,7 +158,7 @@ export const useWebSocketService = (
|
|||||||
null,
|
null,
|
||||||
{
|
{
|
||||||
params: { roomId },
|
params: { roomId },
|
||||||
headers: { Authentication: `Bearer ${Token.token}` },
|
headers: { Authentication: `Bearer ${Token}` },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -175,11 +173,11 @@ export const useWebSocketService = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const joinRoom = async (roomId: any) => {
|
const joinRoom = async (roomId: any) => {
|
||||||
const Token = useSelector((prev: any) => prev.token.token)
|
|
||||||
try {
|
try {
|
||||||
const { data } = await axios.get(
|
const { data } = await axios.get(
|
||||||
`${Variables.socketUrl}livebidding/joinRoom?roomId=${roomId}`,
|
`${Variables.socketUrl}livebidding/joinRoom?roomId=${roomId}`,
|
||||||
{ headers: { Authentication: `Bearer ${Token.token}` } }
|
{ headers: { Authentication: `Bearer ${Token}` } }
|
||||||
);
|
);
|
||||||
|
|
||||||
if (data.statusCode === 200) return data.data.bids;
|
if (data.statusCode === 200) return data.data.bids;
|
||||||
@@ -190,17 +188,17 @@ export const useWebSocketService = (
|
|||||||
|
|
||||||
// ================= BID =================
|
// ================= BID =================
|
||||||
const placeBid = async (BidDTO: any) => {
|
const placeBid = async (BidDTO: any) => {
|
||||||
const Token = useSelector((prev: any) => prev.token.token)
|
|
||||||
try {
|
try {
|
||||||
const res = await axios.post(
|
const res = await axios.post(
|
||||||
`${Variables.socketUrl}livebidding/placeBid`,
|
`${Variables.socketUrl}livebidding/placeBid`,
|
||||||
BidDTO,
|
BidDTO,
|
||||||
{ headers: { Authentication: `Bearer ${Token.token}` } }
|
{ headers: { Authentication: `Bearer ${Token}` } }
|
||||||
);
|
);
|
||||||
|
|
||||||
if (res.data.statusCode === 200) {
|
if (res.data.statusCode === 200) {
|
||||||
showSuccessAlert(res.data.message);
|
showSuccessAlert(res.data.message);
|
||||||
return { data: res.data.data, status: true };
|
return { data: res.data.data, status: true, message: res.data.message };
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
if (err?.response?.data?.statusCode === 400) {
|
if (err?.response?.data?.statusCode === 400) {
|
||||||
|
|||||||
@@ -0,0 +1,340 @@
|
|||||||
|
// import React, { useCallback, useEffect, useState } from 'react';
|
||||||
|
// import { View, FlatList, StyleSheet, Platform, Alert, BackHandler, Text, ToastAndroid } from 'react-native';
|
||||||
|
// import LottieView from 'lottie-react-native';
|
||||||
|
// import { InsideHeader } from '../../Component/Index';
|
||||||
|
// import colors from '../../Constant/Color';
|
||||||
|
// import { useWebSocketService } from '../../socket/Socket';
|
||||||
|
// import Variables from '../../Constant/Variable';
|
||||||
|
// import { useSelector } from 'react-redux';
|
||||||
|
// import { apiCall } from '../../Axios/Axios';
|
||||||
|
// import { FORWARD_AUCTION_ITEM, REVERSE_AUCTION_ITEM, SELECTED_AUCTION_ITEM } from '../../Services/BBPS/ApiUrls';
|
||||||
|
// import BiddingCard from './Component/BiddingCard';
|
||||||
|
// import { CommonActions, useFocusEffect, useNavigation } from '@react-navigation/native';
|
||||||
|
// import NavigationString from '../../Constant/NavigationString';
|
||||||
|
// import CountdownTimer from '../../Component/Counter/CountdownTimer';
|
||||||
|
// import FontsFamily from '../../Constant/FontsFamily';
|
||||||
|
|
||||||
|
// const StartBidding = () => {
|
||||||
|
// const SelectedAuction = useSelector((state: any) => state.auction.auction);
|
||||||
|
// const loginUser = useSelector((state: any) => state.token.token)
|
||||||
|
// const Navigation: any = useNavigation()
|
||||||
|
// const [items, setItems] = useState<any>([]);
|
||||||
|
// const [bidValues, setBidValues] = useState<Record<number, number>>({});
|
||||||
|
// const [allBoolean, setAllBoolean] = useState({ showSuccess: false, showDialog: false, bidPayload: {} })
|
||||||
|
// const { subscribe, createRoom, placeBid } = useWebSocketService(
|
||||||
|
// Variables.webSocketUrl,
|
||||||
|
// () => console.log('Connected!'),
|
||||||
|
// (error) => console.log('WebSocket Error:', error),
|
||||||
|
// loginUser.token,
|
||||||
|
// );
|
||||||
|
|
||||||
|
// const getAllAcutionItems = async () => {
|
||||||
|
// try {
|
||||||
|
// const payload = { auctionNumber: SelectedAuction.auctionNumber };
|
||||||
|
// let auctionItem: any[] = [];
|
||||||
|
|
||||||
|
// if (SelectedAuction.auctionPattern === 'Forward') {
|
||||||
|
// const res = await apiCall<any>('get', FORWARD_AUCTION_ITEM, {}, payload);
|
||||||
|
// if (res?.statusCode === 200) auctionItem = res.data || [];
|
||||||
|
// } else if(SelectedAuction.auctionPattern === 'Reverse') {
|
||||||
|
// const res = await apiCall<any>('get', REVERSE_AUCTION_ITEM, {}, payload);
|
||||||
|
// if (res?.statusCode === 200) auctionItem = res.data || [];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const selectedRes = await apiCall<any>('get', SELECTED_AUCTION_ITEM, {}, payload);
|
||||||
|
|
||||||
|
// const uniqueArray: number[] = Array.from(
|
||||||
|
// new Set(selectedRes?.data || [])
|
||||||
|
// );
|
||||||
|
|
||||||
|
// const filteredItems = auctionItem.filter(item =>
|
||||||
|
// uniqueArray.includes(item.id)
|
||||||
|
// );
|
||||||
|
|
||||||
|
|
||||||
|
// const result = await createRoom(SelectedAuction.auctionNumber);
|
||||||
|
|
||||||
|
// subscribe(`/topic/room/${SelectedAuction.auctionNumber}`, data => {
|
||||||
|
// console.log('🔥 BID UPDATE:', data);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const bidAmountMap2 = new Map<number, { bidAmount: number; contractorId: number }>();
|
||||||
|
|
||||||
|
// (result || []).forEach((r: any) => {
|
||||||
|
// bidAmountMap2.set(r.auctionItemId, {
|
||||||
|
// bidAmount: r.bidAmount,
|
||||||
|
// contractorId: r.contractorId,
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// const bidAmountMap = new Map<number, number>();
|
||||||
|
|
||||||
|
// (result || []).forEach((r: any) => {
|
||||||
|
// bidAmountMap.set(r.auctionItemId, r.bidAmount);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const updatedFilteredItems = filteredItems.map(item => {
|
||||||
|
// const bidData = bidAmountMap2.get(item.id);
|
||||||
|
// return {
|
||||||
|
// ...item,
|
||||||
|
// bidAmount: bidData?.bidAmount ?? item.auctionStartValueFigure,
|
||||||
|
// bidAvilable: bidData?.bidAmount ?? 0,
|
||||||
|
// me: bidData?.contractorId == loginUser.contractorId ? true : false
|
||||||
|
// };
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const initialBids: Record<number, number> = {};
|
||||||
|
// updatedFilteredItems.forEach(item => {
|
||||||
|
// initialBids[item.id] = item.bidAmount;
|
||||||
|
// });
|
||||||
|
// setBidValues(initialBids);
|
||||||
|
// setItems(updatedFilteredItems);
|
||||||
|
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error('Error fetching auction items:', error);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// subscribe(`/topic/room/${SelectedAuction.auctionNumber}`, async (message) => {
|
||||||
|
|
||||||
|
// const result = message[message.length - 1]
|
||||||
|
|
||||||
|
// const updatedBidItem = (prev: any[]) =>
|
||||||
|
// prev.map(item =>
|
||||||
|
// item.id === result.auctionItemId
|
||||||
|
// ? { ...item, bidAmount: result.bidAmount, me: result.contractorId == loginUser.contractorId ? true : false }
|
||||||
|
// : item
|
||||||
|
// );
|
||||||
|
|
||||||
|
// setItems(updatedBidItem);
|
||||||
|
|
||||||
|
// setBidValues(prev => ({
|
||||||
|
// ...prev,
|
||||||
|
// [result.auctionItemId]: result.bidAmount,
|
||||||
|
// }));
|
||||||
|
// try {
|
||||||
|
|
||||||
|
// } catch (err) {
|
||||||
|
// console.log('JSON parse error:', err);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// getAllAcutionItems();
|
||||||
|
// subscribe(`/topic/room/${SelectedAuction.auctionNumber}`, (data) => { });
|
||||||
|
// }, []);
|
||||||
|
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// const initial: Record<number, number> = {};
|
||||||
|
// items.forEach((item: any) => {
|
||||||
|
// initial[item.id] = item.bidAmount + item.bidVariationValue;
|
||||||
|
// });
|
||||||
|
// setBidValues(initial);
|
||||||
|
// }, []);
|
||||||
|
|
||||||
|
// const handleUpdate = (id: number, val: number) => {
|
||||||
|
// setBidValues(prev => ({ ...prev, [id]: prev[id] + val }));
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const submitBid = async (item: any) => {
|
||||||
|
// const payload = {
|
||||||
|
// itemId: item.id,
|
||||||
|
// bidAmount: bidValues[item.id],
|
||||||
|
// auctionId: SelectedAuction.auctionId,
|
||||||
|
// contractorId: loginUser.contractorId,
|
||||||
|
// fullName: loginUser.fullName,
|
||||||
|
// roomId: SelectedAuction.auctionNumber,
|
||||||
|
// };
|
||||||
|
// setAllBoolean((prev: any) => ({ ...prev, bidPayload: payload, }));
|
||||||
|
// Alert.alert(
|
||||||
|
// 'Confirm Bid',
|
||||||
|
// `Are you sure you want to place a bid of ₹${payload.bidAmount}?`,
|
||||||
|
// [
|
||||||
|
// {
|
||||||
|
// text: 'Cancel',
|
||||||
|
// style: 'cancel',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// text: 'Submit',
|
||||||
|
// onPress: () => {
|
||||||
|
// placeBidSubmit(payload);
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// { cancelable: true }
|
||||||
|
// );
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const placeBidSubmit = async (data: any) => {
|
||||||
|
// try {
|
||||||
|
// const result: any = await placeBid(data);
|
||||||
|
|
||||||
|
// if (result?.status && result.data) {
|
||||||
|
// const updatedBidItem = (prev: any[]) =>
|
||||||
|
// prev.map(item =>
|
||||||
|
// item.id === result.data.auctionItemId
|
||||||
|
// ? { ...item, bidAmount: result.data.bidAmount, me: result.data?.contractorId == loginUser.contractorId ? true : false }
|
||||||
|
// : item
|
||||||
|
// );
|
||||||
|
|
||||||
|
// // ToastAndroid.show(result.message, ToastAndroid.SHORT)
|
||||||
|
// // setItems(updatedBidItem);
|
||||||
|
|
||||||
|
|
||||||
|
// // setBidValues((prev: any) => ({
|
||||||
|
// // ...prev,
|
||||||
|
// // [result.data.auctionItemId]: {
|
||||||
|
// // ...prev[result.data.auctionItemId],
|
||||||
|
// // bidAmount: result.data.bidAmount,
|
||||||
|
// // },
|
||||||
|
// // }));
|
||||||
|
// getAllAcutionItems()
|
||||||
|
// }
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error('Error placing bid:', error);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// useFocusEffect(
|
||||||
|
// useCallback(() => {
|
||||||
|
// const onBackPress = () => {
|
||||||
|
// Alert.alert(
|
||||||
|
// 'Confirm',
|
||||||
|
// 'Do you want to go back to Dashboard?',
|
||||||
|
// [
|
||||||
|
// { text: 'Cancel', style: 'cancel' },
|
||||||
|
// {
|
||||||
|
// text: 'Yes',
|
||||||
|
// onPress: () => {
|
||||||
|
// Navigation.dispatch(
|
||||||
|
// CommonActions.reset({
|
||||||
|
// index: 0,
|
||||||
|
// routes: [{ name: NavigationString.Home }],
|
||||||
|
// })
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// { cancelable: true }
|
||||||
|
// );
|
||||||
|
|
||||||
|
// return true; // block default back action
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const subscription = BackHandler.addEventListener(
|
||||||
|
// 'hardwareBackPress',
|
||||||
|
// onBackPress
|
||||||
|
// );
|
||||||
|
|
||||||
|
// return () => subscription.remove();
|
||||||
|
// }, [Navigation])
|
||||||
|
// );
|
||||||
|
// return (
|
||||||
|
// <View style={styles.container}>
|
||||||
|
// <InsideHeader title="Bidding Panel" showArrow />
|
||||||
|
// <View style={styles.container2}>
|
||||||
|
// <Text style={styles.title}>
|
||||||
|
// {SelectedAuction.deptName}
|
||||||
|
// </Text>
|
||||||
|
|
||||||
|
// <View style={styles.timerWrapper}>
|
||||||
|
// <CountdownTimer
|
||||||
|
// endDate={SelectedAuction.keyDates.auctionBidding.endDateTime}
|
||||||
|
// myStyle={{ fontSize: 30 }}
|
||||||
|
// size={30}
|
||||||
|
// />
|
||||||
|
// </View>
|
||||||
|
// </View>
|
||||||
|
|
||||||
|
// <FlatList
|
||||||
|
// data={items}
|
||||||
|
// keyExtractor={item => item.id.toString()}
|
||||||
|
// renderItem={({ item, index }) => (
|
||||||
|
// <BiddingCard
|
||||||
|
// item={{ ...item, index }}
|
||||||
|
// bidValue={bidValues[item.id] || 0}
|
||||||
|
// onIncrease={() => handleUpdate(item.id, item.bidVariationValue)}
|
||||||
|
// onDecrease={() => handleUpdate(item.id, -item.bidVariationValue)}
|
||||||
|
// onPlaceBid={() => { submitBid(item) }}
|
||||||
|
// SelectedAuction={SelectedAuction}
|
||||||
|
// />
|
||||||
|
// )}
|
||||||
|
// contentContainerStyle={{ padding: 16 }}
|
||||||
|
// />
|
||||||
|
|
||||||
|
// {allBoolean.showSuccess && (
|
||||||
|
// <View style={styles.overlay}>
|
||||||
|
// <LottieView
|
||||||
|
// source={require('../../lottie/Success.json')}
|
||||||
|
// autoPlay
|
||||||
|
// loop={false}
|
||||||
|
// style={{ width: 200, height: 200 }}
|
||||||
|
// />
|
||||||
|
// </View>
|
||||||
|
// )}
|
||||||
|
// </View>
|
||||||
|
// );
|
||||||
|
// };
|
||||||
|
|
||||||
|
// export default StartBidding;
|
||||||
|
|
||||||
|
// const styles = StyleSheet.create({
|
||||||
|
// container: { flex: 1, backgroundColor: colors.white },
|
||||||
|
// container2: {
|
||||||
|
// paddingHorizontal: 16,
|
||||||
|
// paddingTop: 12,
|
||||||
|
// paddingBottom: 8,
|
||||||
|
// },
|
||||||
|
// title: {
|
||||||
|
// fontSize: 18,
|
||||||
|
// fontFamily: FontsFamily.poppinsSemiBold,
|
||||||
|
// color: colors.black,
|
||||||
|
// marginBottom: 6,
|
||||||
|
// // textAlign:'center'
|
||||||
|
// },
|
||||||
|
// timerWrapper: {
|
||||||
|
// alignItems: 'center',
|
||||||
|
// },
|
||||||
|
// card: {
|
||||||
|
// backgroundColor: '#FFF',
|
||||||
|
// borderRadius: 24,
|
||||||
|
// padding: 20,
|
||||||
|
// marginBottom: 16,
|
||||||
|
// borderWidth: 1,
|
||||||
|
// borderColor: '#E2E8F0',
|
||||||
|
// overflow: 'hidden',
|
||||||
|
// ...Platform.select({ ios: { shadowColor: '#000', shadowOpacity: 0.05, shadowRadius: 10 }, android: { elevation: 2 } }),
|
||||||
|
// },
|
||||||
|
// leadingCard: { borderColor: '#22C55E', borderWidth: 2, backgroundColor: '#F0FDF4' },
|
||||||
|
// cardHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start' },
|
||||||
|
// headerRight: { flexDirection: 'row', alignItems: 'center', gap: 8 },
|
||||||
|
// productName: { fontSize: 18, fontWeight: 'bold', color: '#1E293B' },
|
||||||
|
// itemIdText: { fontSize: 12, color: '#64748B', marginTop: 2 },
|
||||||
|
// badge: { paddingHorizontal: 10, paddingVertical: 4, borderRadius: 8 },
|
||||||
|
// liveBadge: { backgroundColor: '#FEE2E2' },
|
||||||
|
// meBadge: { backgroundColor: '#BBF7D0' },
|
||||||
|
// badgeText: { fontSize: 10, fontWeight: '900' },
|
||||||
|
// liveText: { color: '#EF4444' },
|
||||||
|
// meText: { color: '#15803D' },
|
||||||
|
// arrow: { fontSize: 10, color: '#94A3B8' },
|
||||||
|
// priceRow: { flexDirection: 'row', justifyContent: 'space-between', marginTop: 20 },
|
||||||
|
// label: { fontSize: 11, color: '#94A3B8', textTransform: 'uppercase', fontWeight: '600' },
|
||||||
|
// mainPrice: { fontSize: 22, fontWeight: '900', color: '#0F172A' },
|
||||||
|
// incrementText: { fontSize: 16, fontWeight: '700', color: '#3B82F6' },
|
||||||
|
// collapsibleContainer: { overflow: 'hidden' },
|
||||||
|
// divider: { height: 1, backgroundColor: '#E2E8F0', marginVertical: 10 },
|
||||||
|
// bidLabel: { fontSize: 13, fontWeight: '600', color: '#475569', marginBottom: 10 },
|
||||||
|
// stepperContainer: { flexDirection: 'row', gap: 12, marginBottom: 20 },
|
||||||
|
// stepBtn: { width: 45, height: 45, backgroundColor: colors.primary, borderRadius: 12, justifyContent: 'center', alignItems: 'center' },
|
||||||
|
// disabledBtn: { backgroundColor: '#CBD5E1' },
|
||||||
|
// stepText: { color: '#FFF', fontSize: 20, fontWeight: 'bold' },
|
||||||
|
// inputBox: { flex: 1, height: 45, backgroundColor: '#F1F5F9', borderRadius: 12, flexDirection: 'row', alignItems: 'center', justifyContent: 'center' },
|
||||||
|
// currency: { fontSize: 16, fontWeight: 'bold', color: '#64748B', marginRight: 4 },
|
||||||
|
// bidValueText: { fontSize: 18, fontWeight: '800', color: '#0F172A' },
|
||||||
|
// submitBtn: { height: 50, backgroundColor: colors.primary, borderRadius: 15, justifyContent: 'center', alignItems: 'center' },
|
||||||
|
// submitBtnText: { color: '#FFF', fontSize: 16, fontWeight: 'bold' },
|
||||||
|
// overlay: { ...StyleSheet.absoluteFillObject, backgroundColor: 'rgba(255,255,255,0.7)', justifyContent: 'center', alignItems: 'center', zIndex: 99 },
|
||||||
|
// });
|
||||||
Reference in New Issue
Block a user