Skip to content

feat: Frontend UI enhancements — Toasts, Wallet Modal, Trading Interface & Activity Feed - #285

Merged
parkerwinner merged 4 commits into
parkerwinner:mainfrom
jayteemoney:feat/frontend-ui-enhancements
Jul 29, 2026
Merged

parkerwinner merged 4 commits into
parkerwinner:mainfrom
jayteemoney:feat/frontend-ui-enhancements

Conversation

@jayteemoney

Copy link
Copy Markdown
Contributor

Summary

Four frontend features, one per commit, all built on the existing design system (shadcn-style primitives, CSS variables, light/dark) and branched from the current main (e7fc3e8) so it merges cleanly.

  • Toast notification system for feedback #261 — Toast notifications: headless store in lib/toast.ts (queue, variants, actions, auto-dismiss, toast.promise) + ui/Toast.tsx portal container mounted in the root layout. The existing sonner call sites were migrated to the new API (toast.success / toast.error signatures are unchanged).
  • Enhanced wallet connection with multiple providers #244 — Multi-provider wallet connection: lib/wallet-providers.ts registry for Freighter, Albedo, LOBSTR, xBull and Rabet with detection, connect/sign/disconnect, typed errors and session restore; WalletModal.tsx picker + account view; WalletConnect.tsx now opens the modal and keeps its original props.
  • Buy/sell interface for asset trading #245 — Buy/sell trading interface: /trade/[id] with OrderBook.tsx (depth bars, spread, click-to-fill), OrderForm.tsx (market/limit, slippage presets, live fee + price-impact calculator) and OrderConfirmModal.tsx (full breakdown, slippage limits, ETA, high-impact warnings). Pricing maths lives in lib/trading.ts.
  • Real time activity feed for platform events #268 — Real-time activity feed: useActivityFeed.ts (cursor pagination, filtering, WebSocket updates with de-duplication, day grouping) + ActivityFeed.tsx (type filters, event icons, sticky day headers, infinite scroll) and a /activity route so it's reachable.

Notes for the reviewer

  • Every feature has explicit loading, empty and error states. Where a backend endpoint doesn't exist yet (order book, activity), the UI falls back to clearly labelled sample data rather than an empty screen — the same pattern the analytics page already uses.
  • getWebSocketUrl() was added to lib/websocket.ts and is shared by the trade page and the activity feed; both reuse the existing WebSocketClient.
  • components/ui/sonner.tsx is now unused. It was left in place on purpose to avoid conflicting with branches that still touch it — safe to delete in a follow-up.
  • Reusable pieces added along the way: components/ui/dialog.tsx (Radix dialog primitive) and the existing InfiniteScroll component is reused by the feed.

Verification

  • npm run lint and npx tsc --noEmit: no new errors or warnings — counts are identical to main before this branch (36 errors / 34 warnings, all pre-existing).
  • next build compiles the new code successfully (✓ Compiled successfully).
  • /activity and /trade/<id> were rendered against a local dev server and return 200 with the expected markup.

Pre-existing breakage on main (not touched by this PR)

These already fail on e7fc3e8 and are unrelated to these features — flagging them since they block a fully green build:

  1. src/hooks/useWebSocket.ts contains JSX (WSStatusBadge) in a .ts file → parse/type error. Needs renaming to .tsx.
  2. src/components/charts/PieChart.tsx has two recharts v3 typing errors (label, Tooltip formatter).
  3. next-intl@3 doesn't support Next 16 (peer conflict requires --legacy-peer-deps), and at runtime every route 500s with "Couldn't find next-intl config file".

Closes #261
Closes #244
Closes #245
Closes #268

Adds an in-app toast system with a headless store so any module can raise a
notification without prop drilling.

- lib/toast.ts: queue, variants (success/error/warning/info/loading), action
  buttons, per-variant auto-dismiss durations, update-by-id and toast.promise
- ui/Toast.tsx: portal container with position/max-visible options, pause on
  hover or focus, overflow counter, reduced-motion friendly animations, and
  role=status / role=alert announcements
- layout.tsx: mounts <ToastContainer /> in place of the sonner Toaster
- migrates existing toast call sites to @/lib/toast (API-compatible)

Closes parkerwinner#261
…r#244)

Replaces the Freighter-only connect button with a multi-provider flow.

- lib/wallet-providers.ts: registry for Freighter, Albedo, LOBSTR, xBull and
  Rabet with detection, connect, sign, disconnect, typed WalletError codes and
  localStorage-backed session restore
- WalletModal.tsx: provider picker with detection badges, install links for
  missing wallets, per-provider connecting state, error handling, re-scan, plus
  a connected account view (copy address, disconnect)
- WalletConnect.tsx: opens the modal, silently restores the previous session,
  and gains a compact `button` variant — existing props are unchanged
- ui/dialog.tsx: shared Radix dialog primitive used by the modal

Closes parkerwinner#244
Adds a trading ticket at /trade/[id].

- lib/trading.ts: order book types, quote maths (book walking, average fill
  price, platform + network fees, price impact, slippage limits, completion
  estimate), order submission and a WebSocket book subscription
- OrderBook.tsx: bids/asks with depth bars, spread, click-to-fill pricing,
  loading/empty/error states
- OrderForm.tsx: market and limit orders, slippage presets, live cost
  calculator, validation, imperative applyPrice for order book clicks
- OrderConfirmModal.tsx: final review with fee breakdown, slippage limits and
  warnings for thin liquidity or high price impact
- trade/[id]/page.tsx: asset summary, live/polling book updates, recent trades
- websocket.ts: shared getWebSocketUrl() helper

Sample depth is used (and clearly labelled) when the marketplace API is
unavailable, matching the existing analytics page pattern.

Closes parkerwinner#245
Adds a platform-wide activity feed.

- hooks/useActivityFeed.ts: cursor pagination, type/asset filtering, live
  WebSocket updates with de-duplication, retained-event cap, and day grouping
  (Today / Yesterday / dated sections)
- ActivityFeed.tsx: per-type icons and filter chips, sticky day headers,
  infinite scroll via the existing InfiniteScroll component, live status
  indicator, skeleton loading, empty and error states
- activity/page.tsx: standalone /activity route so the feed is reachable

Falls back to labelled sample events when the activity API is unavailable.

Closes parkerwinner#268
@drips-wave

drips-wave Bot commented Jul 28, 2026

Copy link
Copy Markdown

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

@parkerwinner

Copy link
Copy Markdown
Owner

code reviewed

@parkerwinner
parkerwinner merged commit ac47a41 into parkerwinner:main Jul 29, 2026
3 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants