import { submitPrompt, getChallenges } from "../services/classroom.js"; import { getPeerPrompts } from "../services/classroom.js"; // Import needed for modal // Cache challenges locally to avoid refetching heavily let cachedChallenges = []; export async function renderStudentView() { const nickname = localStorage.getItem('vibecoding_nickname') || 'Guest'; // Fetch challenges if empty if (cachedChallenges.length === 0) { try { cachedChallenges = await getChallenges(); } catch (e) { console.error("Failed to fetch challenges", e); throw new Error("無法讀取題目列表,請檢查網路連線 (Error: " + e.message + ")"); } } // Group by Level (optional, but good for UI organization if we wanted headers) // For now, let's just map them. // Or if we want to keep the headers: const levelGroups = { beginner: cachedChallenges.filter(c => c.level === 'beginner'), intermediate: cachedChallenges.filter(c => c.level === 'intermediate'), advanced: cachedChallenges.filter(c => c.level === 'advanced') }; const levelNames = { beginner: "初級 (Beginner)", intermediate: "中級 (Intermediate)", advanced: "高級 (Advanced)" }; const renderCard = (c) => `

${c.title}

${c.description}

Go to Task
`; // Render logic let contentHtml = ''; if (cachedChallenges.length === 0) { contentHtml = '
目前沒有題目,請請講師至後台新增。
'; } else { ['beginner', 'intermediate', 'advanced'].forEach(levelId => { const tasks = levelGroups[levelId] || []; if (tasks.length > 0) { contentHtml += `

${levelNames[levelId]}

${tasks.map(renderCard).join('')}
`; } }); } return `
${nickname}
教室: ${roomCode}

VIBECODING

${contentHtml}
`; } export function setupStudentEvents() { window.submitLevel = async (challengeId) => { const input = document.getElementById(`input-${challengeId}`); const errorMsg = document.getElementById(`error-${challengeId}`); const prompt = input.value; const roomCode = localStorage.getItem('vibecoding_room_code'); const userId = localStorage.getItem('vibecoding_user_id'); if (!participantDataCheck(roomCode, userId)) return; // Validation Rule: Length >= 5 if (prompt.trim().length < 5) { errorMsg.classList.remove('hidden'); input.classList.add('border-red-500'); return; } // Reset error state errorMsg.classList.add('hidden'); input.classList.remove('border-red-500'); try { await submitPrompt(userId, roomCode, challengeId, prompt); // Visual feedback const container = input.parentElement; const btn = container.querySelector('button'); const originalText = btn.textContent; btn.textContent = "✓ 已提交"; btn.classList.add("bg-green-600", "from-green-600", "to-green-600"); setTimeout(() => { btn.textContent = originalText; btn.classList.remove("bg-green-600", "from-green-600", "to-green-600"); }, 2000); } catch (error) { console.error(error); alert("提交失敗: " + error.message); } }; } function participantDataCheck(roomCode, userId) { if (!roomCode || !userId) { alert("連線資訊遺失,請重新登入"); window.location.reload(); return false; } return true; } // Peer Learning Modal Logic function renderPeerModal() { // Dropdown options based on cachedChallenges let optionsHtml = ''; if (cachedChallenges.length > 0) { optionsHtml += cachedChallenges.map(c => `` ).join(''); } return ` `; } window.openPeerModal = () => { // Remove existing modal if any to ensure fresh render (especially for dropdown) const existing = document.getElementById('peer-modal'); if (existing) existing.remove(); const div = document.createElement('div'); div.innerHTML = renderPeerModal(); document.body.appendChild(div.firstElementChild); document.getElementById('peer-modal').classList.remove('hidden'); }; window.closePeerModal = () => { document.getElementById('peer-modal').classList.add('hidden'); }; window.loadPeerPrompts = async (challengeId) => { const container = document.getElementById('peer-prompts-container'); container.innerHTML = '
載入中...
'; const roomCode = localStorage.getItem('vibecoding_room_code'); const prompts = await getPeerPrompts(roomCode, challengeId); if (prompts.length === 0) { container.innerHTML = '
尚無同學提交此關卡
'; return; } container.innerHTML = prompts.map(p => `
${p.nickname[0]}
${p.nickname} ${new Date(p.timestamp.seconds * 1000).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}

${p.prompt}

`).join(''); };