PR #144 (`31da384`, 2026-06-13) shipped a `ReferenceError: useFocusTrap
is not defined` to production because the flat ESLint config did NOT
enable the core `no-undef` rule — only `react/jsx-no-undef` (which
catches undefined JSX components, not plain JS identifier references).
This PR closes that gap, narrowly.
## What changes
- `eslint.config.mjs`: enable `no-undef: 'error'` for source files +
define the ~40 browser / Node / Vitest globals the rule needs.
Hand-curated globals list (rejected pulling in the `globals` npm
package for one config block).
- 3 latent bugs surfaced + fixed (NOT silenced with disables):
| Site | Bug | Fix |
|------|-----|-----|
| `components/CollectionPageView.js:238` | `onClick={toggleFavorite}` — fn defined in `lib/use-collection-view.js:269` (collection-level favorite) but missing from the hook's `return {}` | Added to hook return + component destructure |
| `components/CollectionPageView.js:532` | `onTogglePublic={togglePublic}` — same pattern, fn at line 315 of the hook | Same shape: hook return + destructure |
| `components/ShareModal.js:99` | `fetchInvitedUsers()` scoped inside the useEffect body but called from `handleInvite` outside | Extracted to component scope via `useCallback`; effect dep array updated |
Bugs 1 + 2 broke the "Favorite collection" button and the public-toggle
in the Share modal on the collection-detail page. Bug 3 broke the
"refresh invitee list" path after a successful invite. None had been
flagged because the operator hadn't exercised those exact flows since
the relevant hooks were last refactored.
- `components/ShareModal.js`: also adds an eslint-disable for
`react-hooks/set-state-in-effect` on the moved `fetchInvitedUsers()`
call. Matches the canonical pattern in `pages/profile.js:90` —
async fetch; setState fires post-resolve, not synchronously to the
effect body.
## Why not pull in @eslint/js/recommended wholesale?
The recommended bundle also enables `no-unused-vars`,
`no-prototype-builtins`, `no-empty`, `no-cond-assign`, and ~10 others
— each would generate dozens of pre-existing violations on this
codebase. The right rule-by-rule sweep is the deferred
`adopt-eslint-recommended-set` convoy. This PR is scoped to the one
rule that would have caught PR #144's bug class.
## Test plan
- [x] `npm run lint` — clean (1 pre-existing unrelated warning on
`CollectionsPageView.js`'s `eslint-disable` directive — out of
scope)
- [x] `npm run test:run` — 25 files / 123 tests pass
- [ ] CI on this PR
- [ ] Post-merge: exercise the three formerly-broken paths (favorite a
collection from its detail page; toggle a collection public via
Share modal; invite a user and confirm the invitee list refreshes)
## Convoy doc
`.convoys/enable-no-undef-eslint-rule.md` documents the surfaced bugs,
D1 (no-undef only vs recommended bundle), D2 (hand-curated globals vs
`globals` package), risks, and acceptance.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Align UI copy with My Collection vs Lists vocabulary.
Replace stale ownership/list labels across pages and components, add
lib/collection-vocabulary.js as the single copy source, document the
taxonomy in AGENTS.md, and gate retired strings in CI.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Fix remaining list/collection copy gaps from review.
Sweep community, settings, share modal, scanner create-list modal,
and invite flows for vocabulary consistency before merge.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
🎨 Complete Brand Transformation:
- Rebranded from 'TCG Vault' to 'Deck Hearth'
- Updated logo initials from 'TCG' to 'DH'
- Changed app name throughout the application
🔥 Fire-Themed Color Palette:
Light Theme (Warm Daylight by the Hearth):
- Primary: Warm cream (#fefcf8) like sunlit stone
- Secondary: Soft beige (#f7f3ed) like aged parchment
- Tertiary: Light wood tone (#f0e6d6)
- Text: Dark chocolate brown (#2d1810)
- Accents: Ember orange, flame orange, golden yellow
Dark Theme (Cozy Evening by the Fire):
- Primary: Deep charcoal (#1a0f0a) like burnt wood
- Secondary: Rich dark brown (#2d1b12) like oak
- Tertiary: Medium brown (#3d2317) like mahogany
- Text: Warm white (#fff8f0) like firelight
- Accents: Bright flame, glowing ember, golden glow
🎨 Fire-Inspired Design Elements:
- Flame gradient: Orange to ember red
- Golden gradient: Golden yellow to flame orange
- Fire glow effects with warm shadows
- Wood-toned borders and accents
- Ember and flame-colored interactive elements
🔧 Enhanced Component Styling:
- Updated BulkSelectionToolbar with fire colors
- New CSS classes: btn-flame, btn-ember, btn-gold
- Fire glow and ember glow effects
- Gradient backgrounds: gradient-bg-fire, gradient-bg-golden
- Tailwind color palette: hearth.flame, hearth.ember, etc.
✨ Warm & Inviting Experience:
- Light mode: Cozy daytime fireplace atmosphere
- Dark mode: Intimate evening hearth ambiance
- Maintains accessibility with proper contrast
- Smooth transitions between themes
The app now perfectly captures the warm, inviting feeling of gathering around a hearth! 🔥🏠✨
Built out all requested features from top to bottom:
✅ Upload Modal for Hero Images:
- Created UploadImageModal component with drag-and-drop
- Support for both URL input and file upload
- Live preview and validation
- Integrated into collection detail page
✅ Smart TCG Tags:
- Dynamic tags showing only games with cards
- Properly positioned under description
- Clean blue rounded styling
✅ Combined Share & Invite Modal:
- Unified ShareModal replacing separate buttons
- Public access toggle with community visibility
- Email/member search functionality
- Default viewer role for invitations
- Social sharing (Twitter, Facebook, Reddit, Discord)
- User search API endpoint (/api/users/search)
✅ Comprehensive Favorites System:
- Database schema for cards, collections, and decks
- API endpoint (/api/favorites) for CRUD operations
- Real-time favorite status checking
- Working toggle functionality in UI
- Migration script for database setup
✅ CSV Download Functionality:
- Complete card metadata export
- Proper CSV formatting with escaping
- All card fields included (name, set, rarity, etc.)
- Automatic filename generation
- Client-side download implementation
🎯 UI/UX Improvements:
- Removed duplicate buttons and switches
- Clean action bar with proper hierarchy
- Working modals with proper state management
- Error handling and loading states
🛠️ Technical Features:
- JWT authentication for all endpoints
- Proper database relationships and indexes
- CORS headers and error handling
- Optimized queries and performance
All todos completed! Ready for full collection management! 🎮✨