import { createRoom, subscribeToRoom, getChallenges } from "../services/classroom.js"; let cachedChallenges = []; export async function renderInstructorView() { // Pre-fetch challenges for table headers cachedChallenges = await getChallenges(); return `

🔒 講師身分驗證

講師儀表板 Instructor Dashboard

or
`; } export function setupInstructorEvents() { // Auth Logic const authBtn = document.getElementById('auth-btn'); const pwdInput = document.getElementById('instructor-password'); const authModal = document.getElementById('auth-modal'); authBtn.addEventListener('click', () => checkPassword()); pwdInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') checkPassword(); }); function checkPassword() { if (pwdInput.value === '88300') { authModal.classList.add('hidden'); } else { alert('密碼錯誤'); pwdInput.value = ''; } } const createBtn = document.getElementById('create-room-btn'); const roomInfo = document.getElementById('room-info'); const createContainer = document.getElementById('create-room-container'); const dashboardContent = document.getElementById('dashboard-content'); const displayRoomCode = document.getElementById('display-room-code'); const studentsGrid = document.getElementById('students-grid'); const navAdminBtn = document.getElementById('nav-admin-btn'); navAdminBtn.addEventListener('click', () => { window.location.hash = 'admin'; }); // Auto-fill room code from local storage const savedRoomCode = localStorage.getItem('vibecoding_instructor_room'); if (savedRoomCode) { document.getElementById('rejoin-room-code').value = savedRoomCode; } const rejoinBtn = document.getElementById('rejoin-room-btn'); rejoinBtn.addEventListener('click', () => { const code = document.getElementById('rejoin-room-code').value.trim(); if (!code) return alert('請輸入教室代碼'); enterRoom(code); }); createBtn.addEventListener('click', async () => { try { createBtn.disabled = true; createBtn.textContent = "建立中..."; const roomCode = await createRoom(); enterRoom(roomCode); } catch (error) { console.error(error); alert("建立教室失敗"); createBtn.disabled = false; } }); function enterRoom(roomCode) { // UI Switch createContainer.classList.add('hidden'); roomInfo.classList.remove('hidden'); dashboardContent.classList.remove('hidden'); displayRoomCode.textContent = roomCode; // Save to local storage localStorage.setItem('vibecoding_instructor_room', roomCode); // Subscribe to updates subscribeToRoom(roomCode, (students) => { renderStudentCards(students, studentsGrid); }); } } function renderStudentCards(students, container) { if (students.length === 0) { container.innerHTML = '
尚無學員加入
'; return; } // Sort students by join time (if available) or random // students.sort((a,b) => a.joinedAt - b.joinedAt); container.innerHTML = students.map(student => { const progress = student.progress || {}; // Map of challengeId -> {status, prompt ...} // Progress Summary let totalCompleted = 0; let badgesHtml = cachedChallenges.map(c => { const isCompleted = progress[c.id]?.status === 'completed'; if (isCompleted) totalCompleted++; // Only show completed dots/badges or progress bar to save space? // User requested "Card showing status". 15 items is a lot for small badges. // Let's us simple dots color-coded by level. const colors = { beginner: 'cyan', intermediate: 'blue', advanced: 'purple' }; const color = colors[c.level] || 'gray'; return `
`; }).join(''); return `
${student.nickname[0]}

${student.nickname}

完成度: ${totalCompleted} / ${cachedChallenges.length}

${badgesHtml}
`; }).join(''); }