1
0
mirror of https://github.com/oceanprotocol/commons.git synced 2023-03-15 18:03:00 +01:00

category search, make multiple layouts on one page possible

This commit is contained in:
Matthias Kretschmann 2019-05-15 16:45:32 +02:00
parent 13c2c9b68a
commit 1b1ac5c9ef
Signed by: m
GPG Key ID: 606EEEF3C479A91F
10 changed files with 188 additions and 171 deletions

View File

@ -24,9 +24,9 @@ const Route = ({
{description && <meta name="description" content={description} />} {description && <meta name="description" content={description} />}
</Helmet> </Helmet>
<Content wide={wide}> <article>
<article> <header className={styles.header}>
<header className={styles.header}> <Content wide={wide}>
<h1 className={styles.title}>{title}</h1> <h1 className={styles.title}>{title}</h1>
{description && ( {description && (
<p <p
@ -36,11 +36,11 @@ const Route = ({
}} }}
/> />
)} )}
</header> </Content>
</header>
{children} {children}
</article> </article>
</Content>
</div> </div>
) )

View File

@ -1,5 +1,6 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import Route from '../components/templates/Route' import Route from '../components/templates/Route'
import Content from '../components/atoms/Content'
class About extends Component { class About extends Component {
public render() { public render() {
@ -8,28 +9,31 @@ class About extends Component {
title="About" title="About"
description="A marketplace to find and publish open data sets in the Ocean Network." description="A marketplace to find and publish open data sets in the Ocean Network."
> >
<p> <Content>
Commons is built on top of the Ocean{' '} <p>
<a href="https://docs.oceanprotocol.com/concepts/testnets/#the-nile-testnet"> Commons is built on top of the Ocean{' '}
Nile test network <a href="https://docs.oceanprotocol.com/concepts/testnets/#the-nile-testnet">
</a>{' '} Nile test network
and is targeted at enthusiastic data scientists with some </a>{' '}
crypto experience. It can be used with any Web3-capable and is targeted at enthusiastic data scientists with
browser, like Firefox with MetaMask installed. some crypto experience. It can be used with any
</p> Web3-capable browser, like Firefox with MetaMask
installed.
</p>
<ul> <ul>
<li> <li>
<a href="https://blog.oceanprotocol.com/the-commons-marketplace-c57a44288314"> <a href="https://blog.oceanprotocol.com/the-commons-marketplace-c57a44288314">
Read the blog post Read the blog post
</a> </a>
</li> </li>
<li> <li>
<a href="https://github.com/oceanprotocol/commons"> <a href="https://github.com/oceanprotocol/commons">
Check out oceanprotocol/commons on GitHub Check out oceanprotocol/commons on GitHub
</a> </a>
</li> </li>
</ul> </ul>
</Content>
</Route> </Route>
) )
} }

View File

@ -5,6 +5,7 @@ import Spinner from '../../components/atoms/Spinner'
import { User } from '../../context' import { User } from '../../context'
import AssetDetails from './AssetDetails' import AssetDetails from './AssetDetails'
import stylesApp from '../../App.module.scss' import stylesApp from '../../App.module.scss'
import Content from '../../components/atoms/Content'
interface DetailsProps { interface DetailsProps {
location: Location location: Location
@ -46,7 +47,9 @@ export default class Details extends Component<DetailsProps, DetailsState> {
return metadata.base.name !== '' ? ( return metadata.base.name !== '' ? (
<Route title={metadata.base.name}> <Route title={metadata.base.name}>
<AssetDetails metadata={metadata} ddo={ddo} /> <Content>
<AssetDetails metadata={metadata} ddo={ddo} />
</Content>
</Route> </Route>
) : ( ) : (
<div className={stylesApp.loader}> <div className={stylesApp.loader}>

View File

@ -6,6 +6,7 @@ import Spinner from '../components/atoms/Spinner'
import { User } from '../context' import { User } from '../context'
import Web3message from '../components/organisms/Web3message' import Web3message from '../components/organisms/Web3message'
import styles from './Faucet.module.scss' import styles from './Faucet.module.scss'
import Content from '../components/atoms/Content'
interface FaucetState { interface FaucetState {
isLoading: boolean isLoading: boolean
@ -101,19 +102,21 @@ export default class Faucet extends PureComponent<{}, FaucetState> {
title="Faucet" title="Faucet"
description="Shower yourself with some Ether for Ocean's Nile test network." description="Shower yourself with some Ether for Ocean's Nile test network."
> >
<Web3message /> <Content>
<Web3message />
<div className={styles.action}> <div className={styles.action}>
{isLoading ? ( {isLoading ? (
<Spinner message="Getting Ether..." /> <Spinner message="Getting Ether..." />
) : error ? ( ) : error ? (
<this.Error /> <this.Error />
) : success ? ( ) : success ? (
<this.Success /> <this.Success />
) : ( ) : (
isWeb3 && <this.Action /> isWeb3 && <this.Action />
)} )}
</div> </div>
</Content>
</Route> </Route>
) )
} }

View File

@ -3,16 +3,18 @@ import Route from '../components/templates/Route'
import AssetsUser from '../components/organisms/AssetsUser' import AssetsUser from '../components/organisms/AssetsUser'
import Web3message from '../components/organisms/Web3message' import Web3message from '../components/organisms/Web3message'
import { User } from '../context' import { User } from '../context'
import Content from '../components/atoms/Content'
export default class History extends Component { export default class History extends Component {
public render() { public render() {
return ( return (
<Route title="History"> <Route title="History">
{(!this.context.isLogged || !this.context.isOceanNetwork) && ( <Content>
<Web3message /> {(!this.context.isLogged ||
)} !this.context.isOceanNetwork) && <Web3message />}
<AssetsUser list /> <AssetsUser list />
</Content>
</Route> </Route>
) )
} }

View File

@ -1,4 +1,5 @@
import React, { ChangeEvent, Component, FormEvent } from 'react' import React, { ChangeEvent, Component, FormEvent } from 'react'
import { Link } from 'react-router-dom'
import { User } from '../context' import { User } from '../context'
import { Logger } from '@oceanprotocol/squid' import { Logger } from '@oceanprotocol/squid'
import Spinner from '../components/atoms/Spinner' import Spinner from '../components/atoms/Spinner'
@ -11,7 +12,9 @@ import Route from '../components/templates/Route'
import styles from './Home.module.scss' import styles from './Home.module.scss'
import meta from '../data/meta.json' import meta from '../data/meta.json'
import formPublish from '../data/form-publish.json'
import { History } from 'history' import { History } from 'history'
import Content from '../components/atoms/Content'
interface HomeProps { interface HomeProps {
history: History history: History
@ -19,46 +22,15 @@ interface HomeProps {
interface HomeState { interface HomeState {
search?: string search?: string
categoryAssets?: Array<any> categoryAssets?: any[]
isLoading?: boolean isLoading?: boolean
} }
const categories = [ const categories =
'AI For Good', (formPublish.steps[1].fields &&
'Image Recognition', formPublish.steps[1].fields.categories &&
'Dataset Of Datasets', formPublish.steps[1].fields.categories.options) ||
'Language', []
'Performing Arts',
'Visual Arts & Design',
'Philosophy',
'History',
'Theology',
'Anthropology & Archeology',
'Sociology',
'Psychology',
'Politics',
'Interdisciplinary',
'Economics & Finance',
'Demography',
'Biology',
'Chemistry',
'Physics & Energy',
'Earth & Climate',
'Space & Astronomy',
'Mathematics',
'Computer Technology',
'Engineering',
'Agriculture & Bio Engineering',
'Transportation',
'Urban Planning',
'Medicine',
'Business & Management',
'Sports & Recreation',
'Communication & Journalism',
'Deep Learning',
'Law',
'Other'
]
class Home extends Component<HomeProps, HomeState> { class Home extends Component<HomeProps, HomeState> {
public state = { public state = {
@ -78,7 +50,7 @@ class Home extends Component<HomeProps, HomeState> {
offset: 25, offset: 25,
page: 1, page: 1,
query: { query: {
categories: ["Economics & Finance"], categories: ['Engineering'],
price: [-1, 1] price: [-1, 1]
}, },
sort: { sort: {
@ -99,55 +71,59 @@ class Home extends Component<HomeProps, HomeState> {
} }
public render() { public render() {
const { categoryAssets, isLoading, search } = this.state
return ( return (
<Route <Route
title={meta.title} title={meta.title}
description={meta.description} description={meta.description}
className={styles.home} className={styles.home}
wide
> >
<Form onSubmit={this.searchAssets} minimal> <Content>
<Input <Form onSubmit={this.searchAssets} minimal>
type="search" <Input
name="search" type="search"
label="Search for data sets" name="search"
placeholder="e.g. shapes of plants" label="Search for data sets"
value={this.state.search} placeholder="e.g. shapes of plants"
onChange={this.inputChange} value={search}
group={ onChange={this.inputChange}
<Button primary disabled={!this.state.search}> group={
Search <Button primary disabled={!search}>
</Button> Search
} </Button>
/> }
</Form> />
<div> </Form>
</Content>
<Content wide>
<h4>AI for Good</h4> <h4>AI for Good</h4>
<div> <div>
{ {isLoading ? (
this.state.isLoading ? ( <Spinner message="Loading..." />
<Spinner message="Loading..." /> ) : categoryAssets && categoryAssets.length ? (
) : this.state.categoryAssets && this.state.categoryAssets.length ? ( <div className={styles.results}>
<div className={styles.results}> {categoryAssets.map((asset: any) => (
{this.state.categoryAssets.map((asset: any) => ( <Asset key={asset.id} asset={asset} />
<Asset key={asset.id} asset={asset} /> ))}
))} </div>
</div> ) : (
) : ( <div>No data sets found.</div>
<div>No data sets found.</div> )}
)
}
</div> </div>
<h4>Explore Categories</h4> <h4>Explore Categories</h4>
<div className={styles.categories}> <div className={styles.categories}>
{categories.map((category: string) => ( {categories.map((category: string) => (
<div key={category}> <Link
<CategoryImage category={category}/> to={`/search?categories=${category}`}
key={category}
>
<CategoryImage category={category} />
{category} {category}
</div> </Link>
))} ))}
</div> </div>
</div> </Content>
</Route> </Route>
) )
} }

View File

@ -1,9 +1,14 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import Route from '../components/templates/Route' import Route from '../components/templates/Route'
import Content from '../components/atoms/Content'
class NotFound extends Component { class NotFound extends Component {
public render() { public render() {
return <Route title="404 - Not Found">Not Found</Route> return (
<Route title="404 - Not Found">
<Content>Not Found</Content>
</Route>
)
} }
} }

View File

@ -10,6 +10,7 @@ import Progress from './Progress'
import ReactGA from 'react-ga' import ReactGA from 'react-ga'
import { steps } from '../../data/form-publish.json' import { steps } from '../../data/form-publish.json'
import Content from '../../components/atoms/Content'
type AssetType = 'dataset' | 'algorithm' | 'container' | 'workflow' | 'other' type AssetType = 'dataset' | 'algorithm' | 'container' | 'workflow' | 'other'
@ -319,33 +320,37 @@ class Publish extends Component<{}, PublishState> {
title="Publish" title="Publish"
description="Publish a new data set into the Ocean Protocol Network." description="Publish a new data set into the Ocean Protocol Network."
> >
{(!this.context.isLogged || !this.context.isOceanNetwork) && ( <Content>
<Web3message /> {(!this.context.isLogged ||
)} !this.context.isOceanNetwork) && <Web3message />}
<Progress steps={steps} currentStep={this.state.currentStep} /> <Progress
steps={steps}
currentStep={this.state.currentStep}
/>
<Form onSubmit={this.registerAsset}> <Form onSubmit={this.registerAsset}>
{steps.map((step: any, index: number) => ( {steps.map((step: any, index: number) => (
<Step <Step
key={index} key={index}
index={index} index={index}
title={step.title} title={step.title}
description={step.description} description={step.description}
currentStep={this.state.currentStep} currentStep={this.state.currentStep}
fields={step.fields} fields={step.fields}
inputChange={this.inputChange} inputChange={this.inputChange}
inputToArrayChange={this.inputToArrayChange} inputToArrayChange={this.inputToArrayChange}
state={this.state} state={this.state}
next={this.next} next={this.next}
prev={this.prev} prev={this.prev}
totalSteps={steps.length} totalSteps={steps.length}
tryAgain={this.tryAgain} tryAgain={this.tryAgain}
toStart={this.toStart} toStart={this.toStart}
content={step.content} content={step.content}
/> />
))} ))}
</Form> </Form>
</Content>
</Route> </Route>
) )
} }

View File

@ -8,6 +8,7 @@ import { User } from '../context'
import Asset from '../components/molecules/Asset' import Asset from '../components/molecules/Asset'
import Pagination from '../components/molecules/Pagination' import Pagination from '../components/molecules/Pagination'
import styles from './Search.module.scss' import styles from './Search.module.scss'
import Content from '../components/atoms/Content'
interface SearchProps { interface SearchProps {
location: Location location: Location
@ -22,6 +23,7 @@ interface SearchState {
currentPage: number currentPage: number
isLoading: boolean isLoading: boolean
searchTerm: string searchTerm: string
searchCategories: string
} }
export default class Search extends PureComponent<SearchProps, SearchState> { export default class Search extends PureComponent<SearchProps, SearchState> {
@ -32,17 +34,25 @@ export default class Search extends PureComponent<SearchProps, SearchState> {
totalPages: 1, totalPages: 1,
currentPage: 1, currentPage: 1,
isLoading: true, isLoading: true,
searchTerm: '' searchTerm: '',
searchCategories: ''
} }
public async componentDidMount() { public async componentDidMount() {
const searchTerm = await queryString.parse(this.props.location.search) const searchTerm = await queryString.parse(this.props.location.search)
.text .text
const searchPage = queryString.parse(this.props.location.search).page const searchPage = await queryString.parse(this.props.location.search)
.page
const searchCategories = await queryString.parse(
this.props.location.search
).categories
await this.setState({ if (searchTerm || searchCategories) {
searchTerm: encodeURIComponent(`${searchTerm}`) await this.setState({
}) searchTerm: encodeURIComponent(`${searchTerm}`),
searchCategories: `${searchCategories}`
})
}
// switch to respective page if query string is present // switch to respective page if query string is present
if (searchPage) { if (searchPage) {
@ -55,12 +65,14 @@ export default class Search extends PureComponent<SearchProps, SearchState> {
private searchAssets = async () => { private searchAssets = async () => {
const { ocean } = this.context const { ocean } = this.context
const { offset, currentPage, searchTerm, searchCategories } = this.state
const searchQuery = { const searchQuery = {
offset: this.state.offset, offset,
page: this.state.currentPage, page: currentPage,
query: { query: {
text: [decodeURIComponent(this.state.searchTerm)], text: [decodeURIComponent(searchTerm)],
categories: [decodeURIComponent(searchCategories)],
price: [-1, 1] price: [-1, 1]
}, },
sort: { sort: {
@ -113,6 +125,7 @@ export default class Search extends PureComponent<SearchProps, SearchState> {
return ( return (
<Route title="Search" wide> <Route title="Search" wide>
<Content wide>
{totalResults > 0 && ( {totalResults > 0 && (
<h2 <h2
className={styles.resultsTitle} className={styles.resultsTitle}
@ -120,16 +133,17 @@ export default class Search extends PureComponent<SearchProps, SearchState> {
__html: `${totalResults} results for <span>${decodeURIComponent( __html: `${totalResults} results for <span>${decodeURIComponent(
this.state.searchTerm this.state.searchTerm
)}</span>` )}</span>`
}} }}
/> />
)} )}
{this.renderResults()} {this.renderResults()}
<Pagination <Pagination
totalPages={totalPages} totalPages={totalPages}
currentPage={currentPage} currentPage={currentPage}
handlePageClick={this.handlePageClick} handlePageClick={this.handlePageClick}
/> />
</Content>
</Route> </Route>
) )
} }

View File

@ -5,6 +5,7 @@ import Input from '../components/atoms/Form/Input'
import Route from '../components/templates/Route' import Route from '../components/templates/Route'
import styles from './Styleguide.module.scss' import styles from './Styleguide.module.scss'
import form from '../data/form-styleguide.json' import form from '../data/form-styleguide.json'
import Content from '../components/atoms/Content'
class Styleguide extends Component { class Styleguide extends Component {
public formFields = (entries: any[]) => public formFields = (entries: any[]) =>
@ -25,18 +26,22 @@ class Styleguide extends Component {
const entries = Object.entries(form.fields) const entries = Object.entries(form.fields)
return ( return (
<Route title="Styleguide" className={styles.styleguide}> <Route title="Styleguide" className={styles.styleguide}>
<div className={styles.buttons}> <Content>
<Button>I am a button</Button> <div className={styles.buttons}>
<Button primary>I am a primary button</Button> <Button>I am a button</Button>
<Button href="https://hello.com"> <Button primary>I am a primary button</Button>
I am a link disguised as a button <Button href="https://hello.com">
</Button> I am a link disguised as a button
<Button link>I am a button disguised as a text link</Button> </Button>
</div> <Button link>
I am a button disguised as a text link
</Button>
</div>
<Form title={form.title} description={form.description}> <Form title={form.title} description={form.description}>
{this.formFields(entries)} {this.formFields(entries)}
</Form> </Form>
</Content>
</Route> </Route>
) )
} }