Skip to content

feat(web): implement authenticated home upcoming events empty state#385

Open
AbdulmalikAlayande wants to merge 2 commits intoAgora-Events:mainfrom
AbdulmalikAlayande:feat/upcoming-events-empty-state-284
Open

feat(web): implement authenticated home upcoming events empty state#385
AbdulmalikAlayande wants to merge 2 commits intoAgora-Events:mainfrom
AbdulmalikAlayande:feat/upcoming-events-empty-state-284

Conversation

@AbdulmalikAlayande
Copy link
Copy Markdown

Summary

This PR implements the authenticated dashboard Upcoming Events empty state requested in issue #284.

When the My Events > Upcoming tab has no data, the home page now renders a dedicated, branded empty-state experience instead of leaving the older inline placeholder logic embedded directly in apps/web/app/home/page.tsx.

Problem

The issue called for a polished empty-state treatment for the authenticated dashboard that would:

  • appear when upcomingEvents.length === 0
  • feel visually intentional and aligned with the existing Agora dashboard styling
  • include a branded illustration or placeholder visual
  • provide a clear message instead of a blank or weak placeholder
  • offer an obvious next step through a CTA
  • animate in smoothly with Framer Motion
  • remain responsive and accessible

What 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:

  • uses the existing empty-state-bg.svg and zero.svg assets already present in the project
  • uses motion.div for the requested fade-in and slight upward entrance
  • uses useReducedMotion so users who prefer less motion are not forced into the animated transition
  • keeps the layout centered and stable with a fixed minimum-height region to avoid visual collapse when the empty state appears
  • uses the shared Button component so the CTA remains consistent with the rest of the design system
  • routes the CTA to /discover so the empty state gives the user a meaningful next action

2. Wired the new component into the authenticated home dashboard

Updated apps/web/app/home/page.tsx.

The page now:

  • imports the reusable empty-state component
  • detects whether the active tab is upcoming
  • renders the dedicated empty-state component only for the empty Upcoming tab
  • keeps a lightweight generic fallback for other tabs if they ever become empty

3. Updated the current mock dashboard state so the issue scenario is visible

The upcomingEvents mock array in apps/web/app/home/page.tsx is now empty.

This makes the implemented issue state visible on /home immediately, 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:

  • removes the old inline illustration-specific imports that are now owned by the new component
  • removes the unused index parameter from the timeline render loop

Why the Work Is Split Into Two Commits

This PR is intentionally split into two commits so maintainers can review it in a clean order:

  1. feat(web): add reusable upcoming events empty state component
    This commit contains the visual building block only.

  2. feat(web): render upcoming events empty state on authenticated home
    This 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.tsx
  • apps/web/app/home/page.tsx

Reviewer Guide

Recommended review order:

  1. Review apps/web/components/empty-state/upcoming-events-empty-state.tsx
    Focus on the illustration composition, copy, CTA, animation, and responsive structure.

  2. Review apps/web/app/home/page.tsx
    Focus 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 install
  • pnpm --filter web lint
  • pnpm --filter web build

Results:

  • lint passed
  • production build passed

Build note:

  • Next.js prints a warning about detecting multiple lockfiles because apps/web/package-lock.json exists alongside the workspace pnpm-lock.yaml
  • this warning did not block the build and is not introduced by this PR

Behavior After This Change

When the authenticated home dashboard loads and the Upcoming tab has no events:

  • users see a branded empty-state card instead of the previous inline placeholder block
  • the state animates in smoothly
  • the CTA gives them a clear next step by taking them to Discover
  • the layout remains centered and consistent with the dashboard spacing and styling patterns already in the codebase

Risk and Scope

This change is low risk and intentionally narrow in scope.

It only affects:

  • the empty Upcoming state in the authenticated home dashboard
  • the related reusable component introduced for that state

It does not change:

  • the filled-state event cards
  • routing behavior outside the CTA click target
  • other dashboard sections except for the generic fallback that remains available if non-upcoming tabs become empty

Screenshots

Desktop

Pending attachment from local browser capture.

Mobile

Pending attachment from local browser capture.

Issue Link

Closes #284

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.
Copilot AI review requested due to automatic review settings March 30, 2026 14:02
@drips-wave
Copy link
Copy Markdown

drips-wave bot commented Mar 30, 2026

@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! 🚀

Learn more about application limits

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 30, 2026

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

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 UpcomingEventsEmptyState component with illustration, copy, and Framer Motion entrance behavior.
  • Updated /home to 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.

Comment on lines +16 to +18
initial={shouldReduceMotion ? { opacity: 0 } : { opacity: 0, y: 10 }}
animate={shouldReduceMotion ? { opacity: 1 } : { opacity: 1, y: 0 }}
transition={{ duration: 0.4, ease: "easeOut" }}
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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" }
}

Copilot uses AI. Check for mistakes.
@AbdulmalikAlayande
Copy link
Copy Markdown
Author

Local validation is green on this branch:

  • pnpm install
  • pnpm --filter web lint
  • pnpm --filter web build

Current upstream check blockers are authorization-related rather than code-related:

  • Frontend CI is in action_required on the upstream repo, which usually means the forked PR needs approval before the workflow can run there
  • Vercel is failing with Authorization required to deploy

Once those upstream permissions are granted, the remote checks should be able to evaluate the exact committed branch state already validated locally.

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.

[Frontend] Auth Home: Upcoming Events (Empty State)

2 participants