HookCard.tsx141 lines · main
1import { PermissionAction } from '@supabase/shared-types/out/constants'
2import { Check, Webhook } from 'lucide-react'
3import { Badge } from 'ui'
4import { Input } from 'ui-patterns/DataInputs/Input'
5
6import { Hook } from './hooks.constants'
7import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
8import { DocsButton } from '@/components/ui/DocsButton'
9import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
10import { DOCS_URL } from '@/lib/constants'
11
12interface HookCardProps {
13 hook: Hook
14 onSelect: () => void
15}
16
17export const HookCard = ({ hook, onSelect }: HookCardProps) => {
18 const { can: canUpdateAuthHook } = useAsyncCheckPermissions(PermissionAction.AUTH_EXECUTE, '*')
19
20 return (
21 <div className="bg-surface-100 border-default overflow-hidden border shadow-sm px-5 py-4 flex flex-row first:rounded-t-md last:rounded-b-md space-x-4">
22 <div>
23 <Webhook size={21} strokeWidth="1" />
24 </div>
25 <div className="flex flex-col grow overflow-y-auto w-full">
26 <span className="text-sm text-foreground">{hook.title}</span>
27 <span className="text-sm text-foreground-lighter">{hook.subtitle}</span>
28 <div className="text-sm flex flex-row space-x-5 py-4">
29 {hook.method.type === 'postgres' ? (
30 <div className="flex flex-col w-full space-y-2">
31 <div className="flex flex-row items-center">
32 <span className="text-foreground-light w-20">type</span>
33 <span className="text-foreground">Postgres function</span>
34 </div>
35 <div className="flex flex-row items-center">
36 <label htmlFor="schema" className="text-foreground-light w-20">
37 schema
38 </label>
39 <Input
40 id="schema"
41 title={hook.method.schema}
42 copy
43 readOnly
44 disabled
45 containerClassName="flex-1"
46 className="font-mono text-xs md:text-xs disabled:text-foreground-light opacity-100"
47 value={hook.method.schema}
48 />
49 </div>
50 <div className="flex flex-row items-center">
51 <label htmlFor="functionName" className="text-foreground-light w-20">
52 function
53 </label>
54 <Input
55 id="functionName"
56 title={hook.method.functionName}
57 copy
58 readOnly
59 disabled
60 containerClassName="flex-1"
61 className="font-mono text-xs md:text-xs disabled:text-foreground-light opacity-100"
62 value={hook.method.functionName}
63 />
64 </div>
65 </div>
66 ) : (
67 <div className="flex flex-col w-full space-y-2">
68 <div className="flex flex-row items-center">
69 <span className="text-foreground-light w-20">type</span>
70 <span className="text-foreground">HTTPS endpoint</span>
71 </div>
72 <div className="flex flex-row items-center">
73 <label htmlFor="url" className="text-foreground-light w-20">
74 endpoint
75 </label>
76 <Input
77 id="url"
78 title={hook.method.url}
79 copy
80 readOnly
81 disabled
82 containerClassName="flex-1"
83 className="font-mono text-xs md:text-xs disabled:text-foreground-light opacity-100"
84 value={hook.method.url}
85 />
86 </div>
87 <div className="flex flex-row items-center">
88 <label htmlFor="secret" className="text-foreground-light w-20">
89 secret
90 </label>
91 <Input
92 id="secret"
93 copy
94 title={hook.method.secret}
95 reveal={true}
96 readOnly
97 disabled
98 containerClassName="flex-1"
99 className="font-mono text-xs md:text-xs disabled:text-foreground-light opacity-100"
100 value={hook.method.secret}
101 />
102 </div>
103 </div>
104 )}
105 </div>
106 <div className="flex flex-row gap-2">
107 <ButtonTooltip
108 type="default"
109 disabled={!canUpdateAuthHook}
110 onClick={() => onSelect()}
111 tooltip={{
112 content: {
113 side: 'bottom',
114 text: !canUpdateAuthHook
115 ? 'You need additional permissions to configure auth hooks'
116 : undefined,
117 },
118 }}
119 >
120 Configure hook
121 </ButtonTooltip>
122 <DocsButton href={`${DOCS_URL}/guides/auth/auth-hooks/${hook.docSlug}`} />
123 </div>
124 </div>
125 <div>
126 {hook.enabled ? (
127 <Badge className="space-x-1" variant="success">
128 <div className="h-3.5 w-3.5 bg-brand rounded-full flex justify-center items-center">
129 <Check className="h-2 w-2 text-background-overlay " strokeWidth={6} />
130 </div>
131 <span>Enabled</span>
132 </Badge>
133 ) : (
134 <Badge variant="warning">
135 <span>Disabled</span>
136 </Badge>
137 )}
138 </div>
139 </div>
140 )
141}