import { memo } from 'react'; import { useAppTranslation } from '@features/localization/renderer'; import type { RuntimeDisplayState, TeamRuntimeDisplayRow } from './teamRuntimeDisplayRows'; interface LiveRuntimeStatusSectionProps { rows: readonly TeamRuntimeDisplayRow[]; } const STATE_CLASS_NAMES: Record = { running: 'border-emerald-500/25 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300', starting: 'border-sky-500/25 bg-sky-500/10 text-sky-700 dark:text-sky-300', waiting: 'border-amber-500/25 bg-amber-500/10 text-amber-700 dark:text-amber-300', degraded: 'border-rose-500/25 bg-rose-500/10 text-rose-700 dark:text-rose-300', stopped: 'border-zinc-500/25 bg-zinc-500/10 text-zinc-700 dark:text-zinc-300', unknown: 'border-zinc-500/20 bg-zinc-500/5 text-zinc-600 dark:text-zinc-400', }; export const LiveRuntimeStatusSection = memo(function LiveRuntimeStatusSection({ rows, }: LiveRuntimeStatusSectionProps): React.JSX.Element | null { const { t } = useAppTranslation('team'); if (rows.length === 0) return null; return (
{t('liveRuntimeStatus.title')}

{t('liveRuntimeStatus.description')}

{rows.map((row) => (
{row.memberName}
{row.stateReason}
{t(`liveRuntimeStatus.states.${row.state}`)}
{t('liveRuntimeStatus.source', { source: row.source })} {row.runtimeModel ? ( {row.runtimeModel} ) : null} {row.laneKind ? ( {t('liveRuntimeStatus.lane', { lane: row.laneKind })} ) : null} {row.pidLabel ? ( {row.pidLabel} ) : null} {row.updatedAt ? ( {t('liveRuntimeStatus.updated', { value: formatRuntimeUpdatedAt(row.updatedAt), })} ) : null}
))}
); }); function formatRuntimeUpdatedAt(value: string): string { const timestamp = Date.parse(value); if (!Number.isFinite(timestamp)) return value; const secondsAgo = Math.max(0, Math.round((Date.now() - timestamp) / 1000)); if (secondsAgo < 60) return `${secondsAgo}s ago`; const minutesAgo = Math.round(secondsAgo / 60); if (minutesAgo < 60) return `${minutesAgo}m ago`; return new Date(timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', }); }