'use client' import type { PipelineStatus, PipelineRun, SystemStats, DockerStats, WoodpeckerStatus, TabType } from '../types' import { ProgressBar } from './helpers' interface OverviewTabProps { pipelineStatus: PipelineStatus | null pipelineHistory: PipelineRun[] systemStats: SystemStats | null dockerStats: DockerStats | null woodpeckerStatus: WoodpeckerStatus | null triggeringWoodpecker: boolean triggerWoodpeckerPipeline: () => Promise setActiveTab: (tab: TabType) => void } export function OverviewTab({ pipelineStatus, pipelineHistory, systemStats, dockerStats, woodpeckerStatus, triggeringWoodpecker, triggerWoodpeckerPipeline, setActiveTab, }: OverviewTabProps) { return (
{/* Woodpecker CI Status - Prominent */} {/* Status Cards */}
Gitea Status

{pipelineStatus?.gitea_connected ? 'Verbunden' : 'Nicht verbunden'}

http://macmini:3003

Pipeline Runs

{pipelineStatus?.total_runs || 0}

{pipelineStatus?.successful_runs || 0} erfolgreich

Container

{dockerStats?.running_containers || 0}

von {dockerStats?.total_containers || 0} laufend

Letztes Update

{pipelineStatus?.last_sbom_update ? new Date(pipelineStatus.last_sbom_update).toLocaleDateString('de-DE') : 'Nie'}

{pipelineStatus?.last_sbom_update ? new Date(pipelineStatus.last_sbom_update).toLocaleTimeString('de-DE') : '-'}

{/* System Resources */} {systemStats && (

Server Ressourcen ({systemStats.hostname})

CPU 80 ? 'text-red-600' : 'text-slate-900'}`}> {systemStats.cpu.usage_percent.toFixed(1)}%
RAM 80 ? 'text-red-600' : 'text-slate-900'}`}> {systemStats.memory.usage_percent.toFixed(1)}%
Disk 80 ? 'text-red-600' : 'text-slate-900'}`}> {systemStats.disk.usage_percent.toFixed(1)}%
)} {/* Recent Pipeline Runs */} {pipelineHistory.length > 0 && (

Letzte Pipeline Runs

{pipelineHistory.slice(0, 5).map((run) => (

{run.workflow || 'SBOM Pipeline'}

{run.branch} - {run.commit_sha.substring(0, 8)}

{run.status === 'success' ? 'Erfolgreich' : run.status === 'failed' ? 'Fehlgeschlagen' : run.status === 'running' ? 'Laeuft...' : run.status}

{new Date(run.started_at).toLocaleString('de-DE')}

))}
)}
) } // ============================================================================ // Woodpecker Overview Card (sub-component) // ============================================================================ function WoodpeckerOverviewCard({ woodpeckerStatus, triggeringWoodpecker, triggerWoodpeckerPipeline, setActiveTab, }: { woodpeckerStatus: WoodpeckerStatus | null triggeringWoodpecker: boolean triggerWoodpeckerPipeline: () => Promise setActiveTab: (tab: TabType) => void }) { const latestPipeline = woodpeckerStatus?.pipelines?.[0] const isOnline = woodpeckerStatus?.status === 'online' const latestStatus = latestPipeline?.status const borderClass = isOnline ? latestStatus === 'success' ? 'border-green-300 bg-green-50' : latestStatus === 'failure' || latestStatus === 'error' ? 'border-red-300 bg-red-50' : latestStatus === 'running' ? 'border-blue-300 bg-blue-50' : 'border-slate-300 bg-slate-50' : 'border-red-300 bg-red-50' const iconBgClass = isOnline ? latestStatus === 'success' ? 'bg-green-100' : latestStatus === 'failure' || latestStatus === 'error' ? 'bg-red-100' : 'bg-blue-100' : 'bg-red-100' return (

Woodpecker CI

{isOnline ? 'Online' : 'Offline'}
{latestPipeline && (

Pipeline #{latestPipeline.number}: {' '} {latestStatus} {' '}auf {latestPipeline.branch}

)}
{/* Failed steps preview */} {latestPipeline?.steps?.some(s => s.state === 'failure') && (

Fehlgeschlagene Steps:

{latestPipeline.steps.filter(s => s.state === 'failure').map((step, i) => ( {step.name} ))}
)}
) }