Skip to content

Upgrade eslint stack and fix React Compiler lint errors - #412

Merged
aamoghS merged 2 commits into
rebase/deps-minorfrom
rebase/eslint-react-compiler
Sep 24, 2026
Merged

aamoghS merged 2 commits into
rebase/deps-minorfrom
rebase/eslint-react-compiler

Conversation

@aamoghS

@aamoghS aamoghS commented Sep 24, 2026 •

Copy link
Copy Markdown
Member

Stacked PRs, merge in order: 1) TS 7 → 2) minor bumps → 3) major bumps → 4) eslint + React Compiler fixes. GitHub retargets each to dev as the one below merges.

What

Upgrades @eslint/js 10, @eslint/compat 2, eslint-config-prettier 10, eslint-plugin-react-hooks 7, globals 17; 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:

  • Mounted flags → useIsClient() (lib/use-is-client.ts, useSyncExternalStore).
  • Resize listeners mirroring window width → useWindowWidth() (lib/use-window-width.ts). Hero reads its prop directly.
  • Forms seeded from query data / state reset on input change → "adjust state during render" guarded by the previous value (MembershipTab, settings, InterestForm, EditHackathonForm, submit, judge seeding, admin judging, admin resumes, club scanner).
  • AdminLayout derives loading; Stripe modal memoizes loadStripe; EventFormModal seeds the date in initial state; verify uses window.location.assign; admin judging updates its ref in an effect.
  • hacklytics: countdown seeds from initial state; LazySection drops the IntersectionObserver-missing fallback (every supported browser has it).
  • AttendeesTab: remove a useless initial assignment.

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/js 10, @eslint/compat 2, eslint-config-prettier 10, eslint-plugin-react-hooks 7, globals 17) 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() and useWindowWidth() replace mount/resize useEffect patterns; query-driven forms and filters reset or refill during render with a “last seen” guard instead of syncing in effects; admin judging gets selectHackathon so in-flight prep cannot apply to the wrong edition; smaller fixes include Stripe loadStripe memoization, verify location.assign, resume preview remount by key, and hacklytics countdown useSyncExternalStore plus 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.

@github-actions

github-actions Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

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

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ 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.

Comment thread sites/hacklytics2027/app/page.tsx
@greptile-apps

greptile-apps Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

The PR appears safe to merge; no new findings remain.

Summary

Upgrades the ESLint stack and refactors client components to satisfy React Compiler lint rules.

  • Replaces mount and resize effects with shared hooks.
  • Moves several form and selection resets into guarded renders.
  • Updates judging preparation and resume preview handling.

Reviews (3) · Last reviewed commit: "fix: close stale-result windows in admin..."

Comment thread sites/mainweb/app/(portal)/admin/judging/page.tsx
Comment thread sites/mainweb/components/portal/ResumePreview.tsx Outdated
@aamoghS
aamoghS added this pull request to stack #413 September 24, 2026 19:29
Base automatically changed from rebase/deps-major to rebase/deps-minor September 24, 2026 19:45
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.
@aamoghS
aamoghS force-pushed the rebase/eslint-react-compiler branch from 6fc0532 to 8d05dc9 Compare September 24, 2026 19:45
@aamoghS
aamoghS merged commit f125b60 into rebase/deps-minor Sep 24, 2026
18 of 19 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