source: imaps-frontend/src/components/SearchBar/SearchBar.jsx@ 0c6b92a

main
Last change on this file since 0c6b92a was 0c6b92a, checked in by stefan toskovski <stefantoska84@…>, 5 weeks ago

Pred finalna verzija

  • Property mode set to 100644
File size: 5.5 KB
Line 
1import React, { useState, useEffect, useRef } from "react";
2import ReactDOM from "react-dom";
3import searchIcon from "../../assets/search_icon.png";
4import routeIcon from "../../assets/route_icon.png";
5import closeIcon from "../../assets/close_icon.png";
6import styles from "./SearchBar.module.css";
7
8function SearchBar({ map, handleDirectionsSubmit, setIsPanelOpen, setSelectedRoom, availableShapes,handleFloorChange }) {
9 const [isExpanded, setIsExpanded] = useState(false);
10 const [from, setFrom] = useState("");
11 const [to, setTo] = useState("");
12 const [availableOptions, setAvailableOptions] = useState([]);
13 const [filteredOptions, setFilteredOptions] = useState([]);
14 const [dropdownVisible, setDropdownVisible] = useState(false);
15 const [inputFieldType, setInputFieldType] = useState("");
16 const dropdownRef = useRef(null);
17
18 const toggleExpanded = () => {
19 setIsExpanded(!isExpanded);
20 };
21
22 function searchRoom() {
23 let foundRoom = availableShapes.find(sh => sh.info.name === from)
24 console.log("map fnum",map.floorNum)
25 if(foundRoom.floorNum !== map.floorNum){
26 handleFloorChange(foundRoom.floorNum);
27 }
28
29
30 console.log("FOUND ROOM: " + foundRoom)
31 map.highlightShape(from);
32 setSelectedRoom(foundRoom);
33 setIsPanelOpen(true);
34 }
35
36 const handleInputFocus = (field) => {
37 if (availableOptions.length === 0 && map) {
38 setAvailableOptions(
39 availableShapes
40 .filter((sh) => sh.className === "RenderedRoom")
41 .map((shape) => shape.info.name)
42 );
43 }
44 setDropdownVisible(true);
45 setInputFieldType(field);
46 };
47
48 const handleInputChange = (setter) => (event) => {
49 const value = event.target.value;
50 setter(value);
51 setDropdownVisible(true);
52
53 const filtered = availableOptions.filter((option) =>
54 option.toLowerCase().includes(value.toLowerCase())
55 );
56 setFilteredOptions(filtered);
57 };
58
59 const handleOptionClick = (option) => {
60 if (inputFieldType === "from") {
61 setFrom(option);
62 } else if (inputFieldType === "to") {
63 setTo(option);
64 }
65 setDropdownVisible(false);
66 };
67
68 const renderDropdown = () => {
69 if (!dropdownVisible || filteredOptions.length === 0) return null;
70
71 const position = dropdownRef.current?.getBoundingClientRect() || { top: 0, left: 0, width: 0 };
72
73 return ReactDOM.createPortal(
74 <ul
75 className={styles.dropdown}
76 style={{
77 position: "absolute",
78 top: position.top + position.height,
79 left: position.left,
80 width: position.width,
81 }}
82 >
83 {filteredOptions.map((option, index) => (
84 <li
85 key={index}
86 className={styles.dropdownItem}
87 onClick={() => handleOptionClick(option)}
88 >
89 {option}
90 </li>
91 ))}
92 </ul>,
93 document.body // Portal renders outside the parent hierarchy
94 );
95 };
96
97 return (
98 <div className={styles.wrapper}>
99 {!isExpanded ? (
100 <div className={styles.searchBar}>
101 <input
102 type="search"
103 className={styles.inputField}
104 placeholder="Search location"
105 aria-label="Search"
106 ref={dropdownRef} // Attach the input to calculate dropdown position
107 onFocus={() => handleInputFocus("from")}
108 onChange={handleInputChange(setFrom)}
109 value={from}
110 />
111 {renderDropdown()}
112 <div className={styles.buttons}>
113 <button type="button" className={styles.iconButton} onClick={searchRoom}>
114 <img src={searchIcon} alt="Search Icon" />
115 </button>
116 <button type="button" className={styles.iconButton} onClick={toggleExpanded}>
117 <img src={routeIcon} alt="Route Icon" />
118 </button>
119 </div>
120 </div>
121 ) : (
122 <div className={styles.directionsContainer}>
123 <div className={styles.directionsInputs}>
124 <input
125 type="text"
126 placeholder="From"
127 aria-label="From"
128 value={from}
129 onFocus={() => handleInputFocus("from")}
130 onChange={handleInputChange(setFrom)}
131 className={styles.inputField}
132 ref={inputFieldType === "from" ? dropdownRef : null}
133 />
134 <input
135 type="text"
136 placeholder="To"
137 aria-label="To"
138 value={to}
139 onFocus={() => handleInputFocus("to")}
140 onChange={handleInputChange(setTo)}
141 className={styles.inputField}
142 ref={inputFieldType === "to" ? dropdownRef : null}
143 />
144 {renderDropdown()}
145 </div>
146 <div className={styles.buttons}>
147 <button
148 type="button"
149 className={styles.iconButton}
150 onClick={() => handleDirectionsSubmit(from, to)}
151 >
152 <img src={searchIcon} alt="Submit Directions" />
153 </button>
154 <button type="button" className={styles.iconButton} onClick={toggleExpanded}>
155 <img src={closeIcon} alt="Close Icon" />
156 </button>
157 </div>
158 </div>
159 )}
160 </div>
161 );
162}
163
164export default SearchBar;
Note: See TracBrowser for help on using the repository browser.