diff --git a/apps/Frontend/src/components/claims/claim-edit-modal.tsx b/apps/Frontend/src/components/claims/claim-edit-modal.tsx
index 0a5c665..aa4bb2f 100644
--- a/apps/Frontend/src/components/claims/claim-edit-modal.tsx
+++ b/apps/Frontend/src/components/claims/claim-edit-modal.tsx
@@ -16,6 +16,12 @@ import {
import { formatDateToHumanReadable } from "@/utils/dateUtils";
import React, { useState } from "react";
import { ClaimStatus, ClaimWithServiceLines } from "@repo/db/types";
+import {
+ safeParseMissingTeeth,
+ splitTeeth,
+ ToothChip,
+ toStatusLabel,
+} from "./tooth-ui";
type ClaimEditModalProps = {
isOpen: boolean;
@@ -223,6 +229,65 @@ export default function ClaimEditModal({
+ {/* Missing Teeth */}
+
+
Missing Teeth
+
+
+ Status:{" "}
+ {toStatusLabel((claim as any).missingTeethStatus)}
+
+
+ {/* Only show details when the user chose "Specify Missing" */}
+ {(claim as any).missingTeethStatus === "Yes_missing" &&
+ (() => {
+ const map = safeParseMissingTeeth((claim as any).missingTeeth);
+ const { permanent, primary } = splitTeeth(map);
+ const hasAny = permanent.length > 0 || primary.length > 0;
+
+ if (!hasAny) {
+ return (
+
+ No specific teeth marked as missing.
+
+ );
+ }
+
+ return (
+
+ {permanent.length > 0 && (
+
+
+ Permanent
+
+
+ {permanent.map((t) => (
+
+ ))}
+
+
+ )}
+ {primary.length > 0 && (
+
+
+ Primary
+
+
+ {primary.map((t) => (
+
+ ))}
+
+
+ )}
+
+ );
+ })()}
+
+ {(claim as any).missingTeethStatus === "endentulous" && (
+
Patient is edentulous.
+ )}
+
+
{/* Actions */}
+ {/* Missing Teeth */}
+
+
Missing Teeth
+
+
+ Status:{" "}
+ {toStatusLabel((claim as any).missingTeethStatus)}
+
+
+ {/* Only show details when the user chose "Specify Missing" */}
+ {(claim as any).missingTeethStatus === "Yes_missing" &&
+ (() => {
+ const map = safeParseMissingTeeth(
+ (claim as any).missingTeeth
+ );
+ const { permanent, primary } = splitTeeth(map);
+ const hasAny = permanent.length > 0 || primary.length > 0;
+
+ if (!hasAny) {
+ return (
+
+ No specific teeth marked as missing.
+
+ );
+ }
+
+ return (
+
+ {permanent.length > 0 && (
+
+
+ Permanent
+
+
+ {permanent.map((t) => (
+
+ ))}
+
+
+ )}
+ {primary.length > 0 && (
+
+
+ Primary
+
+
+ {primary.map((t) => (
+
+ ))}
+
+
+ )}
+
+ );
+ })()}
+
+ {(claim as any).missingTeethStatus === "endentulous" && (
+
Patient is edentulous.
+ )}
+
+
{/* Claim Files (metadata) */}
diff --git a/apps/Frontend/src/components/claims/tooth-ui.tsx b/apps/Frontend/src/components/claims/tooth-ui.tsx
index d0d84ab..34f54f5 100644
--- a/apps/Frontend/src/components/claims/tooth-ui.tsx
+++ b/apps/Frontend/src/components/claims/tooth-ui.tsx
@@ -99,3 +99,57 @@ export function TeethGrid({
);
}
+
+
+// ——— Missing Teeth helpers for claim-view and edit modal———
+type MissingMap = Record;
+
+export function toStatusLabel(s?: string) {
+ if (!s) return "Unknown";
+ if (s === "No_missing") return "No Missing";
+ if (s === "endentulous") return "Edentulous";
+ if (s === "Yes_missing") return "Specify Missing";
+ // best-effort prettify
+ return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();
+}
+
+export function safeParseMissingTeeth(raw: unknown): MissingMap {
+ if (!raw) return {};
+ if (typeof raw === "string") {
+ try {
+ const parsed = JSON.parse(raw);
+ if (parsed && typeof parsed === "object") return parsed as MissingMap;
+ } catch {}
+ return {};
+ }
+ if (typeof raw === "object") return raw as MissingMap;
+ return {};
+}
+
+const PERM = new Set(Array.from({ length: 32 }, (_, i) => `T_${i + 1}`));
+const PRIM = new Set(Array.from("ABCDEFGHIJKLMNOPQRST").map((ch) => `T_${ch}`));
+
+export function splitTeeth(map: MissingMap) {
+ const permanent: Array<{ name: string; v: ToothVal }> = [];
+ const primary: Array<{ name: string; v: ToothVal }> = [];
+ for (const [k, v] of Object.entries(map)) {
+ if (!v) continue;
+ if (PERM.has(k)) permanent.push({ name: k, v });
+ else if (PRIM.has(k)) primary.push({ name: k, v });
+ }
+ // stable, human-ish order
+ permanent.sort((a, b) => Number(a.name.slice(2)) - Number(b.name.slice(2)));
+ primary.sort((a, b) => a.name.localeCompare(b.name));
+ return { permanent, primary };
+}
+
+export function ToothChip({ name, v }: { name: string; v: ToothVal }) {
+ return (
+
+ {name.replace("T_", "")}
+
+ {v}
+
+
+ );
+}