Skip to content

Feat/dashboard network context deposit validation copy export - #1072

Merged
Ceejaytech25 merged 7 commits into
ceejaylaboratory:mainfrom
francisdouglas-ux:feat/dashboard-network-context-deposit-validation-copy-export
Aug 28, 2026
Merged

Ceejaytech25 merged 7 commits into
ceejaylaboratory:mainfrom
francisdouglas-ux:feat/dashboard-network-context-deposit-validation-copy-export

Conversation

@francisdouglas-ux

Copy link
Copy Markdown
Contributor

Overview

This Pull Request delivers core state management, client-side validation, accessibility feedback, and data export enhancements across the dashboard workspace.

Key improvements include a centralized NetworkContext orchestrating Horizon and Soroban RPC endpoint re-instantiation, dynamic per-asset Zod validation in DepositForm via React Hook Form, keyboard-accessible copy-to-clipboard feedback with polite ARIA announcements, and client-side RFC-4180 CSV/JSON transaction exporting with date and status filtering.

Linked Issues


Summary of Changes

1. Global Network State & SDK Server Synchronization (#956 / #52)

  • Centralized Network Management: Implemented NetworkContext.tsx, networks.ts, and servers.ts to manage active network configurations (Testnet, Mainnet/Public, Futurenet).
  • Dynamic Server Rebuilding: Because SDK server instances bind URLs at construction, switching networks tears down existing clients and initializes fresh Horizon and Soroban RPC connections. Failed backend switches preserve existing active endpoints to maintain state consistency.
  • Status Telemetry: Integrated NetworkBanner with visual warning states for Mainnet environments.

2. Dynamic Schema Validation for SEP-24 Deposits (#948 / #44)

  • Form Modernization: Refactored DepositForm.tsx to react-hook-form with zodResolver.
  • Per-Asset Bounds: Replaced global static limits with asset-specific configuration rules (properly handling precision and boundaries for assets like ARST and USDC).
  • SEP-24 Formatting: Enforced alphanumeric format constraints and mapped field errors to inline red borders, messages, and aria-invalid="true" attributes.

3. Accessible Clipboard Feedback (#947 / #43)

  • Visual States: Added a 2-second "Copied!" (and "Copy failed") tooltip alongside checkmark icon state changes.
  • Accessibility Discipline: Tooltip is marked aria-hidden="true" to prevent redundant screen reader announcements over the existing aria-live="polite" region. Relies on native <button> behavior for clean Enter/Space keyboard execution without double-firing.

4. Client-Side Transaction Exporter (#946 / #42)

  • Pure Formatter Functions: Extracted toCsv, toJson, csvEscape, filterTransactions, and buildFilename as pure utilities.
  • Scoping & Controls: Added interactive date-range and status filters, accurate records-exported counters, and automated disable states when selection sets are empty.

5. Workspace Health & Translation Bug Fixes

  • I18n Provider Hoisting: Fixed a bug where App.tsx invoked useTranslation() before I18nProvider mounted, which previously caused raw keys (nav.overview, wallet.connect) to render as literal text. Repaired unbalanced JSX delimiters in App.tsx.
  • Dependency Parity: Aligned react-dom and @types/react to React 19 in package.json to ensure clean Vitest runs with DOM matchers.

Verification Logs

  • Vitest Suite: npx vitest run src executes across 9 test files with 125/125 tests passing (verified over 3 consecutive runs).
  • Type Safety: Zero TypeScript compiler errors across all modified and newly created files.

Notes for Maintainers

  • PR Independence: Cut independently from clean main. Carries minimal dependency alignment (react-dom to React 19) and Vitest setup mocks required for tests to run.
  • Pre-Existing Syntax Issues: Pre-existing bad-merge syntax errors in unrelated files (Tooltip.tsx, AdminWidgets.tsx, ContractPlayground.tsx) remain on main and were untouched to preserve PR focus.

godamongstmen897 and others added 4 commits August 27, 2026 14:42
…in NetworkSelector

Switching networks only moved NetworkSelector's own useState, so the rest of
the app kept talking to the previous Horizon and Soroban RPC endpoints.

Add a global NetworkContext owning the active network, its endpoint set
(Horizon URL, Soroban RPC URL, network passphrase) and the SDK server pair,
rebuilt as a new instance whenever the network changes — servers bind their
base URL at construction, so they cannot be repointed in place. A rejected
backend switch leaves the endpoints on the network the backend is still using.

NetworkSelector now drives that context behind its typed confirmation, and a
NetworkBanner names the live environment, styled as a warning on mainnet.

Repairs the unbalanced I18nProvider JSX in App.tsx, which left the file
uncompilable, and adds a Vitest setup providing the matchMedia stub jsdom
lacks. Aligns react-dom and @types/react with the React 19 already declared in
dashboard/package.json; the mismatch made every React test file fail to import.

Closes ceejaylaboratory#956

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…e validation in DepositForm

Move the hand-rolled state and validation onto react-hook-form with a Zod
resolver, and derive the schema from the field set plus the active asset so
the bounds enforced always match the asset on screen.

Amount limits and decimal precision now come from a per-asset table rather
than a single hardcoded $10/$100k floor and ceiling, which either blocked
valid ARST deposits or let dust-sized USDC deposits reach the backend. Asset
code fields are checked against the SEP-24 alphanumeric format.

Invalid fields keep their red border, inline message and aria-invalid, and the
submit handler no longer fires until the whole schema parses.

Closes ceejaylaboratory#948

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…n CopyablePublicKey

Copying swapped the icon and updated an sr-only live region, but sighted users
got no confirmation they could point at. Add a "Copied!" tooltip above the
button, held for two seconds alongside the checkmark, with a "Copy failed"
variant when the clipboard write rejects.

The bubble is aria-hidden so the polite live region stays the single
announcement rather than being read twice.

Cover the copied state, its two-second lifetime, the live-region announcement
and Enter/Space activation of the native button, which needs no key handler of
its own — one would double-fire against the synthesised click.

Closes ceejaylaboratory#947

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ansactionExporter

Pull the CSV and JSON formatters, the RFC-style field escaping and the
filename builder out as exported pure functions so the serialisation is
testable without a DOM, then add date-range and status controls that scope
which records the download contains. The written metadata now distinguishes
the number of records exported from the number available.

Both buttons are disabled when the filters select nothing, rather than
downloading a header-only file.

Hoists I18nProvider above App: App calls useTranslation() itself, so
rendering the provider inside App's own tree left every t() call resolving to
the raw key. Registers the jest-dom matchers in the Vitest setup and points
App's wallet test at the provider picker the header button actually opens.

Closes ceejaylaboratory#946

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@drips-wave

drips-wave Bot commented Aug 27, 2026

Copy link
Copy Markdown

@francisdouglas-ux 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

godamongstmen897 and others added 3 commits August 27, 2026 15:13
…ork-context-deposit-validation-copy-export

# Conflicts:
#	package-lock.json
The Dashboard QA check fails on main: three components carry interleaved
bad-merge artifacts that no parser accepts, and tsc reports a further eight
errors. None of it is reachable from this branch's feature work, but CI cannot
go green while it stands.

Parse errors:
- Tooltip.tsx had two implementations spliced together mid-JSX, with an import
  block dropped into the middle of a return and duplicated className and
  animation props. Reduced to the one complete implementation.
- AdminWidgets.tsx had two whole versions interleaved, each cut into the
  other's hook body and JSX. Rebuilt from the version that survives intact;
  nothing imports the file, so the discarded variant had no callers.
- ContractPlayground.tsx escaped quotes with backslashes inside a JSX
  attribute string, which is not valid JSX.

Type errors:
- SEP24Flow.tsx imported ./Sep24Wizard, a module never committed to the repo.
  Removed the dangling import and its single usage.
- useSocket.ts imports socket.io-client, which no manifest declared. Added it
  to match the backend's socket.io ^4.8.1.
- The two XDR test files use Buffer, so tsconfig now includes the node types.
  That surfaced the SDK's own "type Hash = Opaque[]" workaround disagreeing
  with the Buffers it produces at runtime; cast at the three call sites.
- scvI64 takes an xdr.Int64, and simulateTransaction returns a union that must
  be narrowed before reading "result".
- Sidebar's icon prop declares aria-hidden as a boolean, not a string.

Lint errors: unused imports and never-written state setters across
Sep38QuotePanel and Sidebar.

Sep38QuotePanel.test.tsx could not import while Tooltip.tsx was unparseable.
With it fixed, two of its assertions turn out to be ambiguous - an info
tooltip shares the radio's label, and the countdown renders twice - so they
now target the radio by role and allow the repeated countdown text.

On this branch the repair also covers Breadcrumbs.tsx, which had the same two
interleaved implementations, and index.css, whose light-theme block was nested
inside an unclosed :root.dark rule so PostCSS could not parse the file.

Verified with the CI job's own steps from a clean npm ci: lint clean, build
clean, and the full Vitest suite at 197 passing across 15 files.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Ceejaytech25
Ceejaytech25 merged commit f8cd85f into ceejaylaboratory:main Aug 28, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants