src/components/NewsletterCtaButton.tsx (123 lines of code) (raw):

import React, { useState } from 'react'; import { css, SerializedStyles, ThemeProvider } from '@emotion/react'; import { Button, buttonThemeBrandAlt, Link } from '@guardian/source/react-components'; import { LoadingDots } from '../components/CtaLoadingDotsAnimation'; import type { TrackClick } from '../utils/tracking'; import type { NewsletterSubscribeCallback } from '../types/dcrTypes'; import type { InteractiveButtonStatus } from '../logic/types'; import type { NewsletterButtonColorStyles } from '../styles/colorData'; import { neutral, textEgyptianBold17 } from '@guardian/source/foundations'; type SignUpButtonProps = { buttonStyles: Record<string, SerializedStyles>; newsletterCta: string; onClick: () => void; }; const SignUpButton = ({ buttonStyles, newsletterCta, onClick }: SignUpButtonProps) => ( <ThemeProvider theme={buttonThemeBrandAlt}> <Button cssOverrides={buttonStyles.button} onClick={onClick}> {newsletterCta} </Button> </ThemeProvider> ); interface NewsletterCtaButtonProps { subscribeToNewsletter: NewsletterSubscribeCallback; newsletterId: string; ophanComponentId?: string; trackClick: TrackClick; colors?: NewsletterButtonColorStyles; newsletterCta: string; } export const NewsletterCtaButton: React.FC<NewsletterCtaButtonProps> = ( props: NewsletterCtaButtonProps, ) => { const { subscribeToNewsletter, newsletterId, ophanComponentId, trackClick, colors = defaultNewsletterCtaButtonColors, newsletterCta, } = props; const styles = getButtonStyles(colors); const [subscribeClickStatus, setSubscribeClickStatus] = useState<InteractiveButtonStatus>('DEFAULT'); const onSignUpClick = () => { setSubscribeClickStatus('IN_PROGRESS'); const internalButtonId = 0; trackClick({ internalButtonId, ophanComponentId: ophanComponentId as string, }); subscribeToNewsletter(newsletterId as string) .then(() => setSubscribeClickStatus('SUCCESS')) .catch(() => { setSubscribeClickStatus('FAILURE'); }); }; switch (subscribeClickStatus) { case 'DEFAULT': return ( <SignUpButton buttonStyles={styles} onClick={onSignUpClick} newsletterCta={newsletterCta} /> ); case 'FAILURE': return ( <> <div css={styles.errorText}> There was an error signing up to the newsletter. Please try again </div> <SignUpButton buttonStyles={styles} onClick={onSignUpClick} newsletterCta={newsletterCta} /> </> ); case 'IN_PROGRESS': return <LoadingDots styleReminderAnimation={colors.styleReminderAnimation} />; case 'SUCCESS': return ( <> <div css={styles.thankYouText}>Thank you.</div> <div> <Link href="https://manage.theguardian.com/email-prefs" priority="primary"> Manage my newsletters </Link> <span css={styles.newslettersLinkPeriod}>.</span> </div> </> ); } }; export const defaultNewsletterCtaButtonColors: NewsletterButtonColorStyles = { styleNewsletterButton: '#ffffff', styleNewsletterButtonBackground: '#c70000', styleNewsletterButtonHover: '#c70000', styleReminderAnimation: '#707070', }; const getButtonStyles = (styles: NewsletterButtonColorStyles) => { return { button: css` background-color: ${styles.styleNewsletterButtonBackground} !important; color: ${styles.styleNewsletterButton} !important; &:hover { background-color: ${styles.styleNewsletterButtonHover} !important; } `, thankYouText: css` ${textEgyptianBold17}; color: ${neutral[0]}; `, errorText: css` ${textEgyptianBold17}; color: ${neutral[0]}; margin-bottom: 16px; `, newslettersLinkPeriod: css` color: ${neutral[0]}; `, }; };