Skip to content

Commit ec92941

Browse files
committed
Add app cards for block explorers
1 parent c0c5cde commit ec92941

File tree

4 files changed

+82
-56
lines changed

4 files changed

+82
-56
lines changed

content/learn/explorers.mdx

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ keywords: ['sei blockchain explorer', 'transaction tracking', 'block analysis',
66

77
import { Tabs } from 'nextra/components';
88
import { Callout } from 'nextra/components';
9+
import AppCardV2 from '../../src/components/AppCard/AppCard.v2';
10+
import ecosystemData from '../../src/data/ecosystem-cache.json';
11+
12+
export const getLogoUrl = (name) => {
13+
const app = ecosystemData.data.find((a) => a.fieldData.name.toLowerCase() === name.toLowerCase());
14+
return app?.fieldData?.logo?.url;
15+
};
916

1017
# Block Explorers
1118

@@ -43,21 +50,21 @@ with the network including:
4350

4451
## Sei Explorers
4552

46-
<Tabs items={[`testnet (atlantic-2)`, `mainnet (pacific-1)`]}>
53+
<Tabs items={[`mainnet (pacific-1)`, `testnet (atlantic-2)`]}>
4754
<Tabs.Tab>
48-
49-
- [Seiscan](https://testnet.seiscan.io)
50-
- [Seitrace](https://testnet.seitrace.com)
51-
- [Seistream](https://testnet.seistream.app/)
52-
- [NG Explorer](https://testnet.sei.explorers.guru)
53-
55+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mt-6">
56+
<AppCardV2 title="Seiscan" logoUrl={getLogoUrl('Seiscan')} href="https://seiscan.io" description="A user-friendly block explorer for the Sei Pacific-1 mainnet." />
57+
<AppCardV2 title="Seitrace" logoUrl={getLogoUrl('SeiTrace')} href="https://seitrace.com" description="Advanced blockchain explorer and analytics platform for Sei mainnet." />
58+
<AppCardV2 title="Seistream" logoUrl={getLogoUrl('Seistream')} href="https://seistream.app/" description="Real-time transaction streaming and monitoring tool for Sei mainnet." />
59+
<AppCardV2 title="NG Explorer" logoUrl={getLogoUrl('Nodes Guru')} href="https://sei.explorers.guru" description="Comprehensive blockchain explorer provided by Nodes Guru for Sei mainnet." />
60+
</div>
5461
</Tabs.Tab>
5562
<Tabs.Tab>
56-
57-
- [Seiscan](https://seiscan.io)
58-
- [Seitrace](https://seitrace.com)
59-
- [Seistream](https://seistream.app/)
60-
- [NG Explorer](https://sei.explorers.guru)
61-
63+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mt-6">
64+
<AppCardV2 title="Seiscan" logoUrl={getLogoUrl('Seiscan')} href="https://testnet.seiscan.io" description="A user-friendly block explorer for the Sei Atlantic-2 testnet." />
65+
<AppCardV2 title="Seitrace" logoUrl={getLogoUrl('SeiTrace')} href="https://testnet.seitrace.com" description="Advanced blockchain explorer and analytics platform for Sei testnet." />
66+
<AppCardV2 title="Seistream" logoUrl={getLogoUrl('Seistream')} href="https://testnet.seistream.app/" description="Real-time transaction streaming and monitoring tool for Sei testnet." />
67+
<AppCardV2 title="NG Explorer" logoUrl={getLogoUrl('Nodes Guru')} href="https://testnet.sei.explorers.guru" description="Comprehensive blockchain explorer provided by Nodes Guru for Sei testnet." />
68+
</div>
6269
</Tabs.Tab>
6370
</Tabs>

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"@types/react": "^19.2.7",
4949
"@types/react-dom": "^19.2.3",
5050
"autoprefixer": "^10.4.23",
51+
"baseline-browser-mapping": "^2.9.14",
5152
"concurrently": "^9.1.2",
5253
"cssnano": "^6.1.2",
5354
"globby": "^14.1.0",

src/components/AppCard/AppCard.v2.tsx

Lines changed: 56 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,91 @@
11
import Image from 'next/image';
2-
import { IconExternalLink } from '@tabler/icons-react';
2+
import { IconExternalLink, IconWorld } from '@tabler/icons-react';
33
import { EcosystemFieldData } from '../../data/ecosystemData';
44

55
interface AppCardV2Props {
6-
app: { fieldData: EcosystemFieldData };
6+
app?: { fieldData: EcosystemFieldData };
7+
title?: string;
8+
description?: string;
9+
href?: string;
10+
icon?: React.ReactNode;
11+
logoUrl?: string;
712
}
813

9-
export default function AppCardV2({ app }: AppCardV2Props) {
10-
if (!app) return null;
14+
export default function AppCardV2({ app, title, description, href, icon, logoUrl: logoUrlOverride }: AppCardV2Props) {
15+
if (!app && !title) return null;
1116

12-
const { name, logo, link, 'short-description': desc, 'integration-guide-link': integration, priority } = app.fieldData;
17+
let name = title;
18+
let desc = description;
19+
let finalIntegrationLink = href;
20+
let logoUrl: string | undefined = logoUrlOverride;
21+
let linkText = 'Visit Website';
1322

14-
const integrationGuideOverrides: Record<string, string> = {
15-
'The Graph': '/evm/indexer-providers/the-graph',
16-
'Covalent': '/evm/indexer-providers/goldrush',
17-
'Goldsky': '/evm/indexer-providers/goldsky',
18-
'Alchemy': '/evm/indexer-providers/alchemy',
19-
'Envio': 'https://docs.envio.dev/docs/HyperIndex/getting-started',
20-
'Sonarverse': 'https://docs.sonarplatform.io/',
21-
'Ormi': 'https://docs.orai.io/developer-guides/overview/subquery'
22-
};
23+
if (app) {
24+
const { name: appName, logo, link, 'short-description': appDesc, 'integration-guide-link': integration } = app.fieldData;
25+
name = appName;
26+
desc = appDesc;
27+
logoUrl = logoUrlOverride || logo?.url;
2328

24-
const finalIntegrationLink = integrationGuideOverrides[name] || integration;
25-
const isExternalLink = finalIntegrationLink && !finalIntegrationLink.startsWith('/');
26-
const linkText = isExternalLink ? 'Documentation' : 'Integration Guide';
29+
const integrationGuideOverrides: Record<string, string> = {
30+
'The Graph': '/evm/indexer-providers/the-graph',
31+
Covalent: '/evm/indexer-providers/goldrush',
32+
Goldsky: '/evm/indexer-providers/goldsky',
33+
Alchemy: '/evm/indexer-providers/alchemy'
34+
};
35+
36+
finalIntegrationLink = integrationGuideOverrides[appName] || integration;
37+
const isExternalLinkData = finalIntegrationLink && !finalIntegrationLink.startsWith('/');
38+
linkText = isExternalLinkData ? 'Documentation' : 'Integration Guide';
39+
40+
if (!logoUrl) return null;
41+
}
2742

28-
if (!logo) return null;
43+
const isExternalLink = finalIntegrationLink && !finalIntegrationLink.startsWith('/');
2944

3045
return (
3146
<div className='group relative overflow-hidden transition-all duration-300 ease-out transform-gpu will-change-transform hover:scale-[1.02] hover:shadow-xl hover:shadow-black/10 dark:hover:shadow-black/30 rounded-xl border backdrop-blur-sm bg-neutral-50/80 dark:bg-neutral-900/80 border-neutral-200/50 dark:border-neutral-800/50 hover:bg-white dark:hover:bg-neutral-900 hover:border-neutral-300 dark:hover:border-neutral-700 p-5 h-full flex flex-col'>
3247
<div className='absolute inset-0 opacity-0 group-hover:opacity-100 transition-opacity duration-500 bg-gradient-to-br from-white/10 via-transparent to-transparent dark:from-white/5 dark:via-transparent dark:to-transparent pointer-events-none rounded-xl' />
33-
48+
3449
<div className='absolute inset-0 rounded-xl opacity-0 group-hover:opacity-100 transition-all duration-700 bg-gradient-to-r from-red-900/15 via-red-800/10 to-red-900/15 dark:from-red-800/20 dark:via-red-700/15 dark:to-red-800/20 blur-sm -z-10 transform scale-105' />
35-
50+
3651
<div className='flex flex-col gap-4 relative z-10'>
3752
<div className='flex items-start justify-between'>
3853
<figure className='w-12 h-12 rounded-lg overflow-hidden flex-shrink-0 bg-neutral-200/50 dark:bg-neutral-800/50 group-hover:bg-red-900/10 dark:group-hover:bg-red-800/20 transition-all duration-300 group-hover:scale-110 group-hover:rotate-3 flex items-center justify-center'>
39-
<Image
40-
src={logo.url}
41-
alt={name}
42-
width={48}
43-
height={48}
44-
className='object-cover w-full h-full transform transition-all duration-300 group-hover:scale-110'
45-
/>
54+
{logoUrl ? (
55+
<Image
56+
src={logoUrl}
57+
alt={name || ''}
58+
width={48}
59+
height={48}
60+
className='object-cover w-full h-full transform transition-all duration-300 group-hover:scale-110'
61+
/>
62+
) : (
63+
icon || <IconWorld className='text-neutral-500 group-hover:text-red-600 transition-colors duration-300' size={24} />
64+
)}
4665
</figure>
4766
</div>
48-
67+
4968
<div className='flex flex-col gap-2 flex-grow'>
50-
<h3 className='text-base font-bold text-neutral-800 dark:text-neutral-200 group-hover:text-red-800 dark:group-hover:text-red-300 transition-colors duration-300 leading-tight'>{name}</h3>
51-
{desc && (
52-
<p className='text-sm text-neutral-600 dark:text-neutral-400 leading-relaxed line-clamp-2 flex-grow'>
53-
{desc}
54-
</p>
55-
)}
69+
<h3 className='text-base font-bold text-neutral-800 dark:text-neutral-200 group-hover:text-red-800 dark:group-hover:text-red-300 transition-colors duration-300 leading-tight'>
70+
{name}
71+
</h3>
72+
{desc && <p className='text-sm text-neutral-600 dark:text-neutral-400 leading-relaxed line-clamp-2 flex-grow'>{desc}</p>}
5673
</div>
57-
74+
5875
{finalIntegrationLink && (
5976
<div className='flex items-center mt-auto pt-2'>
6077
<a
6178
href={finalIntegrationLink}
6279
target={isExternalLink ? '_blank' : '_self'}
6380
rel={isExternalLink ? 'noopener noreferrer' : undefined}
64-
className='inline-flex items-center gap-1.5 text-sm font-medium text-red-800 dark:text-red-300 hover:text-red-900 dark:hover:text-red-200 transition-colors duration-200 group/link'
65-
>
81+
className='inline-flex items-center gap-1.5 text-sm font-medium text-red-800 dark:text-red-300 hover:text-red-900 dark:hover:text-red-200 transition-colors duration-200 group/link'>
6682
<span>{linkText}</span>
67-
<IconExternalLink
68-
size={14}
69-
className="transition-all duration-300 group-hover/link:ml-1 group-hover/link:scale-110"
70-
/>
83+
<IconExternalLink size={14} className='transition-all duration-300 group-hover/link:ml-1 group-hover/link:scale-110' />
7184
</a>
7285
</div>
7386
)}
74-
75-
<div className="w-full h-0.5 bg-gradient-to-r from-transparent via-red-800/20 dark:via-red-300/20 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
87+
88+
<div className='w-full h-0.5 bg-gradient-to-r from-transparent via-red-800/20 dark:via-red-300/20 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300' />
7689
</div>
7790
</div>
7891
);

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3103,6 +3103,11 @@ baseline-browser-mapping@^2.9.0:
31033103
resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.10.tgz#099221e89b30ec784675af076fbd4a93e58b53c3"
31043104
integrity sha512-2VIKvDx8Z1a9rTB2eCkdPE5nSe28XnA+qivGnWHoB40hMMt/h1hSz0960Zqsn6ZyxWXUie0EBdElKv8may20AA==
31053105

3106+
baseline-browser-mapping@^2.9.14:
3107+
version "2.9.14"
3108+
resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.14.tgz#3b6af0bc032445bca04de58caa9a87cfe921cbb3"
3109+
integrity sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==
3110+
31063111
basic-ftp@^5.0.2:
31073112
version "5.0.5"
31083113
resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.0.5.tgz#14a474f5fffecca1f4f406f1c26b18f800225ac0"

0 commit comments

Comments
 (0)