Feature Screens¶
Stadium (src/pages/Stadium.tsx)¶
The main landing screen after sign-in. Shows a grid of FIFA 2026 matches.
- Stores read:
useFlagsStore(feature gates),useAuthStore(user identity). - API calls:
api.getMatches(),api.getInstruments()(for live price data). - User interactions: Select a match card → navigate to
/squad?match=<id>&side=<home|away>. The match ID and side are encoded in the URL so/squadsurvives a page refresh. - The match state (pre-match, live, FT) and trade window countdown are derived from
getTradeWindow()inftl-frontend/src/lib/tradeWindow.ts.
Squad (src/pages/Squad.tsx)¶
Player roster for one side of a match. Shows PlayerCard flip cards with stats.
- Stores read:
useTutorialStore(swaps real roster for sandbox squad during the tour),usePriceStore(live prices per card). - API calls:
api.getSquad(matchId, team),api.getMatchEvents(matchId)(for live event feed). - User interactions:
- Click player card → open
CardFlipModal(stats + chart link + trade button). - Click trade button on card → open
BookPositionModalwithdirection='long'. - The trade window gate (
getTradeWindow) blocks opening positions outside the allowed window. During the tutorial, this gate is bypassed. - URL params
?match=<id>&side=<home|away>are read as a refresh-recovery path whenselectedMatchstate is absent.
YourTeam (src/pages/YourTeam.tsx)¶
Shows the user's open CFD positions with live unrealized P&L.
- Stores read:
useAuthStore(cfdPositions,equity,freeMargin,marginLevel,tradesEpoch),usePriceStore(live prices for P&L recompute),useTutorialStore(sandbox positions during tour). - API calls:
api.listPositions({ status: 'open' })on mount and ontradesEpochchange.api.getTrades()for transaction history viaTransactionHistorycomponent. - User interactions:
- Click close on a position row → open
BookPositionModalwithdirection='short'(pre-filled with the position's instrument). TransactionHistorycomponent shows closed trade history with pagination.
Trade (src/pages/Trade.tsx)¶
Price chart and CFD order entry for a single instrument.
- Components:
PriceChart.tsx(canvas-based OHLC chart),CFDTradeForm.tsx(long/short order form), period tabs ('5m' | '6h' | '1d' | 'all'). - Stores read:
usePriceStore(live price),useAuthStore(freeMargin,marginHydrated). - API calls:
api.getPriceHistory(id, period),api.getInstrument(id),api.getRecentTrades(id). - User interactions: Switch period tab → refetch price history. Submit trade form →
api.openPosition()orapi.closePosition(). - The instrument ID is read from the
?instrument=query parameter on mount. Navigating to/trade?instrument=<id>from CardFlipModal or Squad opens this page for that player.
Ranks (src/pages/Ranks.tsx)¶
Leaderboard with three tabs: global, district, friends.
- Stores read:
useAuthStore(user.districtId,user.id). - API calls:
api.getROIGlobal(),api.getROIDistrict(districtId),api.getROIFriends(),api.getDistrictStandings(),api.getSpinnerCurrent(),api.getSpinnerHistory(),api.getRankContext(). - ROI scoring:
score = ROI% × 100. Tiebreakers in order: total P&L, win-trade count, balance. - A "Matchups" tab shows district vs. district aggregate standings from
api.getDistrictStandings(). - The weekly spinner widget shows the current week's winner or tied candidates.
Profile (src/pages/Profile.tsx)¶
User profile with XP, badges, referral link, and tutorial replay.
- Stores read:
useAuthStore(user,xp,level,referralCode),useTutorialStore(for replay trigger). - API calls:
api.getAchievements(),api.getMyRank(). - User interactions:
- Copy referral link → calls
api.validateReferral()and constructs the share URL. - Invite button → navigates to
/invite. - Replay tutorial → calls
useTutorialStore.getState().start(), which sets theftl-tutorial-activesessionStorage flag and resets all tutorial state.
Admin (src/pages/Admin.tsx)¶
Admin-only panel. Accessible only to users with role === 'admin'.
- API calls:
- Feature flags:
api.adminListFlags(),api.adminSetFlag(key, enabled). - Settings:
api.adminListSettings(),api.adminSetSetting(key, value),api.adminScoringMultiplierKeys(). - Users:
api.adminListUsers(),api.adminUsersExportUrl()(direct CSV download link). - Bot:
api.adminGameplayBotFixtures(),api.adminGameplayBotStatus(),api.adminGameplayBotStart(fixture, speedSec),api.adminGameplayBotStop(). - User interactions:
- Toggle a feature flag →
adminSetFlag()→ flag change takes effect for all users at the next flag refresh (up to 5 min, or instantly on tab focus). - Edit a setting value →
adminSetSetting(). - Download users CSV → navigate to the export URL returned by
adminUsersExportUrl(). - Start / stop gameplay bot → used during development to simulate a live match.