feat: protected routes for clinic docs update
fix: doc upload after rejection
This commit is contained in:
parent
3d91cee029
commit
35f21f2749
|
|
@ -116,10 +116,7 @@ const CustomFileUpload = forwardRef(function CustomFileUpload(
|
|||
try {
|
||||
setIsLoading(true);
|
||||
const response = await getPresignedUrl(filePayload);
|
||||
|
||||
// Debug the response structure
|
||||
console.log('API Response:', response);
|
||||
|
||||
|
||||
// Check if we have a valid response with the expected structure
|
||||
if (response?.data?.data?.Key) {
|
||||
// Use the Key from the response
|
||||
|
|
@ -128,7 +125,6 @@ const CustomFileUpload = forwardRef(function CustomFileUpload(
|
|||
} else {
|
||||
// If the expected structure is not found, try to find the key in a different location
|
||||
// or use a fallback value
|
||||
console.log('Response structure is different than expected');
|
||||
|
||||
// Try different possible paths to find the key
|
||||
const key = response?.data?.Key ||
|
||||
|
|
@ -136,7 +132,6 @@ const CustomFileUpload = forwardRef(function CustomFileUpload(
|
|||
response?.Key ||
|
||||
value.name; // Fallback to the file name if key not found
|
||||
|
||||
console.log('Using key:', key);
|
||||
onUploadDone(documentName, key);
|
||||
|
||||
// Try to find the API URL similarly
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import axios from 'axios';
|
||||
import { API_BASE_URL } from '../common/envVariables';
|
||||
import { ERRORS, NOTIFICATION } from '../constants';
|
||||
import { pushNotification } from '../utils/notification';
|
||||
import { commonLogoutFunc } from '../utils/share';
|
||||
import store from '../redux/store';
|
||||
import axios from "axios";
|
||||
import { API_BASE_URL } from "../common/envVariables";
|
||||
import { ERRORS, NOTIFICATION } from "../constants";
|
||||
import { pushNotification } from "../utils/notification";
|
||||
import { commonLogoutFunc } from "../utils/share";
|
||||
import store from "../redux/store";
|
||||
|
||||
export const axiosInstance = axios.create({
|
||||
baseURL: API_BASE_URL,
|
||||
|
|
@ -20,10 +20,15 @@ export const axiosInstance = axios.create({
|
|||
axiosInstance.interceptors.request.use(
|
||||
async function (config) {
|
||||
try {
|
||||
const token = JSON.parse(localStorage.getItem('redux'));
|
||||
const token = JSON.parse(localStorage.getItem("redux"));
|
||||
if (token?.login?.token) {
|
||||
config.headers.Authorization = `Bearer ${token?.login?.token}`;
|
||||
}
|
||||
// if url is dev-ai-appointment.s3.amazonaws.com
|
||||
if (config.url?.includes("dev-ai-appointment.s3.amazonaws.com")) {
|
||||
config.headers.Authorization = null;
|
||||
}
|
||||
|
||||
const state = store.getState();
|
||||
const companyId = state?.loginAsCompanyAdmin?.companyId; // Extract companyId
|
||||
if (companyId) {
|
||||
|
|
@ -58,7 +63,7 @@ axiosInstance.interceptors.response.use(
|
|||
console.log(error);
|
||||
if (!error?.response?.data) {
|
||||
pushNotification(error.message, NOTIFICATION.ERROR);
|
||||
if (error.message !== 'Network Error') commonLogoutFunc();
|
||||
if (error.message !== "Network Error") commonLogoutFunc();
|
||||
} else if (
|
||||
error?.response?.data?.error &&
|
||||
error?.response?.data?.error[0]?.message
|
||||
|
|
@ -91,10 +96,10 @@ axiosInstance.interceptors.response.use(
|
|||
|
||||
export const fileDownloadAxios = axios.create({
|
||||
baseURL: API_BASE_URL,
|
||||
responseType: 'blob',
|
||||
responseType: "blob",
|
||||
crossDomain: true,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
withCredentials: true,
|
||||
timeout: 300000,
|
||||
|
|
@ -103,10 +108,16 @@ export const fileDownloadAxios = axios.create({
|
|||
fileDownloadAxios.interceptors.request.use(
|
||||
async function (config) {
|
||||
try {
|
||||
const token = JSON.parse(localStorage.getItem('redux'));
|
||||
const token = JSON.parse(localStorage.getItem("redux"));
|
||||
if (token?.data?.data) {
|
||||
config.headers.Authorization = `${token?.data?.data}`;
|
||||
}
|
||||
|
||||
// if url is dev-ai-appointment.s3.amazonaws.com
|
||||
if (config.url?.includes("dev-ai-appointment.s3.amazonaws.com")) {
|
||||
config.headers.Authorization = null;
|
||||
}
|
||||
|
||||
const state = store.getState();
|
||||
const companyId = state?.loginAsCompanyAdmin?.companyId; // Extract companyId
|
||||
if (companyId) {
|
||||
|
|
@ -131,7 +142,7 @@ fileDownloadAxios.interceptors.response.use(
|
|||
async function (response) {
|
||||
// Handle error response (when server responds with JSON instead of a file)
|
||||
if (
|
||||
response?.headers['content-type']?.includes('application/json') &&
|
||||
response?.headers["content-type"]?.includes("application/json") &&
|
||||
response?.data
|
||||
) {
|
||||
try {
|
||||
|
|
@ -140,14 +151,14 @@ fileDownloadAxios.interceptors.response.use(
|
|||
|
||||
if (parsedError?.error) {
|
||||
pushNotification(
|
||||
parsedError?.message || 'Download failed',
|
||||
parsedError?.message || "Download failed",
|
||||
NOTIFICATION.ERROR
|
||||
);
|
||||
return Promise.reject(parsedError);
|
||||
}
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Error parsing error response', err);
|
||||
console.error("Error parsing error response", err);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,26 +170,26 @@ fileDownloadAxios.interceptors.response.use(
|
|||
|
||||
if (!error?.response?.data) {
|
||||
pushNotification(error.message, NOTIFICATION.ERROR);
|
||||
if (error.message !== 'Network Error') commonLogoutFunc();
|
||||
if (error.message !== "Network Error") commonLogoutFunc();
|
||||
} else {
|
||||
// Handle error message from API
|
||||
const contentType = error?.response?.headers?.['content-type'];
|
||||
const contentType = error?.response?.headers?.["content-type"];
|
||||
|
||||
if (contentType?.includes('application/json')) {
|
||||
if (contentType?.includes("application/json")) {
|
||||
error.response.data.text().then((text) => {
|
||||
try {
|
||||
const parsedError = JSON.parse(text);
|
||||
pushNotification(
|
||||
parsedError.message || 'Something went wrong',
|
||||
parsedError.message || "Something went wrong",
|
||||
NOTIFICATION.ERROR
|
||||
);
|
||||
} catch (err) {
|
||||
pushNotification('Unknown error occurred', NOTIFICATION.ERROR);
|
||||
pushNotification("Unknown error occurred", NOTIFICATION.ERROR);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
pushNotification(
|
||||
error?.response?.data?.message || 'Download failed',
|
||||
error?.response?.data?.message || "Download failed",
|
||||
NOTIFICATION.ERROR
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,12 @@ import { CLINIC_STATUS, HIDE_MODULES } from "../../../constants";
|
|||
import { isBSPortal } from "../../../utils/share";
|
||||
import { hideAndShowFunctionality } from "../../../views/Signup/signupAction";
|
||||
import { useStyles } from "../mainLayoutStyles";
|
||||
|
||||
// Import the configuration from the separate file
|
||||
import { SIDEBAR_CONFIG } from "./sideBarConfig"; // Adjust path if necessary
|
||||
import {
|
||||
selectClinicStatus,
|
||||
selectUserRole,
|
||||
} from "../../../redux/userRoleSlice";
|
||||
|
||||
// NOTE: Removed the internal SIDEBAR_ITEMS definition.
|
||||
// We will now use the imported SIDEBAR_CONFIG.
|
||||
|
|
@ -41,6 +44,7 @@ const Sidebar = ({ onClose, showCloseIcon }) => {
|
|||
const [childRoute, setchildRoute] = useState("");
|
||||
const [combinedRoute, setcombinedRoute] = useState("");
|
||||
const dispatch = useDispatch();
|
||||
const clinicStatus = useSelector(selectClinicStatus);
|
||||
|
||||
// Assuming companyStatus is fetched or defined elsewhere correctly
|
||||
const companyStatus = "APPROVED"; // Example status, replace with actual logic if needed
|
||||
|
|
@ -83,88 +87,85 @@ const Sidebar = ({ onClose, showCloseIcon }) => {
|
|||
const userRole = useSelector((state) => state.userRole.role);
|
||||
|
||||
// Function to determine visibility and render a single sidebar item link
|
||||
const checkVisibility = (item, i) => {
|
||||
// Check if the user has the necessary role for this item
|
||||
const hasRole = !item.roles || item.roles.includes(userRole);
|
||||
// The checkVisibility function with fixed logic
|
||||
const checkVisibility = (item, i) => {
|
||||
// Check if the user has the necessary role for this item
|
||||
const hasRole = !item.roles || item.roles.includes(userRole);
|
||||
|
||||
// Determine if the feature related to this item should be hidden
|
||||
let hideFeature =
|
||||
(companyStatus === CLINIC_STATUS.APPROVED &&
|
||||
HIDE_FUNCTIONALITY &&
|
||||
HIDE_MODULES.includes(item?.path)) ||
|
||||
(isSuperAdmin && HIDE_FUNCTIONALITY && HIDE_MODULES.includes(item?.path));
|
||||
// Only render if user has the required role
|
||||
if (hasRole) {
|
||||
// Determine if the link should be disabled
|
||||
// FIXED LOGIC: If clinic status is rejected, only allow "/" and "/docs" paths
|
||||
const isDisabled = (clinicStatus === "rejected" || clinicStatus === "under_review" || clinicStatus === "payment_due") && !(item.path == "" || item.path == "docs");
|
||||
|
||||
// Set the correct target path
|
||||
const targetPath = isDisabled ? "#" : `/${item.path}`;
|
||||
const isActive = activeLink === item.path; // Check if this link is the active one
|
||||
|
||||
// Only render if user has the required role
|
||||
if (hasRole) {
|
||||
// Determine if the link should be disabled
|
||||
const isDisabled =
|
||||
(!isSuperAdmin && companyStatus !== CLINIC_STATUS.APPROVED) || hideFeature;
|
||||
const targetPath = isDisabled ? "#" : `/${item.path}`;
|
||||
const isActive = activeLink === item.path; // Check if this link is the active one
|
||||
|
||||
return (
|
||||
<Box
|
||||
className={classes.marginBottom}
|
||||
onClick={() => handleHideFeatures(hideFeature)} // This seems odd, clicking the box hides features? Review this logic.
|
||||
key={item.path || i} // Use a stable key like item.path
|
||||
return (
|
||||
<Box
|
||||
className={classes.marginBottom}
|
||||
onClick={() => handleHideFeatures(isDisabled)} // Pass isDisabled to handleHideFeatures
|
||||
key={item.path || i} // Use a stable key like item.path
|
||||
>
|
||||
<NavLink
|
||||
className={`${isActive ? classes.activeLink : ""} ${
|
||||
classes.textDecorationNone
|
||||
} ${isDisabled ? classes.disabledLink : ""}`}
|
||||
to={targetPath}
|
||||
// Prevent navigation for disabled links
|
||||
onClick={(e) => {
|
||||
if (isDisabled) e.preventDefault();
|
||||
handleLinkClick(item.path); // Set active link on click
|
||||
}}
|
||||
>
|
||||
<NavLink
|
||||
className={`${isActive ? classes.activeLink : ""} ${
|
||||
classes.textDecorationNone
|
||||
} ${isDisabled ? classes.disabledLink : ""}`}
|
||||
to={targetPath}
|
||||
// Prevent navigation for disabled links, although `to="#"` handles this
|
||||
onClick={(e) => {
|
||||
if (isDisabled) e.preventDefault();
|
||||
handleLinkClick(item.path); // Set active link on click
|
||||
}}
|
||||
<ListItem
|
||||
button // Make it clear it's clickable
|
||||
className={`${classes.listItem} ${
|
||||
isActive && classes.activeLink
|
||||
}`}
|
||||
disabled={isDisabled} // Visually disable the ListItem as well
|
||||
>
|
||||
<ListItem
|
||||
button // Make it clear it's clickable
|
||||
className={`${classes.listItem} ${
|
||||
isActive && classes.activeLink
|
||||
}`}
|
||||
disabled={isDisabled} // Visually disable the ListItem as well
|
||||
>
|
||||
<Box className={classes.sidebarListImg}>
|
||||
{isActive
|
||||
? React.createElement(item.activeIcon, {
|
||||
className: classes.sidebarLinkIcons,
|
||||
})
|
||||
: React.createElement(item.icon, {
|
||||
className: classes.sidebarLinkIcons,
|
||||
style: { color: "black" },
|
||||
})}
|
||||
</Box>
|
||||
<ListItemText
|
||||
primary={item.text}
|
||||
primaryTypographyProps={{
|
||||
className: isActive
|
||||
? classes.activeLinkTextColor
|
||||
: classes.normalLinkTextColor,
|
||||
}}
|
||||
/>
|
||||
</ListItem>
|
||||
</NavLink>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
return null; // Return null if item shouldn't be rendered
|
||||
};
|
||||
<Box className={classes.sidebarListImg}>
|
||||
{isActive
|
||||
? React.createElement(item.activeIcon, {
|
||||
className: classes.sidebarLinkIcons,
|
||||
})
|
||||
: React.createElement(item.icon, {
|
||||
className: classes.sidebarLinkIcons,
|
||||
style: { color: "black" },
|
||||
})}
|
||||
</Box>
|
||||
<ListItemText
|
||||
primary={item.text}
|
||||
primaryTypographyProps={{
|
||||
className: isActive
|
||||
? classes.activeLinkTextColor
|
||||
: classes.normalLinkTextColor,
|
||||
}}
|
||||
/>
|
||||
</ListItem>
|
||||
</NavLink>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
return null; // Return null if item shouldn't be rendered
|
||||
};
|
||||
|
||||
// Function to render a sidebar item that has children (accordion)
|
||||
const rendersideMenu = (item, i) => {
|
||||
// Check if the parent item has the necessary role
|
||||
const hasParentRole = !item.roles || item.roles.includes(userRole);
|
||||
|
||||
|
||||
// Only proceed if the parent item has the necessary role
|
||||
if (!hasParentRole) return null;
|
||||
|
||||
|
||||
// Filter visible children first
|
||||
const visibleChildren = item.children
|
||||
?.filter((childItem) => {
|
||||
// Check if child has the necessary role
|
||||
const hasChildRole = !childItem.roles || childItem.roles.includes(userRole);
|
||||
const hasChildRole =
|
||||
!childItem.roles || childItem.roles.includes(userRole);
|
||||
return hasChildRole;
|
||||
})
|
||||
.filter(Boolean); // Filter out any null/undefined results
|
||||
|
|
|
|||
|
|
@ -82,4 +82,13 @@ export const SIDEBAR_CONFIG = [
|
|||
// Clinic admin can access call transcripts
|
||||
roles: [USER_ROLES.CLINIC_ADMIN]
|
||||
},
|
||||
{
|
||||
text: 'Clinic Documents',
|
||||
path: 'docs',
|
||||
requireSaprateApp: false,
|
||||
icon: ArticleOutlinedIcon,
|
||||
activeIcon: ArticleIcon,
|
||||
// Clinic admin can access call transcripts
|
||||
roles: [USER_ROLES.CLINIC_ADMIN]
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,19 +1,22 @@
|
|||
// Initial state
|
||||
const initialState = {
|
||||
role: null,
|
||||
clinicStatus: null,
|
||||
};
|
||||
|
||||
// Action types
|
||||
const SET_USER_ROLE = 'userRole/SET_USER_ROLE';
|
||||
|
||||
// Action creators
|
||||
export const setUserRole = (role) => ({
|
||||
export const setUserRole = (role, clinicStatus) => ({
|
||||
type: SET_USER_ROLE,
|
||||
payload: role,
|
||||
clinicStatus: clinicStatus,
|
||||
});
|
||||
|
||||
// Selector to get user role
|
||||
export const selectUserRole = (state) => state.userRole.role;
|
||||
export const selectClinicStatus = (state) => state.userRole.clinicStatus;
|
||||
|
||||
// Reducer
|
||||
export default function userRoleReducer(state = initialState, action) {
|
||||
|
|
@ -22,6 +25,7 @@ export default function userRoleReducer(state = initialState, action) {
|
|||
return {
|
||||
...state,
|
||||
role: action.payload,
|
||||
clinicStatus: action.clinicStatus,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import ClinicsList from "../views/ClinicsList";
|
|||
import Dashboard from "../views/Dashboard";
|
||||
import StaffManagement from "../views/StaffManagement";
|
||||
import ClinicDetails from "../views/ClinicDetails";
|
||||
import Login from '../views/Login';
|
||||
import Login from "../views/Login";
|
||||
import YourDetailsForm from "../views/Signup/YourDetailsForm";
|
||||
import MockPayment from "../views/MockPayment";
|
||||
import Users from "../views/User";
|
||||
|
|
@ -13,6 +13,7 @@ import ClinicTranscripts from "../views/ClinicTranscripts";
|
|||
import ContractManagement from "../views/ContractManagement";
|
||||
import MasterDataManagement from "../views/MasterData";
|
||||
import PaymentManagement from "../views/PaymentManagement";
|
||||
import ClinicDocUpdater from "../views/ClinicDocUpdate";
|
||||
|
||||
export const routesData = [
|
||||
{
|
||||
|
|
@ -28,6 +29,7 @@ export const routesData = [
|
|||
{ path: "/transcripts", component: ClinicTranscripts },
|
||||
{ path: "/masterData", component: MasterDataManagement },
|
||||
{ path: "/payment-management", component: PaymentManagement },
|
||||
{ path: "/docs", component: ClinicDocUpdater },
|
||||
],
|
||||
isProtected: true,
|
||||
},
|
||||
|
|
@ -38,7 +40,7 @@ export const routesData = [
|
|||
{ path: "/auth/login", component: Login },
|
||||
{ path: "/auth/signup/payment", component: MockPayment },
|
||||
{
|
||||
path: 'signup/your-details',
|
||||
path: "signup/your-details",
|
||||
component: YourDetailsForm,
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,197 @@
|
|||
import { Button, Grid, Paper, Typography } from "@mui/material";
|
||||
import { Box } from "@mui/system";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import CustomFileUpload from "../../components/CustomFileUpload";
|
||||
import { useFormik } from "formik";
|
||||
import * as Yup from "yup";
|
||||
import { MAX_FILE_SIZE_IN_MB, MAX_FILES } from "../../constants";
|
||||
import { updateClinicDocs } from "../../services/clinics.service";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const ClinicDocUpdater = () => {
|
||||
const navigate = useNavigate();
|
||||
// Use state instead of ref for initial form data
|
||||
const [initialFormData, setInitialFormData] = useState({
|
||||
companyABNImage: "",
|
||||
contract: "",
|
||||
logo: "",
|
||||
clinicId: "",
|
||||
});
|
||||
|
||||
// Track if data is loaded
|
||||
const [isDataLoaded, setIsDataLoaded] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// Load user data from localStorage
|
||||
try {
|
||||
const user = JSON.parse(localStorage.getItem("user"));
|
||||
|
||||
if (user && user.created_clinics ) {
|
||||
setInitialFormData({
|
||||
companyABNImage: user.created_clinics.abn_doc || "",
|
||||
contract: user.created_clinics.contract_doc || "",
|
||||
logo: user.created_clinics.logo || "",
|
||||
clinicId: user.created_clinics.id || "",
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error loading user data:", error);
|
||||
} finally {
|
||||
setIsDataLoaded(true);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
companyABNImage: Yup.string().required("Clinic ABN document is required"),
|
||||
contract: Yup.string().required("Contract is required"),
|
||||
logo: Yup.string().required("Logo is required"),
|
||||
});
|
||||
|
||||
const handleFormSubmit = async () => {
|
||||
console.log("Form values:", formik.values);
|
||||
const payload = {
|
||||
abn_doc: formik.values.companyABNImage,
|
||||
contract_doc: formik.values.contract,
|
||||
logo: formik.values.logo,
|
||||
}
|
||||
|
||||
const resp = await updateClinicDocs(formik.values.clinicId, payload);
|
||||
console.log(resp);
|
||||
|
||||
// clear localStorage
|
||||
localStorage.removeItem("user");
|
||||
// redirect to login
|
||||
navigate("/");
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
formik.handleSubmit();
|
||||
};
|
||||
|
||||
// Initialize formik only after data is loaded
|
||||
const formik = useFormik({
|
||||
initialValues: initialFormData,
|
||||
validationSchema,
|
||||
onSubmit: handleFormSubmit,
|
||||
enableReinitialize: true, // This is key - it will update form values when initialValues change
|
||||
});
|
||||
|
||||
// Set uploaded file URL
|
||||
const setUploadedFileUrl = (documentName, fileUrl) => {
|
||||
console.log("Document Name:", documentName);
|
||||
console.log("File URL:", fileUrl);
|
||||
console.log("File URL Type:", typeof fileUrl);
|
||||
|
||||
if (documentName && fileUrl !== undefined) {
|
||||
formik.setFieldValue(documentName, fileUrl);
|
||||
console.log("After setting value:", formik.values[documentName]);
|
||||
} else {
|
||||
console.error("Invalid parameters for setUploadedFileUrl:", {
|
||||
documentName,
|
||||
fileUrl,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Box sx={{ width: "100%" }}>
|
||||
<Paper sx={{ width: "100%", mb: 2 }}>
|
||||
<Box
|
||||
sx={{
|
||||
p: 2,
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Typography variant="h6" component="div">
|
||||
Clinic Docs
|
||||
</Typography>
|
||||
</Box>
|
||||
{isDataLoaded ? (
|
||||
<form onSubmit={formik.handleSubmit}>
|
||||
<Box
|
||||
sx={{
|
||||
p: 2,
|
||||
display: "flex",
|
||||
gap: 2,
|
||||
flexWrap: "wrap",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Grid
|
||||
container
|
||||
spacing={5}
|
||||
// padding={`0 ${theme.spacing(3.2)}`}
|
||||
// className={classes.formRoot}
|
||||
// sx={{ display: "flex" }}
|
||||
>
|
||||
<Grid item md={4} sm={12} xs={12}>
|
||||
<CustomFileUpload
|
||||
label="Add ABN/ACN Image*"
|
||||
documentName="companyABNImage"
|
||||
onUploadDone={setUploadedFileUrl}
|
||||
maxFileSizeInMb={MAX_FILE_SIZE_IN_MB}
|
||||
maxFiles={MAX_FILES}
|
||||
uploadedFileUrl={formik.values.companyABNImage}
|
||||
errorMessage={
|
||||
formik.errors.companyABNImage &&
|
||||
formik.touched.companyABNImage
|
||||
? formik.errors.companyABNImage
|
||||
: ""
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item md={4} sm={12} xs={12}>
|
||||
<CustomFileUpload
|
||||
label="Add Contract*"
|
||||
documentName="contract"
|
||||
onUploadDone={setUploadedFileUrl}
|
||||
maxFileSizeInMb={MAX_FILE_SIZE_IN_MB}
|
||||
maxFiles={MAX_FILES}
|
||||
uploadedFileUrl={formik.values.contract}
|
||||
errorMessage={
|
||||
formik.errors.contract && formik.touched.contract
|
||||
? formik.errors.contract
|
||||
: ""
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item md={4} sm={12} xs={12}>
|
||||
<CustomFileUpload
|
||||
label="Add Logo*"
|
||||
documentName="logo"
|
||||
onUploadDone={setUploadedFileUrl}
|
||||
maxFileSizeInMb={MAX_FILE_SIZE_IN_MB}
|
||||
maxFiles={MAX_FILES}
|
||||
uploadedFileUrl={formik.values.logo}
|
||||
errorMessage={
|
||||
formik.errors.logo && formik.touched.logo
|
||||
? formik.errors.logo
|
||||
: ""
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Box>
|
||||
</form>
|
||||
) : (
|
||||
<Box sx={{ p: 2 }}>
|
||||
<Typography>Loading clinic documents...</Typography>
|
||||
</Box>
|
||||
)}
|
||||
</Paper>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default ClinicDocUpdater;
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
export const convertToSignupForm = (data) => {
|
||||
return {
|
||||
name: data.name,
|
||||
email: data.email,
|
||||
password: data.password,
|
||||
mobileNumber: data.mobileNumber,
|
||||
mobilePrefix: data.mobilePrefix,
|
||||
companyName: data.companyName,
|
||||
designation: data.designation,
|
||||
businessPhonePrefix: data.businessPhonePrefix,
|
||||
businessPhone: data.businessPhone,
|
||||
emergencyBusinessPhone: data.emergencyBusinessPhone,
|
||||
emergencyBusinessPhonePrefix: data.emergencyBusinessPhonePrefix,
|
||||
businessFax: data.businessFax,
|
||||
clinicLogo: data.clinicLogo,
|
||||
businessEmail: data.businessEmail,
|
||||
pincode: data.pincode,
|
||||
state: data.state,
|
||||
locality: data.locality,
|
||||
country: data.country,
|
||||
fullAddress: data.fullAddress,
|
||||
companyABNImageNumber: data.companyABNImageNumber,
|
||||
companyABNImage: data.companyABNImage,
|
||||
termsAccepted: data.termsAccepted,
|
||||
practiceManagementSystem: data.practiceManagementSystem,
|
||||
practiceId: data.practiceId,
|
||||
practiceName: data.practiceName,
|
||||
contract: data.contract,
|
||||
};
|
||||
};
|
||||
|
|
@ -7,7 +7,12 @@ import SuperAdmin from "./components/SuperAdmin";
|
|||
import { selectUserRole, setUserRole } from "../../redux/userRoleSlice";
|
||||
import Totals from "./Tiles/Totals";
|
||||
import { useStyles } from "./dashboardStyles";
|
||||
import { USER_ROLES } from "../../constants";
|
||||
import { NOTIFICATION, USER_ROLES } from "../../constants";
|
||||
import { getClinicsById } from "../../services/clinics.service";
|
||||
import { pushNotification } from "../../utils/notification";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { updateFormDetails } from "../Signup/signupAction";
|
||||
import { convertToSignupForm } from "./helper";
|
||||
|
||||
function Dashboard() {
|
||||
const classes = useStyles();
|
||||
|
|
@ -31,7 +36,51 @@ function Dashboard() {
|
|||
const userRole = useSelector(selectUserRole);
|
||||
const user = useSelector((state) => state.login.user);
|
||||
|
||||
const navigation = useNavigate();
|
||||
|
||||
const getClinic = async () => {
|
||||
setIsLoading(true);
|
||||
const resp = await getClinicsById(user.created_clinics[0].id);
|
||||
|
||||
|
||||
// if(resp?.data?.data?.error){
|
||||
// setIsActive(false);
|
||||
// pushNotification("Error while fetching clinic data", NOTIFICATION.ERROR);
|
||||
// navigation("/auth/signup/your-details?status=error");
|
||||
// }
|
||||
|
||||
const status = resp?.data?.data?.clinic?.status;
|
||||
|
||||
if(status == "rejected"){
|
||||
setIsActive(false);
|
||||
|
||||
// update user state with latest clinic
|
||||
localStorage.setItem("user", JSON.stringify({
|
||||
...user,
|
||||
created_clinics: resp?.data?.data?.clinic
|
||||
}))
|
||||
|
||||
dispatch(setUserRole(USER_ROLES.CLINIC_ADMIN, "rejected"));
|
||||
|
||||
pushNotification(resp?.data?.data?.fileStatus?.reason || "Your clinic registration has been rejected", NOTIFICATION.WARNING);
|
||||
navigation("/docs");
|
||||
}
|
||||
|
||||
// if(status=="payment_due"){
|
||||
// setIsActive(false);
|
||||
// pushNotification("Payment due", NOTIFICATION.WARNING);
|
||||
// }
|
||||
|
||||
// if(status=="requested_doc"){
|
||||
// setIsActive(false);
|
||||
// pushNotification("Documents requested", NOTIFICATION.WARNING);
|
||||
// }
|
||||
|
||||
setIsLoading(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getClinic();
|
||||
// Determine user role based on user data from login reducer
|
||||
if (user) {
|
||||
// Check if user is a super admin
|
||||
|
|
@ -44,9 +93,9 @@ function Dashboard() {
|
|||
setIsActive(clinicStatus == "active");
|
||||
|
||||
if (isSuperAdmin) {
|
||||
dispatch(setUserRole(USER_ROLES.SUPER_ADMIN));
|
||||
dispatch(setUserRole(USER_ROLES.SUPER_ADMIN, clinicStatus));
|
||||
} else {
|
||||
dispatch(setUserRole(USER_ROLES.CLINIC_ADMIN));
|
||||
dispatch(setUserRole(USER_ROLES.CLINIC_ADMIN, clinicStatus));
|
||||
}
|
||||
}
|
||||
setIsLoading(false);
|
||||
|
|
|
|||
|
|
@ -94,6 +94,11 @@ function YourDetailsForm() {
|
|||
const selectedLocalityRef = useRef();
|
||||
const [testConnection, setTestConnDone] = useState(false);
|
||||
|
||||
|
||||
const errorStatus = new URLSearchParams(window.location.search).get("status");
|
||||
|
||||
console.log(errorStatus)
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoading(true);
|
||||
getLatestClinicId().then((res) => {
|
||||
|
|
@ -209,6 +214,7 @@ function YourDetailsForm() {
|
|||
|
||||
if (yourDetailsFormData) {
|
||||
defaultFormData.current = { ...yourDetailsFormData };
|
||||
console.log(yourDetailsFormData)
|
||||
// setLocalityOption([yourDetailsFormData?.locality])
|
||||
selectedLocalityRef.current = yourDetailsFormData?.locality;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue