Files
robinhood/UI_REFACTORING_IMPLEMENTATION.md
T
Krikorios 48e60d015f feat: Add Phase 4 advanced metrics and components
- Add advanced metrics dashboard with trade analytics
- Add new trading components (EntryTypeAnalysis, MultiDayPositionTracker, NewsEventTracker, etc.)
- Add strategy mode selector and trend confirmation
- Add risk automation panel and slippage correlation analysis
- Add daily trading plan enhancements with modal components
- Add custom hooks (useApi, useLocalStorage, useAdvancedTradeMetrics)
- Add broker service integration and trading API
- Add test setup and vitest configuration
- Include parquet data files for live market data
- Add comprehensive documentation in docs/ folder
2025-11-27 10:23:58 +02:00

456 lines
15 KiB
Markdown

# UI Refactoring - Implementation Guide
## Overview
This document provides a detailed breakdown of how to refactor the App.tsx from a 3-tab workflow (Prep/Trade/Review + 4 legacy tabs) into a clean 5-view navigation system.
## Current State (App.tsx - 859 lines)
```
App.tsx (Current Problems)
├── Imports (HabitTracker, MLPatternRecognition, DecisionLogPanel - unused in focused flow)
├── Types: MainTab = 'Prep' | 'Trade' | 'Review'
├── Types: LegacyTab = 'AI Coach' | 'ML Patterns' | 'Settings' | 'Prompts'
├── State Management (1 activeTab + 1 legacyTab = scattered focus)
├── renderPrepTab() - lots of panels
├── renderTradeTab() - execution cockpit
├── renderReviewTab() - analytics
└── renderLegacyPanels() - HIDDEN FEATURES (problem!)
```
### Issues with Current Structure
```tsx
// PROBLEM 1: Scattered state
const [activeTab, setActiveTab] = useState<MainTab>('Trade')
const [legacyTab, setLegacyTab] = useState<LegacyTab>('AI Coach') // Two separate navigations!
// PROBLEM 2: Hidden features at bottom
const renderLegacyPanels = () => (
<div className="rounded-3xl border border-slate-800...">
<p className="text-xs uppercase tracking-[0.3em] text-slate-500">Need something familiar?</p>
<h3 className="text-lg font-semibold text-white">Legacy views stay close by</h3>
{/* AI Coach, ML Patterns, Settings, Prompts hidden in tabs */}
</div>
)
// PROBLEM 3: Duplicate component usage
<DailyChecklistPanel /> vs <DailyChecklist /> - which one to use?
<RiskManagement /> alongside <RiskAutomationPanel /> - overlapping concerns
<AnalyticsDashboard /> vs <AdvancedMetricsDashboard /> - two sources of truth
```
## Target State (Proposed App.tsx - ~800 lines)
```
App.tsx (Proposed Solution)
├── Imports (clean, no unused components)
├── Types: MainView = 'dashboard' | 'trade' | 'journal' | 'ai' | 'settings'
├── NavItems configuration with icons and descriptions
├── State Management (single activeView, cleaner)
├── Callbacks (shared across all views)
├── View Functions:
│ ├── renderDashboard() - Market Prep & Overview
│ ├── renderTrade() - Live Execution Cockpit
│ ├── renderJournal() - Post-Trading Analysis
│ ├── renderAI() - AI Coaching & Prompts (consolidated)
│ └── renderSettings() - Configuration & Profile Setup
├── Sticky Navigation Bar (primary UI)
├── Quick Trade Drawer (accessible from all views)
└── renderActiveView() - simple switch statement
```
## Code Transformation Guide
### Step 1: Update Type Definitions
**BEFORE:**
```tsx
type MainTab = 'Prep' | 'Trade' | 'Review'
type LegacyTab = 'AI Coach' | 'ML Patterns' | 'Settings' | 'Prompts'
type WorkflowTabConfig = {
id: MainTab
label: string
description: string
icon: JSX.Element
}
const workflowTabs: WorkflowTabConfig[] = [...]
const legacyTabs: Array<{ id: LegacyTab; label: string; description: string }> = [...]
```
**AFTER:**
```tsx
type MainView = 'dashboard' | 'trade' | 'journal' | 'ai' | 'settings'
interface NavItem {
id: MainView
label: string
icon: JSX.Element
description: string
}
const navItems: NavItem[] = [
{ id: 'dashboard', label: 'Dashboard', icon: <BarChart3 className="w-5 h-5" />, description: 'Market overview & prep' },
{ id: 'trade', label: 'Trade', icon: <Activity className="w-5 h-5" />, description: 'Execute & manage positions' },
{ id: 'journal', label: 'Journal', icon: <CalendarDays className="w-5 h-5" />, description: 'Review & analytics' },
{ id: 'ai', label: 'AI Coach', icon: <Brain className="w-5 h-5" />, description: 'AI insights & coaching' },
{ id: 'settings', label: 'Settings', icon: <Settings className="w-5 h-5" />, description: 'Configure preferences' },
]
```
### Step 2: Simplify State
**BEFORE:**
```tsx
const [activeTab, setActiveTab] = useState<MainTab>('Trade')
const [legacyTab, setLegacyTab] = useState<LegacyTab>('AI Coach')
const [tourActive, setTourActive] = useState(false)
const [tourCounter, setTourCounter] = useState(60)
// ... 30+ more state variables
```
**AFTER:**
```tsx
const [activeView, setActiveView] = useState<MainView>('dashboard')
const [showQuickTrade, setShowQuickTrade] = useState(false)
// ... same number of feature state variables, just cleaner organization
```
### Step 3: Remove Complex Hero/Workflow Display
**BEFORE:**
```tsx
// ~100+ lines of workflowHero with tab progression UI
const workflowHero = (
<div className="bg-slate-900 text-white rounded-3xl border border-slate-800 p-6 space-y-6 shadow-2xl">
<div className="flex flex-wrap items-center gap-3">
<div className="inline-flex items-center gap-2 rounded-full bg-amber-400/20 px-3 py-1 text-amber-200 text-sm font-semibold">
<Sparkles className="w-4 h-4" aria-hidden="true" />
Trader-first workflow
</div>
<button type="button" onClick={() => setTourActive((prev) => !prev)} ...>
{tourActive ? `Guided tour · ${tourCounter}s` : 'Ask Copilot to guide me'}
</button>
</div>
{/* Grid of workflow tabs... */}
</div>
)
// Used in return:
<section className="space-y-6">
{workflowHero}
{renderActiveTab()}
</section>
```
**AFTER:**
```tsx
// Replace with simple, clean navigation in sticky header
<nav className="sticky top-0 z-50 border-b border-slate-800 bg-slate-950/95 backdrop-blur-sm">
<div className="flex items-center justify-between">
<div className="flex items-center gap-4">
{/* Logo */}
<div className="flex items-center gap-2">
<div className="p-1.5 rounded-lg bg-amber-500/20">
<TrendingUp className="w-5 h-5 text-amber-400" />
</div>
<span className="text-lg font-bold text-amber-400">Gold Trading</span>
</div>
{/* Main Navigation */}
<div className="hidden md:flex items-center gap-1 ml-8">
{navItems.map((item) => (
<button
key={item.id}
onClick={() => setActiveView(item.id)}
className={cx(
'flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-all',
activeView === item.id
? 'bg-amber-500/20 text-amber-300'
: 'text-slate-400 hover:text-white hover:bg-slate-800'
)}
>
{item.icon}{item.label}
</button>
))}
</div>
</div>
{/* Right Side - Status & Quick Actions */}
<div className="flex items-center gap-4">
<div className="hidden sm:flex items-center gap-2 px-3 py-1.5 rounded-lg bg-slate-800 border border-slate-700">
<span className="w-2 h-2 rounded-full bg-emerald-400 animate-pulse" />
<span className="text-sm font-medium text-white">{formatUsd(currentPrice)}</span>
</div>
{hasPosition && (
<div className={cx(
'hidden sm:flex items-center gap-2 px-3 py-1.5 rounded-lg',
portfolio.totalPnl >= 0 ? 'bg-emerald-500/10 text-emerald-300' : 'bg-red-500/10 text-red-300'
)}>
<span className="text-sm font-medium">
{portfolio.totalPnl >= 0 ? '+' : ''}{formatUsd(portfolio.totalPnl)}
</span>
</div>
)}
<button
onClick={() => setShowQuickTrade(!showQuickTrade)}
className="flex items-center gap-2 px-4 py-2 rounded-lg bg-amber-500 hover:bg-amber-400 text-slate-900 font-medium transition-colors"
>
<Activity className="w-4 h-4" />
<span className="hidden sm:inline">Quick Trade</span>
</button>
<NotificationCenter />
<div className="text-xs text-slate-500 hidden lg:block">
{backendStatus ? (
<span className="flex items-center gap-1">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-400" />
API Connected
</span>
) : (
<span className="flex items-center gap-1">
<span className="w-1.5 h-1.5 rounded-full bg-amber-400 animate-pulse" />
Connecting...
</span>
)}
</div>
</div>
</div>
</nav>
```
### Step 4: Consolidate View Rendering
**BEFORE:**
```tsx
const renderPrepTab = () => (...) // ~20 lines
const renderTradeTab = () => (...) // ~25 lines
const renderReviewTab = () => (...) // ~40 lines
const renderLegacyPanels = () => (...) // ~45 lines - COMPLEX, HIDDEN
const renderActiveTab = () => {
switch (activeTab) {
case 'Prep': return renderPrepTab()
case 'Trade': return renderTradeTab()
case 'Review': return renderReviewTab()
default: return null
}
}
// In return:
<section className="space-y-6">
{renderActiveTab()}
</section>
{renderLegacyPanels()} {/* Always rendered at bottom! */}
```
**AFTER:**
```tsx
// Dashboard - Morning Prep & Overview
const renderDashboard = () => (
<div className="space-y-6">
{/* Quick Stats Cards */}
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
<QuickStatCard title="Gold Price" value={formatUsd(currentPrice)} ... />
<QuickStatCard title="Portfolio Value" value={formatUsd(portfolio.totalValue)} ... />
<QuickStatCard title="Today's P&L" value={...} ... />
<QuickStatCard title="Available Cash" value={formatUsd(portfolio.cash)} ... />
</div>
{/* Main Content Grid */}
<div className="grid gap-6 xl:grid-cols-3">
<div className="xl:col-span-2 space-y-6">
<LiveMarketPanel />
<div className="grid gap-6 md:grid-cols-2">
<AlertsPanel />
<NewsFeed />
</div>
</div>
<div className="space-y-6">
<DailyChecklistPanel checklistType="morning" />
<DailyMarketSummary currentPrice={currentPrice} />
<DailyTradingPlan
currentPrice={currentPrice}
onPlanUpdate={() => setActiveView('trade')}
advancedTrades={advancedTrades}
advancedTradesSource={advancedTradeSource}
/>
</div>
</div>
</div>
)
// Trade - Live Execution
const renderTrade = () => (
<div className="space-y-6">
<MultiChartSSEPanel />
<div className="grid gap-6 xl:grid-cols-3">
<div className="space-y-6">
<TradeControls {...props} />
<RiskManagement {...props} variant="embedded" />
</div>
<div className="space-y-6">
<PortfolioTracker {...props} />
<AIAnalysisPanel {...props} />
</div>
<div className="space-y-6">
<RiskAutomationPanel {...props} variant="embedded" />
<BrokerBridgePanel {...props} />
</div>
</div>
</div>
)
// Journal - Post-Trading Analysis
const renderJournal = () => (
<div className="space-y-6">
<div className="rounded-2xl border border-slate-800 bg-slate-900/60 p-6">
<div className="flex flex-wrap items-center justify-between gap-4 mb-4">
<div>
<h2 className="text-xl font-semibold text-white">Performance Analytics</h2>
<p className="text-sm text-slate-400">
{advancedTradeSource === 'live'
? `Analyzing ${advancedTrades.length} trades from your session`
: 'Sample data shown until you complete trades'}
</p>
</div>
<span className={cx(
'px-3 py-1 rounded-full text-xs font-medium',
advancedTradeSource === 'live' ? 'bg-emerald-500/20 text-emerald-300' : 'bg-amber-500/20 text-amber-300'
)}>
{advancedTradeSource === 'live' ? 'Live Data' : 'Sample Preview'}
</span>
</div>
<AdvancedMetricsDashboard {...props} />
</div>
<div className="grid gap-6 xl:grid-cols-2">
<div className="space-y-6">
<TradingJournal />
<EquityPerformancePanel />
</div>
<div className="space-y-6">
<AnalyticsDashboard />
</div>
</div>
</div>
)
// AI Coach - Consolidated AI Features
const renderAI = () => (
<div className="space-y-6">
<div className="rounded-2xl border border-slate-800 bg-gradient-to-br from-slate-900 to-slate-950 p-6">
<div className="flex items-center gap-3 mb-4">
<div className="p-2 rounded-xl bg-purple-500/20">
<Brain className="w-6 h-6 text-purple-400" />
</div>
<div>
<h2 className="text-xl font-semibold text-white">AI Trading Coach</h2>
<p className="text-sm text-slate-400">Get personalized coaching and insights</p>
</div>
</div>
<AITradingCoach />
</div>
<div className="grid gap-6 md:grid-cols-2">
<div className="space-y-4">
<h3 className="text-lg font-semibold text-white">Quick Analysis</h3>
<AIAnalysisPanel analysis={aiAnalysis} isLoading={isAnalyzing} title="Market Analysis" />
<button onClick={handleRunAnalysis} disabled={isAnalyzing} className="...">
Run AI Analysis
</button>
</div>
<div className="space-y-4">
<h3 className="text-lg font-semibold text-white">Prompt Templates</h3>
<PromptTemplatesPanel />
</div>
</div>
</div>
)
// Settings - Configuration
const renderSettings = () => (
<div className="space-y-6">
<div className="rounded-2xl border border-slate-800 bg-slate-900/60 p-6">
<div className="flex items-center gap-3 mb-6">
<div className="p-2 rounded-xl bg-slate-700">
<Settings className="w-6 h-6 text-slate-300" />
</div>
<div>
<h2 className="text-xl font-semibold text-white">Settings</h2>
<p className="text-sm text-slate-400">Configure your trading preferences</p>
</div>
</div>
<SettingsPanel />
</div>
<button onClick={() => setShowProfileSetup(true)} className="...">
Trading Profile Setup
</button>
</div>
)
const renderActiveView = () => {
switch (activeView) {
case 'dashboard': return renderDashboard()
case 'trade': return renderTrade()
case 'journal': return renderJournal()
case 'ai': return renderAI()
case 'settings': return renderSettings()
default: return null
}
}
```
## Components to Remove from Imports
These are currently imported but can be removed or reorganized:
```tsx
// REMOVE (used in legacy panels, consolidated elsewhere):
import HabitTracker from './components/HabitTracker'
import DecisionLogPanel from './components/DecisionLogPanel'
import MLPatternRecognition from './components/MLPatternRecognition'
// KEEP (still used, just organized differently):
import AITradingCoach from './components/AITradingCoach'
import PromptTemplatesPanel from './components/PromptTemplatesPanel'
import SettingsPanel from './components/SettingsPanel'
```
## Files Modified
- **App.tsx**: Main refactoring (~60 lines removed, ~200 lines reorganized)
- **package.json**: No changes needed
- **Component files**: No changes (they stay the same, just reused in different places)
## Testing Checklist
- [ ] All 5 navigation items clickable and visible
- [ ] State persists when navigating between views
- [ ] Dashboard shows correct stats and components
- [ ] Trade view has all execution tools
- [ ] Journal shows analytics
- [ ] AI Coach displays training features
- [ ] Settings allows configuration
- [ ] Quick Trade button works from navbar
- [ ] Mobile responsive (collapsed nav)
- [ ] Sticky header position correct
- [ ] Price ticker updates live
- [ ] P&L badge shows/hides correctly
- [ ] API status indicator works
- [ ] Profile setup modal opens
- [ ] All callbacks work (buy/sell/reset/analyze)
## Result
**Before**: Confusing workflow with hidden features
**After**: Clean, organized, trader-friendly interface
Lines removed: ~150 (complex hero, legacy panels)
Lines added: ~80 (cleaner layouts)
Net change: -70 lines with MORE features visible and organized