feat: clinic approval

This commit is contained in:
deepvasoya 2025-05-20 14:53:48 +05:30
parent 8d2d652630
commit 1508c54700
3 changed files with 162 additions and 132 deletions

View File

@ -56,7 +56,7 @@ export const getClinicsById = (id) => {
}; };
export const updateClinicStatus = (data) => { export const updateClinicStatus = (data) => {
const url = `/admin/clinic/status/`; const url = `/admin/clinic/status`;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
axiosInstance axiosInstance
.put(url, data) .put(url, data)

View File

@ -1,21 +1,21 @@
import CloseIcon from '@mui/icons-material/Close'; import CloseIcon from "@mui/icons-material/Close";
import DoneIcon from '@mui/icons-material/Done'; import DoneIcon from "@mui/icons-material/Done";
import RemoveRedEyeOutlinedIcon from '@mui/icons-material/RemoveRedEyeOutlined'; import RemoveRedEyeOutlinedIcon from "@mui/icons-material/RemoveRedEyeOutlined";
import SaveAltIcon from '@mui/icons-material/SaveAlt'; import SaveAltIcon from "@mui/icons-material/SaveAlt";
import VerifiedIcon from '@mui/icons-material/Verified'; import VerifiedIcon from "@mui/icons-material/Verified";
import { Box, Button, Grid, Modal, Typography } from '@mui/material'; import { Box, Button, Grid, Modal, Typography } from "@mui/material";
import { format } from 'date-fns'; import { format } from "date-fns";
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from "react";
import downloadIcon from '../../../assets/images/icon/download.svg'; import downloadIcon from "../../../assets/images/icon/download.svg";
import ImagePreviewComponent from '../../../components/ImagePreviewComponent'; import ImagePreviewComponent from "../../../components/ImagePreviewComponent";
import { import {
ABN_NUMBER_LENGTH, ABN_NUMBER_LENGTH,
CLINIC_DOCUMENT_STATUS, CLINIC_DOCUMENT_STATUS,
CLINIC_STATUS, CLINIC_STATUS,
FILE_EXTENTIONS_ICONS, FILE_EXTENTIONS_ICONS,
GST_NUMBER_LENGTH, GST_NUMBER_LENGTH,
} from '../../../constants'; } from "../../../constants";
import { useStyles } from './styles/fileEvaluateStyles'; import { useStyles } from "./styles/fileEvaluateStyles";
const FileEvaluate = ({ const FileEvaluate = ({
companyStatus, companyStatus,
@ -32,68 +32,90 @@ const FileEvaluate = ({
const [notReviewedOtherFiles, setNotReviewedOtherFiles] = useState([]); const [notReviewedOtherFiles, setNotReviewedOtherFiles] = useState([]);
// const getAscendingArray = (array) => { // const getAscendingArray = (array) => {
// return filteredArray; // return filteredArray;
// }; // };
useEffect(() => { useEffect(() => {
if (!Array.isArray(files)) return; if (!Array.isArray(files)) return;
// Process all files at once to avoid multiple iterations // Process all files at once to avoid multiple iterations
const reviewedLogo = []; const reviewedLogo = [];
const notReviewedLogo = []; const notReviewedLogo = [];
const reviewedOther = []; const reviewedOther = [];
const notReviewedOther = []; const notReviewedOther = [];
files.forEach(file => { files.forEach((file) => {
// Handle logo documents // Handle logo documents
if (file.logo_doc) { if (file.logo_doc) {
if (file.logo_doc_is_verified) { if (file.logo_is_verified) {
reviewedLogo.push({file: file.logo_doc, documentType: 'LOGO', isVerified: file.logo_doc_is_verified}); reviewedLogo.push({
file: file.logo_doc,
documentType: "LOGO",
isVerified: file.logo_is_verified,
});
} else { } else {
notReviewedLogo.push({file: file.logo_doc, documentType: 'LOGO', isVerified: file.logo_doc_is_verified}); notReviewedLogo.push({
file: file.logo_doc,
documentType: "LOGO",
isVerified: file.logo_is_verified,
});
} }
} }
// Handle ABN and contract documents (excluding logo docs which are handled separately) // Handle ABN and contract documents (excluding logo docs which are handled separately)
if (file.abn_doc ) { if (file.abn_doc) {
if (file.abn_doc_is_verified) { if (file.abn_doc_is_verified) {
reviewedOther.push({file: file.abn_doc, documentType: 'ABN', isVerified: file.abn_doc_is_verified}); reviewedOther.push({
} file: file.abn_doc,
else{ documentType: "ABN",
notReviewedOther.push({file: file.abn_doc, documentType: 'ABN', isVerified: file.abn_doc_is_verified}); isVerified: file.abn_doc_is_verified,
});
} else {
notReviewedOther.push({
file: file.abn_doc,
documentType: "ABN",
isVerified: file.abn_doc_is_verified,
});
} }
} }
if (file.contract_doc) { if (file.contract_doc) {
if (file.contract_doc_is_verified) { if (file.contract_doc_is_verified) {
reviewedOther.push({file: file.contract_doc, documentType: 'CONTRACT', isVerified: file.contract_doc_is_verified}); reviewedOther.push({
} else{ file: file.contract_doc,
notReviewedOther.push({file: file.contract_doc, documentType: 'CONTRACT', isVerified: file.contract_doc_is_verified}); documentType: "CONTRACT",
isVerified: file.contract_doc_is_verified,
});
} else {
notReviewedOther.push({
file: file.contract_doc,
documentType: "CONTRACT",
isVerified: file.contract_doc_is_verified,
});
} }
} }
}); });
// Update state with filtered files // Update state with filtered files
setReviewedLogoFiles(reviewedLogo); setReviewedLogoFiles(reviewedLogo);
setNotReviewedLogoFiles(notReviewedLogo); setNotReviewedLogoFiles(notReviewedLogo);
setReviewedOtherFiles(reviewedOther); setReviewedOtherFiles(reviewedOther);
setNotReviewedOtherFiles(notReviewedOther); setNotReviewedOtherFiles(notReviewedOther);
// Debug logs // Debug logs
console.log('Files processed:', files.length); console.log("Files processed:", files.length);
console.log('reviewedLogoFiles:', reviewedLogo); console.log("reviewedLogoFiles:", reviewedLogo);
console.log('notReviewedLogoFiles:', notReviewedLogo); console.log("notReviewedLogoFiles:", notReviewedLogo);
console.log('reviewedOtherFiles:', reviewedOther); console.log("reviewedOtherFiles:", reviewedOther);
console.log('notReviewedOtherFiles:', notReviewedOther); console.log("notReviewedOtherFiles:", notReviewedOther);
}, [files]); }, [files]);
// .........................get file name and extention function....................... // .........................get file name and extention function.......................
const getFileNameUsingFile = (file) => { const getFileNameUsingFile = (file) => {
if (file) { if (file) {
// const url = new URL(file); // const url = new URL(file);
// return url.pathname.split('/').pop(); // return url.pathname.split('/').pop();
return file return file;
} }
return; return;
}; };
@ -101,8 +123,8 @@ const FileEvaluate = ({
const getFileExtentionUsingFile = (file) => { const getFileExtentionUsingFile = (file) => {
if (file) { if (file) {
const url = new URL(file.file); const url = new URL(file.file);
const fileName = url.pathname.split('/').pop(); const fileName = url.pathname.split("/").pop();
return fileName.split('.').pop(); return fileName.split(".").pop();
} }
return; return;
}; };
@ -111,20 +133,20 @@ const FileEvaluate = ({
const handleActionClick = (index, file, actionType) => { const handleActionClick = (index, file, actionType) => {
const newFile = { const newFile = {
...file, ...file,
status: isVerified:
actionType === 'ACCEPT' actionType === "ACCEPT"
? CLINIC_DOCUMENT_STATUS.APPROVED ? true
: CLINIC_DOCUMENT_STATUS.REJECTED, : false,
}; };
if (file.logo_doc) { if (file.documentType == "LOGO") {
const updatedFiles = [...notReviewedLogoFiles]; const updatedFiles = [...notReviewedLogoFiles];
updatedFiles.splice(index, 1, newFile); updatedFiles.splice(index, 1, newFile);
setNotReviewedLogoFiles(updatedFiles); setNotReviewedLogoFiles(updatedFiles);
} else { } else {
const updatedFiles = [...notReviewedOtherFiles]; const updatedFiles = [...notReviewedOtherFiles];
updatedFiles.splice(index, 1, newFile); updatedFiles.splice(index, 1, newFile);
setNotReviewedOtherFile(updatedFiles); setNotReviewedOtherFiles(updatedFiles);
} }
onFileButtonClick(newFile); onFileButtonClick(newFile);
@ -132,14 +154,14 @@ const FileEvaluate = ({
// ..............buttons................. // ..............buttons.................
const ActionButton = ({ index, file, actionType, onClick }) => { const ActionButton = ({ index, file, actionType, onClick }) => {
const isAccept = actionType === 'ACCEPT'; const isAccept = actionType === "ACCEPT";
const buttonClass = isAccept ? classes.acceptButton : classes.rejectButton; const buttonClass = isAccept ? classes.acceptButton : classes.rejectButton;
const icon = isAccept ? ( const icon = isAccept ? (
<DoneIcon className={classes.acceptButtonIcon} /> <DoneIcon className={classes.acceptButtonIcon} />
) : ( ) : (
<CloseIcon className={classes.rejectButtonIcon} /> <CloseIcon className={classes.rejectButtonIcon} />
); );
const buttonText = isAccept ? 'Accept' : 'Reject'; const buttonText = isAccept ? "Accept" : "Reject";
return ( return (
<Button className={buttonClass} onClick={() => onClick(index, file)}> <Button className={buttonClass} onClick={() => onClick(index, file)}>
@ -168,13 +190,13 @@ const FileEvaluate = ({
const handleDownload = (file) => { const handleDownload = (file) => {
if (file) { if (file) {
const anchor = document.createElement('a'); const anchor = document.createElement("a");
anchor.href = file.file; // file is now a direct URL anchor.href = file.file; // file is now a direct URL
// Extract filename from URL for download attribute // Extract filename from URL for download attribute
const fileName = file.file.split('/').pop(); const fileName = file.file.split("/").pop();
anchor.download = fileName; anchor.download = fileName;
anchor.click(); anchor.click();
} }
}; };
@ -313,19 +335,13 @@ const FileEvaluate = ({
</Box> </Box>
</Box> </Box>
<Box className={classes.buttonBox}> <Box className={classes.buttonBox}>
{file.status === CLINIC_DOCUMENT_STATUS.REJECTED && ( {!file.isVerified && <DisableRejectedButton />}
<DisableRejectedButton /> {file.isVerified && <DisableAcceptedButton />}
)}
{file.status === CLINIC_DOCUMENT_STATUS.APPROVED && (
<DisableAcceptedButton />
)}
{file.status === CLINIC_DOCUMENT_STATUS.NOT_REVIEWED && (
<DisableRejectedButton />
)}
</Box> </Box>
</Box> </Box>
</Grid> </Grid>
))} ))}
{notReviewedLogoFiles.map((file, index) => ( {notReviewedLogoFiles.map((file, index) => (
<Grid key={index} className={classes.outerGrid}> <Grid key={index} className={classes.outerGrid}>
<Box className={classes.outerBox}> <Box className={classes.outerBox}>
@ -367,14 +383,14 @@ const FileEvaluate = ({
</Box> </Box>
</Box> </Box>
<Box className={classes.buttonBox}> <Box className={classes.buttonBox}>
{file.status === CLINIC_STATUS.NOT_REVIEWED ? ( {file.isVerified == null ? (
<> <>
<ActionButton <ActionButton
index={index} index={index}
file={file} file={file}
actionType="REJECT" actionType="REJECT"
onClick={(index, file) => onClick={(index, file) =>
handleActionClick(index, file, 'REJECT') handleActionClick(index, file, "REJECT")
} }
/> />
<ActionButton <ActionButton
@ -382,33 +398,33 @@ const FileEvaluate = ({
file={file} file={file}
actionType="ACCEPT" actionType="ACCEPT"
onClick={(index, file) => onClick={(index, file) =>
handleActionClick(index, file, 'ACCEPT') handleActionClick(index, file, "ACCEPT")
} }
/> />
</> </>
) : file.status === CLINIC_DOCUMENT_STATUS.REJECTED ? ( ) : file.isVerified ? (
<> <>
<DisableRejectedButton />
<ActionButton <ActionButton
index={index} index={index}
file={file} file={file}
actionType="ACCEPT" actionType="REJECT"
onClick={(index, file) => onClick={(index, file) =>
handleActionClick(index, file, 'ACCEPT') handleActionClick(index, file, "REJECT")
} }
/> />
<DisableAcceptedButton />
</> </>
) : ( ) : (
<> <>
<ActionButton <ActionButton
index={index} index={index}
file={file} file={file}
actionType="REJECT" actionType="ACCEPT"
onClick={(index, file) => onClick={(index, file) =>
handleActionClick(index, file, 'REJECT') handleActionClick(index, file, "ACCEPT")
} }
/> />
<DisableAcceptedButton /> <DisableRejectedButton />
</> </>
)} )}
</Box> </Box>
@ -426,10 +442,10 @@ const FileEvaluate = ({
<Typography className={classes.titleOfBox}> <Typography className={classes.titleOfBox}>
CLINIC {file.documentType} INFO CLINIC {file.documentType} INFO
</Typography> </Typography>
<Typography className={classes.updatedDate}> {/* <Typography className={classes.updatedDate}>
Uploaded:{' '} Uploaded:{" "}
{format(new Date(file?.updatedAt), 'dd MMM yyyy')} {format(new Date(file?.updatedAt), "dd MMM yyyy")}
</Typography> </Typography> */}
<Typography className={classes.documentNumberAndNameLabel}> <Typography className={classes.documentNumberAndNameLabel}>
{file.documentNumber} {file.documentNumber}
</Typography> </Typography>
@ -465,19 +481,13 @@ const FileEvaluate = ({
</Box> </Box>
</Box> </Box>
<Box className={classes.buttonBox}> <Box className={classes.buttonBox}>
{file.status === CLINIC_DOCUMENT_STATUS.REJECTED && ( {!file.isVerified && <DisableRejectedButton />}
<DisableRejectedButton /> {file.isVerified && <DisableAcceptedButton />}
)}
{file.status === CLINIC_DOCUMENT_STATUS.APPROVED && (
<DisableAcceptedButton />
)}
{file.status === CLINIC_DOCUMENT_STATUS.NOT_REVIEWED && (
<DisableRejectedButton />
)}
</Box> </Box>
</Box> </Box>
</Grid> </Grid>
))} ))}
<Grid xs={12}></Grid> <Grid xs={12}></Grid>
{notReviewedOtherFiles.map((file, index) => ( {notReviewedOtherFiles.map((file, index) => (
<Grid key={index} className={classes.outerGrid}> <Grid key={index} className={classes.outerGrid}>
@ -548,14 +558,14 @@ const FileEvaluate = ({
</Box> </Box>
</Box> </Box>
<Box className={classes.buttonBox}> <Box className={classes.buttonBox}>
{file.status === CLINIC_STATUS.NOT_REVIEWED ? ( {file.isVerified == null ? (
<> <>
<ActionButton <ActionButton
index={index} index={index}
file={file} file={file}
actionType="REJECT" actionType="REJECT"
onClick={(index, file) => onClick={(index, file) =>
handleActionClick(index, file, 'REJECT') handleActionClick(index, file, "REJECT")
} }
/> />
<ActionButton <ActionButton
@ -563,33 +573,33 @@ const FileEvaluate = ({
file={file} file={file}
actionType="ACCEPT" actionType="ACCEPT"
onClick={(index, file) => onClick={(index, file) =>
handleActionClick(index, file, 'ACCEPT') handleActionClick(index, file, "ACCEPT")
} }
/> />
</> </>
) : file.status === CLINIC_DOCUMENT_STATUS.REJECTED ? ( ) : file.isVerified ? (
<> <>
<DisableRejectedButton />
<ActionButton <ActionButton
index={index} index={index}
file={file} file={file}
actionType="ACCEPT" actionType="REJECT"
onClick={(index, file) => onClick={(index, file) =>
handleActionClick(index, file, 'ACCEPT') handleActionClick(index, file, "REJECT")
} }
/> />
<DisableAcceptedButton />
</> </>
) : ( ) : (
<> <>
<ActionButton <ActionButton
index={index} index={index}
file={file} file={file}
actionType="REJECT" actionType="ACCEPT"
onClick={(index, file) => onClick={(index, file) =>
handleActionClick(index, file, 'REJECT') handleActionClick(index, file, "ACCEPT")
} }
/> />
<DisableAcceptedButton /> <DisableRejectedButton />
</> </>
)} )}
</Box> </Box>
@ -623,15 +633,13 @@ const FileEvaluate = ({
<Grid container> <Grid container>
<Grid item md={12} className={classes.previewFileTitle}> <Grid item md={12} className={classes.previewFileTitle}>
<Typography color="white"> <Typography color="white">{previewFile.file}</Typography>
{previewFile.split('/').pop()}
</Typography>
</Grid> </Grid>
</Grid> </Grid>
<Grid xs={12} className={classes.previewImageGrid}> <Grid xs={12} className={classes.previewImageGrid}>
<ImagePreviewComponent <ImagePreviewComponent
fileUrl={previewFile} fileUrl={previewFile.file}
fileExtension={getFileExtentionUsingFile(previewFile)} fileExtension={getFileExtentionUsingFile(previewFile)}
handleDownload={() => handleDownload(previewFile)} handleDownload={() => handleDownload(previewFile)}
classes={classes} classes={classes}

View File

@ -135,14 +135,46 @@ function ClinicDetails() {
// ................functions................. // ................functions.................
const handleFileButtonClick = (file) => { const handleFileButtonClick = (file) => {
const oldIndex = updateFiles.findIndex((f) => f.fileURL === file.fileURL); const oldIndex = updateFiles.findIndex((f) => f.file === file.file);
if (oldIndex === -1) { if (oldIndex === -1) {
setUpdateFiles((prevFiles) => [...prevFiles, file]); const newFile = {
...file,
};
if (file.documentType == "LOGO") {
newFile.logo_is_verified = file.isVerified;
clinicFiles.logo_is_verified = file.isVerified;
}
if (file.documentType == "ABN") {
newFile.abn_doc_is_verified = file.isVerified;
clinicFiles.abn_doc_is_verified = file.isVerified;
}
if (file.documentType == "CONTRACT") {
newFile.contract_doc_is_verified = file.isVerified;
clinicFiles.contract_doc_is_verified = file.isVerified;
}
setUpdateFiles((prevFiles) => [...prevFiles, newFile]);
} else { } else {
setUpdateFiles((prevFiles) => { setUpdateFiles((prevFiles) => {
const updatedFiles = [...prevFiles]; const updatedFiles = [...prevFiles];
updatedFiles[oldIndex] = file; const fileToBeUpdate = updatedFiles[oldIndex];
if (fileToBeUpdate.documentType == "LOGO") {
fileToBeUpdate.logo_is_verified = file.isVerified;
clinicFiles.logo_is_verified = file.isVerified;
}
if (fileToBeUpdate.documentType == "ABN") {
fileToBeUpdate.abn_doc_is_verified = file.isVerified;
clinicFiles.abn_doc_is_verified = file.isVerified;
}
if (fileToBeUpdate.documentType == "CONTRACT") {
fileToBeUpdate.contract_doc_is_verified = file.isVerified;
clinicFiles.contract_doc_is_verified = file.isVerified;
}
updatedFiles[oldIndex] = fileToBeUpdate;
return updatedFiles; return updatedFiles;
}); });
} }
@ -189,7 +221,7 @@ function ClinicDetails() {
const documentStatusMap = {}; const documentStatusMap = {};
updateFiles.forEach((doc) => { updateFiles.forEach((doc) => {
documentStatusMap[doc.documentType] = doc.status; documentStatusMap[doc.documentType] = doc.isVerified;
}); });
const data = { const data = {
@ -201,9 +233,9 @@ function ClinicDetails() {
: buttonClickStatus === "On Hold" : buttonClickStatus === "On Hold"
? CLINIC_STATUS.UNDER_REVIEW.toLowerCase() ? CLINIC_STATUS.UNDER_REVIEW.toLowerCase()
: CLINIC_STATUS.ACTIVE.toLowerCase(), : CLINIC_STATUS.ACTIVE.toLowerCase(),
// documentStatus: { documentStatus: {
// ...documentStatusMap, ...documentStatusMap,
// }, },
}; };
return data; return data;
}; };
@ -229,29 +261,31 @@ function ClinicDetails() {
// ..................update file use effects................ // ..................update file use effects................
useEffect(() => { useEffect(() => {
setIsRejectedButtonShow( // Check if any document is not verified or is null/undefined
clinicFiles.abn_doc_is_verified != true && const hasUnverifiedDocuments =
clinicFiles.contract_doc_is_verified != true clinicFiles?.abn_doc_is_verified !== true ||
); clinicFiles?.contract_doc_is_verified !== true ||
clinicFiles?.logo_is_verified !== true;
setIsOnHoldButtonShow(
clinicFiles.abn_doc_is_verified != true && // Set button visibility based on document verification status
clinicFiles.contract_doc_is_verified != true setIsRejectedButtonShow(hasUnverifiedDocuments);
); setIsOnHoldButtonShow(hasUnverifiedDocuments);
const areAllFilesApproved = const areAllFilesApproved =
clinicFiles.abn_doc_is_verified == true && clinicFiles?.abn_doc_is_verified === true &&
clinicFiles.contract_doc_is_verified == true; clinicFiles?.contract_doc_is_verified === true &&
clinicFiles?.logo_is_verified === true;
if ( if (
areAllFilesApproved && areAllFilesApproved &&
clinicData?.status === CLINIC_STATUS.UNDER_REVIEW.toLowerCase() (clinicData?.status === CLINIC_STATUS.UNDER_REVIEW.toLowerCase() ||
clinicData?.status === CLINIC_STATUS.REJECTED.toLowerCase())
) { ) {
setIsAcceptedButtonShow(true); setIsAcceptedButtonShow(true);
} else { } else {
setIsAcceptedButtonShow(false); setIsAcceptedButtonShow(false);
} }
}, [clinicFiles]); }, [clinicFiles, updateFiles]);
// ..............handle table change.......... // ..............handle table change..........
const handleTabChange = (event, newValue) => { const handleTabChange = (event, newValue) => {
@ -300,19 +334,7 @@ function ClinicDetails() {
pageTitle="Clinics Details" pageTitle="Clinics Details"
hideAddButton hideAddButton
extraComponent={ extraComponent={
clinicData.status === CLINIC_STATUS.ACTIVE.toLowerCase() ? ( clinicData.status !== CLINIC_STATUS.ACTIVE.toLowerCase() && (
<>
<Button
className={classes.editCompanyInfoButton}
color="primary"
variant="outlined"
loading={false}
onClick={handleEditCompanyInfo}
>
Edit Clinics Info
</Button>
</>
) : (
<Box display="flex" flexDirection="row"> <Box display="flex" flexDirection="row">
{/* ...rejected button.... */} {/* ...rejected button.... */}
<Box> <Box>
@ -439,7 +461,7 @@ function ClinicDetails() {
contract_doc_is_verified: contract_doc_is_verified:
clinicFiles?.contract_doc_is_verified, clinicFiles?.contract_doc_is_verified,
logo_doc: clinicData?.logo, logo_doc: clinicData?.logo,
logo_doc_is_verified: clinicFiles?.logo_is_verified, logo_is_verified: clinicFiles?.logo_is_verified,
}, },
] ]
} }