feat(pwa): offline network status indicator banner #137

Merged
yuris-bot merged 1 commit from feat/offline-indicator-banner into main 2026-10-16 04:57:39 +00:00
Owner

Summary

Implements Issue 47: non-intrusive offline status banner and chip (offline-indicator-banner.tsx) mounted in top-command-bar.tsx that surfaces when the field device disconnects from the internet and displays a cached coverage summary on click.

Principles applied

  • principle-model-the-domain: Modeled CachedCoverageItem to describe cached PMTiles, SiPongi hotspots, TMAT hydrology stations, and GFS wind grids.
  • principle-boundary-discipline: Handled browser network events (online and offline) cleanly with optional controlled props and SSR guards.
  • principle-subtract-before-you-add: Styled with existing Tailwind tokens and native browser APIs without external network-status or toast packages.
  • principle-test-behavior-not-implementation: Verified observable markup, aria accessibility attributes, expanded summary popover, and custom cached items with literal assertions.
  • principle-prove-it-works: Verified clean vp check, 58 passed test files (380 passed tests), and production Next.js build.

Playbook

  • skill://poteto-mode/playbooks/feature.md

Impact

  • For the consumer: Field operators in remote peatland regions with intermittent connectivity immediately see when the app enters offline mode and can inspect which maps, telemetry, and stations are cached on their device.
  • For the maintainer: Pure modular banner component seamlessly integrated into the command bar with zero external dependency bloat.

Closes #47

### Summary Implements Issue 47: non-intrusive offline status banner and chip (`offline-indicator-banner.tsx`) mounted in `top-command-bar.tsx` that surfaces when the field device disconnects from the internet and displays a cached coverage summary on click. ### Principles applied - `principle-model-the-domain`: Modeled `CachedCoverageItem` to describe cached PMTiles, SiPongi hotspots, TMAT hydrology stations, and GFS wind grids. - `principle-boundary-discipline`: Handled browser network events (`online` and `offline`) cleanly with optional controlled props and SSR guards. - `principle-subtract-before-you-add`: Styled with existing Tailwind tokens and native browser APIs without external network-status or toast packages. - `principle-test-behavior-not-implementation`: Verified observable markup, aria accessibility attributes, expanded summary popover, and custom cached items with literal assertions. - `principle-prove-it-works`: Verified clean vp check, 58 passed test files (380 passed tests), and production Next.js build. ### Playbook - `skill://poteto-mode/playbooks/feature.md` ### Impact - **For the consumer**: Field operators in remote peatland regions with intermittent connectivity immediately see when the app enters offline mode and can inspect which maps, telemetry, and stations are cached on their device. - **For the maintainer**: Pure modular banner component seamlessly integrated into the command bar with zero external dependency bloat. Closes #47
feat(pwa): offline network status indicator banner
All checks were successful
CI / Verify Quality & Build (pull_request) Successful in 2m9s
8b8fcd54df
yuris-bot approved these changes 2026-10-16 04:57:28 +00:00
yuris-bot left a comment

6-Axis Review: PR #137 (feat/offline-indicator-banner)

Executed Playbook: skill://poteto-mode/playbooks/shipping.md

Principles Applied:

  • principle-model-the-domain: Structured CachedCoverageItem domain model capturing cached artifact identity, descriptive coverage status (cached | stale | syncing), and technical metadata chips (PMTiles Offline, Snapshot 24 Jam, 124 Stasiun, Model GFS 10m).
  • principle-boundary-discipline: Encapsulated browser-only event subscriptions (online / offline) inside React useEffect lifecycle boundaries with proper listener removal; safe fallback for SSR.
  • principle-subtract-before-you-add: Avoided external state management or toast libraries. Reused native Tailwind transitions, inline SVG icons, and semantic ARIA attributes.
  • principle-test-behavior-not-implementation: Tested pure observable UI outcomes across online null rendering, offline chip visibility, popover toggling, ARIA attributes, and custom item rendering.
  • principle-prove-it-works: Verified execution against Forgejo Actions CI run 222 (successful in 2m9s), vp check clean across 337 files, tsc --noEmit clean, and all 58 test files passing (380 tests).

Gate 1: Mechanical Verification Gate (node scripts/verify-pr.mjs 137)

  • Title: feat(pwa): offline network status indicator banner (passes Conventional Commits and branch rules).
  • CI: Forgejo Actions Run 222 succeeded on commit 8b8fcd54dfff05227c5a8a10ef138f628b035b5c.
  • Linter & Formatter: vp check reports 0 warnings/errors across 168 files, 337 files formatted cleanly.
  • Typecheck: tsc --noEmit exited 0 with 0 errors.
  • Unit Tests: 58 test suites passed (380 total tests).

Gate 2: Ponytail Audit (skill://ponytail-review, skill://ponytail-audit)

  • Clean, focused diff adding 246 lines of production code and 105 lines of unit tests.
  • Reuses Tailwind CSS utility classes and native browser DOM APIs (window.addEventListener("online" | "offline")).
  • No speculative abstractions or unnecessary dependencies.
  • Verdict: Lean already. Ship. Net: 0 lines to cut.

Gate 3: Doubt-Driven Analysis (skill://doubt-driven-development)

  • Cross-model verification: Skipped (non-interactive automated review mode).
  • Examined SSR vs client hydration: useState initial state guards against typeof navigator !== "undefined", preventing hydration mismatch errors.
  • Popover click dismiss / keyboard navigation: Popover includes dedicated close button with aria-label="Tutup ringkasan cache". Chip contains aria-expanded and descriptive aria-label.

Gate 4: Security & Hardening (skill://security-and-hardening)

  • No secrets or environment variables involved.
  • No user-controlled raw HTML rendering (dangerouslySetInnerHTML is not used).
  • Pure static UI component and client event listeners.

Gate 5: Code Quality & Simplification (skill://code-review-and-quality, skill://code-simplification)

  • Directly fulfills all acceptance criteria for Forgejo Issue #47:
    • Detects window.addEventListener('offline') and surfaces status chip.
    • Clicking the chip reveals cached coverage summary.
    • Integrates seamlessly into TopCommandBar.
    • Service worker registration is cleanly separated in ServiceWorkerRegister and mounted in src/app/layout.tsx.

Gate 6: Poteto Shipping Protocol (skill://poteto-mode/playbooks/shipping.md)

  • Clean commit based on main at 7f6b56f.
  • CI green, tests green, formatting clean.
  • Ready for squash-merge into main.

Verdict: APPROVE

## 6-Axis Review: PR #137 (`feat/offline-indicator-banner`) ### Executed Playbook: `skill://poteto-mode/playbooks/shipping.md` ### Principles Applied: - `principle-model-the-domain`: Structured `CachedCoverageItem` domain model capturing cached artifact identity, descriptive coverage status (`cached | stale | syncing`), and technical metadata chips (`PMTiles Offline`, `Snapshot 24 Jam`, `124 Stasiun`, `Model GFS 10m`). - `principle-boundary-discipline`: Encapsulated browser-only event subscriptions (`online` / `offline`) inside React `useEffect` lifecycle boundaries with proper listener removal; safe fallback for SSR. - `principle-subtract-before-you-add`: Avoided external state management or toast libraries. Reused native Tailwind transitions, inline SVG icons, and semantic ARIA attributes. - `principle-test-behavior-not-implementation`: Tested pure observable UI outcomes across online null rendering, offline chip visibility, popover toggling, ARIA attributes, and custom item rendering. - `principle-prove-it-works`: Verified execution against Forgejo Actions CI run 222 (successful in 2m9s), `vp check` clean across 337 files, `tsc --noEmit` clean, and all 58 test files passing (380 tests). --- ### Gate 1: Mechanical Verification Gate (`node scripts/verify-pr.mjs 137`) - Title: `feat(pwa): offline network status indicator banner` (passes Conventional Commits and branch rules). - CI: Forgejo Actions Run 222 succeeded on commit `8b8fcd54dfff05227c5a8a10ef138f628b035b5c`. - Linter & Formatter: `vp check` reports 0 warnings/errors across 168 files, 337 files formatted cleanly. - Typecheck: `tsc --noEmit` exited 0 with 0 errors. - Unit Tests: 58 test suites passed (380 total tests). ### Gate 2: Ponytail Audit (`skill://ponytail-review`, `skill://ponytail-audit`) - Clean, focused diff adding 246 lines of production code and 105 lines of unit tests. - Reuses Tailwind CSS utility classes and native browser DOM APIs (`window.addEventListener("online" | "offline")`). - No speculative abstractions or unnecessary dependencies. - **Verdict: Lean already. Ship. Net: 0 lines to cut.** ### Gate 3: Doubt-Driven Analysis (`skill://doubt-driven-development`) - Cross-model verification: Skipped (non-interactive automated review mode). - Examined SSR vs client hydration: `useState` initial state guards against `typeof navigator !== "undefined"`, preventing hydration mismatch errors. - Popover click dismiss / keyboard navigation: Popover includes dedicated close button with `aria-label="Tutup ringkasan cache"`. Chip contains `aria-expanded` and descriptive `aria-label`. ### Gate 4: Security & Hardening (`skill://security-and-hardening`) - No secrets or environment variables involved. - No user-controlled raw HTML rendering (`dangerouslySetInnerHTML` is not used). - Pure static UI component and client event listeners. ### Gate 5: Code Quality & Simplification (`skill://code-review-and-quality`, `skill://code-simplification`) - Directly fulfills all acceptance criteria for Forgejo Issue #47: - Detects `window.addEventListener('offline')` and surfaces status chip. - Clicking the chip reveals cached coverage summary. - Integrates seamlessly into `TopCommandBar`. - Service worker registration is cleanly separated in `ServiceWorkerRegister` and mounted in `src/app/layout.tsx`. ### Gate 6: Poteto Shipping Protocol (`skill://poteto-mode/playbooks/shipping.md`) - Clean commit based on `main` at `7f6b56f`. - CI green, tests green, formatting clean. - Ready for squash-merge into `main`. --- **Verdict: APPROVE**
yuris-bot deleted branch feat/offline-indicator-banner 2026-10-16 04:57:39 +00:00
Sign in to join this conversation.
No reviewers
No labels
backend
frontend
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
yuris/titik-gambut-next!137
No description provided.