feat(web): implement authenticated home upcoming events empty state#385
Conversation
Introduce a dedicated UpcomingEventsEmptyState component so the authenticated home dashboard can render a polished, self-contained upcoming-events placeholder without keeping the illustration, copy, motion, and CTA logic inline inside the page component. Implementation details: - builds the empty state as a client component under apps/web/components/empty-state for clear reuse and easier review - uses the existing branded zero badge and empty-state illustration assets already present in the web app to stay visually aligned with the Agora dashboard - applies the requested Framer Motion entrance behavior with a reduced-motion-aware fallback so the component remains accessible - preserves layout stability with a fixed minimum-height container and constrained card sizing that matches the design intent - adds a prominent CTA using the existing shared Button component and routes users to /discover so the empty state is actionable instead of decorative This commit is intentionally isolated from the page integration so maintainers can review the visual building block first, then inspect the dashboard wiring separately in the follow-up commit.
Wire the new UpcomingEventsEmptyState component into the authenticated dashboard so the My Events > Upcoming tab now shows the designed empty experience whenever there are no upcoming events instead of leaving a generic placeholder block in place. Implementation details: - imports the new reusable empty-state component into apps/web/app/home/page.tsx and removes the older inline illustration-specific imports - updates the temporary upcomingEvents mock data to an empty array so the issue state is represented in the current authenticated dashboard implementation - adds an isUpcomingTab guard inside MyEventsContent so only the upcoming tab receives the high-fidelity empty state while other empty tabs keep a lightweight fallback message - replaces the previous inline markup with the dedicated component, reducing duplication and keeping the page component easier to scan - removes the unused map index parameter introduced by the refactor to keep the rendering code tidy Validation performed before this commit: - pnpm install - pnpm --filter web lint - pnpm --filter web build The split between this commit and the previous one is deliberate: this commit answers where and when the empty state appears, while the previous commit answers how the empty state UI itself is built.
|
@AbdulmalikAlayande 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! 🚀 |
|
@AbdulmalikAlayande is attempting to deploy a commit to the oseh-svg's projects Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
Pull request overview
Implements a dedicated, branded empty state for the authenticated Home dashboard’s My Events → Upcoming tab when there are no upcoming events, moving the UI/animation/CTA out of page.tsx into a reusable component.
Changes:
- Added a new
UpcomingEventsEmptyStatecomponent with illustration, copy, and Framer Motion entrance behavior. - Updated
/hometo render the new empty state only for the Upcoming tab when its events array is empty (with a generic fallback for other empty tabs). - Adjusted mock data to make the Upcoming tab empty and removed now-obsolete inline empty-state logic (and an unused map index param).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| apps/web/components/empty-state/upcoming-events-empty-state.tsx | New reusable Upcoming empty-state UI with Framer Motion + CTA to Discover |
| apps/web/app/home/page.tsx | Integrates the new component into the Upcoming tab empty branch and removes inline placeholder code |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| initial={shouldReduceMotion ? { opacity: 0 } : { opacity: 0, y: 10 }} | ||
| animate={shouldReduceMotion ? { opacity: 1 } : { opacity: 1, y: 0 }} | ||
| transition={{ duration: 0.4, ease: "easeOut" }} |
There was a problem hiding this comment.
useReducedMotion() is intended to minimize/disable animations, but the reduced-motion branch still animates opacity from 0→1 using the same transition (0.4s). Consider skipping animation entirely when shouldReduceMotion is true (e.g., set initial={false} and/or use a 0 duration transition in that branch) so reduced-motion users don’t get a fade-in.
| initial={shouldReduceMotion ? { opacity: 0 } : { opacity: 0, y: 10 }} | |
| animate={shouldReduceMotion ? { opacity: 1 } : { opacity: 1, y: 0 }} | |
| transition={{ duration: 0.4, ease: "easeOut" }} | |
| initial={shouldReduceMotion ? false : { opacity: 0, y: 10 }} | |
| animate={shouldReduceMotion ? { opacity: 1 } : { opacity: 1, y: 0 }} | |
| transition={ | |
| shouldReduceMotion | |
| ? { duration: 0 } | |
| : { duration: 0.4, ease: "easeOut" } | |
| } |
|
Local validation is green on this branch:
Current upstream check blockers are authorization-related rather than code-related:
Once those upstream permissions are granted, the remote checks should be able to evaluate the exact committed branch state already validated locally. |
Summary
This PR implements the authenticated dashboard Upcoming Events empty state requested in issue #284.
When the
My Events > Upcomingtab has no data, the home page now renders a dedicated, branded empty-state experience instead of leaving the older inline placeholder logic embedded directly inapps/web/app/home/page.tsx.Problem
The issue called for a polished empty-state treatment for the authenticated dashboard that would:
upcomingEvents.length === 0What I Implemented
1. Added a reusable empty-state component
Created
apps/web/components/empty-state/upcoming-events-empty-state.tsx.This component encapsulates the empty-state UI so the page component does not need to manage the illustration layout, copy, animation, and CTA inline.
The component:
empty-state-bg.svgandzero.svgassets already present in the projectmotion.divfor the requested fade-in and slight upward entranceuseReducedMotionso users who prefer less motion are not forced into the animated transitionButtoncomponent so the CTA remains consistent with the rest of the design system/discoverso the empty state gives the user a meaningful next action2. Wired the new component into the authenticated home dashboard
Updated
apps/web/app/home/page.tsx.The page now:
upcoming3. Updated the current mock dashboard state so the issue scenario is visible
The
upcomingEventsmock array inapps/web/app/home/page.tsxis now empty.This makes the implemented issue state visible on
/homeimmediately, which matches the issue request and makes the change easy to review in the running application.4. Removed small bits of now-obsolete inline code
As part of the integration, the page cleanup also:
indexparameter from the timeline render loopWhy the Work Is Split Into Two Commits
This PR is intentionally split into two commits so maintainers can review it in a clean order:
feat(web): add reusable upcoming events empty state componentThis commit contains the visual building block only.
feat(web): render upcoming events empty state on authenticated homeThis commit contains the page integration, the empty-data trigger, and the small cleanup around the old inline implementation.
This separation should make the review faster because the reviewer can first validate the component in isolation and then validate where and when it is used.
Files Changed
apps/web/components/empty-state/upcoming-events-empty-state.tsxapps/web/app/home/page.tsxReviewer Guide
Recommended review order:
Review
apps/web/components/empty-state/upcoming-events-empty-state.tsxFocus on the illustration composition, copy, CTA, animation, and responsive structure.
Review
apps/web/app/home/page.tsxFocus on the conditions under which the new component renders, the fact that it is scoped to the Upcoming tab, and the small cleanup around the previous inline placeholder.
Validation
I ran the same frontend workflow steps that the repository CI uses:
pnpm installpnpm --filter web lintpnpm --filter web buildResults:
Build note:
apps/web/package-lock.jsonexists alongside the workspacepnpm-lock.yamlBehavior After This Change
When the authenticated home dashboard loads and the Upcoming tab has no events:
Risk and Scope
This change is low risk and intentionally narrow in scope.
It only affects:
It does not change:
Screenshots
Desktop
Pending attachment from local browser capture.
Mobile
Pending attachment from local browser capture.
Issue Link
Closes #284