Skip to content

Commit ce17dd8

Browse files
committed
refactor: enhance WebhookTableRow with URL copy functionality
- Introduced a new WebhookNameAndUrl component to encapsulate the display and copy functionality for webhook names and URLs. - Implemented clipboard copying with visual feedback for the URL, improving user interaction. - Updated WebhookTableRow to utilize the new component, streamlining the code and enhancing maintainability. These changes aim to improve the user experience when managing webhooks by making URL copying more intuitive.
1 parent 2db48f4 commit ce17dd8

1 file changed

Lines changed: 62 additions & 12 deletions

File tree

src/features/dashboard/settings/webhooks/table-row.tsx

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
'use client'
22

33
import { useState } from 'react'
4+
import { useClipboard } from '@/lib/hooks/use-clipboard'
5+
import { defaultSuccessToast, toast } from '@/lib/hooks/use-toast'
46
import { cn } from '@/lib/utils'
57
import { Badge } from '@/ui/primitives/badge'
8+
import { Button } from '@/ui/primitives/button'
69
import {
710
DropdownMenu,
811
DropdownMenuContent,
@@ -12,6 +15,8 @@ import {
1215
} from '@/ui/primitives/dropdown-menu'
1316
import { IconButton } from '@/ui/primitives/icon-button'
1417
import {
18+
CheckIcon,
19+
CopyIcon,
1520
EditIcon,
1621
IndicatorDotsIcon,
1722
PrivateIcon,
@@ -36,6 +41,62 @@ type WebhookRowActionsProps = {
3641
webhook: Webhook
3742
}
3843

44+
type WebhookNameAndUrlProps = {
45+
name: string
46+
url: string
47+
}
48+
49+
type UrlIconState = 'copied' | 'hovered' | 'idle'
50+
51+
const urlIconMap: Record<UrlIconState, typeof WebhookIcon> = {
52+
copied: CheckIcon,
53+
hovered: CopyIcon,
54+
idle: WebhookIcon,
55+
}
56+
57+
const WebhookNameAndUrl = ({ name, url }: WebhookNameAndUrlProps) => {
58+
const [wasCopied, copy] = useClipboard(1500)
59+
const [isUrlHovered, setIsUrlHovered] = useState(false)
60+
const iconState: UrlIconState = wasCopied
61+
? 'copied'
62+
: isUrlHovered
63+
? 'hovered'
64+
: 'idle'
65+
const UrlIcon = urlIconMap[iconState]
66+
67+
const handleCopy = async (e: React.MouseEvent) => {
68+
e.stopPropagation()
69+
await copy(url)
70+
toast(defaultSuccessToast('Webhook URL copied'))
71+
}
72+
73+
return (
74+
<>
75+
<div
76+
aria-hidden="true"
77+
className="border-stroke flex size-8 shrink-0 items-center justify-center border"
78+
>
79+
<UrlIcon className="size-4 text-fg-secondary" />
80+
</div>
81+
82+
<div className="flex min-w-0 flex-1 flex-col justify-center gap-0.5 pb-0.5">
83+
<p className="truncate text-left text-fg prose-body">{name}</p>
84+
<Button
85+
variant="quaternary"
86+
size="none"
87+
onClick={handleCopy}
88+
onMouseEnter={() => setIsUrlHovered(true)}
89+
onMouseLeave={() => setIsUrlHovered(false)}
90+
aria-label={`Copy webhook URL ${url}`}
91+
className="w-full min-w-0 justify-start font-mono uppercase prose-label-numeric"
92+
>
93+
<span className="truncate">{url}</span>
94+
</Button>
95+
</div>
96+
</>
97+
)
98+
}
99+
39100
const rowCellClassName = 'h-[50px] p-0 align-top'
40101
const rowContentClassName = 'flex h-11 items-center'
41102
const actionIconClassName = 'size-4 text-fg-tertiary'
@@ -101,18 +162,7 @@ export const WebhookTableRow = ({ webhook, className }: WebhookRowProps) => {
101162
<TableRow className={cn('h-[50px] bg-bg hover:bg-transparent', className)}>
102163
<TableCell className={cn(rowCellClassName, 'max-w-0 pr-12')}>
103164
<div className={cn(rowContentClassName, 'min-w-0 gap-3')}>
104-
<div className="border-stroke flex size-8 shrink-0 items-center justify-center border">
105-
<WebhookIcon className="size-4 text-fg-secondary" />
106-
</div>
107-
108-
<div className="flex min-w-0 flex-1 flex-col justify-center gap-0.5 pb-0.5">
109-
<p className="truncate text-left text-fg prose-body">
110-
{webhook.name}
111-
</p>
112-
<p className="truncate font-mono text-[12px] leading-[17px] text-fg-tertiary uppercase">
113-
{webhook.url}
114-
</p>
115-
</div>
165+
<WebhookNameAndUrl name={webhook.name} url={webhook.url} />
116166
</div>
117167
</TableCell>
118168

0 commit comments

Comments
 (0)