Skip to content

chore(release): v1.1.0 - #23

Merged
perkinson1251 merged 12 commits into
mainfrom
dev
Aug 31, 2026
Merged

perkinson1251 merged 12 commits into
mainfrom
dev

Conversation

@perkinson1251

Copy link
Copy Markdown
Contributor

Release v1.1.0

Promotes dev → main.

Highlights

  • Offline support — page loads from service worker cache when there's no network
  • Cached schedule renders offline; offline banner shows last-fetch time
  • All 59 icons bundled in client build — no external CDN dependency
  • Fixed month-grid border cells showing empty at academic year boundary (Aug/Sep)
  • Preview server moved to port 3001 to prevent SW leaking into dev mode

Release notes

New features
  • Offline support: the app loads from a service worker cache when offline; the offline banner now shows the time data was last fetched (e.g. "Без з'єднання — дані від 15:31"). If no cached data exists for the selected schedule, a dedicated empty state is shown instead of a blank calendar.
Performance & offline
  • All 59 icons are now bundled directly in the client JS (18 KB uncompressed) using @iconify-json/* packages — no requests to api.iconify.design at runtime. Icons render offline and are not blocked by ad-blockers or slow CDN.
  • Service worker caches the app shell (network-first) and static assets (cache-first) so repeat visits are instant even on flaky connections.
Fixes
  • Month and week grid cells that overflow the academic year boundary (e.g. trailing Sept cells in August, or leading Aug cells in September) no longer show empty — the fetch window is now padded ±7 days around Sept 1.
Under the hood
  • Service worker (public/sw.js, v3): NetworkFirst shell keyed by pathname (not full URL), CacheFirst assets at /_nuxt/ + /_fonts/, SWR for /_icons/. Never intercepts /api/*.
  • SW plugin (app/plugins/sw.client.ts): registers on prod, actively tears down stale workers + caches in dev mode.
  • Preview script fixed to port 3001 (pnpm preview) — separate origin prevents service worker from leaking across dev/preview sessions.
  • Icon endpoint moved to /_icons (localApiEndpoint) so SW can distinguish icon fetches from backend API calls.
  • serverBundle: false on @nuxt/icon — avoids 14 MB of full collection JSONs in the Nitro server bundle.
  • Filters store migrated to useStorage + skipHydrate pattern, eliminating SSR/client hydration mismatch.
  • ScheduleFilters type deduplicated; DialogConfig extracted to app/types/dialogs.ts; useDialogManager uses useStorage.
  • Components reorganised into subdirectories (backgrounds/, banners/, settings/).
  • useCalendarStore.lastUpdatedAt tracks last event fetch timestamp for the offline banner.

Compare: main...dev

- Delete app/utils/tanstack-table.ts (valueUpdater had zero callers)
- Delete app/utils/tw-helper.ts (tw() identity tag never invoked)
- Remove getFirstLetters() from strings.ts (exported, never called)
- Remove @tanstack/vue-table dep (only imported by now-deleted file)
Replace manual localStorage.getItem/setItem calls in stores/filters.ts with
useStorage() + skipHydrate(), consistent with schedule.ts / settings.ts / links.ts.

- storageKey ref drives reactive key re-binding when schedule changes
- Custom serializer preserves existing parse/validate logic (ensureArray guards)
- Remove saveFilters() (no longer needed; useStorage writes automatically)
- index.vue: migrate 'op-first-visit-seen' to STORAGE_KEYS.firstVisitSeen
  ('mindenit:first-visit-seen'), wrap with skipHydrate() to prevent SSR mismatch
- constants/storage.ts: add firstVisitSeen key to registry
…uted

- Add shared ScheduleFilters type to app/types/schedule.ts
- Remove GroupScheduleFilters, TeacherScheduleFilters, AuditoriumScheduleFilters
  from query files — all three were structurally identical
- Remove duplicate effectiveTimezone computed from useIcsExport.ts and
  stores/calendar.ts — both now delegate to useTimezone()
- Drop resolveTimezone and storeToRefs imports that became unused
- Normalize <script setup lang="ts"> order across 12 non-Ui .vue files
  (was <script lang="ts" setup>; matches project-dominant style)
- Add DIALOG_KEYS constant to constants/dialogs.ts with settings, shortcuts,
  and scheduleAdd keys
- Replace magic useState key strings in 5 components + 1 composable with
  DIALOG_KEYS.* references
Settings components → settings/:
  SettingsDialog, SettingsMainView, SettingsLinksManagement

Background/decoration → backgrounds/:
  SnowEffect, WaitHand

Banner components → banners/ (new dir):
  ConsentBanner, HiringInfo, AppOfflineBanner, ScheduleEphemeralBanner

Component names are unchanged — nuxt.config uses pathPrefix: false on the
catch-all ~/components entry, so subdirectory names do not affect the
registered component names.
…and empty offline state

- public/sw.js: new plain service worker (no deps). NetworkFirst for navigation
  (offline falls back to cached shell), CacheFirst for /_nuxt/ and /_fonts/,
  StaleWhileRevalidate for /_icons/, full bypass for /api/ (TanStack IDB owns
  schedule data).
- app/plugins/sw.client.ts: client-only registration; skipped in dev to avoid
  Vite hot-reload conflicts.
- nuxt.config.ts: icon.localApiEndpoint moved from /api/_nuxt_icon to /_icons
  so the SW can cleanly separate Nuxt icon requests from backend API traffic.
  Added /sw.js routeRule with no-cache headers.
- app/stores/calendar.ts: add lastUpdatedAt ref (Unix ms). Set via setEvents()
  from TanStack Query's dataUpdatedAt, enables showing last-fetch time offline.
- app/pages/index.vue: destructure dataUpdatedAt, fetchStatus, status from
  useScheduleQuery; pass updatedAt to setEvents(); compute isOfflineNoData
  (fetchStatus=paused + status=pending = offline with no IDB data); pass to
  BigCalendarRoot.
- app/components/banners/AppOfflineBanner.vue: when offline, show
  'дані від HH:MM' (tzFormat of lastUpdatedAt) instead of static fallback text.
- app/components/calendar/Root.vue: add isOfflineNoData prop; new overlay
  branch 'offline-no-data' renders AppEmptyState with wifi-off icon before
  the generic error branch, so blank-calendar confusion is replaced by a clear
  message when the user is offline and IDB cache is empty.
- AGENTS.md: remove stale server/api dev-proxy claim (server/api/[...any].ts
  no longer exists; SDK uses sh.mindenit.org/api directly in dev and prod).
@perkinson1251
perkinson1251 merged commit b37fb69 into main Aug 31, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant