1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00

search & asset teaser refactor

This commit is contained in:
Matthias Kretschmann 2020-07-01 18:13:32 +02:00
parent 8d4c5ca585
commit ff949c6a67
Signed by: m
GPG Key ID: 606EEEF3C479A91F
6 changed files with 130 additions and 128 deletions

View File

@ -1,72 +1,61 @@
import React from 'react' import React from 'react'
import { DDO } from '@oceanprotocol/squid'
import { Link } from 'gatsby' import { Link } from 'gatsby'
import Dotdotdot from 'react-dotdotdot' import Dotdotdot from 'react-dotdotdot'
import { import { MetaDataMarket } from '../../@types/MetaData'
AdditionalInformationMarket,
MetaDataMarket
} from '../../@types/MetaData'
import Tags from '../atoms/Tags' import Tags from '../atoms/Tags'
import Price from '../atoms/Price' import Price from '../atoms/Price'
import styles from './AssetTeaser.module.css' import styles from './AssetTeaser.module.css'
import Rating from '../atoms/Rating' import Rating from '../atoms/Rating'
declare type AssetTeaserProps = { declare type AssetTeaserProps = {
ddo: Partial<DDO> did: string
metadata: MetaDataMarket
} }
const AssetTeaser: React.FC<AssetTeaserProps> = ({ ddo }: AssetTeaserProps) => { const AssetTeaser: React.FC<AssetTeaserProps> = ({
const { attributes } = ddo.findServiceByType('metadata') did,
const { name, price } = attributes.main metadata
}: AssetTeaserProps) => {
const { name, price } = metadata.main
let description const {
let copyrightHolder description,
let tags copyrightHolder,
let categories tags,
let access categories,
access
} = metadata.additionalInformation
if (attributes && attributes.additionalInformation) { const { curation } = metadata
;({
description,
copyrightHolder,
tags,
categories,
access
} = attributes.additionalInformation as AdditionalInformationMarket)
}
const { curation } = attributes as MetaDataMarket
return ( return (
<article className={styles.teaser}> <article className={styles.teaser}>
<Link to={`/asset/${ddo.id}`}> <Link to={`/asset/${did}`} className={styles.link}>
<a className={styles.link}> <h1 className={styles.title}>{name}</h1>
<h1 className={styles.title}>{name}</h1> {access === 'Compute' && (
{access === 'Compute' && ( <div className={styles.accessLabel}>{access}</div>
<div className={styles.accessLabel}>{access}</div> )}
<Rating curation={curation} readonly />
<div className={styles.content}>
<Dotdotdot tagName="p" clamp={3}>
{description || ''}
</Dotdotdot>
{tags && (
<Tags className={styles.tags} items={tags} max={3} noLinks />
)} )}
<Rating curation={curation} readonly /> </div>
<div className={styles.content}> <footer className={styles.foot}>
<Dotdotdot tagName="p" clamp={3}> {categories && <p className={styles.type}>{categories[0]}</p>}
{description || ''}
</Dotdotdot>
{tags && ( <Price price={price} className={styles.price} />
<Tags className={styles.tags} items={tags} max={3} noLinks />
)}
</div>
<footer className={styles.foot}> <p className={styles.copyright}>
{categories && <p className={styles.type}>{categories[0]}</p>} Provided by <strong>{copyrightHolder}</strong>
</p>
<Price price={price} className={styles.price} /> </footer>
<p className={styles.copyright}>
Provided by <strong>{copyrightHolder}</strong>
</p>
</footer>
</a>
</Link> </Link>
</article> </article>
) )

View File

@ -5,6 +5,7 @@ import shortid from 'shortid'
import Pagination from '../molecules/Pagination' import Pagination from '../molecules/Pagination'
import { updateQueryStringParameter } from '../../utils' import { updateQueryStringParameter } from '../../utils'
import styles from './AssetList.module.css' import styles from './AssetList.module.css'
import { MetaDataMarket } from '../../@types/MetaData'
declare type AssetListProps = { declare type AssetListProps = {
queryResult: QueryResult queryResult: QueryResult
@ -13,40 +14,50 @@ declare type AssetListProps = {
const AssetList: React.FC<AssetListProps> = ({ queryResult }) => { const AssetList: React.FC<AssetListProps> = ({ queryResult }) => {
// 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) {
const newUrl = updateQueryStringParameter( // const newUrl = updateQueryStringParameter(
router.asPath, // router.asPath,
'page', // 'page',
`${pageIndex}` // `${pageIndex}`
) // )
return newUrl // return newUrl
} // }
// This is what iniitates a new search with new `page` // // This is what iniitates a new search with new `page`
// url parameter // // url parameter
function onPageChange(selected: number) { // function onPageChange(selected: number) {
const newUrl = updateQueryStringParameter( // const newUrl = updateQueryStringParameter(
router.asPath, // router.asPath,
'page', // 'page',
`${selected + 1}` // `${selected + 1}`
) // )
return router.push(newUrl) // return router.push(newUrl)
} // }
return ( return (
<> <>
<div className={styles.assetList}> <div className={styles.assetList}>
{queryResult.results && {queryResult.results &&
queryResult.results.map((ddo) => ( queryResult.results.map((ddo) => {
<AssetTeaser ddo={ddo} key={shortid.generate()} /> const { attributes }: MetaDataMarket = ddo.findServiceByType(
))} 'metadata'
)
return (
<AssetTeaser
did={ddo.id}
metadata={attributes}
key={shortid.generate()}
/>
)
})}
</div> </div>
<Pagination {/* <Pagination
totalPages={queryResult.totalPages} totalPages={queryResult.totalPages}
currentPage={queryResult.page} currentPage={queryResult.page}
hrefBuilder={hrefBuilder} hrefBuilder={hrefBuilder}
onPageChange={onPageChange} onPageChange={onPageChange}
/> /> */}
</> </>
) )
} }

View File

@ -0,0 +1,53 @@
import React, { ReactElement, useState, useEffect } from 'react'
import { QueryResult } from '@oceanprotocol/squid/dist/node/aquarius/Aquarius'
import SearchBar from '../../molecules/SearchBar'
import AssetList from '../../organisms/AssetList'
import { SearchPriceFilter } from '../../molecules/SearchPriceFilter'
import styles from './index.module.css'
import queryString from 'query-string'
import { getResults } from './utils'
export declare type SearchPageProps = {
text: string | string[]
tag: string | string[]
queryResult: QueryResult
}
export default function SearchPage({
location
}: {
location: Location
}): ReactElement {
const parsed = queryString.parse(location.search)
const { text, tag } = parsed
const [queryResult, setQueryResult] = useState<QueryResult>()
useEffect(() => {
async function initSearch() {
const results = await getResults(parsed)
setQueryResult(results)
}
initSearch()
}, [])
return (
<section className={styles.grid}>
<div className={styles.search}>
{text && <SearchBar initialValue={text as string} />}
</div>
<aside className={styles.side}>
<SearchPriceFilter />
</aside>
<div className={styles.results}>
{queryResult && queryResult.results.length > 0 ? (
<AssetList queryResult={queryResult} />
) : (
<div className={styles.empty}>No results found.</div>
)}
</div>
</section>
)
}

View File

@ -1,23 +1,10 @@
import React, { ReactElement, useState, useEffect } from 'react'
import { import {
QueryResult, SearchQuery,
SearchQuery QueryResult
} from '@oceanprotocol/squid/dist/node/aquarius/Aquarius' } from '@oceanprotocol/squid/dist/node/aquarius/Aquarius'
import SearchBar from '../molecules/SearchBar' import { priceQueryParamToWei } from '../../../utils'
import AssetList from '../organisms/AssetList'
import { SearchPriceFilter } from '../molecules/SearchPriceFilter'
import styles from './Search.module.css'
import { priceQueryParamToWei } from '../../utils'
import { Aquarius, Logger } from '@oceanprotocol/squid' import { Aquarius, Logger } from '@oceanprotocol/squid'
import { config } from '../../config/ocean' import { config } from '../../../config/ocean'
import queryString from 'query-string'
export declare type SearchPageProps = {
text: string | string[]
tag: string | string[]
queryResult: QueryResult
}
export function getSearchQuery( export function getSearchQuery(
page?: string | string[], page?: string | string[],
@ -72,41 +59,3 @@ export async function getResults(params: any): Promise<QueryResult> {
return queryResult return queryResult
} }
export default function SearchPage({
location
}: {
location: Location
}): ReactElement {
const parsed = queryString.parse(location.search)
const { text, tag } = parsed
const [queryResult, setQueryResult] = useState<QueryResult>()
useEffect(() => {
async function initSearch() {
const results = await getResults(parsed)
setQueryResult(results)
}
initSearch()
}, [])
return (
<section className={styles.grid}>
<div className={styles.search}>
{text && <SearchBar initialValue={text as string} />}
</div>
<aside className={styles.side}>
<SearchPriceFilter />
</aside>
<div className={styles.results}>
{queryResult && queryResult.results.length > 0 ? (
<AssetList queryResult={queryResult} />
) : (
<div className={styles.empty}>No results found.</div>
)}
</div>
</section>
)
}

View File

@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import { render, fireEvent } from '@testing-library/react' import { render, fireEvent } from '@testing-library/react'
import Search from '../../../src/components/templates/search' import Search from '../../../src/components/templates/Search'
import { import {
createHistory, createHistory,
createMemorySource, createMemorySource,