File size: 5,067 Bytes
68c2137
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import React, { useRef, useEffect } from 'react';
import { MessageCard } from './MessageCard';
import type { Message } from '../types/chat';
import { Scale, Sparkles, Code, FileText, Shield, Loader2 } from 'lucide-react';

interface ChatAreaProps {
  messages: Message[];
  onSendMessage: (text: string) => void;
  onRegenerate: () => void;
  onOpenPDFPreview: (pdf: NonNullable<Message['pdfPreview']>) => void;
  onEditMessage?: (id: string, text: string) => void;
  onDeleteMessage?: (id: string) => void;
  isGenerating?: boolean;
}

export const ChatArea: React.FC<ChatAreaProps> = ({
  messages,
  onSendMessage,
  onRegenerate,
  onOpenPDFPreview,
  onEditMessage,
  onDeleteMessage,
  isGenerating
}) => {
  const bottomRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    bottomRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [messages, isGenerating]);

  if (messages.length === 0) {
    return (
      <div className="flex-1 overflow-y-auto p-6 sm:p-12 flex flex-col items-center justify-center text-center">
        <div className="max-w-[900px] w-full mx-auto space-y-8">
          {/* Logo & Header */}
          <div className="space-y-3">
            <div className="w-20 h-20 rounded-3xl bg-gradient-to-br from-blue-600 to-indigo-600 flex items-center justify-center text-white mx-auto shadow-2xl shadow-blue-500/30 animate-pulse">
              <Scale className="w-10 h-10" />
            </div>

            <h2 className="text-3xl font-extrabold text-white tracking-tight">
              Welcome to LawSLM
            </h2>
            <p className="text-sm text-slate-400 max-w-lg mx-auto">
              Your Intelligent AI Legal and General Assistant — Built completely from scratch by Amit Kumar.
            </p>
          </div>

          {/* 4 Feature Suggestion Cards */}
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-4 text-left max-w-2xl mx-auto">
            <SuggestionCard
              icon={<Shield className="w-6 h-6 text-blue-400" />}
              title="Legal Information"
              subtitle="Explain statutes, IPC section provisions & legal procedures"
              onClick={() => onSendMessage("Explain Section 420 of IPC in simple terms")}
            />
            <SuggestionCard
              icon={<FileText className="w-6 h-6 text-amber-400" />}
              title="PDF Report Export"
              subtitle="Generate & export formal legal notices & affidavit documents"
              onClick={() => onSendMessage("Generate formal legal notice PDF report")}
            />
            <SuggestionCard
              icon={<Code className="w-6 h-6 text-emerald-400" />}
              title="Programming & AI"
              subtitle="Write & debug Python, PyTorch, C++, Java & SQL code"
              onClick={() => onSendMessage("Write a Python script to train a Transformer in PyTorch")}
            />
            <SuggestionCard
              icon={<Sparkles className="w-6 h-6 text-purple-400" />}
              title="Model Creator"
              subtitle="Learn about LawSLM's architecture and developer"
              onClick={() => onSendMessage("Who created you?")}
            />
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="flex-1 overflow-y-auto py-6">
      <div className="max-w-[900px] mx-auto space-y-4">
        {messages.map((msg, idx) => (
          <MessageCard
            key={msg.id || idx}
            message={msg}
            onRegenerate={idx === messages.length - 1 && msg.role === 'assistant' ? onRegenerate : undefined}
            onOpenPDFPreview={onOpenPDFPreview}
            onEditMessage={onEditMessage}
            onDeleteMessage={onDeleteMessage}
          />
        ))}

        {/* Animated Thinking Indicator */}
        {isGenerating && messages[messages.length - 1]?.role === 'user' && (
          <div className="flex items-center space-x-3 px-6 py-4 rounded-2xl glass-card-ai max-w-xs mx-6">
            <Loader2 className="w-4 h-4 text-blue-400 animate-spin" />
            <span className="text-xs font-semibold text-slate-300">LawSLM is thinking...</span>
          </div>
        )}

        <div ref={bottomRef} />
      </div>
    </div>
  );
};

interface SuggestionCardProps {
  icon: React.ReactNode;
  title: string;
  subtitle: string;
  onClick: () => void;
}

const SuggestionCard: React.FC<SuggestionCardProps> = ({ icon, title, subtitle, onClick }) => (
  <button
    onClick={onClick}
    className="p-5 rounded-2xl bg-slate-800/80 border border-slate-700/80 text-left flex flex-col justify-between space-y-3 hover:bg-slate-750 hover:border-blue-500/50 transition-all shadow-lg group"
  >
    <div className="p-2.5 rounded-xl bg-slate-900 w-fit group-hover:bg-blue-500/20 transition-colors">
      {icon}
    </div>
    <div>
      <h3 className="text-sm font-bold text-slate-200 group-hover:text-blue-400 transition-colors">
        {title}
      </h3>
      <p className="text-xs text-slate-400 mt-1 leading-snug">
        {subtitle}
      </p>
    </div>
  </button>
);