client/components/mma/accountoverview/updateAmount/UpdateAmount.tsx (100 lines of code) (raw):

import { css } from '@emotion/react'; import { palette, space } from '@guardian/source/foundations'; import { capitalize } from 'lodash'; import type { Dispatch, SetStateAction } from 'react'; import { useState } from 'react'; import { parseDate } from '../../../../../shared/dates'; import type { PaidSubscriptionPlan } from '../../../../../shared/productResponse'; import { augmentBillingPeriod } from '../../../../../shared/productResponse'; import type { ProductType } from '../../../../../shared/productTypes'; import { SuccessMessage } from '../../delivery/address/DeliveryAddressConfirmation'; import { Button } from '../../shared/Buttons'; import { ProductDescriptionListTable } from '../../shared/ProductDescriptionListTable'; import { ContributionUpdateAmountForm } from './ContributionUpdateAmountForm'; import { SupporterPlusUpdateAmountForm } from './SupporterPlusUpdateAmountForm'; interface UpdateAmountProps { subscriptionId: string; mainPlan: PaidSubscriptionPlan; productType: ProductType; nextPaymentDate: string | null; amountUpdateStateChange: Dispatch<SetStateAction<number | null>>; isTestUser: boolean; } export const UpdateAmount = (props: UpdateAmountProps) => { enum Status { OVERVIEW, EDITING, CONFIRMED, } const [status, setStatus] = useState<Status>(Status.OVERVIEW); const [confirmedAmount, setConfirmedAmount] = useState<number | null>(null); const mainPlan = props.mainPlan; const currentAmount = confirmedAmount || mainPlan.price / 100; if (status === Status.EDITING) { return props.productType.productType === 'supporterplus' ? ( <SupporterPlusUpdateAmountForm {...props} currentAmount={currentAmount} onUpdateConfirmed={(updatedAmount) => { setConfirmedAmount(updatedAmount); props.amountUpdateStateChange(updatedAmount); setStatus(Status.CONFIRMED); }} /> ) : ( <ContributionUpdateAmountForm {...props} currentAmount={currentAmount} mode="MANAGE" onUpdateConfirmed={(updatedAmount) => { setConfirmedAmount(updatedAmount); props.amountUpdateStateChange(updatedAmount); setStatus(Status.CONFIRMED); }} /> ); } return ( <> {status === Status.CONFIRMED && ( <SuccessMessage message={`We have successfully updated the amount of your support. ${ props.nextPaymentDate && `This amount will be taken on ${parseDate( props.nextPaymentDate, ).dateStr()}. ` }Thank you for supporting the Guardian.`} additionalCss={css` margin-bottom: ${space[5]}px; `} /> )} <ProductDescriptionListTable borderColour={palette.neutral[86]} content={[ { title: 'Supporter ID', value: props.subscriptionId, }, { title: `${capitalize( augmentBillingPeriod(props.mainPlan.billingPeriod), )} amount`, value: `${ props.mainPlan.currency }${currentAmount.toFixed(2)} ${ props.mainPlan.currencyISO }`, }, ]} /> <Button colour={palette.brand[800]} textColour={palette.brand[400]} fontWeight="bold" text="Change amount" onClick={() => { setStatus(Status.EDITING); }} /> </> ); };