"use client"; import { useState, useEffect } from "react"; import { Modal } from "@/app/_components/GlobalComponents/UIElements/Modal"; import { Button } from "@/app/_components/GlobalComponents/UIElements/Button"; import { FileText, Trash2, Eye, X, RefreshCw, AlertCircle, CheckCircle } from "lucide-react"; import { useTranslations } from "next-intl"; import { getJobLogs, getLogContent, deleteLogFile, deleteAllJobLogs, getJobLogStats, } from "@/app/_server/actions/logs"; interface LogEntry { filename: string; timestamp: string; fullPath: string; size: number; dateCreated: Date; exitCode?: number; hasError?: boolean; } interface LogsModalProps { isOpen: boolean; onClose: () => void; jobId: string; jobComment?: string; preSelectedLog?: string; } export const LogsModal = ({ isOpen, onClose, jobId, jobComment, preSelectedLog, }: LogsModalProps) => { const t = useTranslations(); const [logs, setLogs] = useState([]); const [selectedLog, setSelectedLog] = useState(null); const [logContent, setLogContent] = useState(""); const [isLoadingLogs, setIsLoadingLogs] = useState(false); const [isLoadingContent, setIsLoadingContent] = useState(false); const [stats, setStats] = useState<{ count: number; totalSize: number; totalSizeMB: number; } | null>(null); const loadLogs = async () => { setIsLoadingLogs(true); try { const [logsData, statsData] = await Promise.all([ getJobLogs(jobId, false, true), getJobLogStats(jobId), ]); setLogs(logsData); setStats(statsData); } catch (error) { console.error("Error loading logs:", error); } finally { setIsLoadingLogs(false); } }; useEffect(() => { if (isOpen) { loadLogs().then(() => { if (preSelectedLog) { handleViewLog(preSelectedLog); } }); if (!preSelectedLog) { setSelectedLog(null); setLogContent(""); } } }, [isOpen, jobId, preSelectedLog]); const handleViewLog = async (filename: string) => { setIsLoadingContent(true); setSelectedLog(filename); try { const content = await getLogContent(jobId, filename); setLogContent(content); } catch (error) { console.error("Error loading log content:", error); setLogContent("Error loading log content"); } finally { setIsLoadingContent(false); } }; const handleDeleteLog = async (filename: string) => { if (!confirm(t("cronjobs.confirmDeleteLog"))) return; try { const result = await deleteLogFile(jobId, filename); if (result.success) { await loadLogs(); if (selectedLog === filename) { setSelectedLog(null); setLogContent(""); } } else { alert(result.message); } } catch (error) { console.error("Error deleting log:", error); alert("Error deleting log file"); } }; const handleDeleteAllLogs = async () => { if (!confirm(t("cronjobs.confirmDeleteAllLogs"))) return; try { const result = await deleteAllJobLogs(jobId); if (result.success) { await loadLogs(); setSelectedLog(null); setLogContent(""); } else { alert(result.message); } } catch (error) { console.error("Error deleting all logs:", error); alert("Error deleting all logs"); } }; const formatFileSize = (bytes: number): string => { if (bytes < 1024) return `${bytes} B`; if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)} KB`; return `${(bytes / (1024 * 1024)).toFixed(2)} MB`; }; const formatTimestamp = (timestamp: string): string => { const [datePart, timePart] = timestamp.split("_"); const [year, month, day] = datePart.split("-"); const [hour, minute, second] = timePart.split("-"); const date = new Date( parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hour), parseInt(minute), parseInt(second) ); return date.toLocaleString(); }; return (

{jobComment || jobId}

{stats && (

{stats.count} {t("cronjobs.logs")} • {stats.totalSizeMB} MB

)}
{logs.length > 0 && ( )}

{t("cronjobs.logFiles")}

{isLoadingLogs ? (
{t("common.loading")}...
) : logs.length === 0 ? (
{t("cronjobs.noLogsFound")}
) : ( logs.map((log) => (
handleViewLog(log.filename)} >
{log.hasError ? ( ) : log.exitCode === 0 ? ( ) : ( )} {formatTimestamp(log.timestamp)}

{formatFileSize(log.size)}

{log.exitCode !== undefined && ( Exit: {log.exitCode} )}
)) )}

{t("cronjobs.logContent")}

{isLoadingContent ? (
{t("common.loading")}...
) : selectedLog ? (
                  {logContent}
                
) : (

{t("cronjobs.selectLogToView")}

)}
); };