Lashtw commited on
Commit
0ef1453
·
verified ·
1 Parent(s): 4a115f4

Upload 9 files

Browse files
src/services/auth.js CHANGED
@@ -2,7 +2,8 @@ import { auth, db } from "./firebase.js";
2
  import {
3
  signInWithEmailAndPassword,
4
  createUserWithEmailAndPassword,
5
- signOut
 
6
  } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-auth.js";
7
  import {
8
  doc,
 
2
  import {
3
  signInWithEmailAndPassword,
4
  createUserWithEmailAndPassword,
5
+ signOut,
6
+ sendPasswordResetEmail
7
  } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-auth.js";
8
  import {
9
  doc,
src/views/InstructorView.js CHANGED
@@ -218,9 +218,7 @@ export async function renderInstructorView() {
218
 
219
  <!-- Eraser -->
220
  <button class="annotation-tool p-2 rounded-full hover:bg-gray-700 transition-colors ring-2 ring-transparent focus:outline-none flex items-center justify-center" data-tool="eraser" onclick="setPenTool('eraser', null, this)" title="橡皮擦">
221
- <svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
222
- <path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
223
- </svg>
224
  </button>
225
 
226
  <div class="w-px h-6 bg-gray-600 mx-2"></div>
@@ -433,6 +431,41 @@ export function setupInstructorEvents() {
433
  }
434
  });
435
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
436
  // Register Handler
437
  registerBtn.addEventListener('click', async () => {
438
  const email = loginEmailInput.value;
@@ -1198,7 +1231,7 @@ export function setupInstructorEvents() {
1198
  document.getElementById('broadcast-content').classList.add('hidden');
1199
  const stage = document.getElementById('stage-view');
1200
  stage.classList.remove('hidden');
1201
- document.getElementById('stage-prompt').textContent = prompt;
1202
  document.getElementById('stage-author').textContent = author;
1203
  };
1204
 
@@ -1312,7 +1345,7 @@ export function setupInstructorEvents() {
1312
  onchange="handlePromptSelection(this)">
1313
  </div>
1314
  <!-- Prompt Content -->
1315
- <div class="bg-black/30 rounded p-2 flex-1 overflow-y-auto font-mono text-green-300 whitespace-pre-wrap custom-scrollbar text-base leading-snug group-hover:text-green-200 transaction-colors mb-2">${p.prompt}</div>
1316
 
1317
  <!-- Footer: Time + Actions -->
1318
  <div class="flex justify-between items-center text-[10px] text-gray-500 mt-auto">
@@ -1491,7 +1524,7 @@ export function setupInstructorEvents() {
1491
  </div>
1492
  <!-- Prompt Content: Larger Text (text-4xl) -->
1493
  <div class="flex-1 overflow-y-auto font-mono text-green-300 text-4xl leading-relaxed whitespace-pre-wrap p-2 hover:bg-white/5 transition-colors rounded custom-scrollbar">
1494
- ${item.prompt}
1495
  </div>
1496
  `;
1497
  grid.appendChild(col);
 
218
 
219
  <!-- Eraser -->
220
  <button class="annotation-tool p-2 rounded-full hover:bg-gray-700 transition-colors ring-2 ring-transparent focus:outline-none flex items-center justify-center" data-tool="eraser" onclick="setPenTool('eraser', null, this)" title="橡皮擦">
221
+ <img src="assets/eraser.svg" class="w-6 h-6 object-contain" alt="Eraser">
 
 
222
  </button>
223
 
224
  <div class="w-px h-6 bg-gray-600 mx-2"></div>
 
431
  }
432
  });
433
 
434
+ // Forgot Password Handler
435
+ const forgotBtn = document.createElement('button');
436
+ forgotBtn.textContent = "忘記密碼?";
437
+ forgotBtn.className = "text-sm text-gray-400 hover:text-white mt-2 underline block mx-auto"; // Centered link
438
+
439
+ // Insert after auth-error message or append to modal content?
440
+ // Appending to the parent of Login Button seems best, or just below it.
441
+ // The modal structure in index.html is needed to know exact placement.
442
+ // Assuming loginBtn is inside a flex column form.
443
+ loginBtn.parentNode.insertBefore(forgotBtn, loginBtn.nextSibling);
444
+
445
+ forgotBtn.addEventListener('click', async () => {
446
+ const email = loginEmailInput.value;
447
+ if (!email) {
448
+ authErrorMsg.textContent = "請先在上欄輸入 Email 以發送重設信";
449
+ authErrorMsg.classList.remove('hidden');
450
+ return;
451
+ }
452
+ if (!confirm(`確定要發送重設密碼信件至 ${email} 嗎?`)) return;
453
+
454
+ try {
455
+ // Dynamically import to avoid top-level dependency if not needed
456
+ const { resetPassword } = await import("../services/auth.js");
457
+ await resetPassword(email);
458
+ alert(`已發送重設密碼信件至 ${email},請查收信箱並依照指示重設密碼。`);
459
+ authErrorMsg.classList.add('hidden');
460
+ } catch (e) {
461
+ console.error(e);
462
+ let msg = e.message;
463
+ if (e.code === 'auth/user-not-found') msg = "找不到此帳號,請確認 Email 是否正確。";
464
+ authErrorMsg.textContent = "發送失敗: " + msg;
465
+ authErrorMsg.classList.remove('hidden');
466
+ }
467
+ });
468
+
469
  // Register Handler
470
  registerBtn.addEventListener('click', async () => {
471
  const email = loginEmailInput.value;
 
1231
  document.getElementById('broadcast-content').classList.add('hidden');
1232
  const stage = document.getElementById('stage-view');
1233
  stage.classList.remove('hidden');
1234
+ document.getElementById('stage-prompt').textContent = (prompt || '').trim();
1235
  document.getElementById('stage-author').textContent = author;
1236
  };
1237
 
 
1345
  onchange="handlePromptSelection(this)">
1346
  </div>
1347
  <!-- Prompt Content -->
1348
+ <div class="bg-black/30 rounded p-2 flex-1 overflow-y-auto font-mono text-green-300 whitespace-pre-wrap custom-scrollbar text-base leading-snug group-hover:text-green-200 transaction-colors mb-2">${(p.prompt || '').trim()}</div>
1349
 
1350
  <!-- Footer: Time + Actions -->
1351
  <div class="flex justify-between items-center text-[10px] text-gray-500 mt-auto">
 
1524
  </div>
1525
  <!-- Prompt Content: Larger Text (text-4xl) -->
1526
  <div class="flex-1 overflow-y-auto font-mono text-green-300 text-4xl leading-relaxed whitespace-pre-wrap p-2 hover:bg-white/5 transition-colors rounded custom-scrollbar">
1527
+ ${(item.prompt || '').trim()}
1528
  </div>
1529
  `;
1530
  grid.appendChild(col);