Skip to content

feat(ui): Build an empty state and skeleton loading UI for the event dashboard #228

Description

@grantfox-oss

Body:
Summary
The main dashboard at app/dashboard/ currently has no defined UI states for when events are loading or when no events have been received yet. Users who open the app before any events arrive see a blank or broken layout with no feedback, which is a poor first impression and makes the app feel broken.
Problem

On first load, the event list renders nothing while the WebSocket connection is being established and the first events are fetched from Horizon/RPC
If a user searches for a contract that has emitted no events, the result is an empty list with no messaging
There is no visual distinction between "still loading" and "no results found"

Required work
Skeleton loader (components/dashboard/EventListSkeleton.tsx):

Create a skeleton component that renders 5–8 placeholder event rows matching the shape of a real translated event row
Use Tailwind's animate-pulse utility on placeholder blocks for text, address chips, and timestamp fields
Render the skeleton whenever the WebSocket connection is in a connecting state or the initial event fetch has not yet resolved

Empty state (components/dashboard/EmptyState.tsx):

Design a centred empty state panel with an icon (suggest a magnifying glass or blockchain icon from lucide-react), a heading ("No events found"), and a contextual subline that varies based on cause:

"Waiting for events on the Stellar network…" — when connected but no events received yet
"No events match your search." — when a search filter returns zero results
"Could not connect to Stellar. Retrying…" — on WebSocket error

Include a "Clear search" action button when the empty state is caused by a filter

Integration:

Wire the skeleton and empty states into the existing dashboard layout
Ensure transitions between states are smooth (no flash of empty content)

Acceptance criteria

Skeleton renders on initial load and disappears once the first event batch arrives
Empty state renders with correct contextual message for each cause
No layout shift when transitioning between skeleton → populated → empty states
Components are accessible: skeleton uses aria-busy="true", empty state uses role="status"
Existing dashboard tests continue to pass; new component tests added with at least 80% coverage

Metadata

Metadata

Assignees

Labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions