'use client'; import type { ReactElement } from 'react'; import { formatAge, type FreshnessLabel } from '@/lib/freshness/model'; /** * Rendering rules for non-current freshness states (RI-5-001). * * - `unavailable` renders an explicit failure panel — never an empty * healthy collection. * - `stale` may render last-known data, but only under a visible label * carrying source identity, snapshot version, and age. * - `partial` renders the verified parts plus an explicit list of what is * missing. */ interface RetryableNoticeProps { readonly onRetry?: () => void; readonly retryLabel?: string; } function RetryButton({ onRetry, retryLabel }: RetryableNoticeProps): ReactElement | null { if (!onRetry) return null; return ( ); } export interface UnavailableDataNoticeProps extends RetryableNoticeProps { /** What is unavailable, e.g. "Tasks". */ readonly title: string; /** Optional underlying failure detail (network message, invalidation reason). */ readonly detail?: string | null; } /** Explicit `unavailable` state. Never renders as an empty healthy collection. */ export function UnavailableDataNotice({ title, detail, onRetry, retryLabel, }: UnavailableDataNoticeProps): ReactElement { return (

{title} are unavailable

This is not an empty result — the data could not be verified from the gateway. {detail ? ` ${detail}` : ''}

); } export interface StaleDataNoticeProps extends RetryableNoticeProps { /** Provenance of the last-known snapshot being displayed. */ readonly label: FreshnessLabel; } /** * Situational-awareness banner for `stale` data: last-known data may render, * but visibly labeled with source identity, snapshot version, and age. */ export function StaleDataNotice({ label, onRetry, retryLabel, }: StaleDataNoticeProps): ReactElement { return (

Showing last-known data — it may be out of date

Source {label.source} · snapshot v{label.version} · fetched{' '} {formatAge(label.fetchedAt, Date.now())}. Verdicts derived from this data are unknown and changes are disabled until it is revalidated.

); } export interface PartialDataNoticeProps extends RetryableNoticeProps { /** Display names of the sections whose collections are unavailable. */ readonly missing: readonly string[]; } /** `partial` surface banner: verified parts render, missing parts are explicit. */ export function PartialDataNotice({ missing, onRetry, retryLabel, }: PartialDataNoticeProps): ReactElement { return (

Some data could not be loaded

{missing.join(', ')} {missing.length === 1 ? 'is' : 'are'} unavailable — sections below show an explicit unavailable state instead of an empty list. Derived verdicts remain unknown until every collection is revalidated.

); }