Programmer's Picnic • Phase 2 HTML/JS
Home
⭐ Phase 2 • Timer

Milestone 26: Timer Expiry Rule

Auto-lock when time becomes 0.

65% complete

🎯 Goal

Complete this milestone so the KBC HTML/JavaScript project moves one step closer to the final working app.

🖼 Expected Output SVG

This diagram defines what the project output should include at this milestone.

Milestone 26 output diagram

🔨 Fully Defined Task

What to build

  • Open the files listed in this milestone.
  • Add only the feature described by this milestone.
  • Use the SVG output diagram to understand the target result.
  • Compare your work with the code-up-to-this-point snapshot.
  • Run the project in the browser and fix console errors.

Acceptance Criteria

  • The feature works without console errors.
  • The output matches the SVG diagram for this milestone.
  • The code uses current project state and JSON where applicable.

Submit to Teacher

  • Screenshot of the working feature.
  • Short explanation of the changed code.
  • Git commit message for this milestone.

📄 Files and Code Snapshot

Open the complete code up to this milestone:

💻 Code Up To This Point

View milestone 26 code
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>KBC Quiz</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="app">
    <header class="top"><h1>KBC Quiz</h1>
    </header>
    <section class="game">
      <aside><h2>Prize Ladder</h2><ol id="ladder"></ol></aside>
      <section class="stage">
        <div class="meta"><span id="timer">Time: 30</span><span id="score">Score: 0</span></div>
        <h2 id="question">Question will appear here</h2>
        <div id="options">
        </div>
        <p id="message"></p>
        <button id="nextBtn">Next Question</button>
      </section>
    </section>
  </main>
  <script src="app.js"></script>
</body>
</html>

style.css

body{font-family:Arial;background:#061533;color:white;margin:0}.app{max-width:1100px;margin:auto;padding:24px}button{cursor:pointer}\n.top{display:flex;justify-content:space-between;align-items:center}.top h1{color:#ffd54f}\n.game{display:grid;grid-template-columns:260px 1fr;gap:20px}.stage,aside{background:rgba(255,255,255,.1);border-radius:24px;padding:22px;text-align:center}\n.option{display:block;width:100%;margin:12px 0;padding:14px;border-radius:999px;background:#102d6b;color:white;border:1px solid #ffd54f}\n.correct{background:#00c853}.wrong{background:#ff5252}\n@media(max-width:800px){.game{grid-template-columns:1fr}.top{flex-direction:column}}

app.js

let questions=[];
let current=0;
let score=0;
let selected=null;
let time=30;
let timer=null;
fetch('questions.json').then(r=>r.json()).then(data=>{ questions=data; showQuestion(); });
function showQuestion(){
  const q=questions[current];
  document.getElementById('question').textContent=(current+1)+'. '+q.question;
  const options=document.getElementById('options');
  options.innerHTML='';
  q.options.forEach(opt=>{
    const btn=document.createElement('button');
    btn.className='option';
    btn.textContent=opt;
    btn.onclick=()=>selectAnswer(btn,opt);
    options.appendChild(btn);
  });
  document.getElementById('score').textContent='Score: '+score;
  startTimer();
}
function selectAnswer(btn,opt){
  if(selected!==null)return;
  selected=opt;
  checkAnswer(btn);
}
function checkAnswer(btn){
  const correct=questions[current].answer;
  document.querySelectorAll('.option').forEach(b=>{ b.disabled=true; if(b.textContent===correct)b.classList.add('correct'); });
  if(selected===correct){ score++; document.getElementById('message').textContent='Correct!'; }
  else{ if(btn)btn.classList.add('wrong'); document.getElementById('message').textContent='Wrong. Correct: '+correct; }
}
document.getElementById('nextBtn').onclick=()=>{ current++; if(current>=questions.length){ showResult(); return; } selected=null; showQuestion(); };
function startTimer(){ clearInterval(timer); time=30; timer=setInterval(()=>{ time--; document.getElementById('timer').textContent='Time: '+time; if(time<=0){ clearInterval(timer); checkAnswer(null); } },1000); }

▶ Run This Milestone

Open milestone-code/milestone-26/index.html in your browser.
For best results use VS Code Live Server.

🐞 Debugging Challenge

If this milestone does not work:
1. Check that the correct milestone-code folder is open.
2. Check browser console.
3. Check JSON commas and quotes.
4. Compare with the SVG diagram.
5. Compare with the code snapshot.

🌐 GitHub Commit

git add .
git commit -m "Phase 2 milestone 26: Timer Expiry Rule"
git push

🏆 Completion Checklist