diff --git a/src/Components/LogUpdate/CriticalCareEditor.tsx b/src/Components/LogUpdate/CriticalCareEditor.tsx index 73b6bb674c6..58fe61576ef 100644 --- a/src/Components/LogUpdate/CriticalCareEditor.tsx +++ b/src/Components/LogUpdate/CriticalCareEditor.tsx @@ -1,7 +1,7 @@ import useQuery from "../../Utils/request/useQuery"; import routes from "../../Redux/api"; import LogUpdateSections from "./Sections"; -import { useState } from "react"; +import React, { useState } from "react"; import Loading from "../Common/Loading"; import { DailyRoundsModel } from "../Patient/models"; import ButtonV2, { Submit } from "../Common/components/ButtonV2"; @@ -20,7 +20,7 @@ type Props = { id: string; }; -type Section = (typeof LogUpdateSections)[keyof typeof LogUpdateSections]; +type SectionKey = keyof typeof LogUpdateSections; export default function CriticalCareEditor(props: Props) { const { t } = useTranslation(); @@ -29,8 +29,8 @@ export default function CriticalCareEditor(props: Props) { pathParams: { consultationId: props.consultationId, id: props.id }, }); - const [completed, setCompleted] = useState([]); - const [current, setCurrent] = useState
(); + const [completed, setCompleted] = useState([]); + const [current, setCurrent] = useState(); if (query.loading || !query.data) { return ; @@ -61,7 +61,9 @@ export default function CriticalCareEditor(props: Props) {

- {current?.title ?? t("record_updates")} + {current + ? LogUpdateSections[current].meta.title + : t("record_updates")}

{current ? ( - {Object.entries(LogUpdateSections).map(([key, section]) => { - const isCompleted = completed.some((o) => o === section); + {Object.keys(LogUpdateSections).map((key) => { + const isCompleted = completed.includes(key as SectionKey); + const section = LogUpdateSections[key as SectionKey]; + return (
  • setCurrent(section)} + onClick={() => setCurrent(key as SectionKey)} > - {section.icon && ( + {section.meta.icon && ( )} - {section.title} + {section.meta.title} void; - section: Section; + section: SectionKey; }; const SectionEditor = ({ log, onComplete, section }: SectionEditorProps) => { @@ -159,11 +163,13 @@ const SectionEditor = ({ log, onComplete, section }: SectionEditorProps) => { const [diff, setDiff] = useState>({}); const [isProcessing, setIsProcessing] = useState(false); + const Section = LogUpdateSections[section]; + return (
    - setDiff((base) => ({ ...base, ...changes }))} /> diff --git a/src/Components/LogUpdate/Sections/ABGAnalysis.tsx b/src/Components/LogUpdate/Sections/ABGAnalysis.tsx index 622d31a34f8..b17f5a5509e 100644 --- a/src/Components/LogUpdate/Sections/ABGAnalysis.tsx +++ b/src/Components/LogUpdate/Sections/ABGAnalysis.tsx @@ -1,132 +1,133 @@ import RangeFormField, { ValueDescription, } from "../../Form/FormFields/RangeFormField"; -import { logUpdateSection } from "../utils"; +import { LogUpdateSectionProps } from "../utils"; -export default logUpdateSection( - { - title: "ABG Analysis", - icon: "l-tear", - }, - ({ log, onChange }) => { - const fields = [ - { - key: "po2", - label: "PO2 (mm Hg)", - min: 10, - max: 400, - valueDescription: [ - { till: 49, text: "Low", className: "text-red-500" }, - { till: 200, text: "Normal", className: "text-green-500" }, - { text: "High", className: "text-red-500" }, - ], - }, - { - key: "pco2", - label: "PCO2 (mm Hg)", - min: 10, - max: 200, - valueDescription: [ - { till: 34, text: "Low", className: "text-red-500" }, - { till: 45, text: "Normal", className: "text-green-500" }, - { text: "High", className: "text-red-500" }, - ], - }, - { - key: "ph", - label: "PH", - min: 0, - max: 10, - step: 0.1, - valueDescription: [ - { till: 7.35, text: "Low", className: "text-red-500" }, - { till: 7.45, text: "Normal", className: "text-green-500" }, - { text: "High", className: "text-red-500" }, - ], - }, - { - key: "hco3", - label: "HCO3 (mmol/L)", - min: 5, - max: 80, - step: 0.1, - valueDescription: [ - { till: 21.9, text: "Low", className: "text-red-500" }, - { till: 26, text: "Normal", className: "text-green-500" }, - { text: "High", className: "text-red-500" }, - ], - }, - { - key: "base_excess", - label: "Base Excess (mmol/L)", - min: -20, - max: 20, - valueDescription: [ - { till: -3, text: "Low", className: "text-red-500" }, - { till: 2, text: "Normal", className: "text-green-500" }, - { text: "High", className: "text-red-500" }, - ], - }, - { - key: "lactate", - label: "Lactate (mmol/L)", - min: 0, - max: 20, - step: 0.1, - valueDescription: [ - { till: 2, text: "Normal", className: "text-green-500" }, - { text: "High", className: "text-red-500" }, - ], - }, - { - key: "sodium", - label: "Sodium (mmol/L)", - min: 100, - max: 170, - step: 0.1, - valueDescription: [ - { till: 134.9, text: "Low", className: "text-red-500" }, - { till: 145, text: "Normal", className: "text-green-500" }, - { text: "High", className: "text-red-500" }, - ], - }, - { - key: "potassium", - label: "Potassium (mmol/L)", - min: 0, - max: 10, - step: 0.1, - valueDescription: [ - { till: 3.4, text: "Low", className: "text-red-500" }, - { till: 5.5, text: "Normal", className: "text-green-500" }, - { text: "High", className: "text-red-500" }, - ], - }, - ] satisfies { - key: keyof typeof log; - label: string; - min: number; - max: number; - step?: number; - valueDescription: ValueDescription[]; - }[]; +const ABGAnalysis = ({ log, onChange }: LogUpdateSectionProps) => { + const fields = [ + { + key: "po2", + label: "PO2 (mm Hg)", + min: 10, + max: 400, + valueDescription: [ + { till: 49, text: "Low", className: "text-red-500" }, + { till: 200, text: "Normal", className: "text-green-500" }, + { text: "High", className: "text-red-500" }, + ], + }, + { + key: "pco2", + label: "PCO2 (mm Hg)", + min: 10, + max: 200, + valueDescription: [ + { till: 34, text: "Low", className: "text-red-500" }, + { till: 45, text: "Normal", className: "text-green-500" }, + { text: "High", className: "text-red-500" }, + ], + }, + { + key: "ph", + label: "PH", + min: 0, + max: 10, + step: 0.1, + valueDescription: [ + { till: 7.35, text: "Low", className: "text-red-500" }, + { till: 7.45, text: "Normal", className: "text-green-500" }, + { text: "High", className: "text-red-500" }, + ], + }, + { + key: "hco3", + label: "HCO3 (mmol/L)", + min: 5, + max: 80, + step: 0.1, + valueDescription: [ + { till: 21.9, text: "Low", className: "text-red-500" }, + { till: 26, text: "Normal", className: "text-green-500" }, + { text: "High", className: "text-red-500" }, + ], + }, + { + key: "base_excess", + label: "Base Excess (mmol/L)", + min: -20, + max: 20, + valueDescription: [ + { till: -3, text: "Low", className: "text-red-500" }, + { till: 2, text: "Normal", className: "text-green-500" }, + { text: "High", className: "text-red-500" }, + ], + }, + { + key: "lactate", + label: "Lactate (mmol/L)", + min: 0, + max: 20, + step: 0.1, + valueDescription: [ + { till: 2, text: "Normal", className: "text-green-500" }, + { text: "High", className: "text-red-500" }, + ], + }, + { + key: "sodium", + label: "Sodium (mmol/L)", + min: 100, + max: 170, + step: 0.1, + valueDescription: [ + { till: 134.9, text: "Low", className: "text-red-500" }, + { till: 145, text: "Normal", className: "text-green-500" }, + { text: "High", className: "text-red-500" }, + ], + }, + { + key: "potassium", + label: "Potassium (mmol/L)", + min: 0, + max: 10, + step: 0.1, + valueDescription: [ + { till: 3.4, text: "Low", className: "text-red-500" }, + { till: 5.5, text: "Normal", className: "text-green-500" }, + { text: "High", className: "text-red-500" }, + ], + }, + ] satisfies { + key: keyof typeof log; + label: string; + min: number; + max: number; + step?: number; + valueDescription: ValueDescription[]; + }[]; - return ( -
    - {fields.map((field, index) => ( - {field.label}} - name={field.key} - onChange={(c) => onChange({ [field.key]: c.value })} - value={log[field.key] as number} - start={field.min} - end={field.max} - step={field.step || 1} - valueDescriptions={field.valueDescription} - /> - ))} -
    - ); - }, -); + return ( +
    + {fields.map((field, index) => ( + {field.label}} + name={field.key} + onChange={(c) => onChange({ [field.key]: c.value })} + value={log[field.key] as number} + start={field.min} + end={field.max} + step={field.step || 1} + valueDescriptions={field.valueDescription} + /> + ))} +
    + ); +}; + +ABGAnalysis.meta = { + title: "ABG Analysis", + icon: "l-tear", +} as const; + +export default ABGAnalysis; diff --git a/src/Components/LogUpdate/Sections/BloodSugar.tsx b/src/Components/LogUpdate/Sections/BloodSugar.tsx index 463c5e9ecfe..e68cfc53197 100644 --- a/src/Components/LogUpdate/Sections/BloodSugar.tsx +++ b/src/Components/LogUpdate/Sections/BloodSugar.tsx @@ -1,53 +1,55 @@ import RadioFormField from "../../Form/FormFields/RadioFormField"; import RangeFormField from "../../Form/FormFields/RangeFormField"; -import { INSULIN_INTAKE_FREQUENCY_OPTIONS, logUpdateSection } from "../utils"; +import { + INSULIN_INTAKE_FREQUENCY_OPTIONS, + LogUpdateSectionProps, +} from "../utils"; -export default logUpdateSection( - { - title: "Blood Sugar", - icon: "l-tear", - }, - ({ log, onChange }) => { - return ( -
    - Blood Sugar Level(mg/dL)} - name="blood_sugar" - onChange={(c) => onChange({ blood_sugar_level: c.value })} - value={log.blood_sugar_level} - start={0} - end={700} - valueDescriptions={[ - { till: 69, text: "Low", className: "text-red-500" }, - { till: 110, text: "Normal", className: "text-green-500" }, - { text: "High", className: "text-red-500" }, - ]} - /> -
    -

    Insulin Intake

    -
    - Dosage(units)} - name="insulin_intake" - onChange={(c) => onChange({ insulin_intake_dose: c.value })} - value={log.insulin_intake_dose} - start={0} - end={100} - step={0.1} - /> -
    - Frequency(units/day)} - name="insulin_frequency" - options={INSULIN_INTAKE_FREQUENCY_OPTIONS} - optionDisplay={(c) => c.text} - optionValue={(c) => c.value} - value={log.insulin_intake_frequency} - onChange={(c) => - onChange({ insulin_intake_frequency: c.value || "" }) - } - /> -
    - ); - }, -); +const BloodSugar = ({ log, onChange }: LogUpdateSectionProps) => { + return ( +
    + Blood Sugar Level(mg/dL)} + name="blood_sugar" + onChange={(c) => onChange({ blood_sugar_level: c.value })} + value={log.blood_sugar_level} + start={0} + end={700} + valueDescriptions={[ + { till: 69, text: "Low", className: "text-red-500" }, + { till: 110, text: "Normal", className: "text-green-500" }, + { text: "High", className: "text-red-500" }, + ]} + /> +
    +

    Insulin Intake

    +
    + Dosage(units)} + name="insulin_intake" + onChange={(c) => onChange({ insulin_intake_dose: c.value })} + value={log.insulin_intake_dose} + start={0} + end={100} + step={0.1} + /> +
    + Frequency(units/day)} + name="insulin_frequency" + options={INSULIN_INTAKE_FREQUENCY_OPTIONS} + optionDisplay={(c) => c.text} + optionValue={(c) => c.value} + value={log.insulin_intake_frequency} + onChange={(c) => onChange({ insulin_intake_frequency: c.value || "" })} + /> +
    + ); +}; + +BloodSugar.meta = { + title: "Blood Sugar", + icon: "l-tear", +} as const; + +export default BloodSugar; diff --git a/src/Components/LogUpdate/Sections/Dialysis.tsx b/src/Components/LogUpdate/Sections/Dialysis.tsx index 19adbb7dbaa..819fcb6ec09 100644 --- a/src/Components/LogUpdate/Sections/Dialysis.tsx +++ b/src/Components/LogUpdate/Sections/Dialysis.tsx @@ -1,33 +1,34 @@ import RangeFormField from "../../Form/FormFields/RangeFormField"; -import { logUpdateSection } from "../utils"; +import { LogUpdateSectionProps } from "../utils"; -export default logUpdateSection( - { - title: "Dialysis", - icon: "l-jackhammer", - }, - ({ log, onChange }) => { - return ( -
    - Dialysis Fluid Balance (ml/h)} - name="blood_sugar" - onChange={(c) => onChange({ dialysis_fluid_balance: c.value })} - value={log.dialysis_fluid_balance} - start={0} - end={5000} - /> -
    -
    - Dialysis Net Balance (ml/h)} - name="blood_sugar" - onChange={(c) => onChange({ dialysis_net_balance: c.value })} - value={log.dialysis_net_balance} - start={0} - end={5000} - /> -
    - ); - }, -); +const Dialysis = ({ log, onChange }: LogUpdateSectionProps) => { + return ( +
    + Dialysis Fluid Balance (ml/h)} + name="blood_sugar" + onChange={(c) => onChange({ dialysis_fluid_balance: c.value })} + value={log.dialysis_fluid_balance} + start={0} + end={5000} + /> +
    +
    + Dialysis Net Balance (ml/h)} + name="blood_sugar" + onChange={(c) => onChange({ dialysis_net_balance: c.value })} + value={log.dialysis_net_balance} + start={0} + end={5000} + /> +
    + ); +}; + +Dialysis.meta = { + title: "Dialysis", + icon: "l-jackhammer", +} as const; + +export default Dialysis; diff --git a/src/Components/LogUpdate/Sections/IOBalance.tsx b/src/Components/LogUpdate/Sections/IOBalance.tsx index 8d51ad9ee06..20f493394b5 100644 --- a/src/Components/LogUpdate/Sections/IOBalance.tsx +++ b/src/Components/LogUpdate/Sections/IOBalance.tsx @@ -1,197 +1,200 @@ import { Fragment } from "react/jsx-runtime"; import { NameQuantity } from "../../Patient/models"; -import { logUpdateSection } from "../utils"; import SelectMenuV2 from "../../Form/SelectMenuV2"; import TextFormField from "../../Form/FormFields/TextFormField"; import ButtonV2 from "../../Common/components/ButtonV2"; import CareIcon from "../../../CAREUI/icons/CareIcon"; +import { LogUpdateSectionProps } from "../utils"; -export default logUpdateSection( - { - title: "I/O Balance", - icon: "l-balance-scale", - }, - ({ log, onChange }) => { - const infusionCollection = [ - "Adrenalin", - "Nor-adrenalin", - "Vasopressin", - "Dopamine", - "Dobutamine", - ]; - const ivfluidsCollection = ["RL", "NS", "DNS"]; - const feedsCollection = ["Ryles Tube", "Normal Feed"]; - const outputsCollection = ["Urine", "Rules Tube Aspiration", "ICD"]; +const IOBalance = ({ log, onChange }: LogUpdateSectionProps) => { + const infusionCollection = [ + "Adrenalin", + "Nor-adrenalin", + "Vasopressin", + "Dopamine", + "Dobutamine", + ]; + const ivfluidsCollection = ["RL", "NS", "DNS"]; + const feedsCollection = ["Ryles Tube", "Normal Feed"]; + const outputsCollection = ["Urine", "Rules Tube Aspiration", "ICD"]; - const sections: { + const sections: { + name: string; + fields: { name: string; - fields: { - name: string; - options: string[]; - key: keyof typeof log; - }[]; - }[] = [ - { - name: "Intake", - fields: [ - { - name: "Infusions", - options: infusionCollection, - key: "infusions", - }, - { - name: "IV Fluids", - options: ivfluidsCollection, - key: "iv_fluids", - }, - { - name: "Feed", - options: feedsCollection, - key: "feeds", - }, - ], - }, - { - name: "Outturn", - fields: [ - { - name: "Output", - options: outputsCollection, - key: "output", - }, - ], - }, - ]; + options: string[]; + key: keyof typeof log; + }[]; + }[] = [ + { + name: "Intake", + fields: [ + { + name: "Infusions", + options: infusionCollection, + key: "infusions", + }, + { + name: "IV Fluids", + options: ivfluidsCollection, + key: "iv_fluids", + }, + { + name: "Feed", + options: feedsCollection, + key: "feeds", + }, + ], + }, + { + name: "Outturn", + fields: [ + { + name: "Output", + options: outputsCollection, + key: "output", + }, + ], + }, + ]; - return ( -
    - {sections.map(({ name, fields }, k) => ( - -

    {name}

    - {fields.map((field, i) => ( -
    -

    {field.name}

    - {(log[field.key] as NameQuantity[] | undefined)?.map( - ({ name, quantity }, j) => ( -
    -
    - {j == 0 && ( -
    - Type -
    - )} - - !(log[field.key] as NameQuantity[] | undefined) - ?.map((f) => f.name) - .includes(option), - ) - .concat(field.options.includes(name) ? [name] : [])} - optionLabel={(f) => f} - value={name} - onChange={(val) => - onChange({ - [field.key]: ( - log[field.key] as NameQuantity[] | undefined - )?.map((f, fi) => - j === fi ? { ...f, name: val } : f, - ), - }) - } - className="w-full" - /> -
    - + {sections.map(({ name, fields }, k) => ( + +

    {name}

    + {fields.map((field, i) => ( +
    +

    {field.name}

    + {(log[field.key] as NameQuantity[] | undefined)?.map( + ({ name, quantity }, j) => ( +
    +
    + {j == 0 && ( +
    + Type +
    + )} + + !(log[field.key] as NameQuantity[] | undefined) + ?.map((f) => f.name) + .includes(option), + ) + .concat(field.options.includes(name) ? [name] : [])} + optionLabel={(f) => f} + value={name} onChange={(val) => onChange({ [field.key]: ( log[field.key] as NameQuantity[] | undefined )?.map((f, fi) => - j === fi - ? { ...f, quantity: parseInt(val.value) } - : f, + j === fi ? { ...f, name: val } : f, ), }) } - label={ - j == 0 && ( -
    - Quantity -
    - ) - } + className="w-full" /> - - onChange({ - [field.key]: ( - log[field.key] as NameQuantity[] | undefined - )?.filter((f, fi) => j !== fi), - }) - } - > - -
    - ), - )} - - onChange({ - [field.key]: [ - ...((log[field.key] as NameQuantity[] | undefined) || - []), - { name: null, quantity: 0 }, - ], - }) - } - disabled={ - field.options.length === - (log[field.key] as NameQuantity[] | undefined)?.length - } - > - - Add {field.name} - -
    - ))} -
    -

    Total

    -
    + + onChange({ + [field.key]: ( + log[field.key] as NameQuantity[] | undefined + )?.map((f, fi) => + j === fi + ? { ...f, quantity: parseInt(val.value) } + : f, + ), + }) + } + label={ + j == 0 && ( +
    + Quantity +
    + ) + } + /> + + onChange({ + [field.key]: ( + log[field.key] as NameQuantity[] | undefined + )?.filter((f, fi) => j !== fi), + }) + } + > + + +
    + ), + )} + + onChange({ + [field.key]: [ + ...((log[field.key] as NameQuantity[] | undefined) || []), + { name: null, quantity: 0 }, + ], + }) + } + disabled={ + field.options.length === + (log[field.key] as NameQuantity[] | undefined)?.length + } + > + + Add {field.name} + +
    + ))} +
    +

    Total

    +
    + {fields + .flatMap((f) => + ((log[f.key] as NameQuantity[]) || []).map((f) => f.quantity), + ) + .join("+")} + = + {fields .flatMap((f) => ((log[f.key] as NameQuantity[]) || []).map( (f) => f.quantity, ), ) - .join("+")} - = - - {fields - .flatMap((f) => - ((log[f.key] as NameQuantity[]) || []).map( - (f) => f.quantity, - ), - ) - .reduce((a, b) => a + b, 0)} - -
    + .reduce((a, b) => a + b, 0)} +
    - - ))} -
    -

    I/O Balance

    -
    +
    + + ))} +
    +

    I/O Balance

    +
    + {sections + .map((s) => + s.fields + .flatMap((f) => + ((log[f.key] as NameQuantity[]) || []).map((f) => f.quantity), + ) + .reduce((a, b) => a + b, 0), + ) + .join("-")} + = + {sections .map((s) => s.fields @@ -202,24 +205,17 @@ export default logUpdateSection( ) .reduce((a, b) => a + b, 0), ) - .join("-")} - = - - {sections - .map((s) => - s.fields - .flatMap((f) => - ((log[f.key] as NameQuantity[]) || []).map( - (f) => f.quantity, - ), - ) - .reduce((a, b) => a + b, 0), - ) - .reduce((a, b) => a - b)} - -
    + .reduce((a, b) => a - b)} +
    - ); - }, -); +
    + ); +}; + +IOBalance.meta = { + title: "I/O Balance", + icon: "l-balance-scale", +} as const; + +export default IOBalance; diff --git a/src/Components/LogUpdate/Sections/NeurologicalMonitoring.tsx b/src/Components/LogUpdate/Sections/NeurologicalMonitoring.tsx index 7382bf13831..098c2a150e0 100644 --- a/src/Components/LogUpdate/Sections/NeurologicalMonitoring.tsx +++ b/src/Components/LogUpdate/Sections/NeurologicalMonitoring.tsx @@ -11,200 +11,198 @@ import { DailyRoundsModel } from "../../Patient/models"; import PupilSizeSelect from "../components/PupilSizeSelect"; import { LIMB_RESPONSE_OPTIONS, - logUpdateSection, + LogUpdateSectionProps, REACTION_OPTIONS, } from "../utils"; -export default logUpdateSection( - { - title: "Neurological Monitoring", - icon: "l-brain", - }, - ({ log, onChange }) => { - const limbResponses: (keyof DailyRoundsModel)[] = [ - "limb_response_upper_extremity_left", - "limb_response_upper_extremity_right", - "limb_response_lower_extremity_left", - "limb_response_lower_extremity_right", - ]; +const NeurologicalMonitoring = ({ log, onChange }: LogUpdateSectionProps) => { + const limbResponses: (keyof DailyRoundsModel)[] = [ + "limb_response_upper_extremity_left", + "limb_response_upper_extremity_right", + "limb_response_lower_extremity_left", + "limb_response_lower_extremity_right", + ]; - return ( -
    -
    - onChange({ in_prone_position: e.value })} - /> -
    -
    -

    Levels of Consciousness

    - c.text} - optionValue={(c) => c.id || ""} - value={log.consciousness_level} - onChange={(c) => - onChange({ - consciousness_level: - c.value as (typeof CONSCIOUSNESS_LEVEL)[number]["id"], - }) - } - containerClassName="grid grid-cols-2 mt-5" + return ( +
    +
    + onChange({ in_prone_position: e.value })} /> -
    -
    - {["left", "right"].map((d, i) => ( -
    -

    {d} Pupil

    - - onChange({ - [`${d}_pupil_size` as keyof typeof log.left_pupil_size]: - val, - }) - } - onDetailChange={(val) => - onChange({ - [`${d}_pupil_size_detail` as keyof typeof log.left_pupil_size_detail]: - val, - }) - } - className="mt-4" - /> -
    -
    Reaction
    - o.value !== "UNKNOWN")} - optionDisplay={(c) => c.text} - optionValue={(c) => c.value} - name={`${d}_pupil_light_reaction`} +
    +
    +

    Levels of Consciousness

    + c.text} + optionValue={(c) => c.id || ""} + value={log.consciousness_level} + onChange={(c) => + onChange({ + consciousness_level: + c.value as (typeof CONSCIOUSNESS_LEVEL)[number]["id"], + }) + } + containerClassName="grid grid-cols-2 mt-5" + /> +
    +
    + {["left", "right"].map((d, i) => ( +
    +

    {d} Pupil

    + + onChange({ + [`${d}_pupil_size` as keyof typeof log.left_pupil_size]: val, + }) + } + onDetailChange={(val) => + onChange({ + [`${d}_pupil_size_detail` as keyof typeof log.left_pupil_size_detail]: + val, + }) + } + className="mt-4" + /> +
    +
    Reaction
    + o.value !== "UNKNOWN")} + optionDisplay={(c) => c.text} + optionValue={(c) => c.value} + name={`${d}_pupil_light_reaction`} + value={ + log[ + `${d}_pupil_light_reaction` as keyof typeof log.left_pupil_light_reaction + ] + } + onChange={(c) => + onChange({ + [`${d}_pupil_light_reaction` as keyof typeof log.left_pupil_light_reaction]: + c.value, + }) + } + containerClassName="" + /> + {log[ + `${d}_pupil_light_reaction` as keyof typeof log.left_pupil_light_reaction + ] === "CANNOT_BE_ASSESSED" && ( + onChange({ - [`${d}_pupil_light_reaction` as keyof typeof log.left_pupil_light_reaction]: + [`${d}_pupil_light_reaction_detail` as keyof typeof log.left_pupil_light_reaction_detail]: c.value, }) } - containerClassName="" /> - {log[ - `${d}_pupil_light_reaction` as keyof typeof log.left_pupil_light_reaction - ] === "CANNOT_BE_ASSESSED" && ( - - onChange({ - [`${d}_pupil_light_reaction_detail` as keyof typeof log.left_pupil_light_reaction_detail]: - c.value, - }) - } - /> - )} -
    - ))} -
    -
    -
    -

    Glasgow Coma Scale

    -
    - Total  - - {(log.glasgow_eye_open || 0) + - (log.glasgow_verbal_response || 0) + - (log.glasgow_motor_response || 0)} - + )}
    + ))} +
    +
    +
    +

    Glasgow Coma Scale

    +
    + Total  + + {(log.glasgow_eye_open || 0) + + (log.glasgow_verbal_response || 0) + + (log.glasgow_motor_response || 0)} +
    -
    -
    - Eye Opening Response} - options={EYE_OPEN_SCALE.toReversed()} - optionDisplay={(c) => c.value + " - " + c.text} - optionValue={(c) => `${c.value}`} - name="eye_opening_response" - value={`${log.glasgow_eye_open}`} - onChange={(c) => - onChange({ glasgow_eye_open: parseInt(`${c.value}`) }) - } - containerClassName="flex flex-col" - /> - Verbal Response} - options={VERBAL_RESPONSE_SCALE.toReversed()} - optionDisplay={(c) => c.value + " - " + c.text} - optionValue={(c) => `${c.value}`} - name="verbal_response" - value={`${log.glasgow_verbal_response}`} - onChange={(c) => - onChange({ - glasgow_verbal_response: parseInt(`${c.value}`), - }) - } - containerClassName="flex flex-col" - /> +
    +
    +
    + Eye Opening Response} + options={EYE_OPEN_SCALE.toReversed()} + optionDisplay={(c) => c.value + " - " + c.text} + optionValue={(c) => `${c.value}`} + name="eye_opening_response" + value={`${log.glasgow_eye_open}`} + onChange={(c) => + onChange({ glasgow_eye_open: parseInt(`${c.value}`) }) + } + containerClassName="flex flex-col" + /> + Verbal Response} + options={VERBAL_RESPONSE_SCALE.toReversed()} + optionDisplay={(c) => c.value + " - " + c.text} + optionValue={(c) => `${c.value}`} + name="verbal_response" + value={`${log.glasgow_verbal_response}`} + onChange={(c) => + onChange({ + glasgow_verbal_response: parseInt(`${c.value}`), + }) + } + containerClassName="flex flex-col" + /> + Motor Response} + options={MOTOR_RESPONSE_SCALE.toReversed()} + optionDisplay={(c) => c.value + " - " + c.text} + optionValue={(c) => `${c.value}`} + name="motor_response" + value={`${log.glasgow_motor_response}`} + onChange={(c) => + onChange({ + glasgow_motor_response: parseInt(`${c.value}`), + }) + } + containerClassName="flex flex-col" + /> +
    +
    +

    Limb Response

    +
    +
    + {limbResponses.map((d, i) => ( Motor Response} - options={MOTOR_RESPONSE_SCALE.toReversed()} - optionDisplay={(c) => c.value + " - " + c.text} - optionValue={(c) => `${c.value}`} - name="motor_response" - value={`${log.glasgow_motor_response}`} - onChange={(c) => - onChange({ - glasgow_motor_response: parseInt(`${c.value}`), - }) + key={i} + label={ + + {d.replaceAll("limb_response_", "").replaceAll("_", " ")} + } - containerClassName="flex flex-col" + options={LIMB_RESPONSE_OPTIONS.filter((o) => o.value !== "UNKNOWN")} + optionDisplay={(c) => c.text} + optionValue={(c) => c.value} + name={"limb_response_" + d} + value={`${log[d]}`} + onChange={(c) => onChange({ [d]: c.value })} + containerClassName="flex flex-wrap gap-x-8" /> -
    -
    -

    Limb Response

    -
    -
    - {limbResponses.map((d, i) => ( - - {d.replaceAll("limb_response_", "").replaceAll("_", " ")} - - } - options={LIMB_RESPONSE_OPTIONS.filter( - (o) => o.value !== "UNKNOWN", - )} - optionDisplay={(c) => c.text} - optionValue={(c) => c.value} - name={"limb_response_" + d} - value={`${log[d]}`} - onChange={(c) => onChange({ [d]: c.value })} - containerClassName="flex flex-wrap gap-x-8" - /> - ))} -
    + ))}
    - ); - }, -); +
    + ); +}; + +NeurologicalMonitoring.meta = { + title: "Neurological Monitoring", + icon: "l-brain", +} as const; + +export default NeurologicalMonitoring; diff --git a/src/Components/LogUpdate/Sections/NursingCare.tsx b/src/Components/LogUpdate/Sections/NursingCare.tsx index 3b4d54fe6ec..2dcccd56a7c 100644 --- a/src/Components/LogUpdate/Sections/NursingCare.tsx +++ b/src/Components/LogUpdate/Sections/NursingCare.tsx @@ -1,64 +1,63 @@ import { NURSING_CARE_FIELDS } from "../../../Common/constants"; import CheckBoxFormField from "../../Form/FormFields/CheckBoxFormField"; import TextAreaFormField from "../../Form/FormFields/TextAreaFormField"; -import { logUpdateSection } from "../utils"; +import { LogUpdateSectionProps } from "../utils"; -export default logUpdateSection( - { - title: "Nursing Care", - icon: "l-user-nurse", - }, - ({ log, onChange }) => ( -
    - {NURSING_CARE_FIELDS.map((field, i) => { - const nursing = log.nursing?.find((n) => n.procedure === field.text); +const NursingCare = ({ log, onChange }: LogUpdateSectionProps) => ( +
    + {NURSING_CARE_FIELDS.map((field, i) => { + const nursing = log.nursing?.find((n) => n.procedure === field.text); - return ( -
    -
    + return ( +
    +
    +
    + + onChange({ + nursing: e.value + ? [ + ...(log.nursing || []), + { procedure: field.text, description: "" }, + ] + : log.nursing?.filter((n) => n.procedure !== field.text), + }) + } + /> +
    + {nursing && (
    - - onChange({ - nursing: e.value - ? [ - ...(log.nursing || []), - { procedure: field.text, description: "" }, - ] - : log.nursing?.filter( - (n) => n.procedure !== field.text, - ), - }) - } - /> + {log.nursing?.find((n) => n.procedure === field.text) && ( + + onChange({ + nursing: log.nursing?.map((n) => + n.procedure === field.text + ? { ...n, description: val.value } + : n, + ), + }) + } + placeholder="Description" + /> + )}
    - {nursing && ( -
    - {log.nursing?.find((n) => n.procedure === field.text) && ( - - onChange({ - nursing: log.nursing?.map((n) => - n.procedure === field.text - ? { ...n, description: val.value } - : n, - ), - }) - } - placeholder="Description" - /> - )} -
    - )} -
    + )}
    - ); - })} -
    - ), +
    + ); + })} +
    ); + +NursingCare.meta = { + title: "Nursing Care", + icon: "l-user-nurse", +} as const; + +export default NursingCare; diff --git a/src/Components/LogUpdate/Sections/PressureSore.tsx b/src/Components/LogUpdate/Sections/PressureSore.tsx index a2d620861b3..e8bf3c8e854 100644 --- a/src/Components/LogUpdate/Sections/PressureSore.tsx +++ b/src/Components/LogUpdate/Sections/PressureSore.tsx @@ -6,8 +6,8 @@ import HumanBodyChart, { import { getValueDescription } from "../../Form/FormFields/RangeFormField"; import { SelectFormField } from "../../Form/FormFields/SelectFormField"; import TextFormField from "../../Form/FormFields/TextFormField"; -import { logUpdateSection } from "../utils"; import TextAreaFormField from "../../Form/FormFields/TextAreaFormField"; +import { LogUpdateSectionProps } from "../utils"; type PressureSore = { description: string; @@ -19,231 +19,229 @@ type PressureSore = { width: number; }; -export default logUpdateSection( - { - title: "Pressure Sore", - icon: "l-user-md", - }, - ({ log, onChange }) => { - const getTitle = (text: string) => text.split(/(?=[A-Z])/).join(" "); - const pressureSore = log.pressure_sore; +const PressureSore = ({ log, onChange }: LogUpdateSectionProps) => { + const getTitle = (text: string) => text.split(/(?=[A-Z])/).join(" "); + const pressureSore = log.pressure_sore; - const valueDescriptions = [ - { - till: 0, - color: "#ECECEC", - text: "", - className: "bg-secondary-300 border border-secondary-400", - }, - { - till: 3, - color: "#FF7000", - text: "", - className: "bg-red-400 text-white", - }, - { - till: 7, - color: "#FF0000", - text: "", - className: "bg-red-600 text-white", - }, - { - till: 10, - color: "#CF0000", - text: "", - className: "bg-red-800 text-white", - }, - ]; + const valueDescriptions = [ + { + till: 0, + color: "#ECECEC", + text: "", + className: "bg-secondary-300 border border-secondary-400", + }, + { + till: 3, + color: "#FF7000", + text: "", + className: "bg-red-400 text-white", + }, + { + till: 7, + color: "#FF0000", + text: "", + className: "bg-red-600 text-white", + }, + { + till: 10, + color: "#CF0000", + text: "", + className: "bg-red-800 text-white", + }, + ]; - const [selectedRegion, setSelectedRegion] = useState(); - const selectedPressureSore = pressureSore?.find( - (p) => p.region === selectedRegion, - ); - const selectedValueDescription = getValueDescription( - valueDescriptions, - selectedPressureSore?.scale || 0, - ); - const exudateAmounts = ["None", "Light", "Moderate", "Heavy"]; - const tissueTypes = [ - "Closed", - "Epithelial", - "Granulation", - "Slough", - "Necrotic", - ]; + const [selectedRegion, setSelectedRegion] = useState(); + const selectedPressureSore = pressureSore?.find( + (p) => p.region === selectedRegion, + ); + const selectedValueDescription = getValueDescription( + valueDescriptions, + selectedPressureSore?.scale || 0, + ); + const exudateAmounts = ["None", "Light", "Moderate", "Heavy"]; + const tissueTypes = [ + "Closed", + "Epithelial", + "Granulation", + "Slough", + "Necrotic", + ]; - const calculatePushScore = (pressureSore: PressureSore): number => { - const areaIntervalPoints = [ - 0.0, 0.3, 0.6, 1.0, 2.2, 3.0, 4.0, 8.0, 12.0, 24.0, - ]; - const { length, width, exudate_amount, tissue_type } = pressureSore; + const calculatePushScore = (pressureSore: PressureSore): number => { + const areaIntervalPoints = [ + 0.0, 0.3, 0.6, 1.0, 2.2, 3.0, 4.0, 8.0, 12.0, 24.0, + ]; + const { length, width, exudate_amount, tissue_type } = pressureSore; - const area = length * width; + const area = length * width; - const getAreaScore = (area: number): number => { - for (let i = 0; i < areaIntervalPoints.length; i++) { - if (area <= areaIntervalPoints[i]) { - return i; - } + const getAreaScore = (area: number): number => { + for (let i = 0; i < areaIntervalPoints.length; i++) { + if (area <= areaIntervalPoints[i]) { + return i; } - return 10; // Default value if no interval is found - }; + } + return 10; // Default value if no interval is found + }; - const getExudateScore = (amount: typeof exudate_amount): number => { - const index = exudateAmounts.indexOf(amount); - return index === -1 ? 0 : index; - }; + const getExudateScore = (amount: typeof exudate_amount): number => { + const index = exudateAmounts.indexOf(amount); + return index === -1 ? 0 : index; + }; - const getTissueScore = (tissue: typeof tissue_type): number => { - const index = tissueTypes.indexOf(tissue); - return index === -1 ? 0 : index; - }; + const getTissueScore = (tissue: typeof tissue_type): number => { + const index = tissueTypes.indexOf(tissue); + return index === -1 ? 0 : index; + }; - const areaScore = getAreaScore(area); - const exudateScore = getExudateScore(exudate_amount); - const tissueScore = getTissueScore(tissue_type); + const areaScore = getAreaScore(area); + const exudateScore = getExudateScore(exudate_amount); + const tissueScore = getTissueScore(tissue_type); - return areaScore + exudateScore + tissueScore; - }; + return areaScore + exudateScore + tissueScore; + }; - const changePressureSore = (value: Partial) => { - if (!selectedRegion) return; - if (!pressureSore?.find((p) => p.region === selectedRegion)) { - onChange({ - pressure_sore: [ - ...(log.pressure_sore || []), - { - region: selectedRegion, - width: 0, - length: 0, - exudate_amount: "None", - tissue_type: "Closed", - scale: 1, - description: "", - ...value, - }, - ], - }); - } else { - const newPressureSore = pressureSore?.map((p) => - p.region === selectedRegion ? { ...p, ...value } : p, - ); - onChange({ pressure_sore: newPressureSore }); - } - }; + const changePressureSore = (value: Partial) => { + if (!selectedRegion) return; + if (!pressureSore?.find((p) => p.region === selectedRegion)) { + onChange({ + pressure_sore: [ + ...(log.pressure_sore || []), + { + region: selectedRegion, + width: 0, + length: 0, + exudate_amount: "None", + tissue_type: "Closed", + scale: 1, + description: "", + ...value, + }, + ], + }); + } else { + const newPressureSore = pressureSore?.map((p) => + p.region === selectedRegion ? { ...p, ...value } : p, + ); + onChange({ pressure_sore: newPressureSore }); + } + }; - return ( - <> - setSelectedRegion(undefined)} - className={"flex w-[275px] flex-col items-center gap-4"} - onSubmit={() => setSelectedRegion(undefined)} - > -
    -

    - {getTitle(selectedRegion || "")} -

    -
    -
    - - changePressureSore({ width: parseInt(e.value) }) - } - /> - - changePressureSore({ length: parseInt(e.value) }) - } - /> - option} - optionValue={(option) => option} - labelClassName="text-xs" - label="Exudate Amount" - value={selectedPressureSore?.exudate_amount || ""} - onChange={(value) => - changePressureSore({ exudate_amount: value.value }) - } - compact - name="exudate-amount" - /> - option} - optionValue={(option) => option} - labelClassName="text-xs" - label="Tissue Type" - value={selectedPressureSore?.tissue_type || ""} - onChange={(value) => - changePressureSore({ tissue_type: value.value }) - } - compact - name="tissue-type" - /> -
    -
    - changePressureSore({ description: e.value })} - /> -
    - {selectedPressureSore && ( -
    0 - ? selectedValueDescription?.color - : undefined, - }} - > -
    Push Score
    -
    - {calculatePushScore(selectedPressureSore)} -
    -
    - )} + return ( + <> + setSelectedRegion(undefined)} + className={"flex w-[275px] flex-col items-center gap-4"} + onSubmit={() => setSelectedRegion(undefined)} + > +
    +

    + {getTitle(selectedRegion || "")} +

    +
    +
    + changePressureSore({ width: parseInt(e.value) })} + /> + + changePressureSore({ length: parseInt(e.value) }) + } + /> + option} + optionValue={(option) => option} + labelClassName="text-xs" + label="Exudate Amount" + value={selectedPressureSore?.exudate_amount || ""} + onChange={(value) => + changePressureSore({ exudate_amount: value.value }) + } + compact + name="exudate-amount" + /> + option} + optionValue={(option) => option} + labelClassName="text-xs" + label="Tissue Type" + value={selectedPressureSore?.tissue_type || ""} + onChange={(value) => + changePressureSore({ tissue_type: value.value }) + } + compact + name="tissue-type" + /> +
    +
    + changePressureSore({ description: e.value })} + />
    - -

    Braden Scale (Risk Severity)

    -
    - setSelectedRegion(region)} - regionColor={(region) => - getValueDescription( - valueDescriptions, - pressureSore?.find((p) => p.region === region)?.scale || 0, - )?.color || "#ECECEC" - } - regionLabelClassName={(region) => - getValueDescription( - valueDescriptions, - pressureSore?.find((p) => p.region === region)?.scale || 0, - )?.className || "" - } - regionText={(region) => - pressureSore?.find((p) => p.region === region)?.scale.toString() || - "" - } - /> - - ); - }, -); + {selectedPressureSore && ( +
    0 + ? selectedValueDescription?.color + : undefined, + }} + > +
    Push Score
    +
    + {calculatePushScore(selectedPressureSore)} +
    +
    + )} +
    +
    +

    Braden Scale (Risk Severity)

    +
    + setSelectedRegion(region)} + regionColor={(region) => + getValueDescription( + valueDescriptions, + pressureSore?.find((p) => p.region === region)?.scale || 0, + )?.color || "#ECECEC" + } + regionLabelClassName={(region) => + getValueDescription( + valueDescriptions, + pressureSore?.find((p) => p.region === region)?.scale || 0, + )?.className || "" + } + regionText={(region) => + pressureSore?.find((p) => p.region === region)?.scale.toString() || "" + } + /> + + ); +}; + +PressureSore.meta = { + title: "Pressure Sore", + icon: "l-user-md", +} as const; + +export default PressureSore; diff --git a/src/Components/LogUpdate/Sections/RespiratorySupport.tsx b/src/Components/LogUpdate/Sections/RespiratorySupport.tsx index 2a8147c27e9..c8a2370ac85 100644 --- a/src/Components/LogUpdate/Sections/RespiratorySupport.tsx +++ b/src/Components/LogUpdate/Sections/RespiratorySupport.tsx @@ -1,183 +1,182 @@ import RadioFormField from "../../Form/FormFields/RadioFormField"; import RangeFormField from "../../Form/FormFields/RangeFormField"; import { - logUpdateSection, + LogUpdateSectionProps, OXYGEN_MODALITY_OPTIONS, YES_NO_OPTIONS, } from "../utils"; -export default logUpdateSection( - { - title: "Respiratory Support", - icon: "l-lungs", - }, - ({ log, onChange }) => { - const RESPIRATORY_SUPPORT_OPTIONS = [ - { - id: 0, - text: "None", - value: "UNKNOWN", - }, - { - id: 1, - text: "Invasive ventilator (IV)", - value: "INVASIVE", - content: <>Invasive, - }, - { - id: 2, - text: "Non-Invasive ventilator (NIV)", - value: "NON_INVASIVE", - content: <>, - }, - { - id: 3, - text: "Oxygen Support", - value: "OXYGEN_SUPPORT", - content: ( - <> - Oxygen Modality} - options={OXYGEN_MODALITY_OPTIONS} - optionDisplay={(c) => c.label} - optionValue={(c) => c.value} - name="oxygen_modality" - value={log.ventilator_oxygen_modality} - onChange={(c) => - onChange({ - ventilator_oxygen_modality: - c.value as typeof log.ventilator_oxygen_modality, - }) - } - /> - {log.ventilator_oxygen_modality === "HIGH_FLOW_NASAL_CANNULA" ? ( - <> - Flow Rate} - name="oxygen_flow_rate" - onChange={(c) => - onChange({ - ventilator_oxygen_modality_flow_rate: c.value, - }) - } - value={log.ventilator_oxygen_modality_flow_rate} - start={0} - end={70} - valueDescriptions={[ - { till: 34, text: "Low", className: "text-red-500" }, - { till: 60, text: "Normal", className: "text-green-500" }, - { text: "High", className: "text-red-500" }, - ]} - /> -
    - FiO2 (%)} - name="oxygen_flow_rate" - onChange={(c) => onChange({ ventilator_fi02: c.value })} - value={log.ventilator_fi02} - start={21} - end={100} - valueDescriptions={[ - { till: 60, text: "Normal", className: "text-green-500" }, - { text: "High", className: "text-red-500" }, - ]} - /> - - ) : ( +const RespiratorySupport = ({ log, onChange }: LogUpdateSectionProps) => { + const RESPIRATORY_SUPPORT_OPTIONS = [ + { + id: 0, + text: "None", + value: "UNKNOWN", + }, + { + id: 1, + text: "Invasive ventilator (IV)", + value: "INVASIVE", + content: <>Invasive, + }, + { + id: 2, + text: "Non-Invasive ventilator (NIV)", + value: "NON_INVASIVE", + content: <>, + }, + { + id: 3, + text: "Oxygen Support", + value: "OXYGEN_SUPPORT", + content: ( + <> + Oxygen Modality} + options={OXYGEN_MODALITY_OPTIONS} + optionDisplay={(c) => c.label} + optionValue={(c) => c.value} + name="oxygen_modality" + value={log.ventilator_oxygen_modality} + onChange={(c) => + onChange({ + ventilator_oxygen_modality: + c.value as typeof log.ventilator_oxygen_modality, + }) + } + /> + {log.ventilator_oxygen_modality === "HIGH_FLOW_NASAL_CANNULA" ? ( + <> Oxygen Flow Rate} + label={Flow Rate} name="oxygen_flow_rate" onChange={(c) => onChange({ - ventilator_oxygen_modality_oxygen_rate: c.value, + ventilator_oxygen_modality_flow_rate: c.value, }) } - value={log.ventilator_oxygen_modality_oxygen_rate} + value={log.ventilator_oxygen_modality_flow_rate} start={0} - end={50} + end={70} + valueDescriptions={[ + { till: 34, text: "Low", className: "text-red-500" }, + { till: 60, text: "Normal", className: "text-green-500" }, + { text: "High", className: "text-red-500" }, + ]} + /> +
    + FiO2 (%)} + name="oxygen_flow_rate" + onChange={(c) => onChange({ ventilator_fi02: c.value })} + value={log.ventilator_fi02} + start={21} + end={100} valueDescriptions={[ - { till: 4, text: "Low", className: "text-red-500" }, - { till: 10, text: "Normal", className: "text-green-500" }, + { till: 60, text: "Normal", className: "text-green-500" }, { text: "High", className: "text-red-500" }, ]} /> - )} - - ), - }, - ]; + + ) : ( + Oxygen Flow Rate} + name="oxygen_flow_rate" + onChange={(c) => + onChange({ + ventilator_oxygen_modality_oxygen_rate: c.value, + }) + } + value={log.ventilator_oxygen_modality_oxygen_rate} + start={0} + end={50} + valueDescriptions={[ + { till: 4, text: "Low", className: "text-red-500" }, + { till: 10, text: "Normal", className: "text-green-500" }, + { text: "High", className: "text-red-500" }, + ]} + /> + )} + + ), + }, + ]; - return ( -
    -

    Bilateral Air Entry

    - c.text} - optionValue={(c) => c.text} - name="ventilator" - value={ - YES_NO_OPTIONS.find((o) => o.value === log.bilateral_air_entry) - ?.text - } - onChange={(c) => - onChange({ - bilateral_air_entry: YES_NO_OPTIONS.find( - (o) => o.text === c.value, - )?.value, - }) - } - /> - EtCO2 (mm Hg)} - name="etco2" - onChange={(c) => onChange({ etco2: c.value })} - value={log.etco2} - start={0} - end={200} - step={1} - valueDescriptions={[ - { till: 34, text: "Low", className: "text-red-500" }, - { till: 45, text: "Normal", className: "text-green-500" }, - { text: "High", className: "text-red-500" }, - ]} - /> -
    -
    - Respiratory Support} - options={RESPIRATORY_SUPPORT_OPTIONS} - optionDisplay={(c) => c.text} - optionValue={(c) => c.value} - name="respiratory_support" - value={log.ventilator_interface} - onChange={(c) => - onChange({ - ventilator_interface: (c.value || - "UNKNOWN") as typeof log.ventilator_interface, - }) - } - /> -
    - { - RESPIRATORY_SUPPORT_OPTIONS.find( - (o) => o.value === log.ventilator_interface, - )?.content - } -
    -
    - SPO2 (%)} - name="ventilator_spo2" - onChange={(c) => onChange({ ventilator_spo2: c.value })} - value={log.ventilator_spo2} - start={0} - end={100} - valueDescriptions={[ - { till: 89, text: "Low", className: "text-red-500" }, - { text: "Normal", className: "text-green-500" }, - ]} - /> + return ( +
    +

    Bilateral Air Entry

    + c.text} + optionValue={(c) => c.text} + name="ventilator" + value={ + YES_NO_OPTIONS.find((o) => o.value === log.bilateral_air_entry)?.text + } + onChange={(c) => + onChange({ + bilateral_air_entry: YES_NO_OPTIONS.find((o) => o.text === c.value) + ?.value, + }) + } + /> + EtCO2 (mm Hg)} + name="etco2" + onChange={(c) => onChange({ etco2: c.value })} + value={log.etco2} + start={0} + end={200} + step={1} + valueDescriptions={[ + { till: 34, text: "Low", className: "text-red-500" }, + { till: 45, text: "Normal", className: "text-green-500" }, + { text: "High", className: "text-red-500" }, + ]} + /> +
    +
    + Respiratory Support} + options={RESPIRATORY_SUPPORT_OPTIONS} + optionDisplay={(c) => c.text} + optionValue={(c) => c.value} + name="respiratory_support" + value={log.ventilator_interface} + onChange={(c) => + onChange({ + ventilator_interface: (c.value || + "UNKNOWN") as typeof log.ventilator_interface, + }) + } + /> +
    + { + RESPIRATORY_SUPPORT_OPTIONS.find( + (o) => o.value === log.ventilator_interface, + )?.content + }
    - ); - }, -); +
    + SPO2 (%)} + name="ventilator_spo2" + onChange={(c) => onChange({ ventilator_spo2: c.value })} + value={log.ventilator_spo2} + start={0} + end={100} + valueDescriptions={[ + { till: 89, text: "Low", className: "text-red-500" }, + { text: "Normal", className: "text-green-500" }, + ]} + /> +
    + ); +}; + +RespiratorySupport.meta = { + title: "Respiratory Support", + icon: "l-lungs", +} as const; + +export default RespiratorySupport; diff --git a/src/Components/LogUpdate/Sections/Vitals.tsx b/src/Components/LogUpdate/Sections/Vitals.tsx index 56dabfe7463..cf7927dab1c 100644 --- a/src/Components/LogUpdate/Sections/Vitals.tsx +++ b/src/Components/LogUpdate/Sections/Vitals.tsx @@ -5,158 +5,158 @@ import RangeFormField from "../../Form/FormFields/RangeFormField"; import TextAreaFormField from "../../Form/FormFields/TextAreaFormField"; import { DailyRoundsModel } from "../../Patient/models"; import PainChart from "../components/PainChart"; -import { logUpdateSection } from "../utils"; +import { LogUpdateSectionProps } from "../utils"; -export default logUpdateSection( - { - title: "Vitals", - icon: "l-heartbeat", - }, - ({ log, onChange }) => { - const heartbeatRhythmChoices = [ - { - label: "Regular", - value: "REGULAR", - }, - { - label: "Irregular", - value: "IRREGULAR", - }, - { - label: "Unknown", - value: null, - }, - ]; +const Vitals = ({ log, onChange }: LogUpdateSectionProps) => { + const heartbeatRhythmChoices = [ + { + label: "Regular", + value: "REGULAR", + }, + { + label: "Irregular", + value: "IRREGULAR", + }, + { + label: "Unknown", + value: null, + }, + ]; - return ( -
    -
    -

    BP (mm hg)

    + return ( +
    +
    +

    BP (mm hg)

    + + Mean Arterial Pressure:{" "} + {log.bp && log.bp.diastolic && log.bp.systolic + ? meanArterialPressure(log.bp)?.toFixed() + : "--"} + +
    + onChange({ bp: { ...log.bp, systolic: c.value } })} + value={log.bp?.systolic} + start={0} + end={250} + step={1} + valueDescriptions={[ + { till: 99, text: "Low", className: "text-red-500" }, + { till: 139, text: "Normal", className: "text-green-500" }, + { text: "High", className: "text-red-500" }, + ]} + /> + onChange({ bp: { ...log.bp, diastolic: c.value } })} + value={log.bp?.diastolic} + start={30} + end={180} + step={1} + valueDescriptions={[ + { till: 49, text: "Low", className: "text-red-500" }, + { till: 89, text: "Normal", className: "text-green-500" }, + { text: "High", className: "text-red-500" }, + ]} + /> + - Mean Arterial Pressure:{" "} - {log.bp && log.bp.diastolic && log.bp.systolic - ? meanArterialPressure(log.bp)?.toFixed() - : "--"} + SpO2 + {" %"} -
    - onChange({ bp: { ...log.bp, systolic: c.value } })} - value={log.bp?.systolic} - start={0} - end={250} - step={1} - valueDescriptions={[ - { till: 99, text: "Low", className: "text-red-500" }, - { till: 139, text: "Normal", className: "text-green-500" }, - { text: "High", className: "text-red-500" }, - ]} - /> - onChange({ bp: { ...log.bp, diastolic: c.value } })} - value={log.bp?.diastolic} - start={30} - end={180} - step={1} - valueDescriptions={[ - { till: 49, text: "Low", className: "text-red-500" }, - { till: 89, text: "Normal", className: "text-green-500" }, - { text: "High", className: "text-red-500" }, - ]} - /> - - SpO2 - {" %"} - - } - name="ventilator_spo2" - onChange={(c) => onChange({ ventilator_spo2: c.value })} - value={log.ventilator_spo2} - start={0} - end={100} - step={1} - valueDescriptions={[ - { till: 89, text: "Low", className: "text-red-500" }, - { text: "Normal", className: "text-green-500" }, - ]} - /> -
    - onChange({ temperature: `${c.value}` })} - value={Number(log.temperature)} - start={95} - end={106} - step={0.1} - valueDescriptions={[ - { till: 97.4, text: "Low", className: "text-red-500" }, - { till: 99.6, text: "Normal", className: "text-green-500" }, - { text: "High", className: "text-red-500" }, - ]} - units={[ - { label: "°F" }, - { - label: "°C", - conversionFn: (val) => ((val - 32) * 5) / 9, - inversionFn: (val) => (val * 9) / 5 + 32, - }, - ]} - /> - onChange({ resp: c.value })} - value={log.resp} - start={0} - end={150} - step={1} - valueDescriptions={[ - { till: 11, text: "Low", className: "text-red-500" }, - { till: 16, text: "Normal", className: "text-green-500" }, - { text: "High", className: "text-red-500" }, - ]} - /> - - p.map((r) => ({ - region: r.region, - scale: 0, - description: "", - })), - ) - } - onChange={(pain_scale_enhanced) => onChange({ pain_scale_enhanced })} - /> -
    - c.label} - optionValue={(c) => c.value || ""} - value={log.rhythm} - onChange={(c) => - onChange({ rhythm: c.value as DailyRoundsModel["rhythm"] }) - } - /> -
    - onChange({ rhythm_detail: c.value })} - /> -
    - ); - }, -); + } + name="ventilator_spo2" + onChange={(c) => onChange({ ventilator_spo2: c.value })} + value={log.ventilator_spo2} + start={0} + end={100} + step={1} + valueDescriptions={[ + { till: 89, text: "Low", className: "text-red-500" }, + { text: "Normal", className: "text-green-500" }, + ]} + /> +
    + onChange({ temperature: `${c.value}` })} + value={Number(log.temperature)} + start={95} + end={106} + step={0.1} + valueDescriptions={[ + { till: 97.4, text: "Low", className: "text-red-500" }, + { till: 99.6, text: "Normal", className: "text-green-500" }, + { text: "High", className: "text-red-500" }, + ]} + units={[ + { label: "°F" }, + { + label: "°C", + conversionFn: (val) => ((val - 32) * 5) / 9, + inversionFn: (val) => (val * 9) / 5 + 32, + }, + ]} + /> + onChange({ resp: c.value })} + value={log.resp} + start={0} + end={150} + step={1} + valueDescriptions={[ + { till: 11, text: "Low", className: "text-red-500" }, + { till: 16, text: "Normal", className: "text-green-500" }, + { text: "High", className: "text-red-500" }, + ]} + /> + + p.map((r) => ({ + region: r.region, + scale: 0, + description: "", + })), + ) + } + onChange={(pain_scale_enhanced) => onChange({ pain_scale_enhanced })} + /> +
    + c.label} + optionValue={(c) => c.value || ""} + value={log.rhythm} + onChange={(c) => + onChange({ rhythm: c.value as DailyRoundsModel["rhythm"] }) + } + /> +
    + onChange({ rhythm_detail: c.value })} + /> +
    + ); +}; + +Vitals.meta = { + title: "Vitals", + icon: "l-heartbeat", +} as const; + +export default Vitals; diff --git a/src/Components/LogUpdate/Sections/index.tsx b/src/Components/LogUpdate/Sections/index.tsx index 0ff10f83d80..298295ebd46 100644 --- a/src/Components/LogUpdate/Sections/index.tsx +++ b/src/Components/LogUpdate/Sections/index.tsx @@ -1,4 +1,4 @@ -import { logUpdateSection } from "../utils"; +import React from "react"; import ABGAnalysis from "./ABGAnalysis"; import BloodSugar from "./BloodSugar"; import Dialysis from "./Dialysis"; @@ -8,6 +8,8 @@ import NursingCare from "./NursingCare"; import PressureSore from "./PressureSore"; import RespiratorySupport from "./RespiratorySupport"; import Vitals from "./Vitals"; +import { LogUpdateSectionProps } from "../utils"; +import { IconName } from "../../../CAREUI/icons/CareIcon"; const LogUpdateSections = { Vitals, @@ -19,6 +21,15 @@ const LogUpdateSections = { Dialysis, PressureSore, NursingCare, -} as const satisfies Record>; +} as const satisfies Record< + string, + React.FC & { + meta: { + title: string; + description?: string; + icon?: IconName; + }; + } +>; export default LogUpdateSections; diff --git a/src/Components/LogUpdate/utils.ts b/src/Components/LogUpdate/utils.ts index 723efcd5f3a..44a535bfb76 100644 --- a/src/Components/LogUpdate/utils.ts +++ b/src/Components/LogUpdate/utils.ts @@ -1,6 +1,4 @@ -import React from "react"; import { DailyRoundsModel } from "../Patient/models"; -import { IconName } from "../../CAREUI/icons/CareIcon"; export const REACTION_OPTIONS = [ { id: 0, value: "UNKNOWN", text: "Unknown" }, @@ -46,13 +44,7 @@ export const INSULIN_INTAKE_FREQUENCY_OPTIONS = [ { id: 3, text: "Thrice a day (TD)", value: "TD" }, ] as const; -export const logUpdateSection = < - TTitle extends string, - TDescription extends string | undefined = undefined, ->( - meta: { title: TTitle; description?: TDescription; icon?: IconName }, - component: React.FC<{ - log: DailyRoundsModel; - onChange: (log: DailyRoundsModel) => void; - }>, -) => ({ ...meta, component }); +export type LogUpdateSectionProps = { + log: DailyRoundsModel; + onChange: (log: DailyRoundsModel) => void; +};