Skip to content

Commit

Permalink
add/event-search (#90)
Browse files Browse the repository at this point in the history
Added search functionality
  • Loading branch information
Akalanka47000 authored Jul 27, 2021
1 parent 36bb477 commit d624bce
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 26 deletions.
129 changes: 129 additions & 0 deletions components/Common/AutocompleteForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import React from 'react'

const style = {
label: `text-gray-700`,
disabled: `cursor-not-allowed`,
container: `relative w-full`,
default: `border focus:border-2 border-gray-500 focus:border-blue outline-none w-full my-4 rounded-sm pr-4 pl-5 md:pl-10 py-3`,
suggestion: {
activeItem: 'bg-gray-300',
item: `px-4 py-3 focus text-sm text-gray-700 cursor-pointer hover:bg-gray-200`,
list: `shadow-xl absolute top-full left-0 right-0 border w-auto md:max-w-xs overflow-y-auto max-h-80 mt-2 bg-white p-3 z-20`,
},
}

interface formProps {
suggestions: Array<string>
value: string
setValue: any
placeholder: string
}

const AutoCompleteForm = ({
suggestions,
value,
setValue,
placeholder,
}: formProps): JSX.Element => {
const ref: any = React.useRef(null)
const [activeSuggestion, setActiveSuggestion] = React.useState(0)
const [showSuggestions, setShowSuggestions] = React.useState(false)
const [filteredSuggestions, setFilteredSuggestions] = React.useState<
Array<string>
>([])

//close suggestions list when click outside
React.useEffect(() => {
const handleOutsideClick = () => {
if (ref.current === null) {
if (!showSuggestions) return
setShowSuggestions(false)
}
}
window.addEventListener('click', handleOutsideClick)
return () => window.removeEventListener('click', handleOutsideClick)
}, [showSuggestions, ref])

const handleChange = React.useCallback(
(e) => {
const userInput = e.currentTarget.value
const filteredSuggestions: Array<string> = suggestions.filter(
(suggestion) =>
suggestion.toLowerCase().indexOf(userInput.toLowerCase()) > -1
)
setActiveSuggestion(0)
setFilteredSuggestions(filteredSuggestions)
setShowSuggestions(true)
setValue(e.currentTarget.value)
},
[setValue, suggestions]
)
const onClick = (e: any) => {
setActiveSuggestion(0)
setFilteredSuggestions([])
setShowSuggestions(false)
setValue(e.currentTarget.innerText)
}
const onKeyDown = (e: any) => {
// User pressed the enter key
if (e.keyCode === 13) {
setActiveSuggestion(0)
setShowSuggestions(false)
setValue(filteredSuggestions[activeSuggestion] || value)
}
// User pressed the up arrow
else if (e.keyCode === 38) {
if (activeSuggestion === 0) {
return
}
setActiveSuggestion(activeSuggestion - 1)
}
// User pressed the down arrow
else if (e.keyCode === 40) {
if (activeSuggestion - 1 === filteredSuggestions.length) {
return
}
setActiveSuggestion(activeSuggestion + 1)
}
}
let suggestionsListComponent
if (showSuggestions && value) {
if (filteredSuggestions.length) {
suggestionsListComponent = (
<ul className={style.suggestion.list}>
{filteredSuggestions.map((suggestion, index) => {
let className
if (index === activeSuggestion) {
className = `${style.suggestion.item} ${style.suggestion.activeItem}`
}
if (index !== activeSuggestion) {
className = style.suggestion.item
}
return (
<li className={className} key={suggestion} onClick={onClick}>
{suggestion}
</li>
)
})}
</ul>
)
} else {
suggestionsListComponent = <div></div>
}
}
return (
<div className={style.container}>
<input
autoComplete="off"
className={style.default}
onChange={handleChange}
onKeyDown={onKeyDown}
value={value}
placeholder={placeholder}
/>
{suggestionsListComponent}
</div>
)
}

export default AutoCompleteForm
18 changes: 11 additions & 7 deletions components/NavSearch.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import AutoCompleteForm from './Common/AutocompleteForm'

interface SearchProps {
handleFilterChange: any
handleSearchParam: any
formSubmit: any
searchValue: string
searchSuggestions: Array<string>
}

const NavSearch = ({
handleFilterChange,
handleSearchParam,
formSubmit,
searchValue,
searchSuggestions,
}: SearchProps): JSX.Element => {
return (
<div className="flex flex-col px-6 mb-6 bg-white relative z-20 shadow ">
Expand All @@ -17,20 +23,18 @@ const NavSearch = ({
onSubmit={formSubmit}
>
<select
className="m-3 mt-5 mb-1 pl-10 md:pl-4 md:my-4 mx-0 md:mx-5 w-full md:w-4/12 h-12 md:h-auto rounded-sm"
className="m-3 mt-5 mb-1 pl-5 md:pl-8 md:my-4 mx-0 md:mx-5 w-full md:w-4/12 h-12 md:h-auto rounded-sm"
onChange={handleFilterChange}
>
<option value="All">All</option>
<option value="Happening Now">Happening Now</option>
<option value="Upcoming">Upcoming</option>
</select>
<input
type="search"
name="search"
required
className="form-control w-full my-4 border border-gray-500 rounded-sm pr-4 pl-10 py-3 outline-none transition-colors duration-150 ease-in-out focus:border-blue-400"
<AutoCompleteForm
value={searchValue}
setValue={handleSearchParam}
suggestions={searchSuggestions}
placeholder="Search for event..."
onChange={handleSearchParam}
/>
<button
type="submit"
Expand Down
52 changes: 33 additions & 19 deletions pages/events/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from 'react'
import { useState, useEffect } from 'react'
import { useGetEvents } from '../../queries/useGetEvent'
import Layout from '../../components/Layout'
import Navbar from '../../components/Navbar'
Expand All @@ -15,36 +15,48 @@ import { EventData } from '../api/event/event.interface'

const AllEvents = (): JSX.Element => {
const { data: eventList = [], isSuccess } = useGetEvents()
console.log('event list : ', eventList)
const [filterValue, setFilterValue] = useState('All')
const [searchValue, setSearchValue] = useState<string>('')
const [searchValue, setSearchValue] = useState('')
const [events, setEvents] = useState<Array<EventData>>([])

useEffect(() => {
if (filterValue === 'Happening Now' || filterValue === 'Upcoming') {
const list: Array<EventData> = eventList.filter((event) => {
return event.status === filterValue
})
setEvents(list)
} else {
setEvents(eventList)
}
}, [filterValue, eventList])

const handleEventFilterParam =
() => (e: React.ChangeEvent<HTMLSelectElement>) => {
const value = e.target.value
setFilterValue(value)
setSearchValue('')
}

const handleSearchParam = () => (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value
const handleSearchParam = () => (value: string) => {
if (value === '') {
setEvents(eventList)
}
setSearchValue(value)
}

const formSubmit = (e: React.FormEvent<HTMLFormElement>) => {
console.log(e)
alert(searchValue)
e.preventDefault()
if (searchValue != '') {
const list: Array<EventData> = eventList.filter((event) => {
return event.name === searchValue
})
setEvents(list)
}
}

let diplayEventList: Array<EventData> = []
if (filterValue === 'Happening Now' || filterValue === 'Upcoming') {
eventList.map((event) => {
if (event.status === filterValue) {
diplayEventList.push(event)
}
})
} else {
diplayEventList = eventList
}
const searchSuggestions: Array<string> = eventList.map((event) => {
return event.name
})

return (
<Layout title="Events | RSVP SLIIT">
Expand All @@ -59,11 +71,13 @@ const AllEvents = (): JSX.Element => {
handleFilterChange={handleEventFilterParam()}
handleSearchParam={handleSearchParam()}
formSubmit={formSubmit}
searchValue={searchValue}
searchSuggestions={searchSuggestions}
/>
{isSuccess ? (
diplayEventList.length != 0 ? (
events.length != 0 ? (
<div className="flex flex-wrap px-6">
{diplayEventList.map((event) => (
{events.map((event) => (
<Event
key={event?._id}
id={event?._id}
Expand Down
1 change: 1 addition & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ module.exports = {
height: ['group-hover'],
padding: ['group-hover'],
brightness: ['hover'],
borderWidth: ['focus'],
},
},
plugins: [require('@tailwindcss/forms')],
Expand Down

0 comments on commit d624bce

Please sign in to comment.