diff --git a/assets/freeClassrooms/clock.svg b/assets/freeClassrooms/clock.svg new file mode 100644 index 00000000..075e8225 --- /dev/null +++ b/assets/freeClassrooms/clock.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/freeClassrooms/expand.svg b/assets/freeClassrooms/expand.svg new file mode 100644 index 00000000..a8064ab6 --- /dev/null +++ b/assets/freeClassrooms/expand.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/freeClassrooms/tick.svg b/assets/freeClassrooms/tick.svg new file mode 100644 index 00000000..bae8dd33 --- /dev/null +++ b/assets/freeClassrooms/tick.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/MainContainer.tsx b/src/MainContainer.tsx index da440944..bd6e522d 100644 --- a/src/MainContainer.tsx +++ b/src/MainContainer.tsx @@ -65,7 +65,25 @@ export const MainContainer: FC = () => { console.log("downloads") }} onNotifications={() => { - console.log("notifications") + navigate("RoomDetails", { + room: { + name: "2.0.1", + capacity: 380, + building: "Edificio 2", + address: "Piazza Leonardo da Vinci, 32 - 20133 - Milano (MI)", + power: false, + }, + startDate: "2023-02-22T16:15:00Z", + roomId: 32, + roomLatitude: 45.4788249919485, + roomLongitude: 9.227210008150676, + occupancies: { + // eslint-disable-next-line @typescript-eslint/naming-convention + "19:00": "FREE", + // eslint-disable-next-line @typescript-eslint/naming-convention + "19:35": "OCCUPIED", + }, + }) }} onSettings={() => { navigate("SettingsNav", { diff --git a/src/api/rooms.ts b/src/api/rooms.ts index 10f35b54..8ff79e64 100644 --- a/src/api/rooms.ts +++ b/src/api/rooms.ts @@ -1,4 +1,4 @@ -import { HttpClient, RequestOptions } from "./HttpClient" +import { AuthType, HttpClient, RequestOptions } from "./HttpClient" /* eslint-disable @typescript-eslint/naming-convention */ export interface Rooms { @@ -10,13 +10,32 @@ export interface Room { building: string power: boolean link: string - occupancyRate: number | undefined + occupancy_rate: number | null + occupancies: Occupancies } + +export type Occupancies = Record<`${number}:${number}`, "FREE" | "OCCUPIED"> + export interface RoomSimplified { roomId: number name: string + occupancies: Occupancies occupancyRate: number | undefined } + +export interface RoomDetails { + name: string + capacity: number + building: string + address: string + power: boolean +} + +export interface OccupancyInfo { + room_id: number + occupancy_rate: null | number +} + const client = HttpClient.getInstance() /** @@ -46,11 +65,36 @@ export const rooms = { return response.data.free_rooms }, + async getOccupancyRate(roomId: number, options?: RequestOptions) { + const response = await client.poliNetworkInstance.get( + "/v1/rooms/" + roomId + "/occupancy", + { + ...options, + } + ) + return response.data + }, + + async postOccupancyRate( + roomId: number, + rate: number, + options?: RequestOptions + ) { + const res = await client.poliNetworkInstance.post( + "/v1/rooms/" + roomId + "/occupancy", + { + ...options, + }, + { params: { rate: rate }, authType: AuthType.POLINETWORK } + ) + return res + }, + /** * Retrieves room details from PoliNetwork Server. */ async getRoomInfo(roomId: number, options?: RequestOptions) { - const response = await client.poliNetworkInstance.get( + const response = await client.poliNetworkInstance.get( "/v1/rooms/" + roomId, { ...options, diff --git a/src/components/ContentWrapperScroll.tsx b/src/components/ContentWrapperScroll.tsx index a30aab87..2290a84b 100644 --- a/src/components/ContentWrapperScroll.tsx +++ b/src/components/ContentWrapperScroll.tsx @@ -1,5 +1,5 @@ import React, { FC } from "react" -import { ScrollView, View } from "react-native" +import { ScrollView, View, ViewStyle } from "react-native" import { Text } from "components/Text" import { NavBar, NavbarProps } from "components/NavBar" import { usePalette } from "utils/colors" @@ -21,7 +21,10 @@ export const ContentWrapperScroll: FC<{ * Props for the navbar, see {@link NavBar} */ navbarOptions?: NavbarProps - marginTop?: number + + style?: ViewStyle + + scrollViewStyle?: ViewStyle }> = props => { const { background, isLight, primary } = usePalette() @@ -56,23 +59,26 @@ export const ContentWrapperScroll: FC<{ )} - + {props.children} diff --git a/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderDynamic.tsx b/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderDynamic.tsx new file mode 100644 index 00000000..56d0ec3a --- /dev/null +++ b/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderDynamic.tsx @@ -0,0 +1,89 @@ +import React, { FC } from "react" +import { View } from "react-native" +import { usePalette } from "utils/colors" +import Animated, { + runOnJS, + useAnimatedStyle, + useSharedValue, +} from "react-native-reanimated" +import { + Gesture, + GestureDetector, + GestureHandlerRootView, +} from "react-native-gesture-handler" +import { getCrowdStatus } from "utils/rooms" + +interface CrowdSliderDynamicProps { + usableWidth?: number + startingPos: number + onSlideEnd: (pos: number) => void +} + +export const CrowdSliderDynamic: FC = props => { + const { sliderBorderColor } = usePalette() + + const wrapper = (pos: number, width: number) => { + const crowdStatus = getCrowdStatus(pos, width) + if (props.onSlideEnd) { + props.onSlideEnd(crowdStatus) + } + } + const circleWidth = 28 + + //320 is modal width, 52 is content padding + const usableWidth = props.usableWidth ?? 320 - 52 - circleWidth + + const startingPos = ((props.startingPos - 1) / 4) * usableWidth + + const position = useSharedValue(startingPos) + const lastPosition = useSharedValue(startingPos) + const panGesture = Gesture.Pan() + .onUpdate(e => { + const newPos = e.translationX + lastPosition.value + position.value = newPos + if (newPos < 0) { + position.value = 0 + } else if (newPos > usableWidth) { + position.value = usableWidth + } + }) + .onEnd(() => { + lastPosition.value = position.value + runOnJS(wrapper)(position.value, usableWidth) + }) + + const animatedPos = useAnimatedStyle(() => ({ + transform: [{ translateX: position.value }], + })) + + return ( + + + + + + + + + + ) +} diff --git a/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderLabels.tsx b/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderLabels.tsx new file mode 100644 index 00000000..7c5ea091 --- /dev/null +++ b/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderLabels.tsx @@ -0,0 +1,49 @@ +import React, { FC } from "react" +import { usePalette } from "utils/colors" +import { BodyText } from "components/Text" +import { View } from "react-native" + +export const CrowdSliderLabels: FC = () => { + const { labelsHighContrast } = usePalette() + + return ( + + + Basso + + + Medio + + + Alto + + + ) +} diff --git a/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderStatic.tsx b/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderStatic.tsx new file mode 100644 index 00000000..931b908f --- /dev/null +++ b/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderStatic.tsx @@ -0,0 +1,42 @@ +import React, { FC } from "react" +import { Dimensions, View } from "react-native" +import { usePalette } from "utils/colors" + +interface CrowdSliderStaticProps { + position: number +} + +export const CrowdSliderStatic: FC = props => { + const { sliderBorderColor } = usePalette() + + //56 is padding, 28 is circle diameter + const usableWidth = Dimensions.get("screen").width - 56 - 28 + + const startingPos = ((props.position - 1) / 4) * usableWidth + + return ( + + + + + + ) +} diff --git a/src/components/FreeClass/ClassDetails/CrowdingSection.tsx b/src/components/FreeClass/ClassDetails/CrowdingSection.tsx new file mode 100644 index 00000000..4e8097a0 --- /dev/null +++ b/src/components/FreeClass/ClassDetails/CrowdingSection.tsx @@ -0,0 +1,145 @@ +import React, { FC, useEffect, useState } from "react" +import { Pressable, View } from "react-native" +import { usePalette } from "utils/colors" +import { BodyText } from "components/Text" +import { CrowdSliderStatic } from "./CrowdSlider/CrowdSliderStatic" +import { CrowdSliderDynamic } from "./CrowdSlider/CrowdSliderDynamic" +import { CrowdSliderLabels } from "./CrowdSlider/CrowdSliderLabels" +import { ButtonCustom } from "components/Button" +import { ModalWithGestures } from "../ModalWithGestures" +import { api, RetryType } from "api" + +interface CrowdingSectionProps { + roomId: number + isSlidable?: boolean + onSlided?: () => void +} + +export const CrowdingSection: FC = props => { + const { iconHighContrast, labelsHighContrast } = usePalette() + + const [isModalVisible, setIsModalVisible] = useState(false) + + const [occupancyRate, setOccupancyRate] = useState(1) + + let occupancyRateUser = 3 + + const getOccupancyRate = async () => { + try { + const res = await api.rooms.getOccupancyRate(props.roomId) + if (res.occupancy_rate !== null) { + setOccupancyRate(res.occupancy_rate) + } + } catch (err) { + console.log(err) + } + } + + useEffect(() => { + void getOccupancyRate() + }, []) + + const postOccupancyRate = async () => { + try { + await api.rooms.postOccupancyRate(props.roomId, occupancyRateUser, { + retryType: RetryType.RETRY_N_TIMES, + maxRetries: 3, + }) + } catch (err) { + console.log(err) + } + } + return ( + + + Affollamento: + + + + + + + Se il dato sull'affollamento non è corretto + + setIsModalVisible(true)}> + + esprimi opinione + + + + + setIsModalVisible(false)} + > + + + Esprimi{"\n"}Opinione + + + Indica il livello di affollamento {"\n"} dell'aula + + + (occupancyRateUser = pos)} + /> + + + + { + void postOccupancyRate() + setIsModalVisible(false) + }} + /> + + + + ) +} diff --git a/src/components/FreeClass/ClassDetails/InfoMapTile.tsx b/src/components/FreeClass/ClassDetails/InfoMapTile.tsx new file mode 100644 index 00000000..91c18ac9 --- /dev/null +++ b/src/components/FreeClass/ClassDetails/InfoMapTile.tsx @@ -0,0 +1,241 @@ +import React, { FC } from "react" +import { Linking, Platform, Pressable, View } from "react-native" +import { usePalette } from "utils/colors" +import { BodyText, Text } from "components/Text" +import { extractBuilding, extractRoom } from "utils/rooms" +import MapView from "react-native-maps" +import expand from "assets/freeClassrooms/expand.svg" +import { Canvas, ImageSVG, useSVG } from "@shopify/react-native-skia" + +interface InfoMapTileProps { + roomName: string + building: string + address?: string + capacity?: number + longitude?: number + latitude?: number +} + +export const InfoMapTile: FC = props => { + const { labelsHighContrast, isLight, palette, primary } = usePalette() + + const building = extractBuilding(props.building) + const roomName = extractRoom(props.roomName) + + const expandSvg = useSVG(expand) + + const latitude = props.latitude + const longitude = props.longitude + + /*from https://stackoverflow.com/questions/73653813/how-to-open-google-map-with-latitude-and-longitude*/ + const openAddressOnMap = (label: string, lat: string, lng: string) => { + const scheme = Platform.select({ + ios: "maps:0,0?q=", + android: "geo:0,0?q=", + }) + const latLng = `${lat},${lng}` + if (scheme) { + const url = Platform.select({ + ios: `${scheme}${label}@${latLng}`, + android: `${scheme}${latLng}(${label})`, + }) + if (url) { + void Linking.openURL(url) + } + } + } + return ( + + + + + {building && roomName ? `${building}.` : undefined} + + + {building && roomName ? roomName : props.roomName} + + + + + Indirizzo : + + + {props.address} + + + + + Capienza:{" "} + + + {props.capacity} + + + + {latitude && longitude && ( + + + + openAddressOnMap( + props.building, + latitude.toString(), + longitude.toString() + ) + } + > + + {expand && expandSvg && ( + + + + + + )} + + + + + consulta la{" "} + + + mappa + + + + + + )} + + ) +} diff --git a/src/components/FreeClass/ClassDetails/RoomUtilsSection.tsx b/src/components/FreeClass/ClassDetails/RoomUtilsSection.tsx new file mode 100644 index 00000000..0cef6ab4 --- /dev/null +++ b/src/components/FreeClass/ClassDetails/RoomUtilsSection.tsx @@ -0,0 +1,32 @@ +import React, { FC } from "react" +import { View } from "react-native" +import { usePalette } from "utils/colors" +import { BodyText } from "components/Text" +import { RoomUtilsTile } from "./RoomUtilsTile" + +interface RoomUtilsSectionProps { + power?: boolean + computers?: boolean + ribaltine?: boolean +} + +export const RoomUtilsSection: FC = props => { + const { labelsHighContrast } = usePalette() + + return ( + + + Info Utili: + + + + + + ) +} diff --git a/src/components/FreeClass/ClassDetails/RoomUtilsTile.tsx b/src/components/FreeClass/ClassDetails/RoomUtilsTile.tsx new file mode 100644 index 00000000..2619988e --- /dev/null +++ b/src/components/FreeClass/ClassDetails/RoomUtilsTile.tsx @@ -0,0 +1,82 @@ +import React, { FC, useMemo } from "react" +import { View } from "react-native" +import { usePalette } from "utils/colors" +import { BodyText } from "components/Text" + +import { + BlendMode, + Canvas, + Group, + ImageSVG, + Skia, + useSVG, +} from "@shopify/react-native-skia" +import tick from "assets/freeClassrooms/tick.svg" + +interface RoomUtilsTileProps { + name: string + status?: boolean +} + +export const RoomUtilsTile: FC = props => { + const { palette, isLight, sliderBorderColor } = usePalette() + + const tickSvg = useSVG(tick) + + const paintTick = useMemo(() => Skia.Paint(), []) + paintTick.setColorFilter( + Skia.ColorFilter.MakeBlend( + Skia.Color( + props.status + ? isLight + ? palette.primary + : palette.lighter + : isLight + ? palette.lighter + : palette.primary + ), + BlendMode.SrcIn + ) + ) + + return ( + + {tick && tickSvg && ( + + + + + + + + )} + + {props.name} + + + ) +} diff --git a/src/components/FreeClass/ClassDetails/TimeLeftTile.tsx b/src/components/FreeClass/ClassDetails/TimeLeftTile.tsx new file mode 100644 index 00000000..9623804f --- /dev/null +++ b/src/components/FreeClass/ClassDetails/TimeLeftTile.tsx @@ -0,0 +1,226 @@ +import React, { FC, useMemo } from "react" +import { View } from "react-native" +import { usePalette } from "utils/colors" +import { BodyText } from "components/Text" + +import { + BlendMode, + Canvas, + Group, + ImageSVG, + Skia, + useSVG, +} from "@shopify/react-native-skia" +import clock from "assets/freeClassrooms/clock.svg" +import { extractTimeLeft, getEndDate } from "utils/rooms" +import { Occupancies } from "api/rooms" + +interface TimeLeftTileProps { + startDate: string + occupancies?: Occupancies +} + +export const TimeLeftTile: FC = props => { + const { isLight, labelsHighContrast, iconHighContrast, primary } = + usePalette() + + const clockSvg = useSVG(clock) + + const paint = useMemo(() => Skia.Paint(), []) + paint.setColorFilter( + Skia.ColorFilter.MakeBlend(Skia.Color(labelsHighContrast), BlendMode.SrcIn) + ) + const paintClock = useMemo(() => Skia.Paint(), []) + paintClock.setColorFilter( + Skia.ColorFilter.MakeBlend( + Skia.Color(isLight ? primary : "#fff"), + BlendMode.SrcIn + ) + ) + + const now = new Date() + + const startDate = new Date(props.startDate) + + const endDate = getEndDate(startDate, props.occupancies) + + const startHour = startDate.getHours().toString().padStart(2, "0") + const startMinutes = startDate.getMinutes().toString().padStart(2, "0") + + const endhour = endDate?.getHours().toString().padStart(2, "0") ?? undefined + const endMinutes = + endDate?.getMinutes().toString().padStart(2, "0") ?? undefined + + const { hoursLeft, minutesLeft } = extractTimeLeft(now, endDate) + + return ( + + + Libera: + + + + + + + Da + + + + {startHour} : {startMinutes} + + + + + + A + + + + {endhour && endMinutes + ? `${endhour} : ${endMinutes}` + : "-- : --"} + + + + + + + + {clock && clockSvg && ( + + + + + + + + )} + + + Mancano: + + + {hoursLeft && minutesLeft + ? `${hoursLeft} h ${minutesLeft}'` + : "-- h -- '"} + + + + + + + ) +} diff --git a/src/components/FreeClass/FreeClassList.tsx b/src/components/FreeClass/FreeClassList.tsx index 9135f470..f33b905b 100644 --- a/src/components/FreeClass/FreeClassList.tsx +++ b/src/components/FreeClass/FreeClassList.tsx @@ -6,6 +6,8 @@ import { usePalette } from "utils/colors" import timerIcon from "assets/freeClassrooms/timer.svg" import overcrowdingIcon from "assets/freeClassrooms/overcrowding.svg" import fireIcon from "assets/freeClassrooms/fire.svg" +import { useNavigation } from "navigation/NavigationTypes" +import { api } from "api" import { FlatList } from "react-native-gesture-handler" import { RoomSimplified } from "api/rooms" @@ -13,6 +15,9 @@ const { width } = Dimensions.get("window") interface FreeClassListProps { data: RoomSimplified[] | undefined + date: Date + latitude?: number + longitude?: number } enum OvercrowdingTypes { @@ -29,6 +34,7 @@ export const FreeClassList: FC = props => { const timerSVG = useSVG(timerIcon) const overcrowdingSVG = useSVG(overcrowdingIcon) const fireSVG = useSVG(fireIcon) + const { navigate } = useNavigation() const [isOvercrowded, setIsOvercrowded] = useState(false) @@ -68,6 +74,22 @@ export const FreeClassList: FC = props => { marginBottom: 34, borderRadius: 12, }} + onPress={async () => { + try { + const selectedRoom = await api.rooms.getRoomInfo(item.roomId) + navigate("RoomDetails", { + room: selectedRoom, + startDate: props.date.toISOString(), + roomId: item.roomId, + roomLatitude: props.latitude, + roomLongitude: props.longitude, + occupancies: item.occupancies, + occupancyRate: item.occupancyRate, + }) + } catch (err) { + console.log(err) + } + }} > void +} + +/** + * custom modal component that can use reanimated gestures!! The problem with standard modals is + * that gestures wrapped inside Pressable dont work. The content needs to use `gestureHandlerRootHOC` + * as implemented below. + * + */ +export const ModalWithGestures: FC = props => { + const { backgroundSecondary, modalBarrier } = usePalette() + + const deleteSvg = useSVG(icon.svg) + + // eslint-disable-next-line @typescript-eslint/naming-convention + const ContentRootHOC = gestureHandlerRootHOC(() => ( + + + props.onClose()} + > + + + {deleteSvg && ( + + )} + + + + + {props.children} + + + + )) + + return ( + //TODO: animationType fade or slide? + + + + ) +} + +const styles = StyleSheet.create({ + pageWrapper: { + flex: 1, + justifyContent: "center", + alignItems: "center", + }, + contentWrapper: { + borderRadius: 12, + + shadowColor: "#000", + shadowOffset: { + width: 0, + height: 3, + }, + shadowOpacity: 0.27, + shadowRadius: 4.65, + elevation: 6, + }, + circle: { + width: 30, + height: 30, + backgroundColor: "#ffffff", + borderRadius: 15, + marginTop: 96, + marginBottom: 8, + justifyContent: "center", + alignItems: "center", + }, +}) diff --git a/src/components/FreeClass/PositionModality.tsx b/src/components/FreeClass/PositionModality.tsx index e3a533ac..34f82ff7 100644 --- a/src/components/FreeClass/PositionModality.tsx +++ b/src/components/FreeClass/PositionModality.tsx @@ -128,7 +128,7 @@ export const PositionModality: FC = props => { size="large" /> ) : ( - + )} ) : ( diff --git a/src/components/FreeClass/buildingCoords.json b/src/components/FreeClass/buildingCoords.json index a68f56c9..01597239 100644 --- a/src/components/FreeClass/buildingCoords.json +++ b/src/components/FreeClass/buildingCoords.json @@ -1,1165 +1,1215 @@ [ - { - "acronym": "MIA", - "campus": [ - { - "name": ["Leonardo"], - "buildings": [ - { - "name": "Edificio 29", - "address": "Piazza Leonardo da Vinci 26, Milano, 20133", - "coords": { - "latitude": 45.47668740966992, - "longitude": 9.226326859295256 - } - }, - { - "name": "Edificio 1", - "address": "Piazza Leonardo da Vinci 32, Milano, 20133", - "coords": { - "latitude": 45.47811790554435, - "longitude": 9.227725945733395 - } - }, - { - "name": "Edificio 10", - "address": "Piazza Leonardo da Vinci 32, Milano, 20133", - "coords": { - "latitude": 45.47912809822935, - "longitude": 9.229883268245544 - } - }, - { - "name": "Edificio 2", - "address": "Piazza Leonardo da Vinci 32, Milano, 20133", - "coords": { - "latitude": 45.4788249919485, - "longitude": 9.227210008150676 - } - }, - { - "name": "Edificio 2A", - "address": "Piazza Leonardo da Vinci 32, Milano, 20133", - "coords": { - "latitude": 45.47876288697592, - "longitude": 9.227837695286086 - } - }, - { - "name": "Edificio 3", - "address": "Piazza Leonardo da Vinci 32, Milano, 20133", - "coords": { - "latitude": 45.477435603580254, - "longitude": 9.227835389634977 - } - }, - { - "name": "Edificio 3A", - "address": "Piazza Leonardo da Vinci 32, Milano, 20133", - "coords": { - "latitude": 45.47729656843257, - "longitude": 9.22805442460651 - } - }, - { - "name": "Edificio 4", - "address": "Piazza Leonardo da Vinci 32, Milano, 20133", - "coords": { - "latitude": 45.478602838628646, - "longitude": 9.22845329881462 - } - }, - { - "name": "Edificio 4A", - "address": "Piazza Leonardo da Vinci 32, Milano, 20133", - "coords": { - "latitude": 45.478974667422236, - "longitude": 9.228990510865588 - } - }, - { - "name": "Edificio 5", - "address": "Piazza Leonardo da Vinci 32, Milano, 20133", - "coords": { - "latitude": 45.47769427270723, - "longitude": 9.228464826976882 - } - }, - { - "name": "Edificio 6", - "address": "Piazza Leonardo da Vinci 32, Milano, 20133", - "coords": { - "latitude": 45.47825202398337, - "longitude": 9.22875994776181 - } - }, - { - "name": "Edificio 7", - "address": "Piazza Leonardo da Vinci 32, Milano, 20133", - "coords": { - "latitude": 45.47814209083751, - "longitude": 9.229737535377756 - } - }, - { - "name": "Edificio 8", - "address": "Piazza Leonardo da Vinci 32, Milano, 20133", - "coords": { - "latitude": 45.478809769736515, - "longitude": 9.229442414594473 - } - }, - { - "name": "Edificio 9", - "address": "Piazza Leonardo da Vinci 32, Milano, 20133", - "coords": { - "latitude": 45.47759727192502, - "longitude": 9.229230296528302 - } - }, - { - "name": "Edificio 9A", - "address": "Piazza Leonardo da Vinci 32, Milano, 20133", - "coords": { - "latitude": 45.4771381326113, - "longitude": 9.229815926853346 - } - } - ] - }, - { - "name": ["Bassini"], - "buildings": [ - { - "name": "Edificio 19", - "address": "Via Ponzio 34/3, Milano, 20133", - "coords": { - "latitude": 45.47879081655148, - "longitude": 9.231155363015363 - } - }, - { - "name": "Edificio 20", - "address": "Via Ponzio 34/5, Milano, 20133", - "coords": { - "latitude": 45.478695312571354, - "longitude": 9.232531759044313 - } - }, - { - "name": "Edificio 21", - "address": "Via Golgi 39, Milano, 20133", - "coords": { - "latitude": 45.479048844048855, - "longitude": 9.233791065831895 - } - }, - { - "name": "Edificio 36", - "address": "Via Golgi 39, Milano, 20133", - "coords": { - "latitude": 45.47839707102326, - "longitude": 9.232902143392922 - } - }, - { - "name": "Edificio 36A", - "address": "Via Golgi 39, Milano, 20133", - "coords": { - "latitude": 45.47840377309843, - "longitude": 9.233573614377585 - } - }, - { - "name": "Edificio 37", - "address": "Via Golgi 39, Milano, 20133", - "coords": { - "latitude": 45.47840377309843, - "longitude": 9.233934440407387 - } - }, - { - "name": "Edificio 42", - "address": "Via Bassini 34/3, Milano, 20133", - "coords": { - "latitude": 45.47751909234621, - "longitude": 9.231437333034433 - } - }, - { - "name": "Edificio 43", - "address": "Via Bassini 34/3, Milano, 20133", - "coords": { - "latitude": 45.477644758070845, - "longitude": 9.231425385160406 - } - }, - { - "name": "Isola Ecologica", - "address": "Via Bassini 2, Milano, 20133", - "coords": { - "latitude": 45.478764590939626, - "longitude": 9.234032129716745 - } - } - ] - }, - { - "name": ["Bonardi"], - "buildings": [ - { - "name": "Edificio 11", - "address": "Via Ampère 2, Milano, 20133", - "coords": { - "latitude": 45.479700368402455, - "longitude": 9.227144319107985 - } - }, - { - "name": "Edificio 11B", - "address": "Via Ampère 4, Milano, 20133", - "coords": { - "latitude": 45.48039066193507, - "longitude": 9.226718974511959 - } - }, - { - "name": "Edificio 12", - "address": "Via Bonardi 3, Milano, 20133", - "coords": { - "latitude": 45.479559627904706, - "longitude": 9.227662857193996 - } - }, - { - "name": "Edificio 13", - "address": "Via Bonardi 9, Milano, 20133", - "coords": { - "latitude": 45.47986624067945, - "longitude": 9.228233965961486 - } - }, - { - "name": "Edificio 14", - "address": "Via Bonardi 9, Milano, 20133", - "coords": { - "latitude": 45.47964507754049, - "longitude": 9.22878834771603 - } - }, - { - "name": "Edificio 14A", - "address": "Via Bonardi 9, Milano, 20133", - "coords": { - "latitude": 45.48014771978483, - "longitude": 9.229170679933038 - } - }, - { - "name": "Edificio 14B", - "address": "Via Bonardi 9, Milano, 20133", - "coords": { - "latitude": 45.48014771978483, - "longitude": 9.228752504070686 - } - }, - { - "name": "Edificio 15", - "address": "Via Ponzio 31, Milano, 20133", - "coords": { - "latitude": 45.47966685878651, - "longitude": 9.229574518342371 - } - }, - { - "name": "Edificio 16A", - "address": "Via Bonardi 9, Milano, 20133", - "coords": { - "latitude": 45.479556276937224, - "longitude": 9.228453806990538 - } - }, - { - "name": "Edificio 16B", - "address": "Via Bonardi 9, Milano, 20133", - "coords": { - "latitude": 45.48007902560742, - "longitude": 9.227603117798322 - } - }, - { - "name": "Edificio 16C", - "address": "Via Bonardi 9, Milano, 20133", - "coords": { - "latitude": 45.479629998198945, - "longitude": 9.229118109245283 - } - }, - { - "name": "Edificio 18", - "address": "Via Ponzio 33, Milano, 20133", - "coords": { - "latitude": 45.48018625550555, - "longitude": 9.229739399120684 - } - } - ] - }, - { - "name": ["Colombo"], - "buildings": [ - { - "name": "Edificio 32.1", - "address": "Via Colombo 40, Milano, 20133", - "coords": { - "latitude": 45.47213230193092, - "longitude": 9.22686863256574 - } - }, - { - "name": "Edificio 32.2", - "address": "Via Colombo 40, Milano, 20133", - "coords": { - "latitude": 45.47207569302287, - "longitude": 9.227194415489148 - } - }, - { - "name": "Edificio 32.3", - "address": "Via Colombo 40, Milano, 20133", - "coords": { - "latitude": 45.47184925682209, - "longitude": 9.227171351211384 - } - }, - { - "name": "Edificio 32.4", - "address": "Via Colombo 40, Milano, 20133", - "coords": { - "latitude": 45.47190990946507, - "longitude": 9.226883047739344 - } - }, - { - "name": "Edificio 32.5", - "address": "Via Colombo 40, Milano, 20133", - "coords": { - "latitude": 45.47175625597605, - "longitude": 9.226926293260147 - } - }, - { - "name": "Edificio 30", - "address": "Via Colombo 81, Milano, 20133", - "coords": { - "latitude": 45.47586392362531, - "longitude": 9.226261178708338 - } - } - ] - }, - { - "name": ["Golgi"], - "buildings": [ - { - "name": "Edificio 26", - "address": "Via Golgi 20, Milano, 20133", - "coords": { - "latitude": 45.47569395835836, - "longitude": 9.235024035751083 - } - }, - { - "name": "Edificio 27", - "address": "Via Valvassori Peroni, Milano, 20133", - "coords": { - "latitude": 45.475868563542505, - "longitude": 9.236353204609438 - } - }, - { - "name": "Edificio 22", - "address": "Via Golgi 42, Milano, 20133", - "coords": { - "latitude": 45.47796163250129, - "longitude": 9.234955773844867 - } - }, - { - "name": "Edificio 23", - "address": "Via Golgi 40, Milano, 20133", - "coords": { - "latitude": 45.47770332464026, - "longitude": 9.234945870954828 - } - }, - { - "name": "Edificio 24", - "address": "Via Golgi 40, Milano, 20133", - "coords": { - "latitude": 45.47747417957433, - "longitude": 9.23470424043846 - } - }, - { - "name": "Edificio 25", - "address": "Via U.B. Secondo 3, Milano, 20133", - "coords": { - "latitude": 45.47750473230304, - "longitude": 9.23513402586612 - } - } - ] - }, - { - "name": ["Mancinelli"], - "buildings": [ - { - "name": "Edificio 28", - "address": "Via Mancinelli 7, Milano, 20133", - "coords": { - "latitude": 45.49016309824922, - "longitude": 9.226888094653553 - } - } - ] - }, - { - "name": ["Pascoli"], - "buildings": [ - { - "name": "Edificio 38", - "address": "Via Pascoli 70/3, Milano, 20133", - "coords": { - "latitude": 45.47547780481562, - "longitude": 9.22570000206852 - } - }, - { - "name": "Edificio 39", - "address": "Via Pascoli 70/3, Milano, 20133", - "coords": { - "latitude": 45.475677913901855, - "longitude": 9.225758755850668 - } - }, - { - "name": "Edificio 40", - "address": "Via Pascoli 70/3, Milano, 20133", - "coords": { - "latitude": 45.47591627820953, - "longitude": 9.225771345946843 - } - } - ] - }, - { - "name": ["Romagna"], - "buildings": [ - { - "name": "Casa dello Studente", - "address": "Viale Romagna 62, Milano, 20133", - "coords": { - "latitude": 45.47678010082273, - "longitude": 9.224452739758812 - } - } - ] + { + "acronym": "MIA", + "campus": [ + { + "name": [ + "Leonardo" + ], + "buildings": [ + { + "name": "Edificio 29", + "address": "Piazza Leonardo da Vinci 26, Milano, 20133", + "coords": { + "latitude": 45.47668740966992, + "longitude": 9.226326859295256 } + }, + { + "name": "Edificio 1", + "address": "Piazza Leonardo da Vinci 32, Milano, 20133", + "coords": { + "latitude": 45.47811790554435, + "longitude": 9.227725945733395 + } + }, + { + "name": "Edificio 10", + "address": "Piazza Leonardo da Vinci 32, Milano, 20133", + "coords": { + "latitude": 45.47912809822935, + "longitude": 9.229883268245544 + } + }, + { + "name": "Edificio 2", + "address": "Piazza Leonardo da Vinci 32, Milano, 20133", + "coords": { + "latitude": 45.4788249919485, + "longitude": 9.227210008150676 + } + }, + { + "name": "Edificio 2A", + "address": "Piazza Leonardo da Vinci 32, Milano, 20133", + "coords": { + "latitude": 45.47876288697592, + "longitude": 9.227837695286086 + } + }, + { + "name": "Edificio 3", + "address": "Piazza Leonardo da Vinci 32, Milano, 20133", + "coords": { + "latitude": 45.477435603580254, + "longitude": 9.227835389634977 + } + }, + { + "name": "Edificio 3A", + "address": "Piazza Leonardo da Vinci 32, Milano, 20133", + "coords": { + "latitude": 45.47729656843257, + "longitude": 9.22805442460651 + } + }, + { + "name": "Edificio 4", + "address": "Piazza Leonardo da Vinci 32, Milano, 20133", + "coords": { + "latitude": 45.478602838628646, + "longitude": 9.22845329881462 + } + }, + { + "name": "Edificio 4A", + "address": "Piazza Leonardo da Vinci 32, Milano, 20133", + "coords": { + "latitude": 45.478974667422236, + "longitude": 9.228990510865588 + } + }, + { + "name": "Edificio 5", + "address": "Piazza Leonardo da Vinci 32, Milano, 20133", + "coords": { + "latitude": 45.47769427270723, + "longitude": 9.228464826976882 + } + }, + { + "name": "Edificio 6", + "address": "Piazza Leonardo da Vinci 32, Milano, 20133", + "coords": { + "latitude": 45.47825202398337, + "longitude": 9.22875994776181 + } + }, + { + "name": "Edificio 7", + "address": "Piazza Leonardo da Vinci 32, Milano, 20133", + "coords": { + "latitude": 45.47814209083751, + "longitude": 9.229737535377756 + } + }, + { + "name": "Edificio 8", + "address": "Piazza Leonardo da Vinci 32, Milano, 20133", + "coords": { + "latitude": 45.478809769736515, + "longitude": 9.229442414594473 + } + }, + { + "name": "Edificio 9", + "address": "Piazza Leonardo da Vinci 32, Milano, 20133", + "coords": { + "latitude": 45.47759727192502, + "longitude": 9.229230296528302 + } + }, + { + "name": "Edificio 9A", + "address": "Piazza Leonardo da Vinci 32, Milano, 20133", + "coords": { + "latitude": 45.4771381326113, + "longitude": 9.229815926853346 + } + } + ] + }, + { + "name": [ + "Bassini" + ], + "buildings": [ + { + "name": "Edificio 19", + "address": "Via Ponzio 34/3, Milano, 20133", + "coords": { + "latitude": 45.47879081655148, + "longitude": 9.231155363015363 + } + }, + { + "name": "Edificio 20", + "address": "Via Ponzio 34/5, Milano, 20133", + "coords": { + "latitude": 45.478695312571354, + "longitude": 9.232531759044313 + } + }, + { + "name": "Edificio 21", + "address": "Via Golgi 39, Milano, 20133", + "coords": { + "latitude": 45.479048844048855, + "longitude": 9.233791065831895 + } + }, + { + "name": "Edificio 36", + "address": "Via Golgi 39, Milano, 20133", + "coords": { + "latitude": 45.47839707102326, + "longitude": 9.232902143392922 + } + }, + { + "name": "Edificio 36A", + "address": "Via Golgi 39, Milano, 20133", + "coords": { + "latitude": 45.47840377309843, + "longitude": 9.233573614377585 + } + }, + { + "name": "Edificio 37", + "address": "Via Golgi 39, Milano, 20133", + "coords": { + "latitude": 45.47840377309843, + "longitude": 9.233934440407387 + } + }, + { + "name": "Edificio 42", + "address": "Via Bassini 34/3, Milano, 20133", + "coords": { + "latitude": 45.47751909234621, + "longitude": 9.231437333034433 + } + }, + { + "name": "Edificio 43", + "address": "Via Bassini 34/3, Milano, 20133", + "coords": { + "latitude": 45.477644758070845, + "longitude": 9.231425385160406 + } + }, + { + "name": "Isola Ecologica", + "address": "Via Bassini 2, Milano, 20133", + "coords": { + "latitude": 45.478764590939626, + "longitude": 9.234032129716745 + } + } + ] + }, + { + "name": [ + "Bonardi" + ], + "buildings": [ + { + "name": "Edificio 11", + "address": "Via Ampère 2, Milano, 20133", + "coords": { + "latitude": 45.479700368402455, + "longitude": 9.227144319107985 + } + }, + { + "name": "Edificio 11B", + "address": "Via Ampère 4, Milano, 20133", + "coords": { + "latitude": 45.48039066193507, + "longitude": 9.226718974511959 + } + }, + { + "name": "Edificio 12", + "address": "Via Bonardi 3, Milano, 20133", + "coords": { + "latitude": 45.479559627904706, + "longitude": 9.227662857193996 + } + }, + { + "name": "Edificio 13", + "address": "Via Bonardi 9, Milano, 20133", + "coords": { + "latitude": 45.47986624067945, + "longitude": 9.228233965961486 + } + }, + { + "name": "Edificio 14", + "address": "Via Bonardi 9, Milano, 20133", + "coords": { + "latitude": 45.47964507754049, + "longitude": 9.22878834771603 + } + }, + { + "name": "Edificio 14A", + "address": "Via Bonardi 9, Milano, 20133", + "coords": { + "latitude": 45.48014771978483, + "longitude": 9.229170679933038 + } + }, + { + "name": "Edificio 14B", + "address": "Via Bonardi 9, Milano, 20133", + "coords": { + "latitude": 45.48014771978483, + "longitude": 9.228752504070686 + } + }, + { + "name": "Edificio 15", + "address": "Via Ponzio 31, Milano, 20133", + "coords": { + "latitude": 45.47966685878651, + "longitude": 9.229574518342371 + } + }, + { + "name": "Edificio 16A", + "address": "Via Bonardi 9, Milano, 20133", + "coords": { + "latitude": 45.479556276937224, + "longitude": 9.228453806990538 + } + }, + { + "name": "Edificio 16B", + "address": "Via Bonardi 9, Milano, 20133", + "coords": { + "latitude": 45.48007902560742, + "longitude": 9.227603117798322 + } + }, + { + "name": "Edificio 16C", + "address": "Via Bonardi 9, Milano, 20133", + "coords": { + "latitude": 45.479629998198945, + "longitude": 9.229118109245283 + } + }, + { + "name": "Edificio 18", + "address": "Via Ponzio 33, Milano, 20133", + "coords": { + "latitude": 45.48018625550555, + "longitude": 9.229739399120684 + } + } + ] + }, + { + "name": [ + "Colombo" + ], + "buildings": [ + { + "name": "Edificio 32.1", + "address": "Via Colombo 40, Milano, 20133", + "coords": { + "latitude": 45.47213230193092, + "longitude": 9.22686863256574 + } + }, + { + "name": "Edificio 32.2", + "address": "Via Colombo 40, Milano, 20133", + "coords": { + "latitude": 45.47207569302287, + "longitude": 9.227194415489148 + } + }, + { + "name": "Edificio 32.3", + "address": "Via Colombo 40, Milano, 20133", + "coords": { + "latitude": 45.47184925682209, + "longitude": 9.227171351211384 + } + }, + { + "name": "Edificio 32.4", + "address": "Via Colombo 40, Milano, 20133", + "coords": { + "latitude": 45.47190990946507, + "longitude": 9.226883047739344 + } + }, + { + "name": "Edificio 32.5", + "address": "Via Colombo 40, Milano, 20133", + "coords": { + "latitude": 45.47175625597605, + "longitude": 9.226926293260147 + } + }, + { + "name": "Edificio 30", + "address": "Via Colombo 81, Milano, 20133", + "coords": { + "latitude": 45.47586392362531, + "longitude": 9.226261178708338 + } + } + ] + }, + { + "name": [ + "Golgi" + ], + "buildings": [ + { + "name": "Edificio 26", + "address": "Via Golgi 20, Milano, 20133", + "coords": { + "latitude": 45.47569395835836, + "longitude": 9.235024035751083 + } + }, + { + "name": "Edificio 27", + "address": "Via Valvassori Peroni, Milano, 20133", + "coords": { + "latitude": 45.475868563542505, + "longitude": 9.236353204609438 + } + }, + { + "name": "Edificio 22", + "address": "Via Golgi 42, Milano, 20133", + "coords": { + "latitude": 45.47796163250129, + "longitude": 9.234955773844867 + } + }, + { + "name": "Edificio 23", + "address": "Via Golgi 40, Milano, 20133", + "coords": { + "latitude": 45.47770332464026, + "longitude": 9.234945870954828 + } + }, + { + "name": "Edificio 24", + "address": "Via Golgi 40, Milano, 20133", + "coords": { + "latitude": 45.47747417957433, + "longitude": 9.23470424043846 + } + }, + { + "name": "Edificio 25", + "address": "Via U.B. Secondo 3, Milano, 20133", + "coords": { + "latitude": 45.47750473230304, + "longitude": 9.23513402586612 + } + } + ] + }, + { + "name": [ + "Mancinelli" + ], + "buildings": [ + { + "name": "Edificio 28", + "address": "Via Mancinelli 7, Milano, 20133", + "coords": { + "latitude": 45.49016309824922, + "longitude": 9.226888094653553 + } + } + ] + }, + { + "name": [ + "Pascoli" + ], + "buildings": [ + { + "name": "Edificio 38", + "address": "Via Pascoli 70/3, Milano, 20133", + "coords": { + "latitude": 45.47547780481562, + "longitude": 9.22570000206852 + } + }, + { + "name": "Edificio 39", + "address": "Via Pascoli 70/3, Milano, 20133", + "coords": { + "latitude": 45.475677913901855, + "longitude": 9.225758755850668 + } + }, + { + "name": "Edificio 40", + "address": "Via Pascoli 70/3, Milano, 20133", + "coords": { + "latitude": 45.47591627820953, + "longitude": 9.225771345946843 + } + } + ] + }, + { + "name": [ + "Romagna" + ], + "buildings": [ + { + "name": "Casa dello Studente", + "address": "Viale Romagna 62, Milano, 20133", + "coords": { + "latitude": 45.47678010082273, + "longitude": 9.224452739758812 + } + } + ] + } + ] + }, + { + "acronym": "MIB", + "campus": [ + { + "name": [ + "Bovisa", + "Durando" + ], + "buildings": [ + { + "name": "Edificio B1", + "address": "Via Candiani 72, Milano, 20158", + "coords": { + "latitude": 45.50526063108648, + "longitude": 9.166960640981896 + } + }, + { + "name": "Edificio B2", + "address": "Via Candiani 72, Milano, 20158", + "coords": { + "latitude": 45.505856940521184, + "longitude": 9.16684246746718 + } + }, + { + "name": "Edificio B3", + "address": "Via Candiani 72, Milano, 20158", + "coords": { + "latitude": 45.506291745504754, + "longitude": 9.16657066831335 + } + }, + { + "name": "Edificio B4", + "address": "Via Candiani 72, Milano, 20158", + "coords": { + "latitude": 45.50582827267731, + "longitude": 9.1657801030213 + } + }, + { + "name": "Edificio B5", + "address": "Via Candiani 72, Milano, 20158", + "coords": { + "latitude": 45.504051263792235, + "longitude": 9.165419660659406 + } + }, + { + "name": "Edificio B5A", + "address": "Via Candiani 72, Milano, 20158", + "coords": { + "latitude": 45.50424070168094, + "longitude": 9.165416008016528 + } + }, + { + "name": "Edificio B6", + "address": "Via Candiani 72, Milano, 20158", + "coords": { + "latitude": 45.50481669134817, + "longitude": 9.16627437531528 + } + }, + { + "name": "Edificio B7", + "address": "Via Candiani 72, Milano, 20158", + "coords": { + "latitude": 45.504682097750845, + "longitude": 9.164140249884532 + } + }, + { + "name": "Edificio B8", + "address": "Via Candiani 72, Milano, 20158", + "coords": { + "latitude": 45.50468698803176, + "longitude": 9.164754281608419 + } + }, + { + "name": "Edificio B9", + "address": "Via Candiani 72, Milano, 20158", + "coords": { + "latitude": 45.50521269076449, + "longitude": 9.164468198661584 + } + }, + { + "name": "Edificio B9A", + "address": "Via Candiani 72, Milano, 20158", + "coords": { + "latitude": 45.50541074493551, + "longitude": 9.164988032336918 + } + }, + { + "name": "Infopoint", + "address": "Via Verità 25, Milano, 20158", + "coords": { + "latitude": 45.50448148112203, + "longitude": 9.165766681881529 + } + } + ] + }, + { + "name": [ + "Bovisa", + "La Masa" + ], + "buildings": [ + { + "name": "Edificio B11", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.500846286602666, + "longitude": 9.155348601436222 + } + }, + { + "name": "Edificio B12", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.50148227512907, + "longitude": 9.154387194659964 + } + }, + { + "name": "Edificio B13", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.50157313004546, + "longitude": 9.155059639273848 + } + }, + { + "name": "Edificio B14", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.501563666, + "longitude": 9.156285702980878 + } + }, + { + "name": "Edificio B14A", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.50161287903062, + "longitude": 9.156733999417478 + } + }, + { + "name": "Edificio B15", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.50188922830498, + "longitude": 9.156825819163954 + } + }, + { + "name": "Edificio B16", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.501845693924324, + "longitude": 9.15774941782049 + } + }, + { + "name": "Edificio B16A", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.50196304740825, + "longitude": 9.158189612507442 + } + }, + { + "name": "Edificio B18A", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.50203686641096, + "longitude": 9.156566563416906 + } + }, + { + "name": "Edificio B18B", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.50223182381833, + "longitude": 9.15721470280378 + } + }, + { + "name": "Edificio B18C", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.50228860740229, + "longitude": 9.157603586435906 + } + }, + { + "name": "Edificio B19", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.502271572336156, + "longitude": 9.155699676957584 + } + }, + { + "name": "Edificio B20", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.50239838883989, + "longitude": 9.15493811315239 + } + }, + { + "name": "Edificio B21", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.50104305808609, + "longitude": 9.15633786717546 + } + }, + { + "name": "Edificio B22", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.50135848414706, + "longitude": 9.157643792042283 + } + }, + { + "name": "Edificio B23", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.50095617559604, + "longitude": 9.15800589026771 + } + }, + { + "name": "Edificio B24", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.50170591921368, + "longitude": 9.153366080649027 + } + }, + { + "name": "Edificio B29", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.50128945237324, + "longitude": 9.15353385381083 + } + }, + { + "name": "Edificio B30", + "address": "Via La Masa 34, Milano, 20156", + "coords": { + "latitude": 45.501549132062195, + "longitude": 9.155347901172796 + } + }, + { + "name": "Edificio B37", + "address": "Via Lambruschini 4, Milano, 20156", + "coords": { + "latitude": 45.5029063064303, + "longitude": 9.156305606322812 + } + }, + { + "name": "Edificio BL25", + "address": "Via Lambruschini 4, Milano, 20156", + "coords": { + "latitude": 45.50309248664372, + "longitude": 9.155917630899358 + } + }, + { + "name": "Edificio BL25A", + "address": "Via Lambruschini 4, Milano, 20156", + "coords": { + "latitude": 45.50284016331667, + "longitude": 9.15555412238212 + } + }, + { + "name": "Edificio BL26", + "address": "Via Lambruschini 4, Milano, 20156", + "coords": { + "latitude": 45.50339625303833, + "longitude": 9.156018993853149 + } + }, + { + "name": "Edificio BL27", + "address": "Via Lambruschini 4, Milano, 20156", + "coords": { + "latitude": 45.50366327214294, + "longitude": 9.157438075212218 + } + }, + { + "name": "Edificio BL28", + "address": "Via Lambruschini 4, Milano, 20156", + "coords": { + "latitude": 45.503143931072984, + "longitude": 9.157036118688078 + } + } ] - }, - { - "acronym": "MIB", - "campus": [ - { - "name": ["Bovisa", "Durando"], - "buildings": [ - { - "name": "Edificio B1", - "address": "Via Candiani 72, Milano, 20158", - "coords": { - "latitude": 45.50526063108648, - "longitude": 9.166960640981896 - } - }, - { - "name": "Edificio B2", - "address": "Via Candiani 72, Milano, 20158", - "coords": { - "latitude": 45.505856940521184, - "longitude": 9.16684246746718 - } - }, - { - "name": "Edificio B3", - "address": "Via Candiani 72, Milano, 20158", - "coords": { - "latitude": 45.506291745504754, - "longitude": 9.16657066831335 - } - }, - { - "name": "Edificio B4", - "address": "Via Candiani 72, Milano, 20158", - "coords": { - "latitude": 45.50582827267731, - "longitude": 9.1657801030213 - } - }, - { - "name": "Edificio B5", - "address": "Via Candiani 72, Milano, 20158", - "coords": { - "latitude": 45.504051263792235, - "longitude": 9.165419660659406 - } - }, - { - "name": "Edificio B5A", - "address": "Via Candiani 72, Milano, 20158", - "coords": { - "latitude": 45.50424070168094, - "longitude": 9.165416008016528 - } - }, - { - "name": "Edificio B6", - "address": "Via Candiani 72, Milano, 20158", - "coords": { - "latitude": 45.50481669134817, - "longitude": 9.16627437531528 - } - }, - { - "name": "Edificio B7", - "address": "Via Candiani 72, Milano, 20158", - "coords": { - "latitude": 45.504682097750845, - "longitude": 9.164140249884532 - } - }, - { - "name": "Edificio B8", - "address": "Via Candiani 72, Milano, 20158", - "coords": { - "latitude": 45.50468698803176, - "longitude": 9.164754281608419 - } - }, - { - "name": "Edificio B9", - "address": "Via Candiani 72, Milano, 20158", - "coords": { - "latitude": 45.50521269076449, - "longitude": 9.164468198661584 - } - }, - { - "name": "Edificio B9A", - "address": "Via Candiani 72, Milano, 20158", - "coords": { - "latitude": 45.50541074493551, - "longitude": 9.164988032336918 - } - }, - { - "name": "Infopoint", - "address": "Via Verità 25, Milano, 20158", - "coords": { - "latitude": 45.50448148112203, - "longitude": 9.165766681881529 - } - } - ] - }, - { - "name": ["Bovisa", "La Masa"], - "buildings": [ - { - "name": "Edificio B11", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.500846286602666, - "longitude": 9.155348601436222 - } - }, - { - "name": "Edificio B12", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.50148227512907, - "longitude": 9.154387194659964 - } - }, - { - "name": "Edificio B13", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.50157313004546, - "longitude": 9.155059639273848 - } - }, - { - "name": "Edificio B14", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.501563666, - "longitude": 9.156285702980878 - } - }, - { - "name": "Edificio B14A", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.50161287903062, - "longitude": 9.156733999417478 - } - }, - { - "name": "Edificio B15", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.50188922830498, - "longitude": 9.156825819163954 - } - }, - { - "name": "Edificio B16", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.501845693924324, - "longitude": 9.15774941782049 - } - }, - { - "name": "Edificio B16A", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.50196304740825, - "longitude": 9.158189612507442 - } - }, - { - "name": "Edificio B18A", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.50203686641096, - "longitude": 9.156566563416906 - } - }, - { - "name": "Edificio B18B", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.50223182381833, - "longitude": 9.15721470280378 - } - }, - { - "name": "Edificio B18C", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.50228860740229, - "longitude": 9.157603586435906 - } - }, - { - "name": "Edificio B19", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.502271572336156, - "longitude": 9.155699676957584 - } - }, - { - "name": "Edificio B20", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.50239838883989, - "longitude": 9.15493811315239 - } - }, - { - "name": "Edificio B21", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.50104305808609, - "longitude": 9.15633786717546 - } - }, - { - "name": "Edificio B22", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.50135848414706, - "longitude": 9.157643792042283 - } - }, - { - "name": "Edificio B23", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.50095617559604, - "longitude": 9.15800589026771 - } - }, - { - "name": "Edificio B24", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.50170591921368, - "longitude": 9.153366080649027 - } - }, - { - "name": "Edificio B29", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.50128945237324, - "longitude": 9.15353385381083 - } - }, - { - "name": "Edificio B30", - "address": "Via La Masa 34, Milano, 20156", - "coords": { - "latitude": 45.501549132062195, - "longitude": 9.155347901172796 - } - }, - { - "name": "Edificio B37", - "address": "Via Lambruschini 4, Milano, 20156", - "coords": { - "latitude": 45.5029063064303, - "longitude": 9.156305606322812 - } - }, - { - "name": "Edificio BL25", - "address": "Via Lambruschini 4, Milano, 20156", - "coords": { - "latitude": 45.50309248664372, - "longitude": 9.155917630899358 - } - }, - { - "name": "Edificio BL25A", - "address": "Via Lambruschini 4, Milano, 20156", - "coords": { - "latitude": 45.50284016331667, - "longitude": 9.15555412238212 - } - }, - { - "name": "Edificio BL26", - "address": "Via Lambruschini 4, Milano, 20156", - "coords": { - "latitude": 45.50339625303833, - "longitude": 9.156018993853149 - } - }, - { - "name": "Edificio BL27", - "address": "Via Lambruschini 4, Milano, 20156", - "coords": { - "latitude": 45.50366327214294, - "longitude": 9.157438075212218 - } - }, - { - "name": "Edificio BL28", - "address": "Via Lambruschini 4, Milano, 20156", - "coords": { - "latitude": 45.503143931072984, - "longitude": 9.157036118688078 - } - } - ] + } + ] + }, + { + "acronym": "CRG", + "campus": [ + { + "name": [ + "Sesto" + ], + "buildings": [ + { + "name": "Edificio C", + "address": "Via Sesto 39, Cremona, 26100", + "coords": { + "latitude": 45.147121757649806, + "longitude": 10.00162101166769 + } + }, + { + "name": "Palazzina A", + "address": "Via Sesto 39, Cremona, 26100", + "coords": { + "latitude": 45.14624583991279, + "longitude": 10.002210009658127 + } + }, + { + "name": "Palazzina B", + "address": "Via Sesto 39, Cremona, 26100", + "coords": { + "latitude": 45.146619394711394, + "longitude": 10.001899530097274 + } + } + ] + } + ] + }, + { + "acronym": "LCF", + "campus": [ + { + "name": [ + "Ghislanzoni" + ], + "buildings": [ + { + "name": "Residenza Loos", + "address": "Via Ghislanzoni 24, Lecco, 23900", + "coords": { + "latitude": 45.84944207561925, + "longitude": 9.397439941157165 + } + }, + { + "name": "BEEpilot", + "address": "Via Previati 1C, Lecco, 23900", + "coords": { + "latitude": 45.84889332151791, + "longitude": 9.39735373582034 + } + }, + { + "name": "Edificio 10", + "address": "Via Previati 1C, Lecco, 23900", + "coords": { + "latitude": 45.84945959386757, + "longitude": 9.396282096446393 + } + }, + { + "name": "Edificio 11", + "address": "Via Previati 1C, Lecco, 23900", + "coords": { + "latitude": 45.84976868042763, + "longitude": 9.397024120135281 + } + }, + { + "name": "Edificio 12", + "address": "Via Previati 1C, Lecco, 23900", + "coords": { + "latitude": 45.850239482856416, + "longitude": 9.396348203485335 + } + }, + { + "name": "Edificio 5", + "address": "Via Previati 1C, Lecco, 23900", + "coords": { + "latitude": 45.84992561501641, + "longitude": 9.396852458762153 + } + }, + { + "name": "Edificio 8", + "address": "Via Previati 1C, Lecco, 23900", + "coords": { + "latitude": 45.84920819614676, + "longitude": 9.39701875573217 + } + }, + { + "name": "Edificio 9", + "address": "Via Previati 1C, Lecco, 23900", + "coords": { + "latitude": 45.84890553228907, + "longitude": 9.396487678342055 + } + }, + { + "name": "Edificio CNR", + "address": "Via Previati 1C, Lecco, 23900", + "coords": { + "latitude": 45.84854681743879, + "longitude": 9.397254790092957 + } + } + ] + } + ] + }, + { + "acronym": "PCL", + "campus": [ + { + "name": [ + "Scalabrini" + ], + "buildings": [ + { + "name": "Padiglione 11", + "address": "Via Scalabrini 113, Piacenza, 29100", + "coords": { + "latitude": 45.04671253164241, + "longitude": 9.703538101434237 + } + }, + { + "name": "Padiglione 12", + "address": "Via Scalabrini 113, Piacenza, 29100", + "coords": { + "latitude": 45.04746700688415, + "longitude": 9.703336354556205 + } + }, + { + "name": "Padiglione 13", + "address": "Via Scalabrini 113, Piacenza, 29100", + "coords": { + "latitude": 45.04736378936126, + "longitude": 9.703562450197184 + } + }, + { + "name": "Padiglione 14", + "address": "Via Scalabrini 113, Piacenza, 29100", + "coords": { + "latitude": 45.04705133747066, + "longitude": 9.702656152043621 + } + }, + { + "name": "Padiglione 15", + "address": "Via Scalabrini 113, Piacenza, 29100", + "coords": { + "latitude": 45.04645536532436, + "longitude": 9.703416037344196 + } + }, + { + "name": "Padiglione 2", + "address": "Via Scalabrini 113, Piacenza, 29100", + "coords": { + "latitude": 45.04688035667178, + "longitude": 9.703307226084346 + } + }, + { + "name": "Padiglione 3", + "address": "Via Scalabrini 113, Piacenza, 29100", + "coords": { + "latitude": 45.04654833371806, + "longitude": 9.70320343683441 + } + }, + { + "name": "Padiglione 4", + "address": "Via Scalabrini 113, Piacenza, 29100", + "coords": { + "latitude": 45.04667055098037, + "longitude": 9.702900718188767 + } + }, + { + "name": "Padiglione 5", + "address": "Via Scalabrini 113, Piacenza, 29100", + "coords": { + "latitude": 45.046444448839786, + "longitude": 9.702814227147154 + } + }, + { + "name": "Padiglione 6", + "address": "Via Scalabrini 113, Piacenza, 29100", + "coords": { + "latitude": 45.04676832460221, + "longitude": 9.702612414716725 + } + }, + { + "name": "Padiglione 8", + "address": "Via Scalabrini 113, Piacenza, 29100", + "coords": { + "latitude": 45.0465911097912, + "longitude": 9.702324111225455 + } + }, + { + "name": "Padiglione 9", + "address": "Via Scalabrini 113, Piacenza, 29100", + "coords": { + "latitude": 45.046383339999025, + "longitude": 9.702499976344225 + } + }, + { + "name": "Edificio 1", + "address": "Via Scalabrini 76, Piacenza, 29100", + "coords": { + "latitude": 45.04830239234551, + "longitude": 9.701883338558217 + } + } + ] + } + ] + }, + { + "acronym": "MNI", + "campus": [ + { + "name": [ + "Scarsellini" + ], + "buildings": [ + { + "name": "Edificio 1", + "address": "Via Scarsellini 15, Mantova, 46100", + "coords": { + "latitude": 45.160352957787765, + "longitude": 10.788892210362015 + } + }, + { + "name": "Edificio B", + "address": "Via Scarsellini 2, Mantova, 46100", + "coords": { + "latitude": 45.16071402717656, + "longitude": 10.78813888256507 + } + } + ] + } + ] + }, + { + "acronym": "MIC", + "campus": [ + { + "name": [ + "Off", + "Campus" + ], + "buildings": [ + { + "name": "NOLO", + "address": "Viale Monza 54, Milano, 20128", + "coords": { + "latitude": 45.49326461001558, + "longitude": 9.21927698715338 + } + }, + { + "name": "San Siro", + "address": "Viale Gigante, Milano, 20148", + "coords": { + "latitude": 45.471604941331265, + "longitude": 9.138379698192313 } + } ] - }, - { - "acronym": "CRG", - "campus": [ - { - "name": ["Sesto"], - "buildings": [ - { - "name": "Edificio C", - "address": "Via Sesto 39, Cremona, 26100", - "coords": { - "latitude": 45.147121757649806, - "longitude": 10.00162101166769 - } - }, - { - "name": "Palazzina A", - "address": "Via Sesto 39, Cremona, 26100", - "coords": { - "latitude": 45.14624583991279, - "longitude": 10.002210009658127 - } - }, - { - "name": "Palazzina B", - "address": "Via Sesto 39, Cremona, 26100", - "coords": { - "latitude": 45.146619394711394, - "longitude": 10.001899530097274 - } - } - ] + }, + { + "name": [ + "Residenza", + "Einstein" + ], + "buildings": [ + { + "name": "Einstein", + "address": "Via Einstein 6, Milano, 20137", + "coords": { + "latitude": 45.45033404949838, + "longitude": 9.216969652664448 } + } ] - }, - { - "acronym": "LCF", - "campus": [ - { - "name": ["Ghislanzoni"], - "buildings": [ - { - "name": "Residenza Loos", - "address": "Via Ghislanzoni 24, Lecco, 23900", - "coords": { - "latitude": 45.84944207561925, - "longitude": 9.397439941157165 - } - }, - { - "name": "BEEpilot", - "address": "Via Previati 1C, Lecco, 23900", - "coords": { - "latitude": 45.84889332151791, - "longitude": 9.39735373582034 - } - }, - { - "name": "Edificio 10", - "address": "Via Previati 1C, Lecco, 23900", - "coords": { - "latitude": 45.84945959386757, - "longitude": 9.396282096446393 - } - }, - { - "name": "Edificio 11", - "address": "Via Previati 1C, Lecco, 23900", - "coords": { - "latitude": 45.84976868042763, - "longitude": 9.397024120135281 - } - }, - { - "name": "Edificio 12", - "address": "Via Previati 1C, Lecco, 23900", - "coords": { - "latitude": 45.850239482856416, - "longitude": 9.396348203485335 - } - }, - { - "name": "Edificio 5", - "address": "Via Previati 1C, Lecco, 23900", - "coords": { - "latitude": 45.84992561501641, - "longitude": 9.396852458762153 - } - }, - { - "name": "Edificio 8", - "address": "Via Previati 1C, Lecco, 23900", - "coords": { - "latitude": 45.84920819614676, - "longitude": 9.39701875573217 - } - }, - { - "name": "Edificio 9", - "address": "Via Previati 1C, Lecco, 23900", - "coords": { - "latitude": 45.84890553228907, - "longitude": 9.396487678342055 - } - }, - { - "name": "Edificio CNR", - "address": "Via Previati 1C, Lecco, 23900", - "coords": { - "latitude": 45.84854681743879, - "longitude": 9.397254790092957 - } - } - ] + }, + { + "name": [ + "Residenza", + "Newton" + ], + "buildings": [ + { + "name": "Newton", + "address": "Via Mario Borsa 25, Milano, 20151", + "coords": { + "latitude": 45.50201311059991, + "longitude": 9.100693099933826 } + } ] - }, - { - "acronym": "PCL", - "campus": [ - { - "name": ["Scalabrini"], - "buildings": [ - { - "name": "Padiglione 11", - "address": "Via Scalabrini 113, Piacenza, 29100", - "coords": { - "latitude": 45.04671253164241, - "longitude": 9.703538101434237 - } - }, - { - "name": "Padiglione 12", - "address": "Via Scalabrini 113, Piacenza, 29100", - "coords": { - "latitude": 45.04746700688415, - "longitude": 9.703336354556205 - } - }, - { - "name": "Padiglione 13", - "address": "Via Scalabrini 113, Piacenza, 29100", - "coords": { - "latitude": 45.04736378936126, - "longitude": 9.703562450197184 - } - }, - { - "name": "Padiglione 14", - "address": "Via Scalabrini 113, Piacenza, 29100", - "coords": { - "latitude": 45.04705133747066, - "longitude": 9.702656152043621 - } - }, - { - "name": "Padiglione 15", - "address": "Via Scalabrini 113, Piacenza, 29100", - "coords": { - "latitude": 45.04645536532436, - "longitude": 9.703416037344196 - } - }, - { - "name": "Padiglione 2", - "address": "Via Scalabrini 113, Piacenza, 29100", - "coords": { - "latitude": 45.04688035667178, - "longitude": 9.703307226084346 - } - }, - { - "name": "Padiglione 3", - "address": "Via Scalabrini 113, Piacenza, 29100", - "coords": { - "latitude": 45.04654833371806, - "longitude": 9.70320343683441 - } - }, - { - "name": "Padiglione 4", - "address": "Via Scalabrini 113, Piacenza, 29100", - "coords": { - "latitude": 45.04667055098037, - "longitude": 9.702900718188767 - } - }, - { - "name": "Padiglione 5", - "address": "Via Scalabrini 113, Piacenza, 29100", - "coords": { - "latitude": 45.046444448839786, - "longitude": 9.702814227147154 - } - }, - { - "name": "Padiglione 6", - "address": "Via Scalabrini 113, Piacenza, 29100", - "coords": { - "latitude": 45.04676832460221, - "longitude": 9.702612414716725 - } - }, - { - "name": "Padiglione 8", - "address": "Via Scalabrini 113, Piacenza, 29100", - "coords": { - "latitude": 45.0465911097912, - "longitude": 9.702324111225455 - } - }, - { - "name": "Padiglione 9", - "address": "Via Scalabrini 113, Piacenza, 29100", - "coords": { - "latitude": 45.046383339999025, - "longitude": 9.702499976344225 - } - }, - { - "name": "Edificio 1", - "address": "Via Scalabrini 76, Piacenza, 29100", - "coords": { - "latitude": 45.04830239234551, - "longitude": 9.701883338558217 - } - } - ] + }, + { + "name": [ + "Residenza", + "Pareto" + ], + "buildings": [ + { + "name": "Pareto", + "address": "Via Maggianico 6, Milano, 20156", + "coords": { + "latitude": 45.50331624885291, + "longitude": 9.145443677552473 } + } ] - }, - { - "acronym": "MNI", - "campus": [ - { - "name": ["Scarsellini"], - "buildings": [ - { - "name": "Edificio 1", - "address": "Via Scarsellini 15, Mantova, 46100", - "coords": { - "latitude": 45.160352957787765, - "longitude": 10.788892210362015 - } - }, - { - "name": "Edificio B", - "address": "Via Scarsellini 2, Mantova, 46100", - "coords": { - "latitude": 45.16071402717656, - "longitude": 10.78813888256507 - } - } - ] + } + ] + }, + { + "acronym": "MID", + "campus": [ + { + "name": [ + "Calabria" + ], + "buildings": [ + { + "name": "Edificio 1", + "address": "Via Calabria 4, Milano, 20098", + "coords": { + "latitude": 45.39350641657452, + "longitude": 9.257432613353823 } + } ] - }, - { - "acronym": "MIC", - "campus": [ - { - "name": ["Off", "Campus"], - "buildings": [ - { - "name": "NOLO", - "address": "Viale Monza 54, Milano, 20128", - "coords": { - "latitude": 45.49326461001558, - "longitude": 9.21927698715338 - } - }, - { - "name": "San Siro", - "address": "Viale Gigante, Milano, 20148", - "coords": { - "latitude": 45.471604941331265, - "longitude": 9.138379698192313 - } - } - ] - }, - { - "name": ["Residenza", "Einstein"], - "buildings": [ - { - "name": "Einstein", - "address": "Via Einstein 6, Milano, 20137", - "coords": { - "latitude": 45.45033404949838, - "longitude": 9.216969652664448 - } - } - ] - }, - { - "name": ["Residenza", "Newton"], - "buildings": [ - { - "name": "Newton", - "address": "Via Mario Borsa 25, Milano, 20151", - "coords": { - "latitude": 45.50201311059991, - "longitude": 9.100693099933826 - } - } - ] - }, - { - "name": ["Residenza", "Pareto"], - "buildings": [ - { - "name": "Pareto", - "address": "Via Maggianico 6, Milano, 20156", - "coords": { - "latitude": 45.50331624885291, - "longitude": 9.145443677552473 - } - } - ] + } + ] + }, + { + "acronym": "COE", + "campus": [ + { + "name": [ + "Anzani" + ], + "buildings": [ + { + "name": "Edificio 4", + "address": "Via Anzani 42, Como, 22100", + "coords": { + "latitude": 45.80120256319488, + "longitude": 9.092668671639375 } + } ] - }, - { - "acronym": "MID", - "campus": [ - { - "name": ["Calabria"], - "buildings": [ - { - "name": "Edificio 1", - "address": "Via Calabria 4, Milano, 20098", - "coords": { - "latitude": 45.39350641657452, - "longitude": 9.257432613353823 - } - } - ] + }, + { + "name": [ + "Castelnuovo" + ], + "buildings": [ + { + "name": "Edificio 1", + "address": "Via Castelnuovo 7, Como, 22100", + "coords": { + "latitude": 45.80276883790487, + "longitude": 9.09505146871641 } + } ] - }, - { - "acronym": "COE", - "campus": [ - { - "name": ["Anzani"], - "buildings": [ - { - "name": "Edificio 4", - "address": "Via Anzani 42, Como, 22100", - "coords": { - "latitude": 45.80120256319488, - "longitude": 9.092668671639375 - } - } - ] - }, - { - "name": ["Castelnuovo"], - "buildings": [ - { - "name": "Edificio 1", - "address": "Via Castelnuovo 7, Como, 22100", - "coords": { - "latitude": 45.80276883790487, - "longitude": 9.09505146871641 - } - } - ] - }, - { - "name": ["Zezio"], - "buildings": [ - { - "name": "Residenza La Presentazione", - "address": "Via Zezio 58, Como, 22100", - "coords": { - "latitude": 45.80645610020381, - "longitude": 9.09718826871654 - } - } - ] + }, + { + "name": [ + "Zezio" + ], + "buildings": [ + { + "name": "Residenza La Presentazione", + "address": "Via Zezio 58, Como, 22100", + "coords": { + "latitude": 45.80645610020381, + "longitude": 9.09718826871654 } + } ] - } -] + } + ] + } +] \ No newline at end of file diff --git a/src/components/Home/MainMenu.tsx b/src/components/Home/MainMenu.tsx index e9520a36..e2eeee65 100644 --- a/src/components/Home/MainMenu.tsx +++ b/src/components/Home/MainMenu.tsx @@ -16,7 +16,6 @@ import grading_book from "assets/menu/grading_book.svg" import tests from "assets/menu/tests.svg" import add from "assets/menu/add.svg" import { ModalCustom } from "components/Modal" - import AsyncStorage from "@react-native-async-storage/async-storage" import { useOutsideClick } from "utils/outsideClick" @@ -199,7 +198,7 @@ export const MainMenu: FC<{ filter?: string }> = ({ filter }) => { onPress={() => { if (isDeleting) setIsDeleting(false) else { - buttonIcon.onClick() + buttonIcon.onClick?.() } }} onLongPress={() => { diff --git a/src/navigation/MainStackNavigator.tsx b/src/navigation/MainStackNavigator.tsx index 8858db9b..90a0fa67 100644 --- a/src/navigation/MainStackNavigator.tsx +++ b/src/navigation/MainStackNavigator.tsx @@ -15,6 +15,7 @@ import { CampusChoice } from "pages/FreeClass/CampusChoice" import { PositionChoice } from "pages/FreeClass/PositionChoice" import { BuildingChoice } from "pages/FreeClass/BuildingChoice" import { ClassChoice } from "pages/FreeClass/ClassChoice" +import { RoomDetails } from "pages/FreeClass/RoomDetails" import { OtherCategories } from "pages/news/OtherCategories" import { Groups } from "pages/Groups" @@ -46,6 +47,7 @@ export const MainStack: FC = () => { component={BuildingChoice} /> + diff --git a/src/navigation/NavigationTypes.ts b/src/navigation/NavigationTypes.ts index 00a94b8b..2da8db13 100644 --- a/src/navigation/NavigationTypes.ts +++ b/src/navigation/NavigationTypes.ts @@ -25,6 +25,7 @@ import { Article } from "api/articles" import { CampusItem } from "pages/FreeClass/CampusChoice" import { NavigatorScreenParams } from "@react-navigation/native" import { BuildingItem } from "pages/FreeClass/BuildingChoice" +import { Occupancies, RoomDetails } from "api/rooms" import { TagWithData } from "contexts/newsPreferences" /** @@ -52,6 +53,15 @@ export type MainStackNavigatorParams = { CampusChoice: { currentDate: string } PositionChoice: undefined BuildingChoice: { campus: CampusItem; currentDate: string } + RoomDetails: { + room: RoomDetails + startDate: string + roomId: number + roomLatitude?: number + roomLongitude?: number + occupancies?: Occupancies + occupancyRate?: number | null + } ClassChoice: { building: BuildingItem; currentDate: string } Groups: undefined } diff --git a/src/pages/FreeClass/BuildingChoice.tsx b/src/pages/FreeClass/BuildingChoice.tsx index 4223ea06..e318b529 100644 --- a/src/pages/FreeClass/BuildingChoice.tsx +++ b/src/pages/FreeClass/BuildingChoice.tsx @@ -70,7 +70,8 @@ export const BuildingChoice: MainStackScreen<"BuildingChoice"> = props => { { roomId: room.room_id, name: room.name, - occupancyRate: room.occupancyRate, + occupancies: room.occupancies, + occupancyRate: room.occupancy_rate ?? undefined, }, ], } @@ -84,7 +85,8 @@ export const BuildingChoice: MainStackScreen<"BuildingChoice"> = props => { tempBuildings[indexElement].freeRoomList.push({ roomId: room.room_id, name: room.name, - occupancyRate: room.occupancyRate, + occupancies: room.occupancies, + occupancyRate: room.occupancy_rate ?? undefined, }) } }) @@ -103,8 +105,15 @@ export const BuildingChoice: MainStackScreen<"BuildingChoice"> = props => { setDate(new Date(currentDate)) }, [props.route.params.currentDate]) + //custom goBack function, in order to maintain the currentDate. + const goBack = () => { + props.navigation.navigate("CampusChoice", { + currentDate: date.toString(), + }) + } + return ( - + goBack() }}> {campus.name.length > 1 ? ( = props => { setDate(new Date(currentDate)) }, [props.route.params.currentDate]) + //custom goBack function in order to maintain the currenyDate + const goBack = () => { + props.navigation.navigate("BuildingChoice", { + campus: building.campus, + currentDate: date.toString(), + }) + } + const buildingName: string[] = building.name.split(" ") // ex. buildingName = ["Ed.","B2"] + const coords = getBuildingCoords( + building.campus, + building.name.replace("Ed. ", "Edificio ") + ) + return ( - <PageWrapper> + <PageWrapper navbarOptions={{ overrideBackBehavior: () => goBack() }}> <View style={{ paddingTop: 28 }}> <Title style={{ @@ -40,7 +54,12 @@ export const ClassChoice: MainStackScreen<"ClassChoice"> = props => { <DateTimePicker date={date} setDate={(date: Date) => setDate(date)} /> </View> <View style={{ flex: 1, marginTop: 26, marginBottom: 93 }}> - <FreeClassList data={building.freeRoomList} /> + <FreeClassList + data={building.freeRoomList} + date={new Date()} + latitude={coords?.latitude} + longitude={coords?.longitude} + /> </View> </PageWrapper> ) diff --git a/src/pages/FreeClass/PositionChoice.tsx b/src/pages/FreeClass/PositionChoice.tsx index 49ff91d3..11b5aa29 100644 --- a/src/pages/FreeClass/PositionChoice.tsx +++ b/src/pages/FreeClass/PositionChoice.tsx @@ -2,7 +2,6 @@ import React, { useState, useEffect } from "react" import { MainStackScreen } from "navigation/NavigationTypes" import { Platform, View } from "react-native" import { Title } from "components/Text" -import { PoliSearchBar } from "components/Home" import * as Location from "expo-location" import { LocationGeocodedAddress, PermissionStatus } from "expo-location" import { AddressText } from "components/FreeClass/AddressText" @@ -115,7 +114,8 @@ export const PositionChoice: MainStackScreen<"PositionChoice"> = () => { { roomId: room.room_id, name: room.name, - occupancyRate: room.occupancyRate, + occupancies: room.occupancies, + occupancyRate: room.occupancy_rate ?? undefined, }, ], } @@ -129,14 +129,16 @@ export const PositionChoice: MainStackScreen<"PositionChoice"> = () => { tempBuildings[indexElement].freeRoomList.push({ roomId: room.room_id, name: room.name, - occupancyRate: room.occupancyRate, + occupancies: room.occupancies, + occupancyRate: room.occupancy_rate ?? undefined, }) } if (tempRoomList.length < 50) { tempRoomList.push({ roomId: room.room_id, name: room.name, - occupancyRate: room.occupancyRate, + occupancies: room.occupancies, + occupancyRate: room.occupancy_rate ?? undefined, }) } else { setRoomList(tempRoomList) diff --git a/src/pages/FreeClass/RoomDetails.tsx b/src/pages/FreeClass/RoomDetails.tsx new file mode 100644 index 00000000..d680636a --- /dev/null +++ b/src/pages/FreeClass/RoomDetails.tsx @@ -0,0 +1,31 @@ +import { MainStackScreen } from "navigation/NavigationTypes" +import React from "react" +import { InfoMapTile } from "components/FreeClass/ClassDetails/InfoMapTile" +import { TimeLeftTile } from "components/FreeClass/ClassDetails/TimeLeftTile" +import { RoomUtilsSection } from "components/FreeClass/ClassDetails/RoomUtilsSection" +import { CrowdingSection } from "components/FreeClass/ClassDetails/CrowdingSection" +import { ContentWrapperScroll } from "components/ContentWrapperScroll" + +export const RoomDetails: MainStackScreen<"RoomDetails"> = props => { + const { room, startDate, roomId, roomLatitude, roomLongitude, occupancies } = + props.route.params + + return ( + <ContentWrapperScroll + scrollViewStyle={{ paddingHorizontal: 28, paddingBottom: 60 }} + style={{ marginTop: 106 }} + > + <InfoMapTile + address={room.address} + building={room.building} + capacity={room.capacity} + roomName={room.name} + latitude={roomLatitude} + longitude={roomLongitude} + /> + <TimeLeftTile startDate={startDate} occupancies={occupancies} /> + <CrowdingSection roomId={roomId} /> + <RoomUtilsSection power={room.power} /> + </ContentWrapperScroll> + ) +} diff --git a/src/utils/colors.ts b/src/utils/colors.ts index 279e0da1..14ce3745 100644 --- a/src/utils/colors.ts +++ b/src/utils/colors.ts @@ -9,6 +9,7 @@ const palette = { lessDark: "#2B344A", variant1: "#414867", variant2: "#010B40", + variant3: "#454773", accent: "#FFB544", } as const @@ -96,6 +97,21 @@ export interface ColorTheme { * Dark blue used for the title in cards with a background image and a yellowish gradient. */ cardTitle: string + + /** + * for RoomDetails page's slider + */ + sliderBorderColor: string + + /** + * dark blue in light mode, white in dark mode, used in slider labels + */ + labelsHighContrast: string + + /** + * purple/blueish in light mode, white in dark mode, used in TimeLeftTile + */ + iconHighContrast: string } /** @@ -181,6 +197,9 @@ export const usePalette: () => ColorTheme & articleTitle: palette.darker, articleSubtitle: palette.primary, cardTitle: palette.variant2, // "#010B40" + sliderBorderColor: "#454773", + labelsHighContrast: palette.variant1, // "#414867", + iconHighContrast: palette.variant3, // "#454773", } const darkTheme: ColorTheme = { @@ -197,6 +216,9 @@ export const usePalette: () => ColorTheme & articleTitle: "#FFFFFF", articleSubtitle: palette.lighter, cardTitle: palette.variant2, // "#010B40" + sliderBorderColor: "#FFFFFF", + labelsHighContrast: "#FFFFFF", + iconHighContrast: "#FFFFFF", } const colors = isLight ? lightTheme : darkTheme diff --git a/src/utils/rooms.ts b/src/utils/rooms.ts new file mode 100644 index 00000000..42ef3d82 --- /dev/null +++ b/src/utils/rooms.ts @@ -0,0 +1,135 @@ +import BuildingListJSON from "components/FreeClass/buildingCoords.json" +import { CampusItem } from "pages/FreeClass/CampusChoice" +import { Occupancies } from "api/rooms" + +export function extractRoom(val: string) { + const arr = val.split(".") + if (arr.length > 2) { + return arr.slice(1).join(".") + } else { + return val + } +} + +export function extractBuilding(val: string) { + const arr = val.split(" ") + if (arr.length === 2) { + return arr[1] + } + return undefined +} + +/* function containsNumber(val: string) { + // if has digits + const regExp = /\d/g + return regExp.test(val) +} */ + +export function extractTimeLeft(now: Date, targetDate?: Date) { + if (!targetDate) { + return { hoursLeft: undefined, minutesLeft: undefined } + } + const deltaMilliseconds = targetDate.getTime() - now.getTime() + if (deltaMilliseconds <= 0) { + return { hoursLeft: undefined, minutesLeft: undefined } + } + const hours = Math.floor(deltaMilliseconds / 3.6e6) + const minutes = Math.floor( + (deltaMilliseconds - hours * 60 * 60 * 1000) / 60000 + ) + const hoursLeft = hours.toString() + const minutesLeft = minutes.toString() + return { + hoursLeft: hoursLeft, + minutesLeft: minutesLeft, + } +} + +/** + * @param pos slider current pos + * @param width slider max width + * @returns a float number from 1 to 5 + */ +export function getCrowdStatus(pos: number, width: number): number { + if (pos < 0) { + return 1 + } + const percentage = pos / width + + return 1 + percentage * 4 +} + +/** + * Return the correct end date in which the room is free given a record of occcupancies + * + * return undefined in case of errors + * + */ +export function getEndDate(startDate: Date, occupancies?: Occupancies) { + let time + + if (occupancies !== undefined) { + try { + time = Object.keys(occupancies).find(time => { + const hour = parseInt(time.substring(0, 2)) + const minutes = parseInt(time.substring(3)) + return occupancies[`${hour}:${minutes}`] === "OCCUPIED" + }) + } catch (err) { + console.log(err) + return undefined + } + } + if (time === undefined) { + const endDate = new Date(startDate) + endDate.setHours(20, 0, 0, 0) + return endDate + } else { + try { + const hour = parseInt(time.substring(0, 2)) + const minutes = parseInt(time.substring(3)) + const endDate = new Date(startDate) + endDate.setHours(hour, minutes, 0, 0) + return endDate + } catch (err) { + console.log(err) + return undefined + } + } +} + +export function getBuildingCoords(campus: CampusItem, buildingName: string) { + for (const element of BuildingListJSON) { + if (element.acronym === campus.acronym) { + for (const c of element.campus) { + if (compareCampusNames(c.name, campus.name)) { + for (const b of c.buildings) { + if (b.name === buildingName) { + return b.coords + } + } + } + } + } + } +} + +const compareCampusNames = (c1: string[], c2: string[]) => { + if (c1.length === c2.length) { + if (c1.length > 1) { + if (c1[0] === c2[0] && c1[1] === c2[1]) { + return true + } else { + return false + } + } else { + if (c1[0] === c2[0]) { + return true + } else { + return false + } + } + } else { + return false + } +}