import { TriangleAlert } from 'lucide-react'; import { useTranslations } from 'next-intl'; import type { ReactNode } from 'react'; import { ErrorInline } from '@/components/layout/error'; import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; import { Badge } from '@/components/ui/badge'; import { type PagesGitHubReleaseSource, type PagesRemoteURLSource, type PagesSourceRevision, } from '@/lib/services/openflare'; import { cn, formatDateTime } from '@/lib/utils'; function revisionSummary( revision: PagesSourceRevision | undefined, empty: string, ) { if (!revision) return empty; const label = revision.label?.trim(); const short = revision.revision.slice(0, 12); return label ? `${label} · ${short}` : short; } function formatOptionalTime(value?: string | null, empty = '—') { return value ? formatDateTime(value) : empty; } function SourceMetaRow({ label, children, mono, }: { label: string; children: ReactNode; mono?: boolean; }) { return (
{label}
{children}
); } export function RemoteSourceDetails({ source, }: { source: PagesRemoteURLSource; }) { const t = useTranslations('pages.source'); return (
{source.remote_url || '—'}
{source.allow_insecure ? t('allowInsecure') : t('verifyCert')} {formatOptionalTime(source.last_synced_at, t('neverSynced'))}
{revisionSummary(source.last_applied, t('noRecord'))}
{source.last_error ? : null}
); } export function GitHubSourceDetails({ source, }: { source: PagesGitHubReleaseSource; }) { const t = useTranslations('pages.source'); const attentionRevision = source.sync_status === 'attention' ? source.last_seen : undefined; const releaseLabel = source.release_selector === 'latest' ? t('latestReleaseLabel') : t('pinnedTagLabel', { tag: source.release_tag || t('tagMissing') }); return (
{attentionRevision ? ( {t('assetChangedTitle')}

{t('assetChangedDesc')}

{attentionRevision.revision}
) : null}
{source.github_repository} {source.asset_name} {releaseLabel}
{source.release_selector === 'latest' ? ( <> {source.auto_update_enabled ? t('autoUpdateOn') : t('autoUpdateOff')} {t('intervalMinutes', { count: source.check_interval_minutes, })} {formatOptionalTime(source.next_check_at, t('waitingSchedule'))} {formatOptionalTime(source.last_checked_at, t('neverChecked'))} ) : ( {formatOptionalTime(source.last_checked_at, t('neverChecked'))} )} {revisionSummary(source.last_seen, t('noRecord'))} {revisionSummary(source.last_applied, t('noRecord'))} {formatOptionalTime(source.last_synced_at, t('neverSynced'))}
{source.last_error ? : null}
); }