"use client"; import type { RecapRangeMode, RecapTimelineSegment } from "@/lib/recap/types"; import { computeWidths, formatDuration, formatTime, LABEL_MIN_WIDTH_PCT, normalizeTimelineSegments, SEGMENT_MIN_WIDTH_PCT, TIMELINE_COLORS, } from "@/components/recap/timelineRender"; import { useI18n } from "@/lib/i18n/useI18n"; type Props = { rangeStart: string; rangeEnd: string; segments: RecapTimelineSegment[]; locale: string; hasData?: boolean; loading?: boolean; rangeMode?: RecapRangeMode; }; export default function RecapFullTimeline({ rangeStart, rangeEnd, segments, locale, hasData = false, loading = false, rangeMode, }: Props) { const { t } = useI18n(); const startMs = new Date(rangeStart).getTime(); const endMs = new Date(rangeEnd).getTime(); const totalMs = Math.max(1, endMs - startMs); const normalized = hasData ? normalizeTimelineSegments(segments, startMs, endMs) : []; const widths = computeWidths(normalized, totalMs, SEGMENT_MIN_WIDTH_PCT); const rangeSuffix = rangeMode === "shift" ? t("recap.range.shiftCurrent") : rangeMode === "yesterday" ? t("recap.range.yesterday") : rangeMode === "custom" ? t("recap.range.custom") : t("recap.range.24h"); const titleText = `${t("recap.timeline.title")} · ${rangeSuffix}`; return (
{titleText}
{loading ? (
) : null} {!loading && !hasData ? (
{t("recap.timeline.noData")}
) : null} {!loading && hasData ? (
{normalized.map((segment, index) => { const widthPct = widths[index] ?? 0; const typeLabel = segment.type === "production" ? t("recap.timeline.type.production") : segment.type === "mold-change" ? t("recap.timeline.type.moldChange") : segment.type === "macrostop" ? t("recap.timeline.type.macrostop") : segment.type === "microstop" || segment.type === "slow-cycle" ? t("recap.timeline.type.microstop") : t("recap.timeline.type.idle"); const title = `${typeLabel} · ${formatTime(segment.startMs, locale)}-${formatTime( segment.endMs, locale )} · ${formatDuration(segment.startMs, segment.endMs)}${segment.label ? ` · ${segment.label}` : ""}`; return (
{widthPct > LABEL_MIN_WIDTH_PCT ? segment.label : ""}
); })}
) : null}
); }