From 7da797cdca7b7cfa8003e5fb4e9188220a2ab1ca Mon Sep 17 00:00:00 2001 From: Abdulrahman Fahmy Date: Mon, 13 Nov 2023 10:42:58 +0200 Subject: [PATCH] added pages for upload --- .../layouts/dashboard/config-navigation.jsx | 4 + client/src/pages/doctor-document-upload.jsx | 46 ++++++++++++ client/src/pages/medical-history.jsx | 38 ++++++++++ client/src/routes/sections.jsx | 14 +++- .../src/sections/register/register-view.jsx | 4 +- client/src/sections/upload/Upload.jsx | 1 + client/src/sections/upload/displayRecords.jsx | 70 ++++++++---------- .../sections/upload/medicalHistoryUpload.jsx | 74 ++++++++----------- server/src/routes/upload.route.ts | 2 +- 9 files changed, 164 insertions(+), 89 deletions(-) create mode 100644 client/src/pages/doctor-document-upload.jsx create mode 100644 client/src/pages/medical-history.jsx diff --git a/client/src/layouts/dashboard/config-navigation.jsx b/client/src/layouts/dashboard/config-navigation.jsx index 356ece4..64bc0da 100644 --- a/client/src/layouts/dashboard/config-navigation.jsx +++ b/client/src/layouts/dashboard/config-navigation.jsx @@ -43,6 +43,10 @@ const navConfig = [ title: 'Upload Documents', path: '/upload-document', icon: icon('ic_disabled') + }, { + title: 'Medical History', + path: '/medical-history', + icon: icon('ic_disabled') }, { title: 'Not found', diff --git a/client/src/pages/doctor-document-upload.jsx b/client/src/pages/doctor-document-upload.jsx new file mode 100644 index 0000000..3454b9b --- /dev/null +++ b/client/src/pages/doctor-document-upload.jsx @@ -0,0 +1,46 @@ +import React from 'react'; +import { Helmet } from 'react-helmet-async'; +import { RegistrationUpload, MedicalHistoryUpload, RecordsList } from 'src/sections/upload'; + +function DoctorDocumentUploadPage() { + return ( + <> + + Upload Documents + + +
+

Document Upload Page

+ +
+

Registration Documents

+ +
+ +
+ + ); +} + + +const containerStyle = { + maxWidth: '800px', + margin: '0 auto', + padding: '20px', +}; + +const headingStyle = { + fontSize: '24px', + marginBottom: '20px', +}; + +const sectionStyle = { + marginBottom: '40px', +}; + +const subHeadingStyle = { + fontSize: '20px', + marginBottom: '10px', +}; + +export default DoctorDocumentUploadPage; diff --git a/client/src/pages/medical-history.jsx b/client/src/pages/medical-history.jsx new file mode 100644 index 0000000..a379e95 --- /dev/null +++ b/client/src/pages/medical-history.jsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { Helmet } from 'react-helmet-async'; +import { RecordsList, MedicalHistoryUpload } from 'src/sections/upload'; + +const MedicalHistoryPage = () => { + return ( + <> + + Medical History + + +
+

Medical History

+ + + +
+ + ); +}; + + +const containerStyle = { + maxWidth: '800px', + margin: '0 auto', + padding: '20px', + backgroundColor: '#fff', + boxShadow: '0px 0px 10px rgba(0, 0, 0, 0.1)', + borderRadius: '8px', +}; + +const headingStyle = { + fontSize: '28px', + marginBottom: '20px', + color: '#333', +}; + +export default MedicalHistoryPage; diff --git a/client/src/routes/sections.jsx b/client/src/routes/sections.jsx index 66e4b46..5bcde8b 100644 --- a/client/src/routes/sections.jsx +++ b/client/src/routes/sections.jsx @@ -13,7 +13,9 @@ export const LoginPage = lazy(() => import('src/pages/login')); export const RegisterPage = lazy(() => import('src/pages/register')); export const ProductsPage = lazy(() => import('src/pages/products')); export const Page404 = lazy(() => import('src/pages/page-not-found')); +export const DoctorDocumentUploadPage = lazy(() => import('src/pages/doctor-document-upload')); +export const MedicalHistoryPage = lazy(() => import('src/pages/medical-history')); // ---------------------------------------------------------------------- export default function Router() { @@ -32,7 +34,14 @@ export default function Router() { { path: 'user', element: }, { path: 'products', element: }, { path: 'blog', element: }, - { path: 'doctors', element: } + { path: 'doctors', element: }, + { + path: '/upload-document', + element: + }, { + path: '/medical-history', + element: + } ] }, { @@ -46,9 +55,6 @@ export default function Router() { { path: '404', element: - }, { - path: '/upload-document', - element: }, { path: '*', diff --git a/client/src/sections/register/register-view.jsx b/client/src/sections/register/register-view.jsx index 52a7691..a5ce290 100644 --- a/client/src/sections/register/register-view.jsx +++ b/client/src/sections/register/register-view.jsx @@ -21,7 +21,7 @@ import { bgGradient } from 'src/theme/css'; import Logo from 'src/components/logo'; import { axiosInstance } from '../../utils/axiosInstance'; -import RegistrationUpload from 'src/sections/upload/registrationUpload'; +import { RegistrationUpload } from 'src/sections/upload'; // ---------------------------------------------------------------------- @@ -58,7 +58,7 @@ export default function RegisterView() { const data = await res.json(); if (res.ok) { - router.push('/'); + router.push('/upload-document'); } else { setError(data.message); } diff --git a/client/src/sections/upload/Upload.jsx b/client/src/sections/upload/Upload.jsx index 79c386f..c6e06a5 100644 --- a/client/src/sections/upload/Upload.jsx +++ b/client/src/sections/upload/Upload.jsx @@ -43,6 +43,7 @@ function Upload({ url, field, handleUploadSuccess, fileName }) { console.log(selectedFiles); setFiles(selectedFiles); setIsFileChanged(true); + setFeedback(""); }; diff --git a/client/src/sections/upload/displayRecords.jsx b/client/src/sections/upload/displayRecords.jsx index 1bb2d96..5659e59 100644 --- a/client/src/sections/upload/displayRecords.jsx +++ b/client/src/sections/upload/displayRecords.jsx @@ -3,22 +3,17 @@ import PDFViewer from './viewPDF'; import ImageViewer from './viewImage.jsx'; import axios from 'axios'; import IconButton from '@mui/material/IconButton'; -import Button from '@mui/material/Button'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import ExpandLessIcon from '@mui/icons-material/ExpandLess'; import DeleteIcon from '@mui/icons-material/Delete'; import { axiosInstance } from '../../utils/axiosInstance'; -import Snackbar from '@mui/material/Snackbar'; const AdditionalContent = ({ ContentInfo, name }) => { + const url = `http://localhost:3000/upload/patient/medicalHistory/${name}`; let comp =

{ContentInfo.url}

; - // let urlParts = String(ContentInfo.url).replace(/\\/g, '/').split('/'); - let url = `http://localhost:3000/upload/patient/medicalHistory/` + name; - url = String(url).replace(/\\/g, '/'); - if (String(ContentInfo.ext) === 'pdf') { - comp = ; - } else if (['jpg', 'jpeg', 'png'].includes(String(ContentInfo.ext).toLowerCase())) { - comp = ; + + if (['pdf', 'jpg', 'jpeg', 'png'].includes(String(ContentInfo.ext).toLowerCase())) { + comp = ContentInfo.ext === 'pdf' ? : ; } return ( @@ -41,7 +36,7 @@ const Row = ({ text, ContentInfo, onDelete }) => { alignItems: 'center', justifyContent: 'space-between', padding: '10px', - backgroundColor: isExpanded ? '#e0f7fa' : isHovered ? '#e0f7fa' : 'transparent', + backgroundColor: isExpanded || isHovered ? '#e0f7fa' : 'transparent', transition: 'background-color 0.3s', cursor: 'pointer', border: '1px solid #b2ebf2', @@ -73,57 +68,56 @@ const Row = ({ text, ContentInfo, onDelete }) => { const RecordsList = () => { const [rows, setRows] = useState([]); - const [isOpen, setIsOpen] = React.useState(false); + useEffect(() => { const fetchData = async () => { - const data = await generateRows(); - setRows(data); + try { + const data = await generateRows(); + setRows(data); + } catch (error) { + console.error('Error fetching data:', error); + } }; fetchData(); }, []); const handleDelete = async (text) => { - const res = await axiosInstance.delete('upload/patient/medicalHistory/' + text); - if (res.status != 200) { return; } - const temp = rows.filter((row) => row.text != text); - setRows(temp); - console.log(`Delete row with text: ${text}`); + try { + const res = await axiosInstance.delete(`upload/patient/medicalHistory/${text}`); + if (res.status === 200) { + const temp = rows.filter((row) => row.text !== text); + setRows(temp); + console.log(`Deleted row with text: ${text}`); + } + } catch (error) { + console.error('Error deleting row:', error); + } }; async function generateRows() { - const rows = []; const res = await axiosInstance.get('upload/patient/medicalHistory/'); - const data = res.data.result; - console.log(data + "-------") - - for (let i = 0; i < data.length; i++) { - console.log(data[i].medicalRecord) - let url, ext; - if (data[i].medicalRecord) { - url = data[i].medicalRecord.split('.'); - ext = url.length > 0 ? url[url.length - 1] : undefined; - } - rows.push({ - text: data[i].name, + + return data.map((item) => { + const urlParts = item.medicalRecord?.split('.'); + const ext = urlParts?.length > 0 ? urlParts[urlParts.length - 1].toLowerCase() : undefined; + + return { + text: item.name, additionalContent: { - url: data[i].medicalRecord, + url: item.medicalRecord, ext: ext, }, - }); - } - - return rows; + }; + }); } - return (
{rows.map((row, index) => ( ))} -
); }; diff --git a/client/src/sections/upload/medicalHistoryUpload.jsx b/client/src/sections/upload/medicalHistoryUpload.jsx index e804c12..62e8afe 100644 --- a/client/src/sections/upload/medicalHistoryUpload.jsx +++ b/client/src/sections/upload/medicalHistoryUpload.jsx @@ -1,19 +1,13 @@ import React, { Suspense, useState } from 'react'; import Button from '@mui/material/Button'; -import Upload from "./Upload"; -import Label from "src/components/label"; import TextField from '@mui/material/TextField'; +import Modal from '@mui/material/Modal'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import Upload from './Upload'; +import Label from 'src/components/label'; const modalStyle = { - position: 'fixed', - top: 0, - left: 0, - width: '100%', - height: '100%', - backgroundColor: 'rgba(0, 0, 0, 0.5)', -}; - -const modalContentStyle = { position: 'absolute', top: '50%', left: '50%', @@ -33,7 +27,6 @@ const closeButtonStyle = { cursor: 'pointer', }; - const MedicalHistoryUploadComponent = ({ onClose }) => { const [isUploaded, setIsUploaded] = useState([0, 0, 0]); const [fileName, setFileName] = useState(''); @@ -51,43 +44,31 @@ const MedicalHistoryUploadComponent = ({ onClose }) => { setFileName(event.target.value); }; - const style = { fontSize: '16px' }; - return ( -
- + + - -
- ); -}; - -const Modal = ({ isOpen, onClose, children }) => { - if (!isOpen) { - return null; - } - - return ( -
-
- {children} -
-
+ ); }; @@ -95,25 +76,30 @@ const MedicalHistoryUpload = () => { const [isModalOpen, setModalOpen] = useState(false); const openModal = () => { - setTimeout(() => { - setModalOpen(true); - }, 50); + setModalOpen(true); }; const closeModal = () => { - setTimeout(() => { - setModalOpen(false); - }, 50); + setModalOpen(false); }; return ( - Loading...} > + Loading...}>
- - - + + + + Medical History Upload + + +
diff --git a/server/src/routes/upload.route.ts b/server/src/routes/upload.route.ts index 01e011e..63c8bac 100644 --- a/server/src/routes/upload.route.ts +++ b/server/src/routes/upload.route.ts @@ -32,7 +32,7 @@ uploadRouter.post("/patient/medicalHistory", medicalHistoryUpload.array("medical //------------------------------------------------------------------------------------------------------------------- -uploadRouter.use(isAuthorized("doctor")); +uploadRouter.use(isAuthorized("Doctor")); uploadRouter.post("/doctor/registration", registrationUpload.fields(allowedRegistrationFields as any[]),(req, res) => { controller(res)(saveRegistrationFiles)(req.decoded.id, req.files); });