Skip to content

Commit

Permalink
Add pages for chains (#136)
Browse files Browse the repository at this point in the history
* Experiment with chain pages

* More progress on chain pages

* Move providers to root

* Add flags and improve styling

* Add gatsby-ssr

* More responsiveness and fixes
  • Loading branch information
FrederikBolding authored Jul 26, 2024
1 parent 96897c2 commit f991fdc
Show file tree
Hide file tree
Showing 15 changed files with 350 additions and 59 deletions.
9 changes: 9 additions & 0 deletions gatsby-browser.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from "react";
import { Web3Provider } from "./src/context/Web3Context";
import { SearchProvider } from "./src/context/SearchContext";

export const wrapRootElement = ({ element }) => (
<SearchProvider>
<Web3Provider>{element}</Web3Provider>
</SearchProvider>
);
2 changes: 2 additions & 0 deletions gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ exports.sourceNodes = async ({
}, Promise.resolve({}));

chains
// Filter out non HTTP(S) RPC URLs
.map((chain) => ({ ...chain, rpc: chain.rpc.filter(rpc => rpc.startsWith('http://') || rpc.startsWith('https://'))}))
.filter((chain) => chain.rpc.length > 0)
.forEach((chain) => {
const icon = chain.icon;
Expand Down
9 changes: 9 additions & 0 deletions gatsby-ssr.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from "react";
import { Web3Provider } from "./src/context/Web3Context";
import { SearchProvider } from "./src/context/SearchContext";

export const wrapRootElement = ({ element }) => (
<SearchProvider>
<Web3Provider>{element}</Web3Provider>
</SearchProvider>
);
99 changes: 55 additions & 44 deletions src/components/Chain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import React, { useContext } from "react";
import { Web3Context } from "../context/Web3Context";
import { ChainData } from "../types/chain";
import { ChainIcon } from "./ChainIcon";
import { Link } from "gatsby";

export const Chain = ({
name,
Expand All @@ -22,55 +23,65 @@ export const Chain = ({
}: ChainData) => {
const { isConnected, handleConnect, handleAddChain } =
useContext(Web3Context);
const handleAddChainClick = () => {

const handleConnectClick = (event: React.MouseEvent) => {
event.preventDefault();
handleConnect();
};

const handleAddChainClick = (event: React.MouseEvent) => {
event.preventDefault();
handleAddChain({ name, chainId, nativeCurrency, ...rest });
};

return (
<Flex
flexDirection="column"
px="5"
py="4"
borderWidth="1px"
rounded="md"
boxShadow="base"
>
<Flex justifyContent="space-between">
<Flex flexDirection="column" minW="200px">
<Flex mb="2">
<Text
fontSize="lg"
fontWeight="semibold"
lineHeight="short"
isTruncated
verticalAlign="middle"
>
{name}
</Text>
<Link to={`/chain/${chainId}`}>
<Flex
flexDirection="column"
px="5"
py="4"
borderWidth="1px"
rounded="md"
boxShadow="base"
>
<Flex justifyContent="space-between">
<Flex flexDirection="column" minW="200px">
<Flex mb="2">
<Text
fontSize="lg"
fontWeight="semibold"
lineHeight="short"
isTruncated
verticalAlign="middle"
>
{name}
</Text>
</Flex>
<StatGroup mb="2">
<Stat>
<StatLabel>Chain ID</StatLabel>
<StatNumber fontSize="md">{chainId}</StatNumber>
</Stat>
<Stat>
<StatLabel>Currency</StatLabel>
<StatNumber fontSize="md">{nativeCurrency.symbol}</StatNumber>
</Stat>
</StatGroup>
</Flex>
<StatGroup mb="2">
<Stat>
<StatLabel>Chain ID</StatLabel>
<StatNumber fontSize="md">{chainId}</StatNumber>
</Stat>
<Stat>
<StatLabel>Currency</StatLabel>
<StatNumber fontSize="md">{nativeCurrency.symbol}</StatNumber>
</Stat>
</StatGroup>
{icon && (
<Flex>
<ChainIcon name={name} icon={icon} />
</Flex>
)}
</Flex>
{icon && (
<Flex>
<ChainIcon name={name} icon={icon} />
</Flex>
)}
<Center mt="auto">
{!isConnected ? (
<Button onClick={handleConnectClick}>Connect</Button>
) : (
<Button onClick={handleAddChainClick}>Add Chain</Button>
)}
</Center>
</Flex>
<Center mt="auto">
{!isConnected ? (
<Button onClick={handleConnect}>Connect Wallet</Button>
) : (
<Button onClick={handleAddChainClick}>Add Chain</Button>
)}
</Center>
</Flex>
</Link>
);
};
4 changes: 2 additions & 2 deletions src/components/ChainIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { GatsbyImage } from "gatsby-plugin-image";
import { ChainData } from "../types/chain";
import { Image } from "@chakra-ui/react";

export const ChainIcon = ({ icon, name }: Pick<ChainData, "icon" | "name">) =>
export const ChainIcon = ({ icon, name, width = "40px" }: Pick<ChainData, "icon" | "name"> & { width?: string; }) =>
icon.childImageSharp ? (
<GatsbyImage
objectFit="scale-down"
image={icon.childImageSharp.gatsbyImageData}
alt={name}
/>
) : (
<Image src={icon.publicURL} width="40px" />
<Image src={icon.publicURL} width={width} />
);
9 changes: 9 additions & 0 deletions src/components/ExternalLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from "react";
import { ExternalLinkIcon } from "@chakra-ui/icons";
import { Link } from "@chakra-ui/react";

export const ExternalLink = ({ href, children }) => (
<Link href={href} isExternal>
{children} <ExternalLinkIcon mx="2px" />
</Link>
);
7 changes: 5 additions & 2 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Search } from "./Search";
import { FaGithub } from "react-icons/fa";
import { AddIcon } from "@chakra-ui/icons";
import { Filters } from "./Filters";
import { Link as GatsbyLink } from "gatsby";

export const Header = ({ showSearch = true, showFilters = true }) => {
const { handleConnect, isConnected, address } = useContext(Web3Context);
Expand All @@ -33,7 +34,9 @@ export const Header = ({ showSearch = true, showFilters = true }) => {
width="100%"
zIndex="sticky"
>
<Heading>Chainlist</Heading>
<GatsbyLink to="/">
<Heading as="h1">Chainlist</Heading>
</GatsbyLink>
{showSearch && <Search />}
<Flex>
{showFilters && <Filters />}
Expand Down Expand Up @@ -62,7 +65,7 @@ export const Header = ({ showSearch = true, showFilters = true }) => {
size="lg"
onClick={handleConnect}
>
Connect Wallet
Connect
</Button>
) : (
<Button size="lg" w={{ base: "100%", md: "auto" }}>
Expand Down
9 changes: 8 additions & 1 deletion src/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ import { Header } from "./Header";
export const Layout = ({ children, headerProps = {} }) => (
<Flex flexDirection="column" py="4" px="8" height="100vh" position="relative">
<Header {...headerProps} />
<Flex as="main" flexDirection="column" mt={{ base: "164px", md: "16" }}>
<Flex
as="main"
flexDirection="column"
mt={{
base: headerProps.showSearch !== false ? "164px" : "116px",
md: "16",
}}
>
{children}
</Flex>
</Flex>
Expand Down
20 changes: 20 additions & 0 deletions src/components/RedFlagBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from "react";
import { Badge, Tooltip } from "@chakra-ui/react";
import { ChainData } from "../types/chain";

export const RedFlagBadge = ({ redFlags }: Pick<ChainData, "redFlags">) => {
if (!redFlags || redFlags.length === 0) {
return null;
}
const flagLabel =
redFlags[0] === "reusedChainId"
? "Flagged for reusing chain ID"
: "Flagged for unknown reasons";
return (
<Tooltip label={flagLabel}>
<Badge colorScheme="red" textTransform="capitalize">
Flagged
</Badge>
</Tooltip>
);
};
45 changes: 45 additions & 0 deletions src/components/RpcTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React, { useContext } from "react";
import {
Button,
Table,
TableContainer,
Tbody,
Td,
Th,
Thead,
Tr,
} from "@chakra-ui/react";
import { Web3Context } from "../context/Web3Context";

export const RpcTable = ({ rpcs, handleRpcClick }) => {
const { isConnected, handleConnect } = useContext(Web3Context);

return (
<TableContainer>
<Table>
<Thead>
<Tr>
<Th pl="0">RPC URL</Th>
<Th></Th>
</Tr>
</Thead>
<Tbody>
{rpcs.map((rpcUrl) => (
<Tr>
<Td pl="0">{rpcUrl}</Td>
<Td pr="0" textAlign="end">
{!isConnected ? (
<Button onClick={handleConnect}>Connect</Button>
) : (
<Button onClick={() => handleRpcClick(rpcUrl)}>
Add Chain
</Button>
)}
</Td>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
);
};
8 changes: 8 additions & 0 deletions src/components/StatValue.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from "react";
import { VStack } from "@chakra-ui/react";

export const StatValue = ({ children }: { children: React.ReactNode }) => (
<VStack align="start" gap="1">
{children}
</VStack>
);
13 changes: 13 additions & 0 deletions src/components/StatusBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from "react";
import { Badge } from "@chakra-ui/react";
import { ChainData } from "../types/chain";

export const StatusBadge = ({ status }: Pick<ChainData, "status">) => {
const actualStatus = status ?? "Active";
const colorScheme = status === "deprecated" ? "yellow" : undefined;
return (
<Badge textTransform="capitalize" colorScheme={colorScheme}>
{actualStatus}
</Badge>
);
};
Loading

0 comments on commit f991fdc

Please sign in to comment.