blob: aa48cd1f053f53eadbf1bdf689c1273215746536 [file] [log] [blame]
gio5f2f1002025-03-20 18:38:48 +04001import { NodeRect } from './node-rect';
2import { GithubNode, nodeIsConnectable, nodeLabel, useStateStore } from '@/lib/state';
3import { useEffect, useMemo } from 'react';
4import { z } from "zod";
5import { DeepPartial, EventType, useForm } from 'react-hook-form';
6import { zodResolver } from '@hookform/resolvers/zod';
7import { Form, FormControl, FormField, FormItem, FormMessage } from './ui/form';
8import { Input } from './ui/input';
9import { Handle, Position } from "@xyflow/react";
10
11export function NodeGithub(node: GithubNode) {
12 const { id, selected } = node;
13 const isConnectable = useMemo(() => nodeIsConnectable(node, "repository"), [node]);
14 return (
gio1dc800a2025-04-24 17:15:43 +000015 <NodeRect id={id} selected={selected} type={node.type} state={node.data.state}>
gio5f2f1002025-03-20 18:38:48 +040016 <div style={{ padding: '10px 20px' }}>
17 {nodeLabel(node)}
18 <Handle
19 id="repository"
20 type={"source"}
21 position={Position.Right}
22 isConnectableStart={isConnectable}
23 isConnectableEnd={isConnectable}
24 isConnectable={isConnectable}
25 />
26 </div>
27 </NodeRect>
28 );
29}
30
31const schema = z.object({
32 address: z.string().min(1),
33});
34
35export function NodeGithubDetails(node: GithubNode) {
36 const { id, data } = node;
37 const store = useStateStore();
38 const form = useForm<z.infer<typeof schema>>({
39 resolver: zodResolver(schema),
40 mode: "onChange",
41 defaultValues: {
42 address: data.address,
43 }
44 });
45 useEffect(() => {
46 const sub = form.watch((value: DeepPartial<z.infer<typeof schema>>, { name, type }: { name?: keyof z.infer<typeof schema> | undefined, type?: EventType | undefined }) => {
47 if (type !== "change") {
48 return;
49 }
50 switch (name) {
51 case "address":
52 store.updateNodeData<"github">(id, {
53 address: value.address,
54 });
55 break;
56 }
57 });
58 return () => sub.unsubscribe();
59 }, [form, store]);
60 return (
61 <>
62 <Form {...form}>
63 <form className="space-y-2">
64 <FormField
65 control={form.control}
66 name="address"
67 render={({ field }) => (
68 <FormItem>
69 <FormControl>
70 <Input placeholder="address" className="border border-black" {...field} />
71 </FormControl>
72 <FormMessage />
73 </FormItem>
74 )}
75 />
76 </form>
77 </Form>
78 </>);
79}