picobook/src/client/GamePage.tsx
2024-03-31 19:48:23 -07:00

77 lines
1.6 KiB
TypeScript

import { useParams } from "react-router-dom"
import { Pico8Console } from "./pico8-client/Pico8Console";
import { useEffect, useState } from "react";
import { DbRelease } from "../server/dbal/dbal";
import { css } from "@emotion/css";
type Info = {
release: DbRelease | null;
versions: string[];
}
export const GamePage = () => {
const {author, slug, version} = useParams();
const [info, setInfo] = useState<Info | null>(null);
useEffect(() => {
const fetchInfo = async () => {
let url = `/api/release?author=${author}&slug=${slug}`;
if (version) {
url += `version=${version}`;
}
const information = await fetch(url);
const json = await information.json();
setInfo(json);
}
fetchInfo();
}, [setInfo, author, slug, version]);
if (!info) {
return (
<div className={`
min-height: 100vh;
`}>
LOADING...
</div>
)
}
if (!info.release) {
return (
<div className={`
min-height: 100vh;
`}>
NOT FOUND
</div>
)
}
return (
<div className={css`
min-height: 100vh;
`}>
<div className={css`
margin: auto;
`}>
<h1>{info.release.manifest.title ?? slug!.split("-").map(word => word[0].toUpperCase()+word.slice(1)).join(" ")}</h1>
<h2>By: {info.release.author}</h2>
<div className={css`
max-width: 512px;
`}>
<Pico8Console carts={info.release.carts} />
</div>
<div className={css`
display: flex;
justify-content: end;
`}>
Version: <select defaultValue={info.release.version}>
{
info.versions.map(v => (
<option key={v} value={v}>{v}</option>
))
}
</select>
</div>
</div>
</div>
)
}