'use client' import React, { useState, useEffect, useCallback } from 'react' import Link from 'next/link' import { useParams } from 'next/navigation' import { AggregatePanel } from './_components/AggregatePanel' import { StationCard } from './_components/StationCard' import { TransferLine } from './_components/TransferLine' import type { LineDashboard, StationDashboard, TransferInfo } from '../_types' import { TRANSFER_COLORS } from '../_types' /** Number of stations per visual row before wrapping */ const STATIONS_PER_ROW = 4 export default function LineDashboardPage() { const params = useParams() const lineId = params.lineId as string const [dashboard, setDashboard] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [expandedStation, setExpandedStation] = useState(null) const fetchDashboard = useCallback(async () => { try { const res = await fetch(`/api/sdk/v1/iace/production-lines/${lineId}/dashboard`) if (!res.ok) { setError('Produktionslinie konnte nicht geladen werden') return } const json = await res.json() setDashboard(json) } catch (err) { console.error('Failed to fetch line dashboard:', err) setError('Verbindung zum Backend fehlgeschlagen') } finally { setLoading(false) } }, [lineId]) useEffect(() => { fetchDashboard() }, [fetchDashboard]) function handleToggle(stationId: string) { setExpandedStation((prev) => (prev === stationId ? null : stationId)) } if (loading) { return (
) } if (error || !dashboard) { return (

{error || 'Produktionslinie nicht gefunden'}

Zurueck zur Uebersicht
) } const sortedStations = [...dashboard.stations].sort( (a, b) => a.station.sort_order - b.station.sort_order ) // Build rows of stations for display const rows = buildStationRows(sortedStations, STATIONS_PER_ROW) return (
{/* Back link */} Alle Produktionslinien {/* Aggregate panel */} {/* Station flow */}

Stationsuebersicht

{rows.map((row, rowIndex) => ( ))}
) } /** Split sorted stations into rows of N for layout */ function buildStationRows( stations: StationDashboard[], perRow: number ): StationDashboard[][] { const rows: StationDashboard[][] = [] for (let i = 0; i < stations.length; i += perRow) { rows.push(stations.slice(i, i + perRow)) } return rows } /** Find the transfer between two adjacent station sort orders */ function findTransfer( transfers: TransferInfo[], fromOrder: number, toOrder: number ): TransferInfo | null { return ( transfers.find( (t) => t.from_station === fromOrder && t.to_station === toOrder ) || null ) } /** Default transfer for stations without an explicit transfer entry */ function defaultTransfer(from: number, to: number): TransferInfo { return { from_station: from, to_station: to, type: 'conveyor', label: '' } } interface StationRowProps { stations: StationDashboard[] transfers: TransferInfo[] expandedStation: string | null onToggle: (id: string) => void reversed: boolean } function StationRow({ stations, transfers, expandedStation, onToggle, reversed }: StationRowProps) { // Reverse even rows for a serpentine layout const ordered = reversed ? [...stations].reverse() : stations return (
{ordered.map((station, idx) => { const nextStation = ordered[idx + 1] const transfer = nextStation ? findTransfer( transfers, station.station.sort_order, nextStation.station.sort_order ) || findTransfer( transfers, nextStation.station.sort_order, station.station.sort_order ) || defaultTransfer(station.station.sort_order, nextStation.station.sort_order) : null const transferColor = transfer ? TRANSFER_COLORS[transfer.type] || TRANSFER_COLORS.conveyor : '#22C55E' return ( onToggle(station.station.id)} /> {transfer && ( )} ) })}
) }