Files
WebFTP/components/LogConsole.tsx
2026-01-19 11:04:36 +09:00

57 lines
1.9 KiB
TypeScript

import React, { useEffect, useRef } from 'react';
import { LogEntry } from '../types';
interface LogConsoleProps {
logs: LogEntry[];
}
const LogConsole: React.FC<LogConsoleProps> = ({ logs }) => {
const scrollRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (scrollRef.current) {
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
}
}, [logs]);
const getColor = (type: LogEntry['type']) => {
switch (type) {
case 'command': return 'text-blue-600';
case 'response': return 'text-green-600';
case 'error': return 'text-red-600';
case 'success': return 'text-emerald-600';
default: return 'text-slate-500';
}
};
return (
<div className="flex flex-col h-full bg-white border border-slate-300 rounded-lg overflow-hidden font-mono text-xs shadow-sm">
<div className="bg-slate-50 px-3 py-1 border-b border-slate-200 text-slate-500 text-xs font-semibold uppercase tracking-wider">
(Connection Log)
</div>
<div
ref={scrollRef}
className="flex-1 overflow-y-auto p-2 space-y-1 bg-white"
>
{logs.map((log) => (
<div key={log.id} className="flex gap-3 hover:bg-slate-50 p-0.5 rounded">
<span className="text-slate-400 shrink-0 select-none">
{new Date(log.timestamp).toLocaleTimeString()}
</span>
<span className={`${getColor(log.type)} break-all`}>
<span className="font-bold mr-2 uppercase text-[10px] opacity-70 border border-slate-200 px-1 rounded bg-slate-50 text-slate-600">
{log.type}
</span>
{log.message}
</span>
</div>
))}
{logs.length === 0 && (
<div className="text-slate-400 italic px-2"> . ...</div>
)}
</div>
</div>
);
};
export default LogConsole;