feat: cream terminal redesign, English-only UI, autopilot launch fixes

- Redesign dashboard into a cream-paper + vermilion IBM Plex Mono terminal
  (live L2 order book, cost/liq map, WS K-line, signal matrix, orchestration
  topology, risk radar, execution log, current positions, equity curve)
- Convert all user-facing UI and backend strings/prompts from Chinese to
  English (multi-language retained, default English)
- Add /api/statistics/full endpoint + full-stats frontend wiring
- Fix Autopilot launch: reuse the existing trader instead of creating
  duplicates (eliminates repeat ~35s create cost and stale-trader 404s);
  launch sends 5m scan interval
- Fix unreadable toasts: cream theme with high-contrast text + per-type accent
- Silence background dashboard polls (getTraderConfig) to stop error-toast spam
This commit is contained in:
tinkle-community
2026-06-30 16:03:52 +08:00
parent eba28bcf0e
commit 110bf52908
149 changed files with 6835 additions and 3611 deletions

View File

@@ -25,7 +25,7 @@ import { BeginnerOnboardingPage } from '../pages/BeginnerOnboardingPage'
import { DataPage } from '../pages/DataPage'
import { SettingsPage } from '../pages/SettingsPage'
import { StrategyStudioPage } from '../pages/StrategyStudioPage'
import { TraderDashboardPage } from '../pages/TraderDashboardPage'
import { TerminalDashboard } from '../components/terminal/TerminalDashboard'
import { useAuth } from '../contexts/AuthContext'
import { useLanguage } from '../contexts/LanguageContext'
import { useSystemConfig } from '../hooks/useSystemConfig'
@@ -35,9 +35,7 @@ import { getUserMode } from '../lib/onboarding'
import type {
AccountInfo,
DecisionRecord,
Exchange,
Position,
Statistics,
SystemStatus,
TraderInfo,
} from '../types'
@@ -73,7 +71,7 @@ function LoadingScreen() {
return (
<div
className="min-h-screen flex items-center justify-center"
style={{ background: '#0B0E11' }}
style={{ background: '#F1ECE2' }}
>
<div className="text-center">
<img
@@ -81,7 +79,7 @@ function LoadingScreen() {
alt="NoFx Logo"
className="w-16 h-16 mx-auto mb-4 animate-pulse"
/>
<p style={{ color: '#EAECEF' }}>{t('loading', language)}</p>
<p style={{ color: '#1A1813' }}>{t('loading', language)}</p>
</div>
</div>
)
@@ -160,7 +158,7 @@ function AppChrome({
return (
<div
className="min-h-screen"
style={{ background: '#0B0E11', color: '#EAECEF' }}
style={{ background: '#F1ECE2', color: '#1A1813' }}
>
<HeaderBar
isLoggedIn={!!user}
@@ -226,14 +224,13 @@ function TradersRoute({
}
function DashboardRoute() {
const { language } = useLanguage()
const { user, token } = useAuth()
const navigate = useNavigate()
const [searchParams] = useSearchParams()
const selectedTraderSlug = searchParams.get('trader') || undefined
const [selectedTraderId, setSelectedTraderId] = useState<string | undefined>()
const [lastUpdate, setLastUpdate] = useState<string>('--:--:--')
const [decisionsLimit, setDecisionsLimit] = useState(5)
const [, setLastUpdate] = useState<string>('--:--:--')
const [decisionsLimit] = useState(5)
const [accountPollOff, setAccountPollOff] = useState(false)
const [positionsPollOff, setPositionsPollOff] = useState(false)
const [decisionsPollOff, setDecisionsPollOff] = useState(false)
@@ -244,7 +241,7 @@ function DashboardRoute() {
setDecisionsPollOff(false)
}, [selectedTraderId])
const { data: traders, error: tradersError } = useSWR<TraderInfo[]>(
const { data: traders } = useSWR<TraderInfo[]>(
user && token ? 'traders-dashboard' : null,
() => api.getTraders(true),
{
@@ -253,15 +250,6 @@ function DashboardRoute() {
}
)
const { data: exchanges } = useSWR<Exchange[]>(
user && token ? 'exchanges-dashboard' : null,
api.getExchangeConfigs,
{
refreshInterval: 60000,
shouldRetryOnError: false,
}
)
useEffect(() => {
if (!traders || traders.length === 0) {
return
@@ -359,16 +347,6 @@ function DashboardRoute() {
}
)
const { data: stats } = useSWR<Statistics>(
selectedTraderId ? `statistics-${selectedTraderId}` : null,
() => api.getStatistics(selectedTraderId, true),
{
refreshInterval: 30000,
revalidateOnFocus: false,
dedupingInterval: 20000,
}
)
useEffect(() => {
if (account) {
setLastUpdate(new Date().toLocaleTimeString())
@@ -381,22 +359,13 @@ function DashboardRoute() {
return (
<AppChrome currentPage="trader" animateContent>
<TraderDashboardPage
<TerminalDashboard
selectedTrader={selectedTrader}
status={status}
account={account}
accountFailed={accountPollOff}
positions={positions}
positionsFailed={positionsPollOff}
decisions={decisions}
decisionsFailed={decisionsPollOff}
decisionsLimit={decisionsLimit}
onDecisionsLimitChange={setDecisionsLimit}
stats={stats}
lastUpdate={lastUpdate}
language={language}
traders={traders}
tradersError={tradersError}
selectedTraderId={selectedTraderId}
onTraderSelect={(traderId) => {
setSelectedTraderId(traderId)
@@ -408,8 +377,6 @@ function DashboardRoute() {
}
)
}}
onNavigateToTraders={() => navigate(ROUTES.traders)}
exchanges={exchanges}
/>
</AppChrome>
)