138 lines
4.0 KiB
TypeScript

import { useEffect, useState } from "preact/hooks";
import { Modal } from "../components/modal.tsx";
import { LabelledHr } from "../components/labelledHr.tsx";
import { PacksList } from "../components/packsList.tsx";
import { PackInfo } from "../components/packInfo.tsx";
import { useAtom } from "jotai";
import { namespaceAtom } from "../atoms/namespace.ts";
import { Outlet, Route, Routes } from "react-router-dom";
import { Selector } from "../components/editor/selector.tsx";
import { NamespaceModal } from "../components/editor/namespaceModal.tsx";
import { EditorWrapper } from "../components/editor/wrapper.tsx";
import { TagRouter } from "../components/editor/tags/editor.tsx";
export const Editor = () => {
const [packName, setPackName] = useState("");
const [loading, setLoading] = useState(true);
const [namespaces, setNamespaces] = useState<string[]>([]);
const [namespace, setNamespace] = useAtom(namespaceAtom);
const fetchNamespaces = async () => {
const res = await fetch("/api/pack/namespaces");
const json = await res.json();
setNamespaces(json);
};
useEffect(() => {
document.title = "BearMetal Packer";
fetch("/api/pack").then((res) => res.json()).then((json) => {
setPackName(json.packName);
setLoading(false);
});
fetchNamespaces();
}, []);
const setPackNameThing = async (event: SubmitEvent) => {
setLoading(true);
const res = await fetch("/api/pack", {
method: "POST",
body: new FormData(event.target as HTMLFormElement),
});
if (res.status === 200) {
document.title = packName;
setPackName(packName);
}
setLoading(false);
};
if (!packName) {
return (
<Modal>
{loading
? <p>Just a sec, trying to put the cats back in the bag.</p>
: (
<>
<form
method="POST"
onSubmit={setPackNameThing}
>
<label class="w-full">Set pack name</label>
<div class="flex gap-2">
<input type="text" name="packName" />
<button type="submit">Set</button>
</div>
</form>
<LabelledHr>OR</LabelledHr>
<PacksList setPackName={setPackName} />
</>
)}
</Modal>
);
}
const [showNamespaceModal, setShowNamespaceModal] = useState(false);
return (
<div class="flex h-full">
<div class="w-1/4 p-4 bg-mixed-400">
<div class="text-center">
<h1 class="text-2xl">BearMetalPacker</h1>
<PackInfo packName={packName} />
</div>
<LabelledHr>Namespaces</LabelledHr>
<div>
<ul class="w-full">
{namespaces.map((namespace) => (
<li
class="text-lg cursor-pointer even:bg-black/5"
onClick={() => setNamespace(namespace)}
>
{namespace}
</li>
))}
<li class="mt-4">
<button onClick={() => setShowNamespaceModal(true)}>
New Namespace
</button>
</li>
</ul>
{showNamespaceModal && (
<NamespaceModal
close={() => {
setShowNamespaceModal(false);
fetchNamespaces();
}}
/>
)}
</div>
</div>
<div class="p-4 w-max">
{!namespace ? <div>No namespace set</div> : (
<>
<h3 class="text-lg font-bold">
Namespace: <span class="italic">{namespace}</span>
</h3>
<Routes>
<Route index element={<Selector />} />
<Route
element={
<EditorWrapper>
<Outlet />
</EditorWrapper>
}
>
<Route
path="tags/*"
element={<TagRouter />}
/>
</Route>
</Routes>
</>
)}
</div>
</div>
);
};