import {Fragment} from 'react'; import styled from '@emotion/styled'; import moment from 'moment-timezone'; import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator'; import {DateTime} from 'sentry/components/dateTime'; import EmptyMessage from 'sentry/components/emptyMessage'; import LoadingError from 'sentry/components/loadingError'; import LoadingIndicator from 'sentry/components/loadingIndicator'; import Panel from 'sentry/components/panels/panel'; import PanelBody from 'sentry/components/panels/panelBody'; import PanelHeader from 'sentry/components/panels/panelHeader'; import PanelItem from 'sentry/components/panels/panelItem'; import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle'; import Switch from 'sentry/components/switchButton'; import {IconToggle} from 'sentry/icons'; import {t, tct} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import { setApiQueryData, useApiQuery, useMutation, useQueryClient, } from 'sentry/utils/queryClient'; import useApi from 'sentry/utils/useApi'; import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader'; import TextBlock from 'sentry/views/settings/components/text/textBlock'; const ENDPOINT = '/users/me/subscriptions/'; export type Subscription = { email: string; listDescription: string; listId: number; listName: string; subscribed: boolean; subscribedDate: string | null; unsubscribedDate: string | null; }; function AccountSubscriptions() { const { data: subscriptions = [], isPending, isError, refetch, } = useApiQuery([ENDPOINT], { staleTime: 2 * 60 * 1000, }); const queryClient = useQueryClient(); const api = useApi(); const {mutate: updateSubscription} = useMutation({ mutationFn: (data: Subscription) => api.requestPromise(ENDPOINT, { method: 'PUT', data, }), onSuccess: (_resp, subscription: Subscription) => { addSuccessMessage( `${subscription.subscribed ? 'Subscribed' : 'Unsubscribed'} to ${subscription.listName}` ); // Update the subscription in the list setApiQueryData(queryClient, [ENDPOINT], subs => { return subs.map(sub => { if (sub.listId === subscription.listId) { return subscription; } return sub; }); }); }, onError: (subscription: Subscription) => { if (subscription) { addErrorMessage( `Unable to ${subscription.subscribed ? '' : 'un'}subscribe to ${subscription.listName}` ); } else { addErrorMessage('An unknown error occurred, please try again later.'); } }, }); if (isPending) { return ; } if (isError) { return ( { refetch(); }} /> ); } const subGroups = Object.entries( subscriptions.reduce>((acc, sub) => { (acc[sub.email] = acc[sub.email] || []).push(sub); return acc; }, {}) ); subGroups.sort(([a], [b]) => a[0]?.localeCompare(b[0])); const handleToggle = (subscription: Subscription) => { const subscribed = !subscription.subscribed; updateSubscription({ ...subscription, subscribed, }); }; const subscriptionText = t('Subscriptions'); return (
{t(`Sentry is committed to respecting your inbox. Our goal is to provide useful content and resources that make fixing errors less painful. Enjoyable even.`)} {t(`As part of our compliance with the EU’s General Data Protection Regulation (GDPR), starting on 25 May 2018, we’ll only email you according to the marketing categories to which you’ve explicitly opted-in.`)} {subscriptions?.length ? (
{t('Subscription')} {subGroups.map(([email, subs]) => ( {subGroups.length > 1 && ( {t('Subscriptions for %s', email)} )} {subs .sort((a, b) => a.listId - b.listId) .map((subscription, i) => ( {subscription.listName} {subscription.listDescription && ( {subscription.listDescription} )} {subscription.subscribed ? (
{tct('[email] on [date]', { email: subscription.email, date: ( ), })}
) : ( {t('Not currently subscribed')} )}
handleToggle(subscription)} />
))}
))}
) : ( {t("There's no subscription backend present.")} )}
{t(`We’re applying GDPR consent and privacy policies to all Sentry contacts, regardless of location. You’ll be able to manage your subscriptions here and from an Unsubscribe link in the footer of all marketing emails.`)} {tct( 'Please contact [email:learn@sentry.io] with any questions or suggestions.', {email: } )}
); } const Heading = styled(PanelItem)` display: grid; grid-template-columns: max-content 1fr; gap: ${space(1)}; align-items: center; font-size: ${p => p.theme.fontSizeMedium}; padding: ${space(1.5)} ${space(2)}; background: ${p => p.theme.backgroundSecondary}; color: ${p => p.theme.subText}; `; const SubscriptionDetails = styled('label')` font-weight: initial; padding-right: ${space(2)}; width: 85%; @media (min-width: ${p => p.theme.breakpoints.small}) { width: 75%; } @media (min-width: ${p => p.theme.breakpoints.large}) { width: 50%; } `; const SubscriptionName = styled('div')` font-size: ${p => p.theme.fontSizeMedium}; `; const Description = styled('div')` font-size: ${p => p.theme.fontSizeSmall}; color: ${p => p.theme.subText}; margin-top: ${space(0.5)}; `; const SubscribedDescription = styled(Description)` color: ${p => p.theme.subText}; `; export default AccountSubscriptions;