'use client'; /** * CronPreview * * Read-only sibling of `CronScheduler`. Renders a human-readable summary * for a cron expression plus an optional list of upcoming run times. * * Unlike `SchedulePreview` (which lives inside the editor and pulls its * state from `CronSchedulerProvider`), `CronPreview` is fully standalone: * pass a value, get a preview. Use it in dashboards, list rows, and * read-only schedule views where the heavier editor is not needed. * * @example * * * @example * */ import * as React from 'react'; import { Calendar } from 'lucide-react'; import { cn } from '@djangocfg/ui-core/lib'; import { humanizeCron } from '../utils/cron-humanize'; import { getNextRuns, formatNextRun } from '../utils/cron-next-runs'; import { isValidCron } from '../utils/cron-parser'; export interface CronPreviewProps extends Omit, 'children'> { /** Cron expression (standard 5-field format, e.g. `"0 9 * * 1-5"`). */ value: string; /** Optional heading shown above the summary. */ title?: string; /** * Number of upcoming run times to display. * `0` hides the list. Defaults to `5`. */ nextRuns?: number; /** Show the raw cron expression alongside the summary. Defaults to `true`. */ showExpression?: boolean; /** Base date for computing next runs. Defaults to "now". */ referenceDate?: Date; /** Additional CSS classes for the outer container. */ className?: string; } export function CronPreview({ value, title, nextRuns = 5, showExpression = true, referenceDate, className, ...rest }: CronPreviewProps) { const trimmed = (value ?? '').trim(); const valid = isValidCron(trimmed); const summary = React.useMemo(() => humanizeCron(trimmed), [trimmed]); const runs = React.useMemo(() => { if (!valid || nextRuns <= 0) return []; return getNextRuns(trimmed, nextRuns, referenceDate ?? new Date()); }, [trimmed, valid, nextRuns, referenceDate]); if (!valid) { return (
Invalid cron expression: {trimmed || '(empty)'}
); } return (
{/* Header */}
{showExpression && ( {trimmed} )}
{/* Next runs */} {runs.length > 0 && (

Next {runs.length === 1 ? 'run' : `${runs.length} runs`}

    {runs.map((run, i) => (
  1. {i + 1} {formatNextRun(run)}
  2. ))}
)}
); } export default CronPreview;