import { SegmentedControl } from '@/components/ui/segmented-control'; import { Label } from '@/components/ui/label'; import { Input } from '@/components/ui/input'; import { DatePicker } from '@/components/ui/date-picker'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { getCronDescription, type SimpleFrequency, type SimpleSchedule } from '@/lib/scheduling'; import { cn } from '@/lib/utils'; const FREQUENCY_OPTIONS: { value: SimpleFrequency; label: string }[] = [ { value: 'once', label: 'Once' }, { value: 'hourly', label: 'Hourly' }, { value: 'daily', label: 'Daily' }, { value: 'weekly', label: 'Weekly' }, { value: 'monthly', label: 'Monthly' }, ]; const WEEKDAYS: { value: number; short: string; full: string }[] = [ { value: 0, short: 'Su', full: 'Sunday' }, { value: 1, short: 'Mo', full: 'Monday' }, { value: 2, short: 'Tu', full: 'Tuesday' }, { value: 3, short: 'We', full: 'Wednesday' }, { value: 4, short: 'Th', full: 'Thursday' }, { value: 5, short: 'Fr', full: 'Friday' }, { value: 6, short: 'Sa', full: 'Saturday' }, ]; const pad2 = (n: number) => String(n).padStart(2, '0'); const numInputValue = (n: number) => (Number.isNaN(n) ? '' : n); /** A compact 0..count-1 dropdown rendered with the design-system Select. */ function UnitSelect({ value, count, ariaLabel, onValueChange }: { value: number; count: number; ariaLabel: string; onValueChange: (n: number) => void; }) { return ( onValueChange(Number(v))}> {Array.from({ length: count }, (_, i) => i).map(n => ( {pad2(n)} ))} ); } interface ScheduleSimplePanelProps { value: SimpleSchedule; onChange: (next: SimpleSchedule) => void; derivedCron: string; error: string | null; } export function ScheduleSimplePanel({ value, onChange, derivedCron, error }: ScheduleSimplePanelProps) { const patch = (partial: Partial) => onChange({ ...value, ...partial }); const toggleWeekday = (day: number, checked: boolean) => { patch({ weekdays: checked ? [...value.weekdays, day] : value.weekdays.filter(d => d !== day) }); }; const timeControl = ( Time patch({ hour })} /> : patch({ minute })} /> ); return ( value={value.frequency} options={FREQUENCY_OPTIONS} onChange={freq => patch({ frequency: freq })} ariaLabel="Schedule frequency" fullWidth /> {value.frequency === 'once' && ( Date patch({ date: date ?? null })} /> )} {value.frequency === 'weekly' && ( Days {WEEKDAYS.map(d => { const active = value.weekdays.includes(d.value); return ( toggleWeekday(d.value, !active)} className={cn( 'rounded px-2.5 py-1 font-mono text-[10px] uppercase tracking-[0.14em] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand/50', active ? 'bg-brand/10 text-brand' : 'text-stat-subtitle hover:text-stat-value', )} > {d.short} ); })} )} {value.frequency === 'monthly' && ( Day of month patch({ dayOfMonth: Number.parseInt(e.target.value, 10) })} className="w-24" /> )} {value.frequency === 'hourly' ? ( Minute patch({ minute })} /> past every hour ) : ( timeControl )} {error ? ( {error} ) : ( {getCronDescription(derivedCron)} ยท {derivedCron} )} Runs in the node's local timezone. ); }
{error}
{getCronDescription(derivedCron)} ยท {derivedCron}
Runs in the node's local timezone.