mirror of
https://github.com/oceanprotocol/docs.git
synced 2024-11-26 19:49:26 +01:00
Issue-545: WIP Create SearchClient component
This commit is contained in:
parent
619c181a10
commit
a0d1c77f48
@ -3,7 +3,7 @@ import { StaticQuery, graphql } from 'gatsby'
|
||||
import { ReactComponent as Logo } from '@oceanprotocol/art/logo/logo.svg'
|
||||
import Content from '../components/Content'
|
||||
import styles from './HeaderHome.module.scss'
|
||||
|
||||
import SearchComponent from './Search/SearchComponent'
|
||||
const HeaderHome = () => (
|
||||
<StaticQuery
|
||||
query={graphql`
|
||||
@ -25,6 +25,7 @@ const HeaderHome = () => (
|
||||
<Logo className={styles.headerLogo} />
|
||||
<h1 className={styles.headerTitle}>{siteTitle}</h1>
|
||||
<p className={styles.headerDescription}>{siteDescription}</p>
|
||||
<SearchComponent />
|
||||
</Content>
|
||||
</header>
|
||||
)
|
||||
|
159
src/components/Search/SearchClient.jsx
Normal file
159
src/components/Search/SearchClient.jsx
Normal file
@ -0,0 +1,159 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import * as JsSearch from 'js-search'
|
||||
import { Link } from 'gatsby'
|
||||
import PropTypes from 'prop-types'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import Modal from '@material-ui/core/Modal'
|
||||
import Backdrop from '@material-ui/core/Backdrop'
|
||||
import Fade from '@material-ui/core/Fade'
|
||||
import List from '@material-ui/core/List'
|
||||
import ListItem from '@material-ui/core/ListItem'
|
||||
import styles from './SearchComponent.module.scss'
|
||||
import Button from '@material-ui/core/Button'
|
||||
import SearchIcon from '@material-ui/icons/Search'
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
modal: {
|
||||
display: 'flex',
|
||||
alignItems: 'top',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
paper: {
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
boxShadow: theme.shadows[5],
|
||||
padding: theme.spacing(2, 4, 3),
|
||||
margin: theme.spacing(3)
|
||||
}
|
||||
}))
|
||||
|
||||
const SearchClient = ({ searchableData }) => {
|
||||
const [searchState, setSearchState] = useState({
|
||||
isLoading: true,
|
||||
searchResults: [],
|
||||
search: null,
|
||||
isError: false,
|
||||
termFrequency: true,
|
||||
removeStopWords: false,
|
||||
searchQuery: '',
|
||||
selectedStrategy: '',
|
||||
selectedSanitizer: '',
|
||||
touched: false
|
||||
})
|
||||
|
||||
const classes = useStyles()
|
||||
const [open, setOpen] = React.useState(false)
|
||||
|
||||
const handleOpen = () => {
|
||||
setOpen(true)
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
setOpen(false)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
rebuildIndex(searchableData)
|
||||
}, [])
|
||||
|
||||
const rebuildIndex = (searchableData) => {
|
||||
// const {
|
||||
// removeStopWords,
|
||||
// selectedStrategy,
|
||||
// selectedSanitizer,
|
||||
// termFrequency
|
||||
// } = searchState
|
||||
const dataToSearch = new JsSearch.Search('title')
|
||||
dataToSearch.addIndex('title')
|
||||
|
||||
dataToSearch.addDocuments(searchableData)
|
||||
setSearchState({
|
||||
...searchState,
|
||||
isLoading: false,
|
||||
search: dataToSearch
|
||||
})
|
||||
}
|
||||
|
||||
const searchData = (e) => {
|
||||
const { search } = searchState
|
||||
const queryResult = search.search(e.target.value)
|
||||
setSearchState({
|
||||
...searchState,
|
||||
touched: true,
|
||||
searchQuery: e.target.value,
|
||||
searchResults: queryResult
|
||||
})
|
||||
}
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button onClick={handleOpen} startIcon={<SearchIcon />}>
|
||||
Search
|
||||
</Button>
|
||||
<Modal
|
||||
className={classes.modal}
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
closeAfterTransition
|
||||
BackdropComponent={Backdrop}
|
||||
BackdropProps={{
|
||||
timeout: 500
|
||||
}}
|
||||
>
|
||||
<Fade in={open}>
|
||||
<div className={classes.paper}>
|
||||
<div>
|
||||
<div style={{ margin: '0 auto' }}>
|
||||
<form onSubmit={handleSubmit} className={styles.searchform}>
|
||||
<input
|
||||
id="Search"
|
||||
value={searchState.searchQuery}
|
||||
onChange={searchData}
|
||||
placeholder="Search..."
|
||||
style={{
|
||||
margin: '0 auto',
|
||||
width: '400px'
|
||||
}}
|
||||
type="text"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
{searchState.touched ? (
|
||||
<ResultList searchResults={searchState.searchResults} />
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Fade>
|
||||
</Modal>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
SearchClient.propTypes = {
|
||||
searchableData: PropTypes.array.isRequired
|
||||
}
|
||||
|
||||
const ResultList = ({ searchResults }) => {
|
||||
return (
|
||||
<div>
|
||||
<div>Total results found: {searchResults.length} </div>
|
||||
<List>
|
||||
{searchResults.map((element) => (
|
||||
<ListItem style={{ before: { content: null } }} key={element.id}>
|
||||
<Link to={element.slug}>{element.title} </Link>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
ResultList.propTypes = {
|
||||
searchResults: PropTypes.array.isRequired
|
||||
}
|
||||
|
||||
export default SearchClient
|
@ -1,32 +1,12 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import * as JsSearch from 'js-search'
|
||||
import { Link } from 'gatsby'
|
||||
import React from 'react'
|
||||
|
||||
import { graphql } from 'gatsby'
|
||||
import PropTypes from 'prop-types'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import Modal from '@material-ui/core/Modal'
|
||||
import Backdrop from '@material-ui/core/Backdrop'
|
||||
import Fade from '@material-ui/core/Fade'
|
||||
import List from '@material-ui/core/List'
|
||||
import ListItem from '@material-ui/core/ListItem'
|
||||
import styles from './SearchComponent.module.scss'
|
||||
import Button from '@material-ui/core/Button'
|
||||
import SearchIcon from '@material-ui/icons/Search'
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
modal: {
|
||||
display: 'flex',
|
||||
alignItems: 'top',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
paper: {
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
boxShadow: theme.shadows[5],
|
||||
padding: theme.spacing(2, 4, 3),
|
||||
margin: theme.spacing(3)
|
||||
}
|
||||
}))
|
||||
import SearchClient from './SearchClient'
|
||||
|
||||
const SearchComponent = ({ pageContext }) => {
|
||||
const SearchComponent = ({ data, pageContext }) => {
|
||||
console.log('data', data)
|
||||
const { searchData } = pageContext
|
||||
const searchableData = searchData.map(({ node }) => {
|
||||
return {
|
||||
@ -38,143 +18,34 @@ const SearchComponent = ({ pageContext }) => {
|
||||
})
|
||||
return (
|
||||
<>
|
||||
<ClientSearch searchableData={searchableData} />
|
||||
<SearchClient searchableData={searchableData} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
SearchComponent.propTypes = {
|
||||
pageContext: PropTypes.object.isRequired
|
||||
pageContext: PropTypes.object,
|
||||
data: PropTypes.object
|
||||
}
|
||||
|
||||
const ClientSearch = ({ searchableData }) => {
|
||||
const [searchState, setSearchState] = useState({
|
||||
isLoading: true,
|
||||
searchResults: [],
|
||||
search: null,
|
||||
isError: false,
|
||||
termFrequency: true,
|
||||
removeStopWords: false,
|
||||
searchQuery: '',
|
||||
selectedStrategy: '',
|
||||
selectedSanitizer: '',
|
||||
touched: false
|
||||
})
|
||||
|
||||
const classes = useStyles()
|
||||
const [open, setOpen] = React.useState(false)
|
||||
|
||||
const handleOpen = () => {
|
||||
setOpen(true)
|
||||
export const SearchComponentQuery = graphql`
|
||||
query {
|
||||
allMarkdownRemark(filter: { fileAbsolutePath: { regex: "/content/" } }) {
|
||||
edges {
|
||||
node {
|
||||
fields {
|
||||
slug
|
||||
section
|
||||
}
|
||||
frontmatter {
|
||||
title
|
||||
description
|
||||
}
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
setOpen(false)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
rebuildIndex(searchableData)
|
||||
}, [])
|
||||
|
||||
const rebuildIndex = (searchableData) => {
|
||||
// const {
|
||||
// removeStopWords,
|
||||
// selectedStrategy,
|
||||
// selectedSanitizer,
|
||||
// termFrequency
|
||||
// } = searchState
|
||||
const dataToSearch = new JsSearch.Search('title')
|
||||
dataToSearch.addIndex('title')
|
||||
|
||||
dataToSearch.addDocuments(searchableData)
|
||||
setSearchState({
|
||||
...searchState,
|
||||
isLoading: false,
|
||||
search: dataToSearch
|
||||
})
|
||||
}
|
||||
|
||||
const searchData = (e) => {
|
||||
const { search } = searchState
|
||||
const queryResult = search.search(e.target.value)
|
||||
setSearchState({
|
||||
...searchState,
|
||||
touched: true,
|
||||
searchQuery: e.target.value,
|
||||
searchResults: queryResult
|
||||
})
|
||||
}
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button onClick={handleOpen} startIcon={<SearchIcon />}>
|
||||
Search
|
||||
</Button>
|
||||
<Modal
|
||||
className={classes.modal}
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
closeAfterTransition
|
||||
BackdropComponent={Backdrop}
|
||||
BackdropProps={{
|
||||
timeout: 500
|
||||
}}
|
||||
>
|
||||
<Fade in={open}>
|
||||
<div className={classes.paper}>
|
||||
<div>
|
||||
<div style={{ margin: '0 auto' }}>
|
||||
<form onSubmit={handleSubmit} className={styles.searchform}>
|
||||
<input
|
||||
id="Search"
|
||||
value={searchState.searchQuery}
|
||||
onChange={searchData}
|
||||
placeholder="Search..."
|
||||
style={{
|
||||
margin: '0 auto',
|
||||
width: '400px'
|
||||
}}
|
||||
type="text"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
{searchState.touched ? (
|
||||
<ResultList searchResults={searchState.searchResults} />
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Fade>
|
||||
</Modal>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
ClientSearch.propTypes = {
|
||||
searchableData: PropTypes.array.isRequired
|
||||
}
|
||||
|
||||
const ResultList = ({ searchResults }) => {
|
||||
return (
|
||||
<div>
|
||||
<div>Total results found: {searchResults.length} </div>
|
||||
<List>
|
||||
{searchResults.map((element) => (
|
||||
<ListItem style={{ before: { content: null } }} key={element.id}>
|
||||
<Link to={element.slug}>{element.title} </Link>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
ResultList.propTypes = {
|
||||
searchResults: PropTypes.array.isRequired
|
||||
}
|
||||
`
|
||||
|
||||
export default SearchComponent
|
||||
|
Loading…
Reference in New Issue
Block a user