Skip to content

Commit 257d4bf

Browse files
committed
Add webhook creation UI to dashboard
1 parent 8136982 commit 257d4bf

File tree

11 files changed

+1841
-9
lines changed

11 files changed

+1841
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
"use client";
2+
3+
import {
4+
FormControl,
5+
FormField,
6+
FormItem,
7+
FormLabel,
8+
FormMessage,
9+
} from "@/components/ui/form";
10+
import { Input } from "@/components/ui/input";
11+
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
12+
import { cn } from "@/lib/utils";
13+
import type { UseFormReturn } from "react-hook-form";
14+
import type { WebhookFormValues } from "../utils/webhookTypes";
15+
16+
interface BasicInfoStepProps {
17+
form: UseFormReturn<WebhookFormValues>;
18+
}
19+
20+
export default function BasicInfoStep({ form }: BasicInfoStepProps) {
21+
return (
22+
<>
23+
<div className="mb-4">
24+
<h2 className="font-medium text-lg">Step 1: Basic Information</h2>
25+
<p className="text-muted-foreground text-sm">
26+
Provide webhook details and select filter type
27+
</p>
28+
</div>
29+
30+
<FormField
31+
control={form.control}
32+
name="name"
33+
render={({ field }) => (
34+
<FormItem className="flex flex-col">
35+
<FormLabel>
36+
Name <span className="text-red-500">*</span>
37+
</FormLabel>
38+
<FormControl>
39+
<Input
40+
placeholder="Webhook name"
41+
value={field.value}
42+
onChange={field.onChange}
43+
/>
44+
</FormControl>
45+
<FormMessage />
46+
</FormItem>
47+
)}
48+
/>
49+
50+
<FormField
51+
control={form.control}
52+
name="webhookUrl"
53+
render={({ field }) => (
54+
<FormItem className="mt-4 flex flex-col">
55+
<FormLabel>
56+
Webhook URL <span className="text-red-500">*</span>
57+
</FormLabel>
58+
<FormControl>
59+
<Input
60+
placeholder="https://your-server.com/webhook"
61+
type="url"
62+
value={field.value}
63+
onChange={field.onChange}
64+
/>
65+
</FormControl>
66+
<FormMessage />
67+
</FormItem>
68+
)}
69+
/>
70+
71+
<FormField
72+
control={form.control}
73+
name="filterType"
74+
render={({ field }) => (
75+
<FormItem className="mt-6 flex flex-col">
76+
<FormLabel>
77+
Filter Type <span className="text-red-500">*</span>
78+
</FormLabel>
79+
<FormControl>
80+
<RadioGroup
81+
onValueChange={(value: string) => {
82+
if (value !== "event" && value !== "transaction") {
83+
return;
84+
}
85+
field.onChange(value);
86+
// Ensure the form state is updated immediately
87+
form.setValue("filterType", value, {
88+
shouldValidate: true,
89+
shouldDirty: true,
90+
});
91+
}}
92+
value={field.value || undefined}
93+
className="grid grid-cols-1 gap-4 md:grid-cols-2"
94+
>
95+
<div className="col-span-1">
96+
<label
97+
htmlFor="filter-event"
98+
className={cn(
99+
"flex cursor-pointer flex-col rounded-lg border-2 p-4 hover:border-primary/50",
100+
field.value === "event"
101+
? "border-primary bg-primary/5"
102+
: "",
103+
)}
104+
>
105+
<RadioGroupItem
106+
value="event"
107+
id="filter-event"
108+
className="sr-only"
109+
/>
110+
<div className="mb-2 flex items-center justify-between">
111+
<span className="font-medium text-base">Event</span>
112+
<div
113+
className={cn(
114+
"flex h-5 w-5 items-center justify-center rounded-full border",
115+
field.value === "event"
116+
? "border-primary"
117+
: "border-muted-foreground",
118+
)}
119+
>
120+
{field.value === "event" && (
121+
<div className="h-3 w-3 rounded-full bg-primary" />
122+
)}
123+
</div>
124+
</div>
125+
<span className="text-muted-foreground text-sm">
126+
Listen for contract events like token transfers or state
127+
changes
128+
</span>
129+
</label>
130+
</div>
131+
132+
<div className="col-span-1">
133+
<label
134+
htmlFor="filter-transaction"
135+
className={cn(
136+
"flex cursor-pointer flex-col rounded-lg border-2 p-4 hover:border-primary/50",
137+
field.value === "transaction"
138+
? "border-primary bg-primary/5"
139+
: "",
140+
)}
141+
>
142+
<RadioGroupItem
143+
value="transaction"
144+
id="filter-transaction"
145+
className="sr-only"
146+
/>
147+
<div className="mb-2 flex items-center justify-between">
148+
<span className="font-medium text-base">Transaction</span>
149+
<div
150+
className={cn(
151+
"flex h-5 w-5 items-center justify-center rounded-full border",
152+
field.value === "transaction"
153+
? "border-primary"
154+
: "border-muted-foreground",
155+
)}
156+
>
157+
{field.value === "transaction" && (
158+
<div className="h-3 w-3 rounded-full bg-primary" />
159+
)}
160+
</div>
161+
</div>
162+
<span className="text-muted-foreground text-sm">
163+
Listen for blockchain transactions with specific
164+
parameters
165+
</span>
166+
</label>
167+
</div>
168+
</RadioGroup>
169+
</FormControl>
170+
<FormMessage />
171+
</FormItem>
172+
)}
173+
/>
174+
</>
175+
);
176+
}

0 commit comments

Comments
 (0)