Skip to content

Commit cb1d388

Browse files
lonerthefirst3-sudoclaudeKingsman-99
authored
Feat/payments devtools skeletons errorboundary (#374)
* feat: add /payments page with chronological transaction log - New /payments route showing all payments made by connected wallet - Sortable table (date desc by default, toggle amount) with pagination (20/page) - Total paid summary: "You have paid X XLM across Y invoices" - Download CSV exports full payment history - Empty state with Browse Invoices CTA - Responsive: table on desktop, card list on mobile - SkeletonPaymentRow placeholder during loading - Redirects to home if wallet is not connected Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: add Zustand stores with Redux DevTools integration - wallet, invoice, and UI Zustand stores in src/lib/stores/ - devtools middleware applied to all stores with explicit names: WalletStore, InvoiceStore, UIStore - immer middleware alongside devtools for ergonomic nested updates - DevTools enabled only in development (enabled: process.env.NODE_ENV === 'development') - Named set calls for every action (e.g. "wallet/setConnected") - 13 new store unit tests covering all state transitions - CONTRIBUTING.md: "Debugging state with Redux DevTools" section Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: expand skeleton screens for perceived-performance polish - SkeletonPaymentRow: matches payment history table row / mobile card - SkeletonLeaderboardRow: matches leaderboard row layout - SkeletonCreatorProfile: avatar + name + 3-stat grid - SkeletonDashboardStats: 4-card dashboard stats grid - InvoiceListSkeleton now accepts count prop (default 6) - DeferredSkeleton wrapper: suppresses skeleton if data loads < 200ms - useDeferredShow hook: 200ms delay before showing skeleton - All new skeletons have aria-busy="true" and aria-label="Loading..." - shimmer uses animate-pulse (light + dark mode compatible) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: integrate Sentry error reporting into error boundaries - @sentry/nextjs installed and configured via sentry.{client,server,edge}.config.ts - Sentry.init only called when NEXT_PUBLIC_SENTRY_DSN is set (disabled in dev) - withSentryConfig wraps next.config.js for source map upload on build - ErrorBoundary dynamically imports Sentry, calls captureException, displays event ID - "Something went wrong" fallback now shows Reload Page + Go to Dashboard buttons - Route-level error.tsx boundaries in /invoice/[id] and /dashboard - /payments/error.tsx added with route-level Sentry capture - Pre-existing bugs fixed: duplicate useRouter in DashboardClient, unclosed Link tag, missing JSX sibling wrapper, undefined canvas reference in timelineImageExport, missing "reminder" and "expired" notification types, mismatched ref type Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Emmanuel Chukwunyere <emmanuelanalaba@gmail.com>
1 parent fd28321 commit cb1d388

17 files changed

Lines changed: 3428 additions & 125 deletions

CONTRIBUTING.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,35 @@ feat: add invoice search to dashboard (#7)
6767
- Keep components small and focused (single responsibility).
6868
- All interactive elements must be keyboard-accessible.
6969

70+
## Debugging State with Redux DevTools
71+
72+
StellarSplit uses [Zustand](https://github.com/pmndrs/zustand) for client-side state. Three stores are available:
73+
74+
| Store | Location | DevTools name |
75+
|---|---|---|
76+
| Wallet | `src/lib/stores/walletStore.ts` | `WalletStore` |
77+
| Invoice | `src/lib/stores/invoiceStore.ts` | `InvoiceStore` |
78+
| UI | `src/lib/stores/uiStore.ts` | `UIStore` |
79+
80+
### Setting up the extension
81+
82+
1. Install the [Redux DevTools browser extension](https://github.com/reduxjs/redux-devtools#browser-extension).
83+
2. Run the dev server: `npm run dev`.
84+
3. Open DevTools → **Redux** tab.
85+
86+
The three stores appear by name. You can:
87+
- **Inspect** current state and individual action payloads.
88+
- **Time-travel** by clicking any action in the log to jump to that state snapshot.
89+
- **Replay** a sequence of actions to reproduce a bug.
90+
91+
### DevTools is development-only
92+
93+
The middleware is tree-shaken out in production (`NODE_ENV !== 'development'`). No DevTools overhead ships to users.
94+
95+
### Named actions
96+
97+
Each `set` call in the stores uses a named action (e.g. `"wallet/setConnected"`). When adding new state mutations, keep this convention so the DevTools log stays readable.
98+
7099
## Questions?
71100

72101
Open a [Discussion](../../discussions) or ask in the issue thread.

next.config.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const withBundleAnalyzer = require("@next/bundle-analyzer")({
22
enabled: process.env.ANALYZE === "true",
33
});
4+
const { withSentryConfig } = require("@sentry/nextjs");
45

56
/** @type {import('next').NextConfig} */
67
const nextConfig = {
@@ -40,4 +41,17 @@ const nextConfig = {
4041
},
4142
};
4243

43-
module.exports = withBundleAnalyzer(nextConfig);
44+
const sentryWebpackPluginOptions = {
45+
org: process.env.SENTRY_ORG,
46+
project: process.env.SENTRY_PROJECT,
47+
authToken: process.env.SENTRY_AUTH_TOKEN,
48+
// Only upload source maps when a real DSN is configured (i.e. in CI / production)
49+
silent: true,
50+
disableServerWebpackPlugin: !process.env.NEXT_PUBLIC_SENTRY_DSN,
51+
disableClientWebpackPlugin: !process.env.NEXT_PUBLIC_SENTRY_DSN,
52+
};
53+
54+
module.exports = withSentryConfig(
55+
withBundleAnalyzer(nextConfig),
56+
sentryWebpackPluginOptions
57+
);

0 commit comments

Comments
 (0)