dental-plaque-chart
Version:
A basic implementation of a dental plaque chart, using React and Tailwind.
502 lines (501 loc) • 10.6 kB
JavaScript
import { jsxs as k, jsx as l } from "react/jsx-runtime";
import { useState as d } from "react";
import './main.css';const b = () => /* @__PURE__ */ k(
"svg",
{
xmlns: "http://www.w3.org/2000/svg",
width: "24",
height: "24",
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
strokeWidth: "2",
strokeLinecap: "round",
strokeLinejoin: "round",
className: "lucide lucide-circle-x h-full w-full aspect-square",
children: [
/* @__PURE__ */ l("circle", { cx: "12", cy: "12", r: "10" }),
/* @__PURE__ */ l("path", { d: "m15 9-6 6" }),
/* @__PURE__ */ l("path", { d: "m9 9 6 6" })
]
}
), p = "bg-rose-500 hover:bg-rose-400 disabled:bg-rose-500", m = "bg-blue-200 hover:bg-blue-300 disabled:bg-gray-300", S = ({
pieceModel: s,
size: e = "100%",
onClickSurface: t = () => {
},
onDiscardPiece: n = () => {
},
disabled: r = !1
}) => /* @__PURE__ */ k("div", { className: "relative aspect-square", style: { width: e, flex: "1 1 0%" }, children: [
!r && /* @__PURE__ */ l(
"div",
{
onClick: () => n(s.id),
className: "absolute right-0 top-0 z-50 w-1/4 aspect-square cursor-pointer",
children: /* @__PURE__ */ l(b, {})
}
),
/* @__PURE__ */ l("div", { className: "w-full aspect-square p-1.5", children: s.present ? /* @__PURE__ */ k("div", { className: "w-full aspect-square grid grid-cols-2 rotate-45", children: [
/* @__PURE__ */ l(
g,
{
surface: "front",
isMarked: s.surfaces.front,
onClickSurface: t,
disabled: r
}
),
/* @__PURE__ */ l(
g,
{
surface: "right",
isMarked: s.surfaces.right,
onClickSurface: t,
disabled: r
}
),
/* @__PURE__ */ l(
g,
{
surface: "left",
isMarked: s.surfaces.left,
onClickSurface: t,
disabled: r
}
),
/* @__PURE__ */ l(
g,
{
surface: "back",
isMarked: s.surfaces.back,
onClickSurface: t,
disabled: r
}
)
] }) : /* @__PURE__ */ l("div", { className: `w-full aspect-square ${r ? "text-gray-700" : "text-blue-800"}`, children: /* @__PURE__ */ l(b, {}) }) })
] }), g = ({
isMarked: s,
surface: e,
onClickSurface: t = () => {
},
disabled: n = !1
}) => {
const r = `${s ? p : m} ${n ? "" : "hover:scale-110 transition active:scale-95"}`;
let a = "border border-black ";
const f = () => {
n || t(e, !s);
};
switch (e) {
case "front":
a += "rounded-tl-full";
break;
case "back":
a += "rounded-br-full";
break;
case "left":
a += "rounded-bl-full";
break;
case "right":
a += "rounded-tr-full";
break;
}
return /* @__PURE__ */ l(
"button",
{
disabled: n,
onClick: f,
className: `${a} ${r}`,
"aria-disabled": n,
role: "button",
type: "button",
tabIndex: 0
}
);
}, h = ({ teeth: s, onClickSurface: e = () => {
}, onDiscardPiece: t = () => {
}, disabled: n = !1 }) => /* @__PURE__ */ l("div", { className: "flex border", children: s.map((r) => /* @__PURE__ */ l(S, { pieceModel: r, onClickSurface: (a, f) => {
e(r.id, a, f);
}, onDiscardPiece: t, disabled: n }, r.id)) }), $ = ({ chart: s, disabled: e = !1 }) => {
const t = (r, a, f, c) => r.map((o) => {
if (o.id === a) {
const u = { ...o };
return u.surfaces[f] = c, u;
} else
return o;
}), n = (r, a) => r.map((f) => {
if (f.id === a) {
const c = { ...f };
return c.present = !c.present, c;
} else
return f;
});
return /* @__PURE__ */ k("div", { className: "w-full grid grid-cols-1 sm:grid-cols-2", children: [
/* @__PURE__ */ l(h, { teeth: s.getModel().quadrant_1, onDiscardPiece: (r) => {
s._listeners.setGroup1((a) => n(a, r));
}, onClickSurface: (r, a, f) => s._listeners.setGroup1((c) => t(c, r, a, f)), disabled: e }),
/* @__PURE__ */ l(h, { teeth: s.getModel().quadrant_2, onDiscardPiece: (r) => {
s._listeners.setGroup2((a) => n(a, r));
}, onClickSurface: (r, a, f) => s._listeners.setGroup2((c) => t(c, r, a, f)), disabled: e }),
/* @__PURE__ */ l(h, { teeth: s.getModel().quadrant_4, onDiscardPiece: (r) => {
s._listeners.setGroup4((a) => n(a, r));
}, onClickSurface: (r, a, f) => s._listeners.setGroup4((c) => t(c, r, a, f)), disabled: e }),
/* @__PURE__ */ l(h, { teeth: s.getModel().quadrant_3, onDiscardPiece: (r) => {
s._listeners.setGroup3((a) => n(a, r));
}, onClickSurface: (r, a, f) => s._listeners.setGroup3((c) => t(c, r, a, f)), disabled: e })
] });
}, N = [
{
id: "18",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "17",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "16",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "15",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "14",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "13",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "12",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "11",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
}
], P = [
{
id: "21",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "22",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "23",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "24",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "25",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "26",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "27",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "28",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
}
], w = [
{
id: "31",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "32",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "33",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "34",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "35",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "36",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "37",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "38",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
}
], G = [
{
id: "48",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "47",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "46",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "45",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "44",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "43",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "42",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
},
{
id: "41",
present: !0,
surfaces: {
back: !1,
front: !1,
left: !1,
right: !1
}
}
], j = (s) => {
const [e, t] = d(() => {
var i;
return JSON.parse(JSON.stringify(((i = s == null ? void 0 : s.model) == null ? void 0 : i.quadrant_1) ?? N));
}), [n, r] = d(() => {
var i;
return JSON.parse(JSON.stringify(((i = s == null ? void 0 : s.model) == null ? void 0 : i.quadrant_2) ?? P));
}), [a, f] = d(() => {
var i;
return JSON.parse(JSON.stringify(((i = s == null ? void 0 : s.model) == null ? void 0 : i.quadrant_3) ?? w));
}), [c, o] = d(() => {
var i;
return JSON.parse(JSON.stringify(((i = s == null ? void 0 : s.model) == null ? void 0 : i.quadrant_4) ?? G));
}), u = {
quadrant_1: e,
quadrant_2: n,
quadrant_3: a,
quadrant_4: c
};
return {
getModel: () => u,
getPresentDentalPieces: () => q(u),
getMarkedSurfaces: () => _(u),
getPlaqueRatio: () => x(_(u), q(u)),
_listeners: { setGroup1: t, setGroup2: r, setGroup3: f, setGroup4: o }
};
}, q = (s) => s.quadrant_1.filter((e) => e.present).length + s.quadrant_2.filter((e) => e.present).length + s.quadrant_3.filter((e) => e.present).length + s.quadrant_4.filter((e) => e.present).length, _ = (s) => s.quadrant_1.filter((e) => e.present).reduce((e, t) => (t.surfaces.front && ++e, t.surfaces.back && ++e, t.surfaces.right && ++e, t.surfaces.left && ++e, e), 0) + s.quadrant_2.filter((e) => e.present).reduce((e, t) => (t.surfaces.front && ++e, t.surfaces.back && ++e, t.surfaces.right && ++e, t.surfaces.left && ++e, e), 0) + s.quadrant_3.filter((e) => e.present).reduce((e, t) => (t.surfaces.front && ++e, t.surfaces.back && ++e, t.surfaces.right && ++e, t.surfaces.left && ++e, e), 0) + s.quadrant_4.filter((e) => e.present).reduce((e, t) => (t.surfaces.front && ++e, t.surfaces.back && ++e, t.surfaces.right && ++e, t.surfaces.left && ++e, e), 0), x = (s, e) => s / e;
export {
$ as DentalPlaqueChart,
j as useDentalPlaqueChart
};