1
Fork 0
countdown-timer/app.js
Leonardo Devai df19a2bbb9 Review and modernize all 42 projects to the updated standard
Pinned 2026 toolchains (Go 1.26, Rust 1.98/edition 2024, Python 3.14 + uv, Node 24,
Zig 0.16, NixOS 26.05), postgres 18 / mongo 8, lockfiles built from, non-root
runtimes, .dockerignore, per-project LICENSE, READMEs with the git.devai.io clone
line, checkout@v7 CI. Security fixes in the legacy Rust APIs (any-password login,
self-assigned admin, hard-coded JWT secret), JWT alg/exp/sub enforcement across the
blog series, safe markdown links in the frontends, and many smaller bugs — every
project was built, run and exercised end to end.

Adds scripts/publish.sh + a CI publish job that splits every folder into its own
repo at git.devai.io/templates/<folder>.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01128fhuZbgivaSJvtMf4s1G
2026-09-27 21:10:38 +02:00

50 lines
1.8 KiB
JavaScript

const targetInput = document.getElementById("target");
const daysEl = document.getElementById("days");
const hoursEl = document.getElementById("hours");
const minutesEl = document.getElementById("minutes");
const secondsEl = document.getElementById("seconds");
const messageEl = document.getElementById("message");
function nextNewYear() {
return new Date(new Date().getFullYear() + 1, 0, 1); // Jan 1st, midnight
}
let target = nextNewYear();
// setInterval hands back an id. We keep it so clearInterval can stop the clock.
let timer = null;
// tick() runs once a second. Subtracting two Dates gives the milliseconds
// between them; the rest is dividing that gap into days, hours, minutes, seconds.
function tick() {
const msLeft = target - new Date();
if (msLeft <= 0) {
daysEl.textContent = hoursEl.textContent = minutesEl.textContent = secondsEl.textContent = "0";
messageEl.textContent = "🎉 It's time!";
clearInterval(timer); // we're done — stop calling tick()
return;
}
messageEl.textContent = "";
const totalSeconds = Math.floor(msLeft / 1000);
daysEl.textContent = Math.floor(totalSeconds / 86400); // 86,400 seconds in a day
hoursEl.textContent = Math.floor((totalSeconds % 86400) / 3600);
minutesEl.textContent = Math.floor((totalSeconds % 3600) / 60);
secondsEl.textContent = totalSeconds % 60;
}
// Always clear the old interval before starting a new one — otherwise every
// date change would stack up another timer, all running at once.
function start() {
clearInterval(timer);
tick(); // show a value now instead of waiting a full second
timer = setInterval(tick, 1000);
}
targetInput.addEventListener("change", () => {
const picked = new Date(targetInput.value);
target = isNaN(picked.getTime()) ? nextNewYear() : picked; // empty box → New Year
start();
});
start();