Initial
This commit is contained in:
110
src/pages/showcase/_components/Card.tsx
Normal file
110
src/pages/showcase/_components/Card.tsx
Normal file
@@ -0,0 +1,110 @@
|
||||
import React from "react";
|
||||
|
||||
import { Showcase } from "../../../utils/apiTypes";
|
||||
import { mapUrl } from "../../../utils/map";
|
||||
import { CardTags } from "./CardTags";
|
||||
|
||||
export interface CardProps {
|
||||
network: Showcase;
|
||||
}
|
||||
|
||||
export const Card = React.memo(({ network }: CardProps) => (
|
||||
<div className="card">
|
||||
<div className="card__image">
|
||||
<div style={{ height: "140px" }}>
|
||||
<img src={mapUrl(network.nodes ?? [])} alt={network.title} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<h4>{network.title}</h4>
|
||||
<small>{network.summary}</small>
|
||||
</div>
|
||||
<div className="card__footer">
|
||||
<a
|
||||
href={`?id=${network.id}`}
|
||||
className="button button--primary button--block"
|
||||
style={{ marginBottom: "0.5rem" }}
|
||||
>
|
||||
Read more
|
||||
</a>
|
||||
<CardTags tags={network.tags} />
|
||||
</div>
|
||||
</div>
|
||||
));
|
||||
|
||||
export const PlaceholderCard = (): JSX.Element => (
|
||||
<div
|
||||
className="card"
|
||||
style={{
|
||||
animation: "pulse 2s infinite",
|
||||
transform: "scale(1)",
|
||||
}}
|
||||
>
|
||||
<div className="card__image">
|
||||
<div
|
||||
style={{
|
||||
height: "140px",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<div
|
||||
style={{
|
||||
width: "30%",
|
||||
height: "2rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
marginBottom: "1rem",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "1rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
marginBottom: "0.5rem",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "1rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="card__footer">
|
||||
<button
|
||||
className="button disabled button--primary button--block"
|
||||
style={{ marginBottom: "0.5rem" }}
|
||||
>
|
||||
|
||||
</button>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
gap: "0.5rem",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: "4rem",
|
||||
height: "1.5rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: "4rem",
|
||||
height: "1.5rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
29
src/pages/showcase/_components/CardTags.tsx
Normal file
29
src/pages/showcase/_components/CardTags.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import React from "react";
|
||||
|
||||
import { ShowcaseTag } from "../../../utils/apiTypes";
|
||||
|
||||
export interface CardTagsProps {
|
||||
tags: ShowcaseTag[];
|
||||
}
|
||||
|
||||
export const CardTags = ({ tags }: CardTagsProps) => {
|
||||
return (
|
||||
<div>
|
||||
{tags.map(({ color, label }) => {
|
||||
return (
|
||||
<span
|
||||
className="badge"
|
||||
key={label}
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
marginRight: "0.3rem",
|
||||
userSelect: "none",
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
90
src/pages/showcase/_components/Filters.tsx
Normal file
90
src/pages/showcase/_components/Filters.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
import React from "react";
|
||||
|
||||
import { FiHeart } from "react-icons/fi";
|
||||
import useSWR from "swr";
|
||||
|
||||
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
|
||||
import { fetcher } from "../../../utils/swr";
|
||||
|
||||
import { ShowcaseTag } from "../../../utils/apiTypes";
|
||||
// import { TagList, Tags } from '../../../utils/showcase';
|
||||
import { PlaceholderTagSelect, TagSelect } from "./TagSelect";
|
||||
|
||||
export const Filters = (): JSX.Element => {
|
||||
const { siteConfig } = useDocusaurusContext();
|
||||
|
||||
const { data, error } = useSWR<ShowcaseTag[]>(
|
||||
`${siteConfig.customFields.API_URL}/showcase/tags`,
|
||||
fetcher,
|
||||
);
|
||||
|
||||
return (
|
||||
<section className="margin-top--l margin-bottom--lg container">
|
||||
{data && !error ? (
|
||||
<ul
|
||||
style={{
|
||||
padding: "0",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
flexWrap: "wrap",
|
||||
}}
|
||||
>
|
||||
{data.map((tag) => {
|
||||
const { label, color } = tag;
|
||||
const id = `showcase_checkbox_id_${tag};`;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={tag.id}
|
||||
style={{
|
||||
boxSizing: "border-box",
|
||||
position: "relative",
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
height: "2rem",
|
||||
marginTop: "0.5rem",
|
||||
marginRight: "0.5rem",
|
||||
fontSize: "0.875rem",
|
||||
lineHeight: "1.25rem",
|
||||
verticalAlign: "middle",
|
||||
userSelect: "none",
|
||||
}}
|
||||
>
|
||||
<TagSelect
|
||||
tag={tag}
|
||||
id={id}
|
||||
label={label}
|
||||
icon={
|
||||
tag.label === "Favorite" ? (
|
||||
<span
|
||||
style={{
|
||||
display: "flex",
|
||||
marginLeft: "0.5rem",
|
||||
color: "rgb(190 24 93)",
|
||||
}}
|
||||
>
|
||||
<FiHeart />
|
||||
</span>
|
||||
) : (
|
||||
<span
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
width: 10,
|
||||
height: 10,
|
||||
borderRadius: "50%",
|
||||
marginLeft: 8,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
) : (
|
||||
<PlaceholderTagSelect />
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
};
|
||||
318
src/pages/showcase/_components/Network.tsx
Normal file
318
src/pages/showcase/_components/Network.tsx
Normal file
@@ -0,0 +1,318 @@
|
||||
import React from "react";
|
||||
|
||||
import useSWR from "swr";
|
||||
|
||||
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
|
||||
import { Showcase } from "../../../utils/apiTypes";
|
||||
import { fetcher } from "../../../utils/swr";
|
||||
|
||||
interface NetworkProps {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export const Network = ({ id }: NetworkProps): JSX.Element => {
|
||||
const { siteConfig } = useDocusaurusContext();
|
||||
|
||||
const { data, error } = useSWR<Showcase>(
|
||||
`${siteConfig.customFields.API_URL}/showcase/${id}`,
|
||||
fetcher,
|
||||
);
|
||||
|
||||
const githubData = useSWR(
|
||||
`https://api.github.com/users/${data?.author?.githubUsername}`,
|
||||
fetcher,
|
||||
).data;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{data && !error ? (
|
||||
<div className="container">
|
||||
<h1>{data.title}</h1>
|
||||
<p>{data.summary}</p>
|
||||
{githubData && (
|
||||
<div className="avatar">
|
||||
<img
|
||||
src={githubData.avatar_url}
|
||||
alt={githubData.name}
|
||||
className="avatar__photo"
|
||||
/>
|
||||
<div className="avatar__intro">
|
||||
<div className="avatar__name">{githubData.name}</div>
|
||||
<div className="avatar__subtitle">{githubData.bio}</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="markdown">{data.body}</div>
|
||||
|
||||
<div
|
||||
className="card"
|
||||
style={{
|
||||
marginLeft: "auto",
|
||||
marginRight: "auto",
|
||||
maxWidth: "900px",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="card__header"
|
||||
style={{
|
||||
margin: "8px",
|
||||
}}
|
||||
>
|
||||
<h2>Bill of Materials</h2>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
{data.materials?.map((material) => (
|
||||
<div
|
||||
key={material.id}
|
||||
style={{
|
||||
borderTop: "2px solid gray",
|
||||
display: "flex",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: "4rem",
|
||||
display: "flex",
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={material.image}
|
||||
height="auto"
|
||||
width="100%"
|
||||
style={{
|
||||
margin: "auto",
|
||||
padding: "4px",
|
||||
display: "block",
|
||||
maxWidth: "60px",
|
||||
maxHeight: "60px",
|
||||
width: "auto",
|
||||
height: "auto",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="avatar__intro">
|
||||
<div className="avatar__name">{material.name}</div>
|
||||
<small className="avatar__subtitle">
|
||||
{material.details}
|
||||
</small>
|
||||
</div>
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
href={material.url}
|
||||
className="button button--outline button--secondary"
|
||||
style={{
|
||||
marginTop: "auto",
|
||||
marginBottom: "auto",
|
||||
}}
|
||||
>
|
||||
View
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
{error && <div>{JSON.stringify(error)}</div>}
|
||||
{!data && <PlaceholderNetwork />}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const PlaceholderNetwork = (): JSX.Element => {
|
||||
return (
|
||||
<div
|
||||
className="container"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: window.innerWidth > 768 ? "row" : "column",
|
||||
gap: "2rem",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: window.innerWidth > 768 ? "60%" : "100%",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="card"
|
||||
style={{
|
||||
width: "100%",
|
||||
animation: "pulse 2s infinite",
|
||||
transform: "scale(1)",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "2rem",
|
||||
padding: "2rem",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "4rem",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "12rem",
|
||||
}}
|
||||
/>
|
||||
<div style={{ display: "flex", gap: "1rem" }}>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: "999px",
|
||||
backgroundColor: "gray",
|
||||
height: "4rem",
|
||||
width: "4rem",
|
||||
minWidth: "4rem",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "1rem",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: "100%",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "1rem",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: "100%",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "2rem",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
width: window.innerWidth > 768 ? "40%" : "100%",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="card"
|
||||
style={{
|
||||
width: "100%",
|
||||
animation: "pulse 2s infinite",
|
||||
transform: "scale(1)",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "2rem",
|
||||
padding: "2rem",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "12rem",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "2rem",
|
||||
}}
|
||||
/>
|
||||
<div style={{ display: "flex", gap: "0.5rem" }}>
|
||||
<div
|
||||
style={{
|
||||
width: "7rem",
|
||||
height: "1.8rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: "7rem",
|
||||
height: "1.8rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: "7rem",
|
||||
height: "1.8rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
style={{ display: "flex", flexDirection: "column", gap: "1rem" }}
|
||||
>
|
||||
<div style={{ display: "flex", gap: "1rem" }}>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "2.5rem",
|
||||
width: "20%",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "2.5rem",
|
||||
width: "60%",
|
||||
}}
|
||||
/>
|
||||
<a
|
||||
className="button disabled button--primary button--block"
|
||||
style={{ width: "20%" }}
|
||||
>
|
||||
|
||||
</a>
|
||||
</div>
|
||||
<div style={{ display: "flex", gap: "1rem" }}>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "2.5rem",
|
||||
width: "20%",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "2.5rem",
|
||||
width: "60%",
|
||||
}}
|
||||
/>
|
||||
<a
|
||||
className="button disabled button--primary button--block"
|
||||
style={{ width: "20%" }}
|
||||
>
|
||||
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
67
src/pages/showcase/_components/NetworkSection.tsx
Normal file
67
src/pages/showcase/_components/NetworkSection.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
import React from "react";
|
||||
|
||||
import { Showcase } from "../../../utils/apiTypes";
|
||||
import { Card, PlaceholderCard } from "./Card";
|
||||
|
||||
interface NetworkSectionProps {
|
||||
title: string;
|
||||
icon?: JSX.Element;
|
||||
iconColor?: string;
|
||||
networks?: Showcase[];
|
||||
}
|
||||
|
||||
export const NetworkSection = ({
|
||||
title,
|
||||
icon,
|
||||
iconColor,
|
||||
networks,
|
||||
}: NetworkSectionProps): JSX.Element => {
|
||||
return (
|
||||
<div className="margin-top--lg container">
|
||||
<div
|
||||
className="margin-bottom--sm"
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<h2>{title}</h2>
|
||||
{icon && (
|
||||
<span
|
||||
style={{
|
||||
marginBottom: "0.5rem",
|
||||
marginLeft: "0.5rem",
|
||||
fontSize: "1.25rem",
|
||||
lineHeight: "1.75rem",
|
||||
color: iconColor,
|
||||
}}
|
||||
>
|
||||
{icon}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<ul
|
||||
style={{
|
||||
position: "relative",
|
||||
display: "grid",
|
||||
gap: "1.5rem",
|
||||
gridTemplateColumns: "repeat(auto-fill, minmax(280px, 1fr))",
|
||||
paddingLeft: "0",
|
||||
}}
|
||||
>
|
||||
{networks ? (
|
||||
<>
|
||||
{networks.map((network) => (
|
||||
<Card key={network.title} network={network} />
|
||||
))}
|
||||
{networks.length === 0 && <h2>No result</h2>}
|
||||
</>
|
||||
) : (
|
||||
<div>
|
||||
<PlaceholderCard />
|
||||
</div>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
52
src/pages/showcase/_components/Networks.tsx
Normal file
52
src/pages/showcase/_components/Networks.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import React from "react";
|
||||
|
||||
import { FiHeart, FiSearch } from "react-icons/fi";
|
||||
import useSWR from "swr";
|
||||
|
||||
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
|
||||
import { useSelectedTags } from "../../../hooks/useSelectedTags";
|
||||
|
||||
import { useFilteredNetworks } from "../../../hooks/useFilteredNetworks";
|
||||
import { Showcase } from "../../../utils/apiTypes";
|
||||
import { fetcher } from "../../../utils/swr";
|
||||
import { NetworkSection } from "./NetworkSection";
|
||||
|
||||
export const Networks = (): JSX.Element => {
|
||||
const { siteConfig } = useDocusaurusContext();
|
||||
|
||||
const { data, error } = useSWR<Showcase[]>(
|
||||
`${siteConfig.customFields.API_URL}/showcase`,
|
||||
fetcher,
|
||||
);
|
||||
|
||||
const selectedTags = useSelectedTags();
|
||||
const filteredNetworks = useFilteredNetworks(data ?? []);
|
||||
|
||||
return (
|
||||
<section className="margin-top--lg margin-bottom--xl">
|
||||
{!error ? (
|
||||
selectedTags.length === 0 ? (
|
||||
<>
|
||||
<NetworkSection
|
||||
title="Our favorites"
|
||||
icon={<FiHeart />}
|
||||
iconColor="rgb(190 24 93)"
|
||||
networks={data?.filter((network) =>
|
||||
network.tags.find((tag) => tag.label === "Favorite"),
|
||||
)}
|
||||
/>
|
||||
<NetworkSection title="All networks" networks={data} />
|
||||
</>
|
||||
) : (
|
||||
<NetworkSection
|
||||
title="Results"
|
||||
icon={<FiSearch />}
|
||||
networks={filteredNetworks}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<div>{JSON.stringify(error)}</div>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
};
|
||||
111
src/pages/showcase/_components/TagSelect.tsx
Normal file
111
src/pages/showcase/_components/TagSelect.tsx
Normal file
@@ -0,0 +1,111 @@
|
||||
import "url-search-params-polyfill";
|
||||
|
||||
import React from "react";
|
||||
|
||||
import { useHistory, useLocation } from "@docusaurus/router";
|
||||
import { ShowcaseTag } from "../../../utils/apiTypes";
|
||||
|
||||
import { toggleListItem } from "../../../utils/showcase";
|
||||
|
||||
interface Props extends React.ComponentProps<"input"> {
|
||||
icon: React.ReactElement<React.ComponentProps<"svg">>;
|
||||
label: React.ReactNode;
|
||||
tag: ShowcaseTag;
|
||||
}
|
||||
|
||||
export function readSearchTags(search: string): string[] {
|
||||
return new URLSearchParams(search).getAll("tags");
|
||||
}
|
||||
|
||||
function replaceSearchTags(search: string, newTags: string[]) {
|
||||
const searchParams = new URLSearchParams(search);
|
||||
searchParams.delete("tags");
|
||||
newTags.forEach((tag) => searchParams.append("tags", tag));
|
||||
return searchParams.toString();
|
||||
}
|
||||
|
||||
export const TagSelect = React.forwardRef<HTMLLabelElement, Props>(
|
||||
({ icon, label, tag }) => {
|
||||
const location = useLocation();
|
||||
const history = useHistory();
|
||||
const [selected, setSelected] = React.useState(false);
|
||||
React.useEffect(() => {
|
||||
const tags = readSearchTags(location.search);
|
||||
setSelected(tags.includes(tag.label));
|
||||
}, [tag, location]);
|
||||
const toggleTag = React.useCallback(() => {
|
||||
const tags = readSearchTags(location.search);
|
||||
const newTags = toggleListItem(tags, tag.label);
|
||||
const newSearch = replaceSearchTags(location.search, newTags);
|
||||
history.push({ ...location, search: newSearch });
|
||||
}, [tag, location, history]);
|
||||
return (
|
||||
<button
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
}}
|
||||
className={`button button--sm button--outline button--secondary ${
|
||||
selected ? "button--active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
toggleTag();
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
{icon}
|
||||
</button>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
export const PlaceholderTagSelect = (): JSX.Element => (
|
||||
<div
|
||||
style={{
|
||||
boxSizing: "border-box",
|
||||
position: "relative",
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
height: "2rem",
|
||||
marginTop: "0.5rem",
|
||||
marginRight: "0.5rem",
|
||||
fontSize: "0.875rem",
|
||||
lineHeight: "1.25rem",
|
||||
verticalAlign: "middle",
|
||||
userSelect: "none",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: "7rem",
|
||||
height: "1.8rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
animation: "pulse 2s infinite",
|
||||
transform: "scale(1)",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: "7rem",
|
||||
height: "1.8rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
animation: "pulse 2s infinite",
|
||||
transform: "scale(1)",
|
||||
marginLeft: 8,
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: "7rem",
|
||||
height: "1.8rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
animation: "pulse 2s infinite",
|
||||
transform: "scale(1)",
|
||||
marginLeft: 8,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
35
src/pages/showcase/index.tsx
Normal file
35
src/pages/showcase/index.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import "url-search-params-polyfill";
|
||||
|
||||
import React from "react";
|
||||
|
||||
import { useLocation } from "@docusaurus/router";
|
||||
import Layout from "@theme/Layout";
|
||||
|
||||
import { Filters } from "./_components/Filters";
|
||||
import { Network } from "./_components/Network";
|
||||
import { Networks } from "./_components/Networks";
|
||||
|
||||
const Showcase = (): JSX.Element => {
|
||||
const location = useLocation();
|
||||
const id = new URLSearchParams(location.search).get("id");
|
||||
|
||||
return (
|
||||
<Layout
|
||||
title="Showcase"
|
||||
description="Portfolio of projects from the Dead community"
|
||||
>
|
||||
<main className="margin-vert--lg">
|
||||
{id ? (
|
||||
<Network id={id} />
|
||||
) : (
|
||||
<>
|
||||
<Filters />
|
||||
<Networks />
|
||||
</>
|
||||
)}
|
||||
</main>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
export default Showcase;
|
||||
Reference in New Issue
Block a user