Skip to content
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
81 changes: 75 additions & 6 deletions src/components/sections/ChainSpecsSection.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,66 @@
"use client";

import { Download } from "lucide-react";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { CHAIN_SPECS_CONTENT } from "@/constants/chain-specs";

function getInitialSelectedFiles(): Record<string, string> {
const initial: Record<string, string> = {};
for (const spec of CHAIN_SPECS_CONTENT.specs) {
initial[spec.title] = spec.files[0].filename;
}
return initial;
}

interface FileSelectProps {
files: readonly { filename: string; url: string }[];
value: string;
onChange: (value: string) => void;
}

function FileSelect({ files, value, onChange }: FileSelectProps) {
return (
<Select value={value} onValueChange={onChange}>
<SelectTrigger className="flex-1 h-8 text-xs bg-background/50 text-left [&>span]:text-left">
<SelectValue />
</SelectTrigger>
<SelectContent>
{files.map((file) => (
<SelectItem key={file.filename} value={file.filename}>
{file.filename}
</SelectItem>
))}
</SelectContent>
</Select>
);
}

export function ChainSpecsSection() {
const [selectedFiles, setSelectedFiles] = useState<Record<string, string>>(
getInitialSelectedFiles,
);

const getSelectedFile = (specTitle: string) => {
const spec = CHAIN_SPECS_CONTENT.specs.find((s) => s.title === specTitle);
const selectedFilename = selectedFiles[specTitle];
return spec?.files.find((f) => f.filename === selectedFilename);
};

const handleFileChange = (specTitle: string, value: string) => {
setSelectedFiles((prev) => ({
...prev,
[specTitle]: value,
}));
};

return (
<section id="chain-specs" className="section-primary py-24">
<div className="max-w-7xl mx-auto px-6">
Expand All @@ -20,6 +76,9 @@ export function ChainSpecsSection() {
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6 mb-12">
{CHAIN_SPECS_CONTENT.specs.map((spec) => {
const Icon = spec.icon;
const selectedFile = getSelectedFile(spec.title);
const hasMultipleFiles = spec.files.length > 1;

return (
<div
key={spec.title}
Expand All @@ -32,15 +91,25 @@ export function ChainSpecsSection() {
<p className="text-muted-foreground text-sm mb-4">
{spec.description}
</p>
<div className="flex items-center justify-between">
<code className="text-xs bg-background/50 px-2 py-1 rounded text-primary">
{spec.filename}
</code>
<div className="flex items-center gap-2">
{hasMultipleFiles ? (
<FileSelect
files={spec.files}
value={selectedFiles[spec.title]}
onChange={(value) => handleFileChange(spec.title, value)}
/>
) : (
<code className="flex-1 text-xs bg-background/50 px-2 py-1 rounded text-primary truncate">
{spec.files[0].filename}
</code>
)}
<Button
variant="ghost"
size="sm"
onClick={() => window.open(spec.url, "_blank")}
className="bg-primary/10 hover:bg-primary/20 text-primary h-auto px-3 py-1 rounded-lg text-sm"
onClick={() =>
selectedFile && window.open(selectedFile.url, "_blank")
}
className="bg-primary/10 hover:bg-primary/20 text-primary h-auto px-3 py-1 rounded-lg text-sm shrink-0"
>
<Download className="w-3 h-3" />
<span>{CHAIN_SPECS_CONTENT.downloadLabel}</span>
Expand Down
68 changes: 54 additions & 14 deletions src/constants/chain-specs.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { Database, FileCode, type LucideIcon, Server } from "lucide-react";
import { URLS } from "./urls";

interface ChainSpecFile {
readonly filename: string;
readonly url: string;
}

interface ChainSpec {
readonly title: string;
readonly description: string;
readonly filename: string;
readonly url: string;
readonly files: readonly ChainSpecFile[];
readonly icon: LucideIcon;
}

Expand All @@ -26,43 +30,79 @@ export const CHAIN_SPECS_CONTENT = {
{
title: "Paseo Relay Chain",
description: "Main relay chain specification file",
filename: "paseo.raw.json",
url: URLS.chainSpecs.relayChain,
files: [
{ filename: "paseo.raw.json", url: URLS.chainSpecs.relayChain },
{
filename: "paseo.raw.smol.json",
url: URLS.chainSpecs.relayChainSmol,
},
],
icon: Server,
},
{
title: "Asset Hub",
description: "Asset Hub parachain specification",
filename: "paseo-asset-hub.json",
url: URLS.chainSpecs.assetHub,
files: [
{ filename: "paseo-asset-hub.json", url: URLS.chainSpecs.assetHub },
{
filename: "paseo-asset-hub.smol.json",
url: URLS.chainSpecs.assetHubSmol,
},
],
icon: Database,
},
{
title: "Bridge Hub",
description: "Bridge Hub parachain specification",
filename: "paseo-bridge-hub.raw.json",
url: URLS.chainSpecs.bridgeHub,
files: [
{
filename: "paseo-bridge-hub.raw.json",
url: URLS.chainSpecs.bridgeHub,
},
{
filename: "paseo-bridge-hub.raw.smol.json",
url: URLS.chainSpecs.bridgeHubSmol,
},
],
icon: FileCode,
},
{
title: "Coretime Chain",
description: "Coretime parachain specification",
filename: "paseo-coretime.raw.json",
url: URLS.chainSpecs.coretime,
files: [
{ filename: "paseo-coretime.raw.json", url: URLS.chainSpecs.coretime },
{
filename: "paseo-coretime.raw.smol.json",
url: URLS.chainSpecs.coretimeSmol,
},
],
icon: Server,
},
{
title: "People Chain",
description: "People parachain specification",
filename: "paseo-people.raw.json",
url: URLS.chainSpecs.people,
files: [
{ filename: "paseo-people.raw.json", url: URLS.chainSpecs.people },
{
filename: "paseo-people.raw.smol.json",
url: URLS.chainSpecs.peopleSmol,
},
],
icon: Database,
},
{
title: "Collectives Chain",
description: "Collectives parachain specification",
filename: "paseo-collectives.raw.json",
url: URLS.chainSpecs.collectives,
files: [
{
filename: "paseo-collectives.raw.json",
url: URLS.chainSpecs.collectives,
},
{
filename: "paseo-collectives.raw.smol.json",
url: URLS.chainSpecs.collectivesSmol,
},
],
icon: Database,
},
],
Expand Down
12 changes: 12 additions & 0 deletions src/constants/urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,25 @@ export const URLS = {
chainSpecsBase: "https://paseo-r2.zondax.ch/chain-specs",
chainSpecs: {
relayChain: "https://paseo-r2.zondax.ch/chain-specs/paseo.raw.json",
relayChainSmol:
"https://paseo-r2.zondax.ch/chain-specs/paseo.raw.smol.json",
assetHub: "https://paseo-r2.zondax.ch/chain-specs/paseo-asset-hub.json",
assetHubSmol:
"https://paseo-r2.zondax.ch/chain-specs/paseo-asset-hub.smol.json",
bridgeHub:
"https://paseo-r2.zondax.ch/chain-specs/paseo-bridge-hub.raw.json",
bridgeHubSmol:
"https://paseo-r2.zondax.ch/chain-specs/paseo-bridge-hub.raw.smol.json",
coretime: "https://paseo-r2.zondax.ch/chain-specs/paseo-coretime.raw.json",
coretimeSmol:
"https://paseo-r2.zondax.ch/chain-specs/paseo-coretime.raw.smol.json",
people: "https://paseo-r2.zondax.ch/chain-specs/paseo-people.raw.json",
peopleSmol:
"https://paseo-r2.zondax.ch/chain-specs/paseo-people.raw.smol.json",
collectives:
"https://paseo-r2.zondax.ch/chain-specs/paseo-collectives.raw.json",
collectivesSmol:
"https://paseo-r2.zondax.ch/chain-specs/paseo-collectives.raw.smol.json",
},

// Resources
Expand Down
Loading