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:
parent
8d4c5ca585
commit
ff949c6a67
@ -1,46 +1,36 @@
|
|||||||
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
|
|
||||||
let tags
|
|
||||||
let categories
|
|
||||||
let access
|
|
||||||
|
|
||||||
if (attributes && attributes.additionalInformation) {
|
|
||||||
;({
|
|
||||||
description,
|
description,
|
||||||
copyrightHolder,
|
copyrightHolder,
|
||||||
tags,
|
tags,
|
||||||
categories,
|
categories,
|
||||||
access
|
access
|
||||||
} = attributes.additionalInformation as AdditionalInformationMarket)
|
} = metadata.additionalInformation
|
||||||
}
|
|
||||||
|
|
||||||
const { curation } = attributes as MetaDataMarket
|
const { curation } = metadata
|
||||||
|
|
||||||
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>
|
||||||
@ -66,7 +56,6 @@ const AssetTeaser: React.FC<AssetTeaserProps> = ({ ddo }: AssetTeaserProps) => {
|
|||||||
Provided by <strong>{copyrightHolder}</strong>
|
Provided by <strong>{copyrightHolder}</strong>
|
||||||
</p>
|
</p>
|
||||||
</footer>
|
</footer>
|
||||||
</a>
|
|
||||||
</Link>
|
</Link>
|
||||||
</article>
|
</article>
|
||||||
)
|
)
|
||||||
|
@ -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}
|
||||||
/>
|
/> */}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
53
src/components/templates/Search/index.tsx
Normal file
53
src/components/templates/Search/index.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
@ -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>
|
|
||||||
)
|
|
||||||
}
|
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user