+ {FLOW_NODES.map((node, idx) => {
+ const status = getNodeStatus(node.id, activeStage, isResolved)
+ const isActive = status === 'active'
+ const isDone = status === 'done' || status === 'resolved'
+ const isLast = idx === FLOW_NODES.length - 1
+
+ return (
+
+
+ {/* 龍蝦 */}
+
+ {isActive && (
+
+
+
+ )}
+
+ {/* 卡片 */}
+
+
+ {node.label}
+
+
+
{!isLast && (
)}
@@ -193,4 +308,96 @@ export function FlowPipeline({ activeStage, isResolved = false, tooltips }: Flow
)
}
+// ── Style D: P3 時間軸 ────────────────────────────────────────────────────────
+
+function PipelineStyleD({ activeStage, isResolved }: { activeStage: FlowStage; isResolved: boolean }) {
+ const color = isResolved ? '#22C55E' : SEV_COLOR.P3
+ const activeIdx = getActiveIndex(activeStage)
+
+ return (
+
+
+
+ {FLOW_NODES.map((node, idx) => {
+ const status = getNodeStatus(node.id, activeStage, isResolved)
+ const isActive = status === 'active'
+ const isDone = status === 'done' || status === 'resolved'
+ const isLast = idx === FLOW_NODES.length - 1
+ const isNextActive = idx === activeIdx - 1
+
+ return (
+
+
+
+ {isActive && (
+
+
+
+ )}
+
+
+
+ {node.label}
+
+
+ {!isLast && (
+
+ {/* Active 前的虛線用 SVG 做流動動畫 */}
+ {isNextActive ? (
+
+ ) : (
+
+ )}
+
+ )}
+
+ )
+ })}
+
+
+ )
+}
+
+// ── Main Component ────────────────────────────────────────────────────────────
+
+export function FlowPipeline({ activeStage, isResolved = false, severity = 'P3', tooltips: _tooltips }: FlowPipelineProps) {
+ // 2026-04-02 Claude Code: severity → pipeline style mapping
+ // P0=StyleA(脈衝光波) P1=StyleB(進度條) P2=StyleC(卡片步驟) P3=StyleD(時間軸)
+ if (isResolved || severity === 'P3') {
+ return
+ }
+ if (severity === 'P0') {
+ return
+ }
+ if (severity === 'P1') {
+ return
+ }
+ // P2
+ return
+}
+
export default FlowPipeline
diff --git a/apps/web/src/components/incident/incident-card.tsx b/apps/web/src/components/incident/incident-card.tsx
index e4441ac6a..c04551f87 100644
--- a/apps/web/src/components/incident/incident-card.tsx
+++ b/apps/web/src/components/incident/incident-card.tsx
@@ -292,7 +292,7 @@ export function IncidentCard({ incident, decision, onApprovalChange }: IncidentC