From ea058dbb5c577559965d2d5224cf4f63d1c929de Mon Sep 17 00:00:00 2001 From: Netdreion <128006926+Netdreion@users.noreply.github.com> Date: Sat, 27 May 2023 17:26:47 +0300 Subject: [PATCH] Ob/issue #17 search bar (#38) * Co-authored-by: Torey Littlefield * searchbar compenent * searchbar compenent * LocationSearch * remove node modules in packages/client * update packages and fix root package.json * move eslint install to root package.json * made changes accordinly * search bar update locationsearch updated with the suggestions recieved * fix import BottomNav compile error --------- Co-authored-by: Torey Littlefield <52614742+toreylittlefield@users.noreply.github.com> --- package-lock.json | 84 ++++++------ package.json | 10 +- packages/client/lib/components/BottomNav.jsx | 16 +-- .../client/lib/components/LocationSearch.jsx | 124 ++++++++++++++++++ packages/client/lib/components/Map.jsx | 1 + .../lib/components/useOnClickOutside.js | 26 ++++ packages/client/package.json | 5 +- packages/client/pages/index.tsx | 4 +- packages/client/styles/globals.css | 4 +- 9 files changed, 209 insertions(+), 65 deletions(-) create mode 100644 packages/client/lib/components/LocationSearch.jsx create mode 100644 packages/client/lib/components/useOnClickOutside.js diff --git a/package-lock.json b/package-lock.json index 7772f28..6630c7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,14 +11,9 @@ "packages/*" ], "devDependencies": { - "@heroicons/react": "^2.0.16", - "@types/leaflet": "^1.9.3", - "autoprefixer": "^10.4.14", - "postcss": "^8.4.21", - "postcss-import": "^15.1.0", + "eslint": "^8.40.0", "prettier": "^2.8.5", - "tailwindcss": "^3.2.7", - "typescript": "4.9.5" + "typescript": "^5.0.4" }, "engines": { "node": ">=14.0.0" @@ -58,13 +53,13 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz", - "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", + "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.0", + "espree": "^9.5.2", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -80,9 +75,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", - "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", + "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -642,9 +637,9 @@ } }, "node_modules/@heroicons/react": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.0.16.tgz", - "integrity": "sha512-x89rFxH3SRdYaA+JCXwfe+RkE1SFTo9GcOkZettHer71Y3T7V+ogKmfw5CjTazgS3d0ClJ7p1NA+SP7VQLQcLw==", + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.0.17.tgz", + "integrity": "sha512-90GMZktkA53YbNzHp6asVEDevUQCMtxWH+2UK2S8OpnLEu7qckTJPhNxNQG52xIR1WFTwFqtH6bt7a60ZNcLLA==", "peerDependencies": { "react": ">= 16" } @@ -2326,14 +2321,14 @@ } }, "node_modules/eslint": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", - "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", + "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.1", - "@eslint/js": "8.36.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.40.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -2343,9 +2338,9 @@ "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.5.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -2639,33 +2634,39 @@ } }, "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/espree": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", - "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", + "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", "dependencies": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -5210,15 +5211,15 @@ } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=12.20" } }, "node_modules/unbox-primitive": { @@ -5611,12 +5612,11 @@ "name": "@pet-poison-alert/client", "version": "0.1.0", "dependencies": { - "@heroicons/react": "^2.0.16", + "@heroicons/react": "^2.0.17", "@types/node": "18.15.2", "@types/react": "18.0.28", "@types/react-dom": "18.0.11", "copy-webpack-plugin": "^11.0.0", - "eslint": "8.36.0", "eslint-config-next": "13.2.4", "firebase": "^9.17.2", "leaflet": "^1.9.3", @@ -5624,7 +5624,7 @@ "react": "18.2.0", "react-dom": "18.2.0", "react-leaflet": "^4.2.1", - "typescript": "4.9.5", + "typescript": "^5.0.4", "zustand": "^4.3.6" }, "devDependencies": { diff --git a/package.json b/package.json index d231396..a1b03a2 100644 --- a/package.json +++ b/package.json @@ -7,14 +7,9 @@ "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css,scss,md}\"" }, "devDependencies": { - "@heroicons/react": "^2.0.16", + "eslint": "^8.40.0", "prettier": "^2.8.5", - "typescript": "4.9.5", - "@types/leaflet": "^1.9.3", - "autoprefixer": "^10.4.14", - "postcss": "^8.4.21", - "postcss-import": "^15.1.0", - "tailwindcss": "^3.2.7" + "typescript": "^5.0.4" }, "engines": { "node": ">=14.0.0" @@ -23,4 +18,3 @@ "packages/*" ] } - diff --git a/packages/client/lib/components/BottomNav.jsx b/packages/client/lib/components/BottomNav.jsx index 16d2939..cfb71c6 100644 --- a/packages/client/lib/components/BottomNav.jsx +++ b/packages/client/lib/components/BottomNav.jsx @@ -1,29 +1,29 @@ -import { useState } from "react"; -import BottomNavItem from "./BottomNavItem.jsx"; +import { useState } from 'react'; +import BottomNavItem from './BottomNavItem.jsx'; import { HomeIcon, MagnifyingGlassIcon, UserIcon, PlusCircleIcon, MapPinIcon, -} from "@heroicons/react/24/outline"; +} from '@heroicons/react/24/outline'; const BottomNav = () => { - const [active, setActive] = useState(0) + const [active, setActive] = useState(0); return (
setActive(0)} selected={active === 0 ? true : false} - name={"Home"} + name={'Home'} > setActive(1)} selected={active === 1 ? true : false} - name={"Search"} + name={'Search'} > @@ -38,14 +38,14 @@ const BottomNav = () => { setActive(2)} selected={active === 2 ? true : false} - name={"Layers"} + name={'Layers'} > setActive(3)} selected={active === 3 ? true : false} - name={"Profile"} + name={'Profile'} > diff --git a/packages/client/lib/components/LocationSearch.jsx b/packages/client/lib/components/LocationSearch.jsx new file mode 100644 index 0000000..3ccd9f2 --- /dev/null +++ b/packages/client/lib/components/LocationSearch.jsx @@ -0,0 +1,124 @@ +import React, { useState, useRef } from 'react'; +import { + MagnifyingGlassCircleIcon, + XMarkIcon, +} from '@heroicons/react/24/outline'; +import useOnClickOutside from './useOnClickOutside'; + +const mockSearchLocationData = { + results: [ + { + lat: 40.7128, + lng: -74.006, + name: 'New York, NY, USA', + }, + { + lat: 37.7749, + lng: -122.4194, + name: 'San Francisco, CA, USA', + }, + { + lat: 34.0522, + lng: -118.2437, + name: 'Los Angeles, CA, USA', + }, + { + lat: 41.8781, + lng: -87.6298, + name: 'Chicago, IL, USA', + }, + ], +}; + +function LocationSearch() { + const [isOpen, setIsOpen] = useState(false); + const [value, setValue] = useState(''); + const [results, setResults] = useState([]); + const searchRef = useRef(null); + + function handleToggleSearch() { + setIsOpen(!isOpen); + } + + function getSearchLocationData(searchText) { + const filteredResults = mockSearchLocationData.results.filter((result) => { + return result.name.toLowerCase().includes(searchText.toLowerCase()); + }); + return filteredResults; + } + + function handleInputChange(event) { + const value = event.target.value; + setValue(value); + const searchResults = getSearchLocationData(value); + setResults(searchResults); + setIsOpen(searchResults.length > 0); + } + + function handleClearInput() { + setValue(''); + setResults([]); + setIsOpen(false); + } + + function handleListItemClick(name) { + setValue(name); + setIsOpen(false); + } + + function hideSearch() { + setIsOpen(false); + } + + useOnClickOutside(searchRef, hideSearch); + + return ( +
+
+
+ + + + {value && ( + + )} +
+ + {isOpen && ( +
+
    + {results.slice(0, 10).map((item) => ( +
  • handleListItemClick(item.name)} + > + {item.name} +
  • + ))} +
+
+ )} +
+
+ ); +} + +export default LocationSearch; diff --git a/packages/client/lib/components/Map.jsx b/packages/client/lib/components/Map.jsx index 1a0ac1c..2c7e2bd 100644 --- a/packages/client/lib/components/Map.jsx +++ b/packages/client/lib/components/Map.jsx @@ -3,6 +3,7 @@ import useStore from '../../store/store'; import 'leaflet/dist/leaflet.css'; import { MapContainer, TileLayer, Marker, ZoomControl,useMap } from 'react-leaflet'; import Leaflet from 'leaflet'; + const SetViewOnUserLocation = () => { const map = useMap(); diff --git a/packages/client/lib/components/useOnClickOutside.js b/packages/client/lib/components/useOnClickOutside.js new file mode 100644 index 0000000..2ed7fc4 --- /dev/null +++ b/packages/client/lib/components/useOnClickOutside.js @@ -0,0 +1,26 @@ +import {useState,useEffect} from "react"; + +function useOnClickOutside(ref,handler){ + +const[isMounted,setIsMounted]=useState(false); + +useEffect(()=>{ +setIsMounted(true); + +function handleClickOutside(event){ +if(isMounted && ref.current && !ref.current.contains(event.target)){ + handler() +} +} +document.addEventListener('mousedown',handleClickOutside); +return ()=> { + setIsMounted(false) + + document.removeEventListener('mousedown',handleClickOutside); +}; +}, [ref,handler,isMounted]); +} + +export default useOnClickOutside; + + diff --git a/packages/client/package.json b/packages/client/package.json index 74c20a3..d8b566e 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -9,12 +9,11 @@ "lint": "next lint" }, "dependencies": { - "@heroicons/react": "^2.0.16", + "@heroicons/react": "^2.0.17", "@types/node": "18.15.2", "@types/react": "18.0.28", "@types/react-dom": "18.0.11", "copy-webpack-plugin": "^11.0.0", - "eslint": "8.36.0", "eslint-config-next": "13.2.4", "firebase": "^9.17.2", "leaflet": "^1.9.3", @@ -22,7 +21,7 @@ "react": "18.2.0", "react-dom": "18.2.0", "react-leaflet": "^4.2.1", - "typescript": "4.9.5", + "typescript": "^5.0.4", "zustand": "^4.3.6" }, "devDependencies": { diff --git a/packages/client/pages/index.tsx b/packages/client/pages/index.tsx index 7fc271d..debb384 100644 --- a/packages/client/pages/index.tsx +++ b/packages/client/pages/index.tsx @@ -1,6 +1,7 @@ import Head from 'next/head'; import dynamic from 'next/dynamic'; -import BottomNav from '../lib/Components/BottomNav' +import BottomNav from '../lib/components/BottomNav'; +import LocationSearch from '@/lib/components/LocationSearch'; const MapWithNoSSR = dynamic(() => import('../lib/components/Map'), { ssr: false, @@ -19,6 +20,7 @@ export default function Home() {
+
diff --git a/packages/client/styles/globals.css b/packages/client/styles/globals.css index 4bf627f..a84af31 100644 --- a/packages/client/styles/globals.css +++ b/packages/client/styles/globals.css @@ -32,9 +32,7 @@ border-top-right-radius: 0.5rem; } .leaflet-bar a:last-child { - border-bottom-left-radius: 0.5rem; - border-bottom-right-radius: 0.5rem; - border-bottom: 0.5rem; +border-bottom:none; } .leaflet-touch .leaflet-bar a:first-child { border-top-left-radius: 0.5rem;