File size: 3,385 Bytes
212c959
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { forwardRef, useState } from 'react'
import MessageBubble from './MessageBubble'

const SUGGESTIONS = [
  { emoji: '🌐', title: 'Latest AI news', text: 'What are the latest developments in AI this week?' },
  { emoji: 'πŸ’‘', title: 'Explain quantum computing', text: 'Explain quantum computing in simple terms' },
  { emoji: 'πŸ“', title: 'Write a cover letter', text: 'Write me a professional cover letter for a software engineer role' },
  { emoji: 'πŸ›', title: 'Debug my code', text: 'Help me debug and optimize my Python code' },
  { emoji: 'πŸ“Š', title: 'Data analysis help', text: 'Help me analyze data and create visualizations' },
  { emoji: '🎨', title: 'Creative writing', text: 'Write a short sci-fi story set in the year 2150' },
]

const EmptyState = ({ onSuggestion }) => (
  <div className="empty-state">
    <div className="empty-logo">✦</div>
    <div className="empty-title">What can I help with?</div>
    <div className="empty-sub">
      Ask me anything β€” code, research, writing, math, or just a conversation.
      I'm powered by the world's best AI models.
    </div>
    <div className="suggestion-grid">
      {SUGGESTIONS.map((s, i) => (
        <button key={s.title} className="suggestion-card" style={{ animation: `fadeUp 0.4s var(--ease) ${0.1 + i*0.05}s both` }} onClick={() => onSuggestion(s.text)}>
          <strong>{s.emoji} {s.title}</strong>
          {s.text}
        </button>
      ))}
    </div>
  </div>
)

const TypingIndicator = () => (
  <div className="msg-row" style={{ animationDelay: '0ms' }}>
    <div className="msg-indicator ai">✦</div>
    <div className="msg-card" style={{ padding: '14px 20px' }}>
      <div className="typing-wave">
        <div className="typing-dot" />
        <div className="typing-dot" />
        <div className="typing-dot" />
      </div>
    </div>
  </div>
)

const ChatArea = forwardRef(function ChatArea({ messages, loading, onSuggestion, user }, ref) {
  const [showFab, setShowFab] = useState(false)

  const handleScroll = (e) => {
    const { scrollTop, scrollHeight, clientHeight } = e.target
    if (scrollHeight - scrollTop - clientHeight > 200) {
      setShowFab(true)
    } else {
      setShowFab(false)
    }
  }

  const scrollToBottom = () => {
    if (ref.current) {
      ref.current.scrollTo({ top: ref.current.scrollHeight, behavior: 'smooth' })
    }
  }

  return (
    <div className="chat-area" ref={ref} onScroll={handleScroll}>
      <div className="chat-inner">
        {messages.length === 0 && !loading ? (
          <EmptyState onSuggestion={onSuggestion} />
        ) : (
          <>
            {messages.map((m, i) => (
              <MessageBubble key={m._id || i} message={m} index={i} user={user} />
            ))}
            {loading && (messages.length === 0 || messages[messages.length - 1].role !== 'assistant') && <TypingIndicator />}
          </>
        )}
      </div>
      <button 
        className={`scroll-fab ${showFab ? 'visible' : ''}`} 
        onClick={scrollToBottom}
        title="Scroll to bottom"
      >
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <line x1="12" y1="5" x2="12" y2="19"/><polyline points="19 12 12 19 5 12"/>
        </svg>
      </button>
    </div>
  )
})

export default ChatArea