Spaces:
Sleeping
Sleeping
Download ui/src/components/QueryModal.tsx from charlesyapai/hcc-meat-coder: direct link, hf CLI and curl.
- Browser
- Download file 3.59 kB
-
https://huggingface.co/spaces/charlesyapai/hcc-meat-coder/resolve/main/ui/src/components/QueryModal.tsx
- Command line
-
hf download hf://spaces/charlesyapai/hcc-meat-coder/ui/src/components/QueryModal.tsx
-
curl -L -o QueryModal.tsx https://huggingface.co/spaces/charlesyapai/hcc-meat-coder/resolve/main/ui/src/components/QueryModal.tsx
3.59 kB
| import { Copy, FileText, X } from "lucide-react"; | |
| import { useEffect, useState } from "react"; | |
| import type { HCCCandidate } from "../lib/types"; | |
| import { cn } from "../lib/cn"; | |
| interface Props { | |
| candidate: HCCCandidate | null; | |
| onClose: () => void; | |
| } | |
| /** | |
| * Full-screen modal rendering the pre-drafted clinician chart-query. The coder | |
| * clicks Copy, pastes into their EHR provider-query tool, and edits as needed. | |
| */ | |
| export function QueryModal({ candidate, onClose }: Props) { | |
| const [copied, setCopied] = useState(false); | |
| useEffect(() => { | |
| function onKey(e: KeyboardEvent) { | |
| if (e.key === "Escape") onClose(); | |
| } | |
| window.addEventListener("keydown", onKey); | |
| return () => window.removeEventListener("keydown", onKey); | |
| }, [onClose]); | |
| useEffect(() => { | |
| if (copied) { | |
| const t = setTimeout(() => setCopied(false), 1500); | |
| return () => clearTimeout(t); | |
| } | |
| }, [copied]); | |
| if (!candidate || !candidate.query_draft) return null; | |
| async function onCopy() { | |
| if (!candidate?.query_draft) return; | |
| await navigator.clipboard.writeText(candidate.query_draft); | |
| setCopied(true); | |
| } | |
| return ( | |
| <div | |
| className="fixed inset-0 z-50 flex items-center justify-center bg-slate-900/40 p-4 dark:bg-slate-950/70" | |
| onClick={onClose} | |
| > | |
| <div | |
| className="flex max-h-[80vh] w-full max-w-2xl flex-col overflow-hidden rounded-lg border border-slate-200 bg-white shadow-xl dark:border-slate-800 dark:bg-slate-900" | |
| onClick={(e) => e.stopPropagation()} | |
| > | |
| <header className="flex items-center justify-between border-b border-slate-200 px-4 py-3 dark:border-slate-800"> | |
| <div className="flex items-center gap-2"> | |
| <FileText className="h-5 w-5 text-indigo-600 dark:text-indigo-400" /> | |
| <div> | |
| <h2 className="text-sm font-semibold text-slate-900 dark:text-slate-100"> | |
| Chart query — {candidate.hcc} | |
| </h2> | |
| <p className="text-xs text-slate-500 dark:text-slate-400"> | |
| Draft to send to the attending. Edit before sending. | |
| </p> | |
| </div> | |
| </div> | |
| <button | |
| onClick={onClose} | |
| className="rounded p-1 text-slate-400 hover:bg-slate-100 hover:text-slate-600 dark:text-slate-500 dark:hover:bg-slate-800 dark:hover:text-slate-300" | |
| aria-label="Close" | |
| > | |
| <X className="h-4 w-4" /> | |
| </button> | |
| </header> | |
| <div className="flex-1 overflow-auto p-4"> | |
| <pre className="whitespace-pre-wrap rounded border border-slate-200 bg-slate-50 p-3 font-sans text-sm leading-relaxed text-slate-800 dark:border-slate-800 dark:bg-slate-950 dark:text-slate-200"> | |
| {candidate.query_draft} | |
| </pre> | |
| </div> | |
| <footer className="flex items-center justify-between border-t border-slate-200 bg-slate-50 px-4 py-3 dark:border-slate-800 dark:bg-slate-950"> | |
| <span className="text-xs text-slate-500 dark:text-slate-400"> | |
| Research demo · review every word before sending · not a provider-query tool | |
| </span> | |
| <button | |
| onClick={onCopy} | |
| className={cn( | |
| "inline-flex items-center gap-1.5 rounded px-3 py-1.5 text-sm font-medium text-white", | |
| copied ? "bg-emerald-600" : "bg-indigo-600 hover:bg-indigo-700", | |
| )} | |
| > | |
| <Copy className="h-4 w-4" /> | |
| {copied ? "Copied" : "Copy draft"} | |
| </button> | |
| </footer> | |
| </div> | |
| </div> | |
| ); | |
| } | |