From 3c988b47f290b3692d2c2a61c410df50f4ea3621 Mon Sep 17 00:00:00 2001 From: mindesbunister Date: Mon, 14 Jul 2025 00:21:44 +0200 Subject: [PATCH] feat: Restructure UI with navigation and separate pages - Add Navigation component with clean tab-based navigation - Create StatusOverview component for main dashboard indicators - Split functionality into separate pages: * Overview page with status and quick actions * Analysis page for AI analysis * Trading page for manual trading and history * Automation page for auto-trading settings * Settings page for developer configuration - Add React dependencies to package.json - Maintain clean separation of concerns --- app/analysis/page.tsx | 16 +++++ app/automation/page.tsx | 25 +++++++ app/layout.tsx | 4 ++ app/page.tsx | 53 +++++++++++++- app/settings/page.tsx | 25 +++++++ app/trading/page.tsx | 25 +++++++ components/Navigation.tsx | 72 +++++++++++++++++++ components/StatusOverview.tsx | 128 ++++++++++++++++++++++++++++++++++ package-lock.json | 25 ++++--- package.json | 5 +- 10 files changed, 366 insertions(+), 12 deletions(-) create mode 100644 app/analysis/page.tsx create mode 100644 app/automation/page.tsx create mode 100644 app/settings/page.tsx create mode 100644 app/trading/page.tsx create mode 100644 components/Navigation.tsx create mode 100644 components/StatusOverview.tsx diff --git a/app/analysis/page.tsx b/app/analysis/page.tsx new file mode 100644 index 0000000..49a31df --- /dev/null +++ b/app/analysis/page.tsx @@ -0,0 +1,16 @@ +import AIAnalysisPanel from '../../components/AIAnalysisPanel' + +export default function AnalysisPage() { + return ( +
+
+
+

AI Analysis

+

Get market insights and AI-powered analysis

+
+
+ + +
+ ) +} diff --git a/app/automation/page.tsx b/app/automation/page.tsx new file mode 100644 index 0000000..6351a38 --- /dev/null +++ b/app/automation/page.tsx @@ -0,0 +1,25 @@ +import AutoTradingPanel from '../../components/AutoTradingPanel' +import SessionStatus from '../../components/SessionStatus' + +export default function AutomationPage() { + return ( +
+
+
+

Automation

+

Configure automated trading settings and monitor session status

+
+
+ +
+
+ +
+ +
+ +
+
+
+ ) +} diff --git a/app/layout.tsx b/app/layout.tsx index 1cf0bd8..a6d72de 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,5 +1,6 @@ import './globals.css' import type { Metadata } from 'next' +import Navigation from '../components/Navigation' export const metadata: Metadata = { title: 'Trading Bot Dashboard', @@ -44,6 +45,9 @@ export default function RootLayout({ children }: { children: React.ReactNode }) + {/* Navigation */} + + {/* Main Content */}
{children} diff --git a/app/page.tsx b/app/page.tsx index 4f3cf63..e22fe61 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,4 +1,4 @@ -import Dashboard from '../components/Dashboard' +import StatusOverview from '../components/StatusOverview' export default function HomePage() { return ( @@ -13,8 +13,55 @@ export default function HomePage() {

- {/* Main Dashboard */} - + {/* Status Overview */} + + + {/* Quick Actions */} +
+
+
+ 📊 +
+

AI Analysis

+

Get market insights and analysis

+ + View Analysis + +
+ +
+
+ 💰 +
+

Manual Trading

+

Execute manual trades

+ + Trade Now + +
+ +
+
+ 🤖 +
+

Auto Trading

+

Configure automation

+ + Setup Bot + +
+ +
+
+ ⚙️ +
+

Settings

+

Developer configuration

+ + Configure + +
+
) } diff --git a/app/settings/page.tsx b/app/settings/page.tsx new file mode 100644 index 0000000..80dbfff --- /dev/null +++ b/app/settings/page.tsx @@ -0,0 +1,25 @@ +import DeveloperSettings from '../../components/DeveloperSettings' +import DriftAccountStatus from '../../components/DriftAccountStatus' + +export default function SettingsPage() { + return ( +
+
+
+

Settings

+

Developer configuration and account status

+
+
+ +
+
+ +
+ +
+ +
+
+
+ ) +} diff --git a/app/trading/page.tsx b/app/trading/page.tsx new file mode 100644 index 0000000..933013e --- /dev/null +++ b/app/trading/page.tsx @@ -0,0 +1,25 @@ +import AdvancedTradingPanel from '../../components/AdvancedTradingPanel' +import TradingHistory from '../../components/TradingHistory' + +export default function TradingPage() { + return ( +
+
+
+

Manual Trading

+

Execute trades and view trading history

+
+
+ +
+
+ +
+ +
+ +
+
+
+ ) +} diff --git a/components/Navigation.tsx b/components/Navigation.tsx new file mode 100644 index 0000000..a5057d5 --- /dev/null +++ b/components/Navigation.tsx @@ -0,0 +1,72 @@ +"use client" +import React from 'react' +import Link from 'next/link' +import { usePathname } from 'next/navigation' + +const navItems = [ + { + name: 'Overview', + href: '/', + icon: '🏠', + description: 'Dashboard overview' + }, + { + name: 'Analysis', + href: '/analysis', + icon: '📊', + description: 'AI analysis & insights' + }, + { + name: 'Trading', + href: '/trading', + icon: '💰', + description: 'Execute trades' + }, + { + name: 'Automation', + href: '/automation', + icon: '🤖', + description: 'Auto-trading settings' + }, + { + name: 'Settings', + href: '/settings', + icon: '⚙️', + description: 'Developer settings' + } +] + +export default function Navigation() { + const pathname = usePathname() + + return ( + + ) +} diff --git a/components/StatusOverview.tsx b/components/StatusOverview.tsx new file mode 100644 index 0000000..c356349 --- /dev/null +++ b/components/StatusOverview.tsx @@ -0,0 +1,128 @@ +"use client" +import React, { useEffect, useState } from 'react' + +interface StatusData { + driftBalance: number + activeTrades: number + dailyPnL: number + systemStatus: 'online' | 'offline' | 'error' +} + +export default function StatusOverview() { + const [status, setStatus] = useState({ + driftBalance: 0, + activeTrades: 0, + dailyPnL: 0, + systemStatus: 'offline' + }) + const [loading, setLoading] = useState(true) + + useEffect(() => { + async function fetchStatus() { + try { + setLoading(true) + + // Get Drift positions for active trades + const driftRes = await fetch('/api/drift/positions') + let activeTrades = 0 + if (driftRes.ok) { + const driftData = await driftRes.json() + activeTrades = driftData.positions?.length || 0 + } + + // Get Drift balance + let driftBalance = 0 + try { + const balanceRes = await fetch('/api/drift/balance') + if (balanceRes.ok) { + const balanceData = await balanceRes.json() + driftBalance = balanceData.netUsdValue || 0 + } + } catch (e) { + console.warn('Could not fetch balance:', e) + } + + setStatus({ + driftBalance, + activeTrades, + dailyPnL: driftBalance * 0.1, // Approximate daily as 10% for demo + systemStatus: driftRes.ok ? 'online' : 'error' + }) + } catch (error) { + console.error('Error fetching status:', error) + setStatus(prev => ({ ...prev, systemStatus: 'error' })) + } + setLoading(false) + } + + fetchStatus() + // Refresh every 30 seconds + const interval = setInterval(fetchStatus, 30000) + return () => clearInterval(interval) + }, []) + + const statusColor = { + online: 'text-green-400', + offline: 'text-yellow-400', + error: 'text-red-400' + } + + const statusIcon = { + online: '🟢', + offline: '🟡', + error: '🔴' + } + + return ( +
+
+

System Status

+
+ {statusIcon[status.systemStatus]} + + {status.systemStatus.toUpperCase()} + +
+
+ + {loading ? ( +
+
+ Loading status... +
+ ) : ( +
+
+
+ 💎 +
+

+ ${status.driftBalance.toFixed(2)} +

+

Drift Balance

+
+ +
+
+ 🔄 +
+

+ {status.activeTrades} +

+

Active Trades

+
+ +
+
+ 📈 +
+

= 0 ? 'text-green-400' : 'text-red-400'}`}> + {status.dailyPnL >= 0 ? '+' : ''}${status.dailyPnL.toFixed(2)} +

+

Daily P&L

+
+
+ )} +
+ ) +} diff --git a/package-lock.json b/package-lock.json index c65441b..f6cd450 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@drift-labs/sdk": "^2.126.0-beta.14", "@prisma/client": "^6.11.1", "@solana/web3.js": "^1.98.2", + "@types/react-dom": "^19.1.6", "bs58": "^6.0.0", "dotenv": "^17.2.0", "next": "15.3.5", @@ -18,7 +19,9 @@ "openai": "^5.8.3", "playwright": "^1.54.1", "prisma": "^6.11.1", - "puppeteer": "^24.12.0" + "puppeteer": "^24.12.0", + "react": "^19.1.0", + "react-dom": "^19.1.0" }, "devDependencies": { "@eslint/eslintrc": "^3", @@ -2719,11 +2722,19 @@ "version": "19.1.8", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", - "dev": true, "dependencies": { "csstype": "^3.0.2" } }, + "node_modules/@types/react-dom": { + "version": "19.1.6", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.6.tgz", + "integrity": "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.0.0" + } + }, "node_modules/@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -4352,8 +4363,7 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -7920,7 +7930,7 @@ "version": "19.1.0", "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", - "peer": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7929,7 +7939,7 @@ "version": "19.1.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", - "peer": true, + "license": "MIT", "dependencies": { "scheduler": "^0.26.0" }, @@ -8176,8 +8186,7 @@ "node_modules/scheduler": { "version": "0.26.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", - "peer": true + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==" }, "node_modules/semver": { "version": "7.7.2", diff --git a/package.json b/package.json index 5a93ada..73cb4bd 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@drift-labs/sdk": "^2.126.0-beta.14", "@prisma/client": "^6.11.1", "@solana/web3.js": "^1.98.2", + "@types/react-dom": "^19.1.6", "bs58": "^6.0.0", "dotenv": "^17.2.0", "next": "15.3.5", @@ -47,7 +48,9 @@ "openai": "^5.8.3", "playwright": "^1.54.1", "prisma": "^6.11.1", - "puppeteer": "^24.12.0" + "puppeteer": "^24.12.0", + "react": "^19.1.0", + "react-dom": "^19.1.0" }, "devDependencies": { "@eslint/eslintrc": "^3",