Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved Ecosystem app handling #129

Merged
merged 12 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions components/AppCard/AppCard.v2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { ExternalLinkIcon } from 'lucide-react';
import Image from 'next/image';
import { EcosystemItem } from '../../data/ecosystemData';

interface AppCardProps {
app: EcosystemItem;
}
const AppCardV2 = ({ app }: AppCardProps) => {
if (!app) return null;
const fields = app.fieldData;
const { name, logo, link, 'integration-guide-link': integration, 'short-description': shortDescription } = fields;
return (
<div className='group flex flex-col'>
<div className='border dark:border-gray-800 rounded-lg overflow-hidden flex flex-row lg:flex-col grow h-ull'>
<div className='relative overflow-hidden grid place-items-center aspect-square border-r lg:border-b lg:border-r-0 dark:border-gray-800'>
<a href={link} rel='noopener noreferrer' target='_blank' className='group'>
<Image src={logo.url} alt={logo.alt} width={300} height={300} className='transition-all group-hover:scale-[1.15]' />
</a>
</div>
<div className='px-3 pt-2 pb-3 bg-gray-100 dark:bg-gray-800 w-full flex flex-col grow space-y-1'>
<h3 className='text-lg font-semibold inline-flex items-center gap-2' title={name}>
{name}
</h3>
{shortDescription && (
<p className='opacity-75 text-sm line-clamp-4' title={shortDescription}>
{shortDescription}
</p>
)}
{integration && (
<a
href={integration}
rel='noopener noreferrer'
target='_blank'
className='inline-flex items-center gap-2 bg-black text-white dark:bg-white dark:text-black px-3 py-1 self-start rounded-lg mt-2 text-sm font-medium tracking-tight'>
Integration <ExternalLinkIcon className='inline-block w-3 h-4 hover:underline' />
</a>
)}
</div>
</div>
</div>
);
};

export default AppCardV2;
33 changes: 33 additions & 0 deletions components/AppCard/AppCardsGridCategory.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useEffect, useState } from 'react';
import { EcosystemDocsCategory, EcosystemResponse, getSeiEcosystemAppByCategory } from '../../data/ecosystemData';
import { EcosystemSkeleton } from '../EcosystemMap';
import AppCardV2 from './AppCard.v2';

function AppCardsGridCategory({ category }: { category: EcosystemDocsCategory }) {
const [apps, setApps] = useState<EcosystemResponse['data']>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
getSeiEcosystemAppByCategory(category).then((res) => {
const data = res.data;
setApps(data);
setLoading(false);
});
}, [category]);
if (!apps || loading) return <EcosystemSkeleton />;
if (apps.length === 0) return null;
return (
<div>
<div className='grid grid-cols-1 lg:grid-cols-4 gap-4 my-4'>
{apps.map((app) => (
<AppCardV2 key={app.id} app={app} />
))}
</div>
<small className='opacity-75'>
Projects listed here are developed by the Sei community. Inclusion on this site does not constitute endorsement. For questions related to each, please
contact the project directly.
</small>
</div>
);
}

export default AppCardsGridCategory;
3 changes: 3 additions & 0 deletions components/AppCard/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export { default as AppCard } from './AppCard';
export { default as AppCardV2 } from './AppCard.v2';
export { default as AppCardsGrid } from './AppCardsGrid';
export { default as AppCardsGridCategory } from './AppCardsGridCategory';

4 changes: 1 addition & 3 deletions components/EcosystemMap/EcosystemDynamicSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ const EcosystemDynamicSection = ({ category }: { category: string }) => {
if (!apps || loading) return <EcosystemSkeleton />

// filter out apps that don't have a categorie
const filteredApps = apps.filter(
(app) => app.fieldData.categorie !== undefined
)
const filteredApps = apps.filter((app) => app.fieldData.categorie !== undefined && app.fieldData['categorie-2'] !== undefined);

const appsByCategory = (category: string) =>
filteredApps.filter((app) => app.fieldData.categorie === category)
Expand Down
60 changes: 25 additions & 35 deletions components/EcosystemMap/EcosystemSection.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,27 @@
import { ExternalLinkIcon } from 'lucide-react'
import _ from 'lodash';
import { EcosystemItem } from '../../data/ecosystemData';
import AppCardV2 from '../AppCard/AppCard.v2';

const EcosystemSection = ({ apps }: { apps: any[] }) => {
return (
<div className="grid grid-cols-2 lg:grid-cols-4 xl:grid-cols-5 gap-6 mt-8">
{apps.map((app, index) => {
const logo = app.fieldData.logo
return (
<a
href={`${app.fieldData.link}?utm_source=sei-docs`}
key={index}
target="_blank"
className="flex flex-col border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden hover:opacity-80 transition-all relative group"
>
<div className="bg-black text-white p-2 absolute rounded-md -right-8 -top-8 group-hover:top-1 group-hover:right-1 transition-all">
<ExternalLinkIcon className="h-4 w-4" />
</div>
{logo && (
<div className="flex flex-col">
<img
src={logo.url}
alt={logo.name}
className="h-full w-full aspect-square"
/>
<div className="truncate bg-gray-100 dark:bg-gray-800 p-4 font-semibold">
{app.fieldData.name}
</div>
</div>
)}
</a>
)
})}
</div>
)
}
const EcosystemSection = ({ apps }: { apps: EcosystemItem[] }) => {
const groupedApps = _.groupBy(apps, (app) => app.fieldData['categorie-2']);
const keys = Object.keys(groupedApps);

export default EcosystemSection
return (
<section>
{keys.map((key) => {
return (
<div key={key} className='flex flex-col gap-4 mt-12'>
<h2 className='text-2xl font-semibold'>{key}</h2>
<div className='grid grid-cols-1 lg:grid-cols-4 gap-6'>
{groupedApps[key].map((app) => (
<AppCardV2 key={app.id} app={app} />
))}
</div>
</div>
);
})}
</section>
);
};

export default EcosystemSection;
31 changes: 28 additions & 3 deletions data/ecosystemData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ export type EcosystemFieldData = {
link: string;
'sei-only': boolean;
name: string;
slug: string;
logo: EcosystemAppLogoType;
slug: string;
categorie: string;
'docs-category': string;
'integration-guide-link': string;
'short-description': string;
'categorie-2': string;
};

export type EcosystemItem = {
Expand Down Expand Up @@ -45,10 +49,31 @@ export async function getSeiEcosystemAppsData(): Promise<EcosystemResponse> {
}

const data = await response.json();
console.log('Sei Ecosystem data', data);
return data;
} catch (error) {
console.error('Failed to fetch data:', error);
return { data: [] };
}
}

export type EcosystemDocsCategory = 'indexer' | 'explorer' | 'wallet' | 'centralized-exchange' | 'rpc-provider' | 'faucet' | 'launchpad' | 'oracle' | 'bridge';

export async function getSeiEcosystemAppByCategory(category: EcosystemDocsCategory): Promise<EcosystemResponse> {
const url = `https://app-api.seinetwork.io/webflow/ecosystem/docs/${category}`;
const headers = { Accept: 'application/json' };

try {
const response = await fetch(url, {
method: 'GET',
headers
});

if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}

const data = await response.json();
return data;
} catch (error) {
return { data: [] };
}
}
5 changes: 5 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ module.exports = withNextra({
protocol: 'https',
hostname: 'cdn.sei.io',
pathname: '**'
},
{
protocol: 'https',
hostname: 'cdn.prod.website-files.com',
pathname: '/65cb43fecf24523357feada9/**'
}
]
}
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@types/styled-components": "^5.1.34",
"@types/underscore": "^1.11.15",
"autoprefixer": "^10.4.17",
"lodash": "^4.17.21",
"postcss": "^8.4.38",
"postcss-preset-mantine": "^1.15.0",
"postcss-simple-vars": "^7.0.1",
Expand Down
6 changes: 2 additions & 4 deletions pages/dev-ecosystem-providers/bridges.mdx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { AppCardsGrid } from "../../components";
import { AppCardsGridCategory } from "../../components";
import { Tag } from "../../data/appData";

# Bridges

Bridges facilitate cross-chain transfers and interoperability between different blockchains. Key bridges for Sei are:

## Apps

<AppCardsGrid tags={[Tag.BRIDGE]} />
<AppCardsGridCategory category="bridge" />

## IBC (Inter-Blockchain Communication)

Expand Down
4 changes: 4 additions & 0 deletions pages/dev-ecosystem-providers/centralized-exchanges.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { AppCardsGrid } from "../../components";
import { AppCardsGridCategory } from "../../components";

import { Tag } from "../../data/appData";

# Centralized Exchanges

Centralized exchanges facilitate seamless trading of **Sei tokens**. Some of the key exchanges supporting Sei include:

<AppCardsGridCategory category="centralized%20exchange" />

<AppCardsGrid tags={[Tag.CEX]} />
4 changes: 0 additions & 4 deletions pages/dev-ecosystem-providers/ecosystem-map.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ Sei Ecosystem is the epicenter of technological advancement, bringing together c

<EcosystemDynamicSection category="Consumer Apps" />

## AI

<EcosystemDynamicSection category="AI" />

## Infastructure

<EcosystemDynamicSection category="Infrastructure" />
Expand Down
21 changes: 3 additions & 18 deletions pages/dev-ecosystem-providers/indexers/indexers.mdx
Original file line number Diff line number Diff line change
@@ -1,22 +1,7 @@
import { AppCardsGridCategory } from "../../../components";

# Indexers

Indexers collect and organize blockchain data, making it easier to query and analyze. Key indexers for Sei include:

## **Flipside**

Provides detailed blockchain analytics and insights.

- [Flipside](https://flipsidecrypto.xyz/)

## **The Graph (EVM only)**

Allows for querying blockchain data using GraphQL.

- [Quick Start Guide](/dev-ecosystem-providers/indexers/the-graph)
- [The Graph](https://thegraph.com/)

## **SubQuery**

SubQuery is a fast, flexible, and reliable open-source data decentralised infrastructure network, providing both RPC and indexed data to consumers around the world.

- [SubQuery Docs](https://academy.subquery.network/indexer/quickstart/quickstart_chains/cosmos-sei.html)
<AppCardsGridCategory category="indexer" />
4 changes: 2 additions & 2 deletions pages/dev-ecosystem-providers/nfts.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { AppCardsGrid } from "../../components";
import { AppCardsGridCategory } from "../../components";
import { Tag } from "../../data/appData";

# NFT’s

The following providers provide helpful tools for creating and managing NFT projects on Sei.

<AppCardsGrid tags={[Tag.NFT]} />
<AppCardsGridCategory category="nft" />
4 changes: 2 additions & 2 deletions pages/dev-ecosystem-providers/oracles.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { AppCardsGrid } from "../../components";
import { AppCardsGridCategory } from "../../components";
import { Tag } from "../../data/appData";

# Oracles

Oracles provide external data to smart contracts, enabling more dynamic and responsive applications. Notable oracles for Sei include:

<AppCardsGrid tags={[Tag.ORACLE]} />
<AppCardsGridCategory category="oracle" />
4 changes: 2 additions & 2 deletions pages/dev-ecosystem-providers/rpc-providers.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { AppCardsGrid } from "../../components";
import { AppCardsGridCategory } from "../../components";
import { Tag } from "../../data/appData";

# RPC Providers

RPC providers offer endpoints for developers to interact with the Sei blockchain, archive nodes, genesis files, and more. Some notable providers include:

<AppCardsGrid tags={[Tag.RPC]} />
<AppCardsGridCategory category="rpc%20provider" />
3 changes: 2 additions & 1 deletion pages/dev-ecosystem-providers/wallets.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { EcosystemDynamicSection } from "../../components";
import { AppCardsGridCategory } from "../../components";

Wallets are essential for managing assets and interacting with the Sei blockchain. There are various types of wallets available, each offering different features and levels of security.

Expand Down Expand Up @@ -33,4 +34,4 @@ There are several other wallets that support the Sei blockchain, mainly generic



<EcosystemDynamicSection category="Wallets" />
<AppCardsGridCategory category="wallet" />
Loading
Loading