"use client"; import { useState, useEffect } from "react"; import { parseCronExpression, cronPatterns, type CronExplanation, } from "@/app/_utils/parser-utils"; import { Button } from "@/app/_components/GlobalComponents/UIElements/Button"; import { Input } from "@/app/_components/GlobalComponents/FormElements/Input"; import { Clock, Info, CheckCircle, AlertCircle, Calendar, ChevronDown, ChevronUp, Search, } from "lucide-react"; import { useLocale } from "next-intl"; interface CronExpressionHelperProps { value: string; onChange: (value: string) => void; placeholder?: string; className?: string; showPatterns?: boolean; } export const CronExpressionHelper = ({ value, onChange, placeholder = "* * * * *", className = "", showPatterns = true, }: CronExpressionHelperProps) => { const locale = useLocale(); const [explanation, setExplanation] = useState(null); const [showPatternsPanel, setShowPatternsPanel] = useState(false); const [debouncedValue, setDebouncedValue] = useState(value); const [patternSearch, setPatternSearch] = useState(""); useEffect(() => { const timer = setTimeout(() => { setDebouncedValue(value); }, 300); return () => clearTimeout(timer); }, [value]); useEffect(() => { if (debouncedValue) { const result = parseCronExpression(debouncedValue, locale); setExplanation(result); } else { setExplanation(null); } }, [debouncedValue]); const handlePatternSelect = (pattern: string) => { onChange(pattern); setShowPatternsPanel(false); }; const filteredPatterns = cronPatterns .map((category) => ({ ...category, patterns: category.patterns.filter( (pattern) => pattern.value.toLowerCase().includes(patternSearch.toLowerCase()) || pattern.description .toLowerCase() .includes(patternSearch.toLowerCase()) ), })) .filter((category) => category.patterns.length > 0); return (
onChange(e.target.value)} placeholder={placeholder} className="font-mono pr-10" />
{explanation?.isValid ? ( ) : value ? ( ) : ( )}
{explanation && (

{explanation.isValid ? explanation.humanReadable : "Invalid Expression"}

{explanation.error && (

{explanation.error}

)}
{explanation.isValid && explanation.nextRuns.length > 0 && (

Next executions:

{explanation.nextRuns.slice(0, 3).map((time, index) => (

{time}

))}
)}
)} {showPatterns && (
{showPatternsPanel && (
setPatternSearch(e.target.value)} placeholder="Search patterns..." className="pl-9" />
{filteredPatterns.map((category) => (

{category.category}

{category.patterns.map((pattern) => ( ))}
))} {filteredPatterns.length === 0 && patternSearch && (

No patterns found for "{patternSearch}"

)}
)}
)}
); }