claude-code-templates 1.10.1 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Sidebar - Minimalist navigation sidebar for the analytics dashboard
3
+ * Provides navigation between Dashboard and Agents sections
4
+ */
5
+ class Sidebar {
6
+ constructor(container, onNavigate) {
7
+ this.container = container;
8
+ this.onNavigate = onNavigate;
9
+ this.currentPage = 'dashboard';
10
+ this.isCollapsed = true; // Start collapsed for minimal design
11
+ this.hoverTimeout = null;
12
+
13
+ this.init();
14
+ }
15
+
16
+ /**
17
+ * Initialize the sidebar
18
+ */
19
+ init() {
20
+ this.render();
21
+ this.bindEvents();
22
+ }
23
+
24
+ /**
25
+ * Render the sidebar structure
26
+ */
27
+ render() {
28
+ this.container.innerHTML = `
29
+ <nav class="sidebar ${this.isCollapsed ? 'collapsed' : ''}">
30
+ <div class="sidebar-header">
31
+ <div class="logo">
32
+ <div class="logo-icon">
33
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
34
+ <path d="M3 3h18v18H3V3zm16 16V5H5v14h14zM7 7h10v2H7V7zm0 4h10v2H7v-2zm0 4h7v2H7v-2z"/>
35
+ </svg>
36
+ </div>
37
+ <span class="logo-text">Claude Analytics</span>
38
+ </div>
39
+ </div>
40
+
41
+ <div class="sidebar-content">
42
+ <ul class="nav-menu">
43
+ <li class="nav-item ${this.currentPage === 'dashboard' ? 'active' : ''}" data-page="dashboard" title="Dashboard">
44
+ <a href="#" class="nav-link">
45
+ <div class="nav-icon">
46
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
47
+ <path d="M4 4h6v6H4V4zm10 0h6v6h-6V4zM4 14h6v6H4v-6zm10 0h6v6h-6v-6z"/>
48
+ </svg>
49
+ </div>
50
+ <span class="nav-text">Dashboard</span>
51
+ </a>
52
+ </li>
53
+ <li class="nav-item ${this.currentPage === 'agents' ? 'active' : ''}" data-page="agents" title="Agent Chats">
54
+ <a href="#" class="nav-link">
55
+ <div class="nav-icon">
56
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
57
+ <path d="M20 2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h4l4 4 4-4h4c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"/>
58
+ </svg>
59
+ </div>
60
+ <span class="nav-text">Chats</span>
61
+ </a>
62
+ </li>
63
+ </ul>
64
+ </div>
65
+
66
+ <div class="sidebar-footer">
67
+ <div class="connection-status" title="Connection Status">
68
+ <div class="status-indicator">
69
+ <span class="status-dot ${this.getConnectionStatus()}"></span>
70
+ <span class="status-text">Live</span>
71
+ </div>
72
+ </div>
73
+ </div>
74
+ </nav>
75
+ `;
76
+ }
77
+
78
+ /**
79
+ * Bind event listeners
80
+ */
81
+ bindEvents() {
82
+ const sidebar = this.container.querySelector('.sidebar');
83
+
84
+ // Navigation items
85
+ const navItems = this.container.querySelectorAll('.nav-item');
86
+ navItems.forEach(item => {
87
+ item.addEventListener('click', (e) => {
88
+ e.preventDefault();
89
+ const page = item.getAttribute('data-page');
90
+ this.navigateToPage(page);
91
+ });
92
+ });
93
+
94
+ // Hover to expand when collapsed
95
+ sidebar.addEventListener('mouseenter', () => {
96
+ if (this.isCollapsed) {
97
+ this.expandOnHover();
98
+ }
99
+ });
100
+
101
+ sidebar.addEventListener('mouseleave', () => {
102
+ if (this.isCollapsed) {
103
+ this.collapseOnLeave();
104
+ }
105
+ });
106
+ }
107
+
108
+ /**
109
+ * Set active page (visual update only)
110
+ * @param {string} page - Page identifier
111
+ */
112
+ setActivePage(page) {
113
+ // Update active state visually
114
+ const navItems = this.container.querySelectorAll('.nav-item');
115
+ navItems.forEach(item => {
116
+ item.classList.toggle('active', item.getAttribute('data-page') === page);
117
+ });
118
+
119
+ this.currentPage = page;
120
+ }
121
+
122
+ /**
123
+ * Handle navigation click and notify parent
124
+ * @param {string} page - Page identifier
125
+ */
126
+ navigateToPage(page) {
127
+ if (page === this.currentPage) return;
128
+
129
+ console.log(`🖱️ Sidebar navigation clicked: ${page}`);
130
+
131
+ // Notify parent component for actual navigation
132
+ if (this.onNavigate) {
133
+ this.onNavigate(page);
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Expand sidebar on hover
139
+ */
140
+ expandOnHover() {
141
+ if (this.hoverTimeout) {
142
+ clearTimeout(this.hoverTimeout);
143
+ }
144
+
145
+ const sidebar = this.container.querySelector('.sidebar');
146
+ sidebar.classList.add('hover-expanded');
147
+ }
148
+
149
+ /**
150
+ * Collapse sidebar when mouse leaves
151
+ */
152
+ collapseOnLeave() {
153
+ this.hoverTimeout = setTimeout(() => {
154
+ const sidebar = this.container.querySelector('.sidebar');
155
+ sidebar.classList.remove('hover-expanded');
156
+ }, 200); // Small delay to prevent flickering
157
+ }
158
+
159
+ /**
160
+ * Get connection status class
161
+ * @returns {string} Status class
162
+ */
163
+ getConnectionStatus() {
164
+ // This would normally check actual connection status
165
+ return 'connected';
166
+ }
167
+
168
+ /**
169
+ * Update connection status
170
+ * @param {string} status - Connection status
171
+ */
172
+ updateConnectionStatus(status) {
173
+ const statusDot = this.container.querySelector('.status-dot');
174
+ const statusText = this.container.querySelector('.status-text');
175
+
176
+ if (statusDot) {
177
+ statusDot.className = `status-dot ${status}`;
178
+ }
179
+
180
+ if (statusText) {
181
+ statusText.textContent = status === 'connected' ? 'Live' : 'Offline';
182
+ }
183
+ }
184
+
185
+ /**
186
+ * Destroy sidebar
187
+ */
188
+ destroy() {
189
+ // Clean up event listeners and DOM
190
+ this.container.innerHTML = '';
191
+ }
192
+ }
193
+
194
+ // Export for module use
195
+ if (typeof module !== 'undefined' && module.exports) {
196
+ module.exports = Sidebar;
197
+ }