Added bookmark and past used in /calculators
This commit is contained in:
@@ -4,8 +4,7 @@ import InputComponent from "@/app/utils/Input";
|
|||||||
import Input from "@/app/utils/Input";
|
import Input from "@/app/utils/Input";
|
||||||
import Result from "@/app/utils/Result";
|
import Result from "@/app/utils/Result";
|
||||||
import { CalculatorRegistry } from "@/app/utils/calculators/registry";
|
import { CalculatorRegistry } from "@/app/utils/calculators/registry";
|
||||||
import { Interpretation } from "@/app/utils/calculators/types";
|
import { Interpretation, pastUsed } from "@/app/utils/calculators/types";
|
||||||
import { Metadata } from "next";
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
export default function RenderCalculator({section, id} : {section:string, id:string}){
|
export default function RenderCalculator({section, id} : {section:string, id:string}){
|
||||||
@@ -53,8 +52,25 @@ export default function RenderCalculator({section, id} : {section:string, id:str
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setResultStatus(true);
|
setResultStatus(true);
|
||||||
const calculatedValue = calculator.calc_func(form);
|
const calculatedValue = calculator.calc_func(form);
|
||||||
|
const interpretation = calculator.interpret_func(calculatedValue)
|
||||||
setValue(calculatedValue);
|
setValue(calculatedValue);
|
||||||
setResult(calculator.interpret_func(calculatedValue));
|
setResult(interpretation);
|
||||||
|
const values : string = localStorage.getItem("pastUsed") || "[]";
|
||||||
|
const valuesobj : pastUsed[] = JSON.parse(values);
|
||||||
|
valuesobj.push(
|
||||||
|
{
|
||||||
|
calcInfo:{
|
||||||
|
section:section,
|
||||||
|
id:id,
|
||||||
|
name:calculator.name
|
||||||
|
},
|
||||||
|
value: calculatedValue,
|
||||||
|
interpretation: interpretation,
|
||||||
|
formData: form,
|
||||||
|
unit:calculator.unit
|
||||||
|
}
|
||||||
|
);
|
||||||
|
localStorage.setItem("pastUsed", JSON.stringify(valuesobj));
|
||||||
}}>
|
}}>
|
||||||
<div className="card max-w-auto bg-white bg-base-100 shadow-sm">
|
<div className="card max-w-auto bg-white bg-base-100 shadow-sm">
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
@@ -74,6 +90,8 @@ export default function RenderCalculator({section, id} : {section:string, id:str
|
|||||||
interpretation={result}
|
interpretation={result}
|
||||||
calculated_value={value}
|
calculated_value={value}
|
||||||
unit={calculator.unit ?? ""}
|
unit={calculator.unit ?? ""}
|
||||||
|
section={undefined}
|
||||||
|
id={undefined}
|
||||||
/>
|
/>
|
||||||
</h3> : null}
|
</h3> : null}
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,7 +1,44 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
|
import { pastUsed } from "@/app/utils/calculators/types";
|
||||||
|
import Result from "@/app/utils/Result";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
export default function Calculators(){
|
export default function Calculators(){
|
||||||
|
const [pastUsedObj, setPastUsedObj] = useState<pastUsed[]>([]);
|
||||||
|
const [index, setIndex] = useState<number>(0)
|
||||||
|
useEffect(() => {
|
||||||
|
const pastUsed : string = localStorage.getItem("pastUsed") || "[]";
|
||||||
|
setPastUsedObj(JSON.parse(pastUsed));
|
||||||
|
}, [])
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<><h1>hi</h1></>
|
<>
|
||||||
)
|
<div className="flex flex-col justify-center mt-2">
|
||||||
|
{
|
||||||
|
pastUsedObj.length !== 0 ?
|
||||||
|
<Result id={pastUsedObj[index].calcInfo.id}
|
||||||
|
section={pastUsedObj[index].calcInfo.section}
|
||||||
|
interpretation={pastUsedObj[index].interpretation}
|
||||||
|
calculated_value={pastUsedObj[index].value}
|
||||||
|
unit={pastUsedObj[index].unit}/>
|
||||||
|
: <h1>Empty</h1>
|
||||||
|
}
|
||||||
|
<div className="join mt-2 self-center">
|
||||||
|
<button className="join-item btn bg-[#ed1b24] text-black" onClick={() => {
|
||||||
|
if(index !== 0 ){
|
||||||
|
setIndex(index - 1);
|
||||||
|
}
|
||||||
|
}}>«</button>
|
||||||
|
<button className="join-item btn bg-white text-black">Result {index + 1}</button>
|
||||||
|
<button className="join-item btn bg-[#ed1b24] text-black" onClick={() => {
|
||||||
|
if(index < pastUsedObj.length - 1){
|
||||||
|
setIndex(index+1);
|
||||||
|
}
|
||||||
|
}}>»</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ export default function Navbar({navbarToggle}: Props){
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="navbar-center flex items-center justify-center">
|
<div className="navbar-center flex items-center justify-center">
|
||||||
<Link href="/" className="flex items-center gap-2 w-fit">
|
<Link href="/calculators" className="flex items-center gap-2 w-fit">
|
||||||
<img src="/calcforcardiac_logo.png" className="h-9 md:h-10 w-auto object-contain" />
|
<img src="/calcforcardiac_logo.png" className="h-9 md:h-10 w-auto object-contain" />
|
||||||
<span className="text-lg font-semibold">
|
<span className="text-lg font-semibold">
|
||||||
CalcForCardiac
|
CalcForCardiac
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
import { Interpretation } from "./calculators/types";
|
import { Calculator, Interpretation } from "./calculators/types";
|
||||||
|
import { CalculatorRegistry } from "./calculators/registry";
|
||||||
export default function Result({interpretation, calculated_value, unit} : {interpretation:Interpretation, calculated_value:string | number, unit:string
|
export default function Result({interpretation, calculated_value, unit, id, section} : {
|
||||||
|
interpretation:Interpretation,
|
||||||
|
calculated_value:string | number,
|
||||||
|
unit:string | undefined,
|
||||||
|
id: string | undefined,
|
||||||
|
section:string | undefined
|
||||||
}){
|
}){
|
||||||
var {level, message, diagnosis, advice} = interpretation;
|
var {level, message, diagnosis, advice} = interpretation;
|
||||||
var levelClass = "";
|
var levelClass = "";
|
||||||
|
const calc : Calculator | undefined = id && section ? CalculatorRegistry[section].calculators.find(e => e.id === id) : undefined;
|
||||||
if(level === "none" || level === "low"){
|
if(level === "none" || level === "low"){
|
||||||
levelClass = "bg-success";
|
levelClass = "bg-success";
|
||||||
}else if(level === "moderate"){
|
}else if(level === "moderate"){
|
||||||
@@ -16,6 +22,7 @@ export default function Result({interpretation, calculated_value, unit} : {inter
|
|||||||
return(
|
return(
|
||||||
<div className={`card max-w-auto ${levelClass} bg-base-100 shadow-sm mt-5 ${levelClass}`}>
|
<div className={`card max-w-auto ${levelClass} bg-base-100 shadow-sm mt-5 ${levelClass}`}>
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
|
{calc ? <h2>{calc.name}</h2> : null}
|
||||||
<h2 className="card-title self-center">Calculated Score/Value: {calculated_value} {unit}</h2>
|
<h2 className="card-title self-center">Calculated Score/Value: {calculated_value} {unit}</h2>
|
||||||
<p>{message}</p>
|
<p>{message}</p>
|
||||||
{diagnosis ? <p>Diagnosis: {diagnosis}</p> : null}
|
{diagnosis ? <p>Diagnosis: {diagnosis}</p> : null}
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
import { Calculator } from "./calculators/types";
|
import { Calculator } from "./calculators/types";
|
||||||
|
|
||||||
export default function Section({sectionName, Calculators, id} : {sectionName:string, Calculators:Calculator[], id:string}){
|
export default function Section({sectionName, Calculators, id} : {sectionName:string, Calculators:Calculator[], id:string}){
|
||||||
|
const [bookmarks, setBookmarks] = useState<string[]>([]);
|
||||||
|
useEffect(() => {
|
||||||
|
const bookmarkedStr:string = localStorage.getItem("bookmarks") || "[]";
|
||||||
|
const bookmarkedObj : string[] = JSON.parse(bookmarkedStr);
|
||||||
|
setBookmarks(bookmarkedObj);
|
||||||
|
}, [])
|
||||||
return(
|
return(
|
||||||
<li>
|
<li>
|
||||||
<details>
|
<details>
|
||||||
@@ -8,10 +17,87 @@ export default function Section({sectionName, Calculators, id} : {sectionName:st
|
|||||||
<ul>
|
<ul>
|
||||||
{Calculators.map((e) => {
|
{Calculators.map((e) => {
|
||||||
return(
|
return(
|
||||||
<li key={e.id}>
|
<li className="flex items-center w-full" key={e.id}>
|
||||||
<a href={`/calculate/${id}/${e.id}`}>
|
<div className="flex items-start w-full">
|
||||||
{e.name}
|
|
||||||
</a>
|
<a
|
||||||
|
href={`/calculate/${id}/${e.id}`}
|
||||||
|
className="flex-1"
|
||||||
|
>
|
||||||
|
{e.name}
|
||||||
|
</a>
|
||||||
|
<button
|
||||||
|
className="shrink-0"
|
||||||
|
onClick={() => {
|
||||||
|
const bookmarks:string = localStorage.getItem("bookmarks") || "[]";
|
||||||
|
var bookmarksArr:string[] = JSON.parse(bookmarks);
|
||||||
|
if(bookmarksArr.indexOf(id) !== -1){
|
||||||
|
bookmarksArr = bookmarksArr.filter(e => e !== id);
|
||||||
|
}else{
|
||||||
|
bookmarksArr.push(id)
|
||||||
|
}
|
||||||
|
setBookmarks(bookmarksArr);
|
||||||
|
localStorage.setItem("bookmarks", JSON.stringify(bookmarksArr));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
|
||||||
|
{ bookmarks.find(e => e === id) ? <svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
className="w-6 h-6"
|
||||||
|
viewBox="0 0 256 256"
|
||||||
|
>
|
||||||
|
<g
|
||||||
|
fill="#ed1b24"
|
||||||
|
fillRule="nonzero"
|
||||||
|
stroke="none"
|
||||||
|
strokeWidth="1"
|
||||||
|
strokeLinecap="butt"
|
||||||
|
strokeLinejoin="miter"
|
||||||
|
strokeMiterlimit="10"
|
||||||
|
strokeDasharray=""
|
||||||
|
strokeDashoffset="0"
|
||||||
|
fontFamily="none"
|
||||||
|
fontWeight="none"
|
||||||
|
fontSize="none"
|
||||||
|
textAnchor="inherit"
|
||||||
|
style={{ mixBlendMode: "normal" }}
|
||||||
|
>
|
||||||
|
<g transform="scale(5.12,5.12)">
|
||||||
|
<path d="M37,48c-0.17578,0 -0.34766,-0.04687 -0.50391,-0.13672l-11.49609,-6.70703l-11.49609,6.70703c-0.30859,0.17969 -0.69141,0.18359 -1,0.00391c-0.3125,-0.17969 -0.50391,-0.50781 -0.50391,-0.86719v-44c0,-0.55078 0.44922,-1 1,-1h24c0.55469,0 1,0.44922 1,1v44c0,0.35938 -0.19141,0.6875 -0.50391,0.86719c-0.15234,0.08984 -0.32422,0.13281 -0.49609,0.13281z" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg> : <svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
viewBox="0 0 256 256"
|
||||||
|
className="w-6 h-6"
|
||||||
|
>
|
||||||
|
<g
|
||||||
|
fill="#ed1b24"
|
||||||
|
fillRule="nonzero"
|
||||||
|
stroke="none"
|
||||||
|
strokeWidth="1"
|
||||||
|
strokeLinecap="butt"
|
||||||
|
strokeLinejoin="miter"
|
||||||
|
strokeMiterlimit="10"
|
||||||
|
strokeDasharray=""
|
||||||
|
strokeDashoffset="0"
|
||||||
|
fontFamily="none"
|
||||||
|
fontWeight="none"
|
||||||
|
fontSize="none"
|
||||||
|
textAnchor="inherit"
|
||||||
|
style={{ mixBlendMode: "normal" }}
|
||||||
|
>
|
||||||
|
<g transform="scale(5.12,5.12)">
|
||||||
|
<path d="M12.8125,2c-0.47656,0.08984 -0.82031,0.51172 -0.8125,1v44c-0.00391,0.35938 0.1875,0.69141 0.49609,0.87109c0.30859,0.18359 0.69141,0.18359 1.00391,0.00391l11.5,-6.71875l11.5,6.71875c0.3125,0.17969 0.69531,0.17969 1.00391,-0.00391c0.30859,-0.17969 0.5,-0.51172 0.49609,-0.87109v-44c0,-0.55078 -0.44922,-1 -1,-1h-24c-0.03125,0 -0.0625,0 -0.09375,0c-0.03125,0 -0.0625,0 -0.09375,0zM14,4h22v41.25l-10.5,-6.125c-0.30859,-0.17969 -0.69141,-0.17969 -1,0l-10.5,6.125z" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ const parameters:Input[] = [
|
|||||||
|
|
||||||
export const TIMI:Calculator = {
|
export const TIMI:Calculator = {
|
||||||
id:"timi-score",
|
id:"timi-score",
|
||||||
name:"Thrombolysis in Myocardial Infarction (TIMI) Score for UA and NSTEMI",
|
name:"Thrombolysis in Myocardial Infarction (TIMI) Score",
|
||||||
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",
|
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,
|
inputs:parameters,
|
||||||
calc_func:(values : Values):number => {
|
calc_func:(values : Values):number => {
|
||||||
|
|||||||
@@ -39,5 +39,15 @@ export interface Section {
|
|||||||
svg:string,
|
svg:string,
|
||||||
calculators:Calculator[]
|
calculators:Calculator[]
|
||||||
}
|
}
|
||||||
|
export interface pastUsed {
|
||||||
|
calcInfo : {
|
||||||
|
section: string,
|
||||||
|
id: string,
|
||||||
|
name: string
|
||||||
|
},
|
||||||
|
value: string | number,
|
||||||
|
interpretation: Interpretation,
|
||||||
|
formData: object,
|
||||||
|
unit: string | undefined
|
||||||
|
}
|
||||||
export type Values = Record<string, string | number | boolean >;
|
export type Values = Record<string, string | number | boolean >;
|
||||||
|
|||||||
Reference in New Issue
Block a user