File size: 6,862 Bytes
ffa2991
66f3298
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ffa2991
66f3298
 
 
 
 
 
 
 
ffa2991
66f3298
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ffa2991
66f3298
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import React from 'react';
import { Send, User, Bot } from 'lucide-react';
import InsuCompassLogo from '../../assets/InsuCompass_Logo.png';
import ReactMarkdown from 'react-markdown';
import { useChatInterface } from './useChatInterface';
import { Plan, UserProfile } from '../../interface';

const PlanCard: React.FC<{ plan: Plan }> = ({ plan }) => (
  <div className="bg-white border border-gray-200 rounded-2xl shadow-sm p-6 hover:shadow-lg transition">
    <h3 className="text-xl font-semibold text-gray-900">{plan.plan_name}</h3>
    <p className="text-sm text-gray-600 mb-2">{plan.plan_type}</p>
    <p className="text-sm italic text-gray-700 mb-4">{plan.reasoning}</p>
    <p className="text-sm font-medium text-gray-800 mb-2">
      Estimated Premium: {plan.estimated_premium}
    </p>
    <ul className="list-disc list-inside space-y-1 text-sm text-gray-700">
      {plan.key_features.map((feat, i) => (
        <li key={i}>{feat}</li>
      ))}
    </ul>
  </div>
);

interface ChatInterfaceScreenProps {
  userProfile: UserProfile;
}

const ChatInterfaceScreen: React.FC<ChatInterfaceScreenProps> = ({ userProfile }) => {

  const {
    chatHistory,
    isLoading,
    currentMessage,
    setCurrentMessage,
    handleSendMessage,
    showPlanRecs,
    chatEndRef,
    inputRef
  } = useChatInterface(userProfile);

  return (
    <div className="min-h-screen bg-gradient-to-br from-blue-50 via-white to-indigo-50 flex flex-col">
      {/* Header */}
      <div className="fixed top-0 left-0 w-full bg-white shadow-sm border-b z-50">
        <div className="max-w-10xl mx-auto px-6 py-4">
          <div className="flex items-center space-x-3">
            <img src={InsuCompassLogo} alt="InsuCompass Logo" className="h-12 w-auto" />
            <div>
              <h1 className="text-2xl font-bold text-gray-900">InsuCompass</h1>
              <p className="text-sm text-gray-600">Chat with your AI insurance advisor</p>
            </div>
          </div>
        </div>
      </div>

      {/* Chat Messages */}
      <div className="flex-1 overflow-y-auto pt-20">
        <div className="max-w-4xl mx-auto px-6 py-8">
          <div className="space-y-6">
            {chatHistory.map((message, index) => (
              <div
                key={index}
                className={`flex ${message.role === 'user' ? 'justify-end' : 'justify-start'}`}
              >
                <div className={`flex items-start space-x-3 max-w-3xl ${message.role === 'user' ? 'flex-row-reverse space-x-reverse' : ''}`}>
                  {/* Avatar */}
                  <div className={`w-10 h-10 rounded-full flex items-center justify-center flex-shrink-0 ${
                    message.role === 'user' 
                      ? 'bg-blue-500 text-white' 
                      : 'bg-gradient-to-r from-purple-500 to-pink-500 text-white'
                  }`}>
                    {message.role === 'user' ? (
                      <User className="w-5 h-5" />
                    ) : (
                      <Bot className="w-5 h-5" />
                    )}
                  </div>
                  {/* Message Bubble */}
                  <div className={`px-6 py-4 rounded-2xl shadow-sm ${
                    message.role === 'user'
                      ? 'bg-blue-500 text-white rounded-tr-sm'
                      : 'bg-white text-gray-900 rounded-tl-sm border border-gray-200'
                  }`}>
                    <div className="text-sm font-medium mb-1 opacity-75">
                      {message.role === 'user' ? 'You' : 'InsuCompass AI'}
                    </div>
                    <ReactMarkdown className="prose prose-sm max-w-none prose-table:border prose-table:border-gray-300 prose-th:bg-gray-100 prose-th:p-2 prose-td:p-2 prose-td:border prose-td:border-gray-300">
                      {message.content}
                    </ReactMarkdown>
                    {showPlanRecs && message.plans?.length && (
                      <>
                        <h2 className="text-2xl font-bold text-gray-900">Recommended Plans for You</h2>
                        <div className="grid md:grid-cols-2 gap-6">
                          {message.plans?.map((plan, idx) => (
                            <PlanCard key={idx} plan={plan} />
                          ))}
                        </div>
                      </>
                    )}
                  </div>
                </div>
              </div>
            ))}
            {/* Loading indicator */}
            {isLoading && (
              <div className="flex justify-start">
                <div className="flex items-start space-x-3">
                  <div className="w-10 h-10 rounded-full bg-gradient-to-r from-purple-500 to-pink-500 text-white flex items-center justify-center">
                    <Bot className="w-5 h-5" />
                  </div>
                  <div className="bg-white px-6 py-4 rounded-2xl rounded-tl-sm border border-gray-200">
                    <div className="flex space-x-2">
                      <div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce"></div>
                      <div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{ animationDelay: '0.1s' }}></div>
                      <div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{ animationDelay: '0.2s' }}></div>
                    </div>
                  </div>
                </div>
              </div>
            )}
            <div ref={chatEndRef} />
          </div>
        </div>
      </div>

      {/* Message Input */}
      <div className="bg-white border-t border-gray-200 p-4">
        <div className="max-w-4xl mx-auto">
          <div className="flex items-center space-x-4">
            <div className="flex-1 relative">
              <input
                ref={inputRef}
                type="text"
                value={currentMessage}
                onChange={(e) => setCurrentMessage(e.target.value)}
                onKeyDown={(e) => e.key === 'Enter' && handleSendMessage()}
                placeholder="Type your message..."
                className="w-full px-4 py-3 pr-12 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-colors"
                disabled={isLoading}
              />
              <button
                onClick={handleSendMessage}
                disabled={isLoading || !currentMessage.trim()}
                className="absolute right-2 top-1/2 transform -translate-y-1/2 p-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
              >
                <Send className="w-4 h-4" />
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

export default ChatInterfaceScreen;