FourLabs-UN2 commited on
Commit
673f34a
·
verified ·
1 Parent(s): ecbb7ed

Faça o background do modal de gerar código ser dessa cor apenas:

Browse files
Files changed (2) hide show
  1. README.md +9 -5
  2. index.html +765 -18
README.md CHANGED
@@ -1,10 +1,14 @@
1
  ---
2
- title: Codegenius Palette Pro
3
- emoji: 🐢
4
- colorFrom: indigo
5
- colorTo: indigo
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
1
  ---
2
+ title: CodeGenius Palette Pro 🎨
3
+ colorFrom: pink
4
+ colorTo: purple
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://deepsite.hf.co).
14
+
index.html CHANGED
@@ -1,19 +1,766 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
 
1
+
2
+
3
+
4
+
5
+
6
+ <!DOCTYPE html>
7
+ <html lang="en">
8
+ <head>
9
+ <meta charset="UTF-8">
10
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
11
+ <title>Mr. Mxyzptlk - Converse com um Modelo | Fourlabs</title>
12
+ <script src="https://cdn.tailwindcss.com"></script>
13
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
14
+ <link rel="icon" type="image/x-icon" href="/static/imgs/icon.svg">
15
+ <link rel="stylesheet" href="/static/style/dashboard.css">
16
+ <link rel="stylesheet" type="text/css" href="/static/style/alert.css">
17
+ <script src="https://unpkg.com/feather-icons"></script>
18
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
19
+ <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.net.min.js"></script>
20
+ <script>
21
+ tailwind.config = {
22
+ theme: {
23
+ extend: {
24
+ colors: {
25
+ primary: '#21223a',
26
+ secondary: '#ff580f',
27
+ }
28
+ }
29
+ }
30
+ }
31
+ </script>
32
+ </head>
33
+ <body class="bg-gray-100">
34
+ <div id="alert-container" style="position: fixed; top: 80px; right: 20px; z-index: 1000; width: 100%; max-width: 500px;"></div>
35
+ <div class="flex h-screen overflow-hidden">
36
+ <!-- Sidebar -->
37
+ <div class="sidebar bg-primary text-white w-64 md:w-20 lg:w-64 fixed h-full overflow-y-auto">
38
+ <div class="p-4 border-b border-gray-700">
39
+ <div class="w-full flex flex-col items-center justify-center">
40
+ <img
41
+ alt="logo"
42
+ loading="lazy"
43
+ width="100"
44
+ height="100"
45
+ decoding="async"
46
+ data-nimg="1"
47
+ class="w-36"
48
+ src="/static/imgs/logo-branco-labs.svg"
49
+ style="color: transparent;margin-top: 8px;"
50
+ >
51
+ <p
52
+ class="text-[10px] text-white mt-2 text-center"
53
+ style="margin-top: -1px; margin-left: 12px;font-size: 9px;">
54
+ Inovação e experimentação
55
+ </p>
56
+ </div>
57
+ </div>
58
+
59
+ <div class="p-4">
60
+ <div class="flex items-center space-x-3 mb-6">
61
+ <div class="w-10 h-10 rounded-full bg-secondary flex items-center justify-center">
62
+ <span class="font-bold">MS</span>
63
+ </div>
64
+ <div class="lg:block hidden">
65
+ <h3 class="font-semibold">Marlon Sousa</h3>
66
+ <p class="text-xs text-gray-400">Admin</p>
67
+ </div>
68
+ </div>
69
+
70
+ <nav>
71
+ <ul class="space-y-2">
72
+ <li>
73
+ <a href="/"
74
+ class="sidebar-item flex items-center p-3 rounded-lg
75
+ active">
76
+ <i class="fa-solid fa-server text-secondary w-6 text-center"></i>
77
+ <span class="ml-3 lg:block hidden">Instances</span>
78
+ </a>
79
+ </li>
80
+ <li>
81
+ <a href=""
82
+ class="sidebar-item flex items-center p-3 rounded-lg
83
+ ">
84
+ <i class="fa-solid fa-cubes text-secondary w-6 text-center"></i>
85
+ <span class="ml-3 lg:block hidden">Moxe</span>
86
+ </a>
87
+ </li>
88
+ <li>
89
+ <a href="/"
90
+ class="sidebar-item flex items-center p-3 rounded-lg
91
+ ">
92
+ <i class="fa-solid fa-robot text-secondary w-5 h-5 mr-3"></i>
93
+ <span class="ml-3 lg:block hidden">Agentes</span>
94
+ </a>
95
+ </li>
96
+ <li>
97
+ <a href="/"
98
+ class="sidebar-item flex items-center p-3 rounded-lg
99
+ ">
100
+ <i class="fa-solid fa-diagram-project text-secondary w-5 h-5 mr-3"></i>
101
+ <span class="ml-3 lg:block hidden">Projetos</span>
102
+ </a>
103
+ </li>
104
+ <li>
105
+ <a href="/"
106
+ class="sidebar-item flex items-center p-3 rounded-lg
107
+ ">
108
+ <i data-feather="activity" class="text-secondary w-5 h-5 mr-3"></i>
109
+ <span class="ml-3 lg:block hidden">Atividade</span>
110
+ </a>
111
+ </li>
112
+ <li>
113
+ <a href="/settings/"
114
+ class="sidebar-item flex items-center p-3 rounded-lg
115
+ ">
116
+ <i class="fa-solid fa-screwdriver-wrench text-secondary w-6 text-center"></i>
117
+ <span class="ml-3 lg:block hidden">Configurações</span>
118
+ </a>
119
+ </li>
120
+ </ul>
121
+ </nav>
122
+ </div>
123
+
124
+ <div class="absolute bottom-0 w-full p-4 border-t border-gray-700">
125
+ <form id="logout-form" method="POST" action="/account/logout/" class="hidden">
126
+ <input type="hidden" name="csrfmiddlewaretoken" value="MnYe4YaLuTb5AZgEnVFzWrZPFMBdPA80wkFGxjael4hIsejNxadyoK7h2ziCbTe5">
127
+ </form>
128
+
129
+ <a href="#" onclick="document.getElementById('logout-form').submit(); return false;" class="sidebar-item flex items-center p-3 rounded-lg">
130
+ <i class="fas fa-sign-out-alt text-secondary w-6 text-center"></i>
131
+ <span class="ml-3 lg:block hidden">Logout</span>
132
+ </a>
133
+ </div>
134
+ </div>
135
+
136
+ <!-- Main Content -->
137
+ <div class="flex-1 ml-0 md:ml-20 lg:ml-64 overflow-y-auto">
138
+ <!-- Top Navigation -->
139
+ <header class="bg-white shadow-sm">
140
+ <div class="flex items-center justify-between p-4">
141
+ <div class="flex items-center space-x-4">
142
+ <button id="mobileToggleSidebar" class="text-gray-600 lg:hidden block">
143
+ <i class="fas fa-bars text-xl"></i>
144
+ </button>
145
+ <h1 class="text-xl font-bold text-primary">Converse com um Modelo</h1>
146
+ </div>
147
+ <div class="flex items-center space-x-4">
148
+ <a href="/launch/" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-primary hover:bg-primary-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
149
+ <i data-feather="plus" class="mr-2 w-4 h-4"></i>
150
+ Subir Instância
151
+ </a>
152
+ <div class="relative">
153
+ <button id="notificationsBtn" class="relative">
154
+ <i class="fas fa-bell text-xl text-gray-600"></i>
155
+ <span class="absolute -top-1 -right-1 bg-secondary text-white text-xs rounded-full h-4 w-4 flex items-center justify-center">0</span>
156
+ </button>
157
+ <div id="notificationsDropdown" class="hidden absolute right-0 mt-2 w-80 bg-white rounded-md shadow-lg overflow-hidden z-50">
158
+ <div class="py-1">
159
+ <div class="px-4 py-2 border-b border-gray-200">
160
+ <h3 class="text-sm font-medium text-gray-700">Notifications</h3>
161
+ </div>
162
+
163
+ </div>
164
+ <div class="px-4 py-2 bg-gray-50 text-center">
165
+ <a href="#" class="text-sm font-medium text-secondary hover:text-primary">View all notifications</a>
166
+ </div>
167
+ </div>
168
+ </div>
169
+ </div>
170
+ </div>
171
+ </header>
172
+
173
+ <!-- Dashboard Content -->
174
+
175
+
176
+ <style>
177
+ :root {
178
+ --primary: #21223a;
179
+ --secondary: #ff580f;
180
+ }
181
+
182
+ .chat-container {
183
+ scroll-behavior: smooth;
184
+ height: calc(100% - 28%);
185
+ overflow-y: auto;
186
+ }
187
+
188
+ .message-bubble {
189
+ max-width: 80%;
190
+ animation: fadeIn 0.3s ease-in;
191
+ }
192
+
193
+ .typing-indicator {
194
+ display: inline-flex;
195
+ align-items: center;
196
+ gap: 4px;
197
+ }
198
+
199
+ .typing-dot {
200
+ width: 6px;
201
+ height: 6px;
202
+ background-color: var(--secondary);
203
+ border-radius: 50%;
204
+ animation: typing 1.4s infinite ease-in-out;
205
+ }
206
+
207
+ .typing-dot:nth-child(2) { animation-delay: 0.16s; }
208
+ .typing-dot:nth-child(3) { animation-delay: 0.32s; }
209
+
210
+ @keyframes typing {
211
+ 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
212
+ 30% { transform: translateY(-10px); opacity: 1; }
213
+ }
214
+
215
+ @keyframes fadeIn {
216
+ from { opacity: 0; transform: translateY(10px); }
217
+ to { opacity: 1; transform: translateY(0); }
218
+ }
219
+
220
+ .llm-option:hover {
221
+ transform: translateY(-2px);
222
+ box-shadow: 0 8px 25px rgba(33, 34, 58, 0.15);
223
+ }
224
+ </style>
225
+
226
+ <div class="bg-gray-50 border-b border-gray-200 p-3">
227
+ <div class="flex items-center justify-between">
228
+ <div class="flex items-center space-x-3">
229
+ <span class="text-sm text-gray-600">Modelo:</span>
230
+ <select class="w-full px-4 py-3 border border-gray-200 rounded-xl" name="model" id="modelSelect">
231
+
232
+
233
+
234
+ <option value="2c387c0e-838d-4c68-8257-296cf0b68469" selected>
235
+ granite-code:8b
236
+ </option>
237
+
238
+
239
+
240
+
241
+
242
+ <option value="5fef64b9-ac1d-4461-a9e9-148582e780f0" >
243
+ deepseek-r1:7b
244
+ </option>
245
+
246
+
247
+
248
+
249
+
250
+ <option value="95d05e19-6063-4fa2-804a-c551e37358b5" >
251
+ deepseek-r1:1.5b
252
+ </option>
253
+
254
+
255
+
256
+
257
+
258
+ <option value="0b685e78-a520-4d3a-8adc-f3f3305d4162" >
259
+ llama3.2:3b
260
+ </option>
261
+
262
+
263
+
264
+
265
+
266
+
267
+
268
+ </select>
269
+ </div>
270
+
271
+ <div class="flex items-center space-x-2">
272
+ <button
273
+ id="uploadPdfBtn"
274
+ class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[#ff580f]"
275
+ >
276
+ <i data-feather="upload" class="mr-2 w-4 h-4"></i>
277
+ Enviar PDF
278
+ </button>
279
+ <button
280
+ id="generateCodeBtn"
281
+ class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium
282
+ rounded-md text-white bg-secondary focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[#ff580f]"
283
+ >
284
+ <i data-feather="code" class="mr-2 w-4 h-4"></i>
285
+ Gerar Código
286
+ </button>
287
+
288
+
289
+ </div>
290
+ </div>
291
+ </div>
292
+
293
+
294
+ <!-- Chat Messages -->
295
+ <div class="flex-1 p-6 space-y-6 chat-container overflow-y-auto" id="chatMessages">
296
+ </div>
297
+
298
+ <!-- Input Area -->
299
+ <div class="bg-white border-t border-gray-200 p-6">
300
+ <div class="flex items-center space-x-4">
301
+ <div class="flex-1 relative">
302
+ <input
303
+ type="text"
304
+ placeholder="Digite sua mensagem..."
305
+ class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[#ff580f] focus:border-transparent"
306
+ id="messageInput"
307
+ >
308
+ <div class="absolute right-3 top-3 flex items-center space-x-2">
309
+ <button class="text-gray-400 hover:text-[#ff580f] transition-colors">
310
+ <i data-feather="paperclip"></i>
311
+ </button>
312
+ <button class="text-gray-400 hover:text-[#ff580f] transition-colors">
313
+ <i data-feather="mic"></i>
314
+ </button>
315
+ </div>
316
+ </div>
317
+ <button
318
+ class="bg-[#ff580f] hover:bg-[#e64a0c] text-white p-3 rounded-lg transition-colors duration-200"
319
+ onclick="sendMessage()"
320
+ >
321
+ <i data-feather="send"></i>
322
+ </button>
323
+ </div>
324
+
325
+ <div class="mt-3 flex items-center justify-end">
326
+ <span class="text-sm text-gray-500">⌘K para atalhos</span>
327
+ </div>
328
+ </div>
329
+
330
+ <div id="pdfUploadModal" class="hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50">
331
+ <div class="relative top-20 mx-auto p-5 border max-w-3xl shadow-lg rounded-md bg-white">
332
+ <div class="mt-3 text-center">
333
+ <div class="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-[#ff580f]">
334
+ <i data-feather="file-text" class="text-white"></i>
335
+ </div>
336
+ <h3 class="text-lg leading-6 font-medium text-gray-900 mt-2">
337
+ Enviar PDF
338
+ </h3>
339
+ <div class="mt-2 px-7 py-3">
340
+ <p class="text-sm text-gray-500">
341
+ Selecione um arquivo PDF para enviar e processar.
342
+ </p>
343
+ <form class="mt-4">
344
+ <div class="flex items-center justify-center w-full">
345
+ <label for="pdfFile" class="flex flex-col items-center justify-center w-full h-32 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 hover:bg-gray-100">
346
+ <div class="flex flex-col items-center justify-center pt-5 pb-6">
347
+ <i data-feather="upload-cloud" class="w-8 h-8 text-gray-400"></i>
348
+ <p class="mb-2 text-sm text-gray-500"><span class="font-semibold">Clique para enviar</span> ou arraste e solte</p>
349
+ <p class="text-xs text-gray-500">PDF (MAX. 10MB)</p>
350
+ </div>
351
+ <input id="pdfFile" name="pdfFile" type="file" class="hidden" accept=".pdf">
352
+ </label>
353
+ </div>
354
+ </form>
355
+ <div class="items-center px-4 py-3 mt-4">
356
+ <button
357
+ id="uploadSubmitBtn"
358
+ class="px-4 py-2 bg-[#ff580f] text-white text-base font-medium rounded-md w-full shadow-sm hover:bg-[#e64a0c] focus:outline-none focus:ring-2 focus:ring-[#ff580f]">
359
+ Enviar PDF
360
+ </button>
361
+ <button
362
+ id="uploadCancelBtn"
363
+ class="mt-3 px-4 py-2 bg-gray-300 text-gray-700 text-base font-medium rounded-md w-full shadow-sm hover:bg-gray-400 focus:outline-none focus:ring-2 focus:ring-gray-500">
364
+ Cancelar
365
+ </button>
366
+ </div>
367
+ </div>
368
+ </div>
369
+ </div>
370
+ </div>
371
+ <div id="codeModal" class="fixed inset-0 z-50 hidden bg-[#21223a] bg-opacity-50 flex items-center justify-center">
372
+ <div class="bg-white rounded-lg shadow-lg w-full max-w-5xl h-[75vh] flex flex-col p-6">
373
+ <!-- Cabeçalho -->
374
+ <div class="flex justify-between items-center mb-4 border-b pb-2">
375
+ <h2 class="text-xl font-semibold text-gray-800">Código para Ollama</h2>
376
+ <button id="closeModal" class="text-gray-500 hover:text-gray-700 text-xl leading-none">✕</button>
377
+ </div>
378
+
379
+ <!-- Linha do select + botões -->
380
+ <div class="flex items-end space-x-3 mb-4">
381
+ <div class="flex-1">
382
+ <label for="languageSelect" class="block text-sm font-medium text-gray-700 mb-1">Linguagem:</label>
383
+ <select
384
+ id="languageSelect"
385
+ class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-[#ff580f]"
386
+ >
387
+ <option value="python">Python</option>
388
+ <option value="javascript">JavaScript</option>
389
+ <option value="java">Java</option>
390
+ <option value="csharp">C#</option>
391
+ </select>
392
+ </div>
393
+
394
+ <button
395
+ id="copyCodeBtn"
396
+ class="inline-flex items-center px-3 py-2 border border-gray-300 rounded-md text-sm text-gray-700 bg-white hover:bg-gray-50 focus:outline-none"
397
+ >
398
+ <i data-feather="copy" class="mr-2 w-4 h-4"></i>
399
+ Copiar Código
400
+ </button>
401
+
402
+ <button
403
+ id="viewDocsBtn"
404
+ class="inline-flex items-center px-3 py-2 border border-gray-300 rounded-md text-sm text-gray-700 bg-white hover:bg-gray-50 focus:outline-none"
405
+ >
406
+ <i data-feather="book-open" class="mr-2 w-4 h-4"></i>
407
+ Ver Documentação
408
+ </button>
409
+ </div>
410
+
411
+ <!-- Código com highlight -->
412
+ <div class="flex-1 rounded-md p-4 overflow-auto border border-gray-700" style="background-color: #21223a;">
413
+ <pre class="h-full"><code id="exampleCode" class="language-python"></code></pre>
414
+ </div>
415
+ </div>
416
+ </div>
417
+
418
+
419
+ <script>
420
+ feather.replace();
421
+
422
+ // PDF Upload Modal Functionality
423
+ const uploadPdfBtn = document.getElementById('uploadPdfBtn');
424
+ const pdfUploadModal = document.getElementById('pdfUploadModal');
425
+ const uploadCancelBtn = document.getElementById('uploadCancelBtn');
426
+ const uploadSubmitBtn = document.getElementById('uploadSubmitBtn');
427
+ const pdfFileInput = document.getElementById('pdfFile');
428
+
429
+ uploadPdfBtn.addEventListener('click', function() {
430
+ pdfUploadModal.classList.remove('hidden');
431
+ });
432
+
433
+ uploadCancelBtn.addEventListener('click', function() {
434
+ pdfUploadModal.classList.add('hidden');
435
+ pdfFileInput.value = '';
436
+ });
437
+
438
+ uploadSubmitBtn.addEventListener('click', function() {
439
+ const file = pdfFileInput.files[0];
440
+ if (!file) {
441
+ alert('Por favor, selecione um arquivo PDF.');
442
+ return;
443
+ }
444
+
445
+ if (file.type !== 'application/pdf') {
446
+ alert('Por favor, selecione apenas arquivos PDF.');
447
+ return;
448
+ }
449
+
450
+ if (file.size > 10 * 1024 * 1024) {
451
+ alert('O arquivo é muito grande. Tamanho máximo: 10MB.');
452
+ return;
453
+ }
454
+
455
+ // Simulate file upload
456
+ addMessage(`PDF enviado: ${file.name}`, 'user');
457
+ addMessage(`Estou processando o arquivo "${file.name}". Em breve poderei responder perguntas sobre seu conteúdo.`, 'ai');
458
+
459
+ pdfUploadModal.classList.add('hidden');
460
+ pdfFileInput.value = '';
461
+ });
462
+
463
+ // Close modal when clicking outside
464
+ pdfUploadModal.addEventListener('click', function(e) {
465
+ if (e.target === pdfUploadModal) {
466
+ pdfUploadModal.classList.add('hidden');
467
+ pdfFileInput.value = '';
468
+ }
469
+ });
470
+
471
+ const chatMessages = document.getElementById('chatMessages');
472
+ const messageInput = document.getElementById('messageInput');
473
+
474
+ function sendMessage() {
475
+ const message = messageInput.value.trim();
476
+ if (!message) return;
477
+
478
+ const modelSelect = document.querySelector("select");
479
+ const selectedModelId = modelSelect.value;
480
+
481
+ addMessage(message, 'user');
482
+ messageInput.value = '';
483
+ addTypingIndicator();
484
+
485
+ fetch("/chatbot/", {
486
+ method: "POST",
487
+ headers: {
488
+ "Content-Type": "application/json",
489
+ "X-CSRFToken": getCookie("csrftoken")
490
+ },
491
+ body: JSON.stringify({
492
+ message: message,
493
+ model_id: selectedModelId
494
+ })
495
+ })
496
+ .then(response => {
497
+ const reader = response.body.getReader();
498
+ const decoder = new TextDecoder();
499
+ let accumulatedText = "";
500
+
501
+ function readChunk() {
502
+ reader.read().then(({ done, value }) => {
503
+ if (done) {
504
+ removeTypingIndicator();
505
+ addMessage(accumulatedText.trim(), 'ai');
506
+ return;
507
+ }
508
+
509
+ const chunk = decoder.decode(value, { stream: true });
510
+ const lines = chunk.split("\n\n");
511
+ for (const line of lines) {
512
+ if (line.startsWith("data: ")) {
513
+ const data = line.replace("data: ", "");
514
+ if (data === "[FIM]") {
515
+ removeTypingIndicator();
516
+ addMessage(accumulatedText.trim(), 'ai');
517
+ return;
518
+ } else {
519
+ console.log(data)
520
+ accumulatedText += data;
521
+ updateTypingIndicatorText(accumulatedText);
522
+ }
523
+ }
524
+ }
525
+ readChunk();
526
+ });
527
+ }
528
+
529
+ readChunk();
530
+ })
531
+ .catch(error => {
532
+ console.error(error);
533
+ removeTypingIndicator();
534
+ addMessage("Erro ao conectar com o servidor.", 'ai');
535
+ });
536
+ }
537
+
538
+ function getCookie(name) {
539
+ let cookieValue = null;
540
+ if (document.cookie && document.cookie !== '') {
541
+ const cookies = document.cookie.split(';');
542
+ for (let i = 0; i < cookies.length; i++) {
543
+ const cookie = cookies[i].trim();
544
+ if (cookie.substring(0, name.length + 1) === (name + '=')) {
545
+ cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
546
+ break;
547
+ }
548
+ }
549
+ }
550
+ return cookieValue;
551
+ }
552
+
553
+ function updateTypingIndicatorText(text) {
554
+ const typingIndicator = document.getElementById('typingIndicator');
555
+ if (typingIndicator) {
556
+ typingIndicator.innerHTML = `<p>${text}</p>`;
557
+ chatMessages.scrollTop = chatMessages.scrollHeight;
558
+ }
559
+ }
560
+
561
+ function addMessage(text, sender) {
562
+ const messageDiv = document.createElement('div');
563
+ messageDiv.className = `message-bubble ${sender === 'user' ? 'bg-white rounded-2xl p-4 shadow-md ml-auto' : 'bg-[#21223a] text-white rounded-2xl p-4 shadow-md'}`;
564
+
565
+ const messageContent = document.createElement('p');
566
+ messageContent.className = sender === 'user' ? 'text-gray-800' : 'text-white';
567
+ messageContent.textContent = text;
568
+
569
+ const timestamp = document.createElement('span');
570
+ timestamp.className = `text-xs block mt-2 ${sender === 'user' ? 'text-gray-500' : 'text-gray-300'}`;
571
+ timestamp.textContent = new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
572
+
573
+ messageDiv.appendChild(messageContent);
574
+ messageDiv.appendChild(timestamp);
575
+ chatMessages.appendChild(messageDiv);
576
+
577
+ // Scroll to bottom
578
+ chatMessages.scrollTop = chatMessages.scrollHeight;
579
+ }
580
+
581
+ function addTypingIndicator() {
582
+ const typingDiv = document.createElement('div');
583
+ typingDiv.className = 'message-bubble bg-[#21223a] text-white rounded-2xl p-4 shadow-md';
584
+ typingDiv.id = 'typingIndicator';
585
+
586
+ const typingContent = document.createElement('div');
587
+ typingContent.className = 'typing-indicator';
588
+
589
+ for (let i = 0; i < 3; i++) {
590
+ const dot = document.createElement('div');
591
+ dot.className = 'typing-dot';
592
+ typingContent.appendChild(dot);
593
+ }
594
+
595
+ typingDiv.appendChild(typingContent);
596
+ chatMessages.appendChild(typingDiv);
597
+
598
+ // Scroll to bottom
599
+ chatMessages.scrollTop = chatMessages.scrollHeight;
600
+ }
601
+
602
+ function removeTypingIndicator() {
603
+ const typingIndicator = document.getElementById('typingIndicator');
604
+ if (typingIndicator) {
605
+ typingIndicator.remove();
606
+ }
607
+ }
608
+
609
+ // Enter key to send message
610
+ messageInput.addEventListener('keypress', function(e) {
611
+ if (e.key === 'Enter') {
612
+ sendMessage();
613
+ }
614
+ });
615
+
616
+ // LLM selection
617
+ document.querySelectorAll('.llm-option').forEach(option => {
618
+ option.addEventListener('click', function() {
619
+ document.querySelectorAll('.llm-option').forEach(opt => {
620
+ opt.classList.remove('border-[#ff580f]');
621
+ });
622
+ this.classList.add('border-[#ff580f]');
623
+
624
+ const modelName = this.querySelector('span').textContent;
625
+ document.querySelector('.mt-3 span:first-child').textContent = `Modelo selecionado: ${modelName}`;
626
+ });
627
+ });
628
+ </script>
629
+
630
+ <link href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.css" rel="stylesheet" />
631
+ <script src="https://cdn.jsdelivr.net/npm/prismjs/prism.js"></script>
632
+ <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-python.min.js"></script>
633
+ <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-javascript.min.js"></script>
634
+ <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-java.min.js"></script>
635
+ <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-csharp.min.js"></script>
636
+
637
+ <script>
638
+ document.addEventListener("DOMContentLoaded", () => {
639
+ feather.replace();
640
+
641
+ // Abrir modal
642
+ const openModal = document.getElementById("generateCodeBtn");
643
+ const codeModal = document.getElementById("codeModal");
644
+ const closeModal = document.getElementById("closeModal");
645
+
646
+ openModal.addEventListener("click", () => codeModal.classList.remove("hidden"));
647
+ closeModal.addEventListener("click", () => codeModal.classList.add("hidden"));
648
+
649
+ // Referências
650
+ const languageSelect = document.getElementById("languageSelect");
651
+ const codeEl = document.getElementById("exampleCode");
652
+ const copyBtn = document.getElementById("copyCodeBtn");
653
+ const docsBtn = document.getElementById("viewDocsBtn");
654
+
655
+ // Exemplos
656
+ const codeExamples = {
657
+ python: `import ollama
658
+
659
+ response = ollama.chat(model="llama3", messages=[
660
+ {"role": "user", "content": "Olá, mundo!"}
661
+ ])
662
+
663
+ print(response['message']['content'])`,
664
+ javascript: `import ollama from "ollama";
665
+
666
+ const response = await ollama.chat({
667
+ model: "llama3",
668
+ messages: [{ role: "user", content: "Olá, mundo!" }],
669
+ });
670
+
671
+ console.log(response.message.content);`,
672
+ java: `import java.util.*;
673
+
674
+ public class Main {
675
+ public static void main(String[] args) {
676
+ System.out.println("Olá, mundo!");
677
+ }
678
+ }`,
679
+ csharp: `using System;
680
+
681
+ class Program {
682
+ static void Main() {
683
+ Console.WriteLine("Olá, mundo!");
684
+ }
685
+ }`
686
+ };
687
+
688
+ // Atualizar código + highlight
689
+ languageSelect.addEventListener("change", (e) => {
690
+ const lang = e.target.value;
691
+ codeEl.className = "language-" + lang;
692
+ codeEl.textContent = codeExamples[lang];
693
+ Prism.highlightElement(codeEl);
694
+ });
695
+
696
+ // Copiar código
697
+ copyBtn.addEventListener("click", () => {
698
+ navigator.clipboard.writeText(codeEl.textContent);
699
+ copyBtn.innerHTML = '<i data-feather="check" class="mr-2 w-4 h-4"></i>Copiado!';
700
+ feather.replace();
701
+ setTimeout(() => {
702
+ copyBtn.innerHTML = '<i data-feather="copy" class="mr-2 w-4 h-4"></i>Copiar Código';
703
+ feather.replace();
704
+ }, 1500);
705
+ });
706
+
707
+ // Ver documentação
708
+ const docsUrls = {
709
+ python: "https://docs.python.org/3/",
710
+ javascript: "https://developer.mozilla.org/pt-BR/docs/Web/JavaScript",
711
+ java: "https://docs.oracle.com/en/java/",
712
+ csharp: "https://learn.microsoft.com/dotnet/csharp/"
713
+ };
714
+ docsBtn.addEventListener("click", () => {
715
+ const lang = languageSelect.value;
716
+ window.open(docsUrls[lang], "_blank");
717
+ });
718
+
719
+ // Inicial highlight
720
+ Prism.highlightElement(codeEl);
721
+ });
722
+ </script>
723
+
724
+
725
+
726
+ </div>
727
+ </div>
728
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
729
+ <script>
730
+ // Initialize Vanta.js background
731
+ VANTA.NET({
732
+ el: "#vanta-bg",
733
+ mouseControls: true,
734
+ touchControls: true,
735
+ gyroControls: false,
736
+ minHeight: 200.00,
737
+ minWidth: 200.00,
738
+ scale: 1.00,
739
+ scaleMobile: 1.00,
740
+ color: 0x3b82f6,
741
+ backgroundColor: 0xf8fafc,
742
+ points: 12.00,
743
+ maxDistance: 22.00,
744
+ spacing: 18.00
745
+ });
746
+ // Initialize feather icons
747
+ feather.replace();
748
+
749
+ // Pagination functionality
750
+ document.querySelectorAll('.pagination a').forEach(link => {
751
+ link.addEventListener('click', function(e) {
752
+ e.preventDefault();
753
+ // Here you would typically fetch the next page of results
754
+ // For demo purposes we'll just show an alert
755
+ if(this.textContent.trim() === '2' || this.textContent.trim() === '3') {
756
+ alert('Loading page ' + this.textContent.trim());
757
+ }
758
+ });
759
+ });
760
+ </script>
761
+ <script src="/static/script/alert.js"></script>
762
+
763
+
764
+ </body>
765
  </html>
766
+