mirror of
https://github.com/documenso/documenso.git
synced 2025-11-10 04:22:32 +10:00
feat: delete webhook functionality
This commit is contained in:
@ -1,7 +1,9 @@
|
||||
'use client';
|
||||
|
||||
import { Zap } from 'lucide-react';
|
||||
import { ToggleLeft, ToggleRight } from 'lucide-react';
|
||||
|
||||
import { trpc } from '@documenso/trpc/react';
|
||||
import { Button } from '@documenso/ui/primitives/button';
|
||||
|
||||
import { SettingsHeader } from '~/components/(dashboard)/settings/layout/header';
|
||||
@ -9,17 +11,7 @@ import { CreateWebhookDialog } from '~/components/(dashboard)/settings/webhooks/
|
||||
import { DeleteWebhookDialog } from '~/components/(dashboard)/settings/webhooks/delete-webhook-dialog';
|
||||
|
||||
export default function WebhookPage() {
|
||||
// TODO: Fetch webhooks from the DB after implementing the backend
|
||||
const webhooks = [
|
||||
{
|
||||
id: 1,
|
||||
secret: 'my-secret',
|
||||
webhookUrl: 'https://example.com/webhook',
|
||||
eventTriggers: ['document.created', 'document.signed'],
|
||||
enabled: true,
|
||||
userID: 1,
|
||||
},
|
||||
];
|
||||
const { data: webhooks } = trpc.webhook.getWebhooks.useQuery();
|
||||
|
||||
return (
|
||||
<div>
|
||||
@ -30,7 +22,7 @@ export default function WebhookPage() {
|
||||
<CreateWebhookDialog />
|
||||
</SettingsHeader>
|
||||
|
||||
{webhooks.length === 0 && (
|
||||
{webhooks?.length === 0 && (
|
||||
// TODO: Perhaps add some illustrations here to make the page more engaging
|
||||
<div className="mb-4">
|
||||
<p className="text-muted-foreground mt-2 text-sm italic">
|
||||
@ -39,9 +31,9 @@ export default function WebhookPage() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{webhooks.length > 0 && (
|
||||
{webhooks?.length > 0 && (
|
||||
<div className="mt-4 flex max-w-xl flex-col gap-y-4">
|
||||
{webhooks.map((webhook) => (
|
||||
{webhooks?.map((webhook) => (
|
||||
<div key={webhook.id} className="border-border rounded-lg border p-4">
|
||||
<div className="flex items-center justify-between gap-x-4">
|
||||
<div>
|
||||
@ -53,6 +45,15 @@ export default function WebhookPage() {
|
||||
<Zap className="mr-1 h-4 w-4 fill-yellow-400 stroke-yellow-600" /> {trigger}
|
||||
</p>
|
||||
))}
|
||||
{webhook.enabled ? (
|
||||
<h4 className="mt-4 flex items-center gap-2 text-lg">
|
||||
Active <ToggleRight className="h-6 w-6 fill-green-200 stroke-green-400" />
|
||||
</h4>
|
||||
) : (
|
||||
<h4 className="mt-4 flex items-center gap-2 text-lg">
|
||||
Inactive <ToggleLeft className="h-6 w-6 fill-slate-200 stroke-slate-400" />
|
||||
</h4>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col-reverse space-y-2 space-y-reverse sm:flex-row sm:justify-end sm:space-x-2 sm:space-y-0">
|
||||
|
||||
@ -127,7 +127,6 @@ export const CreateWebhookDialog = ({ trigger, ...props }: CreateWebhookDialogPr
|
||||
<MultiSelectCombobox
|
||||
listValues={value}
|
||||
onChange={(values: string[]) => {
|
||||
console.log(values);
|
||||
onChange(values);
|
||||
}}
|
||||
/>
|
||||
|
||||
@ -52,7 +52,7 @@ export const DeleteWebhookDialog = ({ webhook, children }: DeleteWebhookDialogPr
|
||||
|
||||
type TDeleteWebhookFormSchema = z.infer<typeof ZDeleteWebhookFormSchema>;
|
||||
|
||||
const { mutateAsync: deleteWebhook } = trpc.webhook.deleteWebhookById.useMutation();
|
||||
const { mutateAsync: deleteWebhook } = trpc.webhook.deleteWebhook.useMutation();
|
||||
|
||||
const form = useForm<TDeleteWebhookFormSchema>({
|
||||
resolver: zodResolver(ZDeleteWebhookFormSchema),
|
||||
|
||||
15
packages/lib/server-only/webhooks/delete-webhook-by-id.ts
Normal file
15
packages/lib/server-only/webhooks/delete-webhook-by-id.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
export type DeleteWebhookByIdOptions = {
|
||||
id: number;
|
||||
userId: number;
|
||||
};
|
||||
|
||||
export const deleteWebhookById = async ({ id, userId }: DeleteWebhookByIdOptions) => {
|
||||
return await prisma.webhook.delete({
|
||||
where: {
|
||||
id,
|
||||
userId,
|
||||
},
|
||||
});
|
||||
};
|
||||
@ -1,10 +1,12 @@
|
||||
import { TRPCError } from '@trpc/server';
|
||||
|
||||
import { createWebhook } from '@documenso/lib/server-only/webhooks/create-webhook';
|
||||
import { deleteWebhookById } from '@documenso/lib/server-only/webhooks/delete-webhook-by-id';
|
||||
import { getWebhooksByUserId } from '@documenso/lib/server-only/webhooks/get-webhooks-by-user-id';
|
||||
|
||||
import { authenticatedProcedure, router } from '../trpc';
|
||||
import { ZCreateWebhookFormSchema } from './schema';
|
||||
import { ZDeleteWebhookSchema } from './schema';
|
||||
|
||||
export const webhookRouter = router({
|
||||
getWebhooks: authenticatedProcedure.query(async ({ ctx }) => {
|
||||
@ -32,4 +34,21 @@ export const webhookRouter = router({
|
||||
});
|
||||
}
|
||||
}),
|
||||
deleteWebhook: authenticatedProcedure
|
||||
.input(ZDeleteWebhookSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const { id } = input;
|
||||
|
||||
return await deleteWebhookById({
|
||||
id,
|
||||
userId: ctx.user.id,
|
||||
});
|
||||
} catch (err) {
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message: 'We were unable to create this webhook. Please try again later.',
|
||||
});
|
||||
}
|
||||
}),
|
||||
});
|
||||
|
||||
@ -11,4 +11,10 @@ export const ZCreateWebhookFormSchema = z.object({
|
||||
enabled: z.boolean(),
|
||||
});
|
||||
|
||||
export const ZDeleteWebhookSchema = z.object({
|
||||
id: z.number(),
|
||||
});
|
||||
|
||||
export type TCreateWebhookFormSchema = z.infer<typeof ZCreateWebhookFormSchema>;
|
||||
|
||||
export type TDeleteWebhookSchema = z.infer<typeof ZDeleteWebhookSchema>;
|
||||
|
||||
Reference in New Issue
Block a user