diff --git a/docs/miscellaneous/MELD.md b/docs/Utilities/MELD.md similarity index 100% rename from docs/miscellaneous/MELD.md rename to docs/Utilities/MELD.md diff --git a/docs/miscellaneous/cockcroft-gault-eq.md b/docs/Utilities/cockcroft-gault-eq.md similarity index 100% rename from docs/miscellaneous/cockcroft-gault-eq.md rename to docs/Utilities/cockcroft-gault-eq.md diff --git a/src/app/(calculators)/calculate/[section]/[id]/renderCalc.tsx b/src/app/(calculators)/calculate/[section]/[id]/renderCalc.tsx index c759bbf..fd203b0 100644 --- a/src/app/(calculators)/calculate/[section]/[id]/renderCalc.tsx +++ b/src/app/(calculators)/calculate/[section]/[id]/renderCalc.tsx @@ -12,13 +12,22 @@ export default function RenderCalculator({section, id} : {section:string, id:str const calculator = CalculatorRegistry[section].calculators.find(e => e.id === id); const [form, setForm] = useState>({}); const [value, setValue] = useState(""); - function handleDataChange(key:string, value:string){ - setForm(prev => { - return { - ...prev, - [key]:value - } - }); + function handleDataChange(key:string, value:string, type: "number" | "string" | boolean){ + if(type === "number"){ + setForm(prev => { + return { + ...prev, + [key]:Number(value) + } + }); + }else{ + setForm(prev => { + return { + ...prev, + [key]:value + } + }); + } } const [showResult, setResultStatus] = useState(false); const [result, setResult] = useState({ diff --git a/src/app/utils/Input.tsx b/src/app/utils/Input.tsx index f4c3385..3c7e274 100644 --- a/src/app/utils/Input.tsx +++ b/src/app/utils/Input.tsx @@ -33,7 +33,7 @@ export default function InputComponent({id, type, inputOptions, min, max, requir }else{ setError(""); setErrorStatus(false); - handleDataChange !== undefined ? handleDataChange(id, e.target.value) : null; + handleDataChange !== undefined ? handleDataChange(id, e.target.value, type) : null; } }} /> diff --git a/src/app/utils/calculators/Emergency/TIMI_score.ts b/src/app/utils/calculators/Emergency/TIMI_score.ts new file mode 100644 index 0000000..8656075 --- /dev/null +++ b/src/app/utils/calculators/Emergency/TIMI_score.ts @@ -0,0 +1,119 @@ +import { Calculator, Input, Interpretation, Values } from "../types"; + +const parameters:Input[] = [ + { + id:"age", + name:"Age", + placeholder:"Enter the age", + type:"number", + required:true + }, + { + id:"isCAD", + name:"Known Coronary Artery Disease (stenosis >= 50%)", + placeholder:"Whether the patient has a known CAD with more than 50% stenosis", + type:"checkbox" + }, + { + id:"cadRiskFactors", + name:"CAD Risk Factors", + placeholder:"Whether the patient has 3 or more than 3 CAD Risk Factors (Family history of CAD, Hypertension, Hypercholesterolemia, Diabetes, Smoker)", + type:"checkbox" + }, + { + id:"asa", + name:"ASA use in the last 7 days", + placeholder:"Whether the patient has taken Aspirin in the last 7 days", + type:"checkbox" + }, + { + id:"angina", + name:"Severe Angina", + placeholder:"Whether the patient had severe angina (>= 2 episodes w/in 24 hrs", + type:"checkbox" + }, + { + id:"stchanges", + name:"ST changes (>= 0.5mm)", + placeholder:"Whether the patient has ST changes of more than or equal to 0.5mm in EKG", + type:"checkbox" + }, + { + id:"biomarkers", + name:"Elevated Serum cardiac biomarkers", + placeholder:"Whether the patient has Elevated Serum cardiac biomarkers (Troponin levels, creatine kinase etc)", + type:"checkbox" + } +]; + +export const TIMI:Calculator = { + id:"timi-score", + name:"Thrombolysis in Myocardial Infarction (TIMI) Score for UA and NSTEMI", + desc:"TIMI (Thrombolysis in Myocardial Infarction) Score is a validated, 7-point clinical tool used to predict the 14-day mortality and ischemic events in patients with unstable angina or NSTEMI", + inputs:parameters, + calc_func:(values : Values):number => { + const age = values.age as number; + const isCAD = values.isCAD as boolean; + const cad = values.cadRiskFactors as boolean; + const asa = values.asa as boolean; + const angina = values.angina as boolean; + const stchanges = values.stchanges as boolean; + const biomarkers = values.biomarkers as boolean; + var score = 0; + if(age >= 65){ + score++; + } + if(isCAD){ + score++; + } + if(cad){ + score++; + } + if(asa){ + score++; + } + if(angina){ + score++; + } + if(stchanges){ + score++; + } + if(biomarkers){ + score++; + } + return score; + }, + interpret_func:(score : number):Interpretation => { + if(score === 0 || score === 1){ + return { + level:"none", + message:"Patient is at 5% risk at 14 days of: all-cause mortality, new or recurrent MI, or severe recurrent ischemia requiring urgent revascularization." + } + }else if(score === 2){ + return { + level:"low", + message:"Patient is at 8% risk at 14 days of: all-cause mortality, new or recurrent MI, or severe recurrent ischemia requiring urgent revascularization." + } + }else if(score === 3){ + return{ + level:"moderate", + message:"Patient is at 13% risk at 14 days of: all-cause mortality, new or recurrent MI, or severe recurrent ischemia requiring urgent revascularization." + } + }else if(score === 4){ + return{ + level:"moderate", + message:"Patient is at 20% risk at 14 days of: all-cause mortality, new or recurrent MI, or severe recurrent ischemia requiring urgent revascularization." + } + }else if(score === 5){ + return{ + level:"moderate", + message:"Patient is at 26% risk at 14 days of: all-cause mortality, new or recurrent MI, or severe recurrent ischemia requiring urgent revascularization." + } + }else{ + return{ + level:"severe", + message:"Patient is at 41% risk at 14 days of: all-cause mortality, new or recurrent MI, or severe recurrent ischemia requiring urgent revascularization." + } + } + } +}; \ No newline at end of file diff --git a/src/app/utils/calculators/General Cardiology/MAP.ts b/src/app/utils/calculators/General Cardiology/MAP.ts new file mode 100644 index 0000000..930213b --- /dev/null +++ b/src/app/utils/calculators/General Cardiology/MAP.ts @@ -0,0 +1,64 @@ +import { Calculator, Input, Interpretation, Values } from "../types"; + +const parameters : Input[] = [ + { + id:"sbp", + name:"Systolic Blood Pressure", + placeholder:"Enter the Systolic Blood Pressure in mmHg", + type:"number", + required:true, + min:0 + }, + { + id:"dbp", + name:"Diastolic Blood Pressure", + placeholder:"Enter the Disatolic Blood Pressure in mmHg", + type:"number", + required:true, + min:0 + } +] + +export const MAP : Calculator = { + id:"map", + name:"Mean Arterial Pressure", + desc:"Mean Arterial Pressure (MAP) is the average arterial pressure throughout one cardiac cycle, that is, systole and diastole. It is influenced by Cardiac Output (CO) and Systemic Vascular Resistance (SVR) and used to check whether the vital organs of the body are well-perfused or not.", + inputs:parameters, + calc_func:(values:Values):number => { + const sbp = values.sbp as number; + const dbp = values.dbp as number; + const pp = sbp - dbp; + const map = dbp + (pp/3); + return Math.floor(map); + }, + interpret_func:(map : number):Interpretation => { + if(map < 60){ + return { + level:"severe", + message:"Vital organs are poorly perfused" + } + }else if(map >= 60 && map < 65){ + return{ + level:"moderate", + message:"Vital organs are borderline perfused" + } + }else if(map >= 65 && map < 70){ + return{ + level:"moderate", + message:"Vital organs are adequately perfused", + + } + }else if(map >= 70 && map < 100){ + return{ + level:'none', + message:"Vital organs are well perfused" + } + }else{ + return{ + level:"severe", + message:"Vital organs are hyper perfused", + diagnosis:"Possibly due to hypertension" + } + } + } +} \ No newline at end of file diff --git a/src/app/utils/calculators/miscellaneous/MELD.ts b/src/app/utils/calculators/Utilities/MELD.ts similarity index 100% rename from src/app/utils/calculators/miscellaneous/MELD.ts rename to src/app/utils/calculators/Utilities/MELD.ts diff --git a/src/app/utils/calculators/miscellaneous/cockcroft-gault-eq.ts b/src/app/utils/calculators/Utilities/cockcroft-gault-eq.ts similarity index 100% rename from src/app/utils/calculators/miscellaneous/cockcroft-gault-eq.ts rename to src/app/utils/calculators/Utilities/cockcroft-gault-eq.ts diff --git a/src/app/utils/calculators/miscellaneous/test.ts b/src/app/utils/calculators/Utilities/test.ts similarity index 100% rename from src/app/utils/calculators/miscellaneous/test.ts rename to src/app/utils/calculators/Utilities/test.ts diff --git a/src/app/utils/calculators/registry.ts b/src/app/utils/calculators/registry.ts index d5dbf38..7b1d112 100644 --- a/src/app/utils/calculators/registry.ts +++ b/src/app/utils/calculators/registry.ts @@ -1,8 +1,28 @@ -import { cockcroftGault } from "./miscellaneous/cockcroft-gault-eq"; -import { IMPACT } from "./transplantation/IMPACT"; +import { cockcroftGault } from "./Utilities/cockcroft-gault-eq"; +import { IMPACT } from "./Transplantation/IMPACT"; import { Section } from "./types"; -import { MELD } from "./miscellaneous/MELD"; +import { MELD } from "./Utilities/MELD"; +import { MAP } from "./General Cardiology/MAP"; +import { TIMI } from "./Emergency/TIMI_score"; export const CalculatorRegistry : Record = { + generalCardiology:{ + id:"generalCardiology", + displayName:"General Cardiology", + textColor:"#ccc", + svg:"", + calculators:[ + MAP + ] + }, + emergency:{ + id:"emergency", + displayName:"Emergency", + textColor:"#ccc", + svg:"", + calculators:[ + TIMI + ] + }, transplantation:{ id:"transplantation", displayName:"Transplantation", @@ -13,8 +33,8 @@ export const CalculatorRegistry : Record = { ] }, miscellaneous:{ - id:"miscellaneous", - displayName:"Miscellaneous", + id:"utilities", + displayName:"Utilities", textColor:"#ccc", svg:"", calculators:[