From aad2fc4103907f6fb388e589c980af51bd9ba9df Mon Sep 17 00:00:00 2001 From: Daniel Bisgrove Date: Fri, 30 Aug 2024 14:33:52 -0400 Subject: [PATCH] Updating the useGetPledgeOrDonation hook to return a object and use a useMemo and Making hook take one object instead of 3 arguments --- .../Flow/ContactFlowRow/ContactFlowRow.tsx | 10 +- .../Appeal/List/ContactRow/ContactRow.tsx | 14 +- .../AmountAndFrequency/AmountAndFrequency.tsx | 27 ++-- .../useGetPledgeOrDonation.test.ts | 97 ++++++++------ .../useGetPledgeOrDonation.ts | 125 ++++++++++++------ 5 files changed, 172 insertions(+), 101 deletions(-) diff --git a/src/components/Tool/Appeal/Flow/ContactFlowRow/ContactFlowRow.tsx b/src/components/Tool/Appeal/Flow/ContactFlowRow/ContactFlowRow.tsx index 8f6976d18..0d655bee2 100644 --- a/src/components/Tool/Appeal/Flow/ContactFlowRow/ContactFlowRow.tsx +++ b/src/components/Tool/Appeal/Flow/ContactFlowRow/ContactFlowRow.tsx @@ -22,7 +22,6 @@ import { import { StarContactIconButton } from 'src/components/Contacts/StarContactIconButton/StarContactIconButton'; import { useGetPledgeOrDonation } from 'src/components/Tool/Appeal/Shared/useGetPledgeOrDonation/useGetPledgeOrDonation'; import { StatusEnum } from 'src/graphql/types.generated'; -import { useLocale } from 'src/hooks/useLocale'; import theme from 'src/theme'; import { getLocalizedContactStatus } from 'src/utils/functions/getLocalizedContactStatus'; import { @@ -94,7 +93,6 @@ export const ContactFlowRow: React.FC = ({ }) => { const { id, name, starred } = contact; const { t } = useTranslation(); - const locale = useLocale(); const { appealId, isRowChecked: isChecked, @@ -104,7 +102,7 @@ export const ContactFlowRow: React.FC = ({ const [deletePledgeModalOpen, setDeletePledgeModalOpen] = useState(false); const { pledgeValues, amountAndFrequency, pledgeDonations, pledgeOverdue } = - useGetPledgeOrDonation(appealStatus, contact, appealId ?? '', locale); + useGetPledgeOrDonation({ appealStatus, contact, appealId: appealId ?? '' }); const [{ isDragging }, drag, preview] = useDrag( () => ({ @@ -188,7 +186,11 @@ export const ContactFlowRow: React.FC = ({ {appealStatus === AppealStatusEnum.Processed && pledgeDonations?.map((donation, idx) => ( - {amountAndFrequency} {donation} + {' '} + {donation} ))} diff --git a/src/components/Tool/Appeal/List/ContactRow/ContactRow.tsx b/src/components/Tool/Appeal/List/ContactRow/ContactRow.tsx index 13340e5d6..4af3ceee3 100644 --- a/src/components/Tool/Appeal/List/ContactRow/ContactRow.tsx +++ b/src/components/Tool/Appeal/List/ContactRow/ContactRow.tsx @@ -19,7 +19,6 @@ import { } from 'src/components/Contacts/ContactRow/ContactRow'; import { preloadContactsRightPanel } from 'src/components/Contacts/ContactsRightPanel/DynamicContactsRightPanel'; import { useGetPledgeOrDonation } from 'src/components/Tool/Appeal/Shared/useGetPledgeOrDonation/useGetPledgeOrDonation'; -import { useLocale } from 'src/hooks/useLocale'; import theme from 'src/theme'; import { AppealStatusEnum, @@ -79,7 +78,6 @@ export const ContactRow: React.FC = ({ setContactFocus: onContactSelected, toggleSelectionById: onContactCheckToggle, } = React.useContext(AppealsContext) as AppealsType; - const locale = useLocale(); const [createPledgeModalOpen, setPledgeModalOpen] = useState(false); const [deletePledgeModalOpen, setDeletePledgeModalOpen] = useState(false); const [addExcludedContactModalOpen, setAddExcludedContactModalOpen] = @@ -93,7 +91,11 @@ export const ContactRow: React.FC = ({ const { id: contactId, name } = contact; const { pledgeValues, amountAndFrequency, pledgeDonations, pledgeOverdue } = - useGetPledgeOrDonation(appealStatus, contact, appealId ?? '', locale); + useGetPledgeOrDonation({ + appealStatus, + contact, + appealId: appealId ?? '', + }); const handleCreatePledge = () => { setPledgeModalOpen(true); @@ -200,7 +202,11 @@ export const ContactRow: React.FC = ({ {appealStatus === AppealStatusEnum.Processed && pledgeDonations?.map((donation, idx) => ( - {amountAndFrequency} {donation} + + {donation} ))} diff --git a/src/components/Tool/Appeal/Shared/AmountAndFrequency/AmountAndFrequency.tsx b/src/components/Tool/Appeal/Shared/AmountAndFrequency/AmountAndFrequency.tsx index 810c59117..972174b3d 100644 --- a/src/components/Tool/Appeal/Shared/AmountAndFrequency/AmountAndFrequency.tsx +++ b/src/components/Tool/Appeal/Shared/AmountAndFrequency/AmountAndFrequency.tsx @@ -2,21 +2,20 @@ import { UseGetPledgeOrDonation } from 'src/components/Tool/Appeal/Shared/useGet import theme from 'src/theme'; export const AmountAndFrequency: React.FC< - Omit + Pick > = ({ amountAndFrequency, pledgeOverdue }) => { - const amount = amountAndFrequency?.length ? amountAndFrequency[0] : ''; - const dateString = - amountAndFrequency?.length === 2 ? ( - - {amountAndFrequency[1]} - - ) : ( - '' - ); + const amount = amountAndFrequency?.amount ?? ''; + const dateString = amountAndFrequency?.dateOrFrequency ? ( + + {amountAndFrequency?.dateOrFrequency} + + ) : ( + '' + ); return ( <> {amount} {dateString} diff --git a/src/components/Tool/Appeal/Shared/useGetPledgeOrDonation/useGetPledgeOrDonation.test.ts b/src/components/Tool/Appeal/Shared/useGetPledgeOrDonation/useGetPledgeOrDonation.test.ts index ca7c9be91..27f30fbff 100644 --- a/src/components/Tool/Appeal/Shared/useGetPledgeOrDonation/useGetPledgeOrDonation.test.ts +++ b/src/components/Tool/Appeal/Shared/useGetPledgeOrDonation/useGetPledgeOrDonation.test.ts @@ -7,10 +7,17 @@ const appealId = 'appealId'; describe('useGetPledgeOrDonation', () => { it('returns the normal donation amount when in appeal status Asked', () => { const { result } = renderHook(() => - useGetPledgeOrDonation(AppealStatusEnum.Asked, defaultContact, appealId), + useGetPledgeOrDonation({ + appealStatus: AppealStatusEnum.Asked, + contact: defaultContact, + appealId: appealId, + }), ); - expect(result.current.amountAndFrequency).toEqual(['CA$500', 'Monthly']); + expect(result.current.amountAndFrequency).toEqual({ + amount: 'CA$500', + dateOrFrequency: 'Monthly', + }); expect(result.current.pledgeDonations).toBeNull(); expect(result.current.pledgeValues).toBeUndefined(); @@ -18,14 +25,17 @@ describe('useGetPledgeOrDonation', () => { it('returns the normal donation amount when in appeal status Excluded', () => { const { result } = renderHook(() => - useGetPledgeOrDonation( - AppealStatusEnum.Excluded, - defaultContact, - appealId, - ), + useGetPledgeOrDonation({ + appealStatus: AppealStatusEnum.Excluded, + contact: defaultContact, + appealId: appealId, + }), ); - expect(result.current.amountAndFrequency).toEqual(['CA$500', 'Monthly']); + expect(result.current.amountAndFrequency).toEqual({ + amount: 'CA$500', + dateOrFrequency: 'Monthly', + }); expect(result.current.pledgeDonations).toBeNull(); expect(result.current.pledgeValues).toBeUndefined(); @@ -33,17 +43,17 @@ describe('useGetPledgeOrDonation', () => { it('returns the pledge when in appeal status Committed', () => { const { result } = renderHook(() => - useGetPledgeOrDonation( - AppealStatusEnum.NotReceived, - defaultContact, - appealId, - ), + useGetPledgeOrDonation({ + appealStatus: AppealStatusEnum.NotReceived, + contact: defaultContact, + appealId: appealId, + }), ); - expect(result.current.amountAndFrequency).toEqual([ - '$3,000', - '(Aug 8, 2024)', - ]); + expect(result.current.amountAndFrequency).toEqual({ + amount: '$3,000', + dateOrFrequency: '(Aug 8, 2024)', + }); expect(result.current.pledgeDonations).toBeNull(); expect(result.current.pledgeValues).toEqual({ @@ -57,17 +67,17 @@ describe('useGetPledgeOrDonation', () => { it('returns the pledge when in appeal status Received', () => { const { result } = renderHook(() => - useGetPledgeOrDonation( - AppealStatusEnum.ReceivedNotProcessed, - defaultContact, - appealId, - ), + useGetPledgeOrDonation({ + appealStatus: AppealStatusEnum.ReceivedNotProcessed, + contact: defaultContact, + appealId: appealId, + }), ); - expect(result.current.amountAndFrequency).toEqual([ - '$3,000', - '(Aug 8, 2024)', - ]); + expect(result.current.amountAndFrequency).toEqual({ + amount: '$3,000', + dateOrFrequency: '(Aug 8, 2024)', + }); expect(result.current.pledgeDonations).toBeNull(); expect(result.current.pledgeValues).toEqual({ @@ -81,14 +91,17 @@ describe('useGetPledgeOrDonation', () => { it('returns the donations to appeal when in appeal status Given', () => { const { result } = renderHook(() => - useGetPledgeOrDonation( - AppealStatusEnum.Processed, - defaultContact, - appealId, - ), + useGetPledgeOrDonation({ + appealStatus: AppealStatusEnum.Processed, + contact: defaultContact, + appealId: appealId, + }), ); - expect(result.current.amountAndFrequency).toEqual(['$3,000']); + expect(result.current.amountAndFrequency).toEqual({ + amount: '$3,000', + dateOrFrequency: '', + }); expect(result.current.pledgeDonations).toEqual(['($50) (Jun 25, 2019)']); expect(result.current.pledgeValues).toEqual({ @@ -117,12 +130,16 @@ describe('useGetPledgeOrDonation', () => { ], }; const { result } = renderHook(() => - useGetPledgeOrDonation(AppealStatusEnum.NotReceived, contact, appealId), + useGetPledgeOrDonation({ + appealStatus: AppealStatusEnum.NotReceived, + contact: contact, + appealId: appealId, + }), ); - expect(result.current.amountAndFrequency).toEqual([ - '$3,000', - '(Aug 8, 2001)', - ]); + expect(result.current.amountAndFrequency).toEqual({ + amount: '$3,000', + dateOrFrequency: '(Aug 8, 2001)', + }); expect(result.current.pledgeOverdue).toEqual(true); }); @@ -147,7 +164,11 @@ describe('useGetPledgeOrDonation', () => { }, }; const { result } = renderHook(() => - useGetPledgeOrDonation(AppealStatusEnum.Processed, contact, appealId), + useGetPledgeOrDonation({ + appealStatus: AppealStatusEnum.Processed, + contact: contact, + appealId: appealId, + }), ); expect(result.current.pledgeDonations).toEqual(['($50) (Jun 25, 2001)']); expect(result.current.pledgeOverdue).toEqual(false); diff --git a/src/components/Tool/Appeal/Shared/useGetPledgeOrDonation/useGetPledgeOrDonation.ts b/src/components/Tool/Appeal/Shared/useGetPledgeOrDonation/useGetPledgeOrDonation.ts index c728b867a..e49c90183 100644 --- a/src/components/Tool/Appeal/Shared/useGetPledgeOrDonation/useGetPledgeOrDonation.ts +++ b/src/components/Tool/Appeal/Shared/useGetPledgeOrDonation/useGetPledgeOrDonation.ts @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import { useMemo } from 'react'; import { TFunction } from 'i18next'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; @@ -29,7 +29,7 @@ const formatPledgeOrDonation = ({ const pledgeOrDonationAmount = amount && currency ? currencyFormat(amount, currency, locale) - : amount || currencyFormat(0, currency, locale); + : amount?.toString() || currencyFormat(0, currency, locale); let pledgeOverdue = false; if ( @@ -54,7 +54,7 @@ const formatPledgeOrDonation = ({ '' : dateOrFrequency ? dateFormat(DateTime.fromISO(dateOrFrequency), locale) - : null; + : ''; return { amount: pledgeOrDonationAmount, dateOrFrequency: pledgeOrDonationDate, @@ -62,27 +62,38 @@ const formatPledgeOrDonation = ({ }; }; +interface AmountAndFrequency { + amount: string; + dateOrFrequency?: string; +} export interface UseGetPledgeOrDonation { pledgeValues: AppealContactInfoFragment['pledges'][0] | undefined; - amountAndFrequency: string[] | undefined; + amountAndFrequency: AmountAndFrequency | null; pledgeDonations: string[] | null; pledgeOverdue: boolean; } -// The return value doesn't change until `delay` milliseconds have elapsed since the last time `value` changed + +interface UseGetPledgeOrDonationProps { + appealStatus: AppealStatusEnum; + contact: AppealContactInfoFragment; + appealId: string; +} + export const useGetPledgeOrDonation = ( - appealStatus: AppealStatusEnum, - contact: AppealContactInfoFragment, - appealId: string, + props: UseGetPledgeOrDonationProps, ): UseGetPledgeOrDonation => { const locale = useLocale(); const { t } = useTranslation(); - const [pledgeValues, setPledgeValues] = - useState(); - const [amountAndFrequency, setAmountAndFrequency] = useState(); - const [pledgeDonations, setPledgeDonations] = useState(null); - const [pledgeOverdue, setPledgeOverdue] = useState(false); + const { appealStatus, contact, appealId } = props; + + const defaultValues = { + amountAndFrequency: null, + pledgeValues: undefined, + pledgeOverdue: false, + pledgeDonations: null, + }; - useEffect(() => { + const pledgeOrDonation = useMemo(() => { const { pledgeAmount, pledgeCurrency, @@ -103,8 +114,14 @@ export const useGetPledgeOrDonation = ( locale, t, }); - setAmountAndFrequency([`${amount}`, `${dateOrFrequency}`]); - setPledgeValues(undefined); + + return { + ...defaultValues, + amountAndFrequency: { + amount, + dateOrFrequency, + }, + }; } else if ( appealStatus === AppealStatusEnum.NotReceived || appealStatus === AppealStatusEnum.ReceivedNotProcessed @@ -113,31 +130,50 @@ export const useGetPledgeOrDonation = ( (pledge) => pledge.appeal.id === appealId, ); - if (appealPledge) { - const { - amount, - dateOrFrequency, - pledgeOverdue: overdue, - } = formatPledgeOrDonation({ - amount: appealPledge?.amount, - currency: appealPledge.amountCurrency, - appealStatus, - dateOrFrequency: appealPledge.expectedDate, - locale, - t, - }); - - setPledgeValues(appealPledge); - setAmountAndFrequency([`${amount}`, `(${dateOrFrequency})`]); - setPledgeOverdue(overdue); - } else { - setAmountAndFrequency([`${currencyFormat(0, 'USD', locale)}`]); + if (!appealPledge) { + return { + ...defaultValues, + amountAndFrequency: { + amount: currencyFormat(0, 'USD', locale), + dateOrFrequency: '', + }, + }; } + + const { + amount, + dateOrFrequency, + pledgeOverdue: overdue, + } = formatPledgeOrDonation({ + amount: appealPledge?.amount, + currency: appealPledge.amountCurrency, + appealStatus, + dateOrFrequency: appealPledge.expectedDate, + locale, + t, + }); + + return { + ...defaultValues, + amountAndFrequency: { + amount, + dateOrFrequency: `(${dateOrFrequency})`, + }, + pledgeValues: appealPledge, + pledgeOverdue: overdue, + }; } else if (appealStatus === AppealStatusEnum.Processed) { const appealPledge = pledges?.find( (pledge) => pledge.appeal.id === appealId, ); + const amountAndFrequency = { + amount: currencyFormat(0, 'USD', locale), + dateOrFrequency: '', + }; + let pledgeValues: AppealContactInfoFragment['pledges'][0] | undefined = + undefined; + if (appealPledge) { const { amount } = formatPledgeOrDonation({ amount: appealPledge?.amount, @@ -146,10 +182,8 @@ export const useGetPledgeOrDonation = ( locale, t, }); - setPledgeValues(appealPledge); - setAmountAndFrequency([`${amount}`]); - } else { - setAmountAndFrequency([`${currencyFormat(0, 'USD', locale)}`]); + amountAndFrequency.amount = amount; + pledgeValues = appealPledge; } // Currently we grab all the donations and filter them by the appeal id @@ -176,9 +210,18 @@ export const useGetPledgeOrDonation = ( return `(${donationAmount}) (${donationDate})`; }); - setPledgeDonations(givenDonations); + return { + ...defaultValues, + amountAndFrequency, + pledgeValues, + pledgeDonations: givenDonations, + }; } }, [appealStatus, contact, locale]); - return { pledgeValues, amountAndFrequency, pledgeDonations, pledgeOverdue }; + if (pledgeOrDonation) { + return pledgeOrDonation; + } else { + return defaultValues; + } };