You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
okapidemo/his/app/src/Patients.js

288 lines
11 KiB

import React from "react";
import { useEffect, useState } from "react";
import { Link, useParams, useLocation } from "react-router-dom";
import "./Index.css";
import { policy, needConsent } from "./ManageConnection";
import format from "date-fns/format";
const hasConsent = (patient, service) => {
let consent = patient.Consent.filter(x => x.ServiceID == service.ServiceID)[0]
if (!consent) {
return false
}
consent.ConsentGivenOn = format(new Date(consent.ConsentGivenOn), "yyyy-MM-dd")
return consent
}
const ConsentLink = ({patient, service, setConsentId}) => {
const consent = hasConsent(patient, service)
return (
<span>
(<a href="#" onClick={e => {
e.stopPropagation()
e.preventDefault()
setConsentId([patient, service])
}}>{ consent ? `toestemming gegeven op: ${format(new Date(consent.ConsentGivenOn), 'dd/MM/yyyy')}` : "toestemming vereist"}</a>)
</span>
)
}
const DropDown = ({patient, services, updateSubscription, loading, saveConsent, removeConsent}) => {
const [open, _setOpen] = useState(false)
const [consentId, setConsentId] = useState(false)
const close = () => {
_setOpen(false)
window.removeEventListener('click', close)
}
const setOpen = (x) => {
_setOpen(x)
window.addEventListener('click', close)
}
const isSubscribed = (patient, service) => {
const present = service.Subscriptions.map(x => x.ID).indexOf(patient.ID) != -1
return policy(service) == 'opt-out' ? !present : present
}
const applyPolicy = (checked, service) => {
return policy(service) == 'opt-out' ? !checked : checked
}
const systems = services.reduce((acc, cur) => {
if (!acc[cur.Connection.System]) {
acc[cur.Connection.System] = []
}
acc[cur.Connection.System].push(cur)
return acc
}, {})
return (
<div className={["c-dropdown", open ? "c-dropdown--open" : null].filter(Boolean).join(' ')}>
<a
className="c-button c-button--sm"
onClick={e => e.preventDefault() || e.stopPropagation() || setOpen(true)}
>
Aanmelden
</a>
<div
className="c-dropdown__options"
onClick={e => e.stopPropagation()}
>
{Object.keys(systems).map(sys => {
return (
<div className="c-dropdown__system" key={sys}>
{consentId ? <ConsentModal
close={_ => setConsentId(false)}
loading={loading}
service={consentId ? consentId[1] : null}
patient={consentId ? consentId[0] : null}
saveConsent={saveConsent}
removeConsent={removeConsent}
/> : null}
<span className="c-dropdown__system-option">{sys}</span>
<div className="c-dropdown__ul">
{
systems[sys].map( x => {
return (
<div className="c-dropdown__option" key={x.ID}>
<label className="c-dropdown__label">
<span><input
type="checkbox"
checked={isSubscribed(patient, x)}
disabled={loading}
readOnly={loading}
onChange={(e) => {
e.stopPropagation()
const enable = applyPolicy(e.target.checked, x)
updateSubscription(patient, x, enable)
enable && needConsent(x) && setConsentId([patient, x])
}} name="" id=""
/> {x.Name} {needConsent(x) ? <ConsentLink saveConsent={saveConsent} setConsentId={setConsentId} patient={patient} service={x}/> : null}</span>
</label>
</div>
)
})
}
</div>
</div>
)
})}
</div>
</div>
)
}
export const ConsentModal = ({loading, close, service, patient, saveConsent, removeConsent}) => {
const [consent, setConsent] = useState(
hasConsent(patient, service)
? Object.assign({}, hasConsent(patient, service), {PatientID: patient.ID, EnableBrochure: !!hasConsent(patient, service).Brochure,})
: {
PatientID: patient.ID,
ServiceID: service.ServiceID,
ConsentGivenOn: format(new Date(), "yyyy-dd-MM"),
VerbalConsent: false,
EnableBrochure: false,
Brochure: "",
Brochureversion: "",
}
)
return (
<div className="c-modal-overlay" onClick={e => e.stopPropagation()}>
<div className="c-modal">
<a onClick={close} className="c-modal__close">x</a>
<div className="c-form-row">
<label htmlFor="">Toestemming gegeven op</label>
<input className="c-input" onChange={x => setConsent(Object.assign({}, consent, {ConsentGivenOn: x.target.value}))} value={consent.ConsentGivenOn} type="date"/>
</div>
<div className="c-form-row" style={{display: "flex"}}>
<input style={{marginRight: 5}} checked={consent.VerbalConsent} onChange={x => {
x.stopPropagation()
setConsent(Object.assign({}, consent, {VerbalConsent: x.target.checked}))
}} type="checkbox"/>
<label htmlFor="">Mondeling geïnformeerd</label>
</div>
<div className="c-form-row" style={{display: "flex"}}>
<input style={{marginRight: 5}} checked={consent.EnableBrochure} onChange={x => {
x.stopPropagation()
setConsent(Object.assign({}, consent, {EnableBrochure: x.target.checked}))
}} type="checkbox"/>
<label htmlFor="">Geïnformeerd d.m.v. brochure</label>
</div>
<div className="c-form-row">
<label htmlFor="" style={{opacity: consent.EnableBrochure ? 1 : 0.3}}>Brochure</label>
<input className="c-input" disabled={!consent.EnableBrochure} onChange={x => setConsent(Object.assign({}, consent, {Brochure: x.target.value}))} value={consent.Brochure} type="text"/>
</div>
<div className="c-form-row">
<label htmlFor="" style={{opacity: consent.EnableBrochure ? 1 : 0.3}}>Brochure versie</label>
<input className="c-input" disabled={!consent.EnableBrochure} onChange={x => setConsent(Object.assign({}, consent, {Brochureversion: x.target.value}))} value={consent.Brochureversion} type="text"/>
</div>
<div className="c-modal-buttons">
<button className="c-button c-button--default" disabled={loading} onClick={async x => {
await removeConsent(Object.assign({}, consent))
close()
}}>Toestemming intrekken</button>
<button className="c-button" disabled={loading} onClick={async x => {
await saveConsent(Object.assign({}, consent))
close()
}}>Opslaan</button>
</div>
</div>
</div>
)
}
const Patients = () => {
const location = useLocation()
const [loading, setLoading] = useState(false)
const [patients, setPatients] = useState([])
const [services, setServices] = useState([])
const updateServices = async () => fetch(`/api/services`).then(x => x.json()).then(x => setServices(x))
const updatePatients = async () => fetch(`/api/patients`).then(x => x.json()).then(x => setPatients(x))
useEffect(() => {
updatePatients()
}, [location])
useEffect(() => {
updateServices()
}, [location])
const updateSubscription = async (patient, service, active) => {
setLoading(true)
await fetch(`/api/services/${service.ID}/subscriptions`, {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({active: active, patient: patient.ID})
})
await updateServices()
setLoading(false)
}
const saveConsent = async (consent) => {
setLoading(true)
consent.ConsentGivenOn = new Date(consent.ConsentGivenOn)
if (!consent.EnableBrochure) {
consent.Brochure = ""
consent.Brochureversion = ""
}
await fetch(`/api/patients/${consent.PatientID}/consent`, {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(consent)
})
await updatePatients()
setLoading(false)
}
const removeConsent = async (consent) => {
setLoading(true)
if (consent.ID) {
await fetch(`/api/patients/${consent.PatientID}/consent/${consent.ID}`, {
method: "DELETE"
})
}
await updatePatients()
setLoading(false)
}
return (
<div>
<h1 className="t-page-header">Patienten</h1>
<table className="c-table" style={{width: "initial"}}>
<thead>
<tr>
<th style={{width: 200}}>Naam</th>
<th style={{width: 200}}>Geboortedatum</th>
<th style={{width: 200}}>BSN</th>
<th>Acties</th>
</tr>
</thead>
<tbody>
{patients.map(x => {
return (<tr key={x.ID}>
<td>{x.Name}</td>
<td>{x.Birthdate}</td>
<td>{x.ExternalId}</td>
<td>
{services.length ? <DropDown
updateSubscription={updateSubscription}
patient={x}
services={services}
loading={loading}
saveConsent={saveConsent}
removeConsent={removeConsent}
/> : null}
</td>
</tr>)
})}
</tbody>
</table>
</div>
);
};
export default Patients;