import { useState } from 'react'; import { BotLog } from '@/app/infra/http/requestParam/bots/GetBotLogsResponse'; import { httpClient } from '@/app/infra/http/HttpClient'; import { PhotoProvider } from 'react-photo-view'; import { useTranslation } from 'react-i18next'; import { Check, ChevronDown, ChevronRight, Copy } from 'lucide-react'; import { toast } from 'sonner'; import { cn } from '@/lib/utils'; import { copyToClipboard } from '@/app/utils/clipboard'; const LEVEL_STYLES: Record = { error: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400', warning: 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400', info: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400', debug: 'bg-muted text-muted-foreground', }; const SHORT_TEXT_LIMIT = 120; export function BotLogCard({ botLog, defaultExpanded = false, }: { botLog: BotLog; defaultExpanded?: boolean; }) { const { t } = useTranslation(); const baseURL = httpClient.getBaseUrl(); const [copied, setCopied] = useState(false); const [expanded, setExpanded] = useState(defaultExpanded); function copySessionId() { const text = botLog.message_session_id; copyToClipboard(text) .then((ok) => { if (ok) { setCopied(true); setTimeout(() => setCopied(false), 2000); toast.success(t('common.copySuccess')); } else { toast.error(t('common.copyFailed')); } }) .catch(() => { toast.error(t('common.copyFailed')); }); } function formatTime(timestamp: number) { const now = new Date(); const date = new Date(timestamp * 1000); const hours = date.getHours().toString().padStart(2, '0'); const minutes = date.getMinutes().toString().padStart(2, '0'); const isToday = now.toDateString() === date.toDateString(); const yesterday = new Date(now); yesterday.setDate(yesterday.getDate() - 1); const isYesterday = yesterday.toDateString() === date.toDateString(); const isThisYear = now.getFullYear() === date.getFullYear(); if (isToday) return `${hours}:${minutes}`; if (isYesterday) return `${t('bots.yesterday')} ${hours}:${minutes}`; if (isThisYear) return t('bots.dateFormat', { month: date.getMonth() + 1, day: date.getDate(), }); return t('bots.earlier'); } const needsExpand = botLog.text.length > SHORT_TEXT_LIMIT || botLog.images.length > 0; const levelStyle = LEVEL_STYLES[botLog.level.toLowerCase()] ?? LEVEL_STYLES.debug; return (
{/* Header: level badge, session id, expand toggle, timestamp */}
{/* Level badge */} {botLog.level} {/* Session ID */} {botLog.message_session_id && ( )}
{needsExpand && ( )} {formatTime(botLog.timestamp)}
{/* Log text */}
{expanded ? botLog.text : botLog.text.length > SHORT_TEXT_LIMIT ? botLog.text.slice(0, SHORT_TEXT_LIMIT) + '...' : botLog.text}
{/* Images (expanded) */} {expanded && botLog.images.length > 0 && (
{botLog.images.map((item) => ( ))}
)} {/* Image count hint (collapsed) */} {!expanded && botLog.images.length > 0 && (
{botLog.images.length} {t('bots.imagesAttached')}
)}
); }