mirror of
https://github.com/oceanprotocol/commons.git
synced 2023-03-15 18:03:00 +01:00
base layout for all pages, meta title, start menu
This commit is contained in:
parent
ca73d8a43f
commit
905c76b5af
48
package-lock.json
generated
48
package-lock.json
generated
@ -1181,8 +1181,7 @@
|
||||
"@types/prop-types": {
|
||||
"version": "15.5.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.5.8.tgz",
|
||||
"integrity": "sha512-3AQoUxQcQtLHsK25wtTWIoIpgYjH3vSDroZOUr7PpCHw/jLY1RB9z9E8dBT/OSmwStVgkRNvdh+ZHNiomRieaw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-3AQoUxQcQtLHsK25wtTWIoIpgYjH3vSDroZOUr7PpCHw/jLY1RB9z9E8dBT/OSmwStVgkRNvdh+ZHNiomRieaw=="
|
||||
},
|
||||
"@types/q": {
|
||||
"version": "1.5.1",
|
||||
@ -1200,7 +1199,6 @@
|
||||
"version": "16.8.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.2.tgz",
|
||||
"integrity": "sha512-6mcKsqlqkN9xADrwiUz2gm9Wg4iGnlVGciwBRYFQSMWG6MQjhOZ/AVnxn+6v8nslFgfYTV8fNdE6XwKu6va5PA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/prop-types": "*",
|
||||
"csstype": "^2.2.0"
|
||||
@ -1215,6 +1213,14 @@
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/react-helmet": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-helmet/-/react-helmet-5.0.8.tgz",
|
||||
"integrity": "sha512-ZTr12eDAYI0yUiMx1K82EHqRYa8J1BOOLus+0gL+AkksUiIPwLE0wLiXa9FNqD8r9GXAi+yRPZImkRh1JNlTkQ==",
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/react-router": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-4.4.3.tgz",
|
||||
@ -5123,8 +5129,7 @@
|
||||
"csstype": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.2.tgz",
|
||||
"integrity": "sha512-Rl7PvTae0pflc1YtxtKbiSqq20Ts6vpIYOD5WBafl4y123DyHUeLrRdQP66sQW8/6gmX8jrYJLXwNeMqYVJcow==",
|
||||
"dev": true
|
||||
"integrity": "sha512-Rl7PvTae0pflc1YtxtKbiSqq20Ts6vpIYOD5WBafl4y123DyHUeLrRdQP66sQW8/6gmX8jrYJLXwNeMqYVJcow=="
|
||||
},
|
||||
"currently-unhandled": {
|
||||
"version": "0.4.1",
|
||||
@ -5293,8 +5298,7 @@
|
||||
"deep-equal": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
|
||||
"integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
|
||||
"dev": true
|
||||
"integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU="
|
||||
},
|
||||
"deep-extend": {
|
||||
"version": "0.6.0",
|
||||
@ -6432,6 +6436,11 @@
|
||||
"clone-regexp": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"exenv": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
|
||||
"integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50="
|
||||
},
|
||||
"exit": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
|
||||
@ -16508,6 +16517,17 @@
|
||||
"integrity": "sha512-7kEBKwU9R8fKnZJBRa5RSIfay4KJwnYvKB6gODGicUmDSAhQJ7Tdnll5S0RLtYrzRfMVXlqYw61rzrSpP4ThLQ==",
|
||||
"dev": true
|
||||
},
|
||||
"react-helmet": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-5.2.0.tgz",
|
||||
"integrity": "sha1-qBgR3yExOm1VxfBYxK66XW89l6c=",
|
||||
"requires": {
|
||||
"deep-equal": "^1.0.1",
|
||||
"object-assign": "^4.1.1",
|
||||
"prop-types": "^15.5.4",
|
||||
"react-side-effect": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"react-router": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz",
|
||||
@ -16866,6 +16886,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-side-effect": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-1.1.5.tgz",
|
||||
"integrity": "sha512-Z2ZJE4p/jIfvUpiUMRydEVpQRf2f8GMHczT6qLcARmX7QRb28JDBTpnM2g/i5y/p7ZDEXYGHWg0RbhikE+hJRw==",
|
||||
"requires": {
|
||||
"exenv": "^1.2.1",
|
||||
"shallowequal": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"read-pkg": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
|
||||
@ -18617,6 +18646,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"shallowequal": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
|
||||
"integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
|
||||
|
@ -16,11 +16,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@oceanprotocol/squid": "^0.2.8",
|
||||
"@types/react-helmet": "^5.0.8",
|
||||
"classnames": "^2.2.6",
|
||||
"eslint": "^5.6.0",
|
||||
"query-string": "^6.2.0",
|
||||
"react": "^16.8.1",
|
||||
"react-dom": "^16.8.1",
|
||||
"react-helmet": "^5.2.0",
|
||||
"react-router-dom": "^4.3.1",
|
||||
"slugify": "^1.3.4",
|
||||
"web3": "^1.0.0-beta.43"
|
||||
|
@ -1,3 +1,9 @@
|
||||
.app {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
> * {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
31
src/App.tsx
31
src/App.tsx
@ -1,10 +1,13 @@
|
||||
import React, { Component } from 'react'
|
||||
import Web3 from 'web3'
|
||||
import styles from './App.module.scss'
|
||||
import { BrowserRouter as Router } from 'react-router-dom'
|
||||
import Header from './components/Header'
|
||||
import Footer from './components/Footer'
|
||||
import { User } from './context/User'
|
||||
import { provideOcean } from './ocean'
|
||||
import Routes from './Routes'
|
||||
import './styles/global.scss'
|
||||
import styles from './App.module.scss'
|
||||
|
||||
import { nodeHost, nodePort, nodeScheme } from './config'
|
||||
|
||||
@ -47,16 +50,6 @@ class App extends Component<{}, AppState> {
|
||||
this.bootstrap()
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<div className={styles.app}>
|
||||
<User.Provider value={this.state}>
|
||||
<Routes />
|
||||
</User.Provider>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private startLoginProcess = async () => {
|
||||
this.setState({ isLoading: true })
|
||||
if (window.web3) {
|
||||
@ -107,6 +100,22 @@ class App extends Component<{}, AppState> {
|
||||
ocean
|
||||
})
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<div className={styles.app}>
|
||||
<User.Provider value={this.state}>
|
||||
<Router>
|
||||
<>
|
||||
<Header />
|
||||
<Routes />
|
||||
<Footer />
|
||||
</>
|
||||
</Router>
|
||||
</User.Provider>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default App
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
|
||||
import { Route, Switch } from 'react-router-dom'
|
||||
|
||||
import About from './pages/About'
|
||||
import Details from './pages/Details'
|
||||
@ -10,7 +10,6 @@ import Search from './pages/Search'
|
||||
import Styleguide from './pages/Styleguide'
|
||||
|
||||
const Routes = () => (
|
||||
<Router>
|
||||
<Switch>
|
||||
<Route exact component={Home} path="/" />
|
||||
<Route component={Styleguide} path="/styleguide" />
|
||||
@ -20,7 +19,6 @@ const Routes = () => (
|
||||
<Route component={Details} path="/asset/:did" />
|
||||
<Route component={NotFound} />
|
||||
</Switch>
|
||||
</Router>
|
||||
)
|
||||
|
||||
export default Routes
|
||||
|
16
src/components/Content.module.scss
Normal file
16
src/components/Content.module.scss
Normal file
@ -0,0 +1,16 @@
|
||||
@import '../styles/variables';
|
||||
|
||||
.content {
|
||||
padding: 0 $spacer / 2;
|
||||
max-width: $break-point--small;
|
||||
margin: 0 auto;
|
||||
|
||||
@media (min-width: $break-point--small) {
|
||||
padding: 0 $spacer;
|
||||
}
|
||||
}
|
||||
|
||||
.wide {
|
||||
composes: content;
|
||||
max-width: $break-point--large;
|
||||
}
|
8
src/components/Content.tsx
Normal file
8
src/components/Content.tsx
Normal file
@ -0,0 +1,8 @@
|
||||
import React from 'react'
|
||||
import styles from './Content.module.scss'
|
||||
|
||||
const Content = ({ wide, children }: { wide?: boolean; children: any }) => (
|
||||
<div className={wide ? styles.wide : styles.content}>{children}</div>
|
||||
)
|
||||
|
||||
export default Content
|
58
src/components/Footer.module.scss
Normal file
58
src/components/Footer.module.scss
Normal file
@ -0,0 +1,58 @@
|
||||
@import '../styles/variables';
|
||||
|
||||
.footer {
|
||||
color: $brand-grey-light;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding-top: $spacer;
|
||||
padding-bottom: $spacer;
|
||||
align-self: flex-end;
|
||||
|
||||
> section {
|
||||
align-self: flex-end;
|
||||
|
||||
@media screen and (min-width: $break-point--small) {
|
||||
text-align: left;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
&,
|
||||
small {
|
||||
font-size: $font-size-small;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: $brand-grey;
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
display: inline-block;
|
||||
width: $font-size-large;
|
||||
height: $font-size-large;
|
||||
}
|
||||
}
|
||||
|
||||
.links {
|
||||
margin-top: $spacer / 2;
|
||||
|
||||
@media screen and (min-width: $break-point--small) {
|
||||
text-align: right;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
margin: 0 $spacer / 2;
|
||||
display: inline-block;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
27
src/components/Footer.tsx
Normal file
27
src/components/Footer.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import React from 'react'
|
||||
import Content from '../components/Content'
|
||||
import styles from './Footer.module.scss'
|
||||
|
||||
import meta from '../data/meta.json'
|
||||
|
||||
const Footer = () => (
|
||||
<footer className={styles.footer}>
|
||||
<Content>
|
||||
<small>
|
||||
© {new Date().getFullYear()}{' '}
|
||||
<a href={meta.social[0].url}>{meta.company}</a> — All
|
||||
Rights Reserved
|
||||
</small>
|
||||
|
||||
<nav className={styles.links}>
|
||||
{meta.social.map(site => (
|
||||
<a key={site.title} href={site.url}>
|
||||
{site.title}
|
||||
</a>
|
||||
))}
|
||||
</nav>
|
||||
</Content>
|
||||
</footer>
|
||||
)
|
||||
|
||||
export default Footer
|
2
src/components/Header.module.scss
Normal file
2
src/components/Header.module.scss
Normal file
@ -0,0 +1,2 @@
|
||||
.header {
|
||||
}
|
22
src/components/Header.tsx
Normal file
22
src/components/Header.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import React from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import Content from '../components/Content'
|
||||
import styles from './Header.module.scss'
|
||||
|
||||
import menu from '../data/menu.json'
|
||||
|
||||
const Header = () => (
|
||||
<header className={styles.header}>
|
||||
<Content wide>
|
||||
<nav>
|
||||
{menu.map(item => (
|
||||
<Link key={item.title} to={item.link}>
|
||||
{item.title}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
</Content>
|
||||
</header>
|
||||
)
|
||||
|
||||
export default Header
|
@ -2,9 +2,7 @@
|
||||
|
||||
.form {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
margin-top: 4rem;
|
||||
max-width: 40rem;
|
||||
|
||||
fieldset {
|
||||
border: 0;
|
||||
|
14
src/data/menu.json
Normal file
14
src/data/menu.json
Normal file
@ -0,0 +1,14 @@
|
||||
[
|
||||
{
|
||||
"title": "Home",
|
||||
"link": "/"
|
||||
},
|
||||
{
|
||||
"title": "Publish",
|
||||
"link": "/publish"
|
||||
},
|
||||
{
|
||||
"title": "About",
|
||||
"link": "/about"
|
||||
}
|
||||
]
|
11
src/data/meta.json
Normal file
11
src/data/meta.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"title": "Commons Marketplace",
|
||||
"description": "",
|
||||
"company": "Ocean Protocol Foundation Ltd.",
|
||||
"social": [
|
||||
{
|
||||
"title": "Site",
|
||||
"url": "https://oceanprotocol.com"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
@import '../styles/variables';
|
||||
|
||||
.about {
|
||||
background: $brand-black;
|
||||
color: $brand-white;
|
||||
min-height: calc(100vh - #{$page-frame} * 2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
> div {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
@ -1,18 +1,9 @@
|
||||
import React, { Component } from 'react'
|
||||
import Button from '../components/atoms/Button'
|
||||
import styles from './About.module.scss'
|
||||
import Page from '../templates/Page'
|
||||
|
||||
class About extends Component {
|
||||
public render() {
|
||||
return (
|
||||
<div className={styles.about}>
|
||||
<Button>I am a button</Button>
|
||||
<Button primary>I am a primary button</Button>
|
||||
<Button href="https://hello.com">
|
||||
I am a link disguised as a button
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
return <Page title="About">Hello About</Page>
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Logger } from '@oceanprotocol/squid'
|
||||
import React, { Component } from 'react'
|
||||
import Page from '../templates/Page'
|
||||
import Button from '../components/atoms/Button'
|
||||
import { User } from '../context/User'
|
||||
|
||||
@ -64,13 +65,13 @@ export default class Details extends Component<DetailsProps, DetailsState> {
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
<Page title={'Details'}>
|
||||
{this.state.metadata ? (
|
||||
this.showDetails(this.state.ddo)
|
||||
) : (
|
||||
<div>Loading</div>
|
||||
)}
|
||||
</>
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import { Link } from 'react-router-dom'
|
||||
import Button from '../components/atoms/Button'
|
||||
import Form from '../components/atoms/Form/Form'
|
||||
import Input from '../components/atoms/Form/Input'
|
||||
import Content from '../components/Content'
|
||||
import styles from './Home.module.scss'
|
||||
|
||||
interface HomeState {
|
||||
@ -19,8 +20,7 @@ class Home extends Component<HomeProps, HomeState> {
|
||||
public render() {
|
||||
return (
|
||||
<div className={styles.home}>
|
||||
<div>Home</div>
|
||||
|
||||
<Content>
|
||||
<Link to={'/styleguide'}>Styleguide</Link>
|
||||
|
||||
<div>
|
||||
@ -35,6 +35,7 @@ class Home extends Component<HomeProps, HomeState> {
|
||||
<Button>Search</Button>
|
||||
</Form>
|
||||
</div>
|
||||
</Content>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
import React, { Component } from 'react'
|
||||
import Page from '../templates/Page'
|
||||
|
||||
class NotFound extends Component {
|
||||
public render() {
|
||||
return <div>Not found</div>
|
||||
return <Page title="404 - Not Found">Not Found</Page>
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { ChangeEvent, Component, FormEvent } from 'react'
|
||||
import Page from '../templates/Page'
|
||||
import Button from '../components/atoms/Button'
|
||||
import Form from '../components/atoms/Form/Form'
|
||||
import Input from '../components/atoms/Form/Input'
|
||||
@ -115,8 +116,7 @@ class Publish extends Component<{}, PublishState> {
|
||||
const entries = Object.entries(form.fields)
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>Publish</h1>
|
||||
<Page title="Publish">
|
||||
<Form
|
||||
title={form.title}
|
||||
description={form.description}
|
||||
@ -138,7 +138,7 @@ class Publish extends Component<{}, PublishState> {
|
||||
}
|
||||
</User.Consumer>
|
||||
</Form>
|
||||
</div>
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import queryString from 'query-string'
|
||||
import React, { Component } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import Page from '../templates/Page'
|
||||
import { provideOcean } from '../ocean'
|
||||
|
||||
interface SearchState {
|
||||
@ -12,7 +13,7 @@ interface SearchProps {
|
||||
history: any
|
||||
}
|
||||
|
||||
class Search extends Component<SearchProps, SearchState> {
|
||||
export default class Search extends Component<SearchProps, SearchState> {
|
||||
public state = { results: [] }
|
||||
|
||||
public async componentDidMount() {
|
||||
@ -32,18 +33,6 @@ class Search extends Component<SearchProps, SearchState> {
|
||||
this.setState({ results: assets })
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
{this.state.results.length ? (
|
||||
this.state.results.map(asset => this.renderAssetBox(asset))
|
||||
) : (
|
||||
<div>No data sets yet</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
private renderAssetBox = (asset: any) => {
|
||||
const { metadata } = asset.findServiceByType('Metadata')
|
||||
return (
|
||||
@ -54,6 +43,16 @@ class Search extends Component<SearchProps, SearchState> {
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Search
|
||||
public render() {
|
||||
return (
|
||||
<Page title="Search Results" wide>
|
||||
{this.state.results.length ? (
|
||||
this.state.results.map(asset => this.renderAssetBox(asset))
|
||||
) : (
|
||||
<div>No data sets yet</div>
|
||||
)}
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
@import '../styles/variables';
|
||||
|
||||
.page {
|
||||
margin: 0 auto;
|
||||
max-width: 40rem;
|
||||
padding: $spacer;
|
||||
}
|
@ -2,7 +2,7 @@ import React, { Component } from 'react'
|
||||
import Button from '../components/atoms/Button'
|
||||
import Form from '../components/atoms/Form/Form'
|
||||
import Input from '../components/atoms/Form/Input'
|
||||
import styles from './Styleguide.module.scss'
|
||||
import Page from '../templates/Page'
|
||||
|
||||
import form from '../data/form-styleguide.json'
|
||||
|
||||
@ -24,9 +24,7 @@ class Styleguide extends Component {
|
||||
public render() {
|
||||
const entries = Object.entries(form.fields)
|
||||
return (
|
||||
<div className={styles.page}>
|
||||
<h1>Styleguide</h1>
|
||||
|
||||
<Page title="Styleguide">
|
||||
<Button>I am a button</Button>
|
||||
<Button primary>I am a primary button</Button>
|
||||
<Button href="https://hello.com">
|
||||
@ -36,7 +34,7 @@ class Styleguide extends Component {
|
||||
<Form title={form.title} description={form.description}>
|
||||
{this.formFields(entries)}
|
||||
</Form>
|
||||
</div>
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -332,10 +332,3 @@ pre {
|
||||
background: $brand-grey-light;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
// Gatsby specific
|
||||
/////////////////////////////////////
|
||||
|
||||
.anchor {
|
||||
margin-top: .6rem;
|
||||
}
|
||||
|
9
src/templates/Page.module.scss
Normal file
9
src/templates/Page.module.scss
Normal file
@ -0,0 +1,9 @@
|
||||
@import '../styles/variables';
|
||||
|
||||
.header {
|
||||
margin-bottom: $spacer;
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
31
src/templates/Page.tsx
Normal file
31
src/templates/Page.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
import React from 'react'
|
||||
import Helmet from 'react-helmet'
|
||||
import Content from '../components/Content'
|
||||
import styles from './Page.module.scss'
|
||||
import meta from '../data/meta.json'
|
||||
|
||||
const Page = ({
|
||||
title,
|
||||
wide,
|
||||
children
|
||||
}: {
|
||||
title: string
|
||||
children: any
|
||||
wide?: boolean
|
||||
}) => (
|
||||
<>
|
||||
<Helmet defaultTitle={meta.title} titleTemplate={`%s - ${meta.title}`}>
|
||||
<title>{title}</title>
|
||||
</Helmet>
|
||||
|
||||
<Content wide={wide}>
|
||||
<header className={styles.header}>
|
||||
<h1>{title}</h1>
|
||||
</header>
|
||||
|
||||
{children}
|
||||
</Content>
|
||||
</>
|
||||
)
|
||||
|
||||
export default Page
|
Loading…
Reference in New Issue
Block a user