diff --git a/src/App.tsx b/src/App.tsx index f06b734..ae5acab 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,351 +1,21 @@ -import React, { useState, useEffect, useMemo } from 'react'; -import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query'; -import { motion, AnimatePresence } from 'framer-motion'; -import { - TrendingUp, - TrendingDown, - Wallet, - BarChart3, - Activity, - Plus -} from 'lucide-react'; -import Sidebar from './components/layout/Sidebar'; -import MarketOverview from './components/dashboard/MarketOverview'; -import AiInsights from './components/dashboard/AiInsights'; -import DashboardMarketStats from './components/dashboard/DashboardMarketStats'; -import CryptoTable from './components/markets/CryptoTable'; -import CryptoChart from './components/charts/CryptoChart'; -import PortfolioOverview from './components/portfolio/PortfolioOverview'; -import AddAssetModal from './components/portfolio/AddAssetModal'; -import Loading from './components/ui/Loading'; -import GlassCard from './components/ui/GlassCard'; -import CollapsibleSection from './components/ui/CollapsibleSection'; -import SectionSeparator from './components/ui/SectionSeparator'; -import Icon from './components/ui/Icon'; -import { usePortfolio } from './hooks/usePortfolio'; -import cryptoApiService, { CryptoCurrency, MarketChartData } from './services/cryptoApi'; - -const queryClient = new QueryClient({ - defaultOptions: { - queries: { - refetchOnWindowFocus: false, - }, - }, -}); - -function AppContent() { - const [activeTab, setActiveTab] = useState('dashboard'); - const [selectedCrypto, setSelectedCrypto] = useState(); - const [showAddAssetModal, setShowAddAssetModal] = useState(false); - const [chartTimeframe, setChartTimeframe] = useState('7'); - const [chartCoin, setChartCoin] = useState(); - const dashboardBackground = useMemo( - () => ({ - backgroundImage: - 'radial-gradient(circle at 20% 20%, rgba(59,130,246,0.08), transparent 55%), radial-gradient(circle at 80% 0%, rgba(248,113,113,0.08), transparent 50%), linear-gradient(135deg, rgba(15,23,42,0.98), rgba(2,6,23,0.98))', - backgroundSize: 'cover', - backgroundPosition: 'center', - backgroundAttachment: 'fixed', - }), - [] - ); - - const { - portfolio, - addAsset, - removeAsset, - updateMultiplePrices, - getPortfolioStats - } = usePortfolio(); - - // Fetch top cryptocurrencies - const { data: cryptocurrencies, isLoading: cryptoLoading } = useQuery({ - queryKey: ['cryptocurrencies'], - queryFn: () => cryptoApiService.getTopCryptocurrencies(50), - refetchInterval: 5 * 60 * 1000, // 5 minutes - refetchIntervalInBackground: false, - staleTime: 4 * 60 * 1000, - retry: 1, - }); - - // Set Bitcoin as the default chart coin once crypto data is loaded - useEffect(() => { - if (!chartCoin && cryptocurrencies && cryptocurrencies.length > 0) { - const bitcoin = cryptocurrencies.find(c => c.id === 'bitcoin'); - setChartCoin(bitcoin || cryptocurrencies[0]); - } - }, [cryptocurrencies, chartCoin]); - - // Fetch global market data - const { data: globalData, isLoading: globalLoading } = useQuery({ - queryKey: ['global-market'], - queryFn: () => cryptoApiService.getGlobalMarketData(), - refetchInterval: 5 * 60 * 1000, - refetchIntervalInBackground: false, - staleTime: 4 * 60 * 1000, - retry: 1, - }); - - // Fetch chart data for the selected coin - const { data: marketChartData, isLoading: chartLoading } = useQuery({ - queryKey: ['market-chart', chartCoin?.id, chartTimeframe], - queryFn: () => { - if (!chartCoin) return Promise.resolve(undefined); - return cryptoApiService.getMarketChart(chartCoin.id, chartTimeframe); - }, - enabled: !!chartCoin, // Only run query if a coin is selected - refetchInterval: chartTimeframe === '1' ? 3 * 60 * 1000 : 5 * 60 * 1000, - refetchIntervalInBackground: false, - staleTime: chartTimeframe === '1' ? 2 * 60 * 1000 : 4 * 60 * 1000, - retry: 1, - }); - - // Update portfolio prices when crypto data changes - useEffect(() => { - if (cryptocurrencies && portfolio.length > 0) { - const priceUpdates: Record = {}; - - portfolio.forEach(asset => { - const crypto = cryptocurrencies.find(c => c.id === asset.id); - if (crypto) { - priceUpdates[asset.id] = crypto.current_price; - } - }); - - if (Object.keys(priceUpdates).length > 0) { - updateMultiplePrices(priceUpdates); - } - } - }, [cryptocurrencies, portfolio, updateMultiplePrices]); - - const handleAddToPortfolio = (crypto: CryptoCurrency) => { - setSelectedCrypto(crypto); - setShowAddAssetModal(true); - }; - - const handleAddAsset = (assetData: any) => { - addAsset(assetData); - }; - - const portfolioStats = getPortfolioStats(); - - const globalOverviewData = globalData?.data - ? { - totalMarketCap: globalData.data.total_market_cap?.usd || 0, - marketCapChange24h: globalData.data.market_cap_change_percentage_24h_usd || 0, - totalVolume: globalData.data.total_volume?.usd || 0, - bitcoinDominance: globalData.data.market_cap_percentage?.btc || 0, - } - : undefined; - - const renderContent = () => { - switch (activeTab) { - case 'dashboard': - return ( -
- - -
- ); - - case 'markets': - return ( -
- - - - - {cryptoLoading ? ( -
- -
- ) : cryptocurrencies ? ( - - ) : ( - -
-
- -
-
-

- We hit the API rate limit (429). ☕ Please give it about 10 minutes and try again. -

-
-
-
- )} -
- ); - - case 'portfolio': - return ( -
-
-
-

Portfolio Management

-

Track and manage your cryptocurrency investments

-
- -
- - - - -
- ); - - case 'charts': - return ( -
-
-

Price Charts & Analysis

-

Interactive cryptocurrency price charts with technical analysis

-
- - - - - - - - {/* Additional charts section with progressive disclosure */} -
- } - className="" - contentClassName="space-y-4" - > -
-
- -
-

Advanced Charts

-

Ethereum, Altcoin charts, and technical indicators will be available in future updates.

-
-
- - } - defaultExpanded - className="" - contentClassName="space-y-4" - > -
- {[ - // { icon: TrendingUp, title: 'Multiple Timeframes', desc: '1D, 7D, 30D, 90D, 1Y views' }, - // { icon: Activity, title: 'Interactive Tooltips', desc: 'Hover for detailed price information' }, - // { icon: BarChart3, title: 'Real-time Updates', desc: 'Live data with automatic refresh' }, - // { icon: Wallet, title: 'Technical Indicators', desc: 'Coming soon: RSI, MACD, Moving Averages' } - ].map((feature, index) => ( -
-
- -
-
-

{feature.title}

-

{feature.desc}

-
-
- ))} -
-
-
-
- ); - - default: - return ( -
- -
-
- -
-
-

- {activeTab.charAt(0).toUpperCase() + activeTab.slice(1)} -

-

This section is under development!

- -

Check back soon for exciting new features and improvements.

-
-
-
-
- ); - } - }; - - return ( -
- {/* Background overlay */} -
- -
- - -
-
- - - {renderContent()} - - -
-
-
- - { - setShowAddAssetModal(false); - setSelectedCrypto(undefined); - }} - onAddAsset={handleAddAsset} - selectedCrypto={selectedCrypto} - /> -
- ); -} +import { BrowserRouter, Routes, Route, Link } from 'react-router-dom' +import RealtimeKline from './pages/RealtimeKline' function App() { return ( - - - - ); + + + + + 欢迎使用 Crypto Dashboard
} /> + } /> + + + ) } -export default App; +export default App