Newer
Older
cortex-hub / ui / client-app / src / components / InteractionLog.js
import React, { useState, useEffect, useRef } from "react";
import ReactMarkdown from 'react-markdown';

const InteractionLog = ({ logs }) => {
  const [expandedLogs, setExpandedLogs] = useState({});
  const [containerHeight, setContainerHeight] = useState("500px");

  const scrollRef = useRef(null);

  // Auto-size based on window height
  useEffect(() => {
    const updateHeight = () => {
      const windowHeight = window.innerHeight;
      const offset = 300; // adjust this based on layout
      setContainerHeight(`${windowHeight - offset}px`);
    };

    updateHeight();
    window.addEventListener("resize", updateHeight);
    return () => window.removeEventListener("resize", updateHeight);
  }, []);

  // Auto-scroll to bottom on new logs
  useEffect(() => {
    if (scrollRef.current) {
      scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
    }
  }, [logs]);

  const toggleExpand = (index) => {
    setExpandedLogs((prev) => ({
      ...prev,
      [index]: !prev[index],
    }));
  };

  const getPreviewText = (message, maxLength = 200) => {
    if (message.length <= maxLength) return message;
    return message.slice(0, maxLength) + "…";
  };

  return (
    <div
      ref={scrollRef}
      className="overflow-y-auto p-4 bg-gray-50 dark:bg-gray-800 rounded-lg shadow-inner"
      style={{ height: containerHeight }}
    >
      <div className="space-y-3">
        {logs.length > 0 ? (
          logs.map((log, index) => {
            const isExpanded = expandedLogs[index];

            return (
              <div
                key={index}
                className={`p-3 rounded-md transition-colors duration-200 cursor-pointer ${
                  log.type === "system"
                    ? "bg-blue-100 dark:bg-blue-900 text-blue-900 dark:text-blue-100"
                    : log.type === "user"
                    ? "bg-green-100 dark:bg-green-900 text-green-900 dark:text-green-100"
                    : log.type === "remote"
                    ? "bg-yellow-100 dark:bg-yellow-900 text-yellow-900 dark:text-yellow-100"
                    : log.type === "local"
                    ? "bg-purple-100 dark:bg-purple-900 text-purple-900 dark:text-purple-100"
                    : "bg-gray-200 dark:bg-gray-700 text-gray-900 dark:text-gray-100"
                }`}
                onClick={() => toggleExpand(index)}
              >
                <p className="font-semibold text-sm">
                  {log.type.charAt(0).toUpperCase() + log.type.slice(1)}:
                </p>
                <ReactMarkdown>{isExpanded ? log.message : getPreviewText(log.message)}</ReactMarkdown>
                {!isExpanded && log.message.length > 200 && (
                  <p className="text-xs mt-1 italic text-gray-600 dark:text-gray-400">
                    Click to expand
                  </p>
                )}
              </div>
            );
          })
        ) : (
          <p className="text-gray-500 dark:text-gray-400 text-center py-10">
            No interactions yet.
          </p>
        )}
      </div>
    </div>
  );
};

export default InteractionLog;