Frontend
🎯 PRTL (Trader Portal)

PRTL - Internal Trader Portal

URL: prtl.altsportsleagues.ai Purpose: Internal trading tools for ASD staff to manage odds, markets, and live trading operations.

Overview

PRTL (Portal) is the internal-facing trading platform where AltSportsData traders create, manage, and approve betting markets before they're published to external sportsbook operators.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         PRTL Architecture                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                   β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚   β”‚   Sidebar   β”‚    β”‚ Event Tree  β”‚    β”‚   Main      β”‚         β”‚
β”‚   β”‚ Navigation  β”‚    β”‚  Sidebar    β”‚    β”‚  Content    β”‚         β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚                                                                   β”‚
β”‚   Trader Context Bar: Name | Role | Email | Phone                β”‚
β”‚                                                                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

User Roles

RoleAccess LevelCapabilities
TraderFullCreate/edit odds, manage markets, suspend/resume
Risk ManagerReviewApprove high-exposure markets, set limits
Data ScientistRead + AnalyticsMonitor ML models, analyze performance
AdminFull + SettingsUser management, system configuration

Key Features

1. Trading Layout

The main trading interface uses a three-column layout:

  • Left Sidebar: Primary navigation (sports, leagues, settings)
  • Event Tree Sidebar: Hierarchical event/fight navigation with expand/collapse
  • Main Content: Market details, odds tables, and controls
// TradingLayout component structure
<TradingLayout title="UFC 305" subtitle="November 25, 2024" showEventTree>
  <EventDetailPage />
</TradingLayout>

2. Event Tree Navigation

The EventTreeSidebar provides hierarchical navigation:

β–Ό MMA
  β–Ό UFC
    ● UFC 305 (Live)
    β—‹ UFC 306 (Upcoming)
  β–Ό BKB Extreme Fighting
    β—‹ BKB 48 Brawl in the Pines V
β–Ό Motorsports
  β–Ό Formula 1
    ● Monaco Grand Prix (Live)

Features:

  • Collapsible sport/league sections
  • Live event indicators (pulsing dot)
  • Active event highlighting
  • One-click navigation to event details

3. Trader Context Bar

The header displays trader information for accountability:

interface TraderInfo {
  name: string;      // "John Smith"
  role: string;      // "Senior Trader"
  email: string;     // "john.smith@altsportsdata.com"
  phone?: string;    // "+1 (555) 123-4567"
  avatar?: string;
}

4. Fight Cards with Edit Controls

Fight cards display matchup information with inline editing:

<FightCard
  fight={fight}
  isSelected={selectedFightId === fight.id}
  onClick={() => setSelectedFightId(fight.id)}
  onEdit={() => openEditModal(fight)}
/>

Elements:

  • Blue/Red corner indicators
  • Fighter names, nicknames, records
  • Weight class badge
  • Status indicator (scheduled/live/completed)
  • Edit button for traders

5. Odds Table

The OddsTable component provides a full editing interface:

Blue CornerBlue OddsBiasRed OddsRed CornerMarket Status
Max Holloway-150 ↑[-] [0] [+]+130 ↓Alexander VolkanovskiOpen

Features:

  • American odds display (positive/negative)
  • Movement indicators (↑ green / ↓ red)
  • Bias adjustment steppers (-5 to +5)
  • Market status toggles (Open/Suspended/Closed)
  • Real-time update highlighting

6. Market Activation Panel

Tree-based market activation with toggle controls:

β–Ό Main Card Markets
  β˜‘ Fight 1: Holloway vs Volkanovski (Moneyline)
  β˜‘ Fight 1: Method of Victory
  ☐ Fight 1: Round Totals (Draft)
β–Ό Preliminary Card Markets
  β˜‘ Fight 5: Jones vs Martinez

7. Odds Footer (Hold/Margin Display)

Shows calculated hold percentage and implied probabilities:

Hold: 4.76% | Blue: 48.5% | Red: 43.5% | Margin: +8.0%

Component Reference

Layout Components

ComponentLocationPurpose
TradingLayoutcomponents/layout/trading-layout.tsxMain page wrapper with sidebar
Headercomponents/layout/header.tsxTop bar with trader context
Sidebarcomponents/layout/sidebar.tsxPrimary navigation
EventTreeSidebarcomponents/layout/event-tree-sidebar.tsxEvent hierarchy nav

UI Components

ComponentLocationPurpose
FightCardcomponents/ui/fight-card.tsxMatchup display with edit
OddsTablecomponents/ui/odds-table.tsxFull odds editing table
OddsFootercomponents/ui/odds-footer.tsxHold/margin display
NumberSteppercomponents/ui/number-stepper.tsxBias adjustment control
CornerIndicatorcomponents/ui/corner-indicator.tsxBlue/Red dot indicator
StatusBadgecomponents/ui/status-badge.tsxMarket status pills
MarketActivationPanelcomponents/ui/market-activation-panel.tsxMarket toggle tree

Types

// src/types/event.ts
 
type Sport = 'mma' | 'jai_alai' | 'f1' | 'esports' | 'drone_racing' | 'arm_wrestling' | 'combat';
type EventStatus = 'live' | 'upcoming' | 'scheduled' | 'completed' | 'cancelled';
type FightStatus = 'scheduled' | 'live' | 'completed' | 'cancelled' | 'postponed';
type MarketStatus = 'draft' | 'pending_review' | 'approved' | 'published' | 'suspended' | 'closed' | 'settled';
type WeightClass = 'flyweight' | 'bantamweight' | 'featherweight' | 'lightweight' | 'welterweight' | 'middleweight' | 'light_heavyweight' | 'heavyweight';
 
interface Fighter {
  id: string;
  name: string;
  nickname?: string;
  record?: string;
  country?: string;
}
 
interface Fight {
  id: string;
  event_id: string;
  fight_number: number;
  weight_class: WeightClass;
  scheduled_rounds: number;
  status: FightStatus;
  blue_corner?: Fighter;
  red_corner?: Fighter;
  result?: FightResult;
}
 
interface OddsMarket {
  id: string;
  type: string;
  name: string;
  status: 'open' | 'suspended' | 'closed';
  selections: OddsSelection[];
  last_updated: string;
}
 
interface OddsSelection {
  id: string;
  name: string;
  odds: number;
  implied_probability: number;
  movement?: 'up' | 'down' | 'none';
}

Sport-Specific Components

PRTL implements specialized event cards for each sport category, automatically selecting the appropriate UI based on sport type.

Sport Categories

CategorySportsKey UI Elements
CombatMMA, Boxing, Slap Fighting, Arm WrestlingBlue/Red corners, weight class, rounds, method of victory
RacquetJai Alai, Tennis, BadmintonSets, games, player pairs, lean controls
MotorsportF1, NASCAR, MotoGP, NHRASessions (practice/qualifying/race), positions, lap times
ExtremeBull Riding, Surfing, SkateboardingHeats, scores, advancing competitors
EsportsLeague of Legends, CS:GO, ValorantBest-of series, game maps, pick/ban phases

Universal Event Renderer

The SportEventRenderer automatically selects the appropriate component:

import { SportEventRenderer, type UniversalEvent } from '@/components/sports';
 
// Automatically renders correct component based on sport type
<SportEventRenderer
  event={{ sport: 'mma', data: fightData }}
  isSelected={isSelected}
  onSelect={handleSelect}
  showOdds={true}
  variant="full" // or "compact" for sidebar lists
/>

Combat Event Card

For combat sports (MMA, Boxing, Slap Fighting):

import { CombatEventCard } from '@/components/sports';
 
<CombatEventCard
  fight={fight}
  isSelected={isSelected}
  onSelect={handleSelect}
  showOdds={true}
  blueOdds={-150}
  redOdds={+130}
  onEdit={() => openEditModal(fight)}
/>

Features:

  • Blue/red corner indicators
  • Fighter name, nickname, record display
  • Weight class badge
  • Rounds and scheduled time
  • Result badge (KO/TKO/SUB/DEC)
  • Edit button for traders

Racquet Match Card (Jai Alai)

For set-based sports with player pairs:

import { RacquetMatchCard } from '@/components/sports';
 
<RacquetMatchCard
  match={match}
  isSelected={isSelected}
  onSelect={handleSelect}
  showLean={true}
  onLeanChange={(playerId, lean) => updateLean(playerId, lean)}
/>

Features:

  • Set-by-set scoring table
  • Player/team names
  • Score indicators with winner highlighting
  • Lean adjustment controls (-10 to +10)
  • Match navigation tabs

Motorsport Event Card

For racing events with sessions:

import { MotorsportEventCard, MotorsportResultsTable } from '@/components/sports';
 
<MotorsportEventCard
  event={raceEvent}
  isSelected={isSelected}
  onSelect={handleSelect}
/>
 
// Results table for completed sessions
<MotorsportResultsTable
  results={qualifyingResults}
  showTeam={true}
  showTime={true}
  showPoints={true}
/>

Features:

  • Circuit and country display
  • Session list (Practice, Qualifying, Race)
  • Live session indicators
  • Results table with positions
  • Driver matchup comparisons
  • Gold/Silver/Bronze podium styling

Extreme Event Card

For action sports with heats and scores:

import { ExtremeEventCard, HeatCard } from '@/components/sports';
 
<ExtremeEventCard
  event={extremeEvent}
  isSelected={isSelected}
  onSelect={handleSelect}
  showLean={true}
/>
 
// For surfing/action sports heats
<HeatCard
  heat={heat}
  isSelected={isSelected}
  onSelect={handleSelect}
/>

Features:

  • Competitor list with scores
  • Round/heat indicators
  • Score components breakdown
  • Advancing competitor highlighting
  • Bull riding: ride time, buck-off indicator

Esports Match Card

For competitive gaming matches:

import { EsportsMatchCard, GameTabs } from '@/components/sports';
 
<EsportsMatchCard
  match={esportsMatch}
  isSelected={isSelected}
  onSelect={handleSelect}
  team1Odds={-120}
  team2Odds={+100}
/>
 
// Game-by-game navigation
<GameTabs
  games={match.games}
  activeGameNumber={currentGame}
  onSelectGame={setCurrentGame}
  bestOf={5}
/>

Features:

  • Team logos/initials with colors
  • Best-of series progress dots
  • Game-by-game results
  • Live game indicator
  • Map veto display
  • Duration tracking

Sport Filter Tabs

For filtering events by sport:

import { SportFilterTabs } from '@/components/sports';
 
<SportFilterTabs
  sports={['mma', 'jai_alai', 'f1', 'bull_riding']}
  activeSport={currentSport}
  onSelectSport={setCurrentSport}
  showCounts={true}
  eventCounts={{ mma: 12, jai_alai: 8, f1: 3, bull_riding: 5 }}
/>

Sport Event List

For grouped event display:

import { SportEventList } from '@/components/sports';
 
<SportEventList
  events={allEvents}
  selectedEventId={selectedId}
  onSelectEvent={handleSelectEvent}
  groupBySport={true}
  variant="full" // or "compact"
/>

Design Patterns

Blue/Red Corner Convention

Combat sports consistently use blue/red corners:

// Corner colors (Tailwind)
const cornerColors = {
  blue: 'bg-blue-500',
  red: 'bg-red-500'
};
 
// Corner indicator usage
<span className="w-3 h-3 rounded-full bg-blue-500" /> // Blue corner
<span className="w-3 h-3 rounded-full bg-red-500" />  // Red corner

Odds Format Display

American odds formatting:

function formatOdds(odds: number): string {
  if (odds >= 0) return `+${odds}`;
  return odds.toString();
}
 
// Display: +150 (underdog) or -200 (favorite)

Status Badge Colors

StatusBackgroundText
Livebg-green-500/10text-green-600
Upcomingbg-blue-500/10text-blue-400
Suspendedbg-yellow-500/10text-yellow-600
Closedbg-gray-500/10text-gray-400

API Integration

PRTL connects to the backend API for all operations:

// Market lifecycle operations
POST /v1/prtl/markets                    // Create market
PUT  /v1/prtl/markets/{id}/odds/{lineId} // Update odds
POST /v1/prtl/markets/{id}/suspend       // Suspend market
POST /v1/prtl/markets/{id}/publish       // Publish to clients
POST /v1/prtl/markets/{id}/settle        // Settle with result

Security

  • Internal SSO authentication required
  • Role-based access control
  • 2FA enforcement for traders
  • IP whitelist/VPN restriction
  • Full audit logging of all actions
  • Session timeout after 30 minutes

Related Documentation

Platform

Documentation

Community

Support

partnership@altsportsdata.comdev@altsportsleagues.ai

2025 Β© AltSportsLeagues.ai. Powered by AI-driven sports business intelligence.

πŸ€– AI-Enhancedβ€’πŸ“Š Data-Drivenβ€’βš‘ Real-Time