From d77c3cdaea9f1f05501bce37d3fa15f2502fd3c9 Mon Sep 17 00:00:00 2001 From: ruby0322 Date: Sun, 9 Aug 2026 15:02:29 +0800 Subject: [PATCH 01/10] feat(frontend): streamline review annotation UX for nursing workflow Rework dashboard/history annotation surfaces to use a clinical-first layout, consistent shared label/badge mappings, and clearer unannotated state handling so nursing review decisions are faster and less ambiguous. Co-authored-by: Cursor --- .../history-upload-annotation-modal.tsx | 235 +++++++++++------- .../history-upload-review-helpers.ts | 13 +- .../patient-day-upload-review-modal.tsx | 13 +- .../admin/_components/today-patient-row.tsx | 10 +- .../app/admin/history-overview/page.tsx | 13 +- apps/frontend/app/admin/review-fast/page.tsx | 45 ++-- apps/frontend/app/admin/review/page.tsx | 32 ++- .../lib/i18n/staff-review-label-mapping.ts | 111 +++++++++ 8 files changed, 332 insertions(+), 140 deletions(-) create mode 100644 apps/frontend/lib/i18n/staff-review-label-mapping.ts diff --git a/apps/frontend/app/admin/_components/history-upload-annotation-modal.tsx b/apps/frontend/app/admin/_components/history-upload-annotation-modal.tsx index b1ecb04..69dc712 100644 --- a/apps/frontend/app/admin/_components/history-upload-annotation-modal.tsx +++ b/apps/frontend/app/admin/_components/history-upload-annotation-modal.tsx @@ -1,12 +1,23 @@ "use client"; import Image from "next/image"; -import Link from "next/link"; import { X } from "lucide-react"; import type { StaffAnnotationItem, StaffHistoryOverviewUploadItem } from "@/lib/api/staff"; +import { + STAFF_ANNOTATION_LABEL_OPTIONS_WITH_UNMARKED, + STAFF_REVIEW_COPY, + STAFF_REVIEW_FIELD_LABELS, + annotationBadgeClass, + annotationLabelTextOrUnmarked, + screeningResultBadgeClass, + screeningResultText, + symptomAwarePriorityBadgeClass, + symptomAwarePriorityText, +} from "@/lib/i18n/staff-review-label-mapping"; +import { activeSymptomLabels, symptomsFromApiFields } from "@/lib/symptoms"; -import { historyUploadRiskLabel, type HistoryUploadDraftVerdict } from "./history-upload-review-helpers"; +import { type HistoryUploadDraftVerdict } from "./history-upload-review-helpers"; type HistoryUploadAnnotationModalProps = { upload: StaffHistoryOverviewUploadItem; @@ -27,6 +38,14 @@ export function HistoryUploadAnnotationModal({ onSave, onClose, }: HistoryUploadAnnotationModalProps) { + const symptomFlags = symptomsFromApiFields({ + symptom_pain: upload.symptom_pain, + symptom_discharge: upload.symptom_discharge, + symptom_pus: upload.symptom_pus, + symptom_cloudy_dialysate: upload.symptom_cloudy_dialysate, + }); + const symptomLabels = activeSymptomLabels(symptomFlags); + return (
@@ -45,96 +64,138 @@ export function HistoryUploadAnnotationModal({
-
- {imageUrl ? ( - {`history-preview-${upload.upload_id}`} - ) : ( -
載入影像中...
- )} +
+
+ {imageUrl ? ( + {`history-preview-${upload.upload_id}`} + ) : ( +
{STAFF_REVIEW_COPY.loadingImage}
+ )} +
-
-
-
-
年齡
-
{upload.age ?? "-"}
-
-
-
上傳時間
-
{new Date(upload.created_at).toLocaleString("zh-TW")}
-
-
-
臨床風險
-
{historyUploadRiskLabel(upload)}
-
-
-
影像判讀
-
{upload.screening_result}
-
-
-
症狀綜合
-
{upload.symptom_aware_priority}
-
-
-
機率
-
- {upload.probability !== null ? `${(upload.probability * 100).toFixed(1)}%` : "-"} -
-
-
-
Threshold
-
- {upload.threshold !== null ? upload.threshold.toFixed(2) : "-"} -
-
-
-
Model
-
{upload.model_version ?? "-"}
+ +
+
+
+
+
{STAFF_REVIEW_FIELD_LABELS.uploadedAt}
+
{new Date(upload.created_at).toLocaleString("zh-TW")}
+
+
+
{STAFF_REVIEW_FIELD_LABELS.symptomRisk}
+
+ {upload.has_high_risk_symptoms ? STAFF_REVIEW_COPY.highRisk : STAFF_REVIEW_COPY.regularRisk} +
+
+
+
+

{STAFF_REVIEW_FIELD_LABELS.symptomReported}

+
+ {symptomLabels.length > 0 ? ( + symptomLabels.map((label) => ( + + {label} + + )) + ) : ( + + {STAFF_REVIEW_COPY.noSymptomsReported} + + )} +
-
-
- - 開啟病患完整頁 - -
- -