client/components/mma/cancel/cancellationContributionReminder.tsx (153 lines of code) (raw):
import { css } from '@emotion/react';
import { space } from '@guardian/source/foundations';
import { Button, Radio, RadioGroup } from '@guardian/source/react-components';
import { useEffect, useState } from 'react';
import type * as React from 'react';
import { useNavigate } from 'react-router';
import {
buttonCentredCss,
stackedButtonLayoutCss,
} from '../../../styles/ButtonStyles';
import { trackEventInOphanOnly } from '../../../utilities/analytics';
import { getGeoLocation } from '../../../utilities/geolocation';
const containerStyles = css`
padding-bottom: ${space[24]}px;
`;
const setReminderContainerStyles = css`
& > * + * {
margin-top: ${space[5]}px;
}
`;
const formContainerStyles = css`
& > * + * {
margin-top: ${space[6]}px;
}
`;
interface ReminderSignup {
reminderPeriod: string;
reminderOption: string;
}
interface ReminderChoice {
signup: ReminderSignup;
label: string;
thankYouMessage: string;
}
const REMINDER_ENDPOINT = '/api/reminders/create';
const REMINDER_PLATFORM = 'MMA';
const REMINDER_STAGE = 'WINBACK';
const REMINDER_COMPONENT = 'CANCELLATION';
const getReminderPeriod = (date: Date) => {
const year = date.getFullYear();
const month = date.getMonth() + 1; // javascript dates run from 0-11, we want 1-12
const paddedMonth = month.toString().padStart(2, '0');
return `${year}-${paddedMonth}-01`;
};
const getReminderOption = (monthsUntilDate: number) =>
`${monthsUntilDate}-months`;
const getDefaultLabel = (date: Date, monthsUntilDate: number, now: Date) => {
const month = date.toLocaleDateString('default', { month: 'long' });
const year =
now.getFullYear() === date.getFullYear()
? ''
: ` ${date.getFullYear()}`;
return `in ${monthsUntilDate} months (${month}${year})`;
};
const getDefaultThankYouMessage = (date: Date) =>
date.toLocaleDateString('default', {
month: 'long',
});
const getDefaultReminderChoice = (monthsUntilDate: number): ReminderChoice => {
const now = new Date();
const date = new Date(now.getFullYear(), now.getMonth() + monthsUntilDate);
return {
label: getDefaultLabel(date, monthsUntilDate, now),
thankYouMessage: getDefaultThankYouMessage(date),
signup: {
reminderPeriod: getReminderPeriod(date),
reminderOption: getReminderOption(monthsUntilDate),
},
};
};
const getDefaultReminderChoices = (): ReminderChoice[] => [
getDefaultReminderChoice(3),
getDefaultReminderChoice(6),
getDefaultReminderChoice(9),
];
export const CancellationContributionReminder: React.FC = () => {
const [selectedChoiceIndex, setSelectedChoiceIndex] = useState(0);
const [hasSetReminder, setHasSetReminder] = useState(false);
const navigate = useNavigate();
const email = window.guardian.identityDetails.email;
const reminderChoices = getDefaultReminderChoices();
const selectedChoice = reminderChoices[selectedChoiceIndex];
const setReminder = () =>
fetch(REMINDER_ENDPOINT, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email,
country: getGeoLocation(),
reminderPlatform: REMINDER_PLATFORM,
reminderComponent: REMINDER_COMPONENT,
reminderStage: REMINDER_STAGE,
...selectedChoice.signup,
}),
});
const onSubmit = () => {
trackEventInOphanOnly({
eventCategory: 'cancellation_flow',
eventAction: 'click',
eventLabel: `set_reminder__${selectedChoice.signup.reminderOption}`,
});
setReminder();
setHasSetReminder(true);
};
useEffect(() => {
trackEventInOphanOnly({
eventCategory: 'cancellation_flow',
eventAction: 'view',
eventLabel: `set_reminder`,
});
}, []);
return (
<div css={containerStyles}>
{hasSetReminder ? (
<p>
Thank you for setting up support reminder. We will be in
touch in {selectedChoice.thankYouMessage}, so look out for a
message from the Guardian in your inbox.
</p>
) : (
<div css={setReminderContainerStyles}>
<p>
We can invite you to support our journalism again at a
later date, when it might suit you better. This will be
no more than two emails, with no obligation to give.
</p>
<div css={formContainerStyles}>
<RadioGroup
name="reminder"
label="I'd like to be reminded in:"
>
{reminderChoices.map((choice, index) => (
<Radio
key={`reminderRadio${index}`}
value={`${index}`}
label={choice.label}
checked={selectedChoiceIndex === index}
onChange={() =>
setSelectedChoiceIndex(index)
}
/>
))}
</RadioGroup>
<div css={stackedButtonLayoutCss}>
<Button
onClick={onSubmit}
cssOverrides={buttonCentredCss}
>
Set my reminder
</Button>
<Button
priority="tertiary"
onClick={() => navigate('/')}
cssOverrides={buttonCentredCss}
>
Return to your account
</Button>
</div>
</div>
</div>
)}
</div>
);
};