diff options
| author | IT Fixcomart <it@fixcomart.co.id> | 2023-03-01 09:18:52 +0000 |
|---|---|---|
| committer | IT Fixcomart <it@fixcomart.co.id> | 2023-03-01 09:18:52 +0000 |
| commit | a7abbf4ddc70068620e9f44b74dc162ce2e16ee2 (patch) | |
| tree | 74f66253717515d364ce74bd8275015c1f829cbc /src/core/components/elements/Navbar | |
| parent | 90e1edab9b6a8ccc09a49fed3addbec2cbc4e4c3 (diff) | |
| parent | a1b9b647a6c4bda1f5db63879639d44543f9557e (diff) | |
Merged in refactor (pull request #1)
Refactor
Diffstat (limited to 'src/core/components/elements/Navbar')
| -rw-r--r-- | src/core/components/elements/Navbar/Navbar.jsx | 46 | ||||
| -rw-r--r-- | src/core/components/elements/Navbar/Search.jsx | 93 |
2 files changed, 139 insertions, 0 deletions
diff --git a/src/core/components/elements/Navbar/Navbar.jsx b/src/core/components/elements/Navbar/Navbar.jsx new file mode 100644 index 00000000..8cecee5b --- /dev/null +++ b/src/core/components/elements/Navbar/Navbar.jsx @@ -0,0 +1,46 @@ +import dynamic from 'next/dynamic' +import Image from 'next/image' +import IndoteknikLogo from '@/images/logo.png' +import { Bars3Icon, HeartIcon, ShoppingCartIcon } from '@heroicons/react/24/outline' +import Link from '../Link/Link' +import useSidebar from '@/core/hooks/useSidebar' + +const Search = dynamic(() => import('./Search')) + +const Navbar = () => { + const { Sidebar, open } = useSidebar() + return ( + <> + <nav className='px-4 py-2 pb-3 sticky top-0 z-50 bg-white shadow'> + <div className='flex justify-between items-center mb-2'> + <Link href='/'> + <Image + src={IndoteknikLogo} + alt='Indoteknik Logo' + width={120} + height={40} + /> + </Link> + <div className='flex gap-x-3'> + <Link href='/my/wishlist'> + <HeartIcon className='w-6 text-gray_r-12' /> + </Link> + <Link href='/shop/cart'> + <ShoppingCartIcon className='w-6 text-gray_r-12' /> + </Link> + <button + type='button' + onClick={open} + > + <Bars3Icon className='w-6 text-gray_r-12' /> + </button> + </div> + </div> + <Search /> + </nav> + {Sidebar} + </> + ) +} + +export default Navbar diff --git a/src/core/components/elements/Navbar/Search.jsx b/src/core/components/elements/Navbar/Search.jsx new file mode 100644 index 00000000..ff2c7adb --- /dev/null +++ b/src/core/components/elements/Navbar/Search.jsx @@ -0,0 +1,93 @@ +import searchSuggestApi from '@/core/api/searchSuggestApi' +import { MagnifyingGlassIcon } from '@heroicons/react/24/outline' +import { useCallback, useEffect, useRef, useState } from 'react' +import Link from '../Link/Link' +import { useRouter } from 'next/router' + +const Search = () => { + const router = useRouter() + const queryRef = useRef() + const [query, setQuery] = useState('') + const [suggestions, setSuggestions] = useState([]) + + useEffect(() => { + setQuery(router.query.q) + }, [router.query]) + + const loadSuggestion = useCallback(() => { + if (query && document.activeElement == queryRef.current) { + ;(async () => { + const dataSuggestion = await searchSuggestApi({ query }) + setSuggestions(dataSuggestion.data.suggestions) + })() + return + } else { + setSuggestions([]) + } + }, [query]) + + useEffect(() => { + if (query && document.activeElement == queryRef.current) { + loadSuggestion() + } else { + setSuggestions([]) + } + }, [loadSuggestion, query]) + + const handleSubmit = (e) => { + e.preventDefault() + if (query) { + router.push(`/shop/search?q=${query}`) + } else { + queryRef.current.focus() + } + } + + const onInputBlur = () => { + setTimeout(() => { + setSuggestions([]) + }, 100) + } + + return ( + <form + onSubmit={handleSubmit} + className='flex relative' + > + <input + type='text' + ref={queryRef} + className='form-input p-3 rounded-r-none border-r-0 focus:border-gray_r-6' + placeholder='Ketik nama, part number, merk' + value={query} + onChange={(e) => setQuery(e.target.value)} + onBlur={onInputBlur} + onFocus={loadSuggestion} + /> + <button + type='submit' + className='rounded-r border border-l-0 border-gray_r-6 px-2' + > + <MagnifyingGlassIcon className='w-6' /> + </button> + + {suggestions.length > 1 && ( + <> + <div className='absolute w-full top-[50px] rounded-b bg-gray_r-1 border border-gray_r-6 divide-y divide-gray_r-6'> + {suggestions.map((suggestion, index) => ( + <Link + href={`/shop/search?q=${suggestion.term}`} + key={index} + className='px-3 py-3 !text-gray_r-12 font-normal' + > + {suggestion.term} + </Link> + ))} + </div> + </> + )} + </form> + ) +} + +export default Search |
