feat: pr changes
This commit is contained in:
parent
d9db46abca
commit
4717c67cca
|
|
@ -7,11 +7,11 @@ import {
|
||||||
Select,
|
Select,
|
||||||
TextField,
|
TextField,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from '@mui/material';
|
} from "@mui/material";
|
||||||
import {MaterialReactTable} from 'material-react-table';
|
import { MaterialReactTable } from "material-react-table";
|
||||||
import PreviousIcon from '@mui/icons-material/ArrowBack';
|
import PreviousIcon from "@mui/icons-material/ArrowBack";
|
||||||
import NextIcon from '@mui/icons-material/ArrowForward';
|
import NextIcon from "@mui/icons-material/ArrowForward";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
import React, {
|
import React, {
|
||||||
forwardRef,
|
forwardRef,
|
||||||
memo,
|
memo,
|
||||||
|
|
@ -20,17 +20,17 @@ import React, {
|
||||||
useMemo,
|
useMemo,
|
||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from "react";
|
||||||
import SearchIcon from '@mui/icons-material/Search';
|
import SearchIcon from "@mui/icons-material/Search";
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from "@mui/material/Typography";
|
||||||
import Pagination from '@mui/material/Pagination';
|
import Pagination from "@mui/material/Pagination";
|
||||||
import PaginationItem from '@mui/material/PaginationItem';
|
import PaginationItem from "@mui/material/PaginationItem";
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from "lodash";
|
||||||
import { ExpandMore } from '@mui/icons-material';
|
import { ExpandMore } from "@mui/icons-material";
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import { useStyles } from './styles/tableStyles';
|
import { useStyles } from "./styles/tableStyles";
|
||||||
import ProtectedComponent from '../components/ProtectedComponent';
|
import ProtectedComponent from "../components/ProtectedComponent";
|
||||||
|
|
||||||
const Table = memo(
|
const Table = memo(
|
||||||
forwardRef((props, ref) => {
|
forwardRef((props, ref) => {
|
||||||
|
|
@ -54,31 +54,13 @@ const Table = memo(
|
||||||
navigateTo,
|
navigateTo,
|
||||||
} = props;
|
} = props;
|
||||||
const [data, setData] = useState([]);
|
const [data, setData] = useState([]);
|
||||||
const [formattedColumns, setFormattedColumns] = useState(
|
const [formattedColumns, setFormattedColumns] = useState([]);
|
||||||
columns.map((column, i) => {
|
|
||||||
if (i === 0) {
|
|
||||||
return {
|
|
||||||
...column,
|
|
||||||
muiTableBodyCellProps: {
|
|
||||||
sx: (theme) => ({
|
|
||||||
opacity: 1,
|
|
||||||
fontWeight: 600,
|
|
||||||
fontSize: '16px',
|
|
||||||
fontFamily: theme.fontFamily.semiBold,
|
|
||||||
color: theme.palette.grey[10],
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return column;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
const [isError, setIsError] = useState(false);
|
const [isError, setIsError] = useState(false);
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [isRefetching, setIsRefetching] = useState(false);
|
const [isRefetching, setIsRefetching] = useState(false);
|
||||||
const [rowCount, setRowCount] = useState(0);
|
const [rowCount, setRowCount] = useState(0);
|
||||||
const [columnFilters, setColumnFilters] = useState([]);
|
const [columnFilters, setColumnFilters] = useState([]);
|
||||||
const [globalFilter, setGlobalFilter] = useState('');
|
const [globalFilter, setGlobalFilter] = useState("");
|
||||||
const [sorting, setSorting] = useState([]);
|
const [sorting, setSorting] = useState([]);
|
||||||
const tableRef = useRef();
|
const tableRef = useRef();
|
||||||
const [pagination, setPagination] = useState({
|
const [pagination, setPagination] = useState({
|
||||||
|
|
@ -111,26 +93,46 @@ const Table = memo(
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// Process columns and add any action columns that have a render function
|
||||||
|
const processedColumns = [...columns];
|
||||||
|
|
||||||
|
// Add action columns with render functions
|
||||||
|
if (actions && actions.length > 0) {
|
||||||
|
actions.forEach((action) => {
|
||||||
|
if (action.render && action.field) {
|
||||||
|
processedColumns.push({
|
||||||
|
accessorKey: action.field,
|
||||||
|
header: action.title || "",
|
||||||
|
Cell: ({ row }) => action.render(row.original),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setFormattedColumns(
|
setFormattedColumns(
|
||||||
columns.map((column, i) => {
|
processedColumns.map((column, i) => {
|
||||||
if (column.isBold) {
|
if (column.isBold) {
|
||||||
return {
|
return {
|
||||||
...column,
|
...column,
|
||||||
muiTableBodyCellProps: {
|
Cell: ({ cell }) => (
|
||||||
sx: (theme) => ({
|
<Typography
|
||||||
opacity: 1,
|
sx={(theme) => ({
|
||||||
fontWeight: 600,
|
opacity: 1,
|
||||||
fontSize: '16px',
|
fontWeight: 600,
|
||||||
fontFamily: theme.fontFamily.semiBold,
|
fontSize: "16px",
|
||||||
color: theme.palette.grey[10],
|
fontFamily: theme.fontFamily.semiBold,
|
||||||
}),
|
color: theme.palette.grey[10],
|
||||||
},
|
})}
|
||||||
|
>
|
||||||
|
{cell.getValue()}
|
||||||
|
</Typography>
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return column;
|
return column;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}, [columns]);
|
}, [columns, actions]);
|
||||||
|
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
if (!data.length) {
|
if (!data.length) {
|
||||||
|
|
@ -138,15 +140,15 @@ const Table = memo(
|
||||||
} else {
|
} else {
|
||||||
setIsRefetching(true);
|
setIsRefetching(true);
|
||||||
}
|
}
|
||||||
let filterString = '';
|
let filterString = "";
|
||||||
columnFilters.forEach((filter) => {
|
columnFilters.forEach((filter) => {
|
||||||
filterString += `${filter.id}=${filter.value}&`;
|
filterString += `${filter.id}=${filter.value}&`;
|
||||||
});
|
});
|
||||||
let sortingString = sorting
|
let sortingString = sorting
|
||||||
.map(
|
.map(
|
||||||
(sort) => `orderBy=${sort.id}&order=${sort.desc ? 'DESC' : 'ASC'}&`
|
(sort) => `orderBy=${sort.id}&order=${sort.desc ? "DESC" : "ASC"}&`
|
||||||
)
|
)
|
||||||
.join('');
|
.join("");
|
||||||
try {
|
try {
|
||||||
const response = await getData({
|
const response = await getData({
|
||||||
pagination,
|
pagination,
|
||||||
|
|
@ -222,11 +224,6 @@ const Table = memo(
|
||||||
InputProps={{
|
InputProps={{
|
||||||
startAdornment: (
|
startAdornment: (
|
||||||
<InputAdornment position="end">
|
<InputAdornment position="end">
|
||||||
{/* <img
|
|
||||||
src={SearchFieldIcon}
|
|
||||||
alt="search icon"
|
|
||||||
className={classes.searchIconImg}
|
|
||||||
/> */}
|
|
||||||
<SearchIcon />
|
<SearchIcon />
|
||||||
</InputAdornment>
|
</InputAdornment>
|
||||||
),
|
),
|
||||||
|
|
@ -256,29 +253,26 @@ const Table = memo(
|
||||||
<CustomPagination table={props.table} />
|
<CustomPagination table={props.table} />
|
||||||
)}
|
)}
|
||||||
muiTableBodyCellProps={{
|
muiTableBodyCellProps={{
|
||||||
// className: classes?.muiTableBodyCell,
|
|
||||||
sx: (theme) => ({
|
sx: (theme) => ({
|
||||||
opacity: '1',
|
opacity: "1",
|
||||||
// lineHeight: '2.5rem',
|
|
||||||
margin: theme.spacing(1),
|
margin: theme.spacing(1),
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
fontSize: '16px',
|
fontSize: "16px",
|
||||||
fontStretch: 'normal',
|
fontStretch: "normal",
|
||||||
fontStyle: 'normal',
|
fontStyle: "normal",
|
||||||
letterSpacing: 'normal',
|
letterSpacing: "normal",
|
||||||
fontFamily: theme.fontFamily.medium,
|
fontFamily: theme.fontFamily.medium,
|
||||||
color: theme.palette.grey[22],
|
color: theme.palette.grey[22],
|
||||||
// textAlign: 'center',
|
textAlign: "left",
|
||||||
textAlign: 'left',
|
|
||||||
}),
|
}),
|
||||||
}}
|
}}
|
||||||
muiTopToolbarProps={{
|
muiTopToolbarProps={{
|
||||||
sx: (theme) => ({
|
sx: (theme) => ({
|
||||||
borderRadius: theme.shape.borderRadius,
|
borderRadius: theme.shape.borderRadius,
|
||||||
'& div': {
|
"& div": {
|
||||||
'& div': {
|
"& div": {
|
||||||
'& .MuiIconButton-sizeMedium': {
|
"& .MuiIconButton-sizeMedium": {
|
||||||
display: 'none',
|
display: "none",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -288,6 +282,16 @@ const Table = memo(
|
||||||
renderTopToolbar={false}
|
renderTopToolbar={false}
|
||||||
muiTableHeadCellProps={{
|
muiTableHeadCellProps={{
|
||||||
className: classes?.muiTableHeadCell,
|
className: classes?.muiTableHeadCell,
|
||||||
|
sx: {
|
||||||
|
// Fix for extra space in header cells
|
||||||
|
padding: "16px 8px",
|
||||||
|
whiteSpace: "nowrap",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
'& .MuiTableSortLabel-root': {
|
||||||
|
width: '100%',
|
||||||
|
justifyContent: 'flex-start',
|
||||||
|
}
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
enableRowNumbers={enableRowNumbers}
|
enableRowNumbers={enableRowNumbers}
|
||||||
rowNumberMode={rowNumberMode}
|
rowNumberMode={rowNumberMode}
|
||||||
|
|
@ -296,15 +300,15 @@ const Table = memo(
|
||||||
sx: (theme) => ({
|
sx: (theme) => ({
|
||||||
borderRadius: theme.shape.borderRadius,
|
borderRadius: theme.shape.borderRadius,
|
||||||
backgroundColor: theme.palette.common.white,
|
backgroundColor: theme.palette.common.white,
|
||||||
boxShadow: 'none',
|
boxShadow: "none",
|
||||||
'& .MuiTableContainer-root': {
|
"& .MuiTableContainer-root": {
|
||||||
border: '0px solid',
|
border: "0px solid",
|
||||||
borderRadius: '16px',
|
borderRadius: "16px",
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
}}
|
}}
|
||||||
muiTableHeadCellFilterTextFieldProps={{
|
muiTableHeadCellFilterTextFieldProps={{
|
||||||
variant: 'outlined',
|
variant: "outlined",
|
||||||
}}
|
}}
|
||||||
muiTableBodyProps={{
|
muiTableBodyProps={{
|
||||||
sx: (theme) => ({
|
sx: (theme) => ({
|
||||||
|
|
@ -328,12 +332,12 @@ const Table = memo(
|
||||||
muiToolbarAlertBannerProps={
|
muiToolbarAlertBannerProps={
|
||||||
isError
|
isError
|
||||||
? {
|
? {
|
||||||
color: 'error',
|
color: "error",
|
||||||
children: 'Error loading data',
|
children: "Error loading data",
|
||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
positionToolbarAlertBanner={'none'}
|
positionToolbarAlertBanner={"none"}
|
||||||
onColumnFiltersChange={setColumnFilters}
|
onColumnFiltersChange={setColumnFilters}
|
||||||
onGlobalFilterChange={setGlobalFilter}
|
onGlobalFilterChange={setGlobalFilter}
|
||||||
onPaginationChange={setPagination}
|
onPaginationChange={setPagination}
|
||||||
|
|
@ -351,16 +355,16 @@ const Table = memo(
|
||||||
className: classes?.tableHeadRow,
|
className: classes?.tableHeadRow,
|
||||||
}}
|
}}
|
||||||
displayColumnDefOptions={{
|
displayColumnDefOptions={{
|
||||||
'mrt-row-actions': {
|
"mrt-row-actions": {
|
||||||
header: '',
|
header: "",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
muiTableBodyRowProps={({ row }) => ({
|
muiTableBodyRowProps={({ row }) => ({
|
||||||
onClick: (event) => {
|
onClick: (event) => {
|
||||||
if (
|
if (
|
||||||
Object.values(event.target)?.[1]
|
Object.values(event.target)?.[1]
|
||||||
?.className?.split(' ')
|
?.className?.split(" ")
|
||||||
.includes('MuiBackdrop-root')
|
.includes("MuiBackdrop-root")
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -378,74 +382,67 @@ const Table = memo(
|
||||||
muiSelectAllCheckboxProps={{
|
muiSelectAllCheckboxProps={{
|
||||||
className: classes?.tableCheckbox,
|
className: classes?.tableCheckbox,
|
||||||
}}
|
}}
|
||||||
renderRowActionMenuItems={({ row, closeMenu }) =>
|
// renderRowActionMenuItems={({ row, closeMenu }) =>
|
||||||
actions?.map((action, index) =>
|
// actions?.filter(action => !action.render)?.map((action, index) =>
|
||||||
!(action?.renderAction?.(row) ?? true) ? null : (
|
// !(action?.renderAction?.(row) ?? true) ? null : (
|
||||||
<ProtectedComponent
|
// <MenuItem
|
||||||
key={index}
|
// key={index}
|
||||||
permission={action.permissionName}
|
// className={classes.menuItem}
|
||||||
>
|
// onClick={(event) => {
|
||||||
{(action?.icon ||
|
// event.stopPropagation();
|
||||||
action?.text ||
|
// action.onClick && action.onClick(row);
|
||||||
(action?.textFn && action?.textFn(row))) && (
|
// closeMenu();
|
||||||
<MenuItem
|
// }}
|
||||||
className={classes.menuItem}
|
// disabled={
|
||||||
onClick={(event) => {
|
// action?.isDisabledValue
|
||||||
event.stopPropagation();
|
// ? action?.isDisabledValue ===
|
||||||
action.onClick(row);
|
// row?.original?.[action?.rowKey]
|
||||||
closeMenu();
|
// : false
|
||||||
}}
|
// }
|
||||||
disabled={
|
// >
|
||||||
action?.isDisabledValue
|
// {action?.icon} {action?.text}{" "}
|
||||||
? action?.isDisabledValue ===
|
// {action.textFn && action.textFn(row)}
|
||||||
row?.original?.[action?.rowKey]
|
// </MenuItem>
|
||||||
: false
|
// )
|
||||||
}
|
// ) ?? []
|
||||||
>
|
// }
|
||||||
{action?.icon} {action?.text}{' '}
|
|
||||||
{action.textFn && action.textFn(row)}
|
|
||||||
</MenuItem>
|
|
||||||
)}
|
|
||||||
</ProtectedComponent>
|
|
||||||
)
|
|
||||||
) ?? []
|
|
||||||
}
|
|
||||||
renderTopToolbarCustomActions={({ table }) => {
|
renderTopToolbarCustomActions={({ table }) => {
|
||||||
const handleActive = () => {
|
const handleActive = () => {
|
||||||
const data = table
|
const data = table
|
||||||
.getSelectedRowModel()
|
.getSelectedRowModel()
|
||||||
.flatRows.map((row) => row?.original);
|
.flatRows.map((row) => row?.original);
|
||||||
return handleBulkAction('ACTIVE', data);
|
return handleBulkAction("ACTIVE", data);
|
||||||
};
|
};
|
||||||
const handleDelete = () => {
|
const handleDelete = () => {
|
||||||
const data = table
|
const data = table
|
||||||
.getSelectedRowModel()
|
.getSelectedRowModel()
|
||||||
.flatRows.map((row) => row?.original);
|
.flatRows.map((row) => row?.original);
|
||||||
return handleBulkAction('DELETE', data, table);
|
return handleBulkAction("DELETE", data, table);
|
||||||
};
|
};
|
||||||
const handleDownload = () => {
|
const handleDownload = () => {
|
||||||
const data = table
|
const data = table
|
||||||
.getSelectedRowModel()
|
.getSelectedRowModel()
|
||||||
.flatRows.map((row) => row?.original);
|
.flatRows.map((row) => row?.original);
|
||||||
return handleBulkAction('DOWNLOAD', data);
|
return handleBulkAction("DOWNLOAD", data);
|
||||||
};
|
};
|
||||||
return table.getIsSomeRowsSelected() ||
|
return table.getIsSomeRowsSelected() ||
|
||||||
table.getIsAllRowsSelected() ? (
|
table.getIsAllRowsSelected() ? (
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
alignItems: 'center',
|
alignItems: "center",
|
||||||
justifyContent: 'center',
|
justifyContent: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip title="Change Status">
|
<Tooltip title="Change Status">
|
||||||
<Box
|
<Box
|
||||||
component="img"
|
component="img"
|
||||||
src={inactive}
|
// Replace with actual image path or icon component
|
||||||
|
// src={inactive}
|
||||||
style={{
|
style={{
|
||||||
marginLeft: '5px',
|
marginLeft: "5px",
|
||||||
cursor: 'pointer',
|
cursor: "pointer",
|
||||||
marginTop: '8px',
|
marginTop: "8px",
|
||||||
}}
|
}}
|
||||||
onClick={handleActive}
|
onClick={handleActive}
|
||||||
/>
|
/>
|
||||||
|
|
@ -453,11 +450,11 @@ const Table = memo(
|
||||||
<Tooltip title="Delete">
|
<Tooltip title="Delete">
|
||||||
<Box
|
<Box
|
||||||
component="img"
|
component="img"
|
||||||
src={deleteIcon}
|
// src={deleteIcon}
|
||||||
style={{
|
style={{
|
||||||
marginLeft: '24px',
|
marginLeft: "24px",
|
||||||
cursor: 'pointer',
|
cursor: "pointer",
|
||||||
marginTop: '8px',
|
marginTop: "8px",
|
||||||
}}
|
}}
|
||||||
onClick={handleDelete}
|
onClick={handleDelete}
|
||||||
/>
|
/>
|
||||||
|
|
@ -466,12 +463,12 @@ const Table = memo(
|
||||||
<Tooltip title="Download Report">
|
<Tooltip title="Download Report">
|
||||||
<Box
|
<Box
|
||||||
component="img"
|
component="img"
|
||||||
src={downloadActivity}
|
// src={downloadActivity}
|
||||||
style={{
|
style={{
|
||||||
marginLeft: '24px',
|
marginLeft: "24px",
|
||||||
cursor: 'pointer',
|
cursor: "pointer",
|
||||||
marginTop: '9px',
|
marginTop: "9px",
|
||||||
height: '20px',
|
height: "20px",
|
||||||
}}
|
}}
|
||||||
onClick={handleDownload}
|
onClick={handleDownload}
|
||||||
/>
|
/>
|
||||||
|
|
@ -483,7 +480,7 @@ const Table = memo(
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
muiTablePaginationProps={{
|
muiTablePaginationProps={{
|
||||||
labelRowsPerPage: 'Records Per Page',
|
labelRowsPerPage: "Records Per Page",
|
||||||
}}
|
}}
|
||||||
tableInstanceRef={tableRef}
|
tableInstanceRef={tableRef}
|
||||||
state={{
|
state={{
|
||||||
|
|
@ -548,9 +545,9 @@ const CustomPagination = ({ table }) => {
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
flexDirection: { xs: 'column', md: 'row' },
|
flexDirection: { xs: "column", md: "row" },
|
||||||
alignItems: 'center',
|
alignItems: "center",
|
||||||
padding: 2,
|
padding: 2,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
@ -562,7 +559,7 @@ const CustomPagination = ({ table }) => {
|
||||||
boundaryCount={3}
|
boundaryCount={3}
|
||||||
onChange={(event, page) => setPageIndex(page - 1)}
|
onChange={(event, page) => setPageIndex(page - 1)}
|
||||||
renderItem={(item) => {
|
renderItem={(item) => {
|
||||||
if (item.type === 'previous') {
|
if (item.type === "previous") {
|
||||||
return (
|
return (
|
||||||
<PaginationItem
|
<PaginationItem
|
||||||
component={() => (
|
component={() => (
|
||||||
|
|
@ -572,13 +569,13 @@ const CustomPagination = ({ table }) => {
|
||||||
disabled={currentPage === 1}
|
disabled={currentPage === 1}
|
||||||
onClick={() => previousPage()}
|
onClick={() => previousPage()}
|
||||||
>
|
>
|
||||||
<PreviousIcon style={{ marginRight: '6px' }} />
|
<PreviousIcon style={{ marginRight: "6px" }} />
|
||||||
Previous
|
Previous
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else if (item.type === 'next') {
|
} else if (item.type === "next") {
|
||||||
return (
|
return (
|
||||||
<PaginationItem
|
<PaginationItem
|
||||||
component={() => (
|
component={() => (
|
||||||
|
|
@ -589,7 +586,7 @@ const CustomPagination = ({ table }) => {
|
||||||
onClick={() => nextPage()}
|
onClick={() => nextPage()}
|
||||||
>
|
>
|
||||||
Next
|
Next
|
||||||
<NextIcon style={{ marginLeft: '6px' }} />
|
<NextIcon style={{ marginLeft: "6px" }} />
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
disabled={currentPage === totalPage}
|
disabled={currentPage === totalPage}
|
||||||
|
|
@ -600,19 +597,19 @@ const CustomPagination = ({ table }) => {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
sx={{
|
sx={{
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
justifyContent: 'center',
|
justifyContent: "center",
|
||||||
flex: '1',
|
flex: "1",
|
||||||
'& .MuiPagination-ul': {
|
"& .MuiPagination-ul": {
|
||||||
width: '100%',
|
width: "100%",
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
cursor: 'pointer',
|
cursor: "pointer",
|
||||||
},
|
},
|
||||||
'& .MuiPagination-ul > :first-child': {
|
"& .MuiPagination-ul > :first-child": {
|
||||||
marginRight: 'auto',
|
marginRight: "auto",
|
||||||
},
|
},
|
||||||
' & .MuiPagination-ul > :last-child': {
|
" & .MuiPagination-ul > :last-child": {
|
||||||
marginLeft: 'auto',
|
marginLeft: "auto",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@ import PeopleOutlineIcon from '@mui/icons-material/PeopleOutline';
|
||||||
import PeopleIcon from '@mui/icons-material/People';
|
import PeopleIcon from '@mui/icons-material/People';
|
||||||
import SettingsOutlinedIcon from '@mui/icons-material/SettingsOutlined';
|
import SettingsOutlinedIcon from '@mui/icons-material/SettingsOutlined';
|
||||||
import SettingsIcon from '@mui/icons-material/Settings';
|
import SettingsIcon from '@mui/icons-material/Settings';
|
||||||
import MedicationIcon from '@mui/icons-material/Medication';
|
|
||||||
import MedicationOutlinedIcon from '@mui/icons-material/MedicationOutlined';
|
|
||||||
import ArticleIcon from '@mui/icons-material/Article';
|
import ArticleIcon from '@mui/icons-material/Article';
|
||||||
import ArticleOutlinedIcon from '@mui/icons-material/ArticleOutlined';
|
import ArticleOutlinedIcon from '@mui/icons-material/ArticleOutlined';
|
||||||
|
import TopicIcon from '@mui/icons-material/Topic';
|
||||||
|
import TopicOutlinedIcon from '@mui/icons-material/TopicOutlined';
|
||||||
|
|
||||||
import { USER_ROLES } from '../../../redux/userRoleSlice';
|
import { USER_ROLES } from '../../../redux/userRoleSlice';
|
||||||
|
|
||||||
|
|
@ -40,6 +40,14 @@ export const SIDEBAR_CONFIG = [
|
||||||
// Only super admin can access admin staff management
|
// Only super admin can access admin staff management
|
||||||
roles: [USER_ROLES.SUPER_ADMIN]
|
roles: [USER_ROLES.SUPER_ADMIN]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: 'Master Data Management',
|
||||||
|
path: 'masterData',
|
||||||
|
icon: SettingsOutlinedIcon,
|
||||||
|
activeIcon: SettingsIcon,
|
||||||
|
// Only super admin can access admin staff management
|
||||||
|
roles: [USER_ROLES.SUPER_ADMIN]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
text: 'Doctor/Nurse Management',
|
text: 'Doctor/Nurse Management',
|
||||||
path: 'doctor',
|
path: 'doctor',
|
||||||
|
|
@ -67,4 +75,13 @@ export const SIDEBAR_CONFIG = [
|
||||||
// Clinic admin can access call transcripts
|
// Clinic admin can access call transcripts
|
||||||
roles: [USER_ROLES.CLINIC_ADMIN]
|
roles: [USER_ROLES.CLINIC_ADMIN]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: 'Contract Management',
|
||||||
|
path: 'contractManagement',
|
||||||
|
requireSaprateApp: false,
|
||||||
|
icon: TopicOutlinedIcon,
|
||||||
|
activeIcon: TopicIcon,
|
||||||
|
// Clinic admin can access contract management
|
||||||
|
roles: [USER_ROLES.CLINIC_ADMIN]
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
export const userDataMock = {
|
||||||
|
data: {
|
||||||
|
records: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "test",
|
||||||
|
email: "test@gmail.com",
|
||||||
|
userType: "Manager",
|
||||||
|
specialities: "Doctor",
|
||||||
|
createdAt: "2025-01-01",
|
||||||
|
status: "Active",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "John Doe",
|
||||||
|
email: "johndoe@example.com",
|
||||||
|
userType: "Employee",
|
||||||
|
specialities: "Engineer",
|
||||||
|
createdAt: "2024-11-15",
|
||||||
|
status: "Inactive",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: "Jane Smith",
|
||||||
|
email: "janesmith@example.com",
|
||||||
|
userType: "Admin",
|
||||||
|
specialities: "Manager",
|
||||||
|
createdAt: "2024-12-01",
|
||||||
|
status: "Active",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
name: "Alice Brown",
|
||||||
|
email: "alicebrown@example.com",
|
||||||
|
userType: "Manager",
|
||||||
|
specialities: "HR",
|
||||||
|
createdAt: "2023-06-22",
|
||||||
|
status: "Active",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
name: "Bob Green",
|
||||||
|
email: "bobgreen@example.com",
|
||||||
|
userType: "Employee",
|
||||||
|
specialities: "Software Developer",
|
||||||
|
createdAt: "2024-09-10",
|
||||||
|
status: "Active",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
name: "Charlie Black",
|
||||||
|
email: "charlieblack@example.com",
|
||||||
|
userType: "Admin",
|
||||||
|
specialities: "IT Support",
|
||||||
|
createdAt: "2023-07-05",
|
||||||
|
status: "Inactive",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 7,
|
||||||
|
name: "Eve White",
|
||||||
|
email: "evewhite@example.com",
|
||||||
|
userType: "Manager",
|
||||||
|
specialities: "Finance",
|
||||||
|
createdAt: "2025-03-30",
|
||||||
|
status: "Active",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
totalCount: 7,
|
||||||
|
},
|
||||||
|
message: "Companies retrieved successfully",
|
||||||
|
error: "",
|
||||||
|
};
|
||||||
|
|
@ -10,6 +10,8 @@ import MockPayment from "../views/MockPayment";
|
||||||
import Users from "../views/User";
|
import Users from "../views/User";
|
||||||
import ClinicSetup from "../views/ClinicSetup";
|
import ClinicSetup from "../views/ClinicSetup";
|
||||||
import ClinicTranscripts from "../views/ClinicTranscripts";
|
import ClinicTranscripts from "../views/ClinicTranscripts";
|
||||||
|
import ContractManagement from "../views/ContractManagement";
|
||||||
|
import MasterDataManagement from "../views/MasterData";
|
||||||
|
|
||||||
export const routesData = [
|
export const routesData = [
|
||||||
{
|
{
|
||||||
|
|
@ -23,6 +25,8 @@ export const routesData = [
|
||||||
{ path: "/doctor", component: Users },
|
{ path: "/doctor", component: Users },
|
||||||
{ path: "/clinicSetup", component: ClinicSetup },
|
{ path: "/clinicSetup", component: ClinicSetup },
|
||||||
{ path: "/transcripts", component: ClinicTranscripts },
|
{ path: "/transcripts", component: ClinicTranscripts },
|
||||||
|
{ path: "/contractManagement", component: ContractManagement },
|
||||||
|
{ path: "/masterData", component: MasterDataManagement },
|
||||||
],
|
],
|
||||||
isProtected: true,
|
isProtected: true,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,30 @@
|
||||||
import { axiosInstance } from '../config/api';
|
import { axiosInstance } from "../config/api";
|
||||||
|
import { userDataMock } from "../mock/users";
|
||||||
|
|
||||||
|
// export const getUsers = (params) => {
|
||||||
|
// let searchParams = new URLSearchParams();
|
||||||
|
// searchParams.append('size', params?.pagination?.pageSize ?? 10);
|
||||||
|
// searchParams.append('page', params?.pagination.pageIndex ?? 0);
|
||||||
|
// if (params?.globalFilter) searchParams.append('search', params?.globalFilter);
|
||||||
|
// if (params?.sortingString) {
|
||||||
|
// const sortingParams = new URLSearchParams(params.sortingString);
|
||||||
|
// sortingParams.forEach((value, key) => {
|
||||||
|
// searchParams.append(key, value);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let url = `/users?${searchParams.toString()}`;
|
||||||
|
// return new Promise((resolve, reject) => {
|
||||||
|
// axiosInstance
|
||||||
|
// .get(url)
|
||||||
|
// .then((response) => resolve(response?.data))
|
||||||
|
// .catch((err) => reject(err));
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
|
||||||
export const getUsers = (params) => {
|
export const getUsers = (params) => {
|
||||||
let searchParams = new URLSearchParams();
|
const data = userDataMock;
|
||||||
searchParams.append('size', params?.pagination?.pageSize ?? 10);
|
return data
|
||||||
searchParams.append('page', params?.pagination.pageIndex ?? 0);
|
|
||||||
if (params?.globalFilter) searchParams.append('search', params?.globalFilter);
|
|
||||||
if (params?.sortingString) {
|
|
||||||
const sortingParams = new URLSearchParams(params.sortingString);
|
|
||||||
sortingParams.forEach((value, key) => {
|
|
||||||
searchParams.append(key, value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let url = `/users?${searchParams.toString()}`;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.get(url)
|
|
||||||
.then((response) => resolve(response?.data))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getUserById = (id) => {
|
export const getUserById = (id) => {
|
||||||
|
|
@ -37,43 +43,43 @@ export const getRoles = ({ page }) =>
|
||||||
data: [
|
data: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
name: 'Adult Immunisation',
|
name: "Adult Immunisation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
name: 'Allied health',
|
name: "Allied health",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
name: 'Assist',
|
name: "Assist",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 4,
|
id: 4,
|
||||||
name: 'Care plan',
|
name: "Care plan",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 5,
|
id: 5,
|
||||||
name: 'Care plan reviews',
|
name: "Care plan reviews",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 6,
|
id: 6,
|
||||||
name: 'Cervical Screening',
|
name: "Cervical Screening",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 7,
|
id: 7,
|
||||||
name: 'Child Immunisation',
|
name: "Child Immunisation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 8,
|
id: 8,
|
||||||
name: 'Health assessments',
|
name: "Health assessments",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 9,
|
id: 9,
|
||||||
name: 'Mental Health Care Plans (MHCP)',
|
name: "Mental Health Care Plans (MHCP)",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 10,
|
id: 10,
|
||||||
name: 'Travel Immunisation',
|
name: "Travel Immunisation",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
// },
|
// },
|
||||||
|
|
@ -88,7 +94,7 @@ export const getRoles = ({ page }) =>
|
||||||
// });
|
// });
|
||||||
|
|
||||||
export const addUser = (data) => {
|
export const addUser = (data) => {
|
||||||
const url = '/users';
|
const url = "/users";
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
axiosInstance
|
axiosInstance
|
||||||
.post(url, data)
|
.post(url, data)
|
||||||
|
|
@ -149,7 +155,7 @@ export const logout = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const changePassword = (data) => {
|
export const changePassword = (data) => {
|
||||||
const url = '/users/me/password';
|
const url = "/users/me/password";
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
axiosInstance
|
axiosInstance
|
||||||
.put(url, data)
|
.put(url, data)
|
||||||
|
|
@ -158,7 +164,7 @@ export const changePassword = (data) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const updateMailersSettings = (data) => {
|
export const updateMailersSettings = (data) => {
|
||||||
const url = '/users/me/mail-notification';
|
const url = "/users/me/mail-notification";
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
axiosInstance
|
axiosInstance
|
||||||
.put(url, data)
|
.put(url, data)
|
||||||
|
|
@ -168,7 +174,7 @@ export const updateMailersSettings = (data) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateUser = (imageUrl, isProfileDelete = false) => {
|
export const updateUser = (imageUrl, isProfileDelete = false) => {
|
||||||
let url = '/users/me';
|
let url = "/users/me";
|
||||||
const data = { profilePhoto: imageUrl, isProfileDelete };
|
const data = { profilePhoto: imageUrl, isProfileDelete };
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
@ -179,7 +185,7 @@ export const updateUser = (imageUrl, isProfileDelete = false) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const companyMe = () => {
|
export const companyMe = () => {
|
||||||
let url = '/companies/me';
|
let url = "/companies/me";
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
axiosInstance
|
axiosInstance
|
||||||
|
|
@ -189,7 +195,7 @@ export const companyMe = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const updateCompanyDetails = (data) => {
|
export const updateCompanyDetails = (data) => {
|
||||||
let url = '/companies/me';
|
let url = "/companies/me";
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
axiosInstance
|
axiosInstance
|
||||||
|
|
@ -200,7 +206,7 @@ export const updateCompanyDetails = (data) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const bsAdminLogin = (token) => {
|
export const bsAdminLogin = (token) => {
|
||||||
const url = '/auth/admin/login';
|
const url = "/auth/admin/login";
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
axiosInstance
|
axiosInstance
|
||||||
.post(url, {
|
.post(url, {
|
||||||
|
|
@ -212,7 +218,7 @@ export const bsAdminLogin = (token) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const resendPasswordMailer = (data) => {
|
export const resendPasswordMailer = (data) => {
|
||||||
const url = '/users/remind-password-setup';
|
const url = "/users/remind-password-setup";
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
axiosInstance
|
axiosInstance
|
||||||
.patch(url, {
|
.patch(url, {
|
||||||
|
|
@ -224,7 +230,7 @@ export const resendPasswordMailer = (data) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateUserEmailAndContact = (data) => {
|
export const updateUserEmailAndContact = (data) => {
|
||||||
let url = '/users/me';
|
let url = "/users/me";
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
axiosInstance
|
axiosInstance
|
||||||
|
|
@ -235,7 +241,7 @@ export const updateUserEmailAndContact = (data) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const transferMasterAdminAccess = (id) => {
|
export const transferMasterAdminAccess = (id) => {
|
||||||
if (!id) throw new Error('User id is required');
|
if (!id) throw new Error("User id is required");
|
||||||
const url = `/users/${id}/transfer-master-admin-access`;
|
const url = `/users/${id}/transfer-master-admin-access`;
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
|
||||||
|
|
@ -1,246 +0,0 @@
|
||||||
import { axiosInstance } from '../config/api';
|
|
||||||
|
|
||||||
export const getUsers = (params) => {
|
|
||||||
let searchParams = new URLSearchParams();
|
|
||||||
searchParams.append('size', params?.pagination?.pageSize ?? 10);
|
|
||||||
searchParams.append('page', params?.pagination.pageIndex ?? 0);
|
|
||||||
if (params?.globalFilter) searchParams.append('search', params?.globalFilter);
|
|
||||||
if (params?.sortingString) {
|
|
||||||
const sortingParams = new URLSearchParams(params.sortingString);
|
|
||||||
sortingParams.forEach((value, key) => {
|
|
||||||
searchParams.append(key, value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let url = `/users?${searchParams.toString()}`;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.get(url)
|
|
||||||
.then((response) => resolve(response?.data))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getUserById = (id) => {
|
|
||||||
const url = `/users/${id}`;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.get(url)
|
|
||||||
.then((response) => resolve(response))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
export const getRoles = ({ page }) =>
|
|
||||||
page == 0
|
|
||||||
? {
|
|
||||||
// data: {
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
name: 'Adult Immunisation',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: 'Allied health',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
name: 'Assist',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
name: 'Care plan',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 5,
|
|
||||||
name: 'Care plan reviews',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 6,
|
|
||||||
name: 'Cervical Screening',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 7,
|
|
||||||
name: 'Child Immunisation',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 8,
|
|
||||||
name: 'Health assessments',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 9,
|
|
||||||
name: 'Mental Health Care Plans (MHCP)',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 10,
|
|
||||||
name: 'Travel Immunisation',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
// },
|
|
||||||
}
|
|
||||||
: { data: [] };
|
|
||||||
// const url = '/roles';
|
|
||||||
// return new Promise((resolve, reject) => {
|
|
||||||
// axiosInstance
|
|
||||||
// .get(url)
|
|
||||||
// .then((response) => resolve(response))
|
|
||||||
// .catch((err) => reject(err));
|
|
||||||
// });
|
|
||||||
|
|
||||||
export const addUser = (data) => {
|
|
||||||
const url = '/users';
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.post(url, data)
|
|
||||||
.then((response) => resolve(response))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const updateUserById = (id, data) => {
|
|
||||||
const url = `/users/${id}`;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.put(url, data)
|
|
||||||
.then((response) => resolve(response))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const revokeAdminTransferAccess = () => {
|
|
||||||
const url = `/users/admin-access-transfer-revoke`;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.put(url)
|
|
||||||
.then((response) => resolve(response))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const approveAdminTransferAccess = (id, token) => {
|
|
||||||
const url = `/users/admin-access-transfer-approve`;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.put(url, { id, token })
|
|
||||||
.then((response) => resolve(response))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const deleteUserById = (id) => {
|
|
||||||
const url = `/users/${id}`;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.delete(url)
|
|
||||||
.then((response) => resolve(response))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const logout = () => {
|
|
||||||
const url = '/auth/companies/logout';
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.get(url)
|
|
||||||
.then((response) => resolve(response))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const changePassword = (data) => {
|
|
||||||
const url = '/users/me/password';
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.put(url, data)
|
|
||||||
.then((response) => resolve(response))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
export const updateMailersSettings = (data) => {
|
|
||||||
const url = '/users/me/mail-notification';
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.put(url, data)
|
|
||||||
.then((response) => resolve(response))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const updateUser = (imageUrl, isProfileDelete = false) => {
|
|
||||||
let url = '/users/me';
|
|
||||||
const data = { profilePhoto: imageUrl, isProfileDelete };
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.put(url, data)
|
|
||||||
.then((response) => resolve(response))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
export const companyMe = () => {
|
|
||||||
let url = '/companies/me';
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.get(url)
|
|
||||||
.then((response) => resolve(response))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
export const updateCompanyDetails = (data) => {
|
|
||||||
let url = '/companies/me';
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.put(url, data)
|
|
||||||
.then((response) => resolve(response))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const bsAdminLogin = (token) => {
|
|
||||||
const url = '/auth/admin/login';
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.post(url, {
|
|
||||||
token,
|
|
||||||
})
|
|
||||||
.then((response) => resolve(response))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const resendPasswordMailer = (data) => {
|
|
||||||
const url = '/users/remind-password-setup';
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.patch(url, {
|
|
||||||
email: data,
|
|
||||||
})
|
|
||||||
.then((response) => resolve(response))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const updateUserEmailAndContact = (data) => {
|
|
||||||
let url = '/users/me';
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.put(url, data)
|
|
||||||
.then((response) => resolve(response))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const transferMasterAdminAccess = (id) => {
|
|
||||||
if (!id) throw new Error('User id is required');
|
|
||||||
const url = `/users/${id}/transfer-master-admin-access`;
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
axiosInstance
|
|
||||||
.put(url)
|
|
||||||
.then((response) => resolve(response))
|
|
||||||
.catch((err) => reject(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
@ -465,8 +465,8 @@ const ClinicsList = () => {
|
||||||
extraComponent={
|
extraComponent={
|
||||||
<Box className={classes.tabsBox}>
|
<Box className={classes.tabsBox}>
|
||||||
<Tabs value={type} onChange={handleTabsChange}>
|
<Tabs value={type} onChange={handleTabsChange}>
|
||||||
<Tab value={CLINIC_TYPE.UNREGISTERED} label="Unregistered" />
|
<Tab value={CLINIC_TYPE.UNREGISTERED} label="Unregistered (2)" />
|
||||||
<Tab value={CLINIC_TYPE.REGISTERED} label="Registered" />
|
<Tab value={CLINIC_TYPE.REGISTERED} label="Registered (2)" />
|
||||||
{/* <Tab value={COMPANY_TYPE.SUBSCRIBED} label="Subscribers" /> */}
|
{/* <Tab value={COMPANY_TYPE.SUBSCRIBED} label="Subscribers" /> */}
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
const ContractManagement = () => {
|
||||||
|
return (
|
||||||
|
<div>ContractManagement</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ContractManagement
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
const MasterDataManagement = () => {
|
||||||
|
return (
|
||||||
|
<div>MasterDataManagement</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MasterDataManagement
|
||||||
|
|
@ -19,6 +19,7 @@ import {
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import creditcard from '../../assets/images/logo/credit_card.png';
|
import creditcard from '../../assets/images/logo/credit_card.png';
|
||||||
|
import AccountBalanceIcon from '@mui/icons-material/AccountBalance';
|
||||||
import { NOTIFICATION } from '../../constants';
|
import { NOTIFICATION } from '../../constants';
|
||||||
import { pushNotification } from '../../utils/notification';
|
import { pushNotification } from '../../utils/notification';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
@ -27,6 +28,9 @@ import { setClinicId } from '../../views/ClinicDetails/store/logInAsClinicAdminA
|
||||||
const PaymentPage = () => {
|
const PaymentPage = () => {
|
||||||
const [paymentMethod, setPaymentMethod] = useState('card');
|
const [paymentMethod, setPaymentMethod] = useState('card');
|
||||||
const [cardNumber, setCardNumber] = useState('');
|
const [cardNumber, setCardNumber] = useState('');
|
||||||
|
const [accountNumber, setAccountNumber] = useState('');
|
||||||
|
const [ifscCode, setIfscCode] = useState('');
|
||||||
|
const [bankName, setBankName] = useState('');
|
||||||
const [cardExpiry, setCardExpiry] = useState('');
|
const [cardExpiry, setCardExpiry] = useState('');
|
||||||
const [cardCVC, setCardCVC] = useState('');
|
const [cardCVC, setCardCVC] = useState('');
|
||||||
const [name, setName] = useState('');
|
const [name, setName] = useState('');
|
||||||
|
|
@ -203,6 +207,112 @@ const PaymentPage = () => {
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</Paper>
|
</Paper>
|
||||||
|
<Paper
|
||||||
|
variant="outlined"
|
||||||
|
sx={{
|
||||||
|
p: 2,
|
||||||
|
mb: 2,
|
||||||
|
mt: 2,
|
||||||
|
borderColor:
|
||||||
|
paymentMethod === 'net_banking' ? 'primary.main' : 'divider',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FormControlLabel
|
||||||
|
value="net_banking"
|
||||||
|
control={<Radio />}
|
||||||
|
label={
|
||||||
|
<Box display="flex" alignItems="center">
|
||||||
|
<AccountBalanceIcon sx={{ mr: 1, height: 24, width: 24 }} />
|
||||||
|
<Typography>Net Banking</Typography>
|
||||||
|
</Box>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{paymentMethod === 'card' && (
|
||||||
|
<Box mt={2}>
|
||||||
|
<TextField
|
||||||
|
label="Card Number"
|
||||||
|
fullWidth
|
||||||
|
margin="dense"
|
||||||
|
value={cardNumber}
|
||||||
|
onChange={(e) =>
|
||||||
|
setCardNumber(formatCardNumber(e.target.value))
|
||||||
|
}
|
||||||
|
placeholder="1234 5678 9012 3456"
|
||||||
|
inputProps={{ maxLength: 19 }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<TextField
|
||||||
|
label="Expiry Date"
|
||||||
|
fullWidth
|
||||||
|
margin="dense"
|
||||||
|
value={cardExpiry}
|
||||||
|
onChange={(e) =>
|
||||||
|
setCardExpiry(formatExpiry(e.target.value))
|
||||||
|
}
|
||||||
|
placeholder="MM/YY"
|
||||||
|
inputProps={{ maxLength: 5 }}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<TextField
|
||||||
|
label="CVC"
|
||||||
|
fullWidth
|
||||||
|
margin="dense"
|
||||||
|
value={cardCVC}
|
||||||
|
onChange={(e) => setCardCVC(e.target.value)}
|
||||||
|
placeholder="123"
|
||||||
|
inputProps={{ maxLength: 3 }}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
label="Name on Card"
|
||||||
|
fullWidth
|
||||||
|
margin="dense"
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
placeholder="John Smith"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{paymentMethod === 'net_banking' && (
|
||||||
|
<Box mt={2}>
|
||||||
|
<TextField
|
||||||
|
label="Bank Name"
|
||||||
|
fullWidth
|
||||||
|
margin="dense"
|
||||||
|
value={bankName}
|
||||||
|
onChange={(e) => setBankName(e.target.value)}
|
||||||
|
placeholder="Enter Bank Name"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
label="Account Number"
|
||||||
|
fullWidth
|
||||||
|
margin="dense"
|
||||||
|
value={accountNumber}
|
||||||
|
onChange={(e) => setAccountNumber(e.target.value)}
|
||||||
|
placeholder="Enter Account Number"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
label="IFSC Code"
|
||||||
|
fullWidth
|
||||||
|
margin="dense"
|
||||||
|
value={ifscCode}
|
||||||
|
onChange={(e) => setIfscCode(e.target.value)}
|
||||||
|
placeholder="Enter IFSC Code"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</Paper>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -213,7 +323,9 @@ const PaymentPage = () => {
|
||||||
disabled={
|
disabled={
|
||||||
loading ||
|
loading ||
|
||||||
(paymentMethod === 'card' &&
|
(paymentMethod === 'card' &&
|
||||||
(!cardNumber || !cardExpiry || !cardCVC || !name))
|
(!cardNumber || !cardExpiry || !cardCVC || !name)) ||
|
||||||
|
(paymentMethod === 'net_banking' &&
|
||||||
|
(!accountNumber || !ifscCode || !bankName))
|
||||||
}
|
}
|
||||||
sx={{ mt: 3 }}
|
sx={{ mt: 3 }}
|
||||||
>
|
>
|
||||||
|
|
@ -267,6 +379,51 @@ const PaymentPage = () => {
|
||||||
</Paper>
|
</Paper>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
{/* Payment Information Section */}
|
||||||
|
<Typography variant="h6" gutterBottom sx={{ mt: 3 }}>
|
||||||
|
Payment Information
|
||||||
|
</Typography>
|
||||||
|
<Box mb={2}>
|
||||||
|
<Paper
|
||||||
|
elevation={0}
|
||||||
|
sx={{ p: 2, backgroundColor: '#f9f9f9', borderRadius: 2 }}
|
||||||
|
>
|
||||||
|
<Typography variant="subtitle2" fontWeight="bold" gutterBottom>
|
||||||
|
Subscription Details
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Stack direction="row" justifyContent="space-between" mb={1}>
|
||||||
|
<Typography variant="body2">Setup Fee</Typography>
|
||||||
|
<Typography variant="body2">$500.00</Typography>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Stack direction="row" justifyContent="space-between" mb={1}>
|
||||||
|
<Typography variant="body2">Subscription Fee (Monthly)</Typography>
|
||||||
|
<Typography variant="body2">$800.00</Typography>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Stack direction="row" justifyContent="space-between" mb={1}>
|
||||||
|
<Typography variant="body2">Per Call Charges</Typography>
|
||||||
|
<Typography variant="body2">$5.00/call</Typography>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Box mt={2}>
|
||||||
|
<Chip
|
||||||
|
label="Special Offer: First 3 months free"
|
||||||
|
size="small"
|
||||||
|
color="secondary"
|
||||||
|
sx={{ mt: 1, mr: 1 }}
|
||||||
|
/>
|
||||||
|
<Chip
|
||||||
|
label="Setup fee waived"
|
||||||
|
size="small"
|
||||||
|
color="success"
|
||||||
|
sx={{ mt: 1 }}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Paper>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<Divider sx={{ my: 2 }} />
|
<Divider sx={{ my: 2 }} />
|
||||||
|
|
||||||
<Stack direction="row" justifyContent="space-between" mb={1}>
|
<Stack direction="row" justifyContent="space-between" mb={1}>
|
||||||
|
|
@ -307,9 +464,17 @@ const PaymentPage = () => {
|
||||||
elevation={0}
|
elevation={0}
|
||||||
sx={{ p: 2, mt: 2, border: '1px solid #e0e0e0', borderRadius: 2 }}
|
sx={{ p: 2, mt: 2, border: '1px solid #e0e0e0', borderRadius: 2 }}
|
||||||
>
|
>
|
||||||
|
<Typography variant="subtitle2" fontWeight="bold" gutterBottom>
|
||||||
|
Transaction Information
|
||||||
|
</Typography>
|
||||||
<Typography variant="body2" color="text.secondary" paragraph>
|
<Typography variant="body2" color="text.secondary" paragraph>
|
||||||
<strong>Secure Payment:</strong> All transactions are encrypted
|
<strong>Direct Debit:</strong> Payments will be automatically processed on the 1st of each month.
|
||||||
and secure.
|
</Typography>
|
||||||
|
<Typography variant="body2" color="text.secondary" paragraph>
|
||||||
|
<strong>Billing Cycle:</strong> Monthly/Annual based on your selected plan.
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" color="text.secondary" paragraph>
|
||||||
|
<strong>Secure Payment:</strong> All transactions are encrypted and secure via Stripe Payment Gateway.
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body2" color="text.secondary">
|
<Typography variant="body2" color="text.secondary">
|
||||||
<strong>Customer Support:</strong> If you have any questions,
|
<strong>Customer Support:</strong> If you have any questions,
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import {
|
||||||
Button,
|
Button,
|
||||||
ButtonBase,
|
ButtonBase,
|
||||||
Drawer,
|
Drawer,
|
||||||
|
FormControl,
|
||||||
FormHelperText,
|
FormHelperText,
|
||||||
Grid,
|
Grid,
|
||||||
IconButton,
|
IconButton,
|
||||||
|
|
@ -103,6 +104,11 @@ function YourDetailsForm() {
|
||||||
{ id: "director", name: "Director" },
|
{ id: "director", name: "Director" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const mobilePrefixOptions = [
|
||||||
|
{ id: "61", name: "+61" },
|
||||||
|
{ id: "91", name: "+91" },
|
||||||
|
];
|
||||||
|
|
||||||
const integrationOptions = ["BP Software", "Medical Director"];
|
const integrationOptions = ["BP Software", "Medical Director"];
|
||||||
|
|
||||||
// Default form data
|
// Default form data
|
||||||
|
|
@ -112,6 +118,7 @@ function YourDetailsForm() {
|
||||||
email: "",
|
email: "",
|
||||||
password: "",
|
password: "",
|
||||||
mobileNumber: "",
|
mobileNumber: "",
|
||||||
|
mobilePrefix: "",
|
||||||
confirmPassword: "",
|
confirmPassword: "",
|
||||||
currentEmail: "",
|
currentEmail: "",
|
||||||
otp: "",
|
otp: "",
|
||||||
|
|
@ -119,7 +126,11 @@ function YourDetailsForm() {
|
||||||
// Clinic details
|
// Clinic details
|
||||||
companyName: "",
|
companyName: "",
|
||||||
designation: "",
|
designation: "",
|
||||||
companyWebsite: "",
|
businessPhone: "",
|
||||||
|
emergencyBusinessPhone: "",
|
||||||
|
emergencyBusinessPhonePrefix: "",
|
||||||
|
businessPhonePrefix: "",
|
||||||
|
businessFax: "",
|
||||||
companyLogo: "",
|
companyLogo: "",
|
||||||
companyIndustry: "",
|
companyIndustry: "",
|
||||||
pincode: "",
|
pincode: "",
|
||||||
|
|
@ -130,6 +141,9 @@ function YourDetailsForm() {
|
||||||
companyPANImage: "",
|
companyPANImage: "",
|
||||||
companyPANImage: "",
|
companyPANImage: "",
|
||||||
termsAccepted: "",
|
termsAccepted: "",
|
||||||
|
practiceManagementSystem: "",
|
||||||
|
practiceId: "",
|
||||||
|
practiceName: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Field references for focus and validation
|
// Field references for focus and validation
|
||||||
|
|
@ -138,6 +152,7 @@ function YourDetailsForm() {
|
||||||
name: useRef(null),
|
name: useRef(null),
|
||||||
email: useRef(null),
|
email: useRef(null),
|
||||||
mobileNumber: useRef(null),
|
mobileNumber: useRef(null),
|
||||||
|
mobilePrefix: useRef(null),
|
||||||
password: useRef(null),
|
password: useRef(null),
|
||||||
confirmPassword: useRef(null),
|
confirmPassword: useRef(null),
|
||||||
otp: useRef(null),
|
otp: useRef(null),
|
||||||
|
|
@ -145,10 +160,14 @@ function YourDetailsForm() {
|
||||||
// Clinic details fields
|
// Clinic details fields
|
||||||
companyName: useRef(null),
|
companyName: useRef(null),
|
||||||
businessPhone: useRef(null),
|
businessPhone: useRef(null),
|
||||||
|
businessPhonePrefix: useRef(null),
|
||||||
|
emergencyBusinessPhone: useRef(null),
|
||||||
|
emergencyBusinessPhonePrefix: useRef(null),
|
||||||
businessFax: useRef(null),
|
businessFax: useRef(null),
|
||||||
practiceManagementSystem: useRef(null),
|
practiceManagementSystem: useRef(null),
|
||||||
|
practiceId: useRef(null),
|
||||||
|
practiceName: useRef(null),
|
||||||
designation: useRef(null),
|
designation: useRef(null),
|
||||||
companyWebsite: useRef(null),
|
|
||||||
companyIndustry: useRef(null),
|
companyIndustry: useRef(null),
|
||||||
pincode: useRef(null),
|
pincode: useRef(null),
|
||||||
state: useRef(null),
|
state: useRef(null),
|
||||||
|
|
@ -214,7 +233,7 @@ function YourDetailsForm() {
|
||||||
designation: Yup.string()
|
designation: Yup.string()
|
||||||
.required("Designation is required")
|
.required("Designation is required")
|
||||||
.typeError("Designation must be string"),
|
.typeError("Designation must be string"),
|
||||||
companyWebsite: Yup.string()
|
businessPhone: Yup.string()
|
||||||
.required("Clinic website is required")
|
.required("Clinic website is required")
|
||||||
.matches(WEBSITE_REGEX, "Please enter a valid URL"),
|
.matches(WEBSITE_REGEX, "Please enter a valid URL"),
|
||||||
companyIndustry: Yup.string().required("Clinic Industry is required"),
|
companyIndustry: Yup.string().required("Clinic Industry is required"),
|
||||||
|
|
@ -246,6 +265,8 @@ function YourDetailsForm() {
|
||||||
termsAccepted: Yup.boolean()
|
termsAccepted: Yup.boolean()
|
||||||
.oneOf([true], "You must accept the terms and conditions")
|
.oneOf([true], "You must accept the terms and conditions")
|
||||||
.required("You must accept the terms and conditions"),
|
.required("You must accept the terms and conditions"),
|
||||||
|
practiceId: Yup.string().required("Practice ID is required"),
|
||||||
|
practiceName: Yup.string().required("Practice Name is required"),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Debounced function for pincode lookup
|
// Debounced function for pincode lookup
|
||||||
|
|
@ -287,6 +308,12 @@ function YourDetailsForm() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleTestConnection = () => {
|
||||||
|
// logic here
|
||||||
|
setTestConnDone(true);
|
||||||
|
pushNotification("Test connection successful", "success");
|
||||||
|
};
|
||||||
|
|
||||||
const handleOTPButton = () => {
|
const handleOTPButton = () => {
|
||||||
console.log("btn");
|
console.log("btn");
|
||||||
setOtpField(true);
|
setOtpField(true);
|
||||||
|
|
@ -483,7 +510,12 @@ function YourDetailsForm() {
|
||||||
function formatedData(inputData) {
|
function formatedData(inputData) {
|
||||||
const data = {
|
const data = {
|
||||||
name: inputData.companyName || "",
|
name: inputData.companyName || "",
|
||||||
website: inputData.companyWebsite || "",
|
businessPhone: inputData.businessPhone || "",
|
||||||
|
emergencyBusinessPhone: inputData.emergencyBusinessPhone || "",
|
||||||
|
emergencyBusinessPhonePrefix:
|
||||||
|
inputData.emergencyBusinessPhonePrefix || "",
|
||||||
|
businessPhonePrefix: inputData.businessPhonePrefix || "",
|
||||||
|
businessFax: inputData.businessFax || "",
|
||||||
city: inputData.locality || "",
|
city: inputData.locality || "",
|
||||||
state: inputData.state || "",
|
state: inputData.state || "",
|
||||||
logo: inputData.companyLogo || null,
|
logo: inputData.companyLogo || null,
|
||||||
|
|
@ -499,6 +531,9 @@ function YourDetailsForm() {
|
||||||
password: inputData.password || "",
|
password: inputData.password || "",
|
||||||
designation: inputData.designation || "",
|
designation: inputData.designation || "",
|
||||||
},
|
},
|
||||||
|
practiceId: inputData.practiceId || "",
|
||||||
|
practiceManagementSystem: inputData.practiceManagementSystem || "",
|
||||||
|
practiceName: inputData.practiceName || "",
|
||||||
companyUsers: inputData.billingUsers || "",
|
companyUsers: inputData.billingUsers || "",
|
||||||
companyDocuments: [
|
companyDocuments: [
|
||||||
...(inputData.companyLogo
|
...(inputData.companyLogo
|
||||||
|
|
@ -601,6 +636,17 @@ function YourDetailsForm() {
|
||||||
<Box className={classes.paperContainerBox}>
|
<Box className={classes.paperContainerBox}>
|
||||||
<Box>
|
<Box>
|
||||||
<form>
|
<form>
|
||||||
|
{/* Practice ID */}
|
||||||
|
<FormSectionHeading title="practice id" />
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
spacing={theme.spacing(2.3)}
|
||||||
|
padding={`0 ${theme.spacing(3.2)}`}
|
||||||
|
className={classes.formRoot}
|
||||||
|
>
|
||||||
|
<TextField disabled />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
{/* Personal Details Section */}
|
{/* Personal Details Section */}
|
||||||
<FormSectionHeading title="PERSONAL DETAILS" />
|
<FormSectionHeading title="PERSONAL DETAILS" />
|
||||||
<Grid
|
<Grid
|
||||||
|
|
@ -718,12 +764,28 @@ function YourDetailsForm() {
|
||||||
pattern: "[0-9]*",
|
pattern: "[0-9]*",
|
||||||
startAdornment: (
|
startAdornment: (
|
||||||
<InputAdornment position="start">
|
<InputAdornment position="start">
|
||||||
<Box className={classes.countryCodeBox}>
|
<Box sx={{ padding: "1px" }}>
|
||||||
<Typography
|
<Select
|
||||||
className={classes.countryCodeLabel}
|
name="mobilePrefix"
|
||||||
|
value={formik.values.mobilePrefix}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
inputRef={fieldRefs.mobilePrefix}
|
||||||
|
defaultValue={"61"}
|
||||||
>
|
>
|
||||||
+61
|
{mobilePrefixOptions.map((option) => (
|
||||||
</Typography>
|
<MenuItem
|
||||||
|
sx={{
|
||||||
|
outline: "none",
|
||||||
|
border: "none",
|
||||||
|
}}
|
||||||
|
key={option.id}
|
||||||
|
value={option.id}
|
||||||
|
>
|
||||||
|
{option.name}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
</Box>
|
</Box>
|
||||||
</InputAdornment>
|
</InputAdornment>
|
||||||
),
|
),
|
||||||
|
|
@ -962,7 +1024,7 @@ function YourDetailsForm() {
|
||||||
{/* Your designation grid */}
|
{/* Your designation grid */}
|
||||||
<Grid item md={4} sm={6} xs={12}>
|
<Grid item md={4} sm={6} xs={12}>
|
||||||
<InputLabel className={classes.inputLabel}>
|
<InputLabel className={classes.inputLabel}>
|
||||||
Your designation*
|
User Role*
|
||||||
</InputLabel>
|
</InputLabel>
|
||||||
<Select
|
<Select
|
||||||
fullWidth
|
fullWidth
|
||||||
|
|
@ -983,46 +1045,330 @@ function YourDetailsForm() {
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{userRoles.map((option) => (
|
{userRoles.map((option) => (
|
||||||
<MenuItem
|
<MenuItem key={option.id} value={option.id}>
|
||||||
key={option.id}
|
|
||||||
value={option.id}
|
|
||||||
>
|
|
||||||
{option.name}
|
{option.name}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{/* Clinic Website grid */}
|
{/* Business Phone grid */}
|
||||||
<Grid item md={4} sm={6} xs={12}>
|
<Grid item md={4} sm={6} xs={12}>
|
||||||
<InputLabel className={classes.inputLabel}>
|
<InputLabel className={classes.inputLabel}>
|
||||||
Clinic Website*
|
Business PhoneNumber*
|
||||||
</InputLabel>
|
</InputLabel>
|
||||||
<TextField
|
<TextField
|
||||||
|
className={classes.mobileNumberInput}
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Enter Clinic Website"
|
placeholder="Enter Mobile Number"
|
||||||
color="secondary"
|
color="secondary"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
name="companyWebsite"
|
name="businessPhone"
|
||||||
value={formik.values.companyWebsite}
|
value={formik.values.businessPhone}
|
||||||
onChange={formik.handleChange}
|
onChange={(e) => {
|
||||||
|
if (e.target.value.length <= 10) {
|
||||||
|
const value =
|
||||||
|
e.target.value?.match(/\d+/g) || "";
|
||||||
|
formik.setFieldValue(
|
||||||
|
"businessPhone",
|
||||||
|
value?.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
onBlur={formik.handleBlur}
|
onBlur={formik.handleBlur}
|
||||||
inputRef={fieldRefs.companyWebsite}
|
InputProps={{
|
||||||
|
type: "text",
|
||||||
|
pattern: "[0-9]*",
|
||||||
|
startAdornment: (
|
||||||
|
<InputAdornment position="start">
|
||||||
|
<Box sx={{ padding: "1px" }}>
|
||||||
|
<Select
|
||||||
|
name="businessPhonePrefix"
|
||||||
|
value={
|
||||||
|
formik.values.businessPhonePrefix
|
||||||
|
}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
inputRef={fieldRefs.businessPhonePrefix}
|
||||||
|
defaultValue={"61"}
|
||||||
|
>
|
||||||
|
{mobilePrefixOptions.map((option) => (
|
||||||
|
<MenuItem
|
||||||
|
sx={{
|
||||||
|
outline: "none",
|
||||||
|
border: "none",
|
||||||
|
}}
|
||||||
|
key={option.id}
|
||||||
|
value={option.id}
|
||||||
|
>
|
||||||
|
{option.name}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</Box>
|
||||||
|
</InputAdornment>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
inputRef={fieldRefs.businessPhone}
|
||||||
error={Boolean(
|
error={Boolean(
|
||||||
formik.errors.companyWebsite &&
|
formik.errors.businessPhone &&
|
||||||
formik.touched.companyWebsite
|
formik.touched.businessPhone
|
||||||
)}
|
)}
|
||||||
helperText={
|
helperText={
|
||||||
formik.errors.companyWebsite &&
|
formik.errors.businessPhone &&
|
||||||
formik.touched.companyWebsite
|
formik.touched.businessPhone
|
||||||
? formik.errors.companyWebsite
|
? formik.errors.businessPhone
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
{/* business emergency phone */}
|
||||||
|
<Grid item md={4} sm={6} xs={12}>
|
||||||
|
<InputLabel className={classes.inputLabel}>
|
||||||
|
Business Emergency Phone Number*
|
||||||
|
</InputLabel>
|
||||||
|
<TextField
|
||||||
|
className={classes.mobileNumberInput}
|
||||||
|
fullWidth
|
||||||
|
placeholder="Enter Emergency Phone Number"
|
||||||
|
color="secondary"
|
||||||
|
variant="outlined"
|
||||||
|
name="emergencyBusinessPhone"
|
||||||
|
value={formik.values.emergencyBusinessPhone}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
InputProps={{
|
||||||
|
type: "text",
|
||||||
|
pattern: "[0-9]*",
|
||||||
|
startAdornment: (
|
||||||
|
<InputAdornment position="start">
|
||||||
|
<Box sx={{ padding: "1px" }}>
|
||||||
|
<Select
|
||||||
|
name="emergencyBusinessPhonePrefix"
|
||||||
|
value={
|
||||||
|
formik.values
|
||||||
|
.emergencyBusinessPhonePrefix
|
||||||
|
}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
inputRef={
|
||||||
|
fieldRefs.emergencyBusinessPhonePrefix
|
||||||
|
}
|
||||||
|
defaultValue={"61"}
|
||||||
|
>
|
||||||
|
{mobilePrefixOptions.map((option) => (
|
||||||
|
<MenuItem
|
||||||
|
sx={{
|
||||||
|
outline: "none",
|
||||||
|
border: "none",
|
||||||
|
}}
|
||||||
|
key={option.id}
|
||||||
|
value={option.id}
|
||||||
|
>
|
||||||
|
{option.name}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</Box>
|
||||||
|
</InputAdornment>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
inputRef={fieldRefs.emergencyBusinessPhone}
|
||||||
|
error={Boolean(
|
||||||
|
formik.errors.emergencyBusinessPhone &&
|
||||||
|
formik.touched.emergencyBusinessPhone
|
||||||
|
)}
|
||||||
|
helperText={
|
||||||
|
formik.errors.emergencyBusinessPhone &&
|
||||||
|
formik.touched.emergencyBusinessPhone
|
||||||
|
? formik.errors.emergencyBusinessPhone
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Business Fax grid */}
|
||||||
|
<Grid item md={4} sm={6} xs={12}>
|
||||||
|
<InputLabel className={classes.inputLabel}>
|
||||||
|
Business Fax Number*
|
||||||
|
</InputLabel>
|
||||||
|
<TextField
|
||||||
|
// className={classes.mobileNumberInput}
|
||||||
|
fullWidth
|
||||||
|
placeholder="Enter Fax Number"
|
||||||
|
color="secondary"
|
||||||
|
variant="outlined"
|
||||||
|
name="businessFax"
|
||||||
|
value={formik.values.businessFax}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (e.target.value.length <= 10) {
|
||||||
|
const value =
|
||||||
|
e.target.value?.match(/\d+/g) || "";
|
||||||
|
formik.setFieldValue(
|
||||||
|
"businessFax",
|
||||||
|
value?.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
InputProps={{
|
||||||
|
type: "text",
|
||||||
|
pattern: "[0-9]*",
|
||||||
|
}}
|
||||||
|
inputRef={fieldRefs.businessFax}
|
||||||
|
error={Boolean(
|
||||||
|
formik.errors.businessFax &&
|
||||||
|
formik.touched.businessFax
|
||||||
|
)}
|
||||||
|
helperText={
|
||||||
|
formik.errors.businessFax &&
|
||||||
|
formik.touched.businessFax
|
||||||
|
? formik.errors.businessFax
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Business Email grid */}
|
||||||
|
<Grid item md={4} sm={6} xs={12}>
|
||||||
|
<InputLabel className={classes.inputLabel}>
|
||||||
|
Business Email*
|
||||||
|
</InputLabel>
|
||||||
|
<TextField
|
||||||
|
// className={classes.mobileNumberInput}
|
||||||
|
fullWidth
|
||||||
|
placeholder="Enter Business Email"
|
||||||
|
color="secondary"
|
||||||
|
variant="outlined"
|
||||||
|
name="businessEmail"
|
||||||
|
value={formik.values.businessEmail}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (e.target.value.length <= 10) {
|
||||||
|
const value =
|
||||||
|
e.target.value?.match(/\d+/g) || "";
|
||||||
|
formik.setFieldValue(
|
||||||
|
"businessEmail",
|
||||||
|
value?.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
InputProps={{
|
||||||
|
type: "email",
|
||||||
|
}}
|
||||||
|
inputRef={fieldRefs.businessEmail}
|
||||||
|
error={Boolean(
|
||||||
|
formik.errors.businessEmail &&
|
||||||
|
formik.touched.businessEmail
|
||||||
|
)}
|
||||||
|
helperText={
|
||||||
|
formik.errors.businessEmail &&
|
||||||
|
formik.touched.businessEmail
|
||||||
|
? formik.errors.businessEmail
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* practice management system */}
|
||||||
|
<Grid item xs={6} md={4}>
|
||||||
|
<InputLabel
|
||||||
|
className={classes.inputLabel}
|
||||||
|
id="integration-software-label"
|
||||||
|
>
|
||||||
|
Integrate with
|
||||||
|
</InputLabel>
|
||||||
|
<Select
|
||||||
|
fullWidth
|
||||||
|
name="practiceManagementSystem"
|
||||||
|
value={formik.values.practiceManagementSystem}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
inputRef={fieldRefs.practiceManagementSystem}
|
||||||
|
error={Boolean(
|
||||||
|
formik.errors.practiceManagementSystem &&
|
||||||
|
formik.touched.practiceManagementSystem
|
||||||
|
)}
|
||||||
|
helperText={
|
||||||
|
formik.errors.practiceManagementSystem &&
|
||||||
|
formik.touched.practiceManagementSystem
|
||||||
|
? formik.errors.practiceManagementSystem
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{integrationOptions.map((option) => (
|
||||||
|
<MenuItem key={option} value={option}>
|
||||||
|
{option}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* PMS ID grid */}
|
||||||
|
<Grid item xs={12} md={4}>
|
||||||
|
<InputLabel className={classes.inputLabel}>
|
||||||
|
PMS ID
|
||||||
|
</InputLabel>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
label="PMS ID"
|
||||||
|
name="practiceId"
|
||||||
|
value={formik.values.practiceId}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
variant="outlined"
|
||||||
|
disabled={!formik.values.practiceManagementSystem}
|
||||||
|
error={
|
||||||
|
!!formik.values.practiceManagementSystem &&
|
||||||
|
formik.errors.practiceId
|
||||||
|
}
|
||||||
|
helperText={
|
||||||
|
!!formik.values.practiceManagementSystem &&
|
||||||
|
formik.errors.practiceId
|
||||||
|
? "Practice ID is required"
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Practice Name grid */}
|
||||||
|
<Grid item xs={12} md={4}>
|
||||||
|
<InputLabel className={classes.inputLabel}>
|
||||||
|
Practice Name
|
||||||
|
</InputLabel>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
label="Practice Name"
|
||||||
|
name="practiceName"
|
||||||
|
value={formik.values.practiceName}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
variant="outlined"
|
||||||
|
disabled={!formik.values.practiceManagementSystem}
|
||||||
|
error={
|
||||||
|
!!formik.values.practiceManagementSystem &&
|
||||||
|
formik.errors.practiceName
|
||||||
|
}
|
||||||
|
helperText={
|
||||||
|
!!formik.values.practiceManagementSystem &&
|
||||||
|
formik.errors.practiceName
|
||||||
|
? "Practice Name is required"
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Test Connection Button */}
|
||||||
|
<Grid item xs={12} md={8}>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
onClick={handleTestConnection}
|
||||||
|
>
|
||||||
|
Test Connection
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
{/* Clinic logo grid */}
|
{/* Clinic logo grid */}
|
||||||
<Grid item md={4} sm={12}>
|
<Grid item md={5} sm={12}>
|
||||||
<InputLabel className={classes.inputLabel}>
|
<InputLabel className={classes.inputLabel}>
|
||||||
Add Business Logo
|
Add Business Logo
|
||||||
{(logoImage || formik.values.companyLogo) && (
|
{(logoImage || formik.values.companyLogo) && (
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ const initialState = {
|
||||||
currentEmail: '',
|
currentEmail: '',
|
||||||
companyName: '',
|
companyName: '',
|
||||||
designation: '',
|
designation: '',
|
||||||
companyWebsite: '',
|
businessPhone: '',
|
||||||
companyAbout: '',
|
companyAbout: '',
|
||||||
companyLogo: '',
|
companyLogo: '',
|
||||||
companyIndustry: '',
|
companyIndustry: '',
|
||||||
|
|
|
||||||
|
|
@ -1,60 +1,61 @@
|
||||||
import { LoadingButton } from '@mui/lab';
|
import { LoadingButton } from "@mui/lab";
|
||||||
import { Box, Grid, MenuItem, Select, TextField } from '@mui/material';
|
import { Box, Button, Grid, MenuItem, Select, Switch, TextField } from "@mui/material";
|
||||||
import { useFormik } from 'formik';
|
import { useFormik } from "formik";
|
||||||
import React, { useMemo, useRef, useState } from 'react';
|
import React, { useMemo, useRef, useState } from "react";
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from "react-redux";
|
||||||
import * as Yup from 'yup';
|
import * as Yup from "yup";
|
||||||
|
|
||||||
/* ----------------- Custom Imports ----------------- */
|
/* ----------------- Custom Imports ----------------- */
|
||||||
import PageHeader from '../../components/PageHeader';
|
import PageHeader from "../../components/PageHeader";
|
||||||
import Table from '../../components/Table';
|
import Table from "../../components/Table";
|
||||||
import ConfirmationModal from '../Modal/ConfirmationModal';
|
import ConfirmationModal from "../Modal/ConfirmationModal";
|
||||||
import CustomModal from '../Modal/Modal';
|
import CustomModal from "../Modal/Modal";
|
||||||
import { useStyles } from './userStyles';
|
import { useStyles } from "./userStyles";
|
||||||
|
|
||||||
/* ----------------- Assets ----------------- */
|
/* ----------------- Assets ----------------- */
|
||||||
import SendIcon from '@mui/icons-material/Send';
|
import SendIcon from "@mui/icons-material/Send";
|
||||||
import AddIcon from '@mui/icons-material/Add';
|
import AddIcon from "@mui/icons-material/Add";
|
||||||
import DeleteIcon from '@mui/icons-material/Delete';
|
import DeleteIcon from "@mui/icons-material/Delete";
|
||||||
import EditIcon from '@mui/icons-material/Edit';
|
import EditIcon from "@mui/icons-material/Edit";
|
||||||
import RemoveIcon from '@mui/icons-material/Remove';
|
import RemoveIcon from "@mui/icons-material/Remove";
|
||||||
import {
|
import {
|
||||||
|
getUsers,
|
||||||
deleteUserById,
|
deleteUserById,
|
||||||
getRoles,
|
getRoles,
|
||||||
getUserById,
|
getUserById,
|
||||||
resendPasswordMailer,
|
resendPasswordMailer,
|
||||||
revokeAdminTransferAccess,
|
revokeAdminTransferAccess,
|
||||||
transferMasterAdminAccess,
|
transferMasterAdminAccess,
|
||||||
} from '../../services/users.services';
|
} from "../../services/users.service";
|
||||||
|
|
||||||
/* ----------------- Utils ----------------- */
|
/* ----------------- Utils ----------------- */
|
||||||
import { format } from 'date-fns';
|
import { format } from "date-fns";
|
||||||
import MultiSelect from '../../components/MultiSelect';
|
import MultiSelect from "../../components/MultiSelect";
|
||||||
import { NOTIFICATION, NOT_AVAILABLE_TEXT } from '../../constants';
|
import { NOTIFICATION, NOT_AVAILABLE_TEXT } from "../../constants";
|
||||||
import { pushNotification } from '../../utils/notification';
|
import { pushNotification } from "../../utils/notification";
|
||||||
|
|
||||||
/* ----------------- Validation Schema ----------------- */
|
/* ----------------- Validation Schema ----------------- */
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
userName: Yup.string().required('User Name is required'),
|
userName: Yup.string().required("User Name is required"),
|
||||||
email: Yup.string()
|
email: Yup.string()
|
||||||
.email('Invalid Email Address')
|
.email("Invalid Email Address")
|
||||||
.required('Email is required'),
|
.required("Email is required"),
|
||||||
mobile: Yup.string()
|
mobile: Yup.string()
|
||||||
.matches(/^\d{10}$/, 'Mobile Number must be exactly 10 digits')
|
.matches(/^\d{10}$/, "Mobile Number must be exactly 10 digits")
|
||||||
.required('Mobile Number is required'),
|
.required("Mobile Number is required"),
|
||||||
});
|
});
|
||||||
|
|
||||||
function Users() {
|
function Users() {
|
||||||
const ref = useRef(null);
|
const ref = useRef(null);
|
||||||
const defaultFormData = useRef({
|
const defaultFormData = useRef({
|
||||||
userName: '',
|
userName: "",
|
||||||
email: 'q@gmail.com',
|
email: "q@gmail.com",
|
||||||
mobile: '1234567890',
|
mobile: "1234567890",
|
||||||
isEditUser: false,
|
isEditUser: false,
|
||||||
lastName: '',
|
lastName: "",
|
||||||
userType: '',
|
userType: "",
|
||||||
appointmentType: [],
|
appointmentType: [],
|
||||||
appointmentTypeObject: '',
|
appointmentTypeObject: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
const fieldRefs = {
|
const fieldRefs = {
|
||||||
|
|
@ -74,9 +75,6 @@ function Users() {
|
||||||
const [isEditUser, setIsEditUser] = useState(false);
|
const [isEditUser, setIsEditUser] = useState(false);
|
||||||
const [deleteModal, setDeleteModal] = useState(false);
|
const [deleteModal, setDeleteModal] = useState(false);
|
||||||
const [masterAdminModal, setMasterAdminModal] = useState(false);
|
const [masterAdminModal, setMasterAdminModal] = useState(false);
|
||||||
const [revokeAdminAccessRequestModal, setRevokeAdminAccessRequestModal] =
|
|
||||||
useState(false);
|
|
||||||
const [seletedUserData, setSelectedUserData] = useState();
|
|
||||||
const [buttonLoading, setButtonLoading] = useState(false);
|
const [buttonLoading, setButtonLoading] = useState(false);
|
||||||
const [userId, setUserId] = useState();
|
const [userId, setUserId] = useState();
|
||||||
const [userTotalCount, setUserTotalCount] = useState(0);
|
const [userTotalCount, setUserTotalCount] = useState(0);
|
||||||
|
|
@ -84,28 +82,41 @@ function Users() {
|
||||||
const [checkboxError, setCheckboxError] = useState(false);
|
const [checkboxError, setCheckboxError] = useState(false);
|
||||||
const [roles, setRoles] = useState();
|
const [roles, setRoles] = useState();
|
||||||
const [isAdmin, setIsAdmin] = useState();
|
const [isAdmin, setIsAdmin] = useState();
|
||||||
const [hasProfileCompleted, setHasProfileCompleted] = useState(false);
|
|
||||||
const [
|
|
||||||
requestRaisedForTransferMasterAdminAccess,
|
|
||||||
setRequestRaisedForTransferMasterAdminAccess,
|
|
||||||
] = useState(false);
|
|
||||||
|
|
||||||
const isBsAdmin = useSelector((state) => state?.login?.user?.isBsAdmin);
|
const isBsAdmin = useSelector((state) => state?.login?.user?.isBsAdmin);
|
||||||
|
|
||||||
/* ----------------- Get Users ----------------- */
|
/* ----------------- Get Users ----------------- */
|
||||||
const getData = async (filters) => {
|
const getData = async (filters) => {
|
||||||
const resp = await getUsers(filters);
|
const resp = await getUsers(filters);
|
||||||
|
console.log(resp);
|
||||||
|
console.log(resp?.data?.totalCount);
|
||||||
setUserTotalCount(resp?.data?.totalCount);
|
setUserTotalCount(resp?.data?.totalCount);
|
||||||
setRequestRaisedForTransferMasterAdminAccess(
|
|
||||||
resp.data?.requestRaisedForTransferMasterAdminAccess
|
|
||||||
);
|
|
||||||
|
|
||||||
const role = await getRoles();
|
const role = await getRoles({ page: 0 });
|
||||||
setRoles(role?.data?.data);
|
setRoles(role?.data);
|
||||||
|
|
||||||
return { data: resp?.data?.records, rowCount: resp?.data?.totalCount };
|
return { data: resp?.data?.records, rowCount: resp?.data?.totalCount };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleToggleButton = async (row) => {
|
||||||
|
try {
|
||||||
|
// Replace this with your actual API call to update user status
|
||||||
|
// Example: await updateUserStatus(row.id, !row.isActive);
|
||||||
|
|
||||||
|
// For now, just show a notification
|
||||||
|
pushNotification(
|
||||||
|
`${row.name}'s status has been ${row.isActive ? 'deactivated' : 'activated'}`,
|
||||||
|
NOTIFICATION.SUCCESS
|
||||||
|
);
|
||||||
|
|
||||||
|
// Refresh the table data
|
||||||
|
ref.current.reFetchData();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
pushNotification('Failed to update status', NOTIFICATION.ERROR);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/* ----------------- Handle Submit ----------------- */
|
/* ----------------- Handle Submit ----------------- */
|
||||||
const handleSubmit = async (values, formik) => {
|
const handleSubmit = async (values, formik) => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -143,7 +154,7 @@ function Users() {
|
||||||
|
|
||||||
// if (response.status === 200) {
|
// if (response.status === 200) {
|
||||||
// pushNotification(response?.data?.message, NOTIFICATION.SUCCESS);
|
// pushNotification(response?.data?.message, NOTIFICATION.SUCCESS);
|
||||||
pushNotification('Doctor added successfully', NOTIFICATION.SUCCESS);
|
pushNotification("Doctor added successfully", NOTIFICATION.SUCCESS);
|
||||||
// ref.current.reFetchData();
|
// ref.current.reFetchData();
|
||||||
toggle();
|
toggle();
|
||||||
formik.resetForm();
|
formik.resetForm();
|
||||||
|
|
@ -162,60 +173,6 @@ function Users() {
|
||||||
setShowModal(!showModal);
|
setShowModal(!showModal);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ----------------- Edit User ----------------- */
|
|
||||||
const editUser = async (row) => {
|
|
||||||
try {
|
|
||||||
const { data: { data: userData } = {} } = await getUserById(
|
|
||||||
row?.original?.id
|
|
||||||
);
|
|
||||||
const formData = {
|
|
||||||
userName: userData?.name,
|
|
||||||
email: userData?.email,
|
|
||||||
mobile: userData?.mobile,
|
|
||||||
password: userData?.password,
|
|
||||||
transferMasterAdminAccess: false,
|
|
||||||
isEditUser: true,
|
|
||||||
};
|
|
||||||
setIsAdmin(userData?.isAdmin);
|
|
||||||
setHasProfileCompleted(userData?.hasProfileCompleted);
|
|
||||||
const updatedCheckboxes = roles.reduce(
|
|
||||||
(acc, role) => ({
|
|
||||||
...acc,
|
|
||||||
[role?.id]: userData?.roles.some(
|
|
||||||
(roleData) => roleData?.id === role?.id
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
|
|
||||||
setSelectedCheckboxes(updatedCheckboxes);
|
|
||||||
formik.setValues(formData);
|
|
||||||
toggle();
|
|
||||||
setIsEditUser(true);
|
|
||||||
setUserId(row?.original?.id);
|
|
||||||
} catch ({ resp }) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error(resp?.data?.message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const resendPasswordSetupMailer = (row) => {
|
|
||||||
try {
|
|
||||||
const response = resendPasswordMailer(row?.original?.email);
|
|
||||||
if (response.status === 200) {
|
|
||||||
pushNotification(response?.data?.message, NOTIFICATION.SUCCESS);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ----------------- Revoke Admin Access Request ----------------- */
|
|
||||||
const revokeAdminAccessRequest = async () => {
|
|
||||||
setRevokeAdminAccessRequestModal(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ----------------- Handle Checkbox Change ----------------- */
|
/* ----------------- Handle Checkbox Change ----------------- */
|
||||||
const handleCheckboxChange = (id, isChecked) => {
|
const handleCheckboxChange = (id, isChecked) => {
|
||||||
setSelectedCheckboxes({ ...selectedCheckboxes, [id]: isChecked });
|
setSelectedCheckboxes({ ...selectedCheckboxes, [id]: isChecked });
|
||||||
|
|
@ -226,7 +183,7 @@ function Users() {
|
||||||
() => [
|
() => [
|
||||||
{
|
{
|
||||||
size: 30,
|
size: 30,
|
||||||
header: 'S.no.',
|
header: "S.no.",
|
||||||
Cell: (props) => {
|
Cell: (props) => {
|
||||||
const tableState = props?.table?.getState();
|
const tableState = props?.table?.getState();
|
||||||
const serialNumber = (
|
const serialNumber = (
|
||||||
|
|
@ -235,59 +192,57 @@ function Users() {
|
||||||
tableState?.pagination?.pageIndex * tableState?.pagination?.pageSize
|
tableState?.pagination?.pageIndex * tableState?.pagination?.pageSize
|
||||||
)
|
)
|
||||||
?.toString()
|
?.toString()
|
||||||
?.padStart(1, '0');
|
?.padStart(1, "0");
|
||||||
return <span>{serialNumber}.</span>;
|
return <span>{serialNumber}.</span>;
|
||||||
},
|
},
|
||||||
enableSorting: false,
|
enableSorting: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorFn: ({ name }) => name || NOT_AVAILABLE_TEXT,
|
accessorFn: ({ name }) => name || NOT_AVAILABLE_TEXT,
|
||||||
accessorKey: 'name',
|
accessorKey: "name",
|
||||||
header: 'Doctor/Nurse Name',
|
header: "Doctor/Nurse Name",
|
||||||
isBold: true,
|
isBold: true,
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// accessorKey: 'roles',
|
|
||||||
// header: 'User Access',
|
|
||||||
// enableSorting: false,
|
|
||||||
// Cell: ({ row }) => (
|
|
||||||
// <div>
|
|
||||||
// {row.original.roles && row.original.roles.length > 0
|
|
||||||
// ? row.original.roles.map((role, index) => (
|
|
||||||
// <span key={index}>
|
|
||||||
// {role.name}
|
|
||||||
// {index !== row.original.roles.length - 1 ? ', ' : ''}
|
|
||||||
// </span>
|
|
||||||
// ))
|
|
||||||
// : NOT_AVAILABLE_TEXT}
|
|
||||||
// {row.original.isAdmin && ', Master Admin'}
|
|
||||||
// </div>
|
|
||||||
// ),
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
accessorFn: ({ mobile }) => mobile || NOT_AVAILABLE_TEXT,
|
accessorFn: ({ mobile }) => mobile || NOT_AVAILABLE_TEXT,
|
||||||
accessorKey: 'mobile',
|
accessorKey: "userType",
|
||||||
header: 'User Type',
|
header: "User Type",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorFn: ({ email }) => email || NOT_AVAILABLE_TEXT,
|
accessorFn: ({ email }) => email || NOT_AVAILABLE_TEXT,
|
||||||
accessorKey: 'email',
|
accessorKey: "specialities",
|
||||||
header: 'Specialties',
|
header: "Specialties",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'createdAt',
|
accessorKey: "createdAt",
|
||||||
Cell: ({ row }) => (
|
Cell: ({ row }) => (
|
||||||
<div className={classes.dateStyle}>
|
<div className={classes.dateStyle}>
|
||||||
{format(new Date(row?.original?.createdAt), 'dd MMM, yyyy')}
|
{format(new Date(row?.original?.createdAt), "dd MMM, yyyy")}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
header: 'Added On',
|
header: "Added On",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorFn: ({ email }) => email || NOT_AVAILABLE_TEXT,
|
accessorFn: ({ email }) => email || NOT_AVAILABLE_TEXT,
|
||||||
accessorKey: 'email',
|
accessorKey: "status",
|
||||||
header: 'Status',
|
header: "Status",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
size: 30,
|
||||||
|
accessorKey: "actions",
|
||||||
|
header: "Actions",
|
||||||
|
enableSorting: false,
|
||||||
|
Cell: ({ row }) => (
|
||||||
|
<div>
|
||||||
|
<Switch
|
||||||
|
checked={row?.original?.isActive}
|
||||||
|
onChange={() => handleToggleButton(row?.original)}
|
||||||
|
inputProps={{ "aria-label": "Status toggle" }}
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
}
|
||||||
],
|
],
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
@ -314,10 +269,6 @@ function Users() {
|
||||||
setSelectedUserData(row?.original);
|
setSelectedUserData(row?.original);
|
||||||
};
|
};
|
||||||
|
|
||||||
const revokeAdminAccessToggle = () => {
|
|
||||||
setRevokeAdminAccessRequestModal(!revokeAdminAccessRequestModal);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ----------------- Transfer Master Admin Access to User ----------------- */
|
/* ----------------- Transfer Master Admin Access to User ----------------- */
|
||||||
const handleTransferMasterAdminAccess = async () => {
|
const handleTransferMasterAdminAccess = async () => {
|
||||||
setButtonLoading(true);
|
setButtonLoading(true);
|
||||||
|
|
@ -355,24 +306,6 @@ function Users() {
|
||||||
setButtonLoading(false);
|
setButtonLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/* ----------------- Revoke Admin Access ----------------- */
|
|
||||||
const handleRevokeAdminAccessRequest = async () => {
|
|
||||||
setButtonLoading(true);
|
|
||||||
try {
|
|
||||||
const response = await revokeAdminTransferAccess();
|
|
||||||
if (response.status === 200) {
|
|
||||||
pushNotification(response?.data?.message, NOTIFICATION.SUCCESS);
|
|
||||||
ref.current.resetPage(true);
|
|
||||||
setRevokeAdminAccessRequestModal(false);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error(error?.response?.data?.message);
|
|
||||||
} finally {
|
|
||||||
ref.current.reFetchData();
|
|
||||||
setButtonLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleuserAccessCancel = () => {
|
const handleuserAccessCancel = () => {
|
||||||
setCheckboxError(false);
|
setCheckboxError(false);
|
||||||
|
|
@ -380,7 +313,7 @@ function Users() {
|
||||||
};
|
};
|
||||||
|
|
||||||
const getRowStyle = (row) =>
|
const getRowStyle = (row) =>
|
||||||
row?.original?.isAdmin ? { backgroundColor: '#E7F4EE !important' } : {};
|
row?.original?.isAdmin ? { backgroundColor: "#E7F4EE !important" } : {};
|
||||||
|
|
||||||
const handleSubmitClick = async () => {
|
const handleSubmitClick = async () => {
|
||||||
const formikErrors = await formik.validateForm();
|
const formikErrors = await formik.validateForm();
|
||||||
|
|
@ -393,10 +326,10 @@ function Users() {
|
||||||
|
|
||||||
if (firstErrorRef) {
|
if (firstErrorRef) {
|
||||||
// Scroll to the first invalid field smoothly
|
// Scroll to the first invalid field smoothly
|
||||||
if (typeof firstErrorRef?.scrollIntoView === 'function') {
|
if (typeof firstErrorRef?.scrollIntoView === "function") {
|
||||||
firstErrorRef?.scrollIntoView({
|
firstErrorRef?.scrollIntoView({
|
||||||
behavior: 'smooth',
|
behavior: "smooth",
|
||||||
block: 'center',
|
block: "center",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -429,49 +362,26 @@ function Users() {
|
||||||
columns={columns}
|
columns={columns}
|
||||||
getData={getData}
|
getData={getData}
|
||||||
options={{ enableRowSelection: false }}
|
options={{ enableRowSelection: false }}
|
||||||
showAction={true}
|
// showAction={true}
|
||||||
hideShowPerPage={true}
|
hideShowPerPage={true}
|
||||||
showSearchBox={true}
|
showSearchBox={true}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
searchText={'user'}
|
searchText={"user"}
|
||||||
getRowStyle={getRowStyle}
|
getRowStyle={getRowStyle}
|
||||||
actions={[
|
// actions={[
|
||||||
{
|
// {
|
||||||
onClick: makeMasterAdminToggle,
|
// title: "Action",
|
||||||
text: 'Make User Master Admin',
|
// field: "isActive",
|
||||||
icon: <RemoveIcon className={classes.tableActionIcons} />,
|
// render: (rowData) => (
|
||||||
renderAction: (row) => isBsAdmin && !row?.original?.isAdmin,
|
// <Switch
|
||||||
},
|
// checked={rowData.isActive}
|
||||||
{
|
// onChange={() => handleToggleButton(rowData)}
|
||||||
onClick: revokeAdminAccessRequest,
|
// inputProps={{ "aria-label": "Status toggle" }}
|
||||||
text: 'Revoke Admin Access Request',
|
// color="primary"
|
||||||
icon: <RemoveIcon className={classes.tableActionIcons} />,
|
// />
|
||||||
// permissionName: "CREATE_USERS",
|
// ),
|
||||||
renderAction: (row) => row?.original?.transferMasterAdminAccess,
|
// },
|
||||||
},
|
// ]}
|
||||||
{
|
|
||||||
onClick: editUser,
|
|
||||||
text: 'Edit',
|
|
||||||
icon: <EditIcon className={classes.tableActionIcons} />,
|
|
||||||
// permissionName: "CREATE_USERS",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
onClick: (row) => resendPasswordSetupMailer(row),
|
|
||||||
text: 'Resend password setup mailer',
|
|
||||||
icon: <SendIcon className={classes.tableActionIcons} />,
|
|
||||||
renderAction: (row) => !row?.original?.hasProfileCompleted,
|
|
||||||
// permissionName: "CREATE_USERS",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
onClick: deleteUserToggle,
|
|
||||||
text: 'Delete',
|
|
||||||
icon: <DeleteIcon className={classes.tableActionIcons} />,
|
|
||||||
renderAction: (row) => !row?.original?.isAdmin,
|
|
||||||
// permissionName: 'DELETE_USERS',
|
|
||||||
// isDisabledValue: user?.id,
|
|
||||||
rowKey: 'id',
|
|
||||||
},
|
|
||||||
].filter(Boolean)}
|
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
|
@ -485,7 +395,7 @@ function Users() {
|
||||||
footerRightButtonTitle="Submit"
|
footerRightButtonTitle="Submit"
|
||||||
onFooterLeftButtonClick={() => handleCancel()}
|
onFooterLeftButtonClick={() => handleCancel()}
|
||||||
onFooterRightButtonClick={() => handleSubmit()}
|
onFooterRightButtonClick={() => handleSubmit()}
|
||||||
title={isEditUser ? 'Edit Doctor/Nurse' : 'Add New Doctor/Nurse'}
|
title={isEditUser ? "Edit Doctor/Nurse" : "Add New Doctor/Nurse"}
|
||||||
isTitleLeft={true}
|
isTitleLeft={true}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
formik.resetForm();
|
formik.resetForm();
|
||||||
|
|
@ -496,8 +406,8 @@ function Users() {
|
||||||
modalBodyFunction={() => (
|
modalBodyFunction={() => (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
'& .MuiDialogContent-root': {
|
"& .MuiDialogContent-root": {
|
||||||
padding: '0px',
|
padding: "0px",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
@ -511,14 +421,14 @@ function Users() {
|
||||||
fullWidth
|
fullWidth
|
||||||
inputProps={{
|
inputProps={{
|
||||||
form: {
|
form: {
|
||||||
autocomplete: 'off',
|
autocomplete: "off",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
name="userName"
|
name="userName"
|
||||||
value={formik.values.userName}
|
value={formik.values.userName}
|
||||||
onChange={formik.handleChange}
|
onChange={formik.handleChange}
|
||||||
onBlur={(e) => {
|
onBlur={(e) => {
|
||||||
formik.setFieldValue('userName', e.target.value.trim());
|
formik.setFieldValue("userName", e.target.value.trim());
|
||||||
formik.handleBlur(e);
|
formik.handleBlur(e);
|
||||||
}}
|
}}
|
||||||
inputRef={fieldRefs.userName}
|
inputRef={fieldRefs.userName}
|
||||||
|
|
@ -531,7 +441,7 @@ function Users() {
|
||||||
<i>{formik.errors.userName}</i>
|
<i>{formik.errors.userName}</i>
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
''
|
""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
@ -544,14 +454,14 @@ function Users() {
|
||||||
fullWidth
|
fullWidth
|
||||||
inputProps={{
|
inputProps={{
|
||||||
form: {
|
form: {
|
||||||
autocomplete: 'off',
|
autocomplete: "off",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
name="lastName"
|
name="lastName"
|
||||||
value={formik.values.lastName}
|
value={formik.values.lastName}
|
||||||
onChange={formik.handleChange}
|
onChange={formik.handleChange}
|
||||||
onBlur={(e) => {
|
onBlur={(e) => {
|
||||||
formik.setFieldValue('lastName', e.target.value.trim());
|
formik.setFieldValue("lastName", e.target.value.trim());
|
||||||
formik.handleBlur(e);
|
formik.handleBlur(e);
|
||||||
}}
|
}}
|
||||||
inputRef={fieldRefs.lastName}
|
inputRef={fieldRefs.lastName}
|
||||||
|
|
@ -564,7 +474,7 @@ function Users() {
|
||||||
<i>{formik.errors.lastName}</i>
|
<i>{formik.errors.lastName}</i>
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
''
|
""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
@ -572,7 +482,7 @@ function Users() {
|
||||||
select
|
select
|
||||||
className={classes.perPageDropdown}
|
className={classes.perPageDropdown}
|
||||||
fullWidth
|
fullWidth
|
||||||
style={{ marginTop: '15px' }}
|
style={{ marginTop: "15px" }}
|
||||||
defaultValue={true}
|
defaultValue={true}
|
||||||
>
|
>
|
||||||
<MenuItem value={true}>Doctor</MenuItem>
|
<MenuItem value={true}>Doctor</MenuItem>
|
||||||
|
|
@ -581,7 +491,7 @@ function Users() {
|
||||||
|
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
apiCall={getRoles}
|
apiCall={getRoles}
|
||||||
searchParams={{ additionalParam: 'value' }}
|
searchParams={{ additionalParam: "value" }}
|
||||||
formik={formik}
|
formik={formik}
|
||||||
fieldValue="appointmentType"
|
fieldValue="appointmentType"
|
||||||
fieldObjectValue="appointmentTypeObject"
|
fieldObjectValue="appointmentTypeObject"
|
||||||
|
|
@ -741,19 +651,6 @@ function Users() {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* ----------- Revoke Admin Access Request ----------- */}
|
|
||||||
{revokeAdminAccessRequestModal && (
|
|
||||||
<ConfirmationModal
|
|
||||||
heading="Revoke Admin Access Request"
|
|
||||||
bodyContent="The request for access privileges to Master Admin will be revoked for this user."
|
|
||||||
confirmationLine="Are you sure you want to revoke access?"
|
|
||||||
leftButtonText="Cancel"
|
|
||||||
rightButtonText="Revoke Access"
|
|
||||||
onCancel={revokeAdminAccessToggle}
|
|
||||||
onConfirm={handleRevokeAdminAccessRequest}
|
|
||||||
buttonLoading={buttonLoading}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue