Newer
Older
cortex-hub / ui / client-app / src / pages / VoiceChatPage.js
import React, { useState, useRef, useEffect, useCallback } from "react";
import useVoiceChat from "../hooks/useVoiceChat";
import ChatWindow from "../components/ChatWindow";
import Controls from "../components/VoiceControls";
import SessionSidebar from "../components/SessionSidebar";

const VoiceChatPage = ({ Icon }) => {
  const chatContainerRef = useRef(null);

  const {
    chatHistory,
    status,
    isRecording,
    isBusy,
    isAutoMode,
    isAutoListening,
    showErrorModal,
    errorMessage,
    tokenUsage,
    setIsAutoMode,
    handleMicClick,
    handleNewSession,
    setShowErrorModal,
    handleSwitchSession,
    sessionId
  } = useVoiceChat({ chatContainerRef });

  useEffect(() => {
    if (chatContainerRef.current) {
      chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;
    }
  }, [chatHistory]);

  const toggleAutoMode = () => {
    setIsAutoMode(!isAutoMode);
  };

  return (
    <div className="flex flex-col flex-grow h-full min-h-screen bg-gray-100 dark:bg-gray-900 text-gray-900 dark:text-gray-100 relative">
      <SessionSidebar
        featureName="voice_chat"
        currentSessionId={sessionId}
        onSwitchSession={handleSwitchSession}
        onNewSession={handleNewSession}
      />

      {/* Header bar mirroring CodingAssistantPage */}
      <div className="bg-white dark:bg-gray-800 p-4 shadow flex justify-between items-center z-10 w-full sm:w-auto">
        <h2 className="text-xl font-bold">Voice Chat Assistant</h2>
        <div className="flex items-center space-x-4">
          <div className="text-sm font-mono text-gray-500 bg-gray-100 dark:bg-gray-700 px-2 py-1 rounded">
            {tokenUsage?.token_count || 0} / {tokenUsage?.token_limit || 100000} tokens ({tokenUsage?.percentage || 0}%)
          </div>
          <button
            onClick={handleNewSession}
            className="text-sm bg-blue-100 hover:bg-blue-200 text-blue-700 dark:bg-blue-900 dark:hover:bg-blue-800 dark:text-blue-200 px-3 py-1 rounded font-semibold transition-colors"
          >
            + New Session
          </button>
        </div>
      </div>

      <div className="flex-grow p-4 overflow-y-auto" ref={chatContainerRef}>
        <ChatWindow chatHistory={chatHistory} />
      </div>

      <Controls
        status={status}
        isBusy={isBusy}
        isRecording={isRecording}
        isAutoMode={isAutoMode}
        isAutoListening={isAutoListening}
        onMicClick={handleMicClick}
        onToggleAutoMode={toggleAutoMode}
      />

      {showErrorModal && (
        <div className="fixed inset-0 bg-gray-900 bg-opacity-75 flex justify-center items-center z-50">
          <div className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-xl text-center">
            <h2 className="text-xl font-bold mb-4 text-red-500">Error</h2>
            <p className="mb-4">{errorMessage}</p>
            <button
              onClick={() => setShowErrorModal(false)}
              className="bg-red-600 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
            >
              Close
            </button>
          </div>
        </div>
      )}
    </div>
  );
};

export default VoiceChatPage;