File size: 4,343 Bytes
b2c1c67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { useState } from "react";
import {
  BarChart3,
  BrainCircuit,
  Check,
  FileText,
  LogOut,
  MessageSquare,
  Pencil,
  Plus,
  Trash2,
  X,
} from "lucide-react";

export default function Sidebar({
  user,
  sessions,
  activeSessionId,
  view,
  onSelectSession,
  onNewChat,
  onDeleteSession,
  onRenameSession,
  onOpenDocs,
  onShowAnalytics,
  onLogout,
}) {
  const [editingId, setEditingId] = useState(null);
  const [editTitle, setEditTitle] = useState("");

  function startEdit(session, event) {
    event.stopPropagation();
    setEditingId(session.id);
    setEditTitle(session.title);
  }

  function commitEdit() {
    const title = editTitle.trim();
    if (title && editingId) onRenameSession(editingId, title).catch(() => {});
    setEditingId(null);
  }

  return (
    <aside className="sidebar">
      <div className="brand">
        <div className="brand-logo">
          <BrainCircuit size={17} />
        </div>
        Synapse
      </div>

      <button className="new-chat-btn" onClick={onNewChat}>
        <Plus size={16} /> New chat
      </button>

      <div className="session-list">
        {sessions.length === 0 && (
          <div className="centered-note">No conversations yet.</div>
        )}
        {sessions.map((session) => (
          <div
            key={session.id}
            className={
              "session-item" +
              (session.id === activeSessionId && view === "chat" ? " active" : "")
            }
            onClick={() => onSelectSession(session.id)}
          >
            <MessageSquare size={14} style={{ flexShrink: 0 }} />
            {editingId === session.id ? (
              <>
                <input
                  className="session-title"
                  style={{
                    background: "var(--panel-2)",
                    border: "1px solid var(--accent)",
                    borderRadius: 6,
                    color: "var(--text)",
                    fontSize: 13,
                    padding: "3px 6px",
                  }}
                  value={editTitle}
                  autoFocus
                  onChange={(e) => setEditTitle(e.target.value)}
                  onKeyDown={(e) => {
                    if (e.key === "Enter") commitEdit();
                    if (e.key === "Escape") setEditingId(null);
                  }}
                  onClick={(e) => e.stopPropagation()}
                />
                <button className="icon-btn" onClick={(e) => { e.stopPropagation(); commitEdit(); }}>
                  <Check size={13} />
                </button>
                <button className="icon-btn" onClick={(e) => { e.stopPropagation(); setEditingId(null); }}>
                  <X size={13} />
                </button>
              </>
            ) : (
              <>
                <span className="session-title" title={session.title}>
                  {session.title}
                </span>
                <button className="icon-btn" title="Rename" onClick={(e) => startEdit(session, e)}>
                  <Pencil size={13} />
                </button>
                <button
                  className="icon-btn danger"
                  title="Delete"
                  onClick={(e) => {
                    e.stopPropagation();
                    onDeleteSession(session.id).catch(() => {});
                  }}
                >
                  <Trash2 size={13} />
                </button>
              </>
            )}
          </div>
        ))}
      </div>

      <div className="sidebar-footer">
        <button className="nav-btn" onClick={onOpenDocs}>
          <FileText size={15} /> Documents
        </button>
        <button
          className={"nav-btn" + (view === "analytics" ? " active" : "")}
          onClick={onShowAnalytics}
        >
          <BarChart3 size={15} /> Analytics
        </button>
        <div className="user-row">
          <div className="avatar">{(user.username || "?").slice(0, 1).toUpperCase()}</div>
          <span style={{ flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
            {user.username}
          </span>
          <button className="icon-btn" title="Sign out" onClick={onLogout}>
            <LogOut size={15} />
          </button>
        </div>
      </div>
    </aside>
  );
}