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
教室代碼
`;
}
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('');
}