diff --git a/app/(protected)/hse/incidents/[id]/page.tsx b/app/(protected)/hse/incidents/[id]/page.tsx index d5331b3..7edff7b 100644 --- a/app/(protected)/hse/incidents/[id]/page.tsx +++ b/app/(protected)/hse/incidents/[id]/page.tsx @@ -6,6 +6,7 @@ import { IncidentDetail, type Incident } from '@/components/incidents/incident-d import { IncidentHeader } from '@/components/incidents/incident-header' import { SimilarIncidentsPanel } from '@/components/incidents/similar-incidents-panel' import { ClosurePanel } from '@/components/incidents/closure-panel' +import { InvestigationPanel } from '@/components/incidents/investigation-panel' interface Props { params: Promise<{ id: string }> @@ -35,6 +36,17 @@ export default async function HseIncidentDetailPage({ params }: Props) { const status = (incident as { status: string }).status + const { data: investigation } = await supabase + .from('investigations') + .select(` + id, method, five_why_steps, fishbone_categories, + findings_text, root_cause_summary, alcohol_test_result, + witness_statement_refs, completed_at, + investigator:users!investigator_id (name, email) + `) + .eq('incident_id', id) + .maybeSingle() + const needsJkkp = Boolean( (incident as { is_fatality?: boolean }).is_fatality || (incident as { is_serious_bodily_injury?: boolean }).is_serious_bodily_injury || @@ -56,6 +68,10 @@ export default async function HseIncidentDetailPage({ params }: Props) {
+ {investigation && ( + + )} + {needsJkkp && (
| null + findings_text: string | null + root_cause_summary: string | null + alcohol_test_result: string | null + witness_statement_refs: string[] + completed_at: string | null + investigator: { name: string | null; email: string } | null +} + +interface Props { + investigation: Investigation +} + +const METHOD_LABELS = { + five_why: '5-Why Analysis', + fishbone: 'Fishbone (Ishikawa)', + other: 'Other Method', +} + +export function InvestigationPanel({ investigation: inv }: Props) { + const investigatorName = inv.investigator?.name ?? inv.investigator?.email ?? 'Unknown' + + return ( +
+
+

Investigation

+
+ {METHOD_LABELS[inv.method] ?? inv.method} + + {inv.completed_at ? 'Completed' : 'In Progress'} + +
+
+ +
+

+ Investigator: {investigatorName} + {inv.completed_at && ( + + ยท Completed {new Date(inv.completed_at).toLocaleDateString('en-MY', { day: 'numeric', month: 'short', year: 'numeric' })} + + )} +

+ + {/* 5-Why steps */} + {inv.method === 'five_why' && inv.five_why_steps && inv.five_why_steps.length > 0 && ( +
+

5-Why Steps

+
    + {inv.five_why_steps.map((step, i) => ( +
  1. + + {i + 1} + +
    +

    {step.why}

    + {step.answer && ( +

    {step.answer}

    + )} +
    +
  2. + ))} +
+
+ )} + + {/* Fishbone categories */} + {inv.method === 'fishbone' && inv.fishbone_categories && Object.keys(inv.fishbone_categories).length > 0 && ( +
+

Fishbone Categories

+
+ {Object.entries(inv.fishbone_categories).map(([cat, val]) => ( +
+
{cat}
+
{val}
+
+ ))} +
+
+ )} + + {/* Findings */} + {inv.findings_text && ( +
+

Findings

+

{inv.findings_text}

+
+ )} + + {/* Root cause */} + {inv.root_cause_summary && ( +
+

Root Cause

+

{inv.root_cause_summary}

+
+ )} + + {/* Alcohol test */} + {inv.alcohol_test_result && ( +
+

Alcohol Test Result

+

{inv.alcohol_test_result}

+
+ )} + + {/* Witness refs */} + {inv.witness_statement_refs && inv.witness_statement_refs.length > 0 && ( +
+

Witness Statements

+
    + {inv.witness_statement_refs.map((ref, i) => ( +
  • {ref}
  • + ))} +
+
+ )} +
+
+ ) +}