Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issues #44

Merged
merged 1 commit into from
May 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"focus-trap-react": "^8.5.0",
"linkifyjs": "^2.1.9",
"react": "^17.0.1",
"react-debounce-input": "^3.2.3",
"react-dom": "^17.0.1",
"react-feather": "^2.0.9",
"react-infinite-scroll-component": "^6.0.0",
Expand Down
34 changes: 34 additions & 0 deletions src/components/_Header_Searchfield/debounce.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React, { useState, useEffect } from 'react'

// Our hook
export default function useDebounce(value, delay) {
// State and setters for debounced value
const [debouncedValue, setDebouncedValue] = useState(value)

useEffect(
() => {
// Set debouncedValue to value (passed in) after the specified delay
const handler = setTimeout(() => {
setDebouncedValue(value)
}, delay)

// Return a cleanup function that will be called every time ...
// ... useEffect is re-called. useEffect will only be re-called ...
// ... if value changes (see the inputs array below).
// This is how we prevent debouncedValue from changing if value is ...
// ... changed within the delay period. Timeout gets cleared and restarted.
// To put it in context, if the user is typing within our app's ...
// ... search box, we don't want the debouncedValue to update until ...
// ... they've stopped typing for more than 500ms.
return () => {
clearTimeout(handler)
}
},
// Only re-call effect if value changes
// You could also add the "delay" var to inputs array if you ...
// ... need to be able to change that dynamically.
[value]
)

return debouncedValue
}
69 changes: 58 additions & 11 deletions src/components/_Header_Searchfield/index.jsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,48 @@
import React, { useState, useEffect } from 'react'
import { Input, Form } from 'semantic-ui-react'
import { BrowserRouter as Router, Switch, Route, Link, Redirect } from 'react-router-dom'
import { DebounceInput } from 'react-debounce-input'

// Icons
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faUser, faUsers, faCalendarDay, faHashtag } from '@fortawesome/free-solid-svg-icons'
import './style.scss'
library.add(faUsers)
library.add(faCalendarDay)
library.add(faHashtag)

import './style.scss'

const SearchField = () => {
const [searchQuery, setSearchQuery] = useState('')
const [userResult, setUserResult] = useState([])
const [topicResult, setTopicResult] = useState([])
const [popularTopics, setPopularTopics] = useState([])
const [isLoadingResults, setIsLoadingResults] = useState(false)

const searchQueryChangeHandler = (event) => {
setSearchQuery(event.target.value)
useEffect(() => {
var tokenHeaders = new Headers()
tokenHeaders.append('Authorization', 'Bearer ' + localStorage.getItem('token'))
var requestOptions = {
method: 'GET',
headers: tokenHeaders,
redirect: 'follow',
}
// eslint-disable-next-line no-undef
fetch(process.env.REACT_APP_API_URL + '/api/sidebar/popular', requestOptions)
.then((response) => response.json())
.then((result) => {
setPopularTopics(result)
})
.catch((error) => console.log('error', error))
}, [])

const searchQueryChangeHandler = () => {
let inputValue = document.querySelector('.SearchField input').value.trim()
setSearchQuery(inputValue)
const controller = new AbortController()
const { signal } = controller

if (event.target.value == '') {
if (inputValue == '' || inputValue.length < 3) {
setUserResult([])
setTopicResult([])
setIsLoadingResults(false)
Expand All @@ -40,7 +62,7 @@ const SearchField = () => {
setIsLoadingResults(true)

// eslint-disable-next-line no-undef
fetch(process.env.REACT_APP_API_URL + '/api/search?query=' + event.target.value, requestOptions, { signal })
fetch(process.env.REACT_APP_API_URL + '/api/search?query=' + encodeURIComponent(inputValue), requestOptions, { signal })
.then((response) => response.json())
.then((result) => {
let userResult = result[0]
Expand Down Expand Up @@ -75,8 +97,20 @@ const SearchField = () => {
return (
<React.Fragment>
<div className="SearchField" onBlur={searchFieldFocusOut}>
<form>
<input value={searchQuery} onFocus={searchFieldFocus} onChange={searchQueryChangeHandler} placeholder="Search for colleagues, groups, events and more..." />
<form
onSubmit={(e) => {
e.preventDefault()
searchQueryChangeHandler()
}}
>
<DebounceInput
minLength={3}
debounceTimeout={500}
value={searchQuery}
onFocus={searchFieldFocus}
onChange={searchQueryChangeHandler}
placeholder="Search for colleagues, groups, events and more..."
/>
{isLoadingResults && <span className="loader"></span>}
</form>

Expand All @@ -89,16 +123,16 @@ const SearchField = () => {
return (
<li key={user.id}>
<Link to={'/app/user/' + user.email}>
<FontAwesomeIcon icon="user" /> {user.name} <small>Rechtsabteilung</small>
<FontAwesomeIcon icon="user" /> {user.name} {(user.user_department !== null || user.user_department !== '') && <small>{user.user_department}</small>}
</Link>
</li>
)
})}
</React.Fragment>
)}
{topicResult.length > 0 && (
{topicResult.length > 0 ? (
<React.Fragment>
<span className="divider">Topics</span>
<span className="divider">Popular topics</span>
{topicResult.map((topic) => {
return (
<li key={topic.id}>
Expand All @@ -109,6 +143,19 @@ const SearchField = () => {
)
})}
</React.Fragment>
) : (
<React.Fragment>
<span className="divider">Popular topics</span>
{popularTopics.map((topic) => {
return (
<li key={topic.id}>
<Link to={'/app/topics/' + topic.topic}>
<FontAwesomeIcon icon="hashtag" /> {topic.topic}
</Link>
</li>
)
})}
</React.Fragment>
)}
</ul>
</div>
Expand Down
10 changes: 9 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7675,7 +7675,7 @@ lodash.clonedeep@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=

lodash.debounce@^4.0.8:
lodash.debounce@^4, lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=
Expand Down Expand Up @@ -9852,6 +9852,14 @@ react-app-polyfill@^2.0.0:
regenerator-runtime "^0.13.7"
whatwg-fetch "^3.4.1"

react-debounce-input@^3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/react-debounce-input/-/react-debounce-input-3.2.3.tgz#9e8c69771a621c81e8fe36b45ade49a95059cd87"
integrity sha512-7Bfjm9sxrtgB+IsSrdXoo4CVqKg7CbWC68dNhr8q7ZmY6C0AqtR524//SenHQWT+eeSG9DmSLWNWCUFSyaaWSQ==
dependencies:
lodash.debounce "^4"
prop-types "^15.7.2"

react-dev-utils@^11.0.1:
version "11.0.4"
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-11.0.4.tgz#a7ccb60257a1ca2e0efe7a83e38e6700d17aa37a"
Expand Down