feat: clinic setup

refactor: removed logo from signup and list
fix: other changes
This commit is contained in:
deepvasoya 2025-05-30 15:31:50 +05:30
parent 73f26704f4
commit 9e39a1f9a1
16 changed files with 684 additions and 392 deletions

View File

@ -34,6 +34,7 @@ import ProtectedComponent from "../components/ProtectedComponent";
import { DesktopDatePicker, LocalizationProvider } from "@mui/x-date-pickers"; import { DesktopDatePicker, LocalizationProvider } from "@mui/x-date-pickers";
import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns"; import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns";
import { DateRangePicker } from "@mui/x-date-pickers-pro"; import { DateRangePicker } from "@mui/x-date-pickers-pro";
import { enGB } from "date-fns/locale";
const Table = memo( const Table = memo(
forwardRef((props, ref) => { forwardRef((props, ref) => {
@ -74,14 +75,6 @@ const Table = memo(
}); });
const navigate = useNavigate(); const navigate = useNavigate();
useEffect(()=>{
if(dateRange){
console.log(dateRange);
}
},[dateRange])
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
reFetchData() { reFetchData() {
setIsLoading(true); setIsLoading(true);
@ -253,29 +246,27 @@ const Table = memo(
/> />
{showDateFilters && ( {showDateFilters && (
<LocalizationProvider <LocalizationProvider
className={classes.searchContainer} className={classes.searchContainer}
dateAdapter={AdapterDateFns} dateAdapter={AdapterDateFns}
> adapterLocale={enGB} // Import: import { enGB } from 'date-fns/locale'
<DateRangePicker >
className={classes.searchDatePicker} <DateRangePicker
renderInput={(props) => ( className={classes.searchDatePicker}
<TextField {...props} variant="outlined" /> slotProps={{
)} field: {
slotProps={{ clearable: true,
field: { },
clearable: true, textField: {
variant: "outlined"
} }
}} }}
value={dateRange} value={dateRange}
onChange={(newValue) => { onChange={(newValue) => {
setDateRange(newValue); setDateRange(newValue);
// column.setFilterValue(newValue); }}
}} format="dd/MM/yyyy"
inputFormat="MMM d, yyyy" />
format="MMM d, yyyy" </LocalizationProvider>
/>
</LocalizationProvider>
)} )}
{!hideShowPerPage && ( {!hideShowPerPage && (
<Box className={classes.pageSizeDropdown}> <Box className={classes.pageSizeDropdown}>

View File

@ -109,6 +109,6 @@ div::-webkit-scrollbar-thumb:hover {
background-color: transparent; background-color: transparent;
} }
div[style*="z-index: 100000"] { /* div[style*="z-index: 100000"] {
visibility: hidden; visibility: hidden;
} } */

View File

@ -5,7 +5,7 @@ import { clinicsData, registeredClinicsData } from "../mock/clinics";
export const getClinics = (params) => { export const getClinics = (params) => {
let searchParams = new URLSearchParams(); let searchParams = new URLSearchParams();
searchParams.append("limit", params?.pagination?.pageSize ?? 10); searchParams.append("limit", params?.pagination?.pageSize ?? 10);
searchParams.append("page", params?.pagination.pageIndex + 1 ?? 1); searchParams.append("page", params?.pagination?.pageIndex + 1 ?? 1);
searchParams.append("filter_type", params?.type ?? CLINIC_TYPE.REGISTERED); searchParams.append("filter_type", params?.type ?? CLINIC_TYPE.REGISTERED);
searchParams.append("search", params?.globalFilter ?? ""); searchParams.append("search", params?.globalFilter ?? "");
@ -69,7 +69,7 @@ export const getClinicDocs = (id) => {
}); });
}; };
export const updateClinicDocs = (id, data) => { export const updateClinic = (id, data) => {
const url = `/clinics/${id}`; const url = `/clinics/${id}`;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
axiosInstance axiosInstance
@ -180,7 +180,6 @@ export const deleteDoctor = (id) => {
}; };
export const getCallTranscripts = (params) => { export const getCallTranscripts = (params) => {
console.log(params);
let searchParams = new URLSearchParams(); let searchParams = new URLSearchParams();
searchParams.append("limit", params?.pagination?.pageSize ?? 10); searchParams.append("limit", params?.pagination?.pageSize ?? 10);
searchParams.append("page", params?.pagination.pageIndex + 1 ?? 1); searchParams.append("page", params?.pagination.pageIndex + 1 ?? 1);

View File

@ -2,6 +2,8 @@ import { axiosInstance } from "../config/api";
export const getMasterData = (params) => { export const getMasterData = (params) => {
let searchParams = new URLSearchParams(); let searchParams = new URLSearchParams();
searchParams.append("limit", params?.pagination?.pageSize ?? 10);
searchParams.append("page", params?.pagination.pageIndex + 1 ?? 1);
searchParams.append("search", params?.globalFilter ?? ""); searchParams.append("search", params?.globalFilter ?? "");
const url = `/admin/master-data?${searchParams.toString()}`; const url = `/admin/master-data?${searchParams.toString()}`;

View File

@ -26,8 +26,8 @@ const FileEvaluate = ({
const classes = useStyles(); const classes = useStyles();
const [isPreview, setIsPreview] = useState(false); const [isPreview, setIsPreview] = useState(false);
const [previewFile, setPreviewFile] = useState(); const [previewFile, setPreviewFile] = useState();
const [reviewedLogoFiles, setReviewedLogoFiles] = useState([]); // const [reviewedLogoFiles, setReviewedLogoFiles] = useState([]);
const [notReviewedLogoFiles, setNotReviewedLogoFiles] = useState([]); // const [notReviewedLogoFiles, setNotReviewedLogoFiles] = useState([]);
const [reviewedOtherFiles, setReviewedOtherFiles] = useState([]); const [reviewedOtherFiles, setReviewedOtherFiles] = useState([]);
const [notReviewedOtherFiles, setNotReviewedOtherFiles] = useState([]); const [notReviewedOtherFiles, setNotReviewedOtherFiles] = useState([]);
@ -40,28 +40,28 @@ const FileEvaluate = ({
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_is_verified) { // if (file.logo_is_verified) {
reviewedLogo.push({ // reviewedLogo.push({
file: file.logo_doc, // file: file.logo_doc,
documentType: "LOGO", // documentType: "LOGO",
isVerified: file.logo_is_verified, // isVerified: file.logo_is_verified,
}); // });
} else { // } else {
notReviewedLogo.push({ // notReviewedLogo.push({
file: file.logo_doc, // file: file.logo_doc,
documentType: "LOGO", // documentType: "LOGO",
isVerified: file.logo_is_verified, // 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) {
@ -98,15 +98,15 @@ const FileEvaluate = ({
}); });
// 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]);
@ -133,21 +133,21 @@ const FileEvaluate = ({
const handleActionClick = (index, file, actionType) => { const handleActionClick = (index, file, actionType) => {
const newFile = { const newFile = {
...file, ...file,
isVerified: isVerified: actionType === "ACCEPT" ? true : false,
actionType === "ACCEPT"
? true
: false,
}; };
if (file.documentType == "LOGO") { // 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);
setNotReviewedOtherFiles(updatedFiles); // setNotReviewedOtherFiles(updatedFiles);
} // }
const updatedFiles = [...notReviewedOtherFiles];
updatedFiles.splice(index, 1, newFile);
setNotReviewedOtherFiles(updatedFiles);
onFileButtonClick(newFile); onFileButtonClick(newFile);
}; };
@ -216,40 +216,6 @@ const FileEvaluate = ({
{/* ............CLINIC is Approved that time show only card............. */} {/* ............CLINIC is Approved that time show only card............. */}
{companyStatus === CLINIC_STATUS.ACTIVE ? ( {companyStatus === CLINIC_STATUS.ACTIVE ? (
<> <>
<Grid container className={classes.mainGrid} gap={3.5}>
{reviewedLogoFiles.map((file, index) => (
<Grid
key={index}
className={
file.status === CLINIC_DOCUMENT_STATUS.APPROVED
? classes.enableApprovedDocument
: classes.disableOuterGrid
}
>
<Box className={classes.outerBox}>
<Box>
<Typography className={classes.titleOfBox}>
CLINIC LOGO INFO
</Typography>
{/* <Typography className={classes.updatedDate}>
Uploaded:{' '}
{format(new Date(file?.updatedAt), 'dd MMM yyyy')}
</Typography> */}
<Typography className={classes.documentNumberAndNameLabel}>
{companyName} LOGO
</Typography>
</Box>
<Box className={classes.imageBox}>
<img
className={classes.image}
src={file.fileURL}
alt="Uploaded File"
/>
</Box>
</Box>
</Grid>
))}
</Grid>
<Grid container className={classes.mainGrid} gap={3.5}> <Grid container className={classes.mainGrid} gap={3.5}>
{reviewedOtherFiles.map((file, index) => ( {reviewedOtherFiles.map((file, index) => (
<Grid <Grid
@ -293,145 +259,6 @@ const FileEvaluate = ({
) : ( ) : (
<> <>
{/* .................logo reviewed grid................ */} {/* .................logo reviewed grid................ */}
<Grid container className={classes.mainGrid} gap={3.5}>
{reviewedLogoFiles.map((file, index) => (
<Grid key={index} className={classes.outerGrid}>
<Box className={classes.outerBox}>
<Box>
<Typography className={classes.titleOfBox}>
CLINIC LOGO INFO
</Typography>
{/* <Typography className={classes.updatedDate}>
Uploaded:{' '}
{format(new Date(file?.updatedAt), 'dd MMM yyyy')}
</Typography> */}
<Typography className={classes.documentNumberAndNameLabel}>
{companyName} LOGO
</Typography>
</Box>
<Box className={classes.imageBox}>
<img
className={classes.image}
src={file.file}
alt="Uploaded File"
/>
<Box className={classes?.onImageButton}>
<button
type="button"
className={classes.eyeButton}
onClick={() => handlePreview(file)}
>
<RemoveRedEyeOutlinedIcon
className={classes.iconSize}
/>
</button>
<button
type="button"
className={classes.downloadButton}
onClick={() => handleDownload(file)}
>
<SaveAltIcon className={classes.iconSize} />
</button>
</Box>
</Box>
<Box className={classes.buttonBox}>
{!file.isVerified && <DisableRejectedButton />}
{file.isVerified && <DisableAcceptedButton />}
</Box>
</Box>
</Grid>
))}
{notReviewedLogoFiles.map((file, index) => (
<Grid key={index} className={classes.outerGrid}>
<Box className={classes.outerBox}>
<Box>
<Typography className={classes.titleOfBox}>
CLINIC {file.documentType} INFO
</Typography>
{/* <Typography className={classes.updatedDate}>
Uploaded:{' '}
{format(new Date(file?.updatedAt), 'dd MMM yyyy')}
</Typography> */}
<Typography className={classes.documentNumberAndNameLabel}>
{companyName} LOGO
</Typography>
</Box>
<Box className={classes.logoPreviewImageBox}>
<img
className={classes.image}
src={file.file}
alt={file.documentType}
/>
<Box className={classes?.onImageButton}>
<button
type="button"
className={classes.eyeButton}
onClick={() => handlePreview(file)}
>
<RemoveRedEyeOutlinedIcon
className={classes.iconSize}
/>
</button>
<button
type="button"
className={classes.downloadButton}
onClick={() => handleDownload(file)}
>
<SaveAltIcon className={classes.iconSize} />
</button>
</Box>
</Box>
<Box className={classes.buttonBox}>
{file.isVerified == null ? (
<>
<ActionButton
index={index}
file={file}
actionType="REJECT"
onClick={(index, file) =>
handleActionClick(index, file, "REJECT")
}
/>
<ActionButton
index={index}
file={file}
actionType="ACCEPT"
onClick={(index, file) =>
handleActionClick(index, file, "ACCEPT")
}
/>
</>
) : file.isVerified ? (
<>
<ActionButton
index={index}
file={file}
actionType="REJECT"
onClick={(index, file) =>
handleActionClick(index, file, "REJECT")
}
/>
<DisableAcceptedButton />
</>
) : (
<>
<ActionButton
index={index}
file={file}
actionType="ACCEPT"
onClick={(index, file) =>
handleActionClick(index, file, "ACCEPT")
}
/>
<DisableRejectedButton />
</>
)}
</Box>
</Box>
</Grid>
))}
</Grid>
{/* .................another image grid............. */} {/* .................another image grid............. */}
<Grid container className={classes.mainGrid} gap={3.5}> <Grid container className={classes.mainGrid} gap={3.5}>

View File

@ -141,10 +141,10 @@ function ClinicDetails() {
const newFile = { const newFile = {
...file, ...file,
}; };
if (file.documentType == "LOGO") { // if (file.documentType == "LOGO") {
newFile.logo_is_verified = file.isVerified; // newFile.logo_is_verified = file.isVerified;
clinicFiles.logo_is_verified = file.isVerified; // clinicFiles.logo_is_verified = file.isVerified;
} // }
if (file.documentType == "ABN") { if (file.documentType == "ABN") {
newFile.abn_doc_is_verified = file.isVerified; newFile.abn_doc_is_verified = file.isVerified;
clinicFiles.abn_doc_is_verified = file.isVerified; clinicFiles.abn_doc_is_verified = file.isVerified;
@ -159,10 +159,10 @@ function ClinicDetails() {
const updatedFiles = [...prevFiles]; const updatedFiles = [...prevFiles];
const fileToBeUpdate = updatedFiles[oldIndex]; const fileToBeUpdate = updatedFiles[oldIndex];
if (fileToBeUpdate.documentType == "LOGO") { // if (fileToBeUpdate.documentType == "LOGO") {
fileToBeUpdate.logo_is_verified = file.isVerified; // fileToBeUpdate.logo_is_verified = file.isVerified;
clinicFiles.logo_is_verified = file.isVerified; // clinicFiles.logo_is_verified = file.isVerified;
} // }
if (fileToBeUpdate.documentType == "ABN") { if (fileToBeUpdate.documentType == "ABN") {
fileToBeUpdate.abn_doc_is_verified = file.isVerified; fileToBeUpdate.abn_doc_is_verified = file.isVerified;
@ -180,16 +180,6 @@ function ClinicDetails() {
} }
}; };
const getNotReviewedFileCount = () => {
if (clinicData?.companyDocuments) {
const notReviewedDocuments = clinicData.companyDocuments.filter(
(document) => document.status === "NOT_REVIEWED"
);
return notReviewedDocuments.length;
}
return;
};
const handleCancelRejection = async () => { const handleCancelRejection = async () => {
try { try {
setIsLoading(true); setIsLoading(true);
@ -246,7 +236,6 @@ function ClinicDetails() {
setButtonClickStatus("Rejected"); setButtonClickStatus("Rejected");
}; };
const handleAcceptClick = () => { const handleAcceptClick = () => {
// setIsShowReasonModel(true); // setIsShowReasonModel(true);
setButtonClickStatus("Accepted"); setButtonClickStatus("Accepted");
@ -260,8 +249,7 @@ function ClinicDetails() {
// Check if any document is not verified or is null/undefined // Check if any document is not verified or is null/undefined
const hasUnverifiedDocuments = const hasUnverifiedDocuments =
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;
// Set button visibility based on document verification status // Set button visibility based on document verification status
setIsRejectedButtonShow(hasUnverifiedDocuments); setIsRejectedButtonShow(hasUnverifiedDocuments);
@ -269,8 +257,7 @@ function ClinicDetails() {
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 &&
@ -279,6 +266,12 @@ function ClinicDetails() {
) { ) {
setIsAcceptedButtonShow(true); setIsAcceptedButtonShow(true);
} else { } else {
if(clinicData?.status === CLINIC_STATUS.PAYMENT_DUE){
pushNotification(
"Accept button is disabled due to Payment Due status",
NOTIFICATION.WARNING
);
}
setIsAcceptedButtonShow(false); setIsAcceptedButtonShow(false);
} }
}, [clinicFiles, updateFiles]); }, [clinicFiles, updateFiles]);
@ -456,8 +449,8 @@ function ClinicDetails() {
contract_doc: clinicData?.contract_doc, contract_doc: clinicData?.contract_doc,
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_is_verified: clinicFiles?.logo_is_verified, // logo_is_verified: clinicFiles?.logo_is_verified,
}, },
] ]
} }

View File

@ -7,7 +7,7 @@ import * as Yup from "yup";
import { MAX_FILE_SIZE_IN_MB, MAX_FILES } from "../../constants"; import { MAX_FILE_SIZE_IN_MB, MAX_FILES } from "../../constants";
import { import {
getClinicDocs, getClinicDocs,
updateClinicDocs, updateClinic,
} from "../../services/clinics.service"; } from "../../services/clinics.service";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
@ -93,7 +93,7 @@ const ClinicDocUpdater = () => {
// Only proceed if there are files to update // Only proceed if there are files to update
if (Object.keys(payload).length > 0) { if (Object.keys(payload).length > 0) {
const resp = await updateClinicDocs(formik.values.clinicId, payload); const resp = await updateClinic(formik.values.clinicId, payload);
console.log(resp); console.log(resp);
} }

View File

@ -0,0 +1,325 @@
import makeStyles from '@mui/styles/makeStyles';
import { pxToRem } from '../../theme/typography';
export const useStyles = makeStyles((theme) => ({
appBarStyle: {
backgroundColor: theme.palette.grey[28],
},
contentBox: {
marginTop: '3%',
},
mainContent: {
marginTop: theme.spacing(4),
marginBottom: theme.spacing(4),
marginLeft: theme.spacing(4),
marginRight: theme.spacing(4),
width: '100%',
overflowX: 'scroll',
'&::-webkit-scrollbar': {
height: '6px',
},
},
logoBox: {
display: 'flex',
width: '100%',
marginLeft: '1%',
[theme.breakpoints.down('md')]: {
width: 'auto',
},
},
logo: {
maxHeight: '61px',
objectFit: 'contain',
justifyContent: 'center',
},
whitePaper: {
width: '100%',
marginBottom: theme.spacing(0.3),
paddingBottom: theme.spacing(0.7),
borderRadius: `${theme.spacing(2)} ${theme.spacing(2)} ${theme.spacing(
1
)} ${theme.spacing(1)}`,
},
inputLabel: {
marginBottom: theme.spacing(0.5),
fontSize: pxToRem(12),
color: theme.palette.grey[10],
},
textAreaLast: {
width: '-webkit-fill-available',
'&.MuiButtonBase-root': {
padding: theme.spacing(0.8),
},
},
helperText: {
color: theme.palette.error.main,
fontStyle: 'italic',
},
formRoot: {
paddingTop: theme.spacing(3.2),
},
formPassswordHeading: {
fontSize: pxToRem(14),
fontWeight: '600',
},
passwordTextFiled: {
marginTop: theme.spacing(0),
},
icon: {
cursor: 'pointer',
paddingLeft: theme.spacing(3),
display: 'flex',
alignItems: 'center',
width: '50px',
[theme.breakpoints.up('md')]: {
width: '50px',
},
[theme.breakpoints.up('lg')]: {
width: '50px',
},
[theme.breakpoints.up('xl')]: {
width: '50px',
},
},
formPasswordHeadingRoot: {
paddingTop: theme.spacing(2),
paddingLeft: theme.spacing(2),
width: '100%',
},
subjectText: {
fontSize: pxToRem(12),
position: 'absolute',
right: pxToRem(8),
top: '90%',
transform: 'translateY(-90%)',
},
// --- AddForm Style ---
screenViewGridItem: {
marginTop: theme.spacing(1),
},
paperContainerBox: {
width: '100%',
},
countryCodeBox: {
padding: pxToRem(12),
paddingRight: pxToRem(20),
paddingLeft: pxToRem(16),
borderRadius: pxToRem(10),
backgroundColor: theme.palette.grey[20],
},
countryCodeLabel: {
marginBottom: theme.spacing(0),
opacity: 1,
fontFamily: 'Inter-Regular',
},
mobileNumberInput: {
fontFamily: 'Inter-Regular',
'& .MuiInputBase-root': {
paddingLeft: theme.spacing(0),
border: 0,
},
'& .MuiOutlinedInput-input': {
paddingLeft: theme.spacing(0),
},
},
passwordCheckListTitle: {
color: theme.palette.grey[20],
fontSize: pxToRem(12),
fontStyle: 'italic',
textAlign: 'left',
marginBottom: theme.spacing(0.4),
},
emailNote: {
color: theme.palette.grey[20],
fontSize: pxToRem(14),
fontStyle: 'italic',
textAlign: 'left',
marginBottom: theme.spacing(0.4),
},
passwordCheckList: {
fontSize: pxToRem(14),
paddingTop: theme.spacing(0.2),
fontStyle: 'italic',
color: theme.palette.grey[600],
},
stateTextField: {
'& .Mui-disabled': {
WebkitTextFillColor: theme.palette.grey[10], // Change to the appropriate color value
opacity: 1,
},
},
termsAndConditionErrorMessage: {
color: theme.palette.error.main,
fontStyle: 'italic',
fontSize: pxToRem(12),
marginTop: theme.spacing(0.5),
},
checkBox: {
marginTop: theme.spacing(3),
paddingRight: theme.spacing(1),
},
checkBoxLabel: {
marginTop: theme.spacing(3.2),
marginLeft: theme.spacing(1.2),
fontSize: pxToRem(16),
color: theme.palette.common.black,
},
linkText: {
color: theme.palette.grey[53],
},
placeholderText: {
fontStyle: 'italic',
fontSize: pxToRem(14),
opacity: 0.5,
color: theme.palette.grey[10],
},
// logo style
reactCrop: {
/* Set a minimum height and width */
minHeight: '200px',
minWidth: '200px',
},
dropZoneOuterBox: {
width: '100%',
},
inputTitle: {
'&.MuiTypography-body1': {
fontSize: pxToRem(12),
color: theme.palette.grey[10],
},
marginBottom: theme.spacing(0.6),
marginLeft: theme.spacing(0.6),
color: theme.palette.grey[10],
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
},
imgButton: {
color: theme?.palette?.primary?.main,
fontSize: pxToRem(12),
fontWeight: 600,
fontFamily: theme?.fontFamily?.Regular,
backgroundColor: 'transparent',
border: 'none',
cursor: 'pointer',
margin: `${theme.spacing(0)} ${theme.spacing(0.8)}`,
padding: theme.spacing(0),
outline: 'none',
},
logoUploadErrorBox: {
display: 'flex',
justifyContent: 'space-between',
},
errorText: {
color: theme.palette.error.main,
fontSize: pxToRem(12),
fontStyle: 'italic',
},
addButton: {
border: `1px dashed ${theme.palette.primary.main}`,
width: '100%',
height: '130px',
backgroundColor: theme.palette.common.white,
borderRadius: theme.spacing(1),
marginBottom: theme.spacing(1.48),
},
addButtonContent: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'column',
height: '100%',
cursor: 'pointer',
width: '100%',
},
addText: {
opacity: 1,
fontFamily: theme?.fontFamily?.medium,
fontSize: pxToRem(14),
height: '16px',
fontWeight: 500,
lineHeight: 'normal',
letterSpacing: 'normal',
marginTop: theme?.spacing(1),
},
addIcon: {
width: '26px',
height: '24px',
},
addSubtext: {
fontSize: pxToRem(12),
color: theme.palette.grey[10],
opacity: '0.6',
textAlign: 'center',
padding: `${theme.spacing(0.5)} ${theme.spacing(7)}`,
[theme.breakpoints.down('md')]: {
padding: theme.spacing(1),
},
[theme.breakpoints.down('lg')]: {
padding: theme.spacing(1),
},
},
previewBox: {
display: 'flex',
justifyContent: 'end',
alignItems: 'start',
width: '153px',
height: '111px',
borderRadius: theme.spacing(0.4),
backgroundSize: 'cover',
},
formSectionHeadingMargin: {
marginTop: theme.spacing(1.5),
},
termsAndConditionDrawer: {
'& .MuiDrawer-paper': {
maxWidth: pxToRem(550),
boxShadow: '-10px 0px 10px -2px rgba(0,0,0,0.1)',
},
[theme.breakpoints.down('md')]: {
width: '100%',
},
},
verifyIcon: {
fontSize: pxToRem(20),
color: theme.palette.grey[54],
},
chipOuter: {
display: 'flex',
flexWrap: 'wrap',
paddingLeft: theme.spacing(3.2),
},
chip: {
minWidth: '170px',
height: '42px',
padding: theme.spacing(1.5),
margin: theme.spacing(1),
marginRight: theme.spacing(1.5),
justifyContent: 'space-between',
borderRadius: '24px',
fontSize: pxToRem(14),
},
billingUserOuterSection: {
marginTop: theme.spacing(3.0),
},
billingUserEmailSection: {
padding: `${theme.spacing(2.2)} ${theme.spacing(3.2)}`,
},
saveUserButton: {
marginLeft: theme.spacing(1.0),
width: '150px',
display: 'flex',
justifyContent: 'space-evenly',
borderRadius: '8px',
height: '47px',
// opacity: 0.5,
},
billingUserEmailWrapper: {
display: 'flex',
[theme.breakpoints.down('md')]: {
flexDirection: 'column',
gap: '15px',
},
},
}));

View File

@ -13,6 +13,7 @@ import {
DialogContent, DialogContent,
DialogContentText, DialogContentText,
DialogTitle, DialogTitle,
InputAdornment,
MenuItem, MenuItem,
Paper, Paper,
Select, Select,
@ -26,10 +27,24 @@ import WarningAmberIcon from "@mui/icons-material/WarningAmber";
import { import {
CLINIC_GREETINGS_LENGTH, CLINIC_GREETINGS_LENGTH,
CLINIC_SCENARIOS_LENGTH, CLINIC_SCENARIOS_LENGTH,
NOTIFICATION,
} from "../../constants"; } from "../../constants";
import { useSelector } from "react-redux";
import { getClinicsById, updateClinic } from "../../services/clinics.service";
import { useStyles } from "./clinicSetupStyles";
import { useNavigate } from "react-router-dom";
// Integration software options // Integration software options
const integrationOptions = ["BP Software", "Medical Director"]; const integrationOptions = [
{
id: "bp",
name: "BP Software",
},
{
id: "medicaldirector",
name: "Medical Director",
},
];
// Steps for the stepper // Steps for the stepper
const steps = [ const steps = [
@ -55,12 +70,24 @@ const voiceModelGender = [
]; ];
export default function ClinicSetup() { export default function ClinicSetup() {
const classes = useStyles();
// Active step state // Active step state
const [activeStep, setActiveStep] = React.useState(0); const [activeStep, setActiveStep] = React.useState(0);
const [openDialog, setOpenDialog] = React.useState(false); const [openDialog, setOpenDialog] = React.useState(false);
const [audioContext, setAudioContext] = React.useState(null); const [audioContext, setAudioContext] = React.useState(null);
const [testConnDone, setTestConnDone] = React.useState(false); const [testConnDone, setTestConnDone] = React.useState(true);
const [confirmPhoneNumber, setConfirmPhoneNumber] = React.useState(false); const [confirmPhoneNumber, setConfirmPhoneNumber] = React.useState(true);
const [audioListenDone, setAudioListenDone] = React.useState(true);
const navigate = useNavigate();
const user = useSelector((state) => state.login.user);
const clinic = user?.created_clinics[0];
if (!clinic) {
pushNotification("Clinic not found!", NOTIFICATION.ERROR);
return;
}
// Completed steps state // Completed steps state
const [completed, setCompleted] = React.useState({}); const [completed, setCompleted] = React.useState({});
@ -68,7 +95,9 @@ export default function ClinicSetup() {
// Form state // Form state
const [formData, setFormData] = React.useState({ const [formData, setFormData] = React.useState({
// General Information // General Information
clinicPhone: "159875654", clinicId: clinic?.id,
clinicPhone: "",
clinicPonePrefix: "+61",
clinicAddress: "1 Wilkinson Road, Para Hills SA 5096", clinicAddress: "1 Wilkinson Road, Para Hills SA 5096",
otherInfo: "", otherInfo: "",
@ -153,8 +182,73 @@ If No -Pt who do not have a Medicare card / Private patients with or without I
// Voice Configuration // Voice Configuration
voice: "", voice: "",
voiceGender: voiceModelGender[1].id, voiceGender: voiceModelGender[1].id,
voice_model_provider: "rime",
}); });
const [prevFormData, setPrevFormData] = React.useState({
...formData,
});
const mobilePrefixOptions = [
{ id: "61", name: "+61" },
{ id: "91", name: "+91" },
];
const parsePhoneNumber = (phoneString) => {
// Split by space
const parts = phoneString.split(" ");
if (parts.length !== 2) {
return {
countryCode: null,
number: null,
error: "Phone number must contain exactly one space",
};
}
const countryCode = parts[0].replace("+", ""); // Everything before space (includes +)
const number = parts[1]; // Everything after space
return {
countryCode,
number,
};
};
const getClinic = async () => {
const resp = await getClinicsById(clinic.id);
if (resp?.data?.error) {
pushNotification(resp?.data?.message, NOTIFICATION.ERROR);
return;
}
const clinicResp = resp?.data?.data?.clinic;
const { countryCode, number } = parsePhoneNumber(clinicResp?.phone);
setFormData({
...formData,
clinicPhone: number,
clinicPonePrefix: countryCode,
clinicAddress: clinicResp?.address,
clinicOthers: clinicResp?.general_info,
otherInfo: clinicResp?.other_info ?? formData.otherInfo,
clinicGreetings: clinicResp?.greeting_msg ?? formData.clinicGreetings,
clinicScenarios: clinicResp?.scenarios ?? formData.clinicScenarios,
integrationSoftware: clinicResp?.integration,
practiceId: clinicResp?.pms_id,
practiceName: clinicResp?.practice_name,
voice: clinicResp?.voice_model ?? formData.voice,
voiceGender: clinicResp?.voice_model_gender ?? formData.voiceGender,
voice_model_provider: clinicResp?.voice_model_provider,
});
setPrevFormData({
...formData,
});
};
React.useEffect(() => {
getClinic();
}, []);
// Handle form reset // Handle form reset
const handleReset = () => { const handleReset = () => {
setActiveStep(0); setActiveStep(0);
@ -172,12 +266,6 @@ If No -Pt who do not have a Medicare card / Private patients with or without I
setConfirmPhoneNumber(true); setConfirmPhoneNumber(true);
}; };
React.useEffect(() => {
if(formData.clinicPhone=="159875654"){
setConfirmPhoneNumber(true);
}
}, []);
React.useEffect(() => { React.useEffect(() => {
// Initialize audio context when component mounts // Initialize audio context when component mounts
function initAudioContext() { function initAudioContext() {
@ -224,11 +312,31 @@ If No -Pt who do not have a Medicare card / Private patients with or without I
// Handle next button click // Handle next button click
const handleNext = () => { const handleNext = () => {
if (
prevFormData.clinicPhone !== formData.clinicPhone &&
!confirmPhoneNumber
) {
pushNotification("Please confirm phone number", "error");
return;
}
if (!confirmPhoneNumber) { if (!confirmPhoneNumber) {
pushNotification("Please confirm phone number", "error"); pushNotification("Please confirm phone number", "error");
return; return;
} }
if (activeStep == 1) {
if (
!audioListenDone
) {
pushNotification(
"Please listen to the audio before proceeding",
"error"
);
return;
}
}
const newActiveStep = const newActiveStep =
isLastStep() && !allStepsCompleted() isLastStep() && !allStepsCompleted()
? // It's the last step, but not all steps have been completed, ? // It's the last step, but not all steps have been completed,
@ -293,6 +401,9 @@ If No -Pt who do not have a Medicare card / Private patients with or without I
} }
); );
}) })
.then(() => {
setAudioListenDone(true);
})
.catch((err) => { .catch((err) => {
pushNotification(`Error: ${err.message}`, "error"); pushNotification(`Error: ${err.message}`, "error");
}); });
@ -330,6 +441,17 @@ If No -Pt who do not have a Medicare card / Private patients with or without I
return; return;
} }
// if voice model or voice gender is changed then must listen first
if (activeStep == 1) {
if (!audioListenDone) {
pushNotification(
"Please listen to the audio before proceeding",
"error"
);
return;
}
}
// Then check if the step is completed // Then check if the step is completed
if (completed[step]) { if (completed[step]) {
setActiveStep(step); setActiveStep(step);
@ -396,6 +518,12 @@ If No -Pt who do not have a Medicare card / Private patients with or without I
// Handle complete step // Handle complete step
const handleComplete = () => { const handleComplete = () => {
if( activeStep == 4 && !testConnDone){
pushNotification("Please test connection before proceeding", NOTIFICATION.ERROR);
return;
}
if (true) { if (true) {
const newCompleted = { ...completed }; const newCompleted = { ...completed };
newCompleted[activeStep] = true; newCompleted[activeStep] = true;
@ -415,6 +543,14 @@ If No -Pt who do not have a Medicare card / Private patients with or without I
setConfirmPhoneNumber(false); setConfirmPhoneNumber(false);
} }
if (name === "voice" || name === "voiceGender") {
setAudioListenDone(false);
}
if (name === "integrationSoftware" || name === "practiceId" || name === "practiceName") {
setTestConnDone(false);
}
setFormData((prev) => ({ setFormData((prev) => ({
...prev, ...prev,
[name]: value, [name]: value,
@ -461,45 +597,40 @@ If No -Pt who do not have a Medicare card / Private patients with or without I
}; };
// Handle form submission // Handle form submission
const handleSubmit = (e) => { const handleSubmit = async (e) => {
e.preventDefault(); e.preventDefault();
const payload = {
clinicId: formData.clinicId,
phone: `${formData.clinicPonePrefix} ${formData.clinicPhone}`,
address: formData.clinicAddress,
other_info: formData.otherInfo,
general_info: formData.clinicOthers,
greeting_msg: formData.clinicGreetings,
scenarios: formData.clinicScenarios,
integration: formData.integrationSoftware,
pms_id: formData.practiceId,
practice_name: formData.practiceName,
voice_model: formData.voice,
voice_model_gender: formData.voiceGender,
voice_model_provider:"rime"
};
if (validateForm()) { if (validateForm()) {
console.log("Form submitted:", formData); const resp = await updateClinic(formData.clinicId, payload);
if(resp?.data?.error){
pushNotification(resp?.data?.message, NOTIFICATION.ERROR);
return;
}
// Here you would typically send the data to your backend // Here you would typically send the data to your backend
pushNotification("Clinic setup updated successfully", "success"); pushNotification("Clinic setup updated successfully", "success");
// Reset the form after submission // Reset the form state manually
handleReset(); setActiveStep(0);
} else { setCompleted({});
// Find the first step with errors and go to it setConfirmPhoneNumber(true);
if ( setTestConnDone(true);
formData.clinicPhone.trim() === "" || setAudioListenDone(true);
formData.clinicAddress.trim() === ""
) {
setActiveStep(0);
setErrors({
...errors,
clinicPhone: formData.clinicPhone.trim() === "",
clinicAddress: formData.clinicAddress.trim() === "",
});
} else if (
formData.integrationSoftware &&
(formData.practiceId.trim() === "" ||
formData.practiceName.trim() === "")
) {
setActiveStep(3);
setErrors({
...errors,
practiceId: formData.practiceId.trim() === "",
practiceName: formData.practiceName.trim() === "",
});
}
// Show an alert // Refetch the clinic data to get the latest state
pushNotification( await getClinic();
"Please fill in all required fields before submitting",
NOTIFICATION_TYPE.ERROR
);
} }
}; };
@ -514,18 +645,22 @@ If No -Pt who do not have a Medicare card / Private patients with or without I
xs={12} xs={12}
md={10} md={10}
alignItems="baseline" alignItems="baseline"
// justifyContent="center"
// alignContent="center"
flexDirection="row" flexDirection="row"
display="flex" display="flex"
> >
<TextField <TextField
type="number" className={classes.mobileNumberInput}
type="string"
style={{ width: "40%" }} style={{ width: "40%" }}
label="Clinic Phone Number" label="Clinic Phone Number"
name="clinicPhone" name="clinicPhone"
value={formData.clinicPhone} value={formData.clinicPhone}
onChange={handleChange} onChange={(e) => {
if (e.target.value.length <= 10) {
const value = e.target.value?.match(/\d+/g) || "";
handleChange(e);
}
}}
helperText={ helperText={
errors.clinicPhone errors.clinicPhone
? "Phone number is required" ? "Phone number is required"
@ -533,6 +668,37 @@ If No -Pt who do not have a Medicare card / Private patients with or without I
} }
variant="outlined" variant="outlined"
error={errors.clinicPhone} error={errors.clinicPhone}
InputProps={{
startAdornment: (
<Box sx={{ padding: "1px" }}>
<InputAdornment position="start">
<Select
name="clinicPonePrefix"
value={formData.clinicPonePrefix}
onChange={(e) => {
setFormData({
...formData,
clinicPonePrefix: e.target.value,
});
}}
>
{mobilePrefixOptions.map((option) => (
<MenuItem
sx={{
outline: "none",
border: "none",
}}
key={option.id}
value={option.id}
>
{option.name}
</MenuItem>
))}
</Select>
</InputAdornment>
</Box>
),
}}
/> />
<Button <Button
style={{ marginLeft: "10px" }} style={{ marginLeft: "10px" }}
@ -791,8 +957,8 @@ If No -Pt who do not have a Medicare card / Private patients with or without I
<em>None</em> <em>None</em>
</MenuItem> </MenuItem>
{integrationOptions.map((option) => ( {integrationOptions.map((option) => (
<MenuItem key={option} value={option}> <MenuItem key={option.id} value={option.id}>
{option} {option.name}
</MenuItem> </MenuItem>
))} ))}
</Select> </Select>
@ -888,10 +1054,10 @@ If No -Pt who do not have a Medicare card / Private patients with or without I
</Typography> </Typography>
<Box sx={{ display: "flex", flexDirection: "row", pt: 2 }}> <Box sx={{ display: "flex", flexDirection: "row", pt: 2 }}>
<Box sx={{ flex: "1 1 auto" }} /> <Box sx={{ flex: "1 1 auto" }} />
{/* <Button onClick={handleReset} sx={{ mr: 1 }}> <Button onClick={handleBack} sx={{ mr: 1 }} color="primary" variant="outlined">
Reset Back
</Button> */} </Button>
<Button variant="contained" color="primary" type="submit"> <Button onClick={handleSubmit} variant="contained" color="primary" type="submit" disabled={activeStep == 4 && !testConnDone}>
Submit Setup Submit Setup
</Button> </Button>
</Box> </Box>
@ -923,7 +1089,7 @@ If No -Pt who do not have a Medicare card / Private patients with or without I
)} )}
{activeStep != 4 && ( {activeStep != 4 && (
<Button <Button
disabled={activeStep == 5 && !testConnDone} disabled={activeStep == 4 && !testConnDone}
onClick={handleNext} onClick={handleNext}
sx={{ mr: 1 }} sx={{ mr: 1 }}
variant="outlined" variant="outlined"

View File

@ -71,7 +71,8 @@ const ClinicsList = () => {
const serialNumber = ( const serialNumber = (
props?.row?.index + props?.row?.index +
1 + 1 +
tableState?.pagination?.pageIndex * tableState?.pagination?.pageSize tableState?.pagination?.pageIndex *
tableState?.pagination?.pageSize
) )
?.toString() ?.toString()
?.padStart(1, "0"); ?.padStart(1, "0");
@ -89,22 +90,10 @@ const ClinicsList = () => {
Cell: ({ row }) => ( Cell: ({ row }) => (
<> <>
<div className={classes.companyNameTableColumn}> <div className={classes.companyNameTableColumn}>
{row?.original?.logo ? (
<img
alt="logo"
className={classes.companyNameLogo}
src={row?.original?.logo}
/>
) : (
<StoreIcon />
)}
{/* <img {/* <img
className={classes.companyNameLogo} className={classes.companyNameLogo}
src={ src="https://dev-ai-appointment.s3.ap-southeast-2.amazonaws.com/common/clinic_logo.jpg"
row?.original?.logo alt="logo"
? row?.original?.logo
: companyDefaultIcon
}
/> */} /> */}
<div className={classes.companyName}> <div className={classes.companyName}>
<Link <Link
@ -287,22 +276,10 @@ const ClinicsList = () => {
Cell: ({ row }) => ( Cell: ({ row }) => (
<> <>
<div className={classes.companyNameTableColumn}> <div className={classes.companyNameTableColumn}>
{row?.original?.logo ? (
<img
className={classes.companyNameLogo}
src={row?.original?.logo}
alt="logo"
/>
) : (
<StoreIcon />
)}
{/* <img {/* <img
className={classes.companyNameLogo} className={classes.companyNameLogo}
src={ src="https://dev-ai-appointment.s3.ap-southeast-2.amazonaws.com/common/clinic_logo.jpg"
row?.original?.logo alt="logo"
? row?.original?.logo
: companyDefaultIcon
}
/> */} /> */}
<div className={classes.companyName}> <div className={classes.companyName}>
@ -375,7 +352,7 @@ const ClinicsList = () => {
setType(newValue); setType(newValue);
}; };
const getData = async (filters) => { const getData = async (filters, unregistered = true) => {
let params = { let params = {
...filters, ...filters,
type, type,
@ -385,7 +362,9 @@ const ClinicsList = () => {
setTotalInactive(resp?.data?.data?.data?.totalRejectedClinics); setTotalInactive(resp?.data?.data?.data?.totalRejectedClinics);
return { return {
data: resp?.data?.data?.data?.clinics, data: resp?.data?.data?.data?.clinics,
rowCount: resp?.data?.data?.total, rowCount: unregistered
? resp?.data?.data?.data?.totalRejectedClinics
: resp?.data?.data?.data?.totalRegisteredClinics,
}; };
}; };
@ -420,7 +399,8 @@ const ClinicsList = () => {
const handleFreezeClinic = async () => { const handleFreezeClinic = async () => {
try { try {
// Determine if we're freezing or unfreezing based on current status // Determine if we're freezing or unfreezing based on current status
const isCurrentlyFrozen = clinicToFreeze.status === CLINIC_STATUS.INACTIVE; const isCurrentlyFrozen =
clinicToFreeze.status === CLINIC_STATUS.INACTIVE;
const newStatus = isCurrentlyFrozen ? "active" : CLINIC_STATUS.INACTIVE; const newStatus = isCurrentlyFrozen ? "active" : CLINIC_STATUS.INACTIVE;
const payload = { const payload = {
@ -442,12 +422,16 @@ const ClinicsList = () => {
} }
} catch (error) { } catch (error) {
// Show appropriate error message // Show appropriate error message
const isCurrentlyFrozen = clinicToFreeze.status === CLINIC_STATUS.INACTIVE; const isCurrentlyFrozen =
clinicToFreeze.status === CLINIC_STATUS.INACTIVE;
const errorMessage = isCurrentlyFrozen const errorMessage = isCurrentlyFrozen
? "Failed to unfreeze clinic" ? "Failed to unfreeze clinic"
: "Failed to freeze clinic"; : "Failed to freeze clinic";
console.error(`Error ${isCurrentlyFrozen ? 'unfreezing' : 'freezing'} clinic:`, error); console.error(
`Error ${isCurrentlyFrozen ? "unfreezing" : "freezing"} clinic:`,
error
);
pushNotification(errorMessage, NOTIFICATION.ERROR); pushNotification(errorMessage, NOTIFICATION.ERROR);
} }
@ -456,7 +440,6 @@ const ClinicsList = () => {
setClinicToFreeze(null); setClinicToFreeze(null);
}; };
const breadcrumbs = [ const breadcrumbs = [
{ {
label: "Dashboard", label: "Dashboard",
@ -517,7 +500,7 @@ const ClinicsList = () => {
<Table <Table
hideTopToolbar hideTopToolbar
columns={columnsUnregistered} columns={columnsUnregistered}
getData={getData} getData={(filters) => getData(filters, true)} // true for unregistered
options={{ options={{
enableRowSelection: false, enableRowSelection: false,
showTopBar: false, showTopBar: false,
@ -532,7 +515,7 @@ const ClinicsList = () => {
<Table <Table
hideTopToolbar hideTopToolbar
columns={columnsRegistered} columns={columnsRegistered}
getData={getData} getData={(filters) => getData(filters, false)} // false for registered
options={{ enableRowSelection: true, showTopBar: false }} options={{ enableRowSelection: true, showTopBar: false }}
showSearchBox={true} showSearchBox={true}
ref={ref} ref={ref}
@ -587,8 +570,7 @@ const ClinicsList = () => {
<Typography variant="body1"> <Typography variant="body1">
{clinicToFreeze?.status === CLINIC_STATUS.INACTIVE {clinicToFreeze?.status === CLINIC_STATUS.INACTIVE
? `Are you sure you want to unfreeze ${clinicToFreeze?.name}? This will restore the clinic's access to the system.` ? `Are you sure you want to unfreeze ${clinicToFreeze?.name}? This will restore the clinic's access to the system.`
: `Are you sure you want to freeze ${clinicToFreeze?.name}? This will prevent the clinic from accessing the system until unfrozen.` : `Are you sure you want to freeze ${clinicToFreeze?.name}? This will prevent the clinic from accessing the system until unfrozen.`}
}
</Typography> </Typography>
</DialogContent> </DialogContent>
@ -618,7 +600,9 @@ const ClinicsList = () => {
px: 3, px: 3,
}} }}
> >
{clinicToFreeze?.status === CLINIC_STATUS.INACTIVE ? "Unfreeze" : "Freeze"} {clinicToFreeze?.status === CLINIC_STATUS.INACTIVE
? "Unfreeze"
: "Freeze"}
</Button> </Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>

View File

@ -52,7 +52,7 @@ const Totals = ({ data, setData }) => {
<TotalNumber <TotalNumber
heading={'Active Doctors/Nurses'} heading={'Active Doctors/Nurses'}
isLoading={isLoading} isLoading={isLoading}
value={totalMaxJobPostings} value={activeJobs}
// showAsterisk // showAsterisk
/> />
</Grid> </Grid>
@ -61,7 +61,7 @@ const Totals = ({ data, setData }) => {
heading={`Inactive Doctors/Nurses`} heading={`Inactive Doctors/Nurses`}
isLoading={isLoading} isLoading={isLoading}
viewAllClick={() => viewAllClick(true)} viewAllClick={() => viewAllClick(true)}
value={activeJobs} value={totalMaxJobPostings}
// infoPopover={'Total no. of jobs which are in active state.'} // infoPopover={'Total no. of jobs which are in active state.'}
// color="#14d1ad" // color="#14d1ad"
/> />

View File

@ -13,10 +13,16 @@ const initialState = {};
const loginPending = (state) => ({ const loginPending = (state) => ({
...state, ...state,
}); });
const loginFulfilled = (state, payload) => ({
...state, const loginFulfilled = (state, payload) => {
token: payload?.payload?.data?.data, // remove prev state
}); localStorage.removeItem('redux');
return {
...state,
token: payload?.payload?.data?.data,
}
}
const loginRejected = (state) => ({ const loginRejected = (state) => ({
...state, ...state,
}); });

View File

@ -127,7 +127,6 @@ const MasterDataManagement = () => {
}; };
const resp = await getMasterData(params); const resp = await getMasterData(params);
console.log("API Response:", resp);
return { return {
data: resp?.data?.data?.data, data: resp?.data?.data?.data,

View File

@ -265,7 +265,7 @@ const PaymentManagement = () => {
showFilters: true, showFilters: true,
}} }}
showAction={true} showAction={true}
searchText="Payments" searchText="Clinics"
showSearchBox={true} showSearchBox={true}
actions={[ actions={[
{ {

View File

@ -1465,7 +1465,7 @@ function YourDetailsForm() {
</Grid> </Grid>
{/* Clinic logo grid */} {/* Clinic logo grid */}
<Grid item md={5} sm={12}> {/* <Grid item md={5} sm={12}>
<InputLabel <InputLabel
sx={{ sx={{
display: "flex", display: "flex",
@ -1616,7 +1616,7 @@ function YourDetailsForm() {
</label> </label>
</Box> </Box>
</Box> </Box>
</Grid> </Grid> */}
</Grid> </Grid>
{/* ADD Business ADDRESS */} {/* ADD Business ADDRESS */}

View File

@ -203,7 +203,7 @@ function Users() {
}, },
{ {
size: 100, size: 100,
accessorFn: ({ role }) => role || NOT_AVAILABLE_TEXT, accessorFn: ({ role }) => (role ? role.charAt(0).toUpperCase() + role.slice(1) : NOT_AVAILABLE_TEXT),
accessorKey: "role", accessorKey: "role",
header: "User Type", header: "User Type",
}, },
@ -276,7 +276,7 @@ function Users() {
}, },
{ {
size: 100, size: 100,
accessorFn: ({ status }) => status || NOT_AVAILABLE_TEXT, accessorFn: ({ status }) => (status ? status[0].toUpperCase() + status.slice(1) : NOT_AVAILABLE_TEXT),
accessorKey: "status", accessorKey: "status",
header: "Status", header: "Status",
}, },
@ -311,7 +311,7 @@ function Users() {
hideShowPerPage={false} hideShowPerPage={false}
showSearchBox={true} showSearchBox={true}
ref={ref} ref={ref}
searchText={"user"} searchText={"Doctor/Nurse(s)"}
getRowStyle={getRowStyle} getRowStyle={getRowStyle}
actions={[ actions={[
{ {