1+ import React , { useState , useEffect , useContext } from 'react' ;
2+ import { AppContext } from '@/contexts/AppContext' ;
3+ import { useSwigWallet } from '@/contexts/SwigWalletProvider' ;
4+ import OverviewPanel from '@/components/analytics/OverviewPanel' ;
5+ import RecentTrades from '@/components/analytics/RecentTrades' ;
6+ import VolumePerDayChart from '@/components/analytics/VolumePerDayChart' ;
7+ import TopTraders from '@/components/analytics/TopTraders' ;
8+
9+ export default function AnalyticsDashboard ( ) {
10+ const { network, selectedNetwork, networks } = useContext ( AppContext ) ;
11+ const { connected, publicKey } = useSwigWallet ( ) ;
12+ const [ timeframe , setTimeframe ] = useState ( '24h' ) ;
13+ const [ refreshInterval , setRefreshInterval ] = useState ( null ) ;
14+
15+ // Real-time protocol data states
16+ const [ protocolOverview , setProtocolOverview ] = useState ( {
17+ totalTrades : 0 ,
18+ protocolVolume : 0 ,
19+ totalFees : 0 ,
20+ completionRate : 0 ,
21+ tradesChange : 0 ,
22+ volumeChange : 0 ,
23+ feesChange : 0 ,
24+ completionChange : 0
25+ } ) ;
26+
27+ const [ recentTrades , setRecentTrades ] = useState ( [ ] ) ;
28+ const [ volumeData , setVolumeData ] = useState ( [ ] ) ;
29+ const [ topTradersData , setTopTradersData ] = useState ( [ ] ) ;
30+
31+ // Initialize real-time data fetching
32+ useEffect ( ( ) => {
33+ // Initial data fetch
34+ fetchAllProtocolData ( ) ;
35+
36+ // Set up real-time updates every 5 seconds
37+ const interval = setInterval ( fetchAllProtocolData , 5000 ) ;
38+ setRefreshInterval ( interval ) ;
39+
40+ return ( ) => {
41+ if ( interval ) {
42+ clearInterval ( interval ) ;
43+ }
44+ } ;
45+ } , [ selectedNetwork , timeframe ] ) ;
46+
47+ const fetchAllProtocolData = async ( ) => {
48+ try {
49+ // Simulate API calls to fetch real-time protocol data
50+ await Promise . all ( [
51+ fetchProtocolOverview ( ) ,
52+ fetchRecentTradesData ( ) ,
53+ fetchVolumeData ( ) ,
54+ fetchTopTradersData ( )
55+ ] ) ;
56+ } catch ( error ) {
57+ console . error ( 'Error fetching protocol analytics data:' , error ) ;
58+ }
59+ } ;
60+
61+ const fetchProtocolOverview = async ( ) => {
62+ // Simulate fetching protocol overview metrics
63+ const mockData = {
64+ totalTrades : Math . floor ( Math . random ( ) * 5000 ) + 1000 , // 1000-6000 trades
65+ protocolVolume : Math . random ( ) * 50000 + 10000 , // 10K-60K SOL
66+ totalFees : Math . random ( ) * 50000 + 5000 , // $5K-$55K in fees
67+ completionRate : 85 + ( Math . random ( ) * 10 ) , // 85-95%
68+ tradesChange : Math . random ( ) * 20 - 5 , // -5% to +15%
69+ volumeChange : Math . random ( ) * 30 - 10 , // -10% to +20%
70+ feesChange : Math . random ( ) * 25 - 5 , // -5% to +20%
71+ completionChange : Math . random ( ) * 5 - 2 // -2% to +3%
72+ } ;
73+ setProtocolOverview ( mockData ) ;
74+ } ;
75+
76+ const fetchRecentTradesData = async ( ) => {
77+ // Simulate fetching recent protocol trades (last 100)
78+ const mockTrades = Array . from ( { length : 100 } , ( _ , i ) => {
79+ const tradeId = `T${ Date . now ( ) . toString ( ) . slice ( - 6 ) } _${ i . toString ( ) . padStart ( 3 , '0' ) } ` ;
80+ const types = [ 'buy' , 'sell' ] ;
81+ const statuses = [ 'completed' , 'in_progress' , 'cancelled' , 'disputed' ] ;
82+ const currencies = [ 'USD' , 'EUR' , 'GBP' ] ;
83+
84+ const solAmount = Math . random ( ) * 10 + 0.1 ; // 0.1-10 SOL
85+ const rate = 130 + ( Math . random ( ) * 40 ) ; // $130-170 per SOL
86+ const fiatAmount = solAmount * rate ;
87+
88+ return {
89+ tradeId,
90+ type : types [ Math . floor ( Math . random ( ) * types . length ) ] ,
91+ status : statuses [ Math . floor ( Math . random ( ) * statuses . length ) ] ,
92+ buyer : `${ Math . random ( ) . toString ( 36 ) . substring ( 2 , 15 ) } ` ,
93+ seller : `${ Math . random ( ) . toString ( 36 ) . substring ( 2 , 15 ) } ` ,
94+ solAmount,
95+ fiatAmount,
96+ currency : currencies [ Math . floor ( Math . random ( ) * currencies . length ) ] ,
97+ rate,
98+ timestamp : new Date ( Date . now ( ) - Math . random ( ) * 86400000 * 7 ) , // Last 7 days
99+ completionTime : Math . random ( ) > 0.7 ? `${ Math . floor ( Math . random ( ) * 30 + 5 ) } min` : null ,
100+ protocolFee : solAmount * 0.005 // 0.5% protocol fee
101+ } ;
102+ } ) ;
103+
104+ // Sort by timestamp, newest first
105+ mockTrades . sort ( ( a , b ) => b . timestamp - a . timestamp ) ;
106+ setRecentTrades ( mockTrades ) ;
107+ } ;
108+
109+ const fetchVolumeData = async ( ) => {
110+ // Simulate fetching volume data based on timeframe
111+ let dataPointsCount ;
112+ let timeIncrement ;
113+
114+ switch ( timeframe ) {
115+ case '1h' :
116+ dataPointsCount = 60 ; // 60 minutes
117+ timeIncrement = 60 * 1000 ; // 1 minute
118+ break ;
119+ case '24h' :
120+ dataPointsCount = 24 ; // 24 hours
121+ timeIncrement = 60 * 60 * 1000 ; // 1 hour
122+ break ;
123+ case '7d' :
124+ dataPointsCount = 7 ; // 7 days
125+ timeIncrement = 24 * 60 * 60 * 1000 ; // 1 day
126+ break ;
127+ case '30d' :
128+ dataPointsCount = 30 ; // 30 days
129+ timeIncrement = 24 * 60 * 60 * 1000 ; // 1 day
130+ break ;
131+ default :
132+ dataPointsCount = 24 ;
133+ timeIncrement = 60 * 60 * 1000 ;
134+ }
135+
136+ const now = new Date ( ) ;
137+ const volumePoints = Array . from ( { length : dataPointsCount } , ( _ , i ) => {
138+ const time = new Date ( now . getTime ( ) - ( dataPointsCount - 1 - i ) * timeIncrement ) ;
139+ const baseVolume = 1000 + Math . random ( ) * 5000 ; // Base volume
140+ const volume = baseVolume + Math . sin ( i / 5 ) * 1000 ; // Add some wave pattern
141+
142+ return {
143+ time : time . toISOString ( ) ,
144+ volume : Math . max ( 0 , volume ) // Ensure non-negative
145+ } ;
146+ } ) ;
147+
148+ setVolumeData ( volumePoints ) ;
149+ } ;
150+
151+ const fetchTopTradersData = async ( ) => {
152+ // Simulate fetching top 100 traders data
153+ const mockTraders = Array . from ( { length : 100 } , ( _ , i ) => {
154+ const baseAddress = Math . random ( ) . toString ( 36 ) . substring ( 2 , 15 ) ;
155+ const address = `${ baseAddress } ...${ Math . random ( ) . toString ( 36 ) . substring ( 2 , 6 ) } ` ;
156+
157+ const tradeCount = Math . floor ( Math . random ( ) * 500 ) + 10 ; // 10-510 trades
158+ const volume = Math . random ( ) * 100000 + 1000 ; // 1K-101K SOL
159+ const pnl = ( Math . random ( ) - 0.3 ) * 50000 ; // -15K to +35K (bias towards positive)
160+ const successRate = 60 + Math . random ( ) * 35 ; // 60-95%
161+
162+ return {
163+ address,
164+ tradeCount,
165+ volume,
166+ pnl,
167+ successRate,
168+ verified : Math . random ( ) > 0.8 // 20% are verified
169+ } ;
170+ } ) ;
171+
172+ setTopTradersData ( mockTraders ) ;
173+ } ;
174+
175+ const timeframeOptions = [
176+ { value : '1h' , label : '1H' } ,
177+ { value : '24h' , label : '24H' } ,
178+ { value : '7d' , label : '7D' } ,
179+ { value : '30d' , label : '30D' }
180+ ] ;
181+
182+ return (
183+ < div className = "analytics-dashboard" >
184+ < div className = "analytics-header" >
185+ < div className = "header-content" >
186+ < div className = "title-section" >
187+ < h1 className = "analytics-title" >
188+ Protocol Analytics Dashboard
189+ </ h1 >
190+ < p className = "analytics-subtitle" >
191+ Monitor svmp2p trading performance and user metrics on { network . name }
192+ </ p >
193+ </ div >
194+
195+ < div className = "header-controls" >
196+ < div className = "timeframe-selector" >
197+ { timeframeOptions . map ( option => (
198+ < button
199+ key = { option . value }
200+ className = { `timeframe-button ${ timeframe === option . value ? 'active' : '' } ` }
201+ onClick = { ( ) => setTimeframe ( option . value ) }
202+ >
203+ { option . label }
204+ </ button >
205+ ) ) }
206+ </ div >
207+
208+ < div className = "connection-status" >
209+ { connected ? (
210+ < span className = "status-connected" >
211+ [ONLINE] { network . name }
212+ </ span >
213+ ) : (
214+ < span className = "status-disconnected" >
215+ [OFFLINE] WALLET NOT CONNECTED
216+ </ span >
217+ ) }
218+ </ div >
219+ </ div >
220+ </ div >
221+ </ div >
222+
223+ < div className = "analytics-content" >
224+ { /* Protocol Overview Panel - KPI Summary */ }
225+ < OverviewPanel
226+ data = { protocolOverview }
227+ network = { network }
228+ timeframe = { timeframe }
229+ />
230+
231+ < div className = "analytics-grid" >
232+ { /* Left Column - Volume Chart and Top Traders */ }
233+ < div className = "analytics-column-left" >
234+ { /* Volume Per Day Chart */ }
235+ < VolumePerDayChart
236+ data = { volumeData }
237+ network = { network }
238+ timeframe = { timeframe }
239+ />
240+
241+ { /* Top Traders Rankings */ }
242+ < TopTraders
243+ tradersData = { topTradersData }
244+ />
245+ </ div >
246+
247+ { /* Right Column - Recent Trades Feed */ }
248+ < div className = "analytics-column-right" >
249+ < RecentTrades
250+ trades = { recentTrades }
251+ network = { network }
252+ />
253+ </ div >
254+ </ div >
255+ </ div >
256+ </ div >
257+ ) ;
258+ }
0 commit comments