feat: AI triage suggestion — severity + DOSH flags pre-fill
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFDuBhMKvoWjrWT3ZnGmmr
This commit is contained in:
@@ -27,6 +27,8 @@ export function TriageForm({ incidentId, currentSeverity }: Props) {
|
||||
const [triageNotes, setTriageNotes] = useState('')
|
||||
const [saving, setSaving] = useState(false)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [aiLoading, setAiLoading] = useState(false)
|
||||
const [aiRationale, setAiRationale] = useState<string | null>(null)
|
||||
|
||||
const dosh = computeDoshObligation({
|
||||
is_fatality: isFatality,
|
||||
@@ -36,6 +38,33 @@ export function TriageForm({ incidentId, currentSeverity }: Props) {
|
||||
lost_days: null,
|
||||
})
|
||||
|
||||
async function getAiSuggestion() {
|
||||
setAiLoading(true)
|
||||
setAiRationale(null)
|
||||
try {
|
||||
const res = await fetch(`/api/incidents/${incidentId}/ai/triage-suggest`, { method: 'POST' })
|
||||
if (!res.ok) return
|
||||
const data = await res.json() as {
|
||||
severity: number
|
||||
is_fatality: boolean
|
||||
is_serious_bodily_injury: boolean
|
||||
is_dangerous_occurrence: boolean
|
||||
is_occupational_disease: boolean
|
||||
rationale: string
|
||||
}
|
||||
setSeverity(data.severity)
|
||||
setIsFatality(data.is_fatality)
|
||||
setIsSBI(data.is_serious_bodily_injury)
|
||||
setIsDO(data.is_dangerous_occurrence)
|
||||
setIsOD(data.is_occupational_disease)
|
||||
setAiRationale(data.rationale)
|
||||
} catch {
|
||||
// Non-blocking — user can still triage manually
|
||||
} finally {
|
||||
setAiLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSubmit(e: React.FormEvent) {
|
||||
e.preventDefault()
|
||||
setSaving(true)
|
||||
@@ -120,15 +149,33 @@ export function TriageForm({ incidentId, currentSeverity }: Props) {
|
||||
/>
|
||||
</div>
|
||||
|
||||
{aiRationale && (
|
||||
<div className="rounded-lg bg-purple-50 border border-purple-200 p-3">
|
||||
<p className="text-xs font-semibold text-purple-700 mb-1">AI Suggestion Rationale</p>
|
||||
<p className="text-xs text-purple-600">{aiRationale}</p>
|
||||
<p className="text-xs text-purple-400 mt-1">Fields pre-filled — review before submitting.</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{error && <p className="text-sm text-red-600">{error}</p>}
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={saving}
|
||||
className="w-full bg-blue-600 text-white rounded-lg py-2 text-sm font-semibold disabled:opacity-50"
|
||||
>
|
||||
{saving ? 'Saving…' : 'Complete Triage'}
|
||||
</button>
|
||||
<div className="flex gap-3">
|
||||
<button
|
||||
type="button"
|
||||
onClick={getAiSuggestion}
|
||||
disabled={aiLoading || saving}
|
||||
className="flex-1 bg-purple-50 text-purple-700 border border-purple-300 rounded-lg py-2 text-sm font-semibold disabled:opacity-50 hover:bg-purple-100"
|
||||
>
|
||||
{aiLoading ? 'Getting suggestion…' : 'Get AI Suggestion'}
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={saving}
|
||||
className="flex-1 bg-blue-600 text-white rounded-lg py-2 text-sm font-semibold disabled:opacity-50"
|
||||
>
|
||||
{saving ? 'Saving…' : 'Complete Triage'}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user