11import type React from "react" ;
2+ import { useEffect , useState } from "react" ;
3+ import { getEnabledNetworks } from "../../../config/networks" ;
4+ import NetworkIcon from "../../common/NetworkIcon" ;
5+
6+ interface GitHubStats {
7+ commits : number | null ;
8+ contributors : number | null ;
9+ }
210
311const About : React . FC = ( ) => {
412 const appVersion = process . env . REACT_APP_VERSION || "0.1.0" ;
513 const commitHash = process . env . REACT_APP_COMMIT_HASH || "development" ;
614 const formattedCommitHash = commitHash . length > 7 ? commitHash . substring ( 0 , 7 ) : commitHash ;
715
16+ const [ githubStats , setGithubStats ] = useState < GitHubStats > ( {
17+ commits : null ,
18+ contributors : null ,
19+ } ) ;
20+
21+ useEffect ( ( ) => {
22+ const fetchGitHubStats = async ( ) => {
23+ try {
24+ // Fetch contributors count
25+ const contributorsRes = await fetch (
26+ "https://api.github.com/repos/openscan-explorer/explorer/contributors?per_page=1" ,
27+ ) ;
28+ if ( contributorsRes . ok ) {
29+ const linkHeader = contributorsRes . headers . get ( "Link" ) ;
30+ if ( linkHeader ) {
31+ const match = linkHeader . match ( / p a g e = ( \d + ) > ; r e l = " l a s t " / ) ;
32+ const lastPage = match ?. [ 1 ] ;
33+ if ( lastPage ) {
34+ setGithubStats ( ( prev ) => ( { ...prev , contributors : parseInt ( lastPage , 10 ) } ) ) ;
35+ }
36+ } else {
37+ const contributors = await contributorsRes . json ( ) ;
38+ setGithubStats ( ( prev ) => ( { ...prev , contributors : contributors . length } ) ) ;
39+ }
40+ }
41+
42+ // Fetch commit count from default branch
43+ const repoRes = await fetch (
44+ "https://api.github.com/repos/openscan-explorer/explorer/commits?per_page=1" ,
45+ ) ;
46+ if ( repoRes . ok ) {
47+ const linkHeader = repoRes . headers . get ( "Link" ) ;
48+ if ( linkHeader ) {
49+ const match = linkHeader . match ( / p a g e = ( \d + ) > ; r e l = " l a s t " / ) ;
50+ const lastPage = match ?. [ 1 ] ;
51+ if ( lastPage ) {
52+ setGithubStats ( ( prev ) => ( { ...prev , commits : parseInt ( lastPage , 10 ) } ) ) ;
53+ }
54+ }
55+ }
56+ } catch ( error ) {
57+ console . error ( "Failed to fetch GitHub stats:" , error ) ;
58+ }
59+ } ;
60+
61+ fetchGitHubStats ( ) ;
62+ } , [ ] ) ;
63+
64+ const visionCommitments = [
65+ {
66+ title : "Trusted Open-Source Alternative" ,
67+ description :
68+ "To be recognised as the most trusted and best alternative to existing, centralised explorer services." ,
69+ } ,
70+ {
71+ title : "Open Standard Adoption" ,
72+ description :
73+ "To serve as a ubiquitous open standard, readily adopted by major wallets, dApps, and blockchain networks." ,
74+ } ,
75+ {
76+ title : "Lean and Transparent Team" ,
77+ description :
78+ "To maintain a small, focused, high-quality core team operating with complete financial and operational transparency." ,
79+ } ,
80+ {
81+ title : "Growth over Extraction" ,
82+ description :
83+ "To ensure all generated revenue is reinvested solely for the platform's continuous development and growth." ,
84+ } ,
85+ ] ;
86+
87+ const corePrinciples = [
88+ {
89+ icon : "👤" ,
90+ title : "User-First Mandate" ,
91+ description :
92+ "The platform is permanently free, fully open, and completely transparent for all end-users." ,
93+ } ,
94+ {
95+ icon : "🔒" ,
96+ title : "Privacy & Experience" ,
97+ description : "No invasive advertising, trackers, or hidden user-data harvesting." ,
98+ } ,
99+ {
100+ icon : "📖" ,
101+ title : "Open-Source & Auditable" ,
102+ description :
103+ "The entire codebase is publicly available, auditable, and encourages community contribution." ,
104+ } ,
105+ {
106+ icon : "🌱" ,
107+ title : "Organic Growth" ,
108+ description :
109+ "Success is driven by technical excellence, accessibility, trustworthiness, and organic adoption." ,
110+ } ,
111+ {
112+ icon : "🏛️" ,
113+ title : "Infrastructure as a Public Good" ,
114+ description :
115+ "The decentralised ecosystem thrives when core infrastructure is free, accessible, and neutral." ,
116+ } ,
117+ ] ;
118+
119+ const features = [
120+ {
121+ title : "Multi-Chain Support" ,
122+ description :
123+ "Explore Ethereum Mainnet, Sepolia, Arbitrum One, Optimism, Base, and local development networks." ,
124+ } ,
125+ {
126+ title : "Block Explorer" ,
127+ description :
128+ "View detailed information about blocks, transactions, and addresses across all supported chains." ,
129+ } ,
130+ {
131+ title : "Contract Verification" ,
132+ description :
133+ "Integration with Sourcify API to display verified contract source code, ABI, and metadata." ,
134+ } ,
135+ {
136+ title : "Real-Time Data" ,
137+ description : "Live network statistics, gas prices, and blockchain data for supported chains." ,
138+ } ,
139+ {
140+ title : "Modern UI" ,
141+ description :
142+ "Clean, responsive interface with dark theme optimized for blockchain data visualization." ,
143+ } ,
144+ {
145+ title : "Fast Performance" ,
146+ description :
147+ "Efficient caching and lazy loading for quick data access and smooth user experience." ,
148+ } ,
149+ ] ;
150+
151+ const networks = getEnabledNetworks ( ) ;
152+
8153 return (
9154 < div className = "container-medium page-container-padded" >
10155 < div className = "page-card" >
11156 { /* Header */ }
12157 < div className = "text-center mb-large" >
13- < h1 className = "page-heading" > About OpenScan</ h1 >
14- < p className = "page-subtitle" >
15- An open-source, lightweight, multi-chain blockchain explorer
158+ < h1 className = "page-heading" > OpenScan</ h1 >
159+ < p className = "page-subtitle" > A Decentralised Explorer</ p >
160+ </ div >
161+
162+ { /* Vision Section */ }
163+ < div className = "about-section" >
164+ < p className = "about-section-intro" >
165+ Our long-term vision is to establish the most accessible, neutral, and transparent
166+ blockchain exploration infrastructure globally—one that is{ " " }
167+ < strong > not governed by private companies</ strong > and sustained by ethical,
168+ non-extractive revenue models.
16169 </ p >
170+ < div className = "data-grid-2 mb-large" >
171+ { visionCommitments . map ( ( item ) => (
172+ < div key = { item . title } className = "feature-card text-center" >
173+ < h3 className = "feature-card-title" > { item . title } </ h3 >
174+ < p className = "feature-card-description" > { item . description } </ p >
175+ </ div >
176+ ) ) }
177+ </ div >
17178 </ div >
18179
19- { /* Version Info Card */ }
20- < div className = "version-card" >
21- < div className = "version-card-grid" >
22- < div className = "version-info-item" >
23- < div className = "version-info-label" > Version</ div >
24- < div className = "version-info-value" > { appVersion } </ div >
25- </ div >
26- < div className = "version-info-item" >
27- < div className = "version-info-label" > Commit</ div >
28- < div className = "version-info-value-mono" > { formattedCommitHash } </ div >
29- </ div >
180+ { /* Core Principles Section */ }
181+ < div className = "about-section" >
182+ < h2 className = "page-heading-large text-center" > Core Principles</ h2 >
183+ < p className = "about-section-intro" >
184+ OpenScan is not merely a product; it is a declaration of principles for public
185+ blockchain infrastructure.
186+ </ p >
187+ < div className = "principles-list" >
188+ { corePrinciples . map ( ( principle ) => (
189+ < div key = { principle . title } className = "principle-item" >
190+ < span className = "principle-icon" > { principle . icon } </ span >
191+ < div className = "principle-content" >
192+ < h4 className = "principle-title" > { principle . title } </ h4 >
193+ < p className = "principle-description" > { principle . description } </ p >
194+ </ div >
195+ </ div >
196+ ) ) }
30197 </ div >
31198 </ div >
32199
33200 { /* Features Grid */ }
34201 < h2 className = "page-heading-large text-center" > Features</ h2 >
35-
36- < div className = "data-grid-3 mb-large" >
37- { [
38- {
39- title : "🌐 Multi-Chain Support" ,
40- description :
41- "Explore Ethereum Mainnet, Sepolia, Arbitrum One, Optimism, and local development networks." ,
42- } ,
43- {
44- title : "🔍 Block Explorer" ,
45- description :
46- "View detailed information about blocks, transactions, and addresses across all supported chains." ,
47- } ,
48- {
49- title : "✅ Contract Verification" ,
50- description :
51- "Integration with Sourcify API to display verified contract source code, ABI, and metadata." ,
52- } ,
53- {
54- title : "📊 Real-Time Data" ,
55- description :
56- "Live network statistics, gas prices, and mempool monitoring for supported chains." ,
57- } ,
58- {
59- title : "🎨 Modern UI" ,
60- description :
61- "Clean, responsive interface with dark theme optimized for blockchain data visualization." ,
62- } ,
63- {
64- title : "⚡ Fast Performance" ,
65- description :
66- "Efficient caching and lazy loading for quick data access and smooth user experience." ,
67- } ,
68- ] . map ( ( feature ) => (
69- < div key = { feature . title } className = "feature-card" >
202+ < div className = "data-grid-3-centered mb-large" >
203+ { features . map ( ( feature ) => (
204+ < div key = { feature . title } className = "feature-card text-center" >
70205 < h3 className = "feature-card-title" > { feature . title } </ h3 >
71206 < p className = "feature-card-description" > { feature . description } </ p >
72207 </ div >
@@ -75,20 +210,12 @@ const About: React.FC = () => {
75210
76211 { /* Supported Networks */ }
77212 < h2 className = "page-heading-large text-center" > Supported Networks</ h2 >
78-
79- < div className = "data-grid-3 mb-large" >
80- { [
81- { name : "Ethereum Mainnet" , chainId : "1" , icon : "⟠" } ,
82- { name : "Sepolia Testnet" , chainId : "11155111" , icon : "🧪" } ,
83- { name : "Arbitrum One" , chainId : "42161" , icon : "🔷" } ,
84- { name : "Optimism" , chainId : "10" , icon : "🔴" } ,
85- { name : "Localhost" , chainId : "31337" , icon : "💻" } ,
86- ] . map ( ( network ) => (
87- < div key = { network . chainId } className = "network-item" >
88- < div className = "network-icon-box" > { network . icon } </ div >
213+ < div className = "data-grid-3-centered mb-large" >
214+ { networks . map ( ( network ) => (
215+ < div key = { network . networkId } className = "network-item text-center" >
89216 < div className = "network-info" >
217+ < NetworkIcon network = { network } size = { 32 } />
90218 < div className = "network-name" > { network . name } </ div >
91- < div className = "network-chain-id" > Chain ID: { network . chainId } </ div >
92219 </ div >
93220 </ div >
94221 ) ) }
@@ -98,23 +225,51 @@ const About: React.FC = () => {
98225 < div className = "text-center mb-large opensource-card" >
99226 < h2 className = "opensource-title" > Open Source</ h2 >
100227 < p className = "opensource-description" >
101- OpenScan is free and open source software. Contributions, issues, and feature requests
102- are welcome!
228+ OpenScan is free and open source software. The entire codebase is publicly available,
229+ auditable, and welcomes community contribution.
103230 </ p >
104231 < a
105232 href = "https://github.com/openscan-explorer/explorer"
106233 target = "_blank"
107234 rel = "noopener noreferrer"
108235 className = "button-primary-inline"
109236 >
110- View on GitHub ↗
237+ View on GitHub
111238 </ a >
112239 </ div >
113240
241+ { /* Version Info Card */ }
242+ < div className = "version-card" >
243+ < div className = "version-card-grid-4 text-center" >
244+ < div className = "version-info-item" >
245+ < div className = "version-info-label" > Version</ div >
246+ < div className = "version-info-value" > { appVersion } </ div >
247+ </ div >
248+ < div className = "version-info-item" >
249+ < div className = "version-info-label" > Commit</ div >
250+ < div className = "version-info-value-mono" > { formattedCommitHash } </ div >
251+ </ div >
252+ < div className = "version-info-item" >
253+ < div className = "version-info-label" > Total Commits</ div >
254+ < div className = "version-info-value" >
255+ { githubStats . commits !== null ? githubStats . commits . toLocaleString ( ) : "—" }
256+ </ div >
257+ </ div >
258+ < div className = "version-info-item" >
259+ < div className = "version-info-label" > Contributors</ div >
260+ < div className = "version-info-value" >
261+ { githubStats . contributors !== null ? githubStats . contributors : "—" }
262+ </ div >
263+ </ div >
264+ </ div >
265+ </ div >
266+
114267 { /* License */ }
115268 < div className = "text-center license-footer" >
116269 < p > OpenScan is licensed under the MIT License</ p >
117- < p className = "license-footer-spacing" > Built with ❤️ for the Ethereum community</ p >
270+ < p className = "license-footer-spacing" >
271+ Built with purpose for the decentralised ecosystem
272+ </ p >
118273 </ div >
119274 </ div >
120275 </ div >
0 commit comments