Extract BetriebOverviewPanel, DetailPanel, FlowCanvas, FlowToolbar, StepTable, useFlowGraph hook and helpers into _components/ so page.tsx drops from 1019 to 156 LOC (under the 300 soft target). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
75 lines
2.9 KiB
TypeScript
75 lines
2.9 KiB
TypeScript
'use client'
|
||
|
||
import { SDK_FLOW_STEPS } from '../flow-data'
|
||
import { completionColor, completionLabel } from './helpers'
|
||
|
||
export function BetriebOverviewPanel() {
|
||
const betriebWithCompletion = SDK_FLOW_STEPS.filter(
|
||
s => s.package === 'betrieb' && s.completion !== undefined
|
||
).sort((a, b) => (b.completion ?? 0) - (a.completion ?? 0))
|
||
|
||
const avg = Math.round(
|
||
betriebWithCompletion.reduce((sum, s) => sum + (s.completion ?? 0), 0) /
|
||
betriebWithCompletion.length
|
||
)
|
||
|
||
return (
|
||
<div className="bg-white rounded-xl border border-slate-200 shadow-sm p-5">
|
||
<div className="flex items-center justify-between mb-4">
|
||
<div>
|
||
<h3 className="font-semibold text-slate-800">
|
||
⚙️ Betrieb — Fertigstellungsgrad
|
||
</h3>
|
||
<p className="text-xs text-slate-400 mt-0.5">
|
||
{betriebWithCompletion.length} Module bewertet · Academy & Training ausgeschlossen
|
||
</p>
|
||
</div>
|
||
<div className="text-right">
|
||
<div className="text-2xl font-bold" style={{ color: completionColor(avg) }}>
|
||
{avg}%
|
||
</div>
|
||
<div className="text-xs text-slate-400">Ø Fertigstellung</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="space-y-3">
|
||
{betriebWithCompletion.map(step => {
|
||
const pct = step.completion ?? 0
|
||
const color = completionColor(pct)
|
||
return (
|
||
<div key={step.id}>
|
||
<div className="flex items-center justify-between mb-1">
|
||
<div className="flex items-center gap-2">
|
||
<span className="text-sm font-medium text-slate-700">{step.name}</span>
|
||
<span
|
||
className="px-1.5 py-0.5 rounded text-[10px] font-medium"
|
||
style={{ background: color + '22', color }}
|
||
>
|
||
{completionLabel(pct)}
|
||
</span>
|
||
</div>
|
||
<span className="text-sm font-bold" style={{ color }}>{pct}%</span>
|
||
</div>
|
||
<div className="h-2 bg-slate-100 rounded-full overflow-hidden">
|
||
<div
|
||
className="h-full rounded-full transition-all"
|
||
style={{ width: `${pct}%`, background: color }}
|
||
/>
|
||
</div>
|
||
<div className="flex items-center gap-3 mt-1 text-[10px] text-slate-400">
|
||
{step.checkpointId && (
|
||
<span className="bg-red-50 text-red-500 px-1 rounded">{step.checkpointId}</span>
|
||
)}
|
||
<span>{step.dbTables.length > 0 ? `DB: ${step.dbTables.length} Tabellen` : 'Kein DB-Backend'}</span>
|
||
{step.ragCollections.length > 0 && (
|
||
<span className="text-green-600">RAG: {step.ragCollections.length}</span>
|
||
)}
|
||
</div>
|
||
</div>
|
||
)
|
||
})}
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|