Files
crossfade/components/status-log.tsx
T

47 lines
1.9 KiB
TypeScript

import { ScrollArea } from "@/components/ui/scroll-area";
import { Terminal } from "lucide-react";
import { useEffect, useRef } from "react";
import { motion, AnimatePresence } from "motion/react";
interface StatusLogProps {
logs: string[];
}
export function StatusLog({ logs }: StatusLogProps) {
const scrollRef = useRef<HTMLDivElement>(null);
// Auto-scroll to bottom when logs change
useEffect(() => {
if (scrollRef.current) {
scrollRef.current.scrollIntoView({ behavior: "smooth" });
}
}, [logs]);
return (
<div className="rounded-lg border bg-neutral-900/40 backdrop-blur text-gray-500 font-mono text-xs p-4 h-48 flex flex-col shadow-inner border-gray-900/30">
<div className="flex items-center gap-2 mb-2 border-b border-gray-900/50 pb-1">
<Terminal className="w-3 h-3" />
<span className="uppercase tracking-wider text-[10px] text-gray-400">System Log</span>
</div>
<ScrollArea className="flex-1">
<div className="flex flex-col gap-1 max-h-10">
<AnimatePresence initial={false}>
{logs.map((log, i) => (
<motion.div
key={`${i}-${log.substring(0, 10)}`} // Use index + content snippet for key to ensure uniqueness but allow animation
initial={{ opacity: 0, x: -10 }}
animate={{ opacity: 1, x: 0 }}
className="break-all"
>
<span className="opacity-50 mr-2 select-none">{">"}</span>
{log}
</motion.div>
))}
</AnimatePresence>
<div ref={scrollRef} />
</div>
</ScrollArea>
</div>
);
}