An installable offline-first PWA for tracking work shifts and paychecks — built as a single self-contained HTML file with no frameworks, no build step, and no backend.
Originally built for personal use in a pharmacy setting.
| Dashboard (Light) | Dashboard (Dark) | Shifts |
|---|---|---|
| Paychecks | Balance | Settings |
|---|---|---|
All 6 screenshots show the light and dark themes, shift tracking, paycheck logging, hours balance, and settings panel.
- Clock In / Clock Out — one tap to start or end a shift; live elapsed timer while clocked in
- Shift history — grouped by week with weekly hour totals; edit or delete any entry
- Paycheck log — record hours paid and amount received per paycheck
- Hours Balance — running ledger showing total worked, total paid, and hours still owed
- Export to .XLS — one-tap spreadsheet download with three sheets: Shifts, Paychecks, and Balance Ledger
- Backup & restore — download a full JSON backup; restore validates structure before writing
- Fully offline — Service Worker caches the app shell for reliable offline use
- Installable — add to your iPhone or Android home screen as a standalone app
| Type | Clock In | Clock Out | Duration |
|---|---|---|---|
| Full day | 9:00 AM | 5:00 PM | 8 h |
| Half day | 10:00 AM | 4:00 PM | 6 h |
The demo runs a 3-shift week (8h · 8h · 6h = 22 h/week) with a weekly paycheck of $396 (22 h × $18/hr). The last two weeks are intentionally left unpaid so the Balance tab shows hours still owed.
| Layer | Choice |
|---|---|
| Stack | Vanilla HTML + CSS + JavaScript — zero dependencies, zero build step |
| PWA | Service Worker + Web App Manifest |
| Styling | CSS custom properties (full design token system) |
| Persistence | localStorage |
| Export | HTML table payload via Blob + URL.createObjectURL → .xls download |
| Deployment | Netlify Drop or GitHub Pages |
- Make sure
index.htmlandsw.jsare in the same folder - Go to app.netlify.com/drop
- Drag the folder onto the page — you get a live HTTPS URL instantly
- Push
index.htmlandsw.jsto a repo - Go to Settings → Pages → Deploy from branch → main / root
- Your app is live at
https://USERNAME.github.io/REPO/
⚠️ The service worker requires HTTPS and same-origin deployment. Both Netlify and GitHub Pages satisfy this out of the box.
iPhone (iOS):
- Open the deployed URL in Safari (not Chrome)
- Tap the Share icon → Add to Home Screen → Add
Android:
- Open the deployed URL in Chrome
- Tap the three-dot menu → Install App (or "Add to Home Screen") → Add
work-tracker/
├── index.html # entire app — HTML, CSS, and JavaScript in one file
├── sw.js # service worker — cache-first offline strategy
└── screenshots/ # app screenshots
Single-file design — All HTML, CSS, and JavaScript live in one file. This makes deployment trivially simple (one drag-and-drop) and eliminates any asset-loading failure modes.
Service worker strategy — Cache First: on every fetch the SW checks the cache and returns the stored response immediately if one exists. On a cache miss it fetches from the network and caches the result. Updates reach users when a new deployment changes CACHE_NAME, which triggers the activate handler to delete the old cache and the install handler to precache the fresh shell.
Seed data system — The app ships with a versioned SEED_VERSION constant. On load, it merges seed shifts and paychecks with any user-added data using a deduplication strategy based on date + clock-in time. This lets pre-loaded demo data be updated via a new deployment without wiping user entries.
XLS export — Uses the application/vnd.ms-excel MIME type with an HTML table payload. Excel and Google Sheets both parse this correctly. Three sheets are generated — Shifts, Paychecks, and Balance Ledger — entirely in-browser with no server involved.
MIT