mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
layout component & site metadata refactor
This commit is contained in:
parent
38ccfc635e
commit
9cc38304c8
22
content/site.json
Normal file
22
content/site.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"site": {
|
||||||
|
"siteTitle": "Ocean Market",
|
||||||
|
"siteTagline": "A marketplace to find and publish open data sets in the Ocean Network.",
|
||||||
|
"siteUrl": "https://market.oceanprotocol.now.sh/",
|
||||||
|
"copyright": "All Rights Reserved. Powered by [Ocean Protocol](https://oceanprotocol.com)",
|
||||||
|
"menu": [
|
||||||
|
{
|
||||||
|
"name": "Explore",
|
||||||
|
"link": "/explore"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Publish",
|
||||||
|
"link": "/publish"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Transactions",
|
||||||
|
"link": "/transactions"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
9
package-lock.json
generated
9
package-lock.json
generated
@ -8385,6 +8385,15 @@
|
|||||||
"popper.js": "^1.14.1"
|
"popper.js": "^1.14.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/react-helmet": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-helmet/-/react-helmet-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-NBMPAxgjpaMooXa51cU1BTgrX6T+hQbMiLm77JhBbfOzPQea3RB5rNpPOD5xGWHIVpGXHd59cltEzIq0qglGcQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/react-jsonschema-form": {
|
"@types/react-jsonschema-form": {
|
||||||
"version": "1.7.3",
|
"version": "1.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-jsonschema-form/-/react-jsonschema-form-1.7.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-jsonschema-form/-/react-jsonschema-form-1.7.3.tgz",
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
"@types/numeral": "^0.0.28",
|
"@types/numeral": "^0.0.28",
|
||||||
"@types/react": "^16.9.41",
|
"@types/react": "^16.9.41",
|
||||||
"@types/react-datepicker": "^3.0.2",
|
"@types/react-datepicker": "^3.0.2",
|
||||||
|
"@types/react-helmet": "^6.0.0",
|
||||||
"@types/react-jsonschema-form": "^1.7.3",
|
"@types/react-jsonschema-form": "^1.7.3",
|
||||||
"@types/react-paginate": "^6.2.1",
|
"@types/react-paginate": "^6.2.1",
|
||||||
"@types/shortid": "0.0.29",
|
"@types/shortid": "0.0.29",
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
siteTitle: 'Ocean Market',
|
|
||||||
siteTagline: `A marketplace to find and publish open data sets in the Ocean Network.`,
|
|
||||||
siteUrl: 'https://market.oceanprotocol.now.sh/',
|
|
||||||
copyright:
|
|
||||||
'All Rights Reserved. Powered by [Ocean Protocol](https://oceanprotocol.com)',
|
|
||||||
menu: [
|
|
||||||
{
|
|
||||||
name: 'Explore',
|
|
||||||
link: '/explore'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Publish',
|
|
||||||
link: '/publish'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Transactions',
|
|
||||||
link: '/transactions'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,3 +1,8 @@
|
|||||||
|
declare module '*.module.css' {
|
||||||
|
const classes: { [key: string]: string }
|
||||||
|
export default classes
|
||||||
|
}
|
||||||
|
|
||||||
declare module '*.svg' {
|
declare module '*.svg' {
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
export const ReactComponent: React.FunctionComponent<React.SVGProps<
|
export const ReactComponent: React.FunctionComponent<React.SVGProps<
|
||||||
@ -7,5 +12,4 @@ declare module '*.svg' {
|
|||||||
export default src
|
export default src
|
||||||
}
|
}
|
||||||
|
|
||||||
declare type Nullable<T> = T | null
|
declare module '*.gif'
|
||||||
declare module '*.md'
|
|
9
src/components/Layout.test.tsx
Normal file
9
src/components/Layout.test.tsx
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import testRender from '../../tests/unit/testRender'
|
||||||
|
import Layout from './Layout'
|
||||||
|
|
||||||
|
describe('Layout', () => {
|
||||||
|
testRender(
|
||||||
|
<Layout location={{ href: 'https://demo.com' } as Location}>Hello</Layout>
|
||||||
|
)
|
||||||
|
})
|
@ -1,31 +1,40 @@
|
|||||||
import React, { ReactNode } from 'react'
|
import React, { ReactNode, ReactElement } from 'react'
|
||||||
import Head from 'next/head'
|
import { Helmet } from 'react-helmet'
|
||||||
import { NextSeo } from 'next-seo'
|
import Header from './organisms/Header'
|
||||||
|
import Footer from './organisms/Footer'
|
||||||
|
import PageHeader from './molecules/PageHeader'
|
||||||
import styles from './Layout.module.css'
|
import styles from './Layout.module.css'
|
||||||
import Header from './components/organisms/Header'
|
import Seo from './atoms/Seo'
|
||||||
import Footer from './components/organisms/Footer'
|
|
||||||
import PageHeader from './components/molecules/PageHeader'
|
export interface LayoutProps {
|
||||||
|
children: ReactNode
|
||||||
|
title?: string
|
||||||
|
description?: string
|
||||||
|
noPageHeader?: boolean
|
||||||
|
location?: Location
|
||||||
|
}
|
||||||
|
|
||||||
export default function Layout({
|
export default function Layout({
|
||||||
children,
|
children,
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
noPageHeader
|
noPageHeader,
|
||||||
}: {
|
location
|
||||||
children: ReactNode
|
}: LayoutProps): ReactElement {
|
||||||
title?: string
|
|
||||||
description?: string
|
|
||||||
noPageHeader?: boolean
|
|
||||||
}) {
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.app}>
|
<div className={styles.app}>
|
||||||
<Head>
|
<Helmet>
|
||||||
<link rel="icon" href="/icons/icon-96x96.png" />
|
<link rel="icon" href="/icons/icon-96x96.png" />
|
||||||
<link rel="apple-touch-icon" href="icons/icon-256x256.png" />
|
<link rel="apple-touch-icon" href="icons/icon-256x256.png" />
|
||||||
<meta name="theme-color" content="#ca2935" />
|
<meta name="theme-color" content="#ca2935" />
|
||||||
</Head>
|
</Helmet>
|
||||||
|
|
||||||
<NextSeo title={title} description={description} />
|
<Seo
|
||||||
|
title={title}
|
||||||
|
description={description}
|
||||||
|
uri={location.href}
|
||||||
|
location={location}
|
||||||
|
/>
|
||||||
|
|
||||||
<Header />
|
<Header />
|
||||||
<main className={styles.main}>
|
<main className={styles.main}>
|
@ -16,8 +16,7 @@
|
|||||||
background: var(--brand-grey-light);
|
background: var(--brand-grey-light);
|
||||||
box-shadow: 0 9px 18px 0 rgba(0, 0, 0, 0.1);
|
box-shadow: 0 9px 18px 0 rgba(0, 0, 0, 0.1);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
margin-left: calc(var(--spacer) / 4);
|
text-align: center;
|
||||||
margin-right: calc(var(--spacer) / 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:first-child {
|
.button:first-child {
|
||||||
@ -57,21 +56,28 @@
|
|||||||
background: var(--brand-gradient);
|
background: var(--brand-gradient);
|
||||||
}
|
}
|
||||||
|
|
||||||
.link {
|
.ghost,
|
||||||
|
.ghost:hover,
|
||||||
|
.ghost:focus,
|
||||||
|
.ghost:active {
|
||||||
|
color: var(--brand-grey);
|
||||||
|
background: var(--brand-white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.text,
|
||||||
|
.text:hover,
|
||||||
|
.text:focus,
|
||||||
|
.text:active {
|
||||||
border: 0;
|
border: 0;
|
||||||
|
border-radius: 0;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
|
padding: 0;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background: 0;
|
background: 0;
|
||||||
padding: 0;
|
|
||||||
color: var(--brand-pink);
|
color: var(--brand-pink);
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.link:hover {
|
|
||||||
background: none;
|
|
||||||
color: var(--brand-pink);
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Size Modifiers */
|
/* Size Modifiers */
|
||||||
.small {
|
.small {
|
||||||
|
@ -1,14 +1,57 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import { action } from '@storybook/addon-actions'
|
||||||
import Button from './Button'
|
import Button from './Button'
|
||||||
import { Center } from '../../../.storybook/helpers'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'Atoms/Button',
|
title: 'Atoms/Button'
|
||||||
decorators: [(storyFn: any) => <Center>{storyFn()}</Center>]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Normal = () => <Button>Hello Button</Button>
|
export const Default = () => (
|
||||||
|
<>
|
||||||
|
<Button onClick={action('clicked')}>Hello Button</Button>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<Button size="small" onClick={action('clicked')}>
|
||||||
|
Hello Button
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
export const Primary = () => <Button primary>Hello Button</Button>
|
export const Primary = () => (
|
||||||
|
<>
|
||||||
|
<Button style="primary" onClick={action('clicked')}>
|
||||||
|
Hello Button
|
||||||
|
</Button>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<Button style="primary" size="small" onClick={action('clicked')}>
|
||||||
|
Hello Button
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
export const Link = () => <Button link>Hello Button</Button>
|
export const Ghost = () => (
|
||||||
|
<>
|
||||||
|
<Button style="ghost" onClick={action('clicked')}>
|
||||||
|
Hello Button
|
||||||
|
</Button>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<Button style="ghost" size="small" onClick={action('clicked')}>
|
||||||
|
Hello Button
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
|
export const Text = () => (
|
||||||
|
<>
|
||||||
|
<Button style="text" onClick={action('clicked')}>
|
||||||
|
Hello Button
|
||||||
|
</Button>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<Button style="text" size="small" onClick={action('clicked')}>
|
||||||
|
Hello Button
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
@ -1,44 +1,53 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactNode, FormEvent } from 'react'
|
||||||
import Link from 'next/link'
|
import { Link } from 'gatsby'
|
||||||
|
import classNames from 'classnames/bind'
|
||||||
import styles from './Button.module.css'
|
import styles from './Button.module.css'
|
||||||
|
|
||||||
declare type ButtonProps = {
|
const cx = classNames.bind(styles)
|
||||||
children: string | ReactElement
|
|
||||||
|
interface ButtonProps {
|
||||||
|
children: ReactNode
|
||||||
className?: string
|
className?: string
|
||||||
primary?: boolean
|
|
||||||
link?: boolean
|
|
||||||
href?: string
|
href?: string
|
||||||
size?: string
|
onClick?: (e: FormEvent) => void
|
||||||
onClick?: any
|
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
|
to?: string
|
||||||
|
name?: string
|
||||||
|
size?: 'small'
|
||||||
|
style?: 'primary' | 'ghost' | 'text'
|
||||||
|
type?: 'submit'
|
||||||
|
download?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const Button = ({
|
export default function Button({
|
||||||
primary,
|
|
||||||
link,
|
|
||||||
href,
|
href,
|
||||||
size,
|
|
||||||
children,
|
children,
|
||||||
className,
|
className,
|
||||||
|
to,
|
||||||
|
size,
|
||||||
|
style,
|
||||||
...props
|
...props
|
||||||
}: ButtonProps) => {
|
}: ButtonProps) {
|
||||||
const classes = primary
|
const styleClasses = cx({
|
||||||
? `${styles.button} ${styles.primary}`
|
button: true,
|
||||||
: link
|
primary: style === 'primary',
|
||||||
? `${styles.button} ${styles.link}`
|
ghost: style === 'ghost',
|
||||||
: styles.button
|
text: style === 'text',
|
||||||
|
small: size === 'small',
|
||||||
|
[className]: className
|
||||||
|
})
|
||||||
|
|
||||||
return href ? (
|
return to ? (
|
||||||
<Link href={href}>
|
<Link to={to} className={styleClasses} {...props}>
|
||||||
<a className={`${classes} ${className}`} {...props}>
|
{children}
|
||||||
|
</Link>
|
||||||
|
) : href ? (
|
||||||
|
<a href={href} className={styleClasses} {...props}>
|
||||||
{children}
|
{children}
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
|
||||||
) : (
|
) : (
|
||||||
<button className={`${classes} ${className}`} {...props}>
|
<button className={styleClasses} {...props}>
|
||||||
{children}
|
{children}
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Button
|
|
||||||
|
56
src/components/atoms/Seo.tsx
Normal file
56
src/components/atoms/Seo.tsx
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Helmet } from 'react-helmet'
|
||||||
|
import { useSiteMetadata } from '../../hooks/useSiteMetadata'
|
||||||
|
|
||||||
|
export default function Seo({
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
uri,
|
||||||
|
location
|
||||||
|
}: {
|
||||||
|
title?: string
|
||||||
|
description?: string
|
||||||
|
uri: string
|
||||||
|
location: Location
|
||||||
|
}) {
|
||||||
|
const { siteTitle, siteTagline, siteUrl, siteImage } = useSiteMetadata()
|
||||||
|
|
||||||
|
// Remove trailing slash from all URLs
|
||||||
|
const canonical = `${siteUrl}${uri}`.replace(/\/$/, '')
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Helmet
|
||||||
|
defaultTitle={`${siteTitle} — ${siteTagline}`}
|
||||||
|
titleTemplate="%s — Ocean Protocol"
|
||||||
|
title={title}
|
||||||
|
>
|
||||||
|
<html lang="en" />
|
||||||
|
|
||||||
|
{typeof window !== 'undefined' &&
|
||||||
|
window.location &&
|
||||||
|
window.location.hostname !== 'oceanprotocol.com' && (
|
||||||
|
<meta name="robots" content="noindex,nofollow" />
|
||||||
|
)}
|
||||||
|
|
||||||
|
<link rel="canonical" href={canonical} />
|
||||||
|
|
||||||
|
<meta name="description" content={description} />
|
||||||
|
<meta property="og:title" content={title} />
|
||||||
|
<meta property="og:description" content={description} />
|
||||||
|
<meta property="og:url" content={location.href} />
|
||||||
|
|
||||||
|
<meta
|
||||||
|
name="image"
|
||||||
|
content={`${siteUrl}${siteImage.childImageSharp.original.src}`}
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
property="og:image"
|
||||||
|
content={`${siteUrl}${siteImage.childImageSharp.original.src}`}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<meta property="og:site_name" content={siteTitle} />
|
||||||
|
<meta name="twitter:creator" content="@oceanprotocol" />
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
</Helmet>
|
||||||
|
)
|
||||||
|
}
|
@ -1,11 +1,6 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Time from '../Time'
|
import { Link } from 'gatsby'
|
||||||
import Link from 'next/link'
|
|
||||||
|
|
||||||
export default function DdoLinkCell({ id, name }: { id: any; name: any }) {
|
export default function DdoLinkCell({ id, name }: { id: any; name: any }) {
|
||||||
return (
|
return <Link to={`/asset/${id}`}>{name}</Link>
|
||||||
<Link href="/asset/[did]" as={`/asset/${id}`} passHref>
|
|
||||||
<a>{name}</a>
|
|
||||||
</Link>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Link from 'next/link'
|
import { Link } from 'gatsby'
|
||||||
import shortid from 'shortid'
|
import shortid from 'shortid'
|
||||||
import slugify from 'slugify'
|
import slugify from 'slugify'
|
||||||
import styles from './Tags.module.css'
|
import styles from './Tags.module.css'
|
||||||
@ -20,10 +20,8 @@ const Tag = ({ tag, noLinks }: { tag: string; noLinks?: boolean }) => {
|
|||||||
return noLinks ? (
|
return noLinks ? (
|
||||||
<span className={styles.tag}>{cleanTag}</span>
|
<span className={styles.tag}>{cleanTag}</span>
|
||||||
) : (
|
) : (
|
||||||
<Link href={`/search?tags=${tag}`}>
|
<Link to={`/search?tags=${tag}`} className={styles.tag} title={cleanTag}>
|
||||||
<a className={styles.tag} title={cleanTag}>
|
|
||||||
{cleanTag}
|
{cleanTag}
|
||||||
</a>
|
|
||||||
</Link>
|
</Link>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { DDO } from '@oceanprotocol/squid'
|
import { DDO } from '@oceanprotocol/squid'
|
||||||
import Link from 'next/link'
|
import { Link } from 'gatsby'
|
||||||
import Dotdotdot from 'react-dotdotdot'
|
import Dotdotdot from 'react-dotdotdot'
|
||||||
import {
|
import {
|
||||||
AdditionalInformationMarket,
|
AdditionalInformationMarket,
|
||||||
@ -40,7 +40,7 @@ const AssetTeaser: React.FC<AssetTeaserProps> = ({ ddo }: AssetTeaserProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<article className={styles.teaser}>
|
<article className={styles.teaser}>
|
||||||
<Link href="/asset/[did]" as={`/asset/${ddo.id}`}>
|
<Link to={`/asset/${ddo.id}`}>
|
||||||
<a className={styles.link}>
|
<a className={styles.link}>
|
||||||
<h1 className={styles.title}>{name}</h1>
|
<h1 className={styles.title}>{name}</h1>
|
||||||
{access === 'Compute' && (
|
{access === 'Compute' && (
|
||||||
|
@ -6,7 +6,7 @@ import styles from './JobDetailsDialog.module.css'
|
|||||||
import MetaItem from '../templates/AssetDetails/MetaItem'
|
import MetaItem from '../templates/AssetDetails/MetaItem'
|
||||||
import Time from '../atoms/Time'
|
import Time from '../atoms/Time'
|
||||||
import shortid from 'shortid'
|
import shortid from 'shortid'
|
||||||
import Link from 'next/link'
|
import { Link } from 'gatsby'
|
||||||
|
|
||||||
export default function JobDetailsDialog({
|
export default function JobDetailsDialog({
|
||||||
computeItem,
|
computeItem,
|
||||||
@ -46,8 +46,8 @@ export default function JobDetailsDialog({
|
|||||||
<MetaItem
|
<MetaItem
|
||||||
title="Results"
|
title="Results"
|
||||||
content={resultsUrls.map((url: string) => (
|
content={resultsUrls.map((url: string) => (
|
||||||
<Link href={url} key={shortid.generate()} passHref>
|
<Link to={url} key={shortid.generate()}>
|
||||||
<a>{url}</a>
|
{url}
|
||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
/>
|
/>
|
||||||
@ -55,24 +55,12 @@ export default function JobDetailsDialog({
|
|||||||
{algorithmLogUrl && (
|
{algorithmLogUrl && (
|
||||||
<MetaItem
|
<MetaItem
|
||||||
title="Algorithm Log"
|
title="Algorithm Log"
|
||||||
content={
|
content={<Link to={algorithmLogUrl}>{algorithmLogUrl}</Link>}
|
||||||
<Link href={algorithmLogUrl} key={shortid.generate()} passHref>
|
|
||||||
<a>{algorithmLogUrl}</a>
|
|
||||||
</Link>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<MetaItem
|
<MetaItem
|
||||||
title="Data Set"
|
title="Data Set"
|
||||||
content={
|
content={<Link to={`/asset/${computeItem.ddo.id}`}>{name}</Link>}
|
||||||
<Link
|
|
||||||
href="/asset/[did]"
|
|
||||||
as={`/asset/${computeItem.ddo.id}`}
|
|
||||||
passHref
|
|
||||||
>
|
|
||||||
<a>{name}</a>
|
|
||||||
</Link>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Link from 'next/link'
|
import { Link } from 'gatsby'
|
||||||
import { useRouter } from 'next/router'
|
import { useLocation } from '@reach/router'
|
||||||
import { menu } from '../../../site.config'
|
|
||||||
import styles from './Menu.module.css'
|
import styles from './Menu.module.css'
|
||||||
|
import { useSiteMetadata } from '../../hooks/useSiteMetadata'
|
||||||
|
|
||||||
declare type MenuItem = {
|
declare type MenuItem = {
|
||||||
name: string
|
name: string
|
||||||
@ -10,20 +10,23 @@ declare type MenuItem = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function MenuLink({ item }: { item: MenuItem }) {
|
function MenuLink({ item }: { item: MenuItem }) {
|
||||||
const router = useRouter()
|
const location = useLocation()
|
||||||
|
|
||||||
const classes =
|
const classes =
|
||||||
router && router.pathname === item.link
|
location && location.pathname === item.link
|
||||||
? `${styles.link} ${styles.active}`
|
? `${styles.link} ${styles.active}`
|
||||||
: styles.link
|
: styles.link
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link key={item.name} href={item.link}>
|
<Link key={item.name} to={item.link} className={classes}>
|
||||||
<a className={classes}>{item.name}</a>
|
{item.name}
|
||||||
</Link>
|
</Link>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Menu() {
|
export default function Menu() {
|
||||||
|
const { menu } = useSiteMetadata()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav className={styles.menu}>
|
<nav className={styles.menu}>
|
||||||
{menu.map((item: MenuItem) => (
|
{menu.map((item: MenuItem) => (
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import AssetTeaser from '../molecules/AssetTeaser'
|
import AssetTeaser from '../molecules/AssetTeaser'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useRouter } from 'next/router'
|
|
||||||
import { QueryResult } from '@oceanprotocol/squid/dist/node/aquarius/Aquarius'
|
import { QueryResult } from '@oceanprotocol/squid/dist/node/aquarius/Aquarius'
|
||||||
import shortid from 'shortid'
|
import shortid from 'shortid'
|
||||||
import Pagination from '../molecules/Pagination'
|
import Pagination from '../molecules/Pagination'
|
||||||
@ -12,8 +11,6 @@ declare type AssetListProps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const AssetList: React.FC<AssetListProps> = ({ queryResult }) => {
|
const AssetList: React.FC<AssetListProps> = ({ queryResult }) => {
|
||||||
const router = useRouter()
|
|
||||||
|
|
||||||
// Construct the urls on the pagination links. This is only for UX,
|
// Construct the urls on the pagination links. This is only for UX,
|
||||||
// since the links are no <Link> they will not work by itself.
|
// since the links are no <Link> they will not work by itself.
|
||||||
function hrefBuilder(pageIndex: number) {
|
function hrefBuilder(pageIndex: number) {
|
||||||
|
@ -10,9 +10,8 @@ import Price from '../atoms/Price'
|
|||||||
import { fromWei } from 'web3-utils'
|
import { fromWei } from 'web3-utils'
|
||||||
import DateCell from '../atoms/Table/DateCell'
|
import DateCell from '../atoms/Table/DateCell'
|
||||||
import DdoLinkCell from '../atoms/Table/DdoLinkCell'
|
import DdoLinkCell from '../atoms/Table/DdoLinkCell'
|
||||||
import { DDO, MetaDataMain } from '@oceanprotocol/squid'
|
import { MetaDataMain } from '@oceanprotocol/squid'
|
||||||
import { findServiceByType } from '../../utils'
|
import { findServiceByType } from '../../utils'
|
||||||
import { config } from '../../config/ocean'
|
|
||||||
|
|
||||||
const consumedColumns = [
|
const consumedColumns = [
|
||||||
{
|
{
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Link from 'next/link'
|
import { Link } from 'gatsby'
|
||||||
import Menu from '../molecules/Menu'
|
import Menu from '../molecules/Menu'
|
||||||
import styles from './Header.module.css'
|
import styles from './Header.module.css'
|
||||||
import { title } from '../../../site.config'
|
|
||||||
import Logo from '@oceanprotocol/art/logo/logo.svg'
|
import Logo from '@oceanprotocol/art/logo/logo.svg'
|
||||||
|
import { useSiteMetadata } from '../../hooks/useSiteMetadata'
|
||||||
|
|
||||||
export default function Header() {
|
export default function Header() {
|
||||||
|
const { siteTitle } = useSiteMetadata()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className={styles.header}>
|
<header className={styles.header}>
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
<Link href="/">
|
<Link to="/" className={styles.logoUnit}>
|
||||||
<a className={styles.logoUnit}>
|
|
||||||
<Logo />
|
<Logo />
|
||||||
<h1 className={styles.title}>{title}</h1>
|
<h1 className={styles.title}>{siteTitle}</h1>
|
||||||
</a>
|
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<Menu />
|
<Menu />
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import Loader from '../atoms/Loader'
|
import Loader from '../atoms/Loader'
|
||||||
import { DDO, MetaDataMain } from '@oceanprotocol/squid'
|
import { MetaDataMain } from '@oceanprotocol/squid'
|
||||||
import {
|
import {
|
||||||
useOcean,
|
useOcean,
|
||||||
OceanConnectionStatus,
|
OceanConnectionStatus,
|
||||||
useSearch
|
useSearch
|
||||||
} from '@oceanprotocol/react'
|
} from '@oceanprotocol/react'
|
||||||
import Table from '../atoms/Table'
|
import Table from '../atoms/Table'
|
||||||
import Time from '../atoms/Time'
|
|
||||||
import Link from 'next/link'
|
|
||||||
import Price from '../atoms/Price'
|
import Price from '../atoms/Price'
|
||||||
import { fromWei } from 'web3-utils'
|
import { fromWei } from 'web3-utils'
|
||||||
import { findServiceByType } from '../../utils'
|
import { findServiceByType } from '../../utils'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Layout from '../../Layout'
|
import Layout from '../../components/Layout'
|
||||||
import AssetList from '../organisms/AssetList'
|
import AssetList from '../organisms/AssetList'
|
||||||
import { QueryResult } from '@oceanprotocol/squid/dist/node/aquarius/Aquarius'
|
import { QueryResult } from '@oceanprotocol/squid/dist/node/aquarius/Aquarius'
|
||||||
|
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Link from 'next/link'
|
import { Link } from 'gatsby'
|
||||||
import shortid from 'shortid'
|
import shortid from 'shortid'
|
||||||
import Layout from '../../Layout'
|
import Layout from '../../components/Layout'
|
||||||
import Button from '../atoms/Button'
|
import Button from '../atoms/Button'
|
||||||
import SearchBar from '../molecules/SearchBar'
|
import SearchBar from '../molecules/SearchBar'
|
||||||
import { title, description } from '../../../site.config'
|
|
||||||
import Explore from '../../images/explore.svg'
|
import Explore from '../../images/explore.svg'
|
||||||
import Publish from '../../images/publish.svg'
|
import Publish from '../../images/publish.svg'
|
||||||
import DataPool from '../../images/datapool.svg'
|
import DataPool from '../../images/datapool.svg'
|
||||||
import styles from './Home.module.css'
|
import styles from './Home.module.css'
|
||||||
|
import { useSiteMetadata } from '../../hooks/useSiteMetadata'
|
||||||
|
|
||||||
const actions = [
|
const actions = [
|
||||||
{
|
{
|
||||||
@ -36,25 +36,29 @@ const actions = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
const HomePage = () => {
|
export default function HomePage() {
|
||||||
|
const { siteTitle, siteDescription } = useSiteMetadata()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout noPageHeader>
|
<Layout noPageHeader>
|
||||||
<header className={styles.header}>
|
<header className={styles.header}>
|
||||||
<h1>{title}</h1>
|
<h1>{siteTitle}</h1>
|
||||||
<h2>{description}</h2>
|
<h2>{siteDescription}</h2>
|
||||||
<SearchBar large />
|
<SearchBar large />
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div className={styles.actions}>
|
<div className={styles.actions}>
|
||||||
{actions.map((action) => (
|
{actions.map((action) => (
|
||||||
<Link key={shortid.generate()} href={action.link}>
|
<Link key={shortid.generate()} to={action.link}>
|
||||||
<a
|
<a
|
||||||
className={action.comingSoon ? styles.comingSoon : styles.action}
|
className={action.comingSoon ? styles.comingSoon : styles.action}
|
||||||
>
|
>
|
||||||
{action.icon}
|
{action.icon}
|
||||||
<h3 className={styles.actionTitle}>{action.title}</h3>
|
<h3 className={styles.actionTitle}>{action.title}</h3>
|
||||||
<p>{action.text}</p>
|
<p>{action.text}</p>
|
||||||
<Button primary={action.primary}>{action.action}</Button>
|
<Button style={action.primary ? 'primary' : null}>
|
||||||
|
{action.action}
|
||||||
|
</Button>
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
@ -62,4 +66,3 @@ const HomePage = () => {
|
|||||||
</Layout>
|
</Layout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
export default HomePage
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Layout from '../../Layout'
|
import Layout from '../../components/Layout'
|
||||||
import PublishForm from '../molecules/PublishForm/PublishForm'
|
import PublishForm from '../molecules/PublishForm/PublishForm'
|
||||||
import styles from './Publish.module.css'
|
import styles from './Publish.module.css'
|
||||||
import Web3Feedback from '../molecules/Web3Feedback'
|
import Web3Feedback from '../molecules/Web3Feedback'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Layout from '../../Layout'
|
import Layout from '../../components/Layout'
|
||||||
import styles from './Transactions.module.css'
|
import styles from './Transactions.module.css'
|
||||||
import Web3Feedback from '../molecules/Web3Feedback'
|
import Web3Feedback from '../molecules/Web3Feedback'
|
||||||
import ConsumedList from '../organisms/ConsumedList'
|
import ConsumedList from '../organisms/ConsumedList'
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
import { DDO } from '@oceanprotocol/squid'
|
import { DDO } from '@oceanprotocol/squid'
|
||||||
import Link from 'next/link'
|
import { Link } from 'gatsby'
|
||||||
import Layout from '../../../Layout'
|
import Layout from '../../../components/Layout'
|
||||||
import { MetaDataMarket } from '../../../@types/MetaData'
|
import { MetaDataMarket } from '../../../@types/MetaData'
|
||||||
import Time from '../../atoms/Time'
|
import Time from '../../atoms/Time'
|
||||||
import Markdown from '../../atoms/Markdown'
|
import Markdown from '../../atoms/Markdown'
|
||||||
@ -67,7 +67,7 @@ const AssetDetailsPageMeta = ({
|
|||||||
</p>
|
</p>
|
||||||
{categories && (
|
{categories && (
|
||||||
<p>
|
<p>
|
||||||
<Link href={`/search?categories=["${categories[0]}"]`}>
|
<Link to={`/search?categories=["${categories[0]}"]`}>
|
||||||
<a>{categories[0]}</a>
|
<a>{categories[0]}</a>
|
||||||
</Link>
|
</Link>
|
||||||
</p>
|
</p>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { QueryResult } from '@oceanprotocol/squid/dist/node/aquarius/Aquarius'
|
import { QueryResult } from '@oceanprotocol/squid/dist/node/aquarius/Aquarius'
|
||||||
import Layout from '../../Layout'
|
import Layout from '../../components/Layout'
|
||||||
import PageHeader from '../molecules/PageHeader'
|
import PageHeader from '../molecules/PageHeader'
|
||||||
import SearchBar from '../molecules/SearchBar'
|
import SearchBar from '../molecules/SearchBar'
|
||||||
import AssetList from '../organisms/AssetList'
|
import AssetList from '../organisms/AssetList'
|
||||||
|
11
src/global/Styles.tsx
Normal file
11
src/global/Styles.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import React, { ReactElement, ReactNode } from 'react'
|
||||||
|
|
||||||
|
import '../global/styles.css'
|
||||||
|
|
||||||
|
export default function Styles({
|
||||||
|
children
|
||||||
|
}: {
|
||||||
|
children: ReactNode
|
||||||
|
}): ReactElement {
|
||||||
|
return <>{children}</>
|
||||||
|
}
|
8
src/helpers/wrapPageElement.tsx
Normal file
8
src/helpers/wrapPageElement.tsx
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import React, { ReactElement } from 'react'
|
||||||
|
import Styles from '../global/Styles'
|
||||||
|
|
||||||
|
const wrapPageElement = ({ element }: { element: ReactElement }) => (
|
||||||
|
<Styles>{element}</Styles>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default wrapPageElement
|
48
src/hooks/useSiteMetadata.ts
Normal file
48
src/hooks/useSiteMetadata.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { useStaticQuery, graphql } from 'gatsby'
|
||||||
|
|
||||||
|
const query = graphql`
|
||||||
|
query {
|
||||||
|
allFile(filter: { relativePath: { eq: "site.json" } }) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
childContentJson {
|
||||||
|
site {
|
||||||
|
siteTitle
|
||||||
|
siteTagline
|
||||||
|
siteDescription
|
||||||
|
siteUrl
|
||||||
|
siteIcon
|
||||||
|
siteImage {
|
||||||
|
childImageSharp {
|
||||||
|
original {
|
||||||
|
src
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
analyticsId
|
||||||
|
company {
|
||||||
|
name
|
||||||
|
address {
|
||||||
|
location
|
||||||
|
street
|
||||||
|
city
|
||||||
|
zip
|
||||||
|
country
|
||||||
|
}
|
||||||
|
}
|
||||||
|
social {
|
||||||
|
name
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export function useSiteMetadata() {
|
||||||
|
const data = useStaticQuery(query)
|
||||||
|
return data.allFile.edges[0].node.childContentJson.site
|
||||||
|
}
|
12
tests/unit/testRender.ts
Normal file
12
tests/unit/testRender.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { render } from '@testing-library/react'
|
||||||
|
import { ReactElement } from 'react'
|
||||||
|
|
||||||
|
const testRender = (component: ReactElement): void => {
|
||||||
|
it('renders without crashing', () => {
|
||||||
|
const { container } = render(component)
|
||||||
|
|
||||||
|
expect(container.firstChild).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default testRender
|
Loading…
Reference in New Issue
Block a user