blob: 2d6d68de215af7b6ec557590bd8d9b1d1dd22e42 [file] [log] [blame]
import { ChangeEvent, useCallback, useEffect, useState } from "react";
import { Project, useProjectId, useStateStore } from "./lib/state";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./components/ui/select";
import { useReactFlow } from "@xyflow/react";
import { Input } from "./components/ui/input";
import { Button } from "./components/ui/button";
import { Dialog, DialogContent, DialogTrigger } from "./components/ui/dialog";
import { useToast } from "@/hooks/use-toast";
export function Header() {
const { toast } = useToast();
const store = useStateStore();
const [projects, setProjects] = useState<Project[]>([]);
// TODO(gio): sth fishy is here
useEffect(() => {
store.setProjects(projects);
}, [projects]);
const refreshProjects = useCallback(async () => {
try {
const resp = await fetch("/api/project");
setProjects(await resp.json());
} catch (e) {
console.log(e);
}
}, [setProjects]);
useEffect(() => {
refreshProjects();
}, [refreshProjects]);
const project = useProjectId();
const [createNewOpen, setCreateNewOpen] = useState(false);
const onSelect = useCallback((projectId: string) => {
if (projectId === "create-new") {
setCreateNewOpen(true);
} else {
store.setProject(projectId);
}
}, [store]);
const instance = useReactFlow();
const restoreSaved = useCallback(async (projectId: string) => {
const resp = await fetch(`/api/project/${projectId}/saved`, {
method: "GET",
});
const inst = await resp.json();
const { x = 0, y = 0, zoom = 1 } = inst.viewport;
instance.setNodes(inst.nodes || []);
instance.setEdges(inst.edges || []);
instance.setViewport({ x, y, zoom });
}, [instance]);
useEffect(() => {
if (project == null) {
return;
}
restoreSaved(project)
}, [project, restoreSaved]);
const [name, setName] = useState<string | undefined>(undefined);
const updateName = useCallback((e: ChangeEvent<HTMLInputElement>) => {
setName(e.target.value);
}, [setName]);
const createNew = useCallback(() => {
console.log(name);
if (!name) {
return;
}
fetch("/api/project", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: name,
}),
}).then(async (resp) => {
if (!resp.ok) {
return;
}
const { id } = await resp.json();
await refreshProjects();
store.setProject(id as string);
setCreateNewOpen(false);
toast({
title: `Created project: ${name}`,
});
}).catch((e) => {
console.log(e);
toast({
variant: "destructive",
title: `Failed to create project: ${name}`,
});
});
}, [name, setCreateNewOpen, toast]); // store
return (
<div className="flex flex-row h-9">
<Select onValueChange={onSelect} value={project}>
<SelectTrigger>
<SelectValue placeholder="Choose Project" defaultValue={project} />
</SelectTrigger>
<SelectContent>
{projects.map((p) => (
<SelectItem value={p.id}>{p.name}</SelectItem>
))}
<SelectItem value={"create-new"}>
<Dialog open={createNewOpen} onOpenChange={setCreateNewOpen}>
<DialogTrigger>Create New</DialogTrigger>
<DialogContent>
<Input type="text" placeholder="Name" onChange={updateName} />
<Button onClick={createNew}>Create New</Button>
</DialogContent>
</Dialog>
</SelectItem>
</SelectContent>
</Select>
</div>
);
}