Compare commits
2 Commits
61466d694b
...
70f97d1e00
| Author | SHA1 | Date | |
|---|---|---|---|
| 70f97d1e00 | |||
|
|
735ec1e31f |
@ -33,6 +33,7 @@
|
|||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-gauge-chart": "^0.4.1",
|
"react-gauge-chart": "^0.4.1",
|
||||||
"react-icons": "^4.9.0",
|
"react-icons": "^4.9.0",
|
||||||
|
"react-image-marker": "^1.2.0",
|
||||||
"react-leaflet": "^4.2.1",
|
"react-leaflet": "^4.2.1",
|
||||||
"react-router-dom": "^6.14.2",
|
"react-router-dom": "^6.14.2",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
|
|||||||
BIN
src/Assets/delete.png
Normal file
BIN
src/Assets/delete.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
BIN
src/Assets/human_body_3d.jpg
Normal file
BIN
src/Assets/human_body_3d.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
26
src/Components/ImageMarker/Entry.tsx
Normal file
26
src/Components/ImageMarker/Entry.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import Slider from '@mui/material/Slider';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
|
||||||
|
import deleteIcon from '../../Assets/delete.png';
|
||||||
|
import Rating from './Rating';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
entry: any;
|
||||||
|
index: number;
|
||||||
|
onUpdate: (data: any) => void;
|
||||||
|
onDelete: (index: number) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Entry = ({ entry, onUpdate, onDelete, index }: Props) => {
|
||||||
|
return (
|
||||||
|
<div className='entry'>
|
||||||
|
<span className='image-marker__marker--default'>{index + 1}</span>
|
||||||
|
<Rating index={entry.index} defaultValue={entry.severity} onUpdate={onUpdate}/>
|
||||||
|
<IconButton aria-label='delete' onClick={() => onDelete(index)}>
|
||||||
|
<img src={deleteIcon} height='25' width='25' />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Entry;
|
||||||
39
src/Components/ImageMarker/EntryForm.tsx
Normal file
39
src/Components/ImageMarker/EntryForm.tsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import Entry from './Entry';
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
entries: Array<any>;
|
||||||
|
onUpdate: (data: any) => void;
|
||||||
|
onDelete: (index: number) => void;
|
||||||
|
onSave: (data: any) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const EntryForm = ({ entries, onUpdate, onDelete, onSave }: Props) => {
|
||||||
|
return (
|
||||||
|
<div className='entryForm'>
|
||||||
|
<span className='header'>*** Mark Your Areas of Pain on the Picture ***</span>
|
||||||
|
{entries && entries.length > 0 &&
|
||||||
|
<span className='sub-header'>How much pain are you in right now?</span>
|
||||||
|
}
|
||||||
|
{entries?.map((entry: any, index: number) => (
|
||||||
|
<Entry
|
||||||
|
entry={entry}
|
||||||
|
index={index}
|
||||||
|
key={index}
|
||||||
|
onUpdate={onUpdate}
|
||||||
|
onDelete={onDelete}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
{/* {
|
||||||
|
entries && entries.length > 0 &&
|
||||||
|
<div className='buttonDiv'>
|
||||||
|
<Button variant='contained' onClick={() => onSave({})}>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
} */}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EntryForm;
|
||||||
160
src/Components/ImageMarker/PatientImageMarker.css
Normal file
160
src/Components/ImageMarker/PatientImageMarker.css
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
.image-marker-div {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-marker-div .entry-div {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-marker-div .entry-div .entryForm {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-marker-div .entry-div .entryForm .header {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-marker-div .entry-div .entryForm .sub-header {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-marker-div .entry-div .entryForm .entry {
|
||||||
|
margin-top: 1%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-marker-div .marker-div {
|
||||||
|
/* margin-right: 5%; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-marker-div .rating-div {
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1200px) {
|
||||||
|
.image-marker-div {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-marker-div .entry-div {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-marker-div .rating-div {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-marker-div .entry-div .entryForm .entry {
|
||||||
|
gap: 0;
|
||||||
|
margin-bottom: 2%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 1400px) {
|
||||||
|
.image-marker-div .rating-div {
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale {
|
||||||
|
min-width: 40px !important;
|
||||||
|
width: 3% !important;
|
||||||
|
text-align: center !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
color: black !important;
|
||||||
|
font-family: 'Lato', sans-serif;
|
||||||
|
border: none !important;
|
||||||
|
margin-left: 1% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected {
|
||||||
|
border: 3px solid black !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-1 {
|
||||||
|
background-color: #33FF00 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-1:hover {
|
||||||
|
background-color: #2CDE00 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-2 {
|
||||||
|
background-color: #66FF00 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-2:hover {
|
||||||
|
background-color: #59DE00 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-3 {
|
||||||
|
background-color: #99FF00 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-3:hover {
|
||||||
|
background-color: #85DE00 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-4 {
|
||||||
|
background-color: #CCFF00 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-4:hover {
|
||||||
|
background-color: #B1DE00 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-5 {
|
||||||
|
background-color: #FFFF00 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-5:hover {
|
||||||
|
background-color: #DEDE00 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-6 {
|
||||||
|
background-color: #FFCC00 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-6:hover {
|
||||||
|
background-color: #DEB100 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-7 {
|
||||||
|
background-color: #FF9900 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-7:hover {
|
||||||
|
background-color: #DE8500 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-8 {
|
||||||
|
background-color: #FF6600 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-8 {
|
||||||
|
background-color: #DE5900 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-9 {
|
||||||
|
background-color: #FF3300 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-9:hover {
|
||||||
|
background-color: #DE2C00 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-10 {
|
||||||
|
background-color: #FF0000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-scale-asc-10:hover {
|
||||||
|
background-color: #DE0000 !important;
|
||||||
|
}
|
||||||
70
src/Components/ImageMarker/PatientImageMarker.tsx
Normal file
70
src/Components/ImageMarker/PatientImageMarker.tsx
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import ImageMarker, { Marker } from 'react-image-marker';
|
||||||
|
|
||||||
|
import humanImage from '../../Assets/human_body_3d.jpg';
|
||||||
|
import EntryForm from './EntryForm';
|
||||||
|
|
||||||
|
import './PatientImageMarker.css'
|
||||||
|
|
||||||
|
type Props = {}
|
||||||
|
|
||||||
|
const PatientImageMarker = (props: Props) => {
|
||||||
|
const [markers, setMarkers] = useState<Array<Marker>>([]);
|
||||||
|
const [entries, setEntries] = useState<Array<any>>([]);
|
||||||
|
const [action, setAction] = useState<any>({});
|
||||||
|
|
||||||
|
const updateEntry = (updated: any) => {
|
||||||
|
setEntries((prevEntries) =>
|
||||||
|
prevEntries.map((entry) =>
|
||||||
|
entry.index === updated.index
|
||||||
|
? { ...entry, severity: updated.severity }
|
||||||
|
: entry
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const addEntries = (marker: Marker) => {
|
||||||
|
setAction({ type: 'add', index: 0 });
|
||||||
|
setMarkers([...markers, marker]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteEntry = (index: number) => {
|
||||||
|
setAction({ type: 'delete', index: index });
|
||||||
|
setMarkers(markers.filter((marker: Marker, ind: number) => ind != index));
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSave = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (action.type === 'add')
|
||||||
|
setEntries([...entries, { index: entries.length + 1, severity: 5 }]);
|
||||||
|
else
|
||||||
|
setEntries(
|
||||||
|
entries.filter((entry: any, ind: number) => ind != action.index)
|
||||||
|
);
|
||||||
|
}, [action]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='image-marker-div'>
|
||||||
|
<div className='entry-div'>
|
||||||
|
<EntryForm
|
||||||
|
entries={entries}
|
||||||
|
onSave={onSave}
|
||||||
|
onDelete={deleteEntry}
|
||||||
|
onUpdate={updateEntry}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className='marker-div'>
|
||||||
|
<ImageMarker
|
||||||
|
src={humanImage}
|
||||||
|
markers={markers}
|
||||||
|
onAddMarker={(marker: Marker) => addEntries(marker)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PatientImageMarker;
|
||||||
30
src/Components/ImageMarker/Rating.tsx
Normal file
30
src/Components/ImageMarker/Rating.tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { Button, Tooltip } from '@mui/material';
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
index: number;
|
||||||
|
defaultValue: number;
|
||||||
|
onUpdate: (data: any) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Rating = ({index, defaultValue, onUpdate} : Props) => {
|
||||||
|
return (
|
||||||
|
<div key={index} className='rating-div'>
|
||||||
|
{[...Array(10)].map((star, ind) => {
|
||||||
|
return (
|
||||||
|
<Tooltip title={(ind+1) < 3 ? 'No Pain' : (ind+1) > 7 ? 'Unbearable' : ''} placement="top-end">
|
||||||
|
<Button
|
||||||
|
className={`btn btn-scale btn-scale-asc-${ind+1} ${(ind+1) === defaultValue ? 'selected' : ''}`}
|
||||||
|
key={ind + 1}
|
||||||
|
onClick={() => onUpdate({ index: index, severity: ind+1 })}
|
||||||
|
>
|
||||||
|
{ind + 1}
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Rating;
|
||||||
@ -19,6 +19,7 @@ import PastTreatment5 from './PastTreatment5';
|
|||||||
import SystemReviewSection6 from './SyestemReviewSection6';
|
import SystemReviewSection6 from './SyestemReviewSection6';
|
||||||
import RecreationalHobbiesSection7 from './RecreationalHobbiesSection7';
|
import RecreationalHobbiesSection7 from './RecreationalHobbiesSection7';
|
||||||
import OtherDetails8 from './OtherDetails8';
|
import OtherDetails8 from './OtherDetails8';
|
||||||
|
import PatientImageMarker from '../ImageMarker/PatientImageMarker';
|
||||||
|
|
||||||
interface Patient {
|
interface Patient {
|
||||||
fullName: string;
|
fullName: string;
|
||||||
@ -153,6 +154,17 @@ export default function PatientForm(){
|
|||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
|
<Accordion expanded={expanded === 'panel9'} onChange={handleExpandChange('panel9')}>
|
||||||
|
<AccordionSummary aria-controls="panel9d-content" id="panel9d-header">
|
||||||
|
<Typography sx={{fontSize:18}}>Patient's Injury Image</Typography>
|
||||||
|
</AccordionSummary>
|
||||||
|
|
||||||
|
<AccordionDetails>
|
||||||
|
<PatientImageMarker />
|
||||||
|
</AccordionDetails>
|
||||||
|
</Accordion>
|
||||||
|
|
||||||
|
|
||||||
<Accordion expanded={expanded === 'panel4'} onChange={handleExpandChange('panel4')}>
|
<Accordion expanded={expanded === 'panel4'} onChange={handleExpandChange('panel4')}>
|
||||||
<AccordionSummary aria-controls="panel4d-content" id="panel4d-header">
|
<AccordionSummary aria-controls="panel4d-content" id="panel4d-header">
|
||||||
<Typography sx={{fontSize:18}}>Patient's Injury Details</Typography>
|
<Typography sx={{fontSize:18}}>Patient's Injury Details</Typography>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user