import type { Spec } from "@json-render/core"; import { formatDisplayText, withChartDisplayTimes } from "@/shared/utils/date-time-text"; const textFields = new Set(["title", "description", "summary", "text", "label", "value", "source", "observed_at"]); const utcLabel = /UTC(?:\s*\+?0(?::00)?)?(?![\w+:-])/; const timeAxis = (value: string) => formatDisplayText(value).replace(/UTC(?:\s*\+?0(?::00)?)?(?![\w+:-])/g, "UTC+8"); const bareTime = /^(?:\d{4}-\d{2}-\d{2}[T ])?\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?$/; function displayCell(value: string, heading: string): string { return formatDisplayText(utcLabel.test(heading) && bareTime.test(value) ? `${value} UTC` : value); } /** Render display fields in UTC8 while keeping the stored spec and identifiers intact. */ export function withAnswerDisplayTimes(spec: Spec): Spec { return { ...spec, elements: Object.fromEntries(Object.entries(spec.elements).map(([id, node]) => { const props = { ...node.props }; for (const key of textFields) { if (typeof props[key] === "string") props[key] = formatDisplayText(props[key]); } if (node.type === "Table") { const columns = props.columns as string[]; props.rows = (props.rows as string[][]).map((row) => row.map((cell, index) => displayCell(cell, columns[index] ?? ""))); props.columns = columns.map(timeAxis); } if (node.type === "Chart") { Object.assign(props, withChartDisplayTimes(props as Parameters[0])); } return [id, { ...node, props }]; })) }; }