Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 24 additions & 44 deletions apps/dashboard/src/routes/analysis.$transactionId.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
import {
ArrowLeft,
Check,
X,
XCircle,
X,
AlertCircle,
AlertTriangle,
CheckCircle2,
Expand Down Expand Up @@ -155,9 +154,7 @@
{met === null && <AlertCircle className="w-3.5 h-3.5" />}
</div>
<span className="text-sm text-foreground flex-1">{label}</span>
{met === true && <CheckCircle2 className="w-5 h-5 text-green-500 flex-shrink-0" />}
{met === false && <XCircle className="w-5 h-5 text-red-500 flex-shrink-0" />}
{met === null && <AlertCircle className="w-5 h-5 text-amber-500 flex-shrink-0" />}
<span className={cn('text-[10px] font-bold uppercase tracking-wide px-2 py-0.5 rounded-md flex-shrink-0', style.text, style.bg)}>{style.statusLabel}</span>
{isEditing && (
<span className="text-xs text-muted-foreground">Toggle</span>
)}
Expand Down Expand Up @@ -276,7 +273,7 @@
const id = transactionId;
return () => {
if (submittedRef.current) return;
const elapsed = Math.floor((Date.now() - enteredAtRef.current) / 1000);

Check warning on line 276 in apps/dashboard/src/routes/analysis.$transactionId.tsx

View workflow job for this annotation

GitHub Actions / Dashboard Build & Test

The ref value 'enteredAtRef.current' will likely have changed by the time this effect cleanup function runs. If this ref points to a node rendered by React, copy 'enteredAtRef.current' to a variable inside the effect, and use that variable in the cleanup function
if (elapsed > 0) {
addReviewTimeMutation.mutate({ id, seconds: elapsed });
}
Expand Down Expand Up @@ -456,6 +453,7 @@
const displayData = isEditing ? editedData : effectiveRequest;
const hasUnmetCriteria = (effectiveRequest.criteria || []).some((c: { met: boolean | null }) => c.met !== true);
const isLowConfidence = effectiveRequest.status === 'ready' && effectiveRequest.confidence < LOW_CONFIDENCE_THRESHOLD;
const canSubmit = effectiveRequest.status !== 'draft' && !!effectiveRequest.clinicalSummary?.trim();

Comment on lines +456 to 457
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Guard handleSubmit with canSubmit.
Line 456 introduces the new gate, but handleSubmit can still be triggered programmatically even when canSubmit is false. Add an early return to enforce the gate in code, not just UI.

✅ Suggested guard near handleSubmit
const handleSubmit = () => {
  if (!canSubmit || isSubmittingRef.current) return;
  isSubmittingRef.current = true;
  setShowSubmissionOverlay(true);
};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/dashboard/src/routes/analysis`.$transactionId.tsx around lines 456 -
457, handleSubmit isn't protected by the new canSubmit guard and can be invoked
programmatically; update the handleSubmit function to early-return when
!canSubmit or when isSubmittingRef.current is true, then set
isSubmittingRef.current = true and call setShowSubmissionOverlay(true) only
after passing the guard (refer to canSubmit, handleSubmit, isSubmittingRef, and
setShowSubmissionOverlay to locate the change).

return (
<div className="p-6 space-y-6 animate-fade-in">
Expand Down Expand Up @@ -602,8 +600,8 @@
</button>
<button
onClick={handleSubmit}
disabled={isSubmitting || showSubmissionOverlay}
className="px-5 py-2.5 text-sm font-semibold bg-teal text-white rounded-xl hover:bg-teal/90 disabled:opacity-70 transition-all shadow-teal flex items-center gap-2 min-w-[160px] justify-center click-effect-primary"
disabled={!canSubmit || isSubmitting || showSubmissionOverlay}
className="px-5 py-2.5 text-sm font-semibold bg-teal text-white rounded-xl hover:bg-teal/90 disabled:opacity-50 disabled:cursor-not-allowed transition-all shadow-teal flex items-center gap-2 min-w-[160px] justify-center click-effect-primary"
>
Comment on lines 602 to 605
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Disabled header submit button lacks a reason.
Line 603 disables the top submit button but keeps the label “Confirm & Submit,” which is inconsistent with the sidebar’s explicit guidance. Consider mirroring the “Process request before submitting” message or adding a tooltip.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/dashboard/src/routes/analysis`.$transactionId.tsx around lines 602 -
605, The top submit button currently uses the same label regardless of disabled
state; update the button rendering in the component that uses
onClick={handleSubmit} and disabled={!canSubmit || isSubmitting ||
showSubmissionOverlay} so that when !canSubmit (or when disabled for the same
conditions) its visible label mirrors the sidebar guidance (e.g., "Process
request before submitting") or add an accessible tooltip/aria-describedby
explaining the reason; ensure you reference the same props/flags (canSubmit,
isSubmitting, showSubmissionOverlay) and keep the existing click/disabled logic
and styling while only changing the displayed text or adding a tooltip/aria
attribute for accessibility.

{(isSubmitting || showSubmissionOverlay) ? (
<>
Expand Down Expand Up @@ -684,7 +682,7 @@
<div className="flex items-center justify-between mb-5">
<h2 className="font-bold text-foreground flex items-center gap-2">
<FileText className="w-5 h-5 text-teal" />
PA Form Data
Clinical Details
</h2>
<span className="flex items-center gap-1.5 px-3 py-1 rounded-full bg-teal/10 text-teal text-xs font-semibold">
<Sparkles className="w-3 h-3" />
Expand All @@ -693,44 +691,19 @@
</div>

<div className="grid grid-cols-2 gap-x-8">
<EditableField
label="Patient Name"
value={request.patient.name}
onChange={() => {}}
isEditing={false}
/>
<EditableField
label="Date of Birth"
value={request.patient.dob}
onChange={() => {}}
isEditing={false}
/>
<EditableField
label="Member ID"
value={request.patient.memberId}
onChange={() => {}}
isEditing={false}
mono
/>
<EditableField
label="Diagnosis Code"
value={`${displayData.diagnosisCode} - ${displayData.diagnosis}`}
<EditableField
label="Diagnosis Code"
value={`${displayData.diagnosisCode} - ${displayData.diagnosis}`}
onChange={(v) => {
const parts = v.split(' - ');
setEditedData({
...editedData,
setEditedData({
...editedData,
diagnosisCode: parts[0] || '',
diagnosis: parts[1] || ''
});
}}
Comment on lines +694 to 704
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Avoid lossy split for Diagnosis Code.
Line 698 splits on ' - ', which truncates diagnoses that contain the delimiter and clears the second field when users type only one side. Split once and preserve the rest.

🔧 Safer parse to preserve hyphens
-  const parts = v.split(' - ');
-  setEditedData({
-    ...editedData,
-    diagnosisCode: parts[0] || '',
-    diagnosis: parts[1] || ''
-  });
+  const [code, ...rest] = v.split(' - ');
+  setEditedData({
+    ...editedData,
+    diagnosisCode: (code ?? '').trim(),
+    diagnosis: rest.join(' - ').trim()
+  });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<EditableField
label="Diagnosis Code"
value={`${displayData.diagnosisCode} - ${displayData.diagnosis}`}
onChange={(v) => {
const parts = v.split(' - ');
setEditedData({
...editedData,
setEditedData({
...editedData,
diagnosisCode: parts[0] || '',
diagnosis: parts[1] || ''
});
}}
<EditableField
label="Diagnosis Code"
value={`${displayData.diagnosisCode} - ${displayData.diagnosis}`}
onChange={(v) => {
const [code, ...rest] = v.split(' - ');
setEditedData({
...editedData,
diagnosisCode: (code ?? '').trim(),
diagnosis: rest.join(' - ').trim()
});
}}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/dashboard/src/routes/analysis`.$transactionId.tsx around lines 694 -
704, The current onChange handler for EditableField (label "Diagnosis Code")
uses v.split(' - ') which loses parts when the diagnosis contains the delimiter
and clears fields if only one side is typed; change the parse to split only once
(e.g., find the first ' - ' and take left part as diagnosisCode and the rest as
diagnosis) so you preserve any additional hyphens and avoid clearing the second
field, then call setEditedData(...) with diagnosisCode and diagnosis derived
from that single-split logic (refer to the EditableField onChange,
setEditedData, and displayData.diagnosisCode/diagnosis symbols).

isEditing={isEditing}
/>
<EditableField
label="Procedure Code"
value={request.procedureCode}
onChange={() => {}}
isEditing={false}
/>
<EditableField
label="Service Date"
value={displayData.serviceDate || ''}
Expand Down Expand Up @@ -793,12 +766,14 @@
</div>
<p className={cn(
'text-center text-sm font-medium mt-4 p-3 rounded-lg',
displayConfidence(effectiveRequest.confidence) >= 80 ? 'bg-success/10 text-success' :
displayConfidence(effectiveRequest.confidence) >= 60 ? 'bg-warning/10 text-warning' :
effectiveRequest.status === 'draft' ? 'bg-secondary text-muted-foreground' :
displayConfidence(effectiveRequest.confidence) >= 80 ? 'bg-success/10 text-success' :
displayConfidence(effectiveRequest.confidence) >= 60 ? 'bg-warning/10 text-warning' :
'bg-destructive/10 text-destructive'
)}>
{displayConfidence(effectiveRequest.confidence) >= 80 ? 'High confidence — ready for submission' :
displayConfidence(effectiveRequest.confidence) >= 60 ? 'Medium confidence — review recommended' :
{effectiveRequest.status === 'draft' ? 'Awaiting AI analysis — click Process to begin' :
displayConfidence(effectiveRequest.confidence) >= 80 ? 'High confidence — ready for submission' :
displayConfidence(effectiveRequest.confidence) >= 60 ? 'Medium confidence — review recommended' :
'Low confidence — manual review required'}
</p>
</div>
Expand Down Expand Up @@ -867,14 +842,19 @@
<div className="space-y-3">
<button
onClick={handleSubmit}
disabled={isSubmitting || showSubmissionOverlay}
className="w-full px-5 py-3.5 text-sm font-semibold bg-teal text-white rounded-xl hover:bg-teal/90 disabled:opacity-70 transition-all shadow-teal flex items-center justify-center gap-2 click-effect-primary"
disabled={!canSubmit || isSubmitting || showSubmissionOverlay}
className="w-full px-5 py-3.5 text-sm font-semibold bg-teal text-white rounded-xl hover:bg-teal/90 disabled:opacity-50 disabled:cursor-not-allowed transition-all shadow-teal flex items-center justify-center gap-2 click-effect-primary"
>
{(isSubmitting || showSubmissionOverlay) ? (
<>
<LoadingSpinner size="sm" className="border-white border-t-transparent" />
<span>Submitting to athenahealth...</span>
</>
) : !canSubmit ? (
<>
<AlertCircle className="w-4 h-4" />
Process request before submitting
</>
) : (
<>
<Send className="w-4 h-4" />
Expand Down
Loading