Upgrade eslint stack and fix React Compiler lint errors - #412
Conversation
|
Visit the preview URL for this PR (updated for commit 8d05dc9): https://hacklytics2027--pr-412-q6qghar4.web.app (expires Thu, 01 Oct 2026 19:46:13 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: c48ba34db61581e25fe2978355160b5eefe0e83f |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 5d166e4. Configure here.
|
Upgrades @eslint/js 10, @eslint/compat 2, eslint-config-prettier 10, eslint-plugin-react-hooks 7 and globals 17, and drops the deprecated @types/eslint__js. react-hooks 7's recommended set adds the React Compiler rules. Both sites build with reactCompiler: true, so these are real findings, not style. Fixes for the 31 new errors: - Mounted flags (`useEffect(() => setMounted(true), [])`) become `useIsClient()`, a useSyncExternalStore hook in lib/use-is-client.ts. - Resize listeners that mirror window.innerWidth into state become `useWindowWidth()` in lib/use-window-width.ts. Hero reads its prop directly instead of copying it into state. - Forms seeded from query data, and state reset when an input changes, use the "adjust state during render" pattern guarded by the previous value, so the stale value never paints. - AdminLayout derives `loading` instead of storing it; the Stripe modal memoizes loadStripe; EventFormModal seeds the date in its initial state; verify uses window.location.assign; the judging page updates its ref in an effect instead of during render. - LazySection drops the IntersectionObserver-missing fallback (every supported browser has it) and the hacklytics countdown seeds its first tick from the initial state. - AttendeesTab: drop a useless initial assignment (no-useless-assignment).
- Admin judging: move the selection ref and prep generation in the click handler instead of a post-render effect. Between render and that effect, a prep run for the previous edition still passed stillThisRun and could land its result on the newly selected edition's panel. Re-selecting the current edition is now a no-op so it cannot orphan its own run. - ResumePreview: remount per src via key instead of keying state by src. Going A -> B -> A before B loaded matched A's retained blob URL, which the A -> B cleanup had already revoked, and showed a broken PDF.
6fc0532 to
8d05dc9
Compare

Stacked PRs, merge in order: 1) TS 7 → 2) minor bumps → 3) major bumps → 4) eslint + React Compiler fixes. GitHub retargets each to
devas the one below merges.What
Upgrades
@eslint/js10,@eslint/compat2,eslint-config-prettier10,eslint-plugin-react-hooks7,globals17; drops deprecated@types/eslint__js.react-hooks 7 turns on the React Compiler rules. Both sites build with
reactCompiler: true, so the 31 new errors were real. Fixes:useIsClient()(lib/use-is-client.ts, useSyncExternalStore).useWindowWidth()(lib/use-window-width.ts). Hero reads its prop directly.loading; Stripe modal memoizesloadStripe; EventFormModal seeds the date in initial state; verify useswindow.location.assign; admin judging updates its ref in an effect.Needs a manual check
Click through: login, settings (profile + membership forms load filled), submit page (switching hackathons refills), admin judging (switching editions clears prep status), admin resumes (filter resets selection), club QR scanner, Stripe modal, 404 and bootcamp pages at mobile width.
Verification
Verified on this branch:
pnpm typecheck,pnpm lint,pnpm test(828 passing), both sites build.Note
Medium Risk
Wide UI refactors (render-time setState, judging race guards) touch live portal flows; ESLint major bumps may surface new lint failures elsewhere.
Overview
Upgrades the shared ESLint toolchain (
@eslint/js10,@eslint/compat2,eslint-config-prettier10, eslint-plugin-react-hooks 7,globals17) and drops deprecated@types/eslint__js, with lockfile updates including new react-hooks 7 transitive deps (Babel/Hermes). react-hooks 7 enables React Compiler rules that were failing on both sites.The bulk of the PR refactors client components to satisfy those rules:
useIsClient()anduseWindowWidth()replace mount/resizeuseEffectpatterns; query-driven forms and filters reset or refill during render with a “last seen” guard instead of syncing in effects; admin judging getsselectHackathonso in-flight prep cannot apply to the wrong edition; smaller fixes include StripeloadStripememoization, verifylocation.assign, resume preview remount bykey, and hacklytics countdownuseSyncExternalStoreplus removing the LazySection IO fallback.Reviewed by Cursor Bugbot for commit 8d05dc9. Bugbot is set up for automated code reviews on this repo. Configure here.