Skip to content

fix(not-found): align 404 page with app design language and remove dead link - #284

Draft
dccakes wants to merge 2 commits into
mainfrom
claude/sharp-feynman-vrf7y4
Draft

dccakes wants to merge 2 commits into
mainfrom
claude/sharp-feynman-vrf7y4

Conversation

@dccakes

@dccakes dccakes commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Daily Product Improvement

Summary

Redesigned the 404 not-found page to match the app's established design language: replaces the old font-bold text-7xl heading and sharedStyles.primaryButton() helper with the app's font-serif typography and the shared Button component. Removes the underlined "Help Center" span that had no href and would confuse users who clicked it.


Recommendations Reviewed

# Area Issue Recommendation Type Priority Effort
1 Dashboard MiniStats and RsvpCard independently reduce the same RSVP event data with near-identical logic Extract a shared getRsvpTotals(events) utility Frontend cleanup Medium Small
2 Dashboard VendorsCard has no loading state — flashes empty state while query is pending Add skeleton like BudgetCard already has UX/UI Medium Small
3 Dashboard Same ~200-char Tailwind CTA string copy-pasted 5× in empty states Extract named constant or small component Frontend cleanup Low Small
4 Dashboard Topbar today date initialised to '' and filled in useEffect, causing visible hydration flash Use suppressHydrationWarning with a stable SSR value UX/UI Medium Small
5 Dashboard Milestone ⚠ symbol has no tooltip or accessible label Add tooltip/aria-description explaining user override UX/UI Low Small
6 Dashboard window.dispatchEvent(new CustomEvent('dashboard:add-task')) bypasses React's component model Replace with a React context or prop callback Frontend cleanup Medium Medium
7 Vendors Server-side error in vendors/page.tsx silently redirects to / instead of triggering the error boundary Remove try/catch and let the error propagate naturally Backend cleanup Medium Small
8 Vendors / Events metadata.title uses placeholder "Your Wedding Website" Replace with the real product name Frontend cleanup Low Small
9 Events isLoading && initialEvents.length === 0 renders <p>Loading events...</p> instead of a skeleton Add a proper skeleton consistent with the vendors loading screen UX/UI Medium Small
10 Events "General RSVP questions" button is disabled with no explanation for why Add a tooltip or helper text UX/UI Medium Small
11 Events event.startTime - event.endTime renders raw DB strings (e.g. 14:00:00) Format to locale-appropriate time (e.g. 2:00 PM) UX/UI Medium Small
12 Settings weddingDetailsLoadFailed shows a dead-end error paragraph with no retry Add a retry button consistent with other settings cards UX/UI Medium Small
13 Settings Heading hierarchy: page opens with <h2> then uses <h3> for peer-level sections Make all section headings <h2> UX/UI Low Small
14 Settings authGet and authPost helpers are copy-pasted between two settings files Extract to a shared auth-client-helpers.ts module Frontend cleanup Medium Small
15 Settings TelegramConnectCard pairing link stays on screen forever; "Connect" button unchanged when already connected Add dismiss + clear on success; change button label when connected UX/UI Medium Small
16 Not-found page font-bold text-7xl heading doesn't match app typography; uses old sharedStyles.primaryButton(); fake underlined link with no href Update to font-serif, use Button component, remove dead link UX/UI High Small
17 Error pages Four near-identical error boundary files with slightly different container/spacing patterns Extract shared <ErrorStateView> component Frontend cleanup Medium Small
18 Global error page "Try again" button loops forever on persistent errors; no navigation escape Add a "Go home" secondary link UX/UI Medium Small
19 Guest list GuestSearchFilter uses hand-rolled dropdowns with manual useOuterClick instead of Radix Select/DropdownMenu Migrate to shared UI components for keyboard nav and ARIA Frontend cleanup Medium Large
20 Guest list Filter chip dismiss buttons have no accessible aria-label Add descriptive labels to each chip dismiss button UX/UI Medium Small
21 Guest list GuestsView is a ~1000-line monolith owning filter, sort, drawer, and mutation state Extract drawer state to useHouseholdDrawer hook Frontend cleanup Medium Large
22 Guest list Mixed icon libraries: react-icons in guest-search-filter while everywhere else uses Lucide Replace react-icons imports with Lucide equivalents Frontend cleanup Medium Small

Selected Improvement

Not-found page design and dead-link fix — src/app/not-found.tsx


Why This Was Selected

The 404 page was a visible UX inconsistency: its heading style (font-bold text-7xl) predates the app's current design language, and it imported an old sharedStyles.primaryButton() helper instead of the Button component the rest of the app uses. It also showed a fake underlined "Help Center" link that triggered no action when clicked — actively confusing users. The fix is a single file, requires no API or routing changes, and brings the most user-facing error screen up to the same standard as every other screen in the product.

No open pull request covers this file.


Changes Made

  • Removed sharedStyles import; no longer needed
  • Added Button import from ~/components/ui/button
  • Replaced font-bold text-7xl <h1> with font-serif text-2xl heading matching app typography
  • Added 404 label in font-mono uppercase tracking-[0.18em] above the heading (same pattern as other contextual labels)
  • Added the icon-in-circle empty-state decoration used by VendorEmptyState and NoGuestsView
  • Changed body copy to font-mono text-[0.65rem] text-foreground/55 leading-relaxed tracking-wider to match empty-state descriptions throughout the app
  • Replaced <Link className={sharedStyles.primaryButton()}> with <Button asChild><Link href="/">…</Link></Button>
  • Removed the <span className='underline'>Search our Help Center or contact us.</span> dead link

Files Changed

  • src/app/not-found.tsx

Verification

  • tsc --noEmit: no new errors (one pre-existing tsconfig baseUrl deprecation warning unrelated to this change)
  • biome check src/app/not-found.tsx: clean, no diagnostics
  • Manual diff review: removed sharedStyles import (now unused in this file), added Button, confirmed asChild prop is supported by the project's Button component

Future Recommendations

Recommendation Priority Effort Reason not included GitHub issue?
Extract shared <ErrorStateView> component to replace 4 near-identical error boundary files Medium Small Multiple files; warrants its own focused PR No
Add "Go home" navigation link to global error.tsx to escape persistent errors Medium Small Safe to ship independently in next run No
Replace react-icons in guest-search-filter with Lucide icons Medium Small Low risk; safe for next run No
Events loading state: replace <p>Loading events…</p> with a skeleton Medium Small Safe for next run No
Format event.startTime/endTime raw DB strings to locale time Medium Small Safe for next run No
GuestSearchFilter hand-rolled dropdowns: migrate to Radix Select/DropdownMenu Medium Large Large scope; keyboard/ARIA rewrite needed Yes
GuestsView monolith: extract drawer state to useHouseholdDrawer hook Medium Large Significant refactor; needs careful scoping Yes
Remove window.dispatchEvent custom event for task dialog; use React context Medium Medium Architectural change; cross-component Yes

GitHub Issues Created or Proposed

No GitHub issues created in this run. The large recommendations above (guest filter refactor, GuestsView monolith, dashboard custom event) each meet the criteria for a tracked issue, but have been deferred to avoid scope creep. They can each be filed in a follow-up run once the open PR backlog is smaller.


🤖 Generated with Claude Code

https://claude.ai/code/session_01KiiHGPth3kxcEePxgts3AF


Generated by Claude Code

…ad link

Replace font-bold text-7xl heading with font-serif typography, drop the old
sharedStyles.primaryButton() import in favour of the Button component, add the
icon pattern used by other empty states, and remove the underlined "Help Center"
span that had no href and would confuse users who clicked it.

Co-Authored-By: AgenticDiego <noreply@carvallo.io>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KiiHGPth3kxcEePxgts3AF
@vercel

vercel Bot commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
scv Error Error Sep 2, 2026 2:24pm UTC

@github-actions

github-actions Bot commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

Jest Test Coverage

Coverage Summary

Lines Statements Branches Functions
Coverage: 83%
83.11% (36264/43629) 82.14% (3813/4642) 69.49% (1073/1544)

The not-found page heading changed from "We can't find this page" to
"Page not found" in the preceding commit, so update the E2E assertion to
match.

Co-Authored-By: AgenticDiego <noreply@carvallo.io>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KiiHGPth3kxcEePxgts3AF

This branch had an error being deployed

1 failed deployment
Preview — 6d64dc89 Deployed Sep 2, 2026 by vercel[bot]
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.

2 participants