Index: imaps-frontend/src/pages/MapView/MapView.jsx
===================================================================
--- imaps-frontend/src/pages/MapView/MapView.jsx	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
+++ imaps-frontend/src/pages/MapView/MapView.jsx	(revision 0c6b92add4cfaedcb91bcd37b45849f142f7d152)
@@ -0,0 +1,289 @@
+import {useNavigate, useParams, useSearchParams} from "react-router-dom";
+import React, {useContext, useEffect, useRef, useState} from "react";
+import {MapDisplay} from "../../scripts/main/MapDisplay.js";
+import styles from "./MapView.module.css";
+import SearchBar from "../../components/SearchBar/SearchBar.jsx";
+import FilterBar from "../../components/FilterBar/FilterBar.jsx";
+import Profile from "../../components/Profile/Profile.jsx";
+import RoomInfoPanel from "../../components/RoomInfoPanel/RoomInfoPanel.jsx";
+import HttpService from "../../scripts/net/HttpService.js";
+import floorIcon from "../../assets/floor_icon.png";
+import Logo from "../../components/Logo/Logo.jsx";
+import config from "../../scripts/net/netconfig.js";
+import parseMapData from "../../scripts/util/parseMapData.js";
+import ShapeRegistry from "../../scripts/util/ShapeRegistry.js";
+import {useAppContext} from "../../components/AppContext/AppContext.jsx";
+
+const MapView = ({isPrivate}) => {
+    const {mapName} = useParams();
+    const {username} = useAppContext();
+
+    const [mapLoaded, setMapLoaded] = useState(false);
+    const [app, setApp] = useState(null);
+    const [isPanelOpen, setIsPanelOpen] = useState(true);
+    const [selectedRoom, setSelectedRoom] = useState(null);
+    const [floors, setFloors] = useState([]); // ova trebit da sa objekti
+    const navigate = useNavigate();
+    const [shapes, setShapes] = useState([]);
+    const [searchParams, setSearchParams] = useSearchParams();
+    const [mainEntrance, setMainEntrance] = useState({});
+
+    const defaultNavObj = {
+        enabled: false,
+        nextFloor: 0,
+        nodes: [],
+        offset: 0
+    }
+
+    const [navNext, setNavNext] = useState(defaultNavObj)
+    const [roomTypes, setRoomTypes] = useState([]);
+
+    useEffect(() => {
+        const loadRoomTypes = async () => {
+            const httpService = new HttpService();
+            let roomTypes;
+            if (isPrivate) {
+                roomTypes = await httpService.get(`${config.room_types.display(true)}?mapName=${mapName}&username=${username}`)
+            } else {
+                roomTypes = await httpService.get(`${config.room_types.display(false)}?mapName=${mapName}`)
+            }
+
+            console.log("loaded ROOM TYPES: " + roomTypes)
+            setRoomTypes(roomTypes);
+        }
+        loadRoomTypes().then(resp => {
+            console.log("LOADED ROOM TYPES")
+        })
+    }, []);
+
+
+    useEffect(() => {
+        if (!searchParams.has("floor")) {
+            setSearchParams({floor: "0"}, {replace: true});
+        }
+    }, [setSearchParams, searchParams]);
+
+
+    useEffect(() => {
+
+
+        const floorNum = parseInt(searchParams.get("floor") || 0);
+        const appInstance = new MapDisplay("map", floorNum);
+
+        const load = async () => {
+            const httpService = new HttpService();
+
+            try {
+                let url;
+                if (isPrivate) {
+                    httpService.setAuthenticated();
+                    url = `${config.view_maps.load(true)}?mapName=${mapName}&username=${username}`
+                } else {
+                    url = `${config.view_maps.load(false)}?mapName=${mapName}`
+                }
+
+                return httpService.get(url);
+            } catch (e) {
+                throw new Error("Can't load map: " + e.message);
+            }
+        };
+
+        load()
+            .then(respFloors => {
+                let tlFloor = respFloors.filter(f => f.num === floorNum)[0];
+
+                let parsedShapes = [];
+
+                respFloors.forEach(flr => {
+                    console.log("FLR", flr)
+                    const parsed = parseMapData(flr.mapData, (shape => shape.className !== "InfoPin"), true)
+                    parsedShapes = [...parsedShapes, ...parsed];
+                })
+
+                setShapes(parsedShapes)
+
+                parsedShapes.forEach(shape => {
+                    console.info("PARSED Shapes: " + shape.info.name)
+                })
+
+                const mainEntrance = parsedShapes.find(shape => shape.info.isMainEntrance);
+                setMainEntrance(mainEntrance)
+
+                console.log("MAIN ENTRANCE: " + mainEntrance)
+
+
+                setFloors(respFloors);
+
+                appInstance.loadMapN(tlFloor?.mapData)
+                setApp(appInstance);
+                setMapLoaded(true);
+            })
+            .catch(reason => {
+                console.log("ERROR LOADING MAP VIEW: " + reason)
+            });
+
+
+    }, []);
+
+    //nova load, ne vo MapDisplay
+
+    //loso
+    useEffect(() => {
+        const openRoomInfoPanel = (e) => {
+            setSelectedRoom(e.detail.room);
+            setIsPanelOpen(true)
+            console.log("SHAPES REG", ShapeRegistry.getShapes().length)
+
+        }
+        window.addEventListener("openRoomInfoPanel", openRoomInfoPanel);
+
+        return () => window.removeEventListener("openRoomInfoPanel", openRoomInfoPanel);
+    }, [])
+
+    const handleDirectionsSubmit = (fromSearch = null, toSearch = null) => {
+
+        if (fromSearch === null && toSearch === null) {
+            return;
+        }
+        if (fromSearch === null || fromSearch === "") {
+            fromSearch = mainEntrance.info.name;
+        }
+        let shapeFrom = shapes.find(sh => sh.info.name === fromSearch)
+
+
+        if (shapeFrom.floorNum != searchParams.get("floor")) {
+            handleFloorChange(shapeFrom.floorNum);
+        }
+
+        const httpService = new HttpService();
+
+        if (isPrivate) httpService.setAuthenticated();
+
+        const fromEncoded = encodeURIComponent(fromSearch).trimEnd()
+        const toEncoded = encodeURIComponent(toSearch).trimEnd()
+
+        httpService.get(`${config.view_maps.navigate}?from=${fromEncoded}&to=${toEncoded}`).then(path => {
+            app.drawRouteNEW(path);
+        }).catch(reason => {
+            console.log("err", reason)
+        })
+    };
+
+    
+
+    const multiFloorNavigate = () => {
+        if (navNext && app) {
+            console.log("NAVNEXT F: " + navNext.nextFloor)
+            const f = navNext.nextFloor;
+            handleFloorChange(f)
+            setTimeout(() => {
+                app.drawRouteNEW(navNext.nodes, navNext.offset)
+            }, 50)
+            setNavNext(defaultNavObj)
+
+        }
+    }
+
+
+    useEffect(() => {
+
+        const handleNavigate = (event) => {
+            console.log("SHAPES NAV", shapes)
+
+            setNavNext({
+                enabled: true,
+                nextFloor: event.detail.changeFloorTo,
+                nodes: event.detail.nodes,
+                offset: event.detail.offset
+            })
+
+            console.log("ROUTE LAYER", app.routeLayer);
+        }
+
+        window.addEventListener("navigate", handleNavigate)
+        return () => {
+            window.removeEventListener("navigate", handleNavigate);
+        };
+
+    }, [app, mapLoaded]);
+
+    const handleFloorChange = (floorNum) => {
+        setSearchParams({floor: floorNum}, {replace: true});
+        const chFloor = floors.find(floor => floor.num === floorNum)
+
+        console.log("FLOOR NUM:", floorNum, "CHFLOOR:", chFloor)
+        app.clearRoute()
+        app.loadMapN(chFloor.mapData)
+        app.floorNum = floorNum;
+
+
+        console.log(`Floor changed to: ${floorNum}`);
+    };
+
+    const closePanel = () => {
+        setIsPanelOpen(false);
+        selectedRoom.unHighlight()
+    };
+
+
+    return (
+        <div id="main" className={styles.main}>
+            {navNext.enabled && (
+                <div className={styles.nextButtonContainer}>
+                    <button onClick={multiFloorNavigate} className={styles.nextButton}>
+                        NEXT FLOOR
+                    </button>
+                </div>
+            )}
+
+            <div id="map" className={styles.mapContainer}></div>
+
+            <RoomInfoPanel isOpen={isPanelOpen} onClose={closePanel} floor={searchParams.get("floor")}
+                           room={selectedRoom} handleDirectionsSubmit={handleDirectionsSubmit}/>
+            <div className={styles.toolbar}>
+                <div className={styles.toolbarContainer}>
+                    <div className={styles.logoContainer}>
+                        <Logo position="relative"/>
+                    </div>
+                    <h1 className={styles.mapTitle}>{mapName}</h1>
+                    {mapLoaded && app && (
+                        <div className={styles.searchFilterContainer}>
+                            <SearchBar
+                                map={app}
+                                handleDirectionsSubmit={handleDirectionsSubmit}
+                                setIsPanelOpen={setIsPanelOpen}
+                                setSelectedRoom={setSelectedRoom}
+                                availableShapes={shapes}
+                                handleFloorChange={handleFloorChange}
+                            />
+                            <FilterBar map={app} roomTypes={roomTypes}/>
+                        </div>
+                    )}
+                    <div className={styles.profileContainer}>
+                        <Profile position="relative"/>
+                    </div>
+                </div>
+            </div>
+
+            <div className={styles.floorSelectorContainer}>
+                <div className={styles.floorSelector}>
+                    <img src={floorIcon} alt="Floor Icon" className={styles.floorIcon}/>
+                    <select
+                        value={searchParams.get("floor")}
+                        onChange={(e) => handleFloorChange(parseInt(e.target.value, 10))}
+                        className={styles.floorDropdown}
+                    >
+                        {floors?.map((floor) => (
+                            <option key={floor.num} value={floor.num}>
+                                Floor {floor.num}
+                            </option>
+                        ))}
+                    </select>
+                </div>
+            </div>
+
+        </div>
+    );
+};
+
+export default MapView;
