feat(web): add Data page with embedded nofxos.ai dashboard

- Add Data navigation item before Market in header
- Create DataPage component with iframe embedding
- Publicly accessible without login required
This commit is contained in:
tinkle-community
2026-01-17 23:37:12 +08:00
parent ee081ebc85
commit 95486173f7
3 changed files with 50 additions and 0 deletions
+31
View File
@@ -14,6 +14,7 @@ import { FAQPage } from './pages/FAQPage'
import { StrategyStudioPage } from './pages/StrategyStudioPage'
import { DebateArenaPage } from './pages/DebateArenaPage'
import { StrategyMarketPage } from './pages/StrategyMarketPage'
import { DataPage } from './pages/DataPage'
import { LoginRequiredOverlay } from './components/LoginRequiredOverlay'
import HeaderBar from './components/HeaderBar'
import { LanguageProvider, useLanguage } from './contexts/LanguageContext'
@@ -41,6 +42,7 @@ type Page =
| 'backtest'
| 'strategy'
| 'strategy-market'
| 'data'
| 'debate'
| 'faq'
| 'login'
@@ -68,6 +70,7 @@ function App() {
if (path === '/backtest' || hash === 'backtest') return 'backtest'
if (path === '/strategy' || hash === 'strategy') return 'strategy'
if (path === '/strategy-market' || hash === 'strategy-market') return 'strategy-market'
if (path === '/data' || hash === 'data') return 'data'
if (path === '/debate' || hash === 'debate') return 'debate'
if (path === '/dashboard' || hash === 'trader' || hash === 'details')
return 'trader'
@@ -88,6 +91,7 @@ function App() {
const pathMap: Record<Page, string> = {
'competition': '/competition',
'strategy-market': '/strategy-market',
'data': '/data',
'traders': '/traders',
'trader': '/dashboard',
'backtest': '/backtest',
@@ -152,6 +156,8 @@ function App() {
setCurrentPage('strategy')
} else if (path === '/strategy-market' || hash === 'strategy-market') {
setCurrentPage('strategy-market')
} else if (path === '/data' || hash === 'data') {
setCurrentPage('data')
} else if (path === '/debate' || hash === 'debate') {
setCurrentPage('debate')
} else if (
@@ -370,6 +376,29 @@ function App() {
if (route === '/reset-password') {
return <ResetPasswordPage />
}
// Data page - publicly accessible with embedded dashboard
if (route === '/data') {
return (
<div
className="min-h-screen"
style={{ background: '#0B0E11', color: '#EAECEF' }}
>
<HeaderBar
isLoggedIn={!!user}
currentPage="data"
language={language}
onLanguageChange={setLanguage}
user={user}
onLogout={logout}
onLoginRequired={handleLoginRequired}
onPageChange={navigateToPage}
/>
<main className="pt-16">
<DataPage />
</main>
</div>
)
}
// Show landing page for root route
if (route === '/' || route === '') {
return <LandingPage />
@@ -408,6 +437,8 @@ function App() {
>
{currentPage === 'competition' ? (
<CompetitionPage />
) : currentPage === 'data' ? (
<DataPage />
) : currentPage === 'strategy-market' ? (
<StrategyMarketPage />
) : currentPage === 'traders' ? (
+3
View File
@@ -13,6 +13,7 @@ type Page =
| 'backtest'
| 'strategy'
| 'strategy-market'
| 'data'
| 'debate'
| 'faq'
| 'login'
@@ -98,6 +99,7 @@ export default function HeaderBar({
{(() => {
// Define all navigation tabs
const navTabs: { page: Page; path: string; label: string; requiresAuth: boolean }[] = [
{ page: 'data', path: '/data', label: language === 'zh' ? '数据' : 'Data', requiresAuth: false },
{ page: 'strategy-market', path: '/strategy-market', label: language === 'zh' ? '策略市场' : 'Market', requiresAuth: true },
{ page: 'traders', path: '/traders', label: t('configNav', language), requiresAuth: true },
{ page: 'trader', path: '/dashboard', label: t('dashboardNav', language), requiresAuth: true },
@@ -327,6 +329,7 @@ export default function HeaderBar({
<div className="flex flex-col gap-6 mb-12">
{(() => {
const navTabs: { page: Page; path: string; label: string; requiresAuth: boolean }[] = [
{ page: 'data', path: '/data', label: language === 'zh' ? '数据' : 'Data', requiresAuth: false },
{ page: 'strategy-market', path: '/strategy-market', label: language === 'zh' ? '策略市场' : 'Market', requiresAuth: true },
{ page: 'traders', path: '/traders', label: t('configNav', language), requiresAuth: true },
{ page: 'trader', path: '/dashboard', label: t('dashboardNav', language), requiresAuth: true },
+16
View File
@@ -0,0 +1,16 @@
import { useLanguage } from '../contexts/LanguageContext'
export function DataPage() {
const { language } = useLanguage()
return (
<div className="w-full h-[calc(100vh-64px)]">
<iframe
src="https://nofxos.ai/dashboard"
title={language === 'zh' ? '数据中心' : 'Data Center'}
className="w-full h-full border-0"
allow="fullscreen"
/>
</div>
)
}