perplexity-hackathon-LawMitra / perplexity_hackathon / legal-chat-pwa / src / components / ChatInput.tsx
ChatInput.tsx
Raw
'use client';

import React, { useState, useRef, useEffect } from 'react';
import { FaMicrophone, FaStop, FaPaperPlane } from 'react-icons/fa';

interface ChatInputProps {
  onSendMessage: (text: string, audioBlob?: Blob) => void;
  voiceEnabled: boolean;
  language: string;
}

export function ChatInput({ onSendMessage, voiceEnabled, language }: ChatInputProps) {
  const [text, setText] = useState('');
  const [isRecording, setIsRecording] = useState(false);
  const [mediaRecorder, setMediaRecorder] = useState<MediaRecorder | null>(null);
  const audioChunks = useRef<Blob[]>([]);

  useEffect(() => {
    if (!voiceEnabled) return;

    navigator.mediaDevices
      .getUserMedia({ audio: true })
      .then((stream) => {
        const recorder = new MediaRecorder(stream);
        recorder.ondataavailable = (e) => {
          if (e.data.size > 0) {
            audioChunks.current.push(e.data);
          }
        };
        recorder.onstop = () => {
          const audioBlob = new Blob(audioChunks.current, { type: 'audio/wav' });
          onSendMessage('', audioBlob);
          audioChunks.current = [];
        };
        setMediaRecorder(recorder);
      })
      .catch((err) => console.error('Error accessing microphone:', err));

    return () => {
      if (mediaRecorder && mediaRecorder.state !== 'inactive') {
        mediaRecorder.stop();
      }
    };
  }, [voiceEnabled]);

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (!text.trim()) return;
    onSendMessage(text);
    setText('');
  };

  const toggleRecording = () => {
    if (!mediaRecorder) return;

    if (isRecording) {
      mediaRecorder.stop();
    } else {
      audioChunks.current = [];
      mediaRecorder.start();
    }
    setIsRecording(!isRecording);
  };

  return (
    <form onSubmit={handleSubmit} className="flex items-center gap-2 p-4 border-t">
      <input
        type="text"
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder={`Type your message in ${language}...`}
        className="flex-1 p-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-blue-500"
      />
      {voiceEnabled && (
        <button
          type="button"
          onClick={toggleRecording}
          className={`p-3 rounded-full ${
            isRecording ? 'bg-red-500' : 'bg-blue-500'
          } text-white hover:opacity-90`}
        >
          {isRecording ? <FaStop /> : <FaMicrophone />}
        </button>
      )}
      <button
        type="submit"
        disabled={!text.trim()}
        className="p-3 rounded-full bg-blue-500 text-white hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed"
      >
        <FaPaperPlane />
      </button>
    </form>
  );
}