import { useState, useEffect } from 'react' import { Link } from 'react-router-dom' import { IconPlus, IconTrash } from '@tabler/icons-react' import { api } from '../../lib/api' import { useDocumentTitle } from '../../hooks/useDocumentTitle' import { useConfirm } from '../../hooks/useConfirm' interface Webhook { id: string url: string secret: string events: string[] active: boolean createdAt: string } const ALL_EVENTS = [ { value: 'status_changed', label: 'Status changed' }, { value: 'post_created', label: 'Post created' }, { value: 'comment_added', label: 'Comment added' }, ] export default function AdminWebhooks() { useDocumentTitle('Webhooks') const confirm = useConfirm() const [webhooks, setWebhooks] = useState([]) const [loading, setLoading] = useState(true) const [showForm, setShowForm] = useState(false) const [url, setUrl] = useState('') const [events, setEvents] = useState(['status_changed', 'post_created', 'comment_added']) const [newSecret, setNewSecret] = useState(null) const [error, setError] = useState('') const fetchWebhooks = () => { api.get<{ webhooks: Webhook[] }>('/admin/webhooks') .then((r) => setWebhooks(r.webhooks)) .catch(() => {}) .finally(() => setLoading(false)) } useEffect(fetchWebhooks, []) const create = async () => { if (!url.trim() || events.length === 0) return setError('') try { const res = await api.post('/admin/webhooks', { url: url.trim(), events }) setNewSecret(res.secret) setUrl('') setShowForm(false) fetchWebhooks() } catch { setError('Failed to create webhook') } } const toggle = async (id: string, active: boolean) => { try { await api.put(`/admin/webhooks/${id}`, { active: !active }) fetchWebhooks() } catch {} } const remove = async (id: string) => { if (!await confirm('Delete this webhook?')) return try { await api.delete(`/admin/webhooks/${id}`) fetchWebhooks() } catch {} } return (

Webhooks

Back
{newSecret && (

Webhook created - copy the signing secret now (it won't be shown again):

{newSecret}
)} {showForm && (
setUrl(e.target.value)} type="url" />
{ALL_EVENTS.map((ev) => { const active = events.includes(ev.value) return ( ) })}
{error &&

{error}

}
)} {loading ? (
{[0, 1].map((i) => (
))}
) : webhooks.length === 0 ? (

No webhooks configured

) : (
{webhooks.map((wh) => (
{wh.url}
{wh.events.map((ev) => ( {ev.replace(/_/g, ' ')} ))} Signed
))}
)}
) }