client/components/mma/holiday/CollatedCredits.tsx (52 lines of code) (raw):

import { DATE_FNS_LONG_OUTPUT_FORMAT } from '../../../../shared/dates'; import type { HolidayStopDetail } from './HolidayStopApi'; type CollatedCreditByInvoiceDate = Record<string, number>; const reduceCreditCallback = ( accumulator: CollatedCreditByInvoiceDate | null, currentValue: HolidayStopDetail, ) => { const credit = currentValue.actualPrice || currentValue.estimatedPrice; if (accumulator && currentValue.invoiceDate && credit) { const invoiceDateAsString = currentValue.invoiceDate.dateStr( DATE_FNS_LONG_OUTPUT_FORMAT, ); return { ...accumulator, [invoiceDateAsString]: credit + (accumulator[invoiceDateAsString] || 0), }; } return null; // if we don't have credits and dates for EVERY entry we shouldn't show anything }; interface CollatedCreditsProps { publicationsImpacted: HolidayStopDetail[]; currency?: string; withBullet?: true; } export const CollatedCredits = (props: CollatedCreditsProps) => { const collatedCreditsByInvoiceDate: CollatedCreditByInvoiceDate | null = props.publicationsImpacted.reduce( reduceCreditCallback, {} as CollatedCreditByInvoiceDate, ); return ( <div> {collatedCreditsByInvoiceDate ? Object.keys(collatedCreditsByInvoiceDate).map( (invoiceDateString, index) => ( <div key={`cc-${index}`}> {props.withBullet && '- '} <strong> {props.currency} {Math.abs( collatedCreditsByInvoiceDate[ invoiceDateString ], ).toFixed(2)} </strong>{' '} off your {invoiceDateString} payment </div> ), ) : 'Unavailable at this time.'} </div> ); };