diff --git a/src/components/Coaching/CoachingDetail/CoachingDetail.test.tsx b/src/components/Coaching/CoachingDetail/CoachingDetail.test.tsx index 11af77363..2be83b504 100644 --- a/src/components/Coaching/CoachingDetail/CoachingDetail.test.tsx +++ b/src/components/Coaching/CoachingDetail/CoachingDetail.test.tsx @@ -59,16 +59,28 @@ const TestComponent: React.FC = ({ mocks={{ LoadCoachingDetail: { coachingAccountList: { - name: 'John Doe', + name: 'John Doe Account', currency: 'USD', monthlyGoal, + users: { + nodes: [ + { firstName: 'John', lastName: 'Doe' }, + { firstName: 'Sally', lastName: 'Doe' }, + ], + }, }, }, LoadAccountListCoachingDetail: { accountList: { - name: 'John Doe', + name: 'John Doe Account', currency: 'USD', monthlyGoal, + users: { + nodes: [ + { firstName: 'John', lastName: 'Doe' }, + { firstName: 'Sally', lastName: 'Doe' }, + ], + }, }, }, LoadCoachingCommitments: { @@ -130,10 +142,13 @@ describe('LoadCoachingDetail', () => { { type: AccountListTypeEnum.Own, name: 'own' }, ])('$name account list', ({ type: accountListType }) => { it('view', async () => { - const { findByRole, getByText } = render( + const { findByRole, getByText, findByText } = render( , ); - expect(await findByRole('heading', { name: 'John Doe' })).toBeVisible(); + expect( + await findByRole('heading', { name: 'John Doe Account' }), + ).toBeVisible(); + expect(await findByText('John Doe, Sally Doe')).toBeVisible(); expect(getByText('Monthly $55')).toBeVisible(); expect(getByText('Monthly Giving')).toBeVisible(); }); @@ -142,7 +157,9 @@ describe('LoadCoachingDetail', () => { const { findByRole, getByText } = render( , ); - expect(await findByRole('heading', { name: 'John Doe' })).toBeVisible(); + expect( + await findByRole('heading', { name: 'John Doe Account' }), + ).toBeVisible(); expect(getByText('Monthly $0')).toBeVisible(); expect(getByText('Monthly Giving')).toBeVisible(); }); @@ -154,7 +171,9 @@ describe('LoadCoachingDetail', () => { const { findByRole, getByRole, queryByRole } = render(); - expect(await findByRole('heading', { name: 'John Doe' })).toBeVisible(); + expect( + await findByRole('heading', { name: 'John Doe Account' }), + ).toBeVisible(); expect(getByRole('heading', { name: 'Coaching' })).toBeInTheDocument(); expect( queryByRole('button', { @@ -169,7 +188,9 @@ describe('LoadCoachingDetail', () => { const { findByRole, getByRole, queryByRole } = render(); - expect(await findByRole('heading', { name: 'John Doe' })).toBeVisible(); + expect( + await findByRole('heading', { name: 'John Doe Account' }), + ).toBeVisible(); expect( queryByRole('heading', { name: 'Coaching' }), ).not.toBeInTheDocument(); diff --git a/src/components/Coaching/CoachingDetail/CoachingDetail.tsx b/src/components/Coaching/CoachingDetail/CoachingDetail.tsx index 87a376503..83bcb323d 100644 --- a/src/components/Coaching/CoachingDetail/CoachingDetail.tsx +++ b/src/components/Coaching/CoachingDetail/CoachingDetail.tsx @@ -135,6 +135,10 @@ export const CoachingDetail: React.FC = ({ const handleCloseDrawer = () => setDrawerVisible(false); + const usersList = accountListData?.users.nodes + .map((user) => user.firstName + ' ' + user.lastName) + .join(', '); + const sidebarDrawer = useMediaQuery((theme) => theme.breakpoints.down('md'), ); @@ -171,7 +175,7 @@ export const CoachingDetail: React.FC = ({ <> - + setDrawerVisible(!drawerVisible)} @@ -183,6 +187,9 @@ export const CoachingDetail: React.FC = ({ {accountListData?.name} + + {usersList} + ({ width: '100%', - padding: theme.spacing(1), + padding: theme.spacing(0, 1), })); const CoachingTitleWrapper = styled(Box)(({ theme }) => ({ width: '100%', @@ -23,13 +22,13 @@ const CoachingTitleWrapper = styled(Box)(({ theme }) => ({ alignContent: 'center', })); -// const CoachingTitleIcon = styled(EcoOutlined)(({ theme }) => ({ -// margin: theme.spacing(1), -// })); +const CoachingTitleIcon = styled(Spa)(({ theme }) => ({ + margin: theme.spacing(1), +})); const CoachingListTitle = styled(Typography)(({ theme }) => ({ color: theme.palette.text.primary, - margin: theme.spacing(1), + margin: 0, })); const CoachingLoading = styled(Skeleton)(() => ({ @@ -47,9 +46,8 @@ export const CoachingList: React.FC = ({ return ( - - {/* */} + {t('Staff You Coach')} diff --git a/src/components/Coaching/CoachingRow/CoachingRow.test.tsx b/src/components/Coaching/CoachingRow/CoachingRow.test.tsx index c1672972c..28b80d20d 100644 --- a/src/components/Coaching/CoachingRow/CoachingRow.test.tsx +++ b/src/components/Coaching/CoachingRow/CoachingRow.test.tsx @@ -26,9 +26,16 @@ const TestComponent: React.FC = () => { { mocks: { id: 'coaching-account', - name: 'John Doe', + name: 'John Doe Account', currency: 'USD', primaryAppeal: null, + balance: 100, + users: { + nodes: [ + { firstName: 'John', lastName: 'Doe' }, + { firstName: 'Sally', lastName: 'Doe' }, + ], + }, }, }, ); @@ -49,9 +56,13 @@ const TestComponent: React.FC = () => { describe('CoachingRow', () => { it('renders', async () => { - const { getByRole } = render(); + const { getByRole, getByText } = render(); - expect(getByRole('heading', { name: 'John Doe' })).toBeInTheDocument(); + expect( + getByRole('heading', { name: 'John Doe Account' }), + ).toBeInTheDocument(); + expect(getByText('John Doe, Sally Doe')).toBeInTheDocument(); + expect(getByText('Balance: $100')).toBeInTheDocument(); }); it('deletes coaching account list', async () => { diff --git a/src/components/Coaching/CoachingRow/CoachingRow.tsx b/src/components/Coaching/CoachingRow/CoachingRow.tsx index 1358bb227..15b0d8dbd 100644 --- a/src/components/Coaching/CoachingRow/CoachingRow.tsx +++ b/src/components/Coaching/CoachingRow/CoachingRow.tsx @@ -1,10 +1,12 @@ import NextLink from 'next/link'; import React, { useState } from 'react'; import VisibilityOff from '@mui/icons-material/VisibilityOff'; -import { Box, Button, Link, Typography } from '@mui/material'; +import { Box, Button, Link, Tooltip, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; +import { useLocale } from 'src/hooks/useLocale'; import { useRequiredSession } from 'src/hooks/useRequiredSession'; +import { currencyFormat } from 'src/lib/intlFormat'; import { Confirmation } from '../../common/Modal/Confirmation/Confirmation'; import { AppealProgress } from '../AppealProgress/AppealProgress'; import { CoachedPersonFragment } from '../LoadCoachingList.generated'; @@ -22,12 +24,6 @@ const CoachingRowWrapper = styled(Box)(({ theme }) => ({ padding: theme.spacing(1), })); -const CoachingNameText = styled(Typography)(({ theme }) => ({ - margin: theme.spacing(2), - cursor: 'pointer', - display: 'flex', -})); - export const CoachingRow: React.FC = ({ coachingAccount, accountListId, @@ -37,13 +33,16 @@ export const CoachingRow: React.FC = ({ id, monthlyGoal, currency, + users, name, + balance, totalPledges, receivedPledges, primaryAppeal, } = coachingAccount; const { t } = useTranslation(); + const locale = useLocale(); const calculatedMonthlyGoal = monthlyGoal ?? 0; const appealCurrencyCode = primaryAppeal?.amountCurrency ?? 'USD'; @@ -61,31 +60,49 @@ export const CoachingRow: React.FC = ({ }, }); + const usersList = users.nodes + .map((user) => user.firstName + ' ' + user.lastName) + .join(', '); + return ( <> - - - - {name} - - - - + + + + + {name} + + + {usersList} + + + + {t('Balance:')} {currencyFormat(balance, currency, locale)} + + + + + + { - it('query correct', async () => { - const { result, waitForNextUpdate } = renderHook( - () => useLoadCoachingListQuery(), - { - wrapper: GqlMockedProvider, - }, - ); - await waitForNextUpdate(); - expect(result.current.data?.coachingAccountLists).toMatchInlineSnapshot(` - Object { - "__typename": "CoachingAccountListConnection", - "nodes": Array [ - Object { - "__typename": "CoachingAccountList", - "balance": 64.55430394702351, - "currency": "CAD", - "id": "7671408", - "monthlyGoal": 12, - "name": "Diamond Sword Restaurant", - "primaryAppeal": Object { - "__typename": "CoachingAppeal", - "active": false, - "amount": 71.24003484887974, - "amountCurrency": "EUR", - "id": "4377364", - "name": "Pebble Solid Triangle", - "pledgesAmountNotReceivedNotProcessed": 70.20389802275804, - "pledgesAmountProcessed": 36.11248127960118, - "pledgesAmountTotal": 96.17510597010335, - }, - "receivedPledges": 79.3262861684276, - "totalPledges": 50.50755229029304, - }, - Object { - "__typename": "CoachingAccountList", - "balance": 20.84220615982889, - "currency": "EUR", - "id": "8465485", - "monthlyGoal": 73, - "name": "Egg Compass Rocket", - "primaryAppeal": Object { - "__typename": "CoachingAppeal", - "active": true, - "amount": 57.02668130320204, - "amountCurrency": "CAD", - "id": "2268928", - "name": "Chess Board Mosquito", - "pledgesAmountNotReceivedNotProcessed": 11.708288466314501, - "pledgesAmountProcessed": 94.3774669075171, - "pledgesAmountTotal": 12.70780215832432, - }, - "receivedPledges": 22.600969051965148, - "totalPledges": 66.2952785316502, - }, - Object { - "__typename": "CoachingAccountList", - "balance": 66.76403183825539, - "currency": "EUR", - "id": "1819981", - "monthlyGoal": 42, - "name": "Leather jacket Onion Pocket", - "primaryAppeal": Object { - "__typename": "CoachingAppeal", - "active": true, - "amount": 7.701867972597047, - "amountCurrency": "CAD", - "id": "5425736", - "name": "Snail", - "pledgesAmountNotReceivedNotProcessed": 60.6603194388847, - "pledgesAmountProcessed": 22.219772841760978, - "pledgesAmountTotal": 16.959686277380897, - }, - "receivedPledges": 59.9470658594177, - "totalPledges": 67.6666019807398, - }, - ], - "pageInfo": Object { - "__typename": "PageInfo", - "endCursor": "Arm Bible Circus", - "hasNextPage": false, - "hasPreviousPage": true, - "startCursor": "Drum Baby Rock", - }, - "totalCount": 7, - "totalPageCount": 59, - } - `); - }); - it('test list view', () => { - const { getAllByRole } = render( - - mocks={{ - LoadCoachingList: { - coachingAccountLists: { - totalCount: 3, - nodes: [ - { currency: 'USD', primaryAppeal: { amountCurrency: 'EUR' } }, - { currency: 'USD', primaryAppeal: { amountCurrency: 'EUR' } }, - { currency: 'USD', primaryAppeal: { amountCurrency: 'JPN' } }, - ], - }, - }, - }} - > - - , - ); - expect(getAllByRole('listitem').length).toMatchInlineSnapshot(`3`); - }); -}); diff --git a/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.test.tsx b/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.test.tsx index 4d22d2495..12dbcd51a 100644 --- a/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.test.tsx +++ b/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.test.tsx @@ -105,7 +105,7 @@ describe('SuggestedContactStatus', () => { }); it('renders suggested status when single contact and checks contact status with gql call', async () => { - const { findByText } = render( + const { getByText } = render( { ); await waitFor(() => { expect(mutationSpy).toHaveBeenCalledTimes(2); - expect(mutationSpy.mock.calls[0][0].operation).toMatchObject({ - operationName: 'ContactStatus', - variables: { - accountListId: accountListId, - contactId: 'contact-1', - }, + expect(mutationSpy).toHaveGraphqlOperation('ContactStatus', { + accountListId: accountListId, + contactId: 'contact-1', }); }); - expect(await findByText('Initiate for Appointment')).toBeInTheDocument(); + await waitFor( + () => expect(getByText('Initiate for Appointment')).toBeInTheDocument(), + { timeout: 3000 }, + ); }); it('does not send a ContactStatus graphql request when the current contacts status is provided', async () => { @@ -138,13 +138,17 @@ describe('SuggestedContactStatus', () => { await waitFor(() => { expect(mutationSpy).toHaveBeenCalledTimes(1); - expect(mutationSpy.mock.calls[0][0].operation).toMatchObject({ - operationName: 'LoadConstants', - variables: {}, - }); - expect(getByText("Change the contact's status to:")).toBeInTheDocument(); - expect(getByText('Initiate for Appointment')).toBeInTheDocument(); + expect(mutationSpy).toHaveGraphqlOperation('LoadConstants', {}); }); + await waitFor( + () => { + expect( + getByText("Change the contact's status to:"), + ).toBeInTheDocument(); + expect(getByText('Initiate for Appointment')).toBeInTheDocument(); + }, + { timeout: 3000 }, + ); }); it('renders suggested status when the contact has no status', async () => { @@ -157,11 +161,14 @@ describe('SuggestedContactStatus', () => { />, ); - await waitFor(() => { - expect(getByText("Change the contact's status to:")).toBeInTheDocument(); - }); - await waitFor(() => - expect(getByText('Initiate for Appointment')).toBeInTheDocument(), + await waitFor( + () => { + expect( + getByText("Change the contact's status to:"), + ).toBeInTheDocument(); + expect(getByText('Initiate for Appointment')).toBeInTheDocument(); + }, + { timeout: 3000 }, ); }); });