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 { ReactComponent as Logo } from '@oceanprotocol/art/logo/logo.svg'
|
||||||
import Content from '../components/Content'
|
import Content from '../components/Content'
|
||||||
import styles from './HeaderHome.module.scss'
|
import styles from './HeaderHome.module.scss'
|
||||||
|
import SearchComponent from './Search/SearchComponent'
|
||||||
const HeaderHome = () => (
|
const HeaderHome = () => (
|
||||||
<StaticQuery
|
<StaticQuery
|
||||||
query={graphql`
|
query={graphql`
|
||||||
@ -25,6 +25,7 @@ const HeaderHome = () => (
|
|||||||
<Logo className={styles.headerLogo} />
|
<Logo className={styles.headerLogo} />
|
||||||
<h1 className={styles.headerTitle}>{siteTitle}</h1>
|
<h1 className={styles.headerTitle}>{siteTitle}</h1>
|
||||||
<p className={styles.headerDescription}>{siteDescription}</p>
|
<p className={styles.headerDescription}>{siteDescription}</p>
|
||||||
|
<SearchComponent />
|
||||||
</Content>
|
</Content>
|
||||||
</header>
|
</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 React from 'react'
|
||||||
import * as JsSearch from 'js-search'
|
|
||||||
import { Link } from 'gatsby'
|
import { graphql } from 'gatsby'
|
||||||
import PropTypes from 'prop-types'
|
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) => ({
|
import SearchClient from './SearchClient'
|
||||||
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 SearchComponent = ({ pageContext }) => {
|
const SearchComponent = ({ data, pageContext }) => {
|
||||||
|
console.log('data', data)
|
||||||
const { searchData } = pageContext
|
const { searchData } = pageContext
|
||||||
const searchableData = searchData.map(({ node }) => {
|
const searchableData = searchData.map(({ node }) => {
|
||||||
return {
|
return {
|
||||||
@ -38,143 +18,34 @@ const SearchComponent = ({ pageContext }) => {
|
|||||||
})
|
})
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ClientSearch searchableData={searchableData} />
|
<SearchClient searchableData={searchableData} />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
SearchComponent.propTypes = {
|
SearchComponent.propTypes = {
|
||||||
pageContext: PropTypes.object.isRequired
|
pageContext: PropTypes.object,
|
||||||
|
data: PropTypes.object
|
||||||
}
|
}
|
||||||
|
|
||||||
const ClientSearch = ({ searchableData }) => {
|
export const SearchComponentQuery = graphql`
|
||||||
const [searchState, setSearchState] = useState({
|
query {
|
||||||
isLoading: true,
|
allMarkdownRemark(filter: { fileAbsolutePath: { regex: "/content/" } }) {
|
||||||
searchResults: [],
|
edges {
|
||||||
search: null,
|
node {
|
||||||
isError: false,
|
fields {
|
||||||
termFrequency: true,
|
slug
|
||||||
removeStopWords: false,
|
section
|
||||||
searchQuery: '',
|
|
||||||
selectedStrategy: '',
|
|
||||||
selectedSanitizer: '',
|
|
||||||
touched: false
|
|
||||||
})
|
|
||||||
|
|
||||||
const classes = useStyles()
|
|
||||||
const [open, setOpen] = React.useState(false)
|
|
||||||
|
|
||||||
const handleOpen = () => {
|
|
||||||
setOpen(true)
|
|
||||||
}
|
}
|
||||||
|
frontmatter {
|
||||||
const handleClose = () => {
|
title
|
||||||
setOpen(false)
|
description
|
||||||
}
|
}
|
||||||
|
id
|
||||||
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
|
export default SearchComponent
|
||||||
|
Loading…
x
Reference in New Issue
Block a user