2022-12-03 20:02:18 +00:00
|
|
|
import Head from 'next/head'
|
|
|
|
import { ReactElement, useEffect, useState } from 'react'
|
|
|
|
import LayoutReadyOrNot from '../components/layout'
|
|
|
|
import styles from '/styles/ReadyOrNot.module.css'
|
|
|
|
import { NextPageWithLayout } from './_app';
|
|
|
|
import React from 'react';
|
|
|
|
import useSWR, { KeyedMutator, mutate } from 'swr';
|
|
|
|
import { useRouter } from 'next/router';
|
2022-12-04 15:42:49 +00:00
|
|
|
import Image from 'next/image';
|
2022-12-03 20:02:18 +00:00
|
|
|
import ReadyOrNotMap from '../interfaces/ReadyOrNot';
|
2022-12-04 15:42:49 +00:00
|
|
|
import useWindowSize from '../components/windowsize';
|
2022-12-03 20:02:18 +00:00
|
|
|
|
|
|
|
const fetcher = (url: string) => fetch(url).then((res) => res.json())
|
|
|
|
|
|
|
|
const ReadyOrNotMaps: NextPageWithLayout = () => {
|
|
|
|
const [floor, setFloor] = useState(0);
|
|
|
|
const { mapInfo, isLoadingInfo, isErrorInfo } = useMap(useRouter().query.map?.toString() || "a_lethal_obsession")
|
|
|
|
const { mapImages, isLoadingImages, isErrorImages, mutateImage } = useImages(useRouter().query.map?.toString() || "a_lethal_obsession")
|
|
|
|
const isMobile = useWindowSize();
|
|
|
|
|
|
|
|
let infoHtml: ReactElement = <></>;
|
|
|
|
let mapHtml: ReactElement = <></>;
|
|
|
|
if (isErrorInfo) {
|
|
|
|
infoHtml = (
|
|
|
|
<h1 className={styles.title}>
|
|
|
|
<a>Error loading page Data</a>
|
|
|
|
</h1>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
else if (isLoadingInfo) {
|
|
|
|
infoHtml = (
|
|
|
|
<h1 className={styles.title}>
|
|
|
|
<a>Loading...</a>
|
|
|
|
</h1>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
const info = mapInfo
|
|
|
|
infoHtml = (
|
|
|
|
<h1 className={styles.title}>
|
|
|
|
<a>{info.name} ({info.alias})</a>
|
|
|
|
</h1>
|
|
|
|
)
|
|
|
|
|
|
|
|
if (isErrorImages) {
|
|
|
|
mapHtml = <div className={styles.mapContainer}><p>Error loading Map or Map not present</p></div>
|
|
|
|
}
|
|
|
|
else if (isLoadingImages) {
|
|
|
|
mapHtml = <div className={styles.mapContainer}><p>Loading...</p></div>
|
|
|
|
}
|
|
|
|
else if(info.floors){
|
|
|
|
// TODO: ask Yahia if he would rather the buttons turn off at the corresponding limits
|
|
|
|
// move to highest floor after going down from lowest
|
|
|
|
if (floor < info.floors[0]) {
|
|
|
|
setFloor(info.floors[info.floors.length-1])
|
|
|
|
}
|
|
|
|
// move to lowest floor after going up from highest
|
|
|
|
if (floor > info.floors[info.floors.length-1]) {
|
|
|
|
setFloor(info.floors[0])
|
|
|
|
}
|
|
|
|
|
|
|
|
// map the images to the corresponding floor number in an array
|
|
|
|
let images: string[] = [];
|
|
|
|
mapImages.forEach((image, index) => {
|
|
|
|
// assign the floor number of the image position, since floors and images are synced from the info object this works
|
|
|
|
images[info.floors[index]] = image
|
|
|
|
});
|
|
|
|
|
|
|
|
let inverseFloors = info.floors.slice(0);
|
|
|
|
inverseFloors.reverse()
|
|
|
|
|
|
|
|
mapHtml = (
|
|
|
|
<div className={[styles.mapContainer, (isMobile ? styles.mc_mobile : styles.mc_desktop)].join(" ")}>
|
|
|
|
<div className={[
|
|
|
|
styles.floorIndicator,
|
|
|
|
(isMobile ? styles.findicator_mobile : styles.findicator_desktop)
|
|
|
|
].join(" ")}>
|
|
|
|
<p className={[
|
|
|
|
styles.floorNumber,
|
|
|
|
(isMobile ? styles.fn_mobile : styles.fn_desktop)
|
|
|
|
].join(" ")}>{floor}</p>
|
|
|
|
{inverseFloors.map((level: number, index: number) => (
|
|
|
|
<div key={level} className={[
|
|
|
|
styles.floorIcon,
|
|
|
|
(floor == level ? styles.fi_active : styles.fi_inactive),
|
|
|
|
(isMobile ? styles.fi_mobile : styles.fi_desktop)
|
|
|
|
].join(" ")} onClick={() => {setFloor(level)}}></div>
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
<div className={[styles.map, (isMobile ? styles.map_mobile : styles.map_desktop)].join(" ")}>
|
|
|
|
<Image alt="Floorplan" src={images[floor]} layout="fill" objectFit='contain'></Image>
|
|
|
|
</div>
|
|
|
|
<div className={[
|
|
|
|
styles.floorSelection,
|
|
|
|
(isMobile ? styles.fs_mobile : styles.fs_desktop)
|
|
|
|
].join(" ")}>
|
|
|
|
<button className={[
|
|
|
|
styles.floor_button,
|
|
|
|
(isMobile ? styles.fb_mobile : "")
|
|
|
|
].join(" ")} onClick={() => setFloor(floor + 1)} >+</button>
|
|
|
|
<button className={[
|
|
|
|
styles.floor_button,
|
|
|
|
(isMobile ? styles.fb_mobile : "")
|
|
|
|
].join(" ")} onClick={() => setFloor(floor - 1)} >-</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mapHtml = <div className={styles.mapContainer}><p>Invalid or missing floor info: {info.floors}</p></div>
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: set background here depending on image loaded
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<Head>
|
|
|
|
<title>Ready or Not</title>
|
|
|
|
<meta charSet='utf-8' />
|
|
|
|
<link rel="icon" href="/favicon.ico" />
|
|
|
|
</Head>
|
|
|
|
{infoHtml}
|
|
|
|
{mapHtml}
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
ReadyOrNotMaps.getLayout = function getLayout(page: ReactElement) {
|
|
|
|
return (
|
|
|
|
<LayoutReadyOrNot>
|
|
|
|
{page}
|
|
|
|
</LayoutReadyOrNot>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
function useMap(path: string):{mapInfo: ReadyOrNotMap, isLoadingInfo: boolean, isErrorInfo: boolean} {
|
|
|
|
const { data, error } = useSWR(`/api/${path}`, fetcher)
|
|
|
|
|
|
|
|
return {
|
|
|
|
mapInfo: data,
|
|
|
|
isLoadingInfo: !error && !data,
|
|
|
|
isErrorInfo: error
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function useImages(path: string):{mapImages: string[], isLoadingImages: boolean, isErrorImages: boolean, mutateImage: KeyedMutator<any>} {
|
|
|
|
const { data, error, mutate } = useSWR(`/api/${path}/maps`, fetcher)
|
|
|
|
|
|
|
|
return {
|
|
|
|
mapImages: data,
|
|
|
|
isLoadingImages: !error && !data,
|
|
|
|
isErrorImages: error,
|
|
|
|
mutateImage: mutate,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default ReadyOrNotMaps;
|