React dashboard and recipient portal for the Fluxora treasury streaming protocol.
- Dashboard — Treasury overview, active streams, and capital flow summary
- Streams — Create and manage USDC streams (rate, duration, cliff)
- Recipient Portal — View incoming streams and withdraw accrued balance
The UI is wired for a future backend API and Stellar wallet integration.
- React 18
- TypeScript
- Vite
- React Router
- Node.js 18+
- npm or pnpm
npm install
npm run devOr with pnpm:
pnpm install
pnpm run devApp runs at http://localhost:5173.
npm run build
npm run previewOr with pnpm:
pnpm run build
pnpm run previewsrc/
components/ # Layout, shared UI
pages/ # Dashboard, Streams, Recipient
App.tsx
main.tsx
index.css
Light/dark theming is owned by a single ThemeProvider (src/theme/ThemeProvider.tsx),
which is the only place that writes the data-theme attribute on <html>.
How a theme is chosen, in order:
- A valid value persisted in
localStorageunder thethemekey (an explicit user choice). - Otherwise, the OS preference via
window.matchMedia("(prefers-color-scheme: dark)").
Behavior:
- No flash (FOUC):
initTheme()is called once insrc/main.tsxto apply the resolved theme to<html>before React renders. - Follows the OS: while the user has not made an explicit choice, the app tracks
prefers-color-schemechanges live. Once the user toggles, their choice wins. - Cross-tab sync: changing the theme in one tab updates all other open tabs via
the
storageevent. - Hardened input: only
"light"and"dark"are accepted. Any tampered or corruptedlocalStorage/storagevalue is ignored, so it can never be written to the DOM (data-theme).
Consume it anywhere under the provider with the useTheme() hook:
import { useTheme } from "./theme/ThemeProvider";
function ThemeToggle() {
const { theme, toggleTheme } = useTheme();
return (
<button onClick={toggleTheme}>
Switch to {theme === "light" ? "dark" : "light"} mode
</button>
);
}useTheme() throws if used outside a ThemeProvider. The provider wraps the app in
src/App.tsx.
Create a .env (or .env.local) when you add API or Stellar config, for example:
VITE_API_URL— Backend API base URLVITE_NETWORK— Stellar network (testnet / mainnet)
- fluxora-backend — API and streaming engine
- fluxora-contracts — Soroban smart contracts
Each is a separate Git repository.