File size: 3,574 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
export default function Sidebar({
  open, sessions, currentSessionId, searchQ,
  onSearchChange, onNewSession, onSelectSession, onDeleteSession,
  onFeedback, onSettings,
}) {
  return (
    <aside className={`sidebar ${open ? '' : 'collapsed'}`}>
      {/* Logo */}
      <div className="sidebar-logo">
        <div className="sidebar-logo-icon"></div>
        <div className="sidebar-logo-text">
          <span className="sidebar-logo-name">OwnGPT</span>
          <span className="sidebar-logo-version">v2 · Private AI</span>
        </div>
      </div>

      {/* New chat */}
      <div className="sidebar-top">
        <button className="btn-new-chat" onClick={onNewSession} title="New Conversation">
          <svg width="14" height="14" viewBox="0 0 24 24"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
          <span className="btn-new-chat-text">New Conversation</span>
        </button>
      </div>

      {/* Search */}
      <div className="sidebar-search" title="Search">
        <input
          className="search-box"
          type="text"
          placeholder="Search conversations…"
          value={searchQ}
          onChange={e => onSearchChange(e.target.value)}
        />
      </div>

      <div className="sidebar-label">Recent</div>

      {/* Session list */}
      <ul className="session-list">
        {sessions.length === 0 && (
          <li style={{ padding: '16px 12px', color: 'var(--t4)', fontSize: '12.5px', textAlign: 'center' }}>
            No conversations yet
          </li>
        )}
        {sessions.map((s, i) => (
          <li key={s.session_id} style={{ animationDelay: `${i * 30}ms` }}>
            <div
              className={`session-item ${s.session_id === currentSessionId ? 'active' : ''}`}
              onClick={() => onSelectSession(s)}
              title={s.title || 'New Chat'}
            >
              <div className="session-title">{s.title || 'New Chat'}</div>
              <button
                className="session-delete"
                onClick={e => { e.stopPropagation(); onDeleteSession(s.session_id) }}
                title="Delete"
              >
                <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
                  <polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6"/><path d="M14 11v6"/><path d="M9 6V4h6v2"/>
                </svg>
              </button>
            </div>
          </li>
        ))}
      </ul>

      {/* Bottom actions */}
      <div className="sidebar-bottom">
        <button className="sidebar-action" onClick={onFeedback} title="Send Feedback">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
          </svg>
          <span className="sidebar-action-text">Send Feedback</span>
        </button>
        <button className="sidebar-action" onClick={onSettings} title="Settings">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <circle cx="12" cy="12" r="3"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14M4.93 4.93a10 10 0 0 0 0 14.14"/>
          </svg>
          <span className="sidebar-action-text">Settings</span>
        </button>
      </div>
    </aside>
  )
}