64 lines
1.4 KiB
TypeScript
64 lines
1.4 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;
|
||
|
`}>
|
||
|
<h1>{info.release.manifest.title ?? slug!.split("-").map(word => word[0].toUpperCase()+word.slice(1)).join(" ")}</h1>
|
||
|
<Pico8Console carts={info.release.carts} />
|
||
|
<div>By: {info.release.author}</div>
|
||
|
<select defaultValue={info.release.version}>
|
||
|
{
|
||
|
info.versions.map(v => (
|
||
|
<option key={v} value={v}>{v}</option>
|
||
|
))
|
||
|
}
|
||
|
</select>
|
||
|
</div>
|
||
|
)
|
||
|
}
|