source: imaps-frontend/src/pages/MapView/MapView.jsx@ 79a0317

main
Last change on this file since 79a0317 was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 3 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 11.3 KB
Line 
1import {useNavigate, useParams, useSearchParams} from "react-router-dom";
2import React, {useContext, useEffect, useRef, useState} from "react";
3import {MapDisplay} from "../../scripts/main/MapDisplay.js";
4import styles from "./MapView.module.css";
5import SearchBar from "../../components/SearchBar/SearchBar.jsx";
6import FilterBar from "../../components/FilterBar/FilterBar.jsx";
7import Profile from "../../components/Profile/Profile.jsx";
8import RoomInfoPanel from "../../components/RoomInfoPanel/RoomInfoPanel.jsx";
9import HttpService from "../../scripts/net/HttpService.js";
10import floorIcon from "../../assets/floor_icon.png";
11import Logo from "../../components/Logo/Logo.jsx";
12import config from "../../scripts/net/netconfig.js";
13import parseMapData from "../../scripts/util/parseMapData.js";
14import ShapeRegistry from "../../scripts/util/ShapeRegistry.js";
15import {useAppContext} from "../../components/AppContext/AppContext.jsx";
16import Report from "../../components/Report/Report.jsx";
17import {Button} from "../IMaps/components/Button.jsx";
18
19const MapView = ({isPrivate}) => {
20 const {mapName} = useParams();
21 const {username} = useAppContext();
22 const {isAuthenticated} = useAppContext();
23
24 const [mapLoaded, setMapLoaded] = useState(false);
25 const [app, setApp] = useState(null);
26 const [isPanelOpen, setIsPanelOpen] = useState(true);
27 const [selectedRoom, setSelectedRoom] = useState(null);
28 const [floors, setFloors] = useState([]); // ova trebit da sa objekti
29 const navigate = useNavigate();
30 const [shapes, setShapes] = useState([]);
31 const [searchParams, setSearchParams] = useSearchParams();
32 const [mainEntrance, setMainEntrance] = useState({});
33 const [canDisplayNavDownload,setCanDisplayNavDownload] = useState(false);
34 const [from,setFrom] = useState("");
35 const [to,setTo] = useState("");
36
37 const defaultNavObj = {
38 enabled: false,
39 nextFloor: 0,
40 nodes: [],
41 offset: 0
42 }
43
44 const [navNext, setNavNext] = useState(defaultNavObj)
45 const [roomTypes, setRoomTypes] = useState([]);
46
47 useEffect(() => {
48 const loadRoomTypes = async () => {
49 const httpService = new HttpService();
50 let roomTypes;
51 if (isPrivate) {
52 roomTypes = await httpService.get(`${config.room_types.display(true)}?mapName=${mapName}&username=${username}`)
53 } else {
54 roomTypes = await httpService.get(`${config.room_types.display(false)}?mapName=${mapName}`)
55 }
56
57 console.log("loaded ROOM TYPES: " + roomTypes)
58 setRoomTypes(roomTypes);
59 }
60 loadRoomTypes().then(resp => {
61 console.log("LOADED ROOM TYPES")
62 })
63 }, []);
64
65
66 useEffect(() => {
67 if (!searchParams.has("floor")) {
68 setSearchParams({floor: "0"}, {replace: true});
69 }
70 }, [setSearchParams, searchParams]);
71
72
73 useEffect(() => {
74
75
76 const floorNum = parseInt(searchParams.get("floor") || 0);
77 const appInstance = new MapDisplay("map", floorNum);
78
79 const load = async () => {
80 const httpService = new HttpService();
81
82 try {
83 let url;
84 if (isPrivate) {
85 httpService.setAuthenticated();
86 url = `${config.view_maps.load(true)}?mapName=${mapName}&username=${username}`
87 } else {
88 url = `${config.view_maps.load(false)}?mapName=${mapName}`
89 }
90
91 return httpService.get(url);
92 } catch (e) {
93 throw new Error("Can't load map: " + e.message);
94 }
95 };
96
97 load()
98 .then(respFloors => {
99 let tlFloor = respFloors.filter(f => f.num === floorNum)[0];
100
101 let parsedShapes = [];
102
103 respFloors.forEach(flr => {
104 console.log("FLR", flr)
105 const parsed = parseMapData(flr.mapData, (shape => shape.className !== "InfoPin"), true)
106 parsedShapes = [...parsedShapes, ...parsed];
107 })
108
109 setShapes(parsedShapes)
110
111 parsedShapes.forEach(shape => {
112 console.info("PARSED Shapes: " + shape.info.name)
113 })
114
115 const mainEntrance = parsedShapes.find(shape => shape.info.isMainEntrance);
116 setMainEntrance(mainEntrance)
117
118 console.log("MAIN ENTRANCE: " + mainEntrance)
119
120
121 setFloors(respFloors);
122
123 console.log("FLOOR DATA: " + tlFloor?.mapData)
124
125 appInstance.loadMapN(tlFloor?.mapData)
126 setApp(appInstance);
127 setMapLoaded(true);
128 })
129 .catch(reason => {
130 console.log("ERROR LOADING MAP VIEW: " + reason)
131 });
132
133
134 }, []);
135
136 //nova load, ne vo MapDisplay
137
138 //loso
139 useEffect(() => {
140 const openRoomInfoPanel = (e) => {
141 setSelectedRoom(e.detail.room);
142 setIsPanelOpen(true)
143 console.log("SHAPES REG", ShapeRegistry.getShapes().length)
144
145 }
146 window.addEventListener("openRoomInfoPanel", openRoomInfoPanel);
147
148 return () => window.removeEventListener("openRoomInfoPanel", openRoomInfoPanel);
149 }, [])
150
151 const handleDirectionsSubmit = (fromSearch = null, toSearch = null) => {
152
153 if (fromSearch === null && toSearch === null) {
154 return;
155 }
156 if (fromSearch === null || fromSearch === "") {
157 fromSearch = mainEntrance.info.name;
158 }
159 let shapeFrom = shapes.find(sh => sh.info.name === fromSearch)
160
161
162 if (shapeFrom.floorNum != searchParams.get("floor")) {
163 handleFloorChange(shapeFrom.floorNum);
164 }
165
166 const httpService = new HttpService();
167
168 if (isPrivate) httpService.setAuthenticated();
169
170 const fromEncoded = encodeURIComponent(fromSearch).trimEnd()
171 const toEncoded = encodeURIComponent(toSearch).trimEnd()
172
173 setFrom(fromSearch);
174 setTo(toSearch);
175
176 httpService.get(`${config.view_maps.navigate}?from=${fromEncoded}&to=${toEncoded}`).then(path => {
177 app.drawRouteNEW(path);
178
179
180 }).catch(reason => {
181 console.log("err", reason)
182 })
183 };
184
185
186
187 const multiFloorNavigate = () => {
188 if (navNext && app) {
189 console.log("NAVNEXT F: " + navNext.nextFloor)
190 const f = navNext.nextFloor;
191 handleFloorChange(f)
192 setTimeout(() => {
193 app.drawRouteNEW(navNext.nodes, navNext.offset)
194 }, 50)
195 setNavNext(defaultNavObj)
196
197 }
198 }
199
200 useEffect(() => {
201 const handleNavigateEnd = (event) => {
202 console.log("DETAIL END",event.detail)
203 setCanDisplayNavDownload(true);
204 }
205
206 window.addEventListener("navend",handleNavigateEnd)
207 return () => {
208 window.removeEventListener("navend",handleNavigateEnd)
209 }
210 }, [app]);
211
212
213 useEffect(() => {
214
215 const handleNavigate = (event) => {
216 console.log("SHAPES NAV", shapes)
217
218 setNavNext({
219 enabled: true,
220 nextFloor: event.detail.changeFloorTo,
221 nodes: event.detail.nodes,
222 offset: event.detail.offset
223 })
224
225 console.log("ROUTE LAYER", app.routeLayer);
226 }
227
228 window.addEventListener("navigate", handleNavigate)
229 return () => {
230 window.removeEventListener("navigate", handleNavigate);
231 };
232
233 }, [app, mapLoaded]);
234
235 const handleFloorChange = (floorNum) => {
236 setSearchParams({floor: floorNum}, {replace: true});
237 const chFloor = floors.find(floor => floor.num === floorNum)
238
239 console.log("FLOOR NUM:", floorNum, "CHFLOOR:", chFloor)
240 app.clearRoute()
241 app.loadMapN(chFloor.mapData)
242 app.floorNum = floorNum;
243
244 console.log(`Floor changed to: ${floorNum}`);
245 };
246
247 const closePanel = () => {
248 setIsPanelOpen(false);
249 selectedRoom.unHighlight()
250 };
251
252
253 return (
254 <div id="main" className={styles.main}>
255 {navNext.enabled && (
256 <div className={styles.nextButtonContainer}>
257 <button onClick={multiFloorNavigate} className={styles.nextButton}>
258 NEXT FLOOR
259 </button>
260 </div>
261 )}
262
263 <div id="map" className={styles.mapContainer}></div>
264
265 <RoomInfoPanel isOpen={isPanelOpen} onClose={closePanel} floor={searchParams.get("floor")}
266 room={selectedRoom} handleDirectionsSubmit={handleDirectionsSubmit}/>
267 <div className={styles.toolbar}>
268 <div className={styles.toolbarContainer}>
269 <div className={styles.logoContainer}>
270 <Logo position="relative"/>
271 </div>
272 <h1 className={styles.mapTitle}>{mapName}</h1>
273 {mapLoaded && app && (
274 <div className={styles.searchFilterContainer}>
275 <SearchBar
276 map={app}
277 handleDirectionsSubmit={handleDirectionsSubmit}
278 setIsPanelOpen={setIsPanelOpen}
279 setSelectedRoom={setSelectedRoom}
280 availableShapes={shapes}
281 handleFloorChange={handleFloorChange}
282 />
283 {canDisplayNavDownload &&
284 (<div className={styles.downloadRouteButton}>
285 <button onClick={() => {
286 app.getRouteImages({
287 mapName: mapName,
288 from: from,
289 to: to
290 })
291 setCanDisplayNavDownload(false)
292 }}> Download Route</button>
293 </div>) }
294 <FilterBar map={app} roomTypes={roomTypes}/>
295 </div>
296 )}
297
298 {isAuthenticated && <Report mapName = {mapName}></Report>}
299 <div className={styles.profileContainer}>
300 <Profile position="relative"/>
301 </div>
302 </div>
303 </div>
304 <div id="temp"></div>
305
306 <div className={styles.floorSelectorContainer}>
307 <div className={styles.floorSelector}>
308 <img src={floorIcon} alt="Floor Icon" className={styles.floorIcon}/>
309 <select
310 value={searchParams.get("floor")}
311 onChange={(e) => handleFloorChange(parseInt(e.target.value, 10))}
312 className={styles.floorDropdown}
313 >
314 {floors?.map((floor) => (
315 <option key={floor.num} value={floor.num}>
316 Floor {floor.num}
317 </option>
318 ))}
319 </select>
320 </div>
321 </div>
322
323
324 </div>
325 );
326};
327
328export default MapView;
Note: See TracBrowser for help on using the repository browser.