Skip to content

feat: Bookmark Manager PWA — full architectural refactor (v1.0.0)#17

Merged
davidangarita1 merged 4 commits intodevelopfrom
feat/bookmark-manager-pwa-refactor
Mar 10, 2026
Merged

feat: Bookmark Manager PWA — full architectural refactor (v1.0.0)#17
davidangarita1 merged 4 commits intodevelopfrom
feat/bookmark-manager-pwa-refactor

Conversation

@davidangarita1
Copy link
Owner

Summary

Complete refactor of the application from a simple resource viewer into a full Bookmark Manager PWA with offline support, Zustand state management, fuzzy search, and a clean modular architecture.


What Changed

Stack

  • Removed: Bootstrap, SCSS, react-bootstrap, formik, axios, dotenv
  • Added: TailwindCSS 4, Zustand, Fuse.js, vite-plugin-pwa

Architecture

New modular structure following SOLID, Clean Code, and Separation of Concerns:

src/
├── app/          # App shell
├── types/        # Resource, ResourceStatus, UserState
├── services/     # storageService, searchService, resourceService
├── store/        # Zustand store (resourceStore)
├── hooks/        # useResources, useFavorites, useStatuses, useSearch
├── components/   # ResourceCard, SearchBar, Sidebar, Topbar, TagList, CategoryList
├── pages/        # Dashboard, NotFound
├── utils/        # url, date
└── __tests__/    # mirrors src structure

Features

  • Fuzzy search with Fuse.js across title, description, tags, URL, category
  • Favorites — toggle and persist in localStorage
  • Status tracking — cycle: Pendiente → Consumido → Referencia → none
  • Sidebar navigation — All / Favorites / Pending / Consumed / Categories
  • Dark mode — class-based via Tailwind @custom-variant dark, persisted in localStorage
  • PWA — installable, offline-capable with auto-updating service worker

Data

  • resources.json migrated to clean schema: id, title, url, description, category, tags, createdAt
  • pendings.json removed — dynamic state lives in localStorage

Bug Fixes

  • Search reactivity: useResources now subscribes to all Zustand slices so any state change triggers re-render
  • Dark mode toggle: applyDarkMode() syncs classList + localStorage atomically (no stale useEffect)

Tests

  • All tests migrated to src/__tests__/ mirroring src/ structure
  • 49 tests across 6 test files — all passing

Tooling

  • New check-links.sh script — parallelized URL checker with configurable workers and timeout, outputs broken-link report

Testing

pnpm test:run       # 49 tests, all passing
pnpm build          # PWA build with service worker
./check-links.sh    # verify all bookmark URLs

Release

Tagged as v1.0.0

- Replace Bootstrap/SCSS with TailwindCSS
- Add Zustand for state management (replacing Context API)
- Add Fuse.js for fuzzy search
- Add vite-plugin-pwa for PWA support
- Refactor resources.json to new schema (id, title, url, description, category, tags, createdAt)
- Remove pendings.json, unused deps (axios, bootstrap, formik, dotenv)
- Create service layer: storageService, searchService, resourceService
- Create Zustand store with filters, favorites, statuses, search
- Create custom hooks: useResources, useFavorites, useStatuses, useSearch
- Create UI components: ResourceCard, SearchBar, Sidebar, Topbar, TagList, CategoryList
- Create pages: Dashboard with grid layout, NotFound
- Implement localStorage persistence for favorites and statuses
- Implement status cycling: pending -> consumed -> reference -> none
- Add 49 unit tests (services, hooks, components)
- Configure PWA manifest and service worker
- Update path aliases and tsconfig
…k checker

- fix(search): rewrite useResources to subscribe to all store slices reactively
  searchQuery/searchResults/activeFilter/activeCategory/favorites/statuses are
  now direct Zustand subscriptions so any change triggers a re-render

- fix(dark-mode): add @custom-variant dark to index.css for Tailwind v4 class-based dark mode
  Tailwind v4 defaults to prefers-color-scheme; class variant requires
  '@custom-variant dark (&:is(.dark, .dark *))' in CSS
  Topbar refactored: applyDarkMode() syncs classList+localStorage atomically,
  no more stale useEffect, reads system preference as fallback

- refactor(tests): move all tests to src/__tests__ mirroring src structure
  src/__tests__/services/storageService.test.ts
  src/__tests__/services/searchService.test.ts
  src/__tests__/hooks/useFavorites.test.ts
  src/__tests__/hooks/useStatuses.test.ts
  src/__tests__/components/ResourceCard.test.tsx
  src/__tests__/components/SearchBar.test.tsx
  All 49 tests pass from new location

- feat(script): add check-links.sh to verify URL availability
  Parallelizes curl checks (default 10 workers, configurable)
  Reports HTTP status codes for broken/inaccessible links
  Saves timestamped TXT report when broken links are found
  Usage: ./check-links.sh [--timeout N] [--parallel N]
@davidangarita1 davidangarita1 merged commit d995b37 into develop Mar 10, 2026
3 checks passed
@davidangarita1 davidangarita1 deleted the feat/bookmark-manager-pwa-refactor branch March 10, 2026 19:44
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