Content Migration from websites repo
This commit is contained in:
parent
4b0bd40dcf
commit
5869e05c33
49 changed files with 9081 additions and 1 deletions
179
pages/[map].tsx
Normal file
179
pages/[map].tsx
Normal file
|
@ -0,0 +1,179 @@
|
|||
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';
|
||||
import Image from 'next/image'
|
||||
import ReadyOrNotMap from '../interfaces/ReadyOrNot';
|
||||
|
||||
const fetcher = (url: string) => fetch(url).then((res) => res.json())
|
||||
|
||||
function useWindowSize() {
|
||||
const [windowSize, setWindowSize] = useState({
|
||||
width: 0,
|
||||
height: 0,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
function handleResize() {
|
||||
setWindowSize({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener("resize", handleResize);
|
||||
|
||||
handleResize();
|
||||
|
||||
return () => window.removeEventListener("resize", handleResize);
|
||||
}, []);
|
||||
return windowSize.width <= 1080;
|
||||
}
|
||||
|
||||
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;
|
22
pages/_app.tsx
Normal file
22
pages/_app.tsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
import '/styles/globals.css'
|
||||
import type { ReactElement, ReactNode } from 'react'
|
||||
import Layout from '../components/layout'
|
||||
import type { NextPage } from 'next'
|
||||
import { AppProps } from 'next/app';
|
||||
|
||||
|
||||
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
|
||||
getLayout?: (page: ReactElement) => ReactNode
|
||||
}
|
||||
|
||||
export type AppPropsWithLayout = AppProps & {
|
||||
Component: NextPageWithLayout
|
||||
}
|
||||
|
||||
export default function Website({ Component, pageProps }: AppPropsWithLayout) {
|
||||
// Use the layout defined at the page level, if available
|
||||
const getLayout = Component.getLayout ?? ((page) => (
|
||||
<Layout>{page}</Layout>))
|
||||
|
||||
return getLayout(<Component {...pageProps} />)
|
||||
}
|
16
pages/api/[map].tsx
Normal file
16
pages/api/[map].tsx
Normal file
|
@ -0,0 +1,16 @@
|
|||
import fsPromises from 'fs/promises'
|
||||
import path from 'path'
|
||||
|
||||
export default async function MapApi(req: any, res: any) {
|
||||
const { map } = req.query
|
||||
try {
|
||||
// get Empire and Game name first to create an EmpireData object
|
||||
const filePathMap = path.join(process.cwd(), '/public/images/'+map+'/info.json');
|
||||
const jsonMapData = await fsPromises.readFile(filePathMap);
|
||||
res.status(200).send(jsonMapData.toString())
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error)
|
||||
res.status(500).json({error: 'Error reading data'})
|
||||
}
|
||||
}
|
23
pages/api/[map]/maps.tsx
Normal file
23
pages/api/[map]/maps.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
import fsPromises from 'fs/promises'
|
||||
import path from 'path'
|
||||
|
||||
export default async function MapApi(req: any, res: any) {
|
||||
const { map } = req.query
|
||||
try {
|
||||
// get list of all files(maps) in the readyornot folder - maybe there is a cleaner way to do this?
|
||||
// we filter out any subdirectories as well as any files not ending in png or jpg
|
||||
var fs = require('fs')
|
||||
var maps = fs.readdirSync(path.join(process.cwd(), "/public/images/" + map + "/"), { withFileTypes: true })
|
||||
.filter((file: any) => file.isFile())
|
||||
.filter((file: any) => file.name.endsWith(".jpg") || file.name.endsWith(".png"))
|
||||
.map((file: any) => '/images/' + map + '/' + file.name);
|
||||
|
||||
|
||||
// get Empire and Game name first to create an EmpireData object
|
||||
res.status(200).json(maps)
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error)
|
||||
res.status(500).json({ error: 'Error reading data' })
|
||||
}
|
||||
}
|
33
pages/api/navbar.tsx
Normal file
33
pages/api/navbar.tsx
Normal file
|
@ -0,0 +1,33 @@
|
|||
// jsut iterate through all relevant data serverside instead of dealing with it client side
|
||||
import fsPromises from 'fs/promises'
|
||||
import path from 'path'
|
||||
import ReadyOrNotMap from '../../interfaces/ReadyOrNot'
|
||||
|
||||
export default async function TobarApi(req: any, res: any) {
|
||||
try {
|
||||
// get list of all folders(maps) in the readyornot folder - maybe there is a cleaner way to do this?
|
||||
var fs = require('fs')
|
||||
var mapList = fs.readdirSync(path.join(process.cwd(), '/public/images/'), { withFileTypes: true })
|
||||
.filter((dirent:any) => dirent.isDirectory())
|
||||
.map((dirent:any) => dirent.name);
|
||||
|
||||
// iterate through every map entry and extract the info
|
||||
let maps: ReadyOrNotMap[] = [];
|
||||
|
||||
for (let i = 0; i < mapList.length; i++) {
|
||||
// get map data for the API request
|
||||
const filePathEmpire = path.join(process.cwd(), '/public/images/' + mapList[i] + '/info.json');
|
||||
const jsonDataEmpire = await fsPromises.readFile(filePathEmpire);
|
||||
let mapData = JSON.parse(jsonDataEmpire.toString());
|
||||
mapData.href = mapList[i];
|
||||
|
||||
maps.push(mapData) ;
|
||||
}
|
||||
|
||||
res.status(200).json(maps);
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error);
|
||||
res.status(500).json({ error: 'Error reading data' });
|
||||
}
|
||||
}
|
34
pages/index.tsx
Normal file
34
pages/index.tsx
Normal file
|
@ -0,0 +1,34 @@
|
|||
import Head from 'next/head'
|
||||
import type { ReactElement } from 'react'
|
||||
import LayoutReadyOrNot from '../components/layout'
|
||||
import styles from '/styles/ReadyOrNot.module.css'
|
||||
import { NextPageWithLayout } from './_app';
|
||||
import React from 'react';
|
||||
|
||||
const ReadyOrNot: NextPageWithLayout = () => {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Ready or Not</title>
|
||||
<meta charSet='utf-8' />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
<h1 className={styles.title}>
|
||||
About
|
||||
</h1>
|
||||
<p className={styles.description}>
|
||||
Ready or Not Floor Plan Application in the works
|
||||
</p>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
ReadyOrNot.getLayout = function getLayout(page: ReactElement) {
|
||||
return (
|
||||
<LayoutReadyOrNot>
|
||||
{page}
|
||||
</LayoutReadyOrNot>
|
||||
)
|
||||
}
|
||||
|
||||
export default ReadyOrNot;
|
Reference in a new issue