feat: freeze clinic improved

This commit is contained in:
deepvasoya 2025-05-22 16:34:50 +05:30
parent 34bec707ca
commit 1f7c183e7e
4 changed files with 208 additions and 61 deletions

View File

@ -42,6 +42,7 @@ export const CLINIC_STATUS = {
APPROVED: 'APPROVED',
APPROVAL_PENDING_DOCUMENT_RESUBMITTED:
'APPROVAL_PENDING_DOCUMENT_RESUBMITTED',
INACTIVE: 'inactive',
};
export const CLINIC_DOCUMENT_STATUS = {

View File

@ -16,8 +16,6 @@ import { clinicsData, registeredClinicsData } from "../mock/clinics";
// };
export const getClinics = (params) => {
console.log(params);
let searchParams = new URLSearchParams();
searchParams.append("size", params?.pagination?.pageSize ?? 10);
searchParams.append("page", params?.pagination.pageIndex ?? 0);

View File

@ -12,7 +12,7 @@ export const getDashboardStats = () => {
export const getSignupMasterPricing = () => {
const url = '/dashboard/signup-pricing-master/';
const url = '/dashboard/signup-pricing-master';
return new Promise((resolve, reject) => {
axiosInstance
.get(url)
@ -23,7 +23,7 @@ export const getSignupMasterPricing = () => {
export const setSignupMasterPricing = (data) => {
const url = '/dashboard/signup-pricing-master/';
const url = '/dashboard/signup-pricing-master';
return new Promise((resolve, reject) => {
axiosInstance
.post(url, data)

View File

@ -1,49 +1,63 @@
import React, { useState, useMemo, useEffect, useRef } from "react";
import { useTheme } from "@emotion/react";
import { useLocation, useNavigate,Link } from "react-router-dom";
import StoreIcon from '@mui/icons-material/Store';
import DescriptionIcon from '@mui/icons-material/Description';
import { Box, Chip,Tab, Tabs } from '@mui/material';
import { differenceInDays, format } from 'date-fns';
import { LoadingButton } from '@mui/lab';
import FileDownloadIcon from '@mui/icons-material/FileDownload';
import { useLocation, useNavigate, Link } from "react-router-dom";
import StoreIcon from "@mui/icons-material/Store";
import BlockIcon from "@mui/icons-material/Block";
import {
Box,
Chip,
Tab,
Tabs,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Button,
Typography,
IconButton,
} from "@mui/material";
import { differenceInDays, format } from "date-fns";
import { LoadingButton } from "@mui/lab";
import FileDownloadIcon from "@mui/icons-material/FileDownload";
import CloseIcon from "@mui/icons-material/Close";
import { useStyles } from "./clinicListStyles";
import { CLINIC_STATUS, CLINIC_TYPE, NOT_AVAILABLE_TEXT, PLAN_STATUS_TYPE } from "../../constants";
import { getClinics } from "../../services/clinics.service";
import {
CLINIC_STATUS,
CLINIC_TYPE,
NOT_AVAILABLE_TEXT,
NOTIFICATION,
PLAN_STATUS_TYPE,
} from "../../constants";
import { getClinics, updateClinicStatus } from "../../services/clinics.service";
import CustomBreadcrumbs from "../../components/CustomBreadcrumbs";
import Table from "../../components/Table";
import TableSelect from "../../components/TableSelect";
import PageHeader from '../../components/PageHeader';
import PageHeader from "../../components/PageHeader";
import { pushNotification } from "../../utils/notification";
const ClinicsList = () => {
const theme = useTheme();
const ref = useRef(null);
const classes = useStyles();
const params = useLocation();
const navigate = useNavigate();
const queryParams = new URLSearchParams(params.search);
const [type, setType] = useState(
queryParams.get("tab") ?? CLINIC_TYPE.UNREGISTERED
);
const showNewPlanAddedModel =
Boolean(queryParams.get("isPlanCreated")) ?? false;
const [isDownloading, setIsDownloading] = useState(false);
const[totalActive, setTotalActive] = useState(0);
const[totalInactive, setTotalInactive] = useState(0);
const [showModel, setShowModel] = useState(false);
const [modelType, setModelType] = useState("");
const [rowActionData, setRowActionData] = useState("");
const [isEmailSentPopupOpen, setIsEmailSentPopupOpen] = useState(false);
const emailList = useRef();
const [totalActive, setTotalActive] = useState(0);
const [totalInactive, setTotalInactive] = useState(0);
// State for freeze clinic confirmation dialog
const [freezeDialogOpen, setFreezeDialogOpen] = useState(false);
const [clinicToFreeze, setClinicToFreeze] = useState(null);
const UNREGISTERED_CLINIC_STATUS_OPTIONS = [
{ id: 1, name: CLINIC_STATUS.NOT_REVIEWED, showName: 'Approval Pending' },
{ id: 1, name: CLINIC_STATUS.NOT_REVIEWED, showName: "Approval Pending" },
{ id: 2, name: CLINIC_STATUS.APPROVAL_PENDING_DOCUMENT_RESUBMITTED },
{ id: 3, name: CLINIC_STATUS.ON_HOLD, showName: 'On Hold' },
{ id: 4, name: CLINIC_STATUS.REJECTED, showName: 'Rejected' },
{ id: 3, name: CLINIC_STATUS.ON_HOLD, showName: "On Hold" },
{ id: 4, name: CLINIC_STATUS.REJECTED, showName: "Rejected" },
];
const columnsUnregistered = useMemo(
@ -79,7 +93,11 @@ const ClinicsList = () => {
<>
<div className={classes.companyNameTableColumn}>
{row?.original?.logo ? (
<img alt="logo" className={classes.companyNameLogo} src={row?.original?.logo}/>
<img
alt="logo"
className={classes.companyNameLogo}
src={row?.original?.logo}
/>
) : (
<StoreIcon />
)}
@ -121,10 +139,7 @@ const ClinicsList = () => {
<>
<div>
{row?.original?.update_time
? format(
new Date(row.original.update_time),
"dd MMM yyyy"
)
? format(new Date(row.original.update_time), "dd MMM yyyy")
: NOT_AVAILABLE_TEXT}
</div>
</>
@ -275,7 +290,11 @@ const ClinicsList = () => {
<>
<div className={classes.companyNameTableColumn}>
{row?.original?.logo ? (
<img className={classes.companyNameLogo} src={row?.original?.logo} alt="logo" />
<img
className={classes.companyNameLogo}
src={row?.original?.logo}
alt="logo"
/>
) : (
<StoreIcon />
)}
@ -330,6 +349,26 @@ const ClinicsList = () => {
);
},
},
{
enableSorting: false,
size: 100,
header: "Actions",
Cell: ({ row }) => {
return (
<div className={classes.actions}>
<Button
variant="contained"
color="primary"
onClick={() => openFreezeConfirmation(row)}
>
{row.original.status === CLINIC_STATUS.INACTIVE
? "Unfreeze"
: "Freeze"}
</Button>
</div>
);
},
},
].filter(Boolean),
[type]
);
@ -373,10 +412,53 @@ const ClinicsList = () => {
// }
};
const handleRequestSentClose = () => {
// setIsEmailSentPopupOpen(false);
// Open freeze confirmation dialog
const openFreezeConfirmation = (row) => {
setClinicToFreeze(row.original);
setFreezeDialogOpen(true);
};
// Handle freeze/unfreeze clinic after confirmation
const handleFreezeClinic = async () => {
try {
// Determine if we're freezing or unfreezing based on current status
const isCurrentlyFrozen = clinicToFreeze.status === CLINIC_STATUS.INACTIVE;
const newStatus = isCurrentlyFrozen ? "active" : CLINIC_STATUS.INACTIVE;
const payload = {
clinic_id: clinicToFreeze.id,
status: newStatus,
};
const resp = await updateClinicStatus(payload);
// Show appropriate success message
const successMessage = isCurrentlyFrozen
? "Clinic unfrozen successfully"
: "Clinic frozen successfully";
pushNotification(successMessage, NOTIFICATION.SUCCESS);
// Refresh the table
if (ref.current) {
ref.current.reFetchData();
}
} catch (error) {
// Show appropriate error message
const isCurrentlyFrozen = clinicToFreeze.status === CLINIC_STATUS.INACTIVE;
const errorMessage = isCurrentlyFrozen
? "Failed to unfreeze clinic"
: "Failed to freeze clinic";
console.error(`Error ${isCurrentlyFrozen ? 'unfreezing' : 'freezing'} clinic:`, error);
pushNotification(errorMessage, NOTIFICATION.ERROR);
}
// Close the dialog
setFreezeDialogOpen(false);
setClinicToFreeze(null);
};
const breadcrumbs = [
{
label: "Dashboard",
@ -385,7 +467,7 @@ const ClinicsList = () => {
{
label: "Clinic List",
path: "/clinics",
query: { tab: queryParams.get('tab') || 'UNREGISTERED' }
query: { tab: queryParams.get("tab") || "UNREGISTERED" },
},
];
@ -397,17 +479,21 @@ const ClinicsList = () => {
return (
<>
<Box>
<PageHeader
<PageHeader
pageTitle="Clinic List"
hideAddButton
addButtonIcon={
<FileDownloadIcon />
}
addButtonIcon={<FileDownloadIcon />}
extraComponent={
<Box className={classes.tabsBox}>
<Tabs value={type} onChange={handleTabsChange}>
<Tab value={CLINIC_TYPE.UNREGISTERED} label={`Unregistered (${totalInactive})`} />
<Tab value={CLINIC_TYPE.REGISTERED} label={`Registered (${totalActive})`} />
<Tab
value={CLINIC_TYPE.UNREGISTERED}
label={`Unregistered (${totalInactive})`}
/>
<Tab
value={CLINIC_TYPE.REGISTERED}
label={`Registered (${totalActive})`}
/>
{/* <Tab value={COMPANY_TYPE.SUBSCRIBED} label="Subscribers" /> */}
</Tabs>
</Box>
@ -418,9 +504,7 @@ const ClinicsList = () => {
color="primary"
variant="outlined"
loading={isDownloading}
startIcon={
<FileDownloadIcon />
}
startIcon={<FileDownloadIcon />}
// onClick={handleExport}
>
Download Excel
@ -456,26 +540,90 @@ const ClinicsList = () => {
ref={ref}
showAction={true}
searchText="Clinics"
actions={[
{
onClick: (row) =>
handleModelOpen(row, "transactionHistory"),
text: "Freeze Clinic",
icon: (
<DescriptionIcon />
// <img
// src={TransactionHistoryIcon}
// className={classes.tableActionIcons}
// alt="transaction history"
// />
),
},
]}
/>
)}
</Box>
</Box>
</Box>
{/* Freeze Clinic Confirmation Dialog */}
<Dialog
open={freezeDialogOpen}
onClose={() => setFreezeDialogOpen(false)}
maxWidth="xs"
fullWidth
PaperProps={{
sx: {
borderRadius: "12px",
overflow: "hidden",
},
}}
>
<DialogTitle
sx={{
padding: "16px 24px",
backgroundColor: (theme) => theme.palette.error.main,
color: "white",
fontWeight: "bold",
position: "relative",
}}
>
{clinicToFreeze?.status === CLINIC_STATUS.INACTIVE
? "Confirm Unfreeze Clinic"
: "Confirm Freeze Clinic"}
<IconButton
aria-label="close"
onClick={() => setFreezeDialogOpen(false)}
sx={{
position: "absolute",
right: 8,
top: 8,
color: "white",
}}
>
<CloseIcon />
</IconButton>
</DialogTitle>
<DialogContent sx={{ padding: "24px 24px 16px", mt: 1 }}>
<Typography variant="body1">
{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 freeze ${clinicToFreeze?.name}? This will prevent the clinic from accessing the system until unfrozen.`
}
</Typography>
</DialogContent>
<DialogActions
sx={{
padding: "16px 24px",
borderTop: "1px solid",
borderColor: (theme) => theme.palette.grey[200],
justifyContent: "space-between",
}}
>
<Button
onClick={() => setFreezeDialogOpen(false)}
sx={{
color: (theme) => theme.palette.grey[700],
fontWeight: "medium",
}}
>
Cancel
</Button>
<Button
onClick={handleFreezeClinic}
variant="contained"
color="error"
sx={{
borderRadius: "8px",
px: 3,
}}
>
{clinicToFreeze?.status === CLINIC_STATUS.INACTIVE ? "Unfreeze" : "Freeze"}
</Button>
</DialogActions>
</Dialog>
</>
);
};