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

interface Case {
  id: string;
  type: string;
  description: string;
  status: 'new' | 'assigned' | 'in_progress' | 'resolved';
  createdAt: Date;
  transcripts: string[];
}

interface Question {
  text: string;
  answer: string;
  timestamp: Date;
  audioUrl?: string;
}

interface User {
  name: string;
  phoneNumber: string;
  cases: Case[];
  questions: Question[];
}

export function NGODemo() {
  const [phoneNumber, setPhoneNumber] = useState('');
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(false);
  const [currentAudio, setCurrentAudio] = useState<HTMLAudioElement | null>(null);
  const [isPlaying, setIsPlaying] = useState(false);

  const searchUser = () => {
    setLoading(true);
    // Simulate API call
    setTimeout(() => {
      setUser({
        name: 'John Doe',
        phoneNumber: phoneNumber,
        cases: [
          {
            id: '1',
            type: 'Tenant Rights',
            description: 'Security deposit dispute with landlord',
            status: 'in_progress',
            createdAt: new Date(),
            transcripts: [
              'Initial consultation completed. Client has provided lease agreement and communication records.',
            ],
          },
        ],
        questions: [
          {
            text: 'What are my rights regarding security deposit return?',
            answer: 'Landlords must return security deposits within 30 days of move-out...',
            timestamp: new Date(),
            audioUrl: 'https://example.com/audio.mp3',
          },
        ],
      });
      setLoading(false);
    }, 1000);
  };

  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);
    }
  };

  const addFollowUp = (caseId: string) => {
    const question = prompt('Enter follow-up question:');
    if (question && user) {
      const updatedCases = user.cases.map((c) =>
        c.id === caseId
          ? {
              ...c,
              transcripts: [...c.transcripts, `Follow-up question: ${question}`],
            }
          : c
      );
      setUser({ ...user, cases: updatedCases });
    }
  };

  return (
    <div className="space-y-6">
      <Card>
        <div className="flex items-center gap-4">
          <div className="relative flex-1">
            <input
              type="tel"
              value={phoneNumber}
              onChange={(e) => setPhoneNumber(e.target.value)}
              placeholder="Enter phone number..."
              className="w-full rounded-lg border border-gray-300 px-4 py-2 pl-10 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200"
            />
            <FaPhone className="absolute left-3 top-3 text-gray-400" />
          </div>
          <button
            onClick={searchUser}
            disabled={loading}
            className="flex min-w-[120px] items-center justify-center gap-2 rounded-lg bg-blue-500 px-6 py-2 font-medium text-white transition-colors hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-200 disabled:opacity-50"
          >
            {loading ? (
              <div className="h-5 w-5 animate-spin rounded-full border-b-2 border-white" />
            ) : (
              <>
                <FaSearch />
                Search
              </>
            )}
          </button>
        </div>
      </Card>

      {user && (
        <div className="space-y-6">
          <Card>
            <h2 className="text-xl font-semibold">{user.name}</h2>
            <p className="text-gray-600">{user.phoneNumber}</p>
          </Card>

          <div className="grid gap-6 lg:grid-cols-2">
            <Card>
              <h3 className="mb-4 text-lg font-semibold">Cases</h3>
              <div className="space-y-4">
                {user.cases.map((case_) => (
                  <div key={case_.id} className="border-t border-gray-100 pt-4">
                    <div className="mb-2 flex items-center justify-between">
                      <div>
                        <h4 className="font-medium">{case_.type}</h4>
                        <p className="text-sm text-gray-600">{case_.description}</p>
                      </div>
                      <button
                        onClick={() => addFollowUp(case_.id)}
                        className="rounded bg-blue-500 px-3 py-1 text-sm text-white hover:bg-blue-600"
                      >
                        Add Follow-up
                      </button>
                    </div>
                    {case_.transcripts.map((transcript, index) => (
                      <p key={index} className="mt-2 text-sm text-gray-600">
                        {transcript}
                      </p>
                    ))}
                  </div>
                ))}
              </div>
            </Card>

            <Card>
              <h3 className="mb-4 text-lg font-semibold">Questions</h3>
              <div className="space-y-4">
                {user.questions.map((question, index) => (
                  <div key={index} className="border-t border-gray-100 pt-4">
                    <p className="font-medium">{question.text}</p>
                    <p className="mt-2 text-sm text-gray-600">{question.answer}</p>
                    {question.audioUrl && (
                      <button
                        onClick={() => toggleAudio(question.audioUrl!)}
                        className="mt-2 flex items-center gap-2 text-sm text-blue-500"
                      >
                        {isPlaying && currentAudio?.src === question.audioUrl ? (
                          <FaPause />
                        ) : (
                          <FaPlay />
                        )}
                        {isPlaying && currentAudio?.src === question.audioUrl
                          ? 'Pause Audio'
                          : 'Play Audio'}
                      </button>
                    )}
                  </div>
                ))}
              </div>
            </Card>
          </div>
        </div>
      )}
    </div>
  );
}