| 08-mobile-pwa |
01 |
ui |
| pwa |
| service-worker |
| serwist |
| next.js |
| tailwind |
| mobile |
| responsive |
|
| phase |
provides |
| 07-multilanguage |
next-intl i18n framework used for offline banner and mobile nav labels |
|
| phase |
provides |
| 04-rbac |
RBAC role system used to filter More sheet items by user role |
|
|
| PWA manifest at /manifest.webmanifest with K monogram icons |
| Serwist service worker with precaching and runtime cache (app/sw.ts) |
| Service worker registration component (components/sw-register.tsx) |
| Offline detection hook (lib/use-offline.ts) and banner (components/offline-banner.tsx) |
| Mobile bottom tab bar (components/mobile-nav.tsx) — 5 tabs, md:hidden |
| Mobile More sheet (components/mobile-more-sheet.tsx) — RBAC-filtered secondary nav + LanguageSwitcher |
| Responsive dashboard layout |
| sidebar hidden on mobile, tab bar shown, safe-area padding |
|
|
| 08-02 through 08-04 (push notifications, offline cache, deep linking all build on this PWA foundation) |
|
| added |
patterns |
| @serwist/next ^9.5.7 |
| serwist ^9.5.7 |
| idb (IndexedDB utilities, used in plan 03) |
| sharp (devDep, icon generation script) |
|
| withNextIntl(withSerwist(nextConfig)) compose order in next.config.ts |
| Viewport export with viewportFit: cover for iOS safe-area CSS env vars |
| md:hidden for mobile-only components, hidden md:flex for desktop-only |
| env(safe-area-inset-bottom) via inline style for iOS home indicator |
| RBAC filtering in mobile UI mirrors desktop Nav.tsx pattern |
|
|
| created |
modified |
| packages/portal/app/manifest.ts |
| packages/portal/app/sw.ts |
| packages/portal/components/sw-register.tsx |
| packages/portal/components/offline-banner.tsx |
| packages/portal/lib/use-offline.ts |
| packages/portal/components/mobile-nav.tsx |
| packages/portal/components/mobile-more-sheet.tsx |
| packages/portal/public/icon-192.png |
| packages/portal/public/icon-512.png |
| packages/portal/public/icon-maskable-192.png |
| packages/portal/public/apple-touch-icon.png |
| packages/portal/public/badge-72.png |
| packages/portal/scripts/generate-icons.mjs |
|
| packages/portal/next.config.ts |
| packages/portal/app/layout.tsx |
| packages/portal/app/(dashboard)/layout.tsx |
| packages/portal/messages/en.json |
| packages/portal/messages/es.json |
| packages/portal/messages/pt.json |
|
|
| Serwist service worker disabled in development (NODE_ENV !== production) — avoids stale cache headaches during dev |
| ServiceWorkerRegistration placed outside NextIntlClientProvider — needs no translations, mounts immediately |
| OfflineBanner placed inside NextIntlClientProvider — requires translations for offline message |
| Mobile More sheet uses plain div + backdrop (not @base-ui/react Drawer) — simpler, zero dependency, fully functional |
| Serwist class API (new Serwist + addEventListeners) used over deprecated installSerwist — linter enforced this |
| Viewport exported from layout.tsx (not metadata) — Next.js 16 separates viewport from metadata |
| K monogram icons generated via sharp from SVG with radial gradient glow — consistent with sidebar brand mark aesthetic |
| nav.settings and nav.language keys added to en/es/pt — reused nav namespace to avoid duplication |
|
| All mobile-only UI uses md:hidden; all desktop-only uses hidden md:flex |
| Bottom safe-area handled via env(safe-area-inset-bottom) as inline style (Tailwind cannot use CSS env() directly) |
| PWA icons generated from script (scripts/generate-icons.mjs), not checked in from external tool |
|
|
7min |
2026-03-26 |