Skip to content

feat: policy dashboard — paginated list, filters, action flows - #257

Merged
jhayniffy merged 2 commits into
InsurNiffy:mainfrom
darcszn:feat/policy-dashboard
Mar 28, 2026
Merged

feat: policy dashboard — paginated list, filters, action flows#257
jhayniffy merged 2 commits into
InsurNiffy:mainfrom
darcszn:feat/policy-dashboard

Conversation

@darcszn

@darcszn darcszn commented Mar 28, 2026

Copy link
Copy Markdown
Contributor

What was built

features/policies/api/index.ts

Zod-validated API client that mirrors the backend PolicyListDto shape exactly. Passes holder, status, after (cursor),
and limit as query params. Throws a typed PolicyListError on non-OK responses or parse failures.

features/policies/hooks/usePolicies.ts

useReducer-based hook with per-page cursor caching. Key design decisions:

  • Cache key includes holder + network + status + sort — any change triggers a full RESET
  • Pages are cached by index; navigating back to a previous page is instant
  • retry() dispatches INVALIDATE_PAGE on the current index, which causes the effect to re-fetch without resetting the
    whole cache
  • state.pages is intentionally excluded from the effect deps to avoid infinite loops — only pageIndex triggers re-
    fetches

features/policies/components/PolicyItem.tsx

  • PolicyCard — mobile/card layout with formatXlm() (stroops ÷ 10⁷, locale-aware)
  • PolicyRow — table row for desktop
  • ActionButton — disabled with title tooltip + aria-label explaining the contract rule when unavailable
  • Renewal gate: active + within 30-day window (≤ 518_400 ledgers)
  • Terminate gate: active only
  • Deep links to /policy/[holder]/[policyId]

features/policies/components/PolicyStates.tsx

  • PolicyListSkeleton — adapts to row/card layout
  • PolicyEmptyState — three variants (all/active/expired) with CTA for first-time users
  • PolicyErrorState — distinguishes wallet-not-connected from fetch errors; shows retry button only when retrying makes
    sense

features/policies/components/PolicyDashboard.tsx

Orchestrates everything: status filter, sort select, layout toggle (table/card), count label, content area, and
pagination. Resets to page 0 on filter change to avoid cursor mismatches.

features/policies/components/RenewModal.tsx + TerminateModal.tsx

Multi-step modals: confirm → signing → done | error. Both explain the on-chain transaction requirement upfront and
include the indexer-lag microcopy note.

app/dashboard/page.tsx

New route at /dashboard rendering PolicyDashboard.

app/policy/[holder]/[policyId]/page.tsx

Deep-link detail page. Uses getPolicy() (chain read, no indexer lag) and explicitly notes this in the microcopy.
Breadcrumb back to /dashboard.

i18n (messages/en/policy.json, messages/es/policy.json)

Added dashboard.* namespace with all UI strings in both languages.

- Add paginated policy list at /dashboard with active/expired filter,
  sort (expiry/coverage/premium), and row/card layout toggle
- Cursor-based pagination with per-page cache; reset on filter/network change
- Skeleton loaders, empty states (first-time user CTA), and error state with retry
- PolicyCard (mobile) + PolicyRow (desktop) with locale-aware XLM formatting
  (stroops ÷ 10^7) and tabular-nums
- Action buttons disabled with tooltip explanations when contract rules forbid:
  - Renew: active + within 30-day window (≤518,400 ledgers)
  - Terminate: active policies only
- RenewModal + TerminateModal: confirm → sign → done/error steps with
  indexer-lag microcopy ("dashboard may take up to 15s to reflect change")
- Deep-link policy detail page at /policy/[holder]/[policyId] using chain
  read (no indexer lag); notes this distinction in microcopy
- i18n: add dashboard.* namespace to en + es policy.json
@drips-wave

drips-wave Bot commented Mar 28, 2026

Copy link
Copy Markdown

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

@drips-wave

drips-wave Bot commented Mar 28, 2026

Copy link
Copy Markdown

Hey @darcszn! 👋 It looks like this PR isn't linked to any issue.

If this PR is for one of the issues assigned to you as part of a Wave, please link it to ensure your contribution is tracked properly. You can do this by adding a keyword to the PR description (e.g., Closes #123), or by clicking a button below:

Issue Title
#75 Frontend — Policies dashboard: lists, filters, renewal/terminate actions, and empty states Link to this issue

ℹ️ Learn more about linking PRs to issues

@jhayniffy
jhayniffy merged commit 9500a85 into InsurNiffy:main Mar 28, 2026
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.

2 participants