Skip to content

Standardize loading and empty states across the primary data pagesΒ #29

Description

@Meshmulla

πŸ‘‹ This is a great first issue β€” it's visible, self-contained, touches a handful of well-understood pages, and it noticeably improves how polished the whole app feels.

Background

Swipely has many data-driven pages, and right now they don't handle two very common situations consistently: while data is loading, and when there's no data to show. Some pages render a blank area, some show a bare spinner, some show nothing at all until data arrives. To a user, a blank panel is indistinguishable from a broken one β€” they can't tell whether the app is working, still loading, or genuinely empty. There's already an open issue about the empty state on the Bridges page specifically; this issue generalizes that fix into a consistent pattern across the primary pages.

Why this matters

Loading and empty states are small details that disproportionately shape how trustworthy an app feels. A skeleton that matches the shape of the incoming content tells the user "this is working, hold on" without a jarring layout jump. A friendly empty state tells them "there's genuinely nothing here β€” and here's what you can do about it" instead of leaving them staring at a blank rectangle wondering if something failed. Making these consistent across pages also makes the codebase more predictable for the next contributor.

What needs to be done

  • Establish or reuse a small set of shared building blocks: a loading skeleton/placeholder and an EmptyState component. Check src/components/ first β€” these may already exist, in which case reuse them rather than creating new ones.
  • Apply them consistently to the primary list/data pages β€” for example Bridges.tsx, Watchlist.tsx, Alerts.tsx, Incidents.tsx, and Transactions.tsx:
    • Loading: show a skeleton that roughly matches the eventual content's shape, so there's no layout shift when data arrives.
    • Empty: show a friendly EmptyState with a helpful message. Where filters or search can cause emptiness, distinguish "nothing here yet" from "nothing matches your current filter," and offer a way to clear the filters in the latter case.
  • Route all user-facing copy through the existing internationalization setup (react-i18next) rather than hardcoding strings.
  • Respect reduced-motion preferences for any shimmer/animation on the skeletons.

Where to look

  • src/components/ β€” existing EmptyState and skeleton primitives to reuse if present
  • src/pages/Bridges.tsx, Watchlist.tsx, Alerts.tsx, Incidents.tsx, Transactions.tsx
  • src/i18n/ β€” for the localized copy

Acceptance criteria

  • The listed pages show a consistent loading skeleton and a friendly EmptyState when empty
  • "Empty" versus "no matches" are distinguished where filtering exists, with a way to clear filters
  • Copy is localized via i18n, and reduced-motion is respected for any shimmer
  • Tests cover the empty rendering for at least one page
  • CI checks must be green before the PR can be merged

Notes

Scoped to the primary pages so it stays approachable β€” the remaining pages are future-batch work. If you're unsure whether a shared component already exists, just ask in the comments and someone will point you at it. πŸ™‚

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardThird CampaignCampaign: Third CampaignenhancementNew feature or requestgood first issueGood for newcomers

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions