Skip to content

feat(design): loading skeletons and async state patterns#135

Open
johnsmccain wants to merge 1 commit intoPredictify-org:mainfrom
johnsmccain:design/loading
Open

feat(design): loading skeletons and async state patterns#135
johnsmccain wants to merge 1 commit intoPredictify-org:mainfrom
johnsmccain:design/loading

Conversation

@johnsmccain
Copy link
Copy Markdown

feat(design): loading skeletons and async state patterns

📝 Description

Implements loading skeletons for the three core surfaces (markets list, event detail, events table), inline async loading states for buttons/forms, and error + retry banners for network failures. All patterns are layout-shift-free.

🎯 Type of Change

  • 🎨 Style/UI changes
  • ✨ New feature (non-breaking change which adds functionality)

🔗 Related Issues

Closes #120

📋 Changes Made

New Files

File Purpose
components/skeletons/markets-skeleton.tsx MarketCardSkeleton + MarketsListSkeleton — mirrors market card layout exactly
components/skeletons/event-detail-skeleton.tsx EventDetailSkeleton — covers badges, title, stat grid, options, form
components/ui/async-button.tsx AsyncButton — inline spinner + loading text, auto-disables
components/ui/error-banner.tsx ErrorBanner — destructive alert with optional Retry action
app/(dashboard)/loading-patterns/page.tsx Demo page showing all 3 surfaces + patterns

Modified Files

File Change
app/(dashboard)/events/event-page/page.tsx Added isLoading/fetchError states; renders skeleton on load, error banner on failure; replaced manual Loader2 button with AsyncButton
components/events/events-section.tsx Reads error from events store; renders ErrorBanner with loadEvents as retry callback

Key Design Decisions

  • Skeleton blocks use explicit h-*/w-* sizes matching real content — no layout shift on reveal.
  • AsyncButton wraps the existing Button primitive; zero API surface change for callers.
  • ErrorBanner is a thin wrapper over the existing Alert component — consistent with the design system.
  • Error/retry pattern hooks directly into the Zustand events-store error + loadEvents — no new state needed.

🧪 Testing

  • ✅ Manual testing completed
  • ✅ TypeScript check passes (pnpm tsc --noEmit — zero new errors)
  • ✅ Mobile responsiveness tested (skeletons use responsive grid classes)
  1. Markets List Skeleton — 3 shimmer cards matching the marketing widget
  2. Event Detail Skeleton — full page skeleton for the event detail route
  3. Events Table Skeleton — existing skeleton wired via loading.tsx
  4. AsyncButton — live demo with 2-second simulated action
  5. ErrorBanner — with and without retry callback

✅ Pre-submission Checklist

  • ✅ Code follows project style guidelines (Tailwind, shadcn/ui primitives)
  • ✅ No TypeScript errors in new files
  • ✅ No new dependencies added
  • ✅ No breaking changes — all changes are additive
  • ✅ Skeletons match real content dimensions (no layout shift)
  • AsyncButton is backwards-compatible with Button props

🔧 Additional Notes

  • The two pre-existing TS errors (activity-timeline-demo/page.tsx, typography-example.tsx) are unrelated to this PR.
  • The /loading-patterns demo page can be removed before merging to main if not needed in production.

- Add MarketCardSkeleton / MarketsListSkeleton for markets widget
- Add EventDetailSkeleton for event detail page
- EventsTableSkeleton already existed; wired via loading.tsx
- Add AsyncButton: inline spinner + loading text, no layout shift
- Add ErrorBanner: destructive alert with optional Retry action
- Wire EventDetailSkeleton + ErrorBanner into event-page/page.tsx
- Wire ErrorBanner + retry into EventsSection (events-store error state)
- Add /loading-patterns demo page covering all 3 core surfaces
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 2, 2026

@johnsmccain is attempting to deploy a commit to the Jagadeesh B's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave
Copy link
Copy Markdown

drips-wave bot commented Apr 2, 2026

@johnsmccain 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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Design: Loading skeletons and async state patterns

1 participant