perplexity-hackathon-LawMitra / perplexity_hackathon / demo / web / src / components / UserDemo.tsx
UserDemo.tsx
Raw
import React, { useState } from 'react';
import { FaMicrophone, FaPaperPlane, FaPlay, FaPause } from 'react-icons/fa';
import { Card } from './shared/Card';

interface Message {
  id: string;
  text: string;
  type: 'user' | 'bot';
  timestamp: number;
  audioUrl?: string;
}

export function UserDemo() {
  const [messages, setMessages] = useState<Message[]>([]);
  const [input, setInput] = useState('');
  const [isRecording, setIsRecording] = useState(false);
  const [currentAudio, setCurrentAudio] = useState<HTMLAudioElement | null>(null);
  const [isPlaying, setIsPlaying] = useState(false);

  const handleSend = async () => {
    if (!input.trim()) return;

    const userMessage: Message = {
      id: Date.now().toString(),
      text: input,
      type: 'user',
      timestamp: Date.now(),
    };

    setMessages((prev) => [...prev, userMessage]);
    setInput('');

    // Simulate bot response
    setTimeout(() => {
      const botMessage: Message = {
        id: Date.now().toString(),
        text: 'This is a simulated response from the legal assistant. In a real scenario, this would be generated based on your query.',
        type: 'bot',
        timestamp: Date.now(),
        audioUrl: 'https://example.com/audio.mp3',
      };
      setMessages((prev) => [...prev, botMessage]);
    }, 1000);
  };

  const toggleRecording = () => {
    setIsRecording(!isRecording);
    if (!isRecording) {
      // Simulate voice recording
      setTimeout(() => {
        const message: Message = {
          id: Date.now().toString(),
          text: 'Voice message transcription would appear here',
          type: 'user',
          timestamp: Date.now(),
          audioUrl: 'https://example.com/recording.mp3',
        };
        setMessages((prev) => [...prev, message]);
        setIsRecording(false);
      }, 3000);
    }
  };

  const toggleAudio = (audioUrl: string) => {
    if (currentAudio) {
      currentAudio.pause();
      setIsPlaying(false);
    }

    if (!isPlaying || currentAudio?.src !== audioUrl) {
      const audio = new Audio(audioUrl);
      audio.addEventListener('ended', () => setIsPlaying(false));
      audio.play();
      setCurrentAudio(audio);
      setIsPlaying(true);
    }
  };

  return (
    <div className="flex h-[calc(100vh-12rem)] flex-col">
      <div className="flex-1 overflow-y-auto p-4">
        <div className="space-y-4">
          {messages.map((message) => (
            <Card
              key={message.id}
              className={`flex max-w-[80%] flex-col ${
                message.type === 'user' ? 'ml-auto' : 'mr-auto'
              }`}
            >
              <p className="text-sm">{message.text}</p>
              {message.audioUrl && (
                <button
                  onClick={() => toggleAudio(message.audioUrl!)}
                  className="mt-2 flex items-center gap-2 text-sm text-blue-500"
                >
                  {isPlaying && currentAudio?.src === message.audioUrl ? (
                    <FaPause />
                  ) : (
                    <FaPlay />
                  )}
                  {isPlaying && currentAudio?.src === message.audioUrl
                    ? 'Pause Audio'
                    : 'Play Audio'}
                </button>
              )}
              <span className="mt-1 text-xs text-gray-500">
                {new Date(message.timestamp).toLocaleTimeString()}
              </span>
            </Card>
          ))}
        </div>
      </div>
      <div className="border-t bg-white p-4">
        <div className="flex gap-2">
          <button
            onClick={toggleRecording}
            className={`rounded-full p-3 ${
              isRecording ? 'bg-red-500' : 'bg-blue-500'
            } text-white transition-colors hover:opacity-90`}
          >
            <FaMicrophone />
          </button>
          <input
            type="text"
            value={input}
            onChange={(e) => setInput(e.target.value)}
            placeholder="Type your legal question..."
            className="flex-1 rounded-lg border border-gray-300 px-4 py-2 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200"
            onKeyPress={(e) => e.key === 'Enter' && handleSend()}
          />
          <button
            onClick={handleSend}
            disabled={!input.trim()}
            className="rounded-full bg-blue-500 p-3 text-white transition-colors hover:opacity-90 disabled:opacity-50"
          >
            <FaPaperPlane />
          </button>
        </div>
      </div>
    </div>
  );
}