Skip to content

Frontend code quality cleanup: LandingPage duplication, i18n any, CSS dup, double loading fallback#1238

Open
samuelisi wants to merge 4 commits into
solutions-plug:mainfrom
samuelisi:refactor/frontend-code-quality-cleanup
Open

Frontend code quality cleanup: LandingPage duplication, i18n any, CSS dup, double loading fallback#1238
samuelisi wants to merge 4 commits into
solutions-plug:mainfrom
samuelisi:refactor/frontend-code-quality-cleanup

Conversation

@samuelisi

@samuelisi samuelisi commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

closes #1176
closes #1177
closes #1178
closes #1179

Summary

  • Extract FeatureCard, Step, FooterColumn components (new src/components/landing/) and drive them from local data arrays in LandingPage.tsx, removing the hand-copied JSX blocks and shrinking the file (355 → 314 lines).
  • Type the i18n.ts translation lookup as Translations | string instead of any, narrowing with the existing typeof checks.
  • Remove the duplicate .visually-hidden rule from LoadingSpinner.css and Skeleton.css; the single definition in the globally-imported accessibility.css now applies everywhere.
  • Drop the redundant outer <Suspense> around the ssr: true next/dynamic import in app/page.tsx, which rendered two different loading fallbacks with mismatched aria-labels for the same loading state. One fallback remains, with a consistent label.

Test plan

  • Added LandingPage.dataDriven.test.tsx asserting feature cards, steps, and footer columns render from the data arrays with translated copy
  • Added i18n.test.ts cases covering the non-string terminal-value branch (proves the any removal didn't change behavior)
  • Added accessibility.css.test.ts asserting exactly one .visually-hidden definition exists across the stylesheet tree
  • Rewrote page.test.tsx to render Home and assert exactly one loading indicator (consistent aria-label="Loading page") appears during the dynamic import, and it's replaced once LandingPage resolves
  • cd frontend && npm test — 210/210 tests passing
  • cd frontend && npm run build — builds cleanly with zero errors

Known gap (pre-existing, not introduced by this PR)

npm run lint is currently broken on main: Next.js 16 removed the next lint subcommand and there's no standalone ESLint config/dependency in the repo. This predates these changes — flagging since the tickets ask for a clean lint pass.

🤖 Generated with Claude Code

samuelisi and others added 4 commits July 27, 2026 11:39
…gPage

The three feature cards, four how-it-works steps, and three footer
sections were each near-identical hand-copied JSX blocks. Extract
shared components and drive them from small local data arrays via
.map() to remove the duplication and shrink LandingPage.tsx.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The i18n.t() lookup used `let value: any` to walk the translation
tree, bypassing strict type checking for the function that resolves
all UI copy. Type it as Translations | string and rely on the
existing typeof narrowing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
.visually-hidden was defined identically in accessibility.css
(globally imported) and again verbatim in LoadingSpinner.css and
Skeleton.css. Remove the duplicates and rely on the global rule.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…page

next/dynamic's ssr: true already manages its own loading boundary, so
wrapping it in an outer <Suspense> rendered two different fallbacks
(with mismatched aria-labels) for the same loading state. Drop the
outer Suspense and keep a single consistent fallback.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@drips-wave

drips-wave Bot commented Jul 27, 2026

Copy link
Copy Markdown

@samuelisi Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment