blob: 36118db281060953e5e0ef1a099a7c22f6f9ad32 [file] [log] [blame]
gio5f2f1002025-03-20 18:38:48 +04001import { Button } from "@/components/ui/button";
2import { ReactFlowInstance, useReactFlow } from "@xyflow/react";
3import { v4 as uuidv4 } from "uuid";
4import { useCallback, useState } from "react";
5import { Accordion, AccordionTrigger } from "./ui/accordion";
6import { AccordionContent, AccordionItem } from "@radix-ui/react-accordion";
gioa2a845c2025-05-08 11:27:14 +00007import { NodeType, useCategories } from "@/lib/state";
gio5f2f1002025-03-20 18:38:48 +04008import { CategoryItem } from "@/lib/categories";
9import { Icon } from "./icon";
10
gioa2a845c2025-05-08 11:27:14 +000011function addResource(i: CategoryItem<NodeType>, flow: ReactFlowInstance) {
gio5f2f1002025-03-20 18:38:48 +040012 flow.addNodes({
13 id: uuidv4(),
14 position: {
15 x: 0,
16 y: 0,
17 },
18 type: i.type,
19 connectable: true,
20 data: i.init,
21 });
22}
23
24export function Resources() {
gio6cf8c272025-05-08 09:01:38 +000025 const flow = useReactFlow();
gio5f2f1002025-03-20 18:38:48 +040026 const categories = useCategories();
gioa2a845c2025-05-08 11:27:14 +000027 const onResourceAdd = useCallback((item: CategoryItem<NodeType>) => {
gio5f2f1002025-03-20 18:38:48 +040028 return () => addResource(item, flow);
29 }, [flow]);
30 const [open, setOpen] = useState<string[]>(categories.map((c) => c.title));
31 return (
32 <>
33 <Accordion type="multiple" value={open} onValueChange={(v) => setOpen(v)}>
34 {categories.map((c) => (
35 <AccordionItem key={c.title} value={c.title} className={"px-3" + (c.active ? " bg-amber-100" : "")}>
36 <AccordionTrigger>
37 {c.title}
38 </AccordionTrigger>
39 <AccordionContent>
40 <div className="flex flex-col space-y-1">
41 {c.items.map((item) => (
42 <Button key={item.title} onClick={onResourceAdd(item)} style={{ justifyContent: "flex-start" }}>{Icon(item.type)}{item.title}</Button>
43 ))}
44 </div>
45 </AccordionContent>
46 </AccordionItem>
47 ))}
48 </Accordion>
49 </>
50 );
51}