mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-07 13:00:59 +08:00
refactor(web): restructure AITradersPage into modular architecture (#1023)
* refactor(web): restructure AITradersPage into modular architecture Refactored the massive 2652-line AITradersPage.tsx into a clean, modular architecture following React best practices. **Changes:** - Decomposed 2652-line component into 12 focused modules - Introduced Zustand stores for config and modal state management - Extracted all business logic into useTraderActions custom hook (633 lines) - Created reusable section components (PageHeader, TradersGrid, etc.) - Separated complex modal logic into dedicated components - Added TraderConfig type, eliminated all any types - Fixed critical bugs in configuredExchanges logic and getState() usage **File Structure:** - Main page reduced from 2652 → 234 lines (91% reduction) - components/traders/: 7 UI components + 5 section components - stores/: tradersConfigStore, tradersModalStore - hooks/: useTraderActions (all business logic) Co-Authored-By: tinkle-community <tinklefund@gmail.com> * chore: ignore PR_DESCRIPTION.md * fix(web): restore trader dashboard navigation functionality Fixed missing navigation logic in refactored AITradersPage. The "查看" (View) button now correctly navigates to the trader dashboard. **Root Cause:** During refactoring, the `useNavigate` hook and default navigation logic were inadvertently omitted from the main page component. **Changes:** - Added `useNavigate` import from react-router-dom - Implemented `handleTraderSelect` function with fallback navigation - Restored original behavior: use `onTraderSelect` prop if provided, otherwise navigate to `/dashboard?trader=${traderId}` **Testing:** - ✅ Click "查看" button navigates to trader dashboard - ✅ Query parameter correctly passed to dashboard Co-Authored-By: tinkle-community <tinklefund@gmail.com> * fix(web): correct type definitions for trader configuration Fixed TypeScript build errors by using the correct `TraderConfigData` type instead of the incorrect `TraderConfig` type. **Root Cause:** During refactoring, a new `TraderConfig` type was incorrectly created that extended `CreateTraderRequest` (with fields like `name`, `ai_model_id`). However, the `TraderConfigModal` component and API responses actually use `TraderConfigData` (with fields like `trader_name`, `ai_model`). **Changes:** - Replaced all `TraderConfig` references with `TraderConfigData`: - stores/tradersModalStore.ts - hooks/useTraderActions.ts - lib/api.ts - Removed incorrect `TraderConfig` type definition from types.ts - Added null check for `editingTrader.trader_id` to satisfy TypeScript **Build Status:** - ✅ TypeScript compilation: PASS - ✅ Vite production build: PASS Co-Authored-By: tinkle-community <tinklefund@gmail.com> --------- Co-authored-by: tinkle-community <tinklefund@gmail.com>
This commit is contained in:
79
web/src/stores/tradersModalStore.ts
Normal file
79
web/src/stores/tradersModalStore.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { create } from 'zustand'
|
||||
import type { TraderConfigData } from '../types'
|
||||
|
||||
interface TradersModalState {
|
||||
// Modal 显示状态
|
||||
showCreateModal: boolean
|
||||
showEditModal: boolean
|
||||
showModelModal: boolean
|
||||
showExchangeModal: boolean
|
||||
showSignalSourceModal: boolean
|
||||
|
||||
// 编辑状态
|
||||
editingModel: string | null
|
||||
editingExchange: string | null
|
||||
editingTrader: TraderConfigData | null
|
||||
|
||||
// Actions
|
||||
setShowCreateModal: (show: boolean) => void
|
||||
setShowEditModal: (show: boolean) => void
|
||||
setShowModelModal: (show: boolean) => void
|
||||
setShowExchangeModal: (show: boolean) => void
|
||||
setShowSignalSourceModal: (show: boolean) => void
|
||||
|
||||
setEditingModel: (modelId: string | null) => void
|
||||
setEditingExchange: (exchangeId: string | null) => void
|
||||
setEditingTrader: (trader: TraderConfigData | null) => void
|
||||
|
||||
// 便捷方法
|
||||
openModelModal: (modelId?: string) => void
|
||||
closeModelModal: () => void
|
||||
openExchangeModal: (exchangeId?: string) => void
|
||||
closeExchangeModal: () => void
|
||||
|
||||
// 重置
|
||||
reset: () => void
|
||||
}
|
||||
|
||||
const initialState = {
|
||||
showCreateModal: false,
|
||||
showEditModal: false,
|
||||
showModelModal: false,
|
||||
showExchangeModal: false,
|
||||
showSignalSourceModal: false,
|
||||
editingModel: null,
|
||||
editingExchange: null,
|
||||
editingTrader: null,
|
||||
}
|
||||
|
||||
export const useTradersModalStore = create<TradersModalState>((set) => ({
|
||||
...initialState,
|
||||
|
||||
setShowCreateModal: (show) => set({ showCreateModal: show }),
|
||||
setShowEditModal: (show) => set({ showEditModal: show }),
|
||||
setShowModelModal: (show) => set({ showModelModal: show }),
|
||||
setShowExchangeModal: (show) => set({ showExchangeModal: show }),
|
||||
setShowSignalSourceModal: (show) => set({ showSignalSourceModal: show }),
|
||||
|
||||
setEditingModel: (modelId) => set({ editingModel: modelId }),
|
||||
setEditingExchange: (exchangeId) => set({ editingExchange: exchangeId }),
|
||||
setEditingTrader: (trader) => set({ editingTrader: trader }),
|
||||
|
||||
openModelModal: (modelId) => {
|
||||
set({ editingModel: modelId || null, showModelModal: true })
|
||||
},
|
||||
|
||||
closeModelModal: () => {
|
||||
set({ showModelModal: false, editingModel: null })
|
||||
},
|
||||
|
||||
openExchangeModal: (exchangeId) => {
|
||||
set({ editingExchange: exchangeId || null, showExchangeModal: true })
|
||||
},
|
||||
|
||||
closeExchangeModal: () => {
|
||||
set({ showExchangeModal: false, editingExchange: null })
|
||||
},
|
||||
|
||||
reset: () => set(initialState),
|
||||
}))
|
||||
Reference in New Issue
Block a user