RemitFlow is a cross-border remittance app powered by the Stellar network. This repository contains the React + Vite frontend.
npm install
npm run devThe app runs at http://localhost:5173 by default.
- Home — landing page describing the product.
- Send Money — enter a recipient and amount, pick currencies, and see a live FX quote with the RemitFlow fee broken out before sending.
- Transfers — list of your transfers with status badges (pending, completed, failed), search/status/date-range filters synced to the URL, plus loading, error and empty states.
- Tabs — reusable tabbed interface with swipe gesture support for mobile, accessible keyboard navigation, and controlled/uncontrolled modes.
- Print support — a dedicated print stylesheet (
src/print.css) optimises the Transfers dashboard and other pages for printing: hides navigation chrome, interactive elements, and applies a light background with readable text and preserved chart/status colours. - Dark mode toggle — switch between Dark and Light visual themes with session persistence saved in
localStorageunderremitflow:theme. - Mock wallet — connect a demo Stellar wallet (no network calls).
- Robust error handling for rejected connections
- Connection timeout protection (30 seconds)
- Clear error feedback to users
- Automatic error state clearing on retry or disconnect
- React 18 + Vite
- React Router for navigation
- Plain CSS with theme tokens (no UI framework)
- A mock Stellar SDK / wallet and a mock backend API (no network)
src/
components/ reusable UI (Navbar, Sidebar, Footer, QuoteCard, TransferRow, ...)
pages/ route screens (Home, SendMoney, Transfers, NotFound)
services/ mock api, wallet, fx and quote logic
hooks/ useWallet, useTransfers
context/ AppContext (wallet state)
utils/ format and validation helpers
constants/ currencies and fee config
Copy .env.example to .env to override the (unused in mock mode) API base URL:
cp .env.example .envnpm run dev— start the dev servernpm run build— production buildnpm run preview— preview the production buildnpm test— run the automated Vitest suitenpm run test:watch— watch mode for local test developmentnpm run format— format all source files with Prettiernpm run format:check— check formatting without modifying files (CI)npm run lighthouse— run Lighthouse CI against the local preview server
The app adapts seamlessly across screen viewports:
| Range | Target | Layout |
|---|---|---|
| >1024px | Desktop | Full sidebar (240px), 3-column features grid |
| 721–1024px | Tablet landscape | Full sidebar with toggle, 2-column features grid, compact content padding |
| ≤720px | Tablet portrait / mobile | Collapsed sidebar (60px), 2-column stacked transfer rows, vertical filter controls, horizontal chart scroll wrapper |
| ≤480px | Small mobile | Single-column transfer rows, full-width filter controls, stacked hero actions |
The Sidebar is rendered alongside the main content area on all viewports wider than 720px and collapses automatically at narrower widths. All dashboard filters and controls adhere to touch target guidelines.
The test suite includes comprehensive coverage of wallet connection handling:
-
Wallet Service Tests (
test/services/wallet.test.js)- Successful connection flow
- User rejection handling
- Storage persistence
- Disconnection cleanup
-
AppContext Wallet Tests (
test/unit/AppContext.wallet.test.jsx)- Connection state management
- Error handling and recovery
- Timeout protection
- State restoration from localStorage
-
WalletButton Tests (
test/components/WalletButton.test.jsx)- UI feedback for connection states
- Error message display
- Retry behavior
- User interaction flows
Integration tests cover send-money validation, successful transfer submission, pending button behavior, duplicate-submission prevention, Transfers page filter sync (search, status, and date-range presets such as last 7/30/90 days), and landscape tablet layout integration.
All interactive elements (buttons, links, inputs, selects, icon buttons, and
checkboxes) meet a minimum touch target of 44×44 CSS pixels, compliant with
WCAG 2.5.5 (Target Size). A dedicated test suite in test/touch-targets.test.js
audits the CSS declarations to ensure compliance isn't regressed.
Form components (TextField, CurrencySelect, SendMoney) follow WCAG accessibility best practices for error announcements:
- ARIA invalid states: Inputs set
aria-invalid="true"when validation fails andaria-invalid="false"when valid. - Accessible descriptions: Input controls link to error message elements using
aria-describedby. - Live region alerts: Error messages render with
role="alert",aria-live="assertive", andaria-atomic="true"so screen readers immediately announce validation feedback. - Form submission failure feedback: When form submission fails validation, an assertive live region summary announces the errors, and keyboard focus automatically shifts to the first invalid field.
The Tabs component supports both controlled and uncontrolled modes:
<Tabs
tabs={[
{ label: 'Send', content: <SendForm /> },
{ label: 'History', content: <TransferHistory /> },
]}
activeIndex={0} // omit for uncontrolled
onChange={(i) => {}} // called on tab switch
/>- Swipe gestures: On touch devices, swipe left/right to switch between tabs (50px threshold).
- Accessibility: Uses ARIA
tablist,tab, andtabpanelroles with properaria-selected,aria-controls, andaria-labelledbyrelationships. - Keyboard: Active tab is focusable via
tabIndex. Tab headers are<button>elements.
The app supports notched and rounded-screen devices (e.g. iPhone X+,
Android flagships) via CSS env(safe-area-inset-*):
- CSS custom properties are defined in
src/index.css(--safe-area-inset-top,--safe-area-inset-bottom,--safe-area-inset-left,--safe-area-inset-right) with a0pxfallback. - The
<meta name="viewport">tag already includesviewport-fit=cover. - Layout components (
Navbar,Footer,Sidebar,Modal) consume the custom properties to keep content clear of notches, rounded corners and the home indicator. - The
useSafeAreaInsetshook (insrc/hooks/useSafeAreaInsets.js) exposes the numeric pixel values for any component that needs them in JavaScript.
Lighthouse checks are configured in lighthouserc.json and run in GitHub Actions on pull requests to the main branch. To validate locally, build the app and run:
npm run build
npm run lighthouseWe welcome contributions! Please see CONTRIBUTING.md for:
- Development workflow and coding standards
- Pull request process
- Testing requirements
- Issue reporting guidelines
For issue tracking and triage process, see .github/ISSUE_TRIAGE.md.
This is a demo frontend. All FX rates, fees, wallet connections and transfers are mocked locally and do not touch the real Stellar network.