Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 107 additions & 107 deletions apps/dashboard/src/routeTree.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,83 +9,83 @@
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.

import { Route as rootRouteImport } from './routes/__root'
import { Route as LoginRouteImport } from './routes/login'
import { Route as AppRouteImport } from './routes/_app'
import { Route as IndexRouteImport } from './routes/index'
import { Route as MoneriumCallbackRouteImport } from './routes/monerium.callback'
import { Route as InviteTokenRouteImport } from './routes/invite.$token'
import { Route as AppTransferRouteImport } from './routes/_app/transfer'
import { Route as AppTransactionsRouteImport } from './routes/_app/transactions'
import { Route as AppSettingsRouteImport } from './routes/_app/settings'
import { Route as AppRecipientsRouteImport } from './routes/_app/recipients'
import { Route as AppQuoteRouteImport } from './routes/_app/quote'
import { Route as AppOverviewRouteImport } from './routes/_app/overview'
import { Route as AppLimitsRouteImport } from './routes/_app/limits'
import { Route as AppRouteImport } from './routes/_app'
import { Route as LoginRouteImport } from './routes/login'
import { Route as AppApiKeysRouteImport } from './routes/_app/api-keys'
import { Route as AppLimitsRouteImport } from './routes/_app/limits'
import { Route as AppOverviewRouteImport } from './routes/_app/overview'
import { Route as AppQuoteRouteImport } from './routes/_app/quote'
import { Route as AppRecipientsRouteImport } from './routes/_app/recipients'
import { Route as AppSettingsRouteImport } from './routes/_app/settings'
import { Route as AppTransactionsRouteImport } from './routes/_app/transactions'
import { Route as AppTransferRouteImport } from './routes/_app/transfer'
import { Route as InviteTokenRouteImport } from './routes/invite.$token'
import { Route as MoneriumCallbackRouteImport } from './routes/monerium.callback'

const LoginRoute = LoginRouteImport.update({
id: '/login',
path: '/login',
getParentRoute: () => rootRouteImport,
} as any)
const AppRoute = AppRouteImport.update({
id: '/_app',
getParentRoute: () => rootRouteImport,
} as any)
const IndexRoute = IndexRouteImport.update({
id: '/',
path: '/',
getParentRoute: () => rootRouteImport,
} as any)
const MoneriumCallbackRoute = MoneriumCallbackRouteImport.update({
id: '/monerium/callback',
path: '/monerium/callback',
const AppRoute = AppRouteImport.update({
id: '/_app',
getParentRoute: () => rootRouteImport,
} as any)
const InviteTokenRoute = InviteTokenRouteImport.update({
id: '/invite/$token',
path: '/invite/$token',
const LoginRoute = LoginRouteImport.update({
id: '/login',
path: '/login',
getParentRoute: () => rootRouteImport,
} as any)
const AppTransferRoute = AppTransferRouteImport.update({
id: '/transfer',
path: '/transfer',
const AppApiKeysRoute = AppApiKeysRouteImport.update({
id: '/api-keys',
path: '/api-keys',
getParentRoute: () => AppRoute,
} as any)
const AppTransactionsRoute = AppTransactionsRouteImport.update({
id: '/transactions',
path: '/transactions',
const AppLimitsRoute = AppLimitsRouteImport.update({
id: '/limits',
path: '/limits',
getParentRoute: () => AppRoute,
} as any)
const AppSettingsRoute = AppSettingsRouteImport.update({
id: '/settings',
path: '/settings',
const AppOverviewRoute = AppOverviewRouteImport.update({
id: '/overview',
path: '/overview',
getParentRoute: () => AppRoute,
} as any)
const AppQuoteRoute = AppQuoteRouteImport.update({
id: '/quote',
path: '/quote',
getParentRoute: () => AppRoute,
} as any)
const AppRecipientsRoute = AppRecipientsRouteImport.update({
id: '/recipients',
path: '/recipients',
getParentRoute: () => AppRoute,
} as any)
const AppQuoteRoute = AppQuoteRouteImport.update({
id: '/quote',
path: '/quote',
const AppSettingsRoute = AppSettingsRouteImport.update({
id: '/settings',
path: '/settings',
getParentRoute: () => AppRoute,
} as any)
const AppOverviewRoute = AppOverviewRouteImport.update({
id: '/overview',
path: '/overview',
const AppTransactionsRoute = AppTransactionsRouteImport.update({
id: '/transactions',
path: '/transactions',
getParentRoute: () => AppRoute,
} as any)
const AppLimitsRoute = AppLimitsRouteImport.update({
id: '/limits',
path: '/limits',
const AppTransferRoute = AppTransferRouteImport.update({
id: '/transfer',
path: '/transfer',
getParentRoute: () => AppRoute,
} as any)
const AppApiKeysRoute = AppApiKeysRouteImport.update({
id: '/api-keys',
path: '/api-keys',
getParentRoute: () => AppRoute,
const InviteTokenRoute = InviteTokenRouteImport.update({
id: '/invite/$token',
path: '/invite/$token',
getParentRoute: () => rootRouteImport,
} as any)
const MoneriumCallbackRoute = MoneriumCallbackRouteImport.update({
id: '/monerium/callback',
path: '/monerium/callback',
getParentRoute: () => rootRouteImport,
} as any)

export interface FileRoutesByFullPath {
Expand Down Expand Up @@ -188,11 +188,11 @@ export interface RootRouteChildren {

declare module '@tanstack/react-router' {
interface FileRoutesByPath {
'/login': {
id: '/login'
path: '/login'
fullPath: '/login'
preLoaderRoute: typeof LoginRouteImport
'/': {
id: '/'
path: '/'
fullPath: '/'
preLoaderRoute: typeof IndexRouteImport
parentRoute: typeof rootRouteImport
}
'/_app': {
Expand All @@ -202,46 +202,39 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof AppRouteImport
parentRoute: typeof rootRouteImport
}
'/': {
id: '/'
path: '/'
fullPath: '/'
preLoaderRoute: typeof IndexRouteImport
parentRoute: typeof rootRouteImport
}
'/monerium/callback': {
id: '/monerium/callback'
path: '/monerium/callback'
fullPath: '/monerium/callback'
preLoaderRoute: typeof MoneriumCallbackRouteImport
'/login': {
id: '/login'
path: '/login'
fullPath: '/login'
preLoaderRoute: typeof LoginRouteImport
parentRoute: typeof rootRouteImport
}
'/invite/$token': {
id: '/invite/$token'
path: '/invite/$token'
fullPath: '/invite/$token'
preLoaderRoute: typeof InviteTokenRouteImport
parentRoute: typeof rootRouteImport
'/_app/api-keys': {
id: '/_app/api-keys'
path: '/api-keys'
fullPath: '/api-keys'
preLoaderRoute: typeof AppApiKeysRouteImport
parentRoute: typeof AppRoute
}
'/_app/transfer': {
id: '/_app/transfer'
path: '/transfer'
fullPath: '/transfer'
preLoaderRoute: typeof AppTransferRouteImport
'/_app/limits': {
id: '/_app/limits'
path: '/limits'
fullPath: '/limits'
preLoaderRoute: typeof AppLimitsRouteImport
parentRoute: typeof AppRoute
}
'/_app/transactions': {
id: '/_app/transactions'
path: '/transactions'
fullPath: '/transactions'
preLoaderRoute: typeof AppTransactionsRouteImport
'/_app/overview': {
id: '/_app/overview'
path: '/overview'
fullPath: '/overview'
preLoaderRoute: typeof AppOverviewRouteImport
parentRoute: typeof AppRoute
}
'/_app/settings': {
id: '/_app/settings'
path: '/settings'
fullPath: '/settings'
preLoaderRoute: typeof AppSettingsRouteImport
'/_app/quote': {
id: '/_app/quote'
path: '/quote'
fullPath: '/quote'
preLoaderRoute: typeof AppQuoteRouteImport
parentRoute: typeof AppRoute
}
'/_app/recipients': {
Expand All @@ -251,33 +244,40 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof AppRecipientsRouteImport
parentRoute: typeof AppRoute
}
'/_app/quote': {
id: '/_app/quote'
path: '/quote'
fullPath: '/quote'
preLoaderRoute: typeof AppQuoteRouteImport
'/_app/settings': {
id: '/_app/settings'
path: '/settings'
fullPath: '/settings'
preLoaderRoute: typeof AppSettingsRouteImport
parentRoute: typeof AppRoute
}
'/_app/overview': {
id: '/_app/overview'
path: '/overview'
fullPath: '/overview'
preLoaderRoute: typeof AppOverviewRouteImport
'/_app/transactions': {
id: '/_app/transactions'
path: '/transactions'
fullPath: '/transactions'
preLoaderRoute: typeof AppTransactionsRouteImport
parentRoute: typeof AppRoute
}
'/_app/limits': {
id: '/_app/limits'
path: '/limits'
fullPath: '/limits'
preLoaderRoute: typeof AppLimitsRouteImport
'/_app/transfer': {
id: '/_app/transfer'
path: '/transfer'
fullPath: '/transfer'
preLoaderRoute: typeof AppTransferRouteImport
parentRoute: typeof AppRoute
}
'/_app/api-keys': {
id: '/_app/api-keys'
path: '/api-keys'
fullPath: '/api-keys'
preLoaderRoute: typeof AppApiKeysRouteImport
parentRoute: typeof AppRoute
'/invite/$token': {
id: '/invite/$token'
path: '/invite/$token'
fullPath: '/invite/$token'
preLoaderRoute: typeof InviteTokenRouteImport
parentRoute: typeof rootRouteImport
}
'/monerium/callback': {
id: '/monerium/callback'
path: '/monerium/callback'
fullPath: '/monerium/callback'
preLoaderRoute: typeof MoneriumCallbackRouteImport
parentRoute: typeof rootRouteImport
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions apps/frontend/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ frontend-scoped architecture, conventions, and commands. Run commands from
- **Forms**: React Hook Form with Zod validation (not Yup).
- **Data fetching**: TanStack Query.
- **Routing**: TanStack Router — route tree auto-generated in `src/routeTree.gen.ts` (do not hand-edit).
- **Rendering**: TanStack Start. Marketing routes are prerendered to static HTML at build time
(`dist/client`); `/widget` sets `ssr: false` and is served from the `_shell.html` SPA shell.
- **State machines**: XState machines in `src/machines/` for complex flows (KYC, ramp process).
- **Wallets**: Wagmi/AppKit (EVM) + Talisman (Polkadot).

Expand All @@ -21,6 +23,17 @@ frontend-scoped architecture, conventions, and commands. Run commands from
- Extract complex conditional rendering into new components.
- Skip useless comments; only comment race conditions, TODOs, or genuinely confusing code.

### Server-safe code (marketing routes)

Anything rendered by a marketing route is prerendered in a DOM-less environment, so:

- `useSyncExternalStore` must be given a server snapshot (third argument).
- Probe browser globals with `typeof` — `localStorage` is *undeclared* on the server, so
`!localStorage` and `localStorage?.x` both throw a `ReferenceError`.
- Size from CSS, not from a measured viewport, or the layout shifts on hydration.

`src/tests/ssr-safety.test.tsx` guards these; keep it in the default `node` environment.

### XState v5

- Use `setup({ ... }).createMachine(...)` — not `createMachine` directly.
Expand Down
25 changes: 10 additions & 15 deletions apps/frontend/_redirects
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,16 @@
/api/staging/* https://api-staging.vortexfinance.co/:splat 200
/api/sandbox/* https://api-sandbox.vortexfinance.co/:splat 200

# Known app routes — serve SPA shell with real 200
/ /index.html 200
/business /index.html 200
/payments /index.html 200
/contact /index.html 200
/privacy-policy /index.html 200
/terms-and-conditions /index.html 200
/terms-and-conditions-full /index.html 200
/widget /index.html 200
/en /index.html 200
/en/* /index.html 200
/pt-BR /index.html 200
/pt-BR/* /index.html 200
/pt-br /index.html 200
/pt-br/* /index.html 200
# The marketing routes are prerendered to static HTML (`/business/index.html`, `/pt-BR/...`),
# and Netlify serves those files before applying any non-forced rule below.

# The widget opts out of SSR, so it renders from the prerendered SPA shell.
/widget /_shell.html 200
/en/widget /_shell.html 200
/pt-BR/widget /_shell.html 200

# Support the lowercase widget alias without turning unknown localized paths into soft 404s.
/pt-br/widget /_shell.html 200

# Everything else is a real 404
/* /404.html 404
Expand Down
51 changes: 0 additions & 51 deletions apps/frontend/index.html

This file was deleted.

Loading
Loading