amauricunha commited on
Commit
227440d
·
verified ·
1 Parent(s): 9f9f17f

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +31 -13
index.html CHANGED
@@ -15,7 +15,7 @@
15
  .btn-primary:hover:not(:disabled) { background-color: #4338ca; }
16
  .spinner { border: 2px solid rgba(255,255,255,0.3); width: 20px; height: 20px; border-radius: 50%; border-left-color: #fff; animation: spin 1s ease infinite; }
17
  @keyframes spin { to { transform: rotate(360deg); } }
18
- .flashcard-container { perspective: 1000px; }
19
  .flashcard-inner { position: relative; width: 100%; transition: transform 0.6s; transform-style: preserve-3d; }
20
  .flashcard-container.flipped .flashcard-inner { transform: rotateY(180deg); }
21
  .flashcard-front, .flashcard-back { position: absolute; width: 100%; height:100%; backface-visibility: hidden; border: 1px solid #e5e7eb; border-radius: 12px; padding: 20px; display: flex; flex-direction: column; justify-content: space-between; }
@@ -27,6 +27,8 @@
27
  .user-message { background-color: #4f46e5; color: white; align-self: flex-end; margin-left: auto; border-bottom-right-radius: 4px; }
28
  .ai-message { background-color: #e5e7eb; color: #1f2937; align-self: flex-start; border-bottom-left-radius: 4px; }
29
  .mic-button.is-recording { background-color: #ef4444; }
 
 
30
  </style>
31
  </head>
32
  <body class="p-4 md:p-8">
@@ -95,9 +97,8 @@
95
  </optgroup>
96
  <optgroup label="Groq (Ultra Rápido)">
97
  <option value="groq:llama-3.1-8b-instant">Llama 3.1 8B</option>
98
- <option value="groq:llama-3.1-70b-versatile">Llama 3.1 70B (Poderoso)</option>
99
- <option value="groq:gemma2-9b-it">Gemma2 9B (Novo)</option>
100
- <option value="groq:mixtral-8x7b-32768">Mixtral 8x7b</option>
101
  </optgroup>
102
  </select>
103
  </div>
@@ -175,7 +176,6 @@
175
  audioPlayer.play();
176
  audioPlayer.onended = () => URL.revokeObjectURL(audioUrl);
177
  } catch (error) {
178
- // MELHORIA: Exibe o erro para o usuário
179
  alert(`Erro ao gerar áudio: ${error.message}. Verifique o console para mais detalhes.`);
180
  } finally {
181
  playButton.disabled = false;
@@ -345,10 +345,9 @@
345
  throw new Error(errData.error || 'Erro desconhecido do servidor.');
346
  }
347
  const cardData = await response.json();
348
- if(definition && !cardData.definition) cardData.definition = definition; // Usa a definição da análise de imagem se a IA não retornar uma
349
  renderFlashcard(cardData);
350
  } catch (error) {
351
- // MELHORIA: Exibe o erro para o usuário
352
  alert(`Falha ao criar flashcard: ${error.message}. Verifique as chaves de API e a seleção do modelo.`);
353
  } finally {
354
  if (btn) {
@@ -373,26 +372,29 @@
373
  const minHeight = 380;
374
  container.style.minHeight = `${minHeight}px`;
375
 
 
 
376
  container.innerHTML = `
 
377
  <div class="flashcard-inner" style="min-height: ${minHeight}px;">
378
  <div class="flashcard-front">
379
  <div>
380
  <div class="text-sm text-gray-600 mb-2">Frase de Contexto:</div>
381
- <p class="text-lg text-center text-gray-800">${data.gapped_sentence || 'N/A'}</p>
382
  </div>
383
  <div class="border-t pt-4 mt-4 text-center">
384
- <strong class="text-indigo-600">Dica (PT):</strong> ${data.translation || 'N/A'}
385
  </div>
386
  <div class="text-xs text-center text-gray-400 mt-4">Clique para ver a resposta</div>
387
  </div>
388
  <div class="flashcard-back">
389
  <div>
390
- <h3 class="text-xl font-bold text-center text-indigo-600 mb-2">${data.term}</h3>
391
  <p class="flex items-center justify-center gap-2 text-gray-600 italic mb-3">
392
  <button class="audio-btn" onclick="playAudio('${(data.context_sentence || '').replace(/'/g, "\\'")}', event)">🔊</button>
393
- <span>${data.context_sentence || 'N/A'}</span>
394
  </p>
395
- <p class="text-sm text-gray-800"><strong class="font-semibold">Definição:</strong> ${data.definition || 'N/A'}</p>
396
  </div>
397
  <div class="border-t mt-3 pt-3">
398
  <h4 class="text-sm font-semibold text-center">Pratique sua Pronúncia</h4>
@@ -406,10 +408,26 @@
406
 
407
  flashcardList.prepend(container);
408
  container.addEventListener('click', (e) => {
409
- if(e.target.tagName !== 'BUTTON') container.classList.toggle('flipped');
 
 
 
410
  });
411
  }
412
 
 
 
 
 
 
 
 
 
 
 
 
 
 
413
  // --- LÓGICA DE PRÁTICA DE PRONÚNCIA ---
414
  async function handlePronunciationPractice(button, targetText, event) {
415
  event.stopPropagation();
 
15
  .btn-primary:hover:not(:disabled) { background-color: #4338ca; }
16
  .spinner { border: 2px solid rgba(255,255,255,0.3); width: 20px; height: 20px; border-radius: 50%; border-left-color: #fff; animation: spin 1s ease infinite; }
17
  @keyframes spin { to { transform: rotate(360deg); } }
18
+ .flashcard-container { perspective: 1000px; position: relative; } /* Posição relativa para o botão de excluir */
19
  .flashcard-inner { position: relative; width: 100%; transition: transform 0.6s; transform-style: preserve-3d; }
20
  .flashcard-container.flipped .flashcard-inner { transform: rotateY(180deg); }
21
  .flashcard-front, .flashcard-back { position: absolute; width: 100%; height:100%; backface-visibility: hidden; border: 1px solid #e5e7eb; border-radius: 12px; padding: 20px; display: flex; flex-direction: column; justify-content: space-between; }
 
27
  .user-message { background-color: #4f46e5; color: white; align-self: flex-end; margin-left: auto; border-bottom-right-radius: 4px; }
28
  .ai-message { background-color: #e5e7eb; color: #1f2937; align-self: flex-start; border-bottom-left-radius: 4px; }
29
  .mic-button.is-recording { background-color: #ef4444; }
30
+ .delete-btn { position: absolute; top: 10px; right: 10px; background: none; border: none; font-size: 1.2rem; cursor: pointer; color: #9ca3af; z-index: 10; }
31
+ .delete-btn:hover { color: #ef4444; }
32
  </style>
33
  </head>
34
  <body class="p-4 md:p-8">
 
97
  </optgroup>
98
  <optgroup label="Groq (Ultra Rápido)">
99
  <option value="groq:llama-3.1-8b-instant">Llama 3.1 8B</option>
100
+ <option value="groq:mixtral-8x7b-32768">Mixtral 8x7b (Balanceado)</option>
101
+ <option value="groq:gemma-7b-it">Gemma 7B (Confiável)</option>
 
102
  </optgroup>
103
  </select>
104
  </div>
 
176
  audioPlayer.play();
177
  audioPlayer.onended = () => URL.revokeObjectURL(audioUrl);
178
  } catch (error) {
 
179
  alert(`Erro ao gerar áudio: ${error.message}. Verifique o console para mais detalhes.`);
180
  } finally {
181
  playButton.disabled = false;
 
345
  throw new Error(errData.error || 'Erro desconhecido do servidor.');
346
  }
347
  const cardData = await response.json();
348
+ if(definition && !cardData.definition) cardData.definition = definition;
349
  renderFlashcard(cardData);
350
  } catch (error) {
 
351
  alert(`Falha ao criar flashcard: ${error.message}. Verifique as chaves de API e a seleção do modelo.`);
352
  } finally {
353
  if (btn) {
 
372
  const minHeight = 380;
373
  container.style.minHeight = `${minHeight}px`;
374
 
375
+ const fallback = 'Informação não gerada';
376
+
377
  container.innerHTML = `
378
+ <button class="delete-btn" onclick="deleteFlashcard('${cardId}', event)">🗑️</button>
379
  <div class="flashcard-inner" style="min-height: ${minHeight}px;">
380
  <div class="flashcard-front">
381
  <div>
382
  <div class="text-sm text-gray-600 mb-2">Frase de Contexto:</div>
383
+ <p class="text-lg text-center text-gray-800">${data.gapped_sentence || fallback}</p>
384
  </div>
385
  <div class="border-t pt-4 mt-4 text-center">
386
+ <strong class="text-indigo-600">Dica (PT):</strong> ${data.translation || fallback}
387
  </div>
388
  <div class="text-xs text-center text-gray-400 mt-4">Clique para ver a resposta</div>
389
  </div>
390
  <div class="flashcard-back">
391
  <div>
392
+ <h3 class="text-xl font-bold text-center text-indigo-600 mb-2">${data.term || 'Termo'}</h3>
393
  <p class="flex items-center justify-center gap-2 text-gray-600 italic mb-3">
394
  <button class="audio-btn" onclick="playAudio('${(data.context_sentence || '').replace(/'/g, "\\'")}', event)">🔊</button>
395
+ <span>${data.context_sentence || fallback}</span>
396
  </p>
397
+ <p class="text-sm text-gray-800"><strong class="font-semibold">Definição:</strong> ${data.definition || fallback}</p>
398
  </div>
399
  <div class="border-t mt-3 pt-3">
400
  <h4 class="text-sm font-semibold text-center">Pratique sua Pronúncia</h4>
 
408
 
409
  flashcardList.prepend(container);
410
  container.addEventListener('click', (e) => {
411
+ // Evita virar o card se um botão dentro dele for clicado
412
+ if(e.target.tagName !== 'BUTTON' && !e.target.closest('button')) {
413
+ container.classList.toggle('flipped');
414
+ }
415
  });
416
  }
417
 
418
+ // --- NOVA FUNÇÃO PARA EXCLUIR FLASHCARD ---
419
+ function deleteFlashcard(cardId, event) {
420
+ event.stopPropagation(); // Impede que o evento de clique se propague para o card (evitando que ele vire)
421
+ const cardToDelete = document.getElementById(cardId);
422
+ if (cardToDelete) {
423
+ cardToDelete.remove();
424
+ }
425
+ // Mostra a mensagem de "sem cards" se a lista ficar vazia
426
+ if (flashcardList.children.length === 1) { // Apenas a mensagem <p> restará
427
+ noCardsMessage.classList.remove('hidden');
428
+ }
429
+ }
430
+
431
  // --- LÓGICA DE PRÁTICA DE PRONÚNCIA ---
432
  async function handlePronunciationPractice(button, targetText, event) {
433
  event.stopPropagation();