Skip to content
dehyabiPublic

About

Timer hitung mundur sederhana dan ringan, dibangun dengan Next.js 16 (App Router) + Tailwind CSS v4. Tanpa dependensi tambahan di luar bawaan Next — tidak ada state library, tidak ada komponen UI pihak ketiga.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Timer

Timer hitung mundur sederhana dan ringan, dibangun dengan Next.js 16 (App Router) + Tailwind CSS v4. Tanpa dependensi tambahan di luar bawaan Next — tidak ada state library, tidak ada komponen UI pihak ketiga.

Fitur

  • Preset 1 / 3 / 5 / 10 / 25 menit
  • Start / Pause / Resume / Restart dan Reset
  • Cincin progres SVG yang menyusut mengikuti sisa waktu
  • Alarm 3× beep 880 Hz saat waktu habis, plus angka berkedip
  • Judul tab menampilkan sisa waktu selama timer berjalan
  • Ikut prefers-color-scheme — terang/gelap otomatis
  • Bisa dipasang sebagai PWA (home screen) dan tetap berjalan offline

Menjalankan

npm run dev          # http://localhost:3000

Untuk membuka dari perangkat lain di jaringan yang sama (HP, laptop lain):

npm run dev:lan

Script ini mendeteksi alamat LAN mesin dan menampilkannya sebelum dev server menyala:

  Lokal           http://localhost:3000
  Perangkat lain  http://192.168.137.121:3000  (dari ip route get)

Pintasan keyboard

Tombol Aksi
Space Mulai / jeda — selalu, termasuk saat fokus sedang di sebuah tombol
R Reset ke durasi penuh

Struktur

app/
  layout.tsx        metadata + viewport + font
  page.tsx          merender <Timer />
  timer.tsx         seluruh logika dan tampilan timer (client component)
  pwa-register.tsx  registrasi service worker (produksi saja)
  manifest.ts       web app manifest (/manifest.webmanifest)
  icon.svg          favicon vektor
  favicon.ico       favicon fallback 16–256 px
  apple-icon.png    ikon home screen iOS
  globals.css       token warna, tema terang/gelap, animasi
public/
  sw.js             service worker: app shell + aset ber-hash
  icons/            ikon 192/512 dan versi maskable untuk manifest
scripts/
  dev-lan.mjs       deteksi alamat LAN lalu jalankan next dev
next.config.ts      allowedDevOrigins + header /sw.js

Catatan teknis

Dua hal yang sengaja ditangani supaya timer-nya benar-benar akurat:

Tanpa drift. Hitung mundur dihitung dari target timestamp (endAt - Date.now()), bukan dengan mengurangi counter setiap tick. Interval yang tersendat — misalnya karena tab tidak aktif — tidak menumpuk error, karena setiap tick membaca ulang jam.

Alarm tetap bunyi saat tab di background. Tab yang tersembunyi men-throttle setInterval sampai kira-kira sekali per menit, jadi beep tidak bisa diandalkan kalau dijadwalkan lewat JS timer. Bunyinya dijadwalkan langsung ke jam AudioContext saat Start ditekan, dan dibatalkan saat Pause/Reset. Yang di-throttle hanya pembaruan tampilan — itu pun langsung terkoreksi begitu tab dibuka lagi, karena state-nya juga dihitung dari timestamp.

PWA dan mode offline

Aplikasi bisa dipasang ke home screen dan dijalankan tanpa jaringan.

  • app/manifest.ts mendefinisikan nama, warna, dan ikon yang dipakai saat dipasang.
  • app/icon.svg dan app/favicon.ico adalah favicon; app/apple-icon.png dipakai iOS.
  • public/icons/ berisi ikon 192/512 untuk manifest, termasuk versi maskable agar tidak terpotong di Android.
  • public/sw.js menyimpan app shell dan seluruh chunk ber-hash saat instalasi, menyajikan HTML secara network-first, dan aset /_next/static/* secara cache-first. Reload saat offline tetap membuka timer yang sudah ter-hidrasi.

Service worker hanya didaftarkan pada build produksi. Di next dev, app/pwa-register.tsx justru mencabut service worker lama: next dev dan next start memakai origin yang sama, jadi service worker sisa build produksi bisa menyajikan chunk dev yang basi.

Service worker memerlukan secure context. http://localhost memenuhi syarat, http://192.168.x.x tidak — jadi memasang PWA dari HP lewat alamat LAN tidak akan bekerja. Gunakan deployment HTTPS (mis. Vercel) atau tunnel HTTPS.

Kalau logika cache di sw.js berubah, naikkan VERSION di baris paling atas; cache lama dihapus saat service worker baru aktif. Uji lokal dengan:

npm run build
npm start          # lalu buka http://localhost:3000

Membuka lewat alamat LAN

Sejak Next 16, permintaan ke resource dev (/_next/*, HMR) dari origin lain diblokir secara default. Gejalanya menyesatkan: halaman tampil normal karena HTML-nya dirender server, tetapi chunk JS-nya ditolak 403 — React tidak pernah hidrasi dan semua tombol diam.

next.config.ts mendaftarkan alamat LAN mesin dengan membacanya dari networkInterfaces() saat config dimuat:

for (const [name, addrs] of Object.entries(networkInterfaces())) {
  if (VIRTUAL_IFACE.test(name)) continue;   // buang docker0, vpn, dll
  for (const addr of addrs ?? []) {
    if (addr.family === "IPv4" && !addr.internal) origins.add(addr.address);
  }
}

Karena dibaca saat start, IP dari DHCP boleh berubah tanpa menyunting apa pun — termasuk kalau dijalankan dengan npm run dev biasa.

Kalau perlu menambahkan hostname mDNS atau IP statis:

ALLOWED_DEV_ORIGINS=mesinku.local,10.0.0.5 npm run dev:lan

Next membaca config sekali saat start, jadi kalau jaringan berpindah (mis. Wi-Fi → hotspot) saat server sedang jalan, jalankan ulang perintahnya.

Catatan instalasi

Jaringan di mesin ini lambat dan tidak stabil. Koneksi ke GitHub tetap jalan — push pertama butuh sekitar 30 detik — tetapi registry.npmjs.org konsisten timeout: curl gagal pada detik ke-20, dan npm install menggantung lebih dari 10 menit lalu berakhir dengan network error, setelah lebih dulu menghapus node_modules. Jadi jangan menjalankan npm install di sini.

node_modules diisi dari project lokal lain yang sudah punya Next 16, jadi versinya next@16.3.5 (bukan 16.3.8 yang dipilih create-next-app). Versi di package.json sengaja dipatok agar cocok dengan tree tersebut. Konsekuensinya node_modules masih berisi beberapa paket sisa project sumber (supabase, jose, server-only) yang tidak dipakai — tidak berpengaruh ke build, dan bisa dibersihkan dengan npm install begitu jaringan tersedia.

Verifikasi tanpa install:

npm run build

Deploy

Bisa dideploy ke Vercel. Halaman / sepenuhnya statis, jadi tidak ada konfigurasi khusus — allowedDevOrigins hanya berlaku di mode development dan diabaikan saat produksi.

About

Timer hitung mundur sederhana dan ringan, dibangun dengan Next.js 16 (App Router) + Tailwind CSS v4. Tanpa dependensi tambahan di luar bawaan Next — tidak ada state library, tidak ada komponen UI pihak ketiga.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages