import Button from '@app/components/Common/Button'; import LoadingSpinner from '@app/components/Common/LoadingSpinner'; import NotificationTypeSelector from '@app/components/NotificationTypeSelector'; import useSettings from '@app/hooks/useSettings'; import { useUser } from '@app/hooks/useUser'; import globalMessages from '@app/i18n/globalMessages'; import type { PushoverSound } from '@server/api/pushover'; import type { UserSettingsNotificationsResponse } from '@server/interfaces/api/userSettingsInterfaces'; import axios from 'axios'; import { Field, Form, Formik } from 'formik'; import { useRouter } from 'next/router'; import { defineMessages, useIntl } from 'react-intl'; import { useToasts } from 'react-toast-notifications'; import useSWR from 'swr'; import * as Yup from 'yup'; const messages = defineMessages({ pushoversettingssaved: 'Pushover notification settings saved successfully!', pushoversettingsfailed: 'Pushover notification settings failed to save.', pushoverApplicationToken: 'Application API Token', pushoverApplicationTokenTip: 'Register an application for use with {applicationTitle}', pushoverUserKey: 'User or Group Key', pushoverUserKeyTip: 'Your 30-character user or group identifier', sound: 'Notification Sound', deviceDefault: 'Device Default', validationPushoverApplicationToken: 'You must provide a valid application token', validationPushoverUserKey: 'You must provide a valid user or group key', }); const UserPushoverSettings = () => { const intl = useIntl(); const settings = useSettings(); const { addToast } = useToasts(); const router = useRouter(); const { user } = useUser({ id: Number(router.query.userId) }); const { data, error, mutate: revalidate, } = useSWR( user ? `/api/v1/user/${user?.id}/settings/notifications` : null ); const { data: soundsData } = useSWR( data?.pushoverApplicationToken ? `/api/v1/settings/notifications/pushover/sounds?token=${data.pushoverApplicationToken}` : null ); const UserNotificationsPushoverSchema = Yup.object().shape({ pushoverApplicationToken: Yup.string() .when('types', { is: (types: number) => !!types, then: Yup.string() .nullable() .required( intl.formatMessage(messages.validationPushoverApplicationToken) ), otherwise: Yup.string().nullable(), }) .matches( /^[a-z\d]{30}$/i, intl.formatMessage(messages.validationPushoverApplicationToken) ), pushoverUserKey: Yup.string() .when('types', { is: (types: number) => !!types, then: Yup.string() .nullable() .required(intl.formatMessage(messages.validationPushoverUserKey)), otherwise: Yup.string().nullable(), }) .matches( /^[a-z\d]{30}$/i, intl.formatMessage(messages.validationPushoverUserKey) ), }); if (!data && !error) { return ; } return ( { try { await axios.post(`/api/v1/user/${user?.id}/settings/notifications`, { pgpKey: data?.pgpKey, discordId: data?.discordId, pushbulletAccessToken: data?.pushbulletAccessToken, pushoverApplicationToken: values.pushoverApplicationToken, pushoverUserKey: values.pushoverUserKey, telegramChatId: data?.telegramChatId, telegramSendSilently: data?.telegramSendSilently, notificationTypes: { pushover: values.types, }, }); addToast(intl.formatMessage(messages.pushoversettingssaved), { appearance: 'success', autoDismiss: true, }); } catch (e) { addToast(intl.formatMessage(messages.pushoversettingsfailed), { appearance: 'error', autoDismiss: true, }); } finally { revalidate(); } }} > {({ errors, touched, isSubmitting, isValid, values, setFieldValue, setFieldTouched, }) => { return ( {intl.formatMessage(messages.pushoverApplicationToken)} * {intl.formatMessage(messages.pushoverApplicationTokenTip, { ApplicationRegistrationLink: (msg: React.ReactNode) => ( {msg} ), applicationTitle: settings.currentSettings.applicationTitle, })} {errors.pushoverApplicationToken && touched.pushoverApplicationToken && ( {errors.pushoverApplicationToken} )} {intl.formatMessage(messages.pushoverUserKey)} {intl.formatMessage(messages.pushoverUserKeyTip, { UsersGroupsLink: (msg: React.ReactNode) => ( {msg} ), })} {errors.pushoverUserKey && touched.pushoverUserKey && typeof errors.pushoverUserKey === 'string' && ( {errors.pushoverUserKey} )} {intl.formatMessage(messages.sound)} {intl.formatMessage(messages.deviceDefault)} {soundsData?.map((sound, index) => ( {sound.description} ))} { setFieldValue('types', newTypes); setFieldTouched('types'); }} error={ errors.types && touched.types ? (errors.types as string) : undefined } /> {isSubmitting ? intl.formatMessage(globalMessages.saving) : intl.formatMessage(globalMessages.save)} ); }} ); }; export default UserPushoverSettings;