Skip to content

#720 Rebuild The Page Skeletons On Shared Components - #754

Open
b-at-neu wants to merge 1 commit into
devfrom
720-rebuild-page-skeletons-on-shared-components
Open

b-at-neu wants to merge 1 commit into
devfrom
720-rebuild-page-skeletons-on-shared-components

Conversation

@b-at-neu

Copy link
Copy Markdown
Collaborator

Closes #720

Summary

  • Replaces fourteen hand-drawn loading.tsx skeletons with composition of four new shared skeletons (PageHeaderSkeleton, DataTableSkeleton, DataTableToolbarSkeleton, PositionCardSkeleton), each living beside the real component it mirrors and sharing its layout constants — following the precedent already set by SectionCardSkeleton.
  • Absorbs the two standalone table skeletons (ApplicationsTableSkeleton, EmailLogTableSkeleton) into ApplicationsResultsSkeleton / EmailLogResultsSkeleton so the pagination summary line no longer disappears mid-stream.
  • Fixes two genuine mobile bugs surfaced by building skeletons from real component classes rather than by eye: action/back-link placeholders were 12px short below md (Button is min-h-11 md:min-h-0), and badge placeholders were 20px instead of the real 22px (Badge is text-xs py-0.5 + border).
  • manage/positions/[id]/edit/loading.tsx is intentionally left untouched — it's owned by Redesign The Edit Position Page #666 (PR #666 Redesign The Edit Position Page #690).
  • /positions/[id]/loading.tsx keeps a bespoke (but corrected) header skeleton, since that page hand-rolls its own header instead of using PageHeader.
  • Adds tests/unit/loading-skeletons.test.ts, a filesystem guard that fails if a loading.tsx re-implements Card/Table markup, uses raw animate-pulse, or skips PageHeaderSkeleton (with a documented exception list).
  • Documents the adjacency rule and the row-count convention in docs/DESIGN.md §5.

Changes

  • lib/data-table.ts — new DATA_TABLE_* shell class constants, consumed by components/ui/data-table.tsx.
  • components/ui/data-table-skeleton.tsx — new server component DataTableSkeleton, built on the real Table/TableHead/TableCell primitives.
  • components/ui/data-table-toolbar.tsx — new DataTableToolbarSkeleton.
  • components/layouts/page-header.tsx — hoisted PageHeader class constants, new PageHeaderSkeleton.
  • components/features/position-card.tsx — new PositionCardSkeleton (built against the current PositionStatCluster shape on dev; Replace The Position Card Stat Tiles With Four Status Circles #682 has not yet landed).
  • components/features/applications-results.tsx, components/features/email-log-results.tsx — new *ResultsSkeleton exports.
  • components/features/applications-table-skeleton.tsx, components/features/email-log-table-skeleton.tsx — deleted, superseded by the *ResultsSkeleton exports above.
  • app/(main)/(auth)/manage/applications/page.tsx, app/(main)/(auth)/emails/page.tsxSuspense fallbacks point at the new skeletons.
  • 13 of 14 loading.tsx files rewritten as pure composition of the shared skeletons.
  • tests/unit/loading-skeletons.test.ts — new filesystem guard.
  • docs/DESIGN.md §5 — skeleton adjacency rule + row-count convention.

Testing plan

  • / as admin, as manager, and as a plain applicant: header lands in place, then each dashboard's own widget skeletons appear; no wrong-shaped card flash.
  • /positions signed out and signed in: card heights and the group heading hold; check a position with a long description and one with none.
  • /positions/[id]: back link, title, badge and date line hold; page stays full-bleed with max-w-2xl prose (unchanged width tier).
  • /manage/positions as manager and as admin: group headings and stat columns hold for a manager with only Open positions and one with Open + Closed + Draft; expand Archived.
  • /users: header (with Create user), all three toolbar fields, the trailing count line, and the six table columns hold — confirm the previous 4px jump on resolve is gone.
  • /global-questions: the drag-handle column lines up and the reorder hint does not flash.
  • /applications (My Applications): confirm the columns line up with the resolved <table> instead of reflowing (the grid grid-cols-4 defect called out in the ticket).
  • /manage/applications: default view, then ?status=draft (no checkbox column, privacy line present), then apply a filter so results re-stream — the pagination line should not appear from nowhere.
  • /emails: failure strip, toolbar, info line, table and pagination line all hold.
  • /applications/[id] and /manage/applications/[id]: back link, title + status badge, header actions and meta line hold; on a phone-width viewport confirm the back link and actions render at 44px, not 32px.
  • /profile and /positions/[id]/apply: header holds.
  • Dark mode spot-check on two routes (skeletons use bg-muted).
  • /manage/positions/[id]/edit is untouched and behaves exactly as on dev.
  • Throttle network (DevTools → Slow 4G) at 375px and 1280px on each route above; confirm nothing moves vertically on resolve.
  • Signed-out / unauthorized access to auth-gated routes behaves as before (no change to route guards in this PR).

Automated checks

  • npm run prettier:check — pass
  • npm run eslint:check — pass
  • npm run tsc:check — pass
  • npm run test:unit — 451 passed (one pre-existing failure, email-delivery-events.test.ts, is a DATABASE_URL environment limitation unrelated to this change); npm run test (db project) could not run locally because Postgres isn't available in this environment — CI will run the full suite against a real database.

Notes

  • DataTableSkeleton lives in a new server module rather than inside 'use client' data-table.tsx, per the plan's documented deviation: importing a client module from a server loading.tsx would pull nuqs/dnd-kit into that route's client bundle and the shared class constants would be unreadable from a server component anyway.
  • PositionCardSkeleton's stat column mirrors today's PositionStatCluster shape on dev; if Replace The Position Card Stat Tiles With Four Status Circles #682 (stat circles) lands later, that PR must update the skeleton in the same change — the adjacency rule and shared file are there to make that coupling obvious.
  • Column widths remain declared twice (real cells in the 'use client' table vs. placeholder widths in the skeleton) since a client module's column config can't be imported into a server module. The new test narrows drift to widths only — column count, heights, padding and borders are now structural.

Replace fourteen hand-drawn loading.tsx blocks with composition of
new PageHeaderSkeleton, DataTableSkeleton, DataTableToolbarSkeleton
and PositionCardSkeleton, each living beside and sharing layout
constants with the real component it mirrors. Absorbs the two
standalone table skeletons into ApplicationsResultsSkeleton and
EmailLogResultsSkeleton so the pagination line is no longer missing
mid-stream. Adds a filesystem guard test so the fix can't rot.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@b-at-neu b-at-neu added the claude Will be worked on by Claude label Sep 21, 2026
@b-at-neu b-at-neu self-assigned this Sep 21, 2026
@vercel

vercel Bot commented Sep 21, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
aplio Error Error Sep 21, 2026 4:04am UTC

@b-at-neu b-at-neu added ready for review PR ready for review agent reviewing Review agent working (in-flight) and removed ready for review PR ready for review agent labels Sep 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claude Will be worked on by Claude reviewing Review agent working (in-flight)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rebuild The Page Skeletons On Shared Components

1 participant