Athspi commited on
Commit
82129f8
·
verified ·
1 Parent(s): a3f61dd

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +63 -14
templates/index.html CHANGED
@@ -75,13 +75,16 @@
75
  #download-btn { width: 100%; background-color: var(--primary-color); color: var(--background-primary); display: flex; align-items: center; justify-content: center; gap: 10px; font-size: 1rem; font-weight: 600; border-radius: 8px; padding: 12px; }
76
  #download-btn:hover { background-color: var(--accent-color); color: var(--background-primary); }
77
  #download-btn i { font-size: 1.1rem; }
 
78
  </style>
79
  </head>
80
  <body>
81
  <div class="container">
82
  <div class="sidebar left-sidebar">
83
  <div class="sidebar-header"><i class="fa-solid fa-folder-tree"></i><h2>Project Files</h2></div>
84
- <div id="file-tree" class="sidebar-content"></div>
 
 
85
  <div class="sidebar-footer"><button id="download-btn"><i class="fa-solid fa-download"></i><span>Download Project</span></button></div>
86
  </div>
87
  <div class="main-content">
@@ -139,6 +142,9 @@
139
  const fetchApi = async (url, options) => {
140
  try {
141
  const response = await fetch(url, options);
 
 
 
142
  const data = await response.json();
143
  if (data.error) {
144
  handleApiError(data.error);
@@ -147,6 +153,7 @@
147
  return data;
148
  } catch (error) {
149
  handleApiError('Failed to connect to the backend. Please ensure it is running.');
 
150
  return null;
151
  }
152
  };
@@ -154,17 +161,23 @@
154
  const uploadProject = async (formData) => {
155
  ui.uploadBox.style.display = 'none';
156
  ui.progressIndicator.style.display = 'block';
157
- const data = await fetchApi('/upload', { method: 'POST', body: formData });
 
 
 
 
158
  ui.progressIndicator.style.display = 'none';
159
  if (data) {
160
  ui.uploadSection.style.display = 'none';
161
  ui.chatSection.style.display = 'flex';
162
  updateFileTree(data.file_tree);
163
  ui.chatWindow.innerHTML = '';
164
- data.chat_history.forEach(msg => {
165
- let content = (msg.role === 'user' && msg.content.startsWith('The user has uploaded')) ? 'Project context sent to AI.' : msg.content;
166
- appendMessage(msg.role === 'model' ? 'assistant' : msg.role, content);
167
- });
 
 
168
  } else {
169
  ui.uploadBox.style.display = 'block';
170
  }
@@ -173,14 +186,17 @@
173
  const sendMessage = async () => {
174
  const message = ui.messageInput.value.trim();
175
  if (!message) return;
 
176
  appendMessage('user', message);
177
  ui.messageInput.value = '';
178
  ui.messageInput.style.height = 'auto';
 
179
  const data = await fetchApi('/chat', {
180
  method: 'POST',
181
  headers: { 'Content-Type': 'application/json' },
182
  body: JSON.stringify({ message })
183
  });
 
184
  if (data && data.reply) {
185
  appendMessage('assistant', data.reply);
186
  updateFileTree();
@@ -197,9 +213,13 @@
197
  html = html.replace(/`([^`]+)`/g, '<code>$1</code>');
198
  html = html.replace(/```(\w+)?\n([\s\S]*?)```/g, (match, lang, code) => {
199
  const trimmedCode = code.trim();
200
- const highlighted = hljs.highlight(trimmedCode, { language: lang || 'plaintext', ignoreIllegals: true }).value;
 
 
 
201
  return `<pre><code class="hljs ${lang}">${highlighted}</code></pre>`;
202
  });
 
203
  messageElement.innerHTML = html.replace(/\n/g, '<br>');
204
  ui.chatWindow.appendChild(messageElement);
205
  ui.chatWindow.scrollTop = ui.chatWindow.scrollHeight;
@@ -207,9 +227,11 @@
207
 
208
  const updateFileTree = async () => {
209
  const data = await fetchApi('/file_tree');
210
- if (data && data.file_tree) {
 
 
211
  const activeFilePath = document.querySelector('#file-tree .active')?.dataset.path;
212
- ui.fileTree.innerHTML = '';
213
  data.file_tree.forEach(path => {
214
  const fileElement = document.createElement('div');
215
  fileElement.textContent = path;
@@ -222,6 +244,11 @@
222
  if (path === activeFilePath) fileElement.classList.add('active');
223
  ui.fileTree.appendChild(fileElement);
224
  });
 
 
 
 
 
225
  }
226
  };
227
 
@@ -231,21 +258,43 @@
231
  ui.fileContentDisplay.textContent = data.content;
232
  hljs.highlightElement(ui.fileContentDisplay);
233
  } else {
234
- ui.fileContentDisplay.textContent = 'Could not load file content.';
235
  }
236
  };
237
 
 
238
  ui.projectZipInput.addEventListener('change', () => {
239
  if (ui.projectZipInput.files.length > 0) {
240
  ui.fileNameDisplay.textContent = `Selected: ${ui.projectZipInput.files[0].name}`;
241
  ui.uploadButton.click();
242
  }
243
  });
244
- ui.uploadForm.addEventListener('submit', (e) => { e.preventDefault(); uploadProject(new FormData(ui.uploadForm)); });
 
 
 
 
 
245
  ui.sendBtn.addEventListener('click', sendMessage);
246
- ui.messageInput.addEventListener('keypress', (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); } });
247
- ui.downloadBtn.addEventListener('click', () => { window.location.href = '/download'; });
248
- ui.messageInput.addEventListener('input', function () { this.style.height = 'auto'; this.style.height = (this.scrollHeight) + 'px'; });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  });
250
  </script>
251
  </body>
 
75
  #download-btn { width: 100%; background-color: var(--primary-color); color: var(--background-primary); display: flex; align-items: center; justify-content: center; gap: 10px; font-size: 1rem; font-weight: 600; border-radius: 8px; padding: 12px; }
76
  #download-btn:hover { background-color: var(--accent-color); color: var(--background-primary); }
77
  #download-btn i { font-size: 1.1rem; }
78
+ .empty-state { color: var(--text-secondary); padding: 20px; text-align: center; }
79
  </style>
80
  </head>
81
  <body>
82
  <div class="container">
83
  <div class="sidebar left-sidebar">
84
  <div class="sidebar-header"><i class="fa-solid fa-folder-tree"></i><h2>Project Files</h2></div>
85
+ <div id="file-tree" class="sidebar-content">
86
+ <div class="empty-state">No project files. Upload a project first.</div>
87
+ </div>
88
  <div class="sidebar-footer"><button id="download-btn"><i class="fa-solid fa-download"></i><span>Download Project</span></button></div>
89
  </div>
90
  <div class="main-content">
 
142
  const fetchApi = async (url, options) => {
143
  try {
144
  const response = await fetch(url, options);
145
+ if (!response.ok) {
146
+ throw new Error(`HTTP error! status: ${response.status}`);
147
+ }
148
  const data = await response.json();
149
  if (data.error) {
150
  handleApiError(data.error);
 
153
  return data;
154
  } catch (error) {
155
  handleApiError('Failed to connect to the backend. Please ensure it is running.');
156
+ console.error('API Error:', error);
157
  return null;
158
  }
159
  };
 
161
  const uploadProject = async (formData) => {
162
  ui.uploadBox.style.display = 'none';
163
  ui.progressIndicator.style.display = 'block';
164
+ const data = await fetchApi('/upload', {
165
+ method: 'POST',
166
+ body: formData
167
+ });
168
+
169
  ui.progressIndicator.style.display = 'none';
170
  if (data) {
171
  ui.uploadSection.style.display = 'none';
172
  ui.chatSection.style.display = 'flex';
173
  updateFileTree(data.file_tree);
174
  ui.chatWindow.innerHTML = '';
175
+
176
+ if (data.chat_history && data.chat_history.length > 0) {
177
+ data.chat_history.forEach(msg => {
178
+ appendMessage(msg.role === 'user' ? 'user' : 'assistant', msg.content);
179
+ });
180
+ }
181
  } else {
182
  ui.uploadBox.style.display = 'block';
183
  }
 
186
  const sendMessage = async () => {
187
  const message = ui.messageInput.value.trim();
188
  if (!message) return;
189
+
190
  appendMessage('user', message);
191
  ui.messageInput.value = '';
192
  ui.messageInput.style.height = 'auto';
193
+
194
  const data = await fetchApi('/chat', {
195
  method: 'POST',
196
  headers: { 'Content-Type': 'application/json' },
197
  body: JSON.stringify({ message })
198
  });
199
+
200
  if (data && data.reply) {
201
  appendMessage('assistant', data.reply);
202
  updateFileTree();
 
213
  html = html.replace(/`([^`]+)`/g, '<code>$1</code>');
214
  html = html.replace(/```(\w+)?\n([\s\S]*?)```/g, (match, lang, code) => {
215
  const trimmedCode = code.trim();
216
+ const highlighted = hljs.highlight(trimmedCode, {
217
+ language: lang || 'plaintext',
218
+ ignoreIllegals: true
219
+ }).value;
220
  return `<pre><code class="hljs ${lang}">${highlighted}</code></pre>`;
221
  });
222
+
223
  messageElement.innerHTML = html.replace(/\n/g, '<br>');
224
  ui.chatWindow.appendChild(messageElement);
225
  ui.chatWindow.scrollTop = ui.chatWindow.scrollHeight;
 
227
 
228
  const updateFileTree = async () => {
229
  const data = await fetchApi('/file_tree');
230
+ ui.fileTree.innerHTML = '';
231
+
232
+ if (data && data.file_tree && data.file_tree.length > 0) {
233
  const activeFilePath = document.querySelector('#file-tree .active')?.dataset.path;
234
+
235
  data.file_tree.forEach(path => {
236
  const fileElement = document.createElement('div');
237
  fileElement.textContent = path;
 
244
  if (path === activeFilePath) fileElement.classList.add('active');
245
  ui.fileTree.appendChild(fileElement);
246
  });
247
+ } else {
248
+ const emptyMessage = document.createElement('div');
249
+ emptyMessage.textContent = 'No project files. Upload a project first.';
250
+ emptyMessage.classList.add('empty-state');
251
+ ui.fileTree.appendChild(emptyMessage);
252
  }
253
  };
254
 
 
258
  ui.fileContentDisplay.textContent = data.content;
259
  hljs.highlightElement(ui.fileContentDisplay);
260
  } else {
261
+ ui.fileContentDisplay.textContent = data?.error || 'Could not load file content.';
262
  }
263
  };
264
 
265
+ // Event listeners
266
  ui.projectZipInput.addEventListener('change', () => {
267
  if (ui.projectZipInput.files.length > 0) {
268
  ui.fileNameDisplay.textContent = `Selected: ${ui.projectZipInput.files[0].name}`;
269
  ui.uploadButton.click();
270
  }
271
  });
272
+
273
+ ui.uploadForm.addEventListener('submit', (e) => {
274
+ e.preventDefault();
275
+ uploadProject(new FormData(ui.uploadForm));
276
+ });
277
+
278
  ui.sendBtn.addEventListener('click', sendMessage);
279
+
280
+ ui.messageInput.addEventListener('keypress', (e) => {
281
+ if (e.key === 'Enter' && !e.shiftKey) {
282
+ e.preventDefault();
283
+ sendMessage();
284
+ }
285
+ });
286
+
287
+ ui.downloadBtn.addEventListener('click', () => {
288
+ window.location.href = '/download';
289
+ });
290
+
291
+ ui.messageInput.addEventListener('input', function() {
292
+ this.style.height = 'auto';
293
+ this.style.height = (this.scrollHeight) + 'px';
294
+ });
295
+
296
+ // Initialize the application
297
+ updateFileTree();
298
  });
299
  </script>
300
  </body>