1
- import Container from '@/components/container ' ;
2
- import LatestBlocks from '@/components/homepage/latest-blocks ' ;
3
- import LatestExtrinsics from '@/components/homepage/latest-extrinsics ' ;
4
- import LatestTransactions from '@/components/homepage/latest-transactions ' ;
1
+ import { LatestBlocks } from '@/components/homepage/latest-blocks ' ;
2
+ import { LatestExtrinsics } from '@/components/homepage/latest-extrinsics ' ;
3
+ import { LatestTransactions } from '@/components/homepage/latest-transactions ' ;
4
+ import { Search } from '@/components/homepage/search.tsx ' ;
5
5
import TargetTimeCountdown from '@/components/target-time-countdown' ;
6
- import { Card , CardContent , CardHeader , CardTitle } from '@/components/ui/card' ;
7
6
import { ApiCommand , request } from '@/lib/api' ;
8
7
import { formatNumber , handleRequestResult } from '@/lib/utils' ;
9
- import { ArrowLeftRight , Clock , Pencil , Wallet } from 'lucide- react' ;
8
+ import { RiArrowLeftRightLine , RiArrowRightUpLine , RiPencilLine , RiTimerLine , RiWalletLine } from '@remixicon/ react' ;
10
9
11
10
export const dynamic = 'force-dynamic' ;
12
11
13
12
const getData = async ( ) => {
14
13
const [ blocksResponse , transactionsResponse , extrinsicsResponse , chainSummaryResponse ] = await Promise . all ( [
15
14
request ( ApiCommand . getBlocks , { page : 1 , limit : 10 } ) ,
16
15
request ( ApiCommand . getTransactions , { page : 1 , limit : 5 } ) ,
17
- request ( ApiCommand . getExtrinsics , { page : 1 , limit : 5 } ) ,
16
+ request ( ApiCommand . getExtrinsics , { page : 1 , limit : 10 } ) ,
18
17
request ( ApiCommand . getChainSummary ) ,
19
18
] ) ;
20
19
@@ -29,63 +28,89 @@ const getData = async () => {
29
28
export default async function IndexPage ( ) {
30
29
const { latestBlocks, latestExtrinsics, latestTransactions, chainSummary } = await getData ( ) ;
31
30
31
+ const stats = [
32
+ { title : 'Target Block Time' , value : '4s' , icon : RiTimerLine } ,
33
+ {
34
+ title : 'Signed Extrinsics' ,
35
+ value : Number ( chainSummary ?. signedExtrinsics || 0 ) ,
36
+ icon : RiPencilLine ,
37
+ } ,
38
+ {
39
+ title : 'Total Transactions' ,
40
+ value : Number ( chainSummary ?. evmTransactions || 0 ) ,
41
+ icon : RiArrowLeftRightLine ,
42
+ } ,
43
+ {
44
+ title : 'Wallet Addresses' ,
45
+ value : Number ( chainSummary ?. addresses || 0 ) ,
46
+ icon : RiWalletLine ,
47
+ } ,
48
+ ] ;
49
+
32
50
return (
33
- < Container >
34
- < div className = "flex flex-col gap-8" >
35
- < section className = "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4" >
36
- { [
37
- { title : 'Target Block Time' , value : '4s' , icon : Clock } ,
38
- {
39
- title : 'Signed Extrinsics' ,
40
- value : Number ( chainSummary ?. signedExtrinsics || 0 ) ,
41
- icon : Pencil ,
42
- } ,
43
- {
44
- title : 'Total Transactions' ,
45
- value : Number ( chainSummary ?. evmTransactions || 0 ) ,
46
- icon : ArrowLeftRight ,
47
- } ,
48
- {
49
- title : 'Wallet Addresses' ,
50
- value : Number ( chainSummary ?. addresses || 0 ) ,
51
- icon : Wallet ,
52
- } ,
53
- ] . map ( ( stat , _ ) => {
54
- const Icon = stat . icon ;
55
- return (
56
- < div key = { _ } >
57
- < Card >
58
- < CardHeader className = "flex flex-row items-center justify-between space-y-0 pb-4" >
59
- < Icon className = "size-5 text-muted-foreground" />
60
- < CardTitle className = "text-xs uppercase text-muted-foreground" > { stat . title } </ CardTitle >
61
- </ CardHeader >
62
- < CardContent >
63
- < div className = "text-2xl font-bold" >
64
- { stat ?. title === 'Target Block Time' ? (
65
- < TargetTimeCountdown />
66
- ) : (
67
- formatNumber ( typeof stat . value === 'string' ? Number ( stat . value ) : stat . value )
68
- ) }
69
- </ div >
70
- </ CardContent >
71
- </ Card >
51
+ < div style = { { background : `url('/home-page-background.png') top / 100% no-repeat` } } >
52
+ < div className = "container grid grid-cols-2 gap-4 px-4 pb-6 pt-8 md:gap-6 md:px-6 md:pt-10 lg:px-8 xl:px-14 xl:pb-14 xl:pt-8" >
53
+ < section className = "col-span-2 flex flex-col gap-6 xl:flex-row xl:items-center xl:gap-0 xl:py-4" >
54
+ < div className = "flex flex-1 flex-col gap-4" >
55
+ < h1 className = "text-[32px]/[44px] font-bold" > The Root Network Explorer</ h1 >
56
+ < div className = "w-full xl:max-w-[650px]" >
57
+ < Search />
58
+ </ div >
59
+ </ div >
60
+ < div
61
+ className = "link-box rounded-[16px] p-px"
62
+ style = { { background : 'linear-gradient(90deg, #8F9AE9 0%, #E0BC95 50%, #F78F50 100%)' } }
63
+ >
64
+ < div className = "flex flex-col gap-1 rounded-[15px] bg-white p-6 pt-5 hover:bg-api-portal-banner dark:bg-black xl:max-w-[330px]" >
65
+ < div className = "flex items-center justify-between" >
66
+ < a
67
+ href = "https://build.rootscan.io/"
68
+ target = "_blank"
69
+ className = "link-overlay text-[18px]/[28px] font-semibold"
70
+ >
71
+ API Portal
72
+ </ a >
73
+ < RiArrowRightUpLine className = "size-6" />
72
74
</ div >
73
- ) ;
74
- } ) }
75
+ < p className = "text-xs font-normal text-foreground/60" >
76
+ Kickstart your development on The Root Network with Rootscan’s{ ' ' }
77
+ < strong className = "text-foreground" > API</ strong > and < strong className = "text-foreground" > RPC</ strong > { ' ' }
78
+ services
79
+ </ p >
80
+ </ div >
81
+ </ div >
75
82
</ section >
76
83
77
- < section className = "grid grid-cols-12 gap-6" >
78
- < div className = "col-span-full" >
79
- < LatestBlocks latestBlocks = { latestBlocks } />
80
- </ div >
81
- < div className = "col-span-full lg:col-span-8" >
82
- < LatestTransactions latestTransactions = { latestTransactions } />
83
- </ div >
84
- < div className = "col-span-full lg:col-span-4" >
85
- < LatestExtrinsics latestExtrinsics = { latestExtrinsics } />
86
- </ div >
84
+ < section className = "col-span-2 grid grid-cols-1 gap-px overflow-hidden rounded-[16px] bg-secondary md:grid-cols-2 xl:grid-cols-4" >
85
+ { stats . map ( ( { icon : Icon , ...stat } , i ) => (
86
+ < div key = { i } className = "flex flex-col gap-2 bg-white p-4 dark:bg-black md:gap-3 md:p-6" >
87
+ < div className = "flex items-center gap-2 text-muted-foreground" >
88
+ < Icon className = "size-5" />
89
+ < span className = "text-xs font-bold uppercase" > { stat . title } </ span >
90
+ </ div >
91
+ < div className = "text-2xl font-semibold" >
92
+ { stat ?. title === 'Target Block Time' ? (
93
+ < TargetTimeCountdown />
94
+ ) : (
95
+ formatNumber ( typeof stat . value === 'string' ? Number ( stat . value ) : stat . value )
96
+ ) }
97
+ </ div >
98
+ </ div >
99
+ ) ) }
87
100
</ section >
101
+
102
+ < div className = "col-span-2 xl:col-span-1" >
103
+ < LatestBlocks latestBlocks = { latestBlocks } />
104
+ </ div >
105
+
106
+ < div className = "col-span-2 xl:col-span-1" >
107
+ < LatestExtrinsics latestExtrinsics = { latestExtrinsics } />
108
+ </ div >
109
+
110
+ < div className = "col-span-2" >
111
+ < LatestTransactions latestTransactions = { latestTransactions } />
112
+ </ div >
88
113
</ div >
89
- </ Container >
114
+ </ div >
90
115
) ;
91
116
}
0 commit comments