pvanand commited on
Commit
35c7794
1 Parent(s): d38945b

Update static/presentation-agent.html

Browse files
Files changed (1) hide show
  1. static/presentation-agent.html +129 -75
static/presentation-agent.html CHANGED
@@ -3,11 +3,11 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Presentation Chatbot</title>
7
- <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
8
- <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
9
- <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.global.prod.js"></script>
10
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
 
11
  <style>
12
  :root {
13
  --primary-color: #007bff;
@@ -189,11 +189,24 @@
189
  <div class="chat-container">
190
  <h1 class="title">PitchPerfect</h1>
191
  <h2 class="subtitle">by Elevatics.ai</h2>
192
- <!-- <h1 class="text-center mb-4">Presentation Chatbot</h1> -->
193
  <div v-for="(message, index) in chatHistory" :key="index" class="message" :class="message.type === 'user' ? 'user-message' : 'bot-message'">
194
  <div v-if="message.type === 'bot'" v-html="message.content"></div>
195
  <div v-else>{{ message.content }}</div>
196
- <iframe v-if="message.html" :srcdoc="message.html" class="presentation-iframe mt-2"></iframe>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  </div>
198
  <div v-if="isLoading" class="text-center">
199
  <div class="spinner-border loading-spinner" role="status">
@@ -215,105 +228,146 @@
215
  </div>
216
 
217
  <script>
218
- const { createApp } = Vue;
219
 
220
  createApp({
221
- data() {
222
- return {
223
- userInput: '',
224
- chatHistory: [],
225
- conversationId: '',
226
- isLoading: false,
227
- errorMessage: '',
228
- AUTH_TOKEN: "44d5c2ac18ced6fc25c1e57dcd06fc0b31fb4ad97bf56e67540671a647465df4",
229
- modelId: 'openai/gpt-4o-mini',
230
- isDarkMode: false
 
 
 
 
 
 
 
 
231
  }
232
- },
233
- mounted() {
234
- this.resetConversation();
235
- this.isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
236
- this.applyDarkMode();
237
- },
238
- updated() {
239
- this.scrollToBottom();
240
- },
241
- methods: {
242
- async sendMessage() {
243
- if (!this.userInput.trim()) return;
244
-
245
- this.chatHistory.push({ type: 'user', content: this.userInput });
246
- const userMessage = this.userInput;
247
- this.userInput = '';
248
- this.isLoading = true;
249
- this.errorMessage = '';
 
 
 
 
250
 
251
  const payload = {
252
  prompt: userMessage,
253
- model_id: this.modelId,
254
- conversation_id: this.conversationId,
255
  user_id: "web_user"
256
- };
257
 
258
  try {
259
  const response = await fetch('https://pvanand-audio-chat.hf.space/presentation-agent', {
260
  method: 'POST',
261
  headers: {
262
  'accept': 'application/json',
263
- 'X-API-Key': this.AUTH_TOKEN,
264
  'Content-Type': 'application/json'
265
  },
266
  body: JSON.stringify(payload)
267
- });
268
 
269
  if (!response.ok) {
270
- const errorText = await response.text();
271
- throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
272
  }
273
 
274
- const data = await response.json();
275
  const botMessage = {
276
  type: 'bot',
277
  content: data.response ? marked.parse(data.response) : '',
278
- html: data.html_presentation || null
279
- };
280
- this.chatHistory.push(botMessage);
 
281
  } catch (error) {
282
- this.errorMessage = `Error: ${error.message}`;
283
  setTimeout(() => {
284
- this.errorMessage = '';
285
- }, 5000);
286
  } finally {
287
- this.isLoading = false;
288
  }
289
- },
290
- resetConversation() {
291
- this.chatHistory = [];
292
- this.conversationId = this.generateUUID();
293
- this.errorMessage = '';
294
- },
295
- generateUUID() {
296
- return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
297
- },
298
- scrollToBottom() {
299
- this.$nextTick(() => {
300
- const container = this.$el.querySelector('.chat-container');
301
- container.scrollTop = container.scrollHeight;
302
- });
303
- },
304
- toggleDarkMode() {
305
- this.isDarkMode = !this.isDarkMode;
306
- this.applyDarkMode();
307
- },
308
- applyDarkMode() {
309
- if (this.isDarkMode) {
310
- document.body.classList.add('dark-mode');
311
- } else {
312
- document.body.classList.remove('dark-mode');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
313
  }
314
  }
 
 
 
 
 
 
 
 
 
 
 
 
315
  }
316
- }).mount('#app');
317
  </script>
 
318
  </body>
319
  </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>PitchPerfect by Elevatics.ai</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/[email protected]-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
8
+ <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
 
9
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
10
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css">
11
  <style>
12
  :root {
13
  --primary-color: #007bff;
 
189
  <div class="chat-container">
190
  <h1 class="title">PitchPerfect</h1>
191
  <h2 class="subtitle">by Elevatics.ai</h2>
 
192
  <div v-for="(message, index) in chatHistory" :key="index" class="message" :class="message.type === 'user' ? 'user-message' : 'bot-message'">
193
  <div v-if="message.type === 'bot'" v-html="message.content"></div>
194
  <div v-else>{{ message.content }}</div>
195
+ <div v-if="message.html" class="position-relative">
196
+ <div class="position-absolute top-0 end-0 m-2">
197
+ <div class="dropdown">
198
+ <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-expanded="false">
199
+ Download
200
+ </button>
201
+ <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
202
+ <li v-for="format in ['html', 'pdf', 'pptx']" :key="format">
203
+ <a class="dropdown-item" href="#" @click.prevent="downloadPresentation(format, message.markdown_presentation)">{{ format.toUpperCase() }}</a>
204
+ </li>
205
+ </ul>
206
+ </div>
207
+ </div>
208
+ <iframe :srcdoc="message.html" class="presentation-iframe mt-2"></iframe>
209
+ </div>
210
  </div>
211
  <div v-if="isLoading" class="text-center">
212
  <div class="spinner-border loading-spinner" role="status">
 
228
  </div>
229
 
230
  <script>
231
+ const { createApp, ref, computed } = Vue
232
 
233
  createApp({
234
+ setup() {
235
+ const userInput = ref('')
236
+ const chatHistory = ref([])
237
+ const conversationId = ref('')
238
+ const isLoading = ref(false)
239
+ const errorMessage = ref('')
240
+ const AUTH_TOKEN = "44d5c2ac18ced6fc25c1e57dcd06fc0b31fb4ad97bf56e67540671a647465df4"
241
+ const modelId = 'openai/gpt-4o-mini'
242
+ const isDarkMode = ref(false)
243
+
244
+ function resetConversation() {
245
+ chatHistory.value = []
246
+ conversationId.value = generateUUID()
247
+ errorMessage.value = ''
248
+ }
249
+
250
+ function generateUUID() {
251
+ return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
252
  }
253
+
254
+ function toggleDarkMode() {
255
+ isDarkMode.value = !isDarkMode.value
256
+ applyDarkMode()
257
+ }
258
+
259
+ function applyDarkMode() {
260
+ if (isDarkMode.value) {
261
+ document.body.classList.add('dark-mode')
262
+ } else {
263
+ document.body.classList.remove('dark-mode')
264
+ }
265
+ }
266
+
267
+ async function sendMessage() {
268
+ if (!userInput.value.trim()) return
269
+
270
+ chatHistory.value.push({ type: 'user', content: userInput.value })
271
+ const userMessage = userInput.value
272
+ userInput.value = ''
273
+ isLoading.value = true
274
+ errorMessage.value = ''
275
 
276
  const payload = {
277
  prompt: userMessage,
278
+ model_id: modelId,
279
+ conversation_id: conversationId.value,
280
  user_id: "web_user"
281
+ }
282
 
283
  try {
284
  const response = await fetch('https://pvanand-audio-chat.hf.space/presentation-agent', {
285
  method: 'POST',
286
  headers: {
287
  'accept': 'application/json',
288
+ 'X-API-Key': AUTH_TOKEN,
289
  'Content-Type': 'application/json'
290
  },
291
  body: JSON.stringify(payload)
292
+ })
293
 
294
  if (!response.ok) {
295
+ const errorText = await response.text()
296
+ throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`)
297
  }
298
 
299
+ const data = await response.json()
300
  const botMessage = {
301
  type: 'bot',
302
  content: data.response ? marked.parse(data.response) : '',
303
+ html: data.html_presentation || null,
304
+ markdown_presentation: data.markdown_presentation || null
305
+ }
306
+ chatHistory.value.push(botMessage)
307
  } catch (error) {
308
+ errorMessage.value = `Error: ${error.message}`
309
  setTimeout(() => {
310
+ errorMessage.value = ''
311
+ }, 5000)
312
  } finally {
313
+ isLoading.value = false
314
  }
315
+ }
316
+
317
+ async function downloadPresentation(format, markdown) {
318
+ if (!markdown) return
319
+
320
+ try {
321
+ const response = await fetch('https://pvanand-audio-chat.hf.space/convert-md-to-presentation', {
322
+ method: 'POST',
323
+ headers: {
324
+ 'Content-Type': 'application/json',
325
+ 'accept': 'application/json'
326
+ },
327
+ body: JSON.stringify({
328
+ markdown: markdown,
329
+ output_format: format
330
+ })
331
+ })
332
+
333
+ if (!response.ok) {
334
+ throw new Error(`HTTP error! status: ${response.status}`)
335
+ }
336
+
337
+ let blob
338
+ if (format === 'html') {
339
+ const data = await response.json()
340
+ blob = new Blob([data.html], { type: 'text/html' })
341
+ } else {
342
+ blob = await response.blob()
343
+ }
344
+
345
+ const url = URL.createObjectURL(blob)
346
+ const a = document.createElement('a')
347
+ a.href = url
348
+ a.download = `presentation.${format}`
349
+ a.click()
350
+ URL.revokeObjectURL(url)
351
+ } catch (error) {
352
+ console.error('Error:', error)
353
+ alert(`Failed to download ${format.toUpperCase()}`)
354
  }
355
  }
356
+
357
+ return {
358
+ userInput,
359
+ chatHistory,
360
+ isLoading,
361
+ errorMessage,
362
+ isDarkMode,
363
+ sendMessage,
364
+ resetConversation,
365
+ toggleDarkMode,
366
+ downloadPresentation
367
+ }
368
  }
369
+ }).mount('#app')
370
  </script>
371
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
372
  </body>
373
  </html>