[search][xl]: initial search page with essential components.

- No pagination at the moment.
- Sorting isn't functional yet.
- Search works - we only have mocks for searching 'gdp' param.
This commit is contained in:
anuveyatsu 2020-06-12 14:49:12 +06:00
parent 3715268134
commit 5a94d9d368
6 changed files with 114 additions and 0 deletions

View File

@ -0,0 +1,33 @@
import { useState } from 'react'
import { useRouter } from 'next/router'
import Link from 'next/link'
export default function Input({ query }) {
const router = useRouter()
const [q, setQ] = useState(query.q)
const handleChange = (event) => {
setQ(event.target.value)
}
const handleSubmit = (event) => {
event.preventDefault()
router.push({
pathname: '/search',
query: { q },
})
}
return (
<form onSubmit={handleSubmit}>
<input
type='text'
name='q'
value={q}
onChange={handleChange}
placeholder='Search'
aria-label='Search'
/>
</form>
)
}

View File

@ -0,0 +1,21 @@
import Link from 'next/link'
export default function Item({ datapackage }) {
return (
<div>
<h3 className="text-2xl font-semibold">
<Link href={`/@${datapackage.organization ? datapackage.organization.name : 'dataset'}/${datapackage.name}`}>
<a className="text-primary">{ datapackage.title || datapackage.name }</a>
</Link>
</h3>
<Link href={`/@${datapackage.organization ? datapackage.organization.name : 'dataset'}`}>
<a className="text-gray-500 block mt-1">
{ datapackage.organization ? datapackage.organization.title : 'dataset' }
</a>
</Link>
<div className="leading-relaxed mt-2">
{ datapackage.description }
</div>
</div>
)
}

View File

@ -0,0 +1,9 @@
import Item from './Item'
export default function List({ datapackages }) {
return (
<ul>
{datapackages.map((datapackage, index) => <Item datapackage={datapackage} key={index} />)}
</ul>
)
}

View File

@ -0,0 +1,14 @@
export default function Sort({ selected }) {
return (
<div>
<label htmlFor="field-order-by">Order by:</label>
<select className="bg-white" id="field-order-by" name="sort">
<option value="score:desc">Relevance</option>
<option value="title_string:asc">Name Ascending</option>
<option value="title_string:desc">Name Descending</option>
<option value="metadata_modified:desc">Last Modified</option>
<option value="views_recent:desc">Popular</option>
</select>
</div>
)
}

View File

@ -0,0 +1,3 @@
export default function Total({ total }) {
return <h1 className="text-4xl font-semibold text-primary">{ total } results found</h1>
}

34
pages/search.tsx Normal file
View File

@ -0,0 +1,34 @@
import { GetServerSideProps } from 'next'
import querystring from 'querystring'
import config from '../config'
import utils from '../utils'
import Input from '../components/search/Input'
import Total from '../components/search/Total'
import Sort from '../components/search/Sort'
import List from '../components/search/List'
function Search({ ckanResult, datapackages, query }) {
return (
<div>
<Input query={query} />
<Total total={ckanResult.count} />
<Sort sort={query.sort} />
<List datapackages={datapackages} />
</div>
)
}
export const getServerSideProps: GetServerSideProps = async (context) => {
const query = context.query || {}
const ckanQuery = querystring.stringify(
utils.convertToCkanSearchQuery(query)
)
console.log(ckanQuery)
const res = await fetch(`${config.get('DMS')}/api/3/action/package_search?${ckanQuery}`)
const ckanResult = (await res.json()).result
const datapackages = ckanResult.results.map(item => utils.ckanToDataPackage(item))
return { props: { ckanResult, datapackages, query } }
}
export default Search