Skip to content

Commit

Permalink
Moving logic for determining pledge, commitment and normal donations …
Browse files Browse the repository at this point in the history
…into useHook
  • Loading branch information
dr-bizz committed Aug 30, 2024
1 parent c09143f commit 660f33e
Show file tree
Hide file tree
Showing 3 changed files with 268 additions and 145 deletions.
150 changes: 5 additions & 145 deletions src/components/Tool/Appeal/List/ContactRow/ContactRow.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React, { useState } from 'react';
import AddIcon from '@mui/icons-material/Add';
import DeleteIcon from '@mui/icons-material/Delete';
import EditIcon from '@mui/icons-material/Edit';
Expand All @@ -13,19 +13,14 @@ import {
} from '@mui/material';
import { styled } from '@mui/material/styles';
import clsx from 'clsx';
import { TFunction } from 'i18next';
import { DateTime } from 'luxon';
import { useTranslation } from 'react-i18next';
import {
ListItemButton,
StyledCheckbox,
} from 'src/components/Contacts/ContactRow/ContactRow';
import { preloadContactsRightPanel } from 'src/components/Contacts/ContactsRightPanel/DynamicContactsRightPanel';
import { PledgeFrequencyEnum } from 'src/graphql/types.generated';
import { useGetPledgeOrDonation } from 'src/hooks/useGetPledgeOrDonation';
import { useLocale } from 'src/hooks/useLocale';
import { currencyFormat, dateFormat } from 'src/lib/intlFormat';
import theme from 'src/theme';
import { getLocalizedPledgeFrequency } from 'src/utils/functions/getLocalizedPledgeFrequency';
import {
AppealStatusEnum,
AppealsContext,
Expand Down Expand Up @@ -65,46 +60,6 @@ const ContactRowActions = styled(Box)(() => ({
paddingRight: theme.spacing(2),
}));

type FormatPledgeOrDonationProps = {
amount?: number | null;
currency?: string | null;
appealStatus: AppealStatusEnum;
dateOrFrequency?: PledgeFrequencyEnum | string | null;
locale: string;
t: TFunction;
};

const formatPledgeOrDonation = ({
amount,
currency,
appealStatus,
dateOrFrequency,
locale,
t,
}: FormatPledgeOrDonationProps) => {
const pledgeOrDonationAmount =
amount && currency
? currencyFormat(amount, currency, locale)
: amount || currencyFormat(0, currency, locale);

const pledgeOrDonationDate =
appealStatus === AppealStatusEnum.Asked ||
appealStatus === AppealStatusEnum.Excluded
? (dateOrFrequency &&
getLocalizedPledgeFrequency(
t,
dateOrFrequency as PledgeFrequencyEnum,
)) ??
''
: dateOrFrequency
? dateFormat(DateTime.fromISO(dateOrFrequency), locale)
: null;
return {
amount: pledgeOrDonationAmount,
dateOrFrequency: pledgeOrDonationDate,
};
};

interface Props {
contact: AppealContactInfoFragment;
appealStatus: AppealStatusEnum;
Expand All @@ -123,116 +78,21 @@ export const ContactRow: React.FC<Props> = ({
setContactFocus: onContactSelected,
toggleSelectionById: onContactCheckToggle,
} = React.useContext(AppealsContext) as AppealsType;
const { t } = useTranslation();
const locale = useLocale();
const [createPledgeModalOpen, setPledgeModalOpen] = useState(false);
const [deletePledgeModalOpen, setDeletePledgeModalOpen] = useState(false);
const [addExcludedContactModalOpen, setAddExcludedContactModalOpen] =
useState(false);
const [removeContactModalOpen, setRemoveContactModalOpen] = useState(false);
const [pledgeValues, setPledgeValues] =
useState<AppealContactInfoFragment['pledges'][0]>();
const [amountAndFrequency, setAmountAndFrequency] = useState<string>();
const [pledgeDonations, setPledgeDonations] = useState<string[] | null>(null);

const handleContactClick = () => {
onContactSelected(contact.id);
};

const {
id: contactId,
name,
pledgeAmount,
pledgeCurrency,
pledgeFrequency,
pledges,
donations,
} = contact;

useEffect(() => {
if (
appealStatus === AppealStatusEnum.Asked ||
appealStatus === AppealStatusEnum.Excluded
) {
const { amount, dateOrFrequency } = formatPledgeOrDonation({
amount: pledgeAmount,
currency: pledgeCurrency,
appealStatus,
dateOrFrequency: pledgeFrequency,
locale,
t,
});
setAmountAndFrequency(`${amount} ${dateOrFrequency}`);
setPledgeValues(undefined);
} else if (
appealStatus === AppealStatusEnum.NotReceived ||
appealStatus === AppealStatusEnum.ReceivedNotProcessed
) {
const appealPledge = pledges?.find(
(pledge) => pledge.appeal.id === appealId,
);

if (appealPledge) {
const { amount, dateOrFrequency } = formatPledgeOrDonation({
amount: appealPledge?.amount,
currency: appealPledge.amountCurrency,
appealStatus,
dateOrFrequency: appealPledge.expectedDate,
locale,
t,
});

setPledgeValues(appealPledge);
setAmountAndFrequency(`${amount} (${dateOrFrequency})`);
} else {
setAmountAndFrequency(`${currencyFormat(0, 'USD', locale)}`);
}
} else if (appealStatus === AppealStatusEnum.Processed) {
const appealPledge = pledges?.find(
(pledge) => pledge.appeal.id === appealId,
);

if (appealPledge) {
const { amount } = formatPledgeOrDonation({
amount: appealPledge?.amount,
currency: appealPledge.amountCurrency,
appealStatus,
locale,
t,
});
setPledgeValues(appealPledge);
setAmountAndFrequency(`${amount}`);
} else {
setAmountAndFrequency(`${currencyFormat(0, 'USD', locale)}`);
}

// Currently we grab all the donations and filter them by the appeal id
// We need a query that allows us to filter by the appeal id
// Maybe buy the backend team some donuts and ask them to add a filter to the donations query
const appealDonations = donations.nodes.filter(
(donation) => donation?.appeal?.id === appealId,
);

const givenDonations = appealDonations.map((donation) => {
const amount = donation?.appealAmount?.amount;
const currency = donation?.appealAmount?.convertedCurrency;
const donationAmount = currencyFormat(
amount && currency ? amount : 0,
currency,
locale,
);

const donationDate = dateFormat(
DateTime.fromISO(donation.donationDate),
locale,
);

return `(${donationAmount}) (${donationDate})`;
});
const { id: contactId, name } = contact;

setPledgeDonations(givenDonations);
}
}, [appealStatus, contact, locale]);
const { pledgeValues, amountAndFrequency, pledgeDonations } =
useGetPledgeOrDonation(appealStatus, contact, appealId ?? '', locale);

const handleCreatePledge = () => {
setPledgeModalOpen(true);
Expand Down
105 changes: 105 additions & 0 deletions src/hooks/useGetPledgeOrDonation.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { renderHook } from '@testing-library/react-hooks';
import { AppealStatusEnum } from 'src/components/Tool/Appeal/AppealsContext/AppealsContext';
import { defaultContact } from 'src/components/Tool/Appeal/List/ContactRow/ContactRowMock';
import { useGetPledgeOrDonation } from './useGetPledgeOrDonation';

const appealId = 'appealId';
describe('useGetPledgeOrDonation', () => {
it('returns the normal donation amount when in appeal status Asked', () => {
const { result } = renderHook(() =>
useGetPledgeOrDonation(
AppealStatusEnum.Asked,
defaultContact,
appealId,
'en-US',
),
);

expect(result.current.amountAndFrequency).toEqual('CA$500 Monthly');

expect(result.current.pledgeDonations).toBeNull();
expect(result.current.pledgeValues).toBeUndefined();
});

it('returns the normal donation amount when in appeal status Excluded', () => {
const { result } = renderHook(() =>
useGetPledgeOrDonation(
AppealStatusEnum.Excluded,
defaultContact,
appealId,
'en-US',
),
);

expect(result.current.amountAndFrequency).toEqual('CA$500 Monthly');

expect(result.current.pledgeDonations).toBeNull();
expect(result.current.pledgeValues).toBeUndefined();
});

it('returns the pledge when in appeal status Committed', () => {
const { result } = renderHook(() =>
useGetPledgeOrDonation(
AppealStatusEnum.NotReceived,
defaultContact,
appealId,
'en-US',
),
);

expect(result.current.amountAndFrequency).toEqual('$3,000 (Aug 8, 2024)');

expect(result.current.pledgeDonations).toBeNull();
expect(result.current.pledgeValues).toEqual({
amount: 3000,
amountCurrency: 'USD',
appeal: { id: appealId },
expectedDate: '2024-08-08',
id: 'pledge-1',
});
});

it('returns the pledge when in appeal status Received', () => {
const { result } = renderHook(() =>
useGetPledgeOrDonation(
AppealStatusEnum.ReceivedNotProcessed,
defaultContact,
appealId,
'en-US',
),
);

expect(result.current.amountAndFrequency).toEqual('$3,000 (Aug 8, 2024)');

expect(result.current.pledgeDonations).toBeNull();
expect(result.current.pledgeValues).toEqual({
amount: 3000,
amountCurrency: 'USD',
appeal: { id: appealId },
expectedDate: '2024-08-08',
id: 'pledge-1',
});
});

it('returns the donations to appeal when in appeal status Given', () => {
const { result } = renderHook(() =>
useGetPledgeOrDonation(
AppealStatusEnum.Processed,
defaultContact,
appealId,
'en-US',
),
);

expect(result.current.amountAndFrequency).toEqual('$3,000');

expect(result.current.pledgeDonations).toEqual(['($50) (Jun 25, 2019)']);
expect(result.current.pledgeValues).toEqual({
amount: 3000,
amountCurrency: 'USD',
appeal: { id: appealId },
expectedDate: '2024-08-08',
id: 'pledge-1',
});
});
});
Loading

0 comments on commit 660f33e

Please sign in to comment.