Skip to content

Commit 01e1054

Browse files
committed
improvement[webhook]: refactored webhook modal into components
1 parent 20caa0e commit 01e1054

File tree

13 files changed

+813
-696
lines changed

13 files changed

+813
-696
lines changed

package-lock.json

Lines changed: 0 additions & 60 deletions
This file was deleted.

package.json

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import { Checkbox } from '@/components/ui/checkbox'
2+
import { Input } from '@/components/ui/input'
3+
import { Label } from '@/components/ui/label'
4+
import { CopyableField } from '../ui/copyable'
5+
import { TestResultDisplay } from '../ui/test-result'
6+
7+
interface GenericConfigProps {
8+
requireAuth: boolean
9+
setRequireAuth: (requireAuth: boolean) => void
10+
generalToken: string
11+
setGeneralToken: (token: string) => void
12+
secretHeaderName: string
13+
setSecretHeaderName: (headerName: string) => void
14+
allowedIps: string
15+
setAllowedIps: (ips: string) => void
16+
isLoadingToken: boolean
17+
testResult: {
18+
success: boolean
19+
message?: string
20+
test?: any
21+
} | null
22+
copied: string | null
23+
copyToClipboard: (text: string, type: string) => void
24+
testWebhook: () => Promise<void>
25+
}
26+
27+
export function GenericConfig({
28+
requireAuth,
29+
setRequireAuth,
30+
generalToken,
31+
setGeneralToken,
32+
secretHeaderName,
33+
setSecretHeaderName,
34+
allowedIps,
35+
setAllowedIps,
36+
isLoadingToken,
37+
testResult,
38+
copied,
39+
copyToClipboard,
40+
}: GenericConfigProps) {
41+
return (
42+
<div className="space-y-4">
43+
<div className="flex items-center space-x-2 mb-3">
44+
<div className="flex items-center h-3.5 space-x-2">
45+
<Checkbox
46+
id="require-auth"
47+
checked={requireAuth}
48+
onCheckedChange={(checked) => setRequireAuth(checked as boolean)}
49+
/>
50+
<Label htmlFor="require-auth" className="text-sm font-medium cursor-pointer">
51+
Require Authentication
52+
</Label>
53+
</div>
54+
</div>
55+
56+
{requireAuth && (
57+
<div className="space-y-4 ml-5 border-l-2 pl-4 border-gray-200 dark:border-gray-700">
58+
<CopyableField
59+
id="auth-token"
60+
label="Authentication Token"
61+
value={generalToken}
62+
onChange={setGeneralToken}
63+
placeholder="Enter an auth token"
64+
description="This token will be used to authenticate requests to your webhook (via Bearer token)."
65+
isLoading={isLoadingToken}
66+
copied={copied}
67+
copyType="general-token"
68+
copyToClipboard={copyToClipboard}
69+
/>
70+
71+
<div className="space-y-2">
72+
<Label htmlFor="header-name">Secret Header Name (Optional)</Label>
73+
<Input
74+
id="header-name"
75+
value={secretHeaderName}
76+
onChange={(e) => setSecretHeaderName(e.target.value)}
77+
placeholder="X-Secret-Key"
78+
className="flex-1"
79+
/>
80+
<p className="text-xs text-muted-foreground">
81+
Custom HTTP header name for passing the authentication token instead of using Bearer
82+
authentication.
83+
</p>
84+
</div>
85+
</div>
86+
)}
87+
88+
<div className="space-y-2">
89+
<Label htmlFor="allowed-ips">Allowed IP Addresses (Optional)</Label>
90+
<Input
91+
id="allowed-ips"
92+
value={allowedIps}
93+
onChange={(e) => setAllowedIps(e.target.value)}
94+
placeholder="192.168.1.1, 10.0.0.1"
95+
className="flex-1"
96+
/>
97+
<p className="text-xs text-muted-foreground">
98+
Comma-separated list of IP addresses that are allowed to access this webhook.
99+
</p>
100+
</div>
101+
102+
<TestResultDisplay
103+
testResult={testResult}
104+
copied={copied}
105+
copyToClipboard={copyToClipboard}
106+
showCurlCommand={true}
107+
/>
108+
109+
<div className="bg-gray-50 dark:bg-gray-800 p-3 rounded-md mt-3 border border-gray-200 dark:border-gray-700">
110+
<h4 className="font-medium text-sm mb-2">Setup Instructions</h4>
111+
<ol className="list-decimal list-inside space-y-1 text-sm">
112+
<li>Copy the Webhook URL above</li>
113+
<li>Configure your service to send HTTP POST requests to this URL</li>
114+
{requireAuth && (
115+
<>
116+
<li>
117+
{secretHeaderName
118+
? `Add the "${secretHeaderName}" header with your token to all requests`
119+
: 'Add an "Authorization: Bearer YOUR_TOKEN" header to all requests'}
120+
</li>
121+
</>
122+
)}
123+
</ol>
124+
125+
<div className="mt-4 pt-3 border-t border-gray-200 dark:border-gray-700">
126+
<p className="text-sm text-gray-700 dark:text-gray-300 flex items-center">
127+
<span className="text-gray-400 dark:text-gray-500 mr-2">💡</span>
128+
The webhook will receive all HTTP POST requests and pass the data to your workflow.
129+
</p>
130+
</div>
131+
</div>
132+
</div>
133+
)
134+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { Loader2 } from 'lucide-react'
2+
import { Input } from '@/components/ui/input'
3+
import { Label } from '@/components/ui/label'
4+
5+
interface GithubConfigProps {
6+
contentType: string
7+
setContentType: (contentType: string) => void
8+
isLoadingToken: boolean
9+
testResult: {
10+
success: boolean
11+
message?: string
12+
test?: any
13+
} | null
14+
copied: string | null
15+
copyToClipboard: (text: string, type: string) => void
16+
}
17+
18+
export function GithubConfig({
19+
contentType,
20+
setContentType,
21+
isLoadingToken,
22+
testResult,
23+
}: GithubConfigProps) {
24+
return (
25+
<div className="space-y-4">
26+
<div className="space-y-2">
27+
<Label htmlFor="github-content-type">Content Type</Label>
28+
{isLoadingToken ? (
29+
<div className="h-10 px-3 py-2 rounded-md border border-input bg-background flex items-center">
30+
<Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
31+
</div>
32+
) : (
33+
<Input
34+
id="github-content-type"
35+
value={contentType}
36+
onChange={(e) => setContentType(e.target.value)}
37+
placeholder="application/json"
38+
className="flex-1"
39+
/>
40+
)}
41+
</div>
42+
43+
<div className="space-y-2">
44+
<h4 className="font-medium">Setup Instructions</h4>
45+
<ol className="list-decimal list-inside space-y-1 text-sm">
46+
<li>Go to your GitHub repository</li>
47+
<li>Navigate to Settings {'>'} Webhooks</li>
48+
<li>Click "Add webhook"</li>
49+
<li>Enter the Webhook URL shown above</li>
50+
<li>Set Content type to "{contentType}"</li>
51+
<li>Choose which events you want to trigger the webhook</li>
52+
<li>Ensure "Active" is checked and save</li>
53+
</ol>
54+
</div>
55+
56+
<div className="bg-gray-50 dark:bg-gray-800 p-3 rounded-md mt-3 border border-gray-200 dark:border-gray-700">
57+
<p className="text-sm text-gray-700 dark:text-gray-300 flex items-center">
58+
<span className="text-gray-400 dark:text-gray-500 mr-2">💡</span>
59+
After saving, GitHub will send a ping event to verify your webhook.
60+
</p>
61+
</div>
62+
</div>
63+
)
64+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
interface StripeConfigProps {
2+
isLoadingToken: boolean
3+
testResult: {
4+
success: boolean
5+
message?: string
6+
test?: any
7+
} | null
8+
copied: string | null
9+
copyToClipboard: (text: string, type: string) => void
10+
}
11+
12+
export function StripeConfig({
13+
isLoadingToken,
14+
testResult,
15+
copied,
16+
copyToClipboard,
17+
}: StripeConfigProps) {
18+
return (
19+
<div className="space-y-2">
20+
<h4 className="font-medium">Setup Instructions</h4>
21+
<ol className="list-decimal list-inside space-y-1 text-sm">
22+
<li>Go to your Stripe Dashboard</li>
23+
<li>Navigate to Developers {'>'} Webhooks</li>
24+
<li>Click "Add endpoint"</li>
25+
<li>Enter the Webhook URL shown above</li>
26+
<li>Select the events you want to listen for</li>
27+
<li>Add the endpoint</li>
28+
</ol>
29+
30+
<div className="bg-gray-50 dark:bg-gray-800 p-3 rounded-md mt-3 border border-gray-200 dark:border-gray-700">
31+
<p className="text-sm text-gray-700 dark:text-gray-300 flex items-center">
32+
<span className="text-gray-400 dark:text-gray-500 mr-2">💡</span>
33+
Stripe will send a test event to verify your webhook endpoint.
34+
</p>
35+
</div>
36+
</div>
37+
)
38+
}

0 commit comments

Comments
 (0)