'use client';
import React, { FC, Fragment, useCallback, useState } from 'react';
import { useFetch } from '@gitroom/helpers/utils/custom.fetch';
import useSWR from 'swr';
import { useUser } from '@gitroom/frontend/components/layout/user.context';
import { Button } from '@gitroom/react/form/button';
import { useModals } from '@gitroom/frontend/components/layout/new-modal';
import { Input } from '@gitroom/react/form/input';
import { FormProvider, useForm } from 'react-hook-form';
import { array, object, string } from 'yup';
import { yupResolver } from '@hookform/resolvers/yup';
import { Select } from '@gitroom/react/form/select';
import { PickPlatforms } from '@gitroom/frontend/components/launches/helpers/pick.platform.component';
import { useToaster } from '@gitroom/react/toaster/toaster';
import clsx from 'clsx';
import { deleteDialog } from '@gitroom/react/helpers/delete.dialog';
import { useT } from '@gitroom/react/translation/get.transation.service.client';
export const Webhooks: FC = () => {
const fetch = useFetch();
const user = useUser();
const modal = useModals();
const toaster = useToaster();
const t = useT();
const list = useCallback(async () => {
return (await fetch('/webhooks')).json();
}, []);
const { data, mutate } = useSWR('webhooks', list);
const addWebhook = useCallback(
(data?: any) => () => {
modal.openModal({
title: data ? t('update_webhook', 'Update webhook') : t('add_webhook', 'Add webhook'),
withCloseButton: true,
children: ,
});
},
[t]
);
const deleteHook = useCallback(
(data: any) => async () => {
if (
await deleteDialog(
t(
'are_you_sure_you_want_to_delete',
`Are you sure you want to delete ${data.name}?`,
{ name: data.name }
)
)
) {
await fetch(`/webhooks/${data.id}`, {
method: 'DELETE',
});
mutate();
toaster.show(t('webhook_deleted_successfully', 'Webhook deleted successfully'), 'success');
}
},
[]
);
return (
{t('webhooks', 'Webhooks')} ({data?.length || 0}/{user?.tier?.webhooks})
{t(
'webhooks_are_a_way_to_get_notified_when_something_happens_in_postiz_via_an_http_request',
'Webhooks are a way to get notified when something happens in Postiz via\n an HTTP request.'
)}
{!!data?.length && (
{t('name', 'Name')}
{t('url', 'URL')}
{t('edit', 'Edit')}
{t('delete', 'Delete')}
{data?.map((p: any) => (
{p.name}
{p.url}
))}
)}
0 && 'my-[16px]')}
>
{t('add_a_webhook', 'Add a webhook')}
);
};
const details = object().shape({
name: string().required(),
url: string().url().required(),
integrations: array(),
});
const getWebhookOptions = (t: (key: string, fallback: string) => string) => [
{
label: t('all_integrations', 'All integrations'),
value: 'all',
},
{
label: t('specific_integrations', 'Specific integrations'),
value: 'specific',
},
];
export const AddOrEditWebhook: FC<{
data?: any;
reload: () => void;
}> = (props) => {
const { data, reload } = props;
const fetch = useFetch();
const t = useT();
const options = getWebhookOptions(t);
const [allIntegrations, setAllIntegrations] = useState(
(data?.integrations?.length || 0) > 0 ? options[1] : options[0]
);
const modal = useModals();
const toast = useToaster();
const form = useForm({
resolver: yupResolver(details),
values: {
name: data?.name || '',
url: data?.url || '',
integrations: data?.integrations?.map((p: any) => p.integration) || [],
},
});
const integrations = form.watch('integrations');
const integration = useCallback(async () => {
return (await fetch('/integrations/list')).json();
}, []);
const changeIntegration = useCallback(
(e: React.ChangeEvent) => {
const findValue = options.find(
(option) => option.value === e.target.value
)!;
setAllIntegrations(findValue);
if (findValue.value === 'all') {
form.setValue('integrations', []);
}
},
[]
);
const { data: dataList, isLoading } = useSWR('integrations', integration, {
revalidateOnFocus: false,
revalidateOnReconnect: false,
revalidateIfStale: false,
revalidateOnMount: true,
refreshWhenHidden: false,
refreshWhenOffline: false,
});
const callBack = useCallback(
async (values: any) => {
await fetch('/webhooks', {
method: data?.id ? 'PUT' : 'POST',
body: JSON.stringify({
...(data?.id
? {
id: data.id,
}
: {}),
...values,
}),
});
toast.show(
data?.id
? t('webhook_updated_successfully', 'Webhook updated successfully')
: t('webhook_added_successfully', 'Webhook added successfully'),
'success'
);
modal.closeAll();
reload();
},
[data, integrations]
);
const sendTest = useCallback(async () => {
const url = form.getValues('url');
toast.show(t('webhook_sent', 'Webhook send'), 'success');
try {
await fetch(`/webhooks/send?url=${encodeURIComponent(url)}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify([
{
id: 'cm6tcts4f0005qcwit25cis26',
content: 'This is the first post to instagram',
publishDate: '2025-02-06T13:09:00.000Z',
releaseURL: 'https://facebook.com/release/release',
state: 'PUBLISHED',
integration: {
id: 'cm6s4uyou0001i2r47pxix6z1',
name: 'test',
providerIdentifier: 'instagram',
picture: 'https://uploads.gitroom.com/F6LSCD8wrrQ.jpeg',
type: 'social',
},
},
{
id: 'cm6tcts4f0005qcwit25cis26',
content: 'This is the second post to facebook',
publishDate: '2025-02-06T13:09:00.000Z',
releaseURL: 'https://facebook.com/release2/release2',
state: 'PUBLISHED',
integration: {
id: 'cm6s4uyou0001i2r47pxix6z1',
name: 'test2',
providerIdentifier: 'facebook',
picture: 'https://uploads.gitroom.com/F6LSCD8wrrQ.jpeg',
type: 'social',
},
},
]),
});
} catch (e: any) {
/** empty **/
}
}, []);
return (
);
};