diff --git a/pages/accountLists/[accountListId]/contacts/helpers.ts b/pages/accountLists/[accountListId]/contacts/helpers.ts index acf908b08..59209c329 100644 --- a/pages/accountLists/[accountListId]/contacts/helpers.ts +++ b/pages/accountLists/[accountListId]/contacts/helpers.ts @@ -50,6 +50,41 @@ export const getRedirectPathname = ({ '/accountLists/[accountListId]/reports/donations/[[...contactId]]' ) { pathname = `/accountLists/${accountListId}/reports/donations`; + } else if ( + routerPathname === + '/accountLists/[accountListId]/tools/fixMailingAddresses/[[...contactId]]' + ) { + pathname = `/accountLists/${accountListId}/tools/fixMailingAddresses`; + } else if ( + routerPathname === + '/accountLists/[accountListId]/tools/fixCommitmentInfo/[[...contactId]]' + ) { + pathname = `/accountLists/${accountListId}/tools/fixCommitmentInfo`; + } else if ( + routerPathname === + '/accountLists/[accountListId]/tools/fixSendNewsletter/[[...contactId]]' + ) { + pathname = `/accountLists/${accountListId}/tools/fixSendNewsletter`; + } else if ( + routerPathname === + '/accountLists/[accountListId]/tools/mergeContacts/[[...contactId]]' + ) { + pathname = `/accountLists/${accountListId}/tools/mergeContacts`; + } else if ( + routerPathname === + '/accountLists/[accountListId]/tools/fixEmailAddresses/[[...contactId]]' + ) { + pathname = `/accountLists/${accountListId}/tools/fixEmailAddresses`; + } else if ( + routerPathname === + '/accountLists/[accountListId]/tools/fixPhoneNumbers/[[...contactId]]' + ) { + pathname = `/accountLists/${accountListId}/tools/fixPhoneNumbers`; + } else if ( + routerPathname === + '/accountLists/[accountListId]/tools/mergePeople/[[...contactId]]' + ) { + pathname = `/accountLists/${accountListId}/tools/mergePeople`; } if (contactId) { diff --git a/pages/accountLists/[accountListId]/tools/ToolsWrapper.tsx b/pages/accountLists/[accountListId]/tools/ToolsWrapper.tsx new file mode 100644 index 000000000..89ff1df59 --- /dev/null +++ b/pages/accountLists/[accountListId]/tools/ToolsWrapper.tsx @@ -0,0 +1,56 @@ +import Head from 'next/head'; +import React, { JSXElementConstructor, ReactElement } from 'react'; +import { DynamicContactsRightPanel } from 'src/components/Contacts/ContactsRightPanel/DynamicContactsRightPanel'; +import { SidePanelsLayout } from 'src/components/Layouts/SidePanelsLayout'; +import Loading from 'src/components/Loading'; +import useGetAppSettings from 'src/hooks/useGetAppSettings'; +import { ContactsWrapper } from '../contacts/ContactsWrapper'; +import { useToolsHelper } from './useToolsHelper'; + +interface ToolsWrapperProps { + pageTitle: string; + pageUrl: string; + selectedMenuId: string; // for later use + children: ReactElement>; +} + +export const ToolsWrapper: React.FC = ({ + pageTitle, + pageUrl, + children, +}) => { + const { appName } = useGetAppSettings(); + const { accountListId, selectedContactId, handleSelectContact } = + useToolsHelper(); + + return ( + <> + + + {appName} | {pageTitle} + + + {accountListId ? ( + + handleSelectContact(pageUrl, '')} + /> + + ) : undefined + } + rightOpen={typeof selectedContactId !== 'undefined'} + rightWidth="60%" + headerHeight={'0px'} + /> + ) : ( + + )} + + ); +}; diff --git a/pages/accountLists/[accountListId]/tools/fixCommitmentInfo.page.tsx b/pages/accountLists/[accountListId]/tools/fixCommitmentInfo.page.tsx deleted file mode 100644 index 527e3d63d..000000000 --- a/pages/accountLists/[accountListId]/tools/fixCommitmentInfo.page.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import Head from 'next/head'; -import React from 'react'; -import { useTranslation } from 'react-i18next'; -import { loadSession } from 'pages/api/utils/pagePropsHelpers'; -import Loading from 'src/components/Loading'; -import FixCommitmentInfo from 'src/components/Tool/FixCommitmentInfo/FixCommitmentInfo'; -import { useAccountListId } from 'src/hooks/useAccountListId'; -import useGetAppSettings from 'src/hooks/useGetAppSettings'; - -const FixCommitmentInfoPage: React.FC = () => { - const { t } = useTranslation(); - const accountListId = useAccountListId(); - const { appName } = useGetAppSettings(); - - return ( - <> - - - {appName} | {t('Fix Commitment Info')} - - - {accountListId ? ( - - ) : ( - - )} - - ); -}; - -export const getServerSideProps = loadSession; - -export default FixCommitmentInfoPage; diff --git a/pages/accountLists/[accountListId]/tools/fixCommitmentInfo/[[...contactId]].page.tsx b/pages/accountLists/[accountListId]/tools/fixCommitmentInfo/[[...contactId]].page.tsx new file mode 100644 index 000000000..259068b0c --- /dev/null +++ b/pages/accountLists/[accountListId]/tools/fixCommitmentInfo/[[...contactId]].page.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { loadSession } from 'pages/api/utils/pagePropsHelpers'; +import FixCommitmentInfo from 'src/components/Tool/FixCommitmentInfo/FixCommitmentInfo'; +import { ToolsWrapper } from '../ToolsWrapper'; +import { SetContactFocus, useToolsHelper } from '../useToolsHelper'; + +const FixCommitmentInfoPage: React.FC = () => { + const { t } = useTranslation(); + const { accountListId, handleSelectContact } = useToolsHelper(); + const pageUrl = 'tools/fixCommitmentInfo'; + + const setContactFocus: SetContactFocus = (contactId) => { + handleSelectContact(pageUrl, contactId); + }; + + return ( + + + + ); +}; + +export const getServerSideProps = loadSession; + +export default FixCommitmentInfoPage; diff --git a/pages/accountLists/[accountListId]/tools/fixEmailAddresses.page.tsx b/pages/accountLists/[accountListId]/tools/fixEmailAddresses.page.tsx deleted file mode 100644 index 9d60eae40..000000000 --- a/pages/accountLists/[accountListId]/tools/fixEmailAddresses.page.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import Head from 'next/head'; -import React from 'react'; -import { useTranslation } from 'react-i18next'; -import { loadSession } from 'pages/api/utils/pagePropsHelpers'; -import Loading from 'src/components/Loading'; -import { FixEmailAddresses } from 'src/components/Tool/FixEmailAddresses/FixEmailAddresses'; -import { useAccountListId } from 'src/hooks/useAccountListId'; -import useGetAppSettings from 'src/hooks/useGetAppSettings'; - -const FixEmailAddressesPage: React.FC = () => { - const { t } = useTranslation(); - const accountListId = useAccountListId(); - const { appName } = useGetAppSettings(); - - return ( - <> - - - {appName} | {t('Fix Email Addresses')} - - - {accountListId ? ( - - ) : ( - - )} - - ); -}; - -export const getServerSideProps = loadSession; - -export default FixEmailAddressesPage; diff --git a/pages/accountLists/[accountListId]/tools/fixEmailAddresses/[[...contactId]].page.tsx b/pages/accountLists/[accountListId]/tools/fixEmailAddresses/[[...contactId]].page.tsx new file mode 100644 index 000000000..3bd01e6aa --- /dev/null +++ b/pages/accountLists/[accountListId]/tools/fixEmailAddresses/[[...contactId]].page.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { loadSession } from 'pages/api/utils/pagePropsHelpers'; +import { FixEmailAddresses } from 'src/components/Tool/FixEmailAddresses/FixEmailAddresses'; +import { ToolsWrapper } from '../ToolsWrapper'; +import { SetContactFocus, useToolsHelper } from '../useToolsHelper'; + +const FixEmailAddressesPage: React.FC = () => { + const { t } = useTranslation(); + const { accountListId, handleSelectContact } = useToolsHelper(); + const pageUrl = 'tools/fixEmailAddresses'; + + const setContactFocus: SetContactFocus = (contactId) => { + handleSelectContact(pageUrl, contactId); + }; + + return ( + + + + ); +}; + +export const getServerSideProps = loadSession; + +export default FixEmailAddressesPage; diff --git a/pages/accountLists/[accountListId]/tools/fixMailingAddresses.page.tsx b/pages/accountLists/[accountListId]/tools/fixMailingAddresses.page.tsx deleted file mode 100644 index e8ff7f206..000000000 --- a/pages/accountLists/[accountListId]/tools/fixMailingAddresses.page.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import Head from 'next/head'; -import React from 'react'; -import { useTranslation } from 'react-i18next'; -import { loadSession } from 'pages/api/utils/pagePropsHelpers'; -import Loading from 'src/components/Loading'; -import FixMailingAddresses from 'src/components/Tool/FixMailingAddresses/FixMailingAddresses'; -import { useAccountListId } from 'src/hooks/useAccountListId'; -import useGetAppSettings from 'src/hooks/useGetAppSettings'; - -const FixMailingAddressesPage: React.FC = () => { - const { t } = useTranslation(); - const accountListId = useAccountListId(); - const { appName } = useGetAppSettings(); - - return ( - <> - - - {appName} | {t('Fix Mailing Addresses')} - - - {accountListId ? ( - - ) : ( - - )} - - ); -}; - -export const getServerSideProps = loadSession; - -export default FixMailingAddressesPage; diff --git a/pages/accountLists/[accountListId]/tools/fixMailingAddresses/[[...contactId]].page.test.tsx b/pages/accountLists/[accountListId]/tools/fixMailingAddresses/[[...contactId]].page.test.tsx new file mode 100644 index 000000000..a6277aa4e --- /dev/null +++ b/pages/accountLists/[accountListId]/tools/fixMailingAddresses/[[...contactId]].page.test.tsx @@ -0,0 +1,102 @@ +import { useRouter } from 'next/router'; +import { ThemeProvider } from '@mui/material/styles'; +import { render, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { ApolloErgonoMockMap } from 'graphql-ergonomock'; +import { getSession } from 'next-auth/react'; +import { SnackbarProvider } from 'notistack'; +import { I18nextProvider } from 'react-i18next'; +import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { mockInvalidAddressesResponse } from 'src/components/Tool/FixMailingAddresses/FixMailingAddressesMock'; +import { InvalidAddressesQuery } from 'src/components/Tool/FixMailingAddresses/GetInvalidAddresses.generated'; +import i18n from 'src/lib/i18n'; +import theme from 'src/theme'; +import FixMailingAddressesPage from './[[...contactId]].page'; + +jest.mock('next-auth/react'); +jest.mock('next/router', () => ({ + useRouter: jest.fn(), +})); +jest.mock('src/lib/helpScout', () => ({ + suggestArticles: jest.fn(), +})); +jest.mock('notistack', () => ({ + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + ...jest.requireActual('notistack'), + useSnackbar: () => { + return { + enqueueSnackbar: jest.fn(), + }; + }, +})); + +const pushFn = jest.fn(); +const accountListId = 'account-list-1'; +const contactId = 'contactId'; +const session = { + expires: '2021-10-28T14:48:20.897Z', + user: { + email: 'Chair Library Bed', + image: null, + name: 'Dung Tapestry', + token: 'superLongJwtString', + }, +}; +const Components = ({ mocks }: { mocks: ApolloErgonoMockMap }) => ( + + + + mocks={mocks} + > + + + + + + + + +); + +describe('FixMailingAddressesPage', () => { + beforeEach(() => { + (getSession as jest.Mock).mockResolvedValue(session); + (useRouter as jest.Mock).mockReturnValue({ + query: { + accountListId, + }, + isReady: true, + push: pushFn, + }); + }); + + it('should open up contact details', async () => { + const { getByText, queryByTestId } = render( + , + ); + await waitFor(() => + expect(queryByTestId('loading')).not.toBeInTheDocument(), + ); + + const contactName = getByText('Baggins, Frodo'); + + expect(contactName).toBeInTheDocument(); + userEvent.click(contactName); + + await waitFor(() => { + expect(pushFn).toHaveBeenCalledWith( + `/accountLists/${accountListId}/tools/fixMailingAddresses/${contactId}`, + ); + }); + }); +}); diff --git a/pages/accountLists/[accountListId]/tools/fixMailingAddresses/[[...contactId]].page.tsx b/pages/accountLists/[accountListId]/tools/fixMailingAddresses/[[...contactId]].page.tsx new file mode 100644 index 000000000..fa661ef06 --- /dev/null +++ b/pages/accountLists/[accountListId]/tools/fixMailingAddresses/[[...contactId]].page.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { loadSession } from 'pages/api/utils/pagePropsHelpers'; +import FixMailingAddresses from 'src/components/Tool/FixMailingAddresses/FixMailingAddresses'; +import { ToolsWrapper } from '../ToolsWrapper'; +import { SetContactFocus, useToolsHelper } from '../useToolsHelper'; + +const FixMailingAddressesPage: React.FC = () => { + const { t } = useTranslation(); + const { accountListId, handleSelectContact } = useToolsHelper(); + const pageUrl = 'tools/fixMailingAddresses'; + + const setContactFocus: SetContactFocus = (contactId) => { + handleSelectContact(pageUrl, contactId); + }; + + return ( + + + + ); +}; + +export const getServerSideProps = loadSession; + +export default FixMailingAddressesPage; diff --git a/pages/accountLists/[accountListId]/tools/fixPhoneNumbers.page.tsx b/pages/accountLists/[accountListId]/tools/fixPhoneNumbers.page.tsx deleted file mode 100644 index 16e2123e2..000000000 --- a/pages/accountLists/[accountListId]/tools/fixPhoneNumbers.page.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import Head from 'next/head'; -import React from 'react'; -import { useTranslation } from 'react-i18next'; -import { loadSession } from 'pages/api/utils/pagePropsHelpers'; -import Loading from 'src/components/Loading'; -import FixPhoneNumbers from 'src/components/Tool/FixPhoneNumbers/FixPhoneNumbers'; -import { useAccountListId } from 'src/hooks/useAccountListId'; -import useGetAppSettings from 'src/hooks/useGetAppSettings'; - -const FixPhoneNumbersPage: React.FC = () => { - const { t } = useTranslation(); - const accountListId = useAccountListId(); - const { appName } = useGetAppSettings(); - - return ( - <> - - - {appName} | {t('Fix Phone Numbers')} - - - {accountListId ? ( - - ) : ( - - )} - - ); -}; - -export const getServerSideProps = loadSession; - -export default FixPhoneNumbersPage; diff --git a/pages/accountLists/[accountListId]/tools/fixPhoneNumbers/[[...contactId]].page.tsx b/pages/accountLists/[accountListId]/tools/fixPhoneNumbers/[[...contactId]].page.tsx new file mode 100644 index 000000000..f25e93932 --- /dev/null +++ b/pages/accountLists/[accountListId]/tools/fixPhoneNumbers/[[...contactId]].page.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { loadSession } from 'pages/api/utils/pagePropsHelpers'; +import FixPhoneNumbers from 'src/components/Tool/FixPhoneNumbers/FixPhoneNumbers'; +import { ToolsWrapper } from '../ToolsWrapper'; +import { SetContactFocus, useToolsHelper } from '../useToolsHelper'; + +const FixPhoneNumbersPage: React.FC = () => { + const { t } = useTranslation(); + const { accountListId, handleSelectContact } = useToolsHelper(); + const pageUrl = 'tools/fixPhoneNumbers'; + + const setContactFocus: SetContactFocus = (contactId) => { + handleSelectContact(pageUrl, contactId); + }; + + return ( + + + + ); +}; + +export const getServerSideProps = loadSession; + +export default FixPhoneNumbersPage; diff --git a/pages/accountLists/[accountListId]/tools/fixSendNewsletter.page.tsx b/pages/accountLists/[accountListId]/tools/fixSendNewsletter.page.tsx deleted file mode 100644 index 3559c3c8b..000000000 --- a/pages/accountLists/[accountListId]/tools/fixSendNewsletter.page.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import Head from 'next/head'; -import React from 'react'; -import { useTranslation } from 'react-i18next'; -import { loadSession } from 'pages/api/utils/pagePropsHelpers'; -import Loading from 'src/components/Loading'; -import FixSendNewsletter from 'src/components/Tool/FixSendNewsletter/FixSendNewsletter'; -import { useAccountListId } from 'src/hooks/useAccountListId'; -import useGetAppSettings from 'src/hooks/useGetAppSettings'; - -const FixSendNewsletterPage: React.FC = () => { - const { t } = useTranslation(); - const accountListId = useAccountListId(); - const { appName } = useGetAppSettings(); - - return ( - <> - - - {appName} | {t('Fix Send Newsletter')} - - - {accountListId ? ( - - ) : ( - - )} - - ); -}; - -export const getServerSideProps = loadSession; - -export default FixSendNewsletterPage; diff --git a/pages/accountLists/[accountListId]/tools/fixSendNewsletter/[[...contactId]].page.tsx b/pages/accountLists/[accountListId]/tools/fixSendNewsletter/[[...contactId]].page.tsx new file mode 100644 index 000000000..0585533ac --- /dev/null +++ b/pages/accountLists/[accountListId]/tools/fixSendNewsletter/[[...contactId]].page.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { loadSession } from 'pages/api/utils/pagePropsHelpers'; +import FixSendNewsletter from 'src/components/Tool/FixSendNewsletter/FixSendNewsletter'; +import { ToolsWrapper } from '../ToolsWrapper'; +import { SetContactFocus, useToolsHelper } from '../useToolsHelper'; + +const FixSendNewsletterPage: React.FC = () => { + const { t } = useTranslation(); + const { accountListId, handleSelectContact } = useToolsHelper(); + const pageUrl = 'tools/fixSendNewsletter'; + + const setContactFocus: SetContactFocus = (contactId) => { + handleSelectContact(pageUrl, contactId); + }; + + return ( + + + + ); +}; + +export const getServerSideProps = loadSession; + +export default FixSendNewsletterPage; diff --git a/pages/accountLists/[accountListId]/tools/mergeContacts.page.tsx b/pages/accountLists/[accountListId]/tools/mergeContacts.page.tsx deleted file mode 100644 index 6606fd09c..000000000 --- a/pages/accountLists/[accountListId]/tools/mergeContacts.page.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import Head from 'next/head'; -import React from 'react'; -import { useTranslation } from 'react-i18next'; -import { loadSession } from 'pages/api/utils/pagePropsHelpers'; -import Loading from 'src/components/Loading'; -import MergeContacts from 'src/components/Tool/MergeContacts/MergeContacts'; -import { useAccountListId } from 'src/hooks/useAccountListId'; -import useGetAppSettings from 'src/hooks/useGetAppSettings'; - -const MergeContactsPage: React.FC = () => { - const { t } = useTranslation(); - const accountListId = useAccountListId(); - const { appName } = useGetAppSettings(); - - return ( - <> - - - {appName} | {t('Merge Contacts')} - - - {accountListId ? ( - - ) : ( - - )} - - ); -}; - -export const getServerSideProps = loadSession; - -export default MergeContactsPage; diff --git a/pages/accountLists/[accountListId]/tools/mergeContacts/[[...contactId]].page.tsx b/pages/accountLists/[accountListId]/tools/mergeContacts/[[...contactId]].page.tsx new file mode 100644 index 000000000..a5ad4eaca --- /dev/null +++ b/pages/accountLists/[accountListId]/tools/mergeContacts/[[...contactId]].page.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { loadSession } from 'pages/api/utils/pagePropsHelpers'; +import MergeContacts from 'src/components/Tool/MergeContacts/MergeContacts'; +import { ToolsWrapper } from '../ToolsWrapper'; +import { SetContactFocus, useToolsHelper } from '../useToolsHelper'; + +const MergeContactsPage: React.FC = () => { + const { t } = useTranslation(); + const { accountListId, handleSelectContact } = useToolsHelper(); + const pageUrl = 'tools/mergeContacts'; + + const setContactFocus: SetContactFocus = (contactId) => { + handleSelectContact(pageUrl, contactId); + }; + + return ( + + + + ); +}; + +export const getServerSideProps = loadSession; + +export default MergeContactsPage; diff --git a/pages/accountLists/[accountListId]/tools/mergePeople.page.tsx b/pages/accountLists/[accountListId]/tools/mergePeople.page.tsx deleted file mode 100644 index 1136b2038..000000000 --- a/pages/accountLists/[accountListId]/tools/mergePeople.page.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import Head from 'next/head'; -import React from 'react'; -import { useTranslation } from 'react-i18next'; -import { loadSession } from 'pages/api/utils/pagePropsHelpers'; -import Loading from 'src/components/Loading'; -import MergePeople from 'src/components/Tool/MergePeople/MergePeople'; -import { useAccountListId } from 'src/hooks/useAccountListId'; -import useGetAppSettings from 'src/hooks/useGetAppSettings'; - -const MergePeoplePage: React.FC = () => { - const { t } = useTranslation(); - const accountListId = useAccountListId(); - const { appName } = useGetAppSettings(); - - return ( - <> - - - {appName} | {t('Merge People')} - - - {accountListId ? ( - - ) : ( - - )} - - ); -}; - -export const getServerSideProps = loadSession; - -export default MergePeoplePage; diff --git a/pages/accountLists/[accountListId]/tools/mergePeople/[[...contactId]].page.tsx b/pages/accountLists/[accountListId]/tools/mergePeople/[[...contactId]].page.tsx new file mode 100644 index 000000000..251c96f74 --- /dev/null +++ b/pages/accountLists/[accountListId]/tools/mergePeople/[[...contactId]].page.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { loadSession } from 'pages/api/utils/pagePropsHelpers'; +import MergePeople from 'src/components/Tool/MergePeople/MergePeople'; +import { ToolsWrapper } from '../ToolsWrapper'; +import { SetContactFocus, useToolsHelper } from '../useToolsHelper'; + +const MergePeoplePage: React.FC = () => { + const { t } = useTranslation(); + const { accountListId, handleSelectContact } = useToolsHelper(); + const pageUrl = 'tools/mergePeople'; + + const setContactFocus: SetContactFocus = (contactId) => { + handleSelectContact(pageUrl, contactId); + }; + + return ( + + + + ); +}; + +export const getServerSideProps = loadSession; + +export default MergePeoplePage; diff --git a/pages/accountLists/[accountListId]/tools/useToolsHelper.ts b/pages/accountLists/[accountListId]/tools/useToolsHelper.ts new file mode 100644 index 000000000..2942b6d26 --- /dev/null +++ b/pages/accountLists/[accountListId]/tools/useToolsHelper.ts @@ -0,0 +1,25 @@ +import { useRouter } from 'next/router'; +import { useCallback } from 'react'; +import { useAccountListId } from 'src/hooks/useAccountListId'; +import { getQueryParam } from 'src/utils/queryParam'; + +export type SetContactFocus = (contactId: string) => void; + +export const useToolsHelper = () => { + const { query, push } = useRouter(); + const accountListId = useAccountListId(); + const selectedContactId = getQueryParam(query, 'contactId'); + + const handleSelectContact = useCallback( + (pagePath: string, contactId: string) => { + push(`/accountLists/${accountListId}/${pagePath}/${contactId}`); + }, + [accountListId], + ); + + return { + accountListId, + selectedContactId, + handleSelectContact, + }; +}; diff --git a/src/components/Tool/FixCommitmentInfo/Contact.test.tsx b/src/components/Tool/FixCommitmentInfo/Contact.test.tsx index d4b86024e..51548b2c4 100644 --- a/src/components/Tool/FixCommitmentInfo/Contact.test.tsx +++ b/src/components/Tool/FixCommitmentInfo/Contact.test.tsx @@ -21,6 +21,7 @@ const testData = { const router = { push: jest.fn(), }; +const setContactFocus = jest.fn(); describe('FixCommitmentContact', () => { it('default', () => { @@ -42,6 +43,7 @@ describe('FixCommitmentContact', () => { hideFunction={hideFunction} updateFunction={updateFunction} statuses={[]} + setContactFocus={setContactFocus} /> , @@ -75,6 +77,7 @@ describe('FixCommitmentContact', () => { hideFunction={hideFunction} updateFunction={updateFunction} statuses={[]} + setContactFocus={setContactFocus} /> , @@ -113,6 +116,7 @@ describe('FixCommitmentContact', () => { hideFunction={hideFunction} updateFunction={updateFunction} statuses={[]} + setContactFocus={setContactFocus} /> , @@ -145,6 +149,7 @@ describe('FixCommitmentContact', () => { { name: 'Partner - Financial', value: 'PARTNER_FINANCIAL' }, { name: 'test_option_1', value: 'test1' }, ]} + setContactFocus={setContactFocus} /> , diff --git a/src/components/Tool/FixCommitmentInfo/Contact.tsx b/src/components/Tool/FixCommitmentInfo/Contact.tsx index a7bb55507..728268424 100644 --- a/src/components/Tool/FixCommitmentInfo/Contact.tsx +++ b/src/components/Tool/FixCommitmentInfo/Contact.tsx @@ -1,4 +1,3 @@ -import NextLink from 'next/link'; import { useRouter } from 'next/router'; import React, { useState } from 'react'; import SearchIcon from '@mui/icons-material/Search'; @@ -9,13 +8,14 @@ import { Button, Grid, IconButton, + Link, NativeSelect, TextField, Typography, } from '@mui/material'; -import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; +import { SetContactFocus } from 'pages/accountLists/[accountListId]/tools/useToolsHelper'; import { FilterOption } from 'src/graphql/types.generated'; import { useAccountListId } from 'src/hooks/useAccountListId'; import theme from '../../../theme'; @@ -85,14 +85,6 @@ const useStyles = makeStyles()(() => ({ }, })); -const ContactLink = styled(Typography)(() => ({ - color: theme.palette.mpdxBlue.main, - '&:hover': { - textDecoration: 'underline', - cursor: 'pointer', - }, -})); - interface Props { id: string; name: string; @@ -112,6 +104,7 @@ interface Props { pledgeFrequency?: string, ) => Promise; statuses: FilterOption[]; + setContactFocus: SetContactFocus; } const Contact: React.FC = ({ @@ -126,6 +119,7 @@ const Contact: React.FC = ({ hideFunction, updateFunction, statuses, + setContactFocus, }) => { const [values, setValues] = useState({ statusValue: statusValue, @@ -149,6 +143,10 @@ const Contact: React.FC = ({ setValues((prevState) => ({ ...prevState, [props]: event.target.value })); }; + const handleContactNameClick = () => { + setContactFocus(id); + }; + return ( @@ -164,12 +162,9 @@ const Contact: React.FC = ({ style={{ width: theme.spacing(7), height: theme.spacing(7) }} /> - - {name} - + + {name} + Current:{' '} {`${statusTitle} ${amount.toFixed( diff --git a/src/components/Tool/FixCommitmentInfo/FixCommitmentInfo.tsx b/src/components/Tool/FixCommitmentInfo/FixCommitmentInfo.tsx index 7a1910f63..7b9db2f0e 100644 --- a/src/components/Tool/FixCommitmentInfo/FixCommitmentInfo.tsx +++ b/src/components/Tool/FixCommitmentInfo/FixCommitmentInfo.tsx @@ -12,6 +12,7 @@ import { useSnackbar } from 'notistack'; import { Trans, useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; import { useContactFiltersQuery } from 'pages/accountLists/[accountListId]/contacts/Contacts.generated'; +import { SetContactFocus } from 'pages/accountLists/[accountListId]/tools/useToolsHelper'; import { MultiselectFilter, PledgeFrequencyEnum, @@ -66,9 +67,13 @@ const useStyles = makeStyles()((theme: Theme) => ({ interface Props { accountListId: string; + setContactFocus: SetContactFocus; } -const FixCommitmentInfo: React.FC = ({ accountListId }: Props) => { +const FixCommitmentInfo: React.FC = ({ + accountListId, + setContactFocus, +}: Props) => { const { classes } = useStyles(); const { t } = useTranslation(); const { enqueueSnackbar } = useSnackbar(); @@ -216,6 +221,7 @@ const FixCommitmentInfo: React.FC = ({ accountListId }: Props) => { hideFunction={hideContact} updateFunction={updateContact} statuses={contactStatuses || [{ name: '', value: '' }]} + setContactFocus={setContactFocus} /> ))} diff --git a/src/components/Tool/FixEmailAddresses/FixEmailAddressPerson.test.tsx b/src/components/Tool/FixEmailAddresses/FixEmailAddressPerson.test.tsx index 5131bc945..2064d0e56 100644 --- a/src/components/Tool/FixEmailAddresses/FixEmailAddressPerson.test.tsx +++ b/src/components/Tool/FixEmailAddresses/FixEmailAddressPerson.test.tsx @@ -26,6 +26,8 @@ const testData = { ], }; +const setContactFocus = jest.fn(); + describe('FixEmailAddresses-Contact', () => { it('default', () => { const handleChangeMock = jest.fn(); @@ -46,6 +48,7 @@ describe('FixEmailAddresses-Contact', () => { handleDelete={handleDeleteModalOpenMock} handleAdd={handleAddMock} handleChangePrimary={handleChangePrimaryMock} + setContactFocus={setContactFocus} /> , @@ -79,6 +82,7 @@ describe('FixEmailAddresses-Contact', () => { handleDelete={handleDeleteModalOpenMock} handleAdd={handleAddMock} handleChangePrimary={handleChangePrimaryMock} + setContactFocus={setContactFocus} /> , diff --git a/src/components/Tool/FixEmailAddresses/FixEmailAddressPerson.tsx b/src/components/Tool/FixEmailAddresses/FixEmailAddressPerson.tsx index 2fe645b26..b43ba625a 100644 --- a/src/components/Tool/FixEmailAddresses/FixEmailAddressPerson.tsx +++ b/src/components/Tool/FixEmailAddresses/FixEmailAddressPerson.tsx @@ -7,6 +7,7 @@ import { Button, Grid, Hidden, + Link, TextField, Theme, Typography, @@ -15,6 +16,7 @@ import { styled } from '@mui/material/styles'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; +import { SetContactFocus } from 'pages/accountLists/[accountListId]/tools/useToolsHelper'; import { PersonEmailAddressInput } from 'src/graphql/types.generated'; import { useLocale } from 'src/hooks/useLocale'; import { dateFormatShort } from 'src/lib/intlFormat'; @@ -102,6 +104,7 @@ interface FixEmailAddressPersonProps { handleDelete: (personId: string, emailAddress: number) => void; handleAdd: (personId: string, email: string) => void; handleChangePrimary: (personId: string, emailIndex: number) => void; + setContactFocus: SetContactFocus; } export const FixEmailAddressPerson: React.FC = ({ @@ -112,6 +115,9 @@ export const FixEmailAddressPerson: React.FC = ({ handleDelete, handleAdd, handleChangePrimary, + // Remove below line when function is being used. + // eslint-disable-next-line @typescript-eslint/no-unused-vars + setContactFocus, }) => { const { t } = useTranslation(); const locale = useLocale(); @@ -133,6 +139,13 @@ export const FixEmailAddressPerson: React.FC = ({ } }; + const handleContactNameClick = () => { + // This currently doesn't work as we need to add the contactId onto the person graphQL endpoint. + // I've asked Andrew to add it here: https://cru-main.slack.com/archives/CG47BDCG6/p1718721024211409 + // You'll need that to run the below function + // setContactFocus(id); + }; + return ( @@ -148,7 +161,9 @@ export const FixEmailAddressPerson: React.FC = ({ > - {name} + + {name} + diff --git a/src/components/Tool/FixEmailAddresses/FixEmailAddresses.test.tsx b/src/components/Tool/FixEmailAddresses/FixEmailAddresses.test.tsx index c1ddb28a5..51c9debc3 100644 --- a/src/components/Tool/FixEmailAddresses/FixEmailAddresses.test.tsx +++ b/src/components/Tool/FixEmailAddresses/FixEmailAddresses.test.tsx @@ -17,6 +17,8 @@ const router = { isReady: true, }; +const setContactFocus = jest.fn(); + const testData: ErgonoMockShape[] = [ { id: 'testid', @@ -90,7 +92,10 @@ describe('FixPhoneNumbers-Home', () => { }, }} > - + @@ -130,7 +135,10 @@ describe('FixPhoneNumbers-Home', () => { }, }} > - + @@ -161,7 +169,10 @@ describe('FixPhoneNumbers-Home', () => { }, }} > - + @@ -193,7 +204,10 @@ describe('FixPhoneNumbers-Home', () => { }, }} > - + @@ -231,7 +245,10 @@ describe('FixPhoneNumbers-Home', () => { }, }} > - + @@ -270,7 +287,10 @@ describe('FixPhoneNumbers-Home', () => { }, }} > - + @@ -300,7 +320,10 @@ describe('FixPhoneNumbers-Home', () => { }, }} > - + diff --git a/src/components/Tool/FixEmailAddresses/FixEmailAddresses.tsx b/src/components/Tool/FixEmailAddresses/FixEmailAddresses.tsx index 81301b808..b7fc38523 100644 --- a/src/components/Tool/FixEmailAddresses/FixEmailAddresses.tsx +++ b/src/components/Tool/FixEmailAddresses/FixEmailAddresses.tsx @@ -10,6 +10,7 @@ import { } from '@mui/material'; import { styled } from '@mui/material/styles'; import { Trans, useTranslation } from 'react-i18next'; +import { SetContactFocus } from 'pages/accountLists/[accountListId]/tools/useToolsHelper'; import { PersonEmailAddressInput } from 'src/graphql/types.generated'; import theme from '../../../theme'; import { ConfirmButtonIcon } from '../ConfirmButtonIcon'; @@ -110,10 +111,12 @@ interface PersonEmailAddresses { interface FixEmailAddressesProps { accountListId: string; + setContactFocus: SetContactFocus; } export const FixEmailAddresses: React.FC = ({ accountListId, + setContactFocus, }) => { const [defaultSource, setDefaultSource] = useState('MPDX'); const [deleteModalState, setDeleteModalState] = useState( @@ -294,6 +297,7 @@ export const FixEmailAddresses: React.FC = ({ handleDelete={handleDeleteModalOpen} handleAdd={handleAdd} handleChangePrimary={handleChangePrimary} + setContactFocus={setContactFocus} /> ))} diff --git a/src/components/Tool/FixMailingAddresses/Contact.tsx b/src/components/Tool/FixMailingAddresses/Contact.tsx index 41132ed8e..adda7cef4 100644 --- a/src/components/Tool/FixMailingAddresses/Contact.tsx +++ b/src/components/Tool/FixMailingAddresses/Contact.tsx @@ -15,6 +15,7 @@ import { Grid, Hidden, IconButton, + Link, Typography, } from '@mui/material'; import clsx from 'clsx'; @@ -22,6 +23,7 @@ import { DateTime } from 'luxon'; import { useSnackbar } from 'notistack'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; +import { SetContactFocus } from 'pages/accountLists/[accountListId]/tools/useToolsHelper'; import { editableSources } from 'src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/EditContactAddressModal/EditContactAddressModal'; import { useSetContactPrimaryAddressMutation } from 'src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/SetPrimaryAddress.generated'; import { @@ -40,6 +42,7 @@ import { emptyAddress } from './FixMailingAddresses'; import { ContactAddressFragment } from './GetInvalidAddresses.generated'; const ContactHeader = styled(CardHeader)(() => ({ + cursor: 'pointer', '.MuiCardHeader-action': { alignSelf: 'center', }, @@ -113,6 +116,7 @@ interface Props { appName: string; openEditAddressModal: (address: ContactAddressFragment, id: string) => void; openNewAddressModal: (address: ContactAddressFragment, id: string) => void; + setContactFocus: SetContactFocus; } const Contact: React.FC = ({ @@ -123,6 +127,7 @@ const Contact: React.FC = ({ appName, openEditAddressModal, openNewAddressModal, + setContactFocus, }) => { const { t } = useTranslation(); const locale = useLocale(); @@ -156,17 +161,31 @@ const Contact: React.FC = ({ }); }; + const handleContactNameClick = () => { + setContactFocus(id); + }; + return ( } + avatar={ + + } action={ } - title={{name}} + title={ + + {name} + + } subheader={{contactPartnershipStatus[status]}} /> diff --git a/src/components/Tool/FixMailingAddresses/FixMailingAddresses.test.tsx b/src/components/Tool/FixMailingAddresses/FixMailingAddresses.test.tsx index 72ac5fc2a..9cb1362cd 100644 --- a/src/components/Tool/FixMailingAddresses/FixMailingAddresses.test.tsx +++ b/src/components/Tool/FixMailingAddresses/FixMailingAddresses.test.tsx @@ -23,6 +23,7 @@ const contactId = 'contactId'; const router = { isReady: true, }; +const setContactFocus = jest.fn(); const mockEnqueue = jest.fn(); jest.mock('notistack', () => ({ @@ -53,7 +54,10 @@ const Components = ({ mocks={mocks} cache={cache} > - + @@ -61,6 +65,9 @@ const Components = ({ ); describe('FixSendNewsletter', () => { + beforeEach(() => { + setContactFocus.mockClear(); + }); it('should show noData component', async () => { const { queryByTestId, getByText } = render( { ); }); }); + + describe('setContactFocus()', () => { + it('should open up contact details', async () => { + const { getByText, queryByTestId } = render( + , + ); + await waitFor(() => + expect(queryByTestId('loading')).not.toBeInTheDocument(), + ); + expect(setContactFocus).not.toHaveBeenCalled(); + + const contactName = getByText('Baggins, Frodo'); + + expect(contactName).toBeInTheDocument(); + userEvent.click(contactName); + expect(setContactFocus).toHaveBeenCalledWith(contactId); + }); + }); }); diff --git a/src/components/Tool/FixMailingAddresses/FixMailingAddresses.tsx b/src/components/Tool/FixMailingAddresses/FixMailingAddresses.tsx index 6f0b53389..086bc13ea 100644 --- a/src/components/Tool/FixMailingAddresses/FixMailingAddresses.tsx +++ b/src/components/Tool/FixMailingAddresses/FixMailingAddresses.tsx @@ -15,6 +15,7 @@ import { } from '@mui/material'; import { Trans, useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; +import { SetContactFocus } from 'pages/accountLists/[accountListId]/tools/useToolsHelper'; import { DynamicAddAddressModal } from 'src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/AddAddressModal/DynamicAddAddressModal'; import { DynamicEditContactAddressModal } from 'src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/EditContactAddressModal/DynamicEditContactAddressModal'; import theme from '../../../theme'; @@ -110,6 +111,7 @@ export const emptyAddress: ContactAddressFragment = { interface Props { accountListId: string; + setContactFocus: SetContactFocus; } enum ModalEnum { New = 'New', @@ -118,7 +120,10 @@ enum ModalEnum { const sourceOptions = [appName, 'DataServer']; -const FixSendNewsletter: React.FC = ({ accountListId }: Props) => { +const FixSendNewsletter: React.FC = ({ + accountListId, + setContactFocus, +}: Props) => { const { classes } = useStyles(); const { t } = useTranslation(); const [showEditAddressModal, setShowEditAddressModal] = useState(false); @@ -297,6 +302,7 @@ const FixSendNewsletter: React.FC = ({ accountListId }: Props) => { openNewAddressModal={(address, contactId) => handleModalOpen(ModalEnum.New, address, contactId) } + setContactFocus={setContactFocus} /> ))} diff --git a/src/components/Tool/FixPhoneNumbers/Contact.test.tsx b/src/components/Tool/FixPhoneNumbers/Contact.test.tsx index e5e355bdc..f63fef861 100644 --- a/src/components/Tool/FixPhoneNumbers/Contact.test.tsx +++ b/src/components/Tool/FixPhoneNumbers/Contact.test.tsx @@ -27,6 +27,8 @@ const testData = { ], }; +const setContactFocus = jest.fn(); + describe('FixPhoneNumbers-Contact', () => { it('default', () => { const handleChangeMock = jest.fn(); @@ -47,6 +49,7 @@ describe('FixPhoneNumbers-Contact', () => { handleDelete={handleDeleteModalOpenMock} handleAdd={handleAddMock} handleChangePrimary={handleChangePrimaryMock} + setContactFocus={setContactFocus} /> , @@ -78,6 +81,7 @@ describe('FixPhoneNumbers-Contact', () => { handleDelete={handleDeleteModalOpenMock} handleAdd={handleAddMock} handleChangePrimary={handleChangePrimaryMock} + setContactFocus={setContactFocus} /> , @@ -113,6 +117,7 @@ describe('FixPhoneNumbers-Contact', () => { handleDelete={handleDeleteModalOpenMock} handleAdd={handleAddMock} handleChangePrimary={handleChangePrimaryMock} + setContactFocus={setContactFocus} /> , diff --git a/src/components/Tool/FixPhoneNumbers/Contact.tsx b/src/components/Tool/FixPhoneNumbers/Contact.tsx index b52a3f877..425f0ba55 100644 --- a/src/components/Tool/FixPhoneNumbers/Contact.tsx +++ b/src/components/Tool/FixPhoneNumbers/Contact.tsx @@ -9,6 +9,7 @@ import { Button, Grid, Hidden, + Link, TextField, Theme, Typography, @@ -17,6 +18,7 @@ import clsx from 'clsx'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; +import { SetContactFocus } from 'pages/accountLists/[accountListId]/tools/useToolsHelper'; import { PersonPhoneNumberInput } from 'src/graphql/types.generated'; import { useLocale } from 'src/hooks/useLocale'; import { dateFormatShort } from 'src/lib/intlFormat'; @@ -111,6 +113,7 @@ interface Props { handleDelete: (personId: string, phoneNumber: number) => void; handleAdd: (personId: string, number: string) => void; handleChangePrimary: (personId: string, numberIndex: number) => void; + setContactFocus: SetContactFocus; } const Contact: React.FC = ({ @@ -121,6 +124,9 @@ const Contact: React.FC = ({ handleDelete, handleAdd, handleChangePrimary, + // Remove below line when function is being used. + // eslint-disable-next-line @typescript-eslint/no-unused-vars + setContactFocus, }) => { const { t } = useTranslation(); const locale = useLocale(); @@ -142,6 +148,13 @@ const Contact: React.FC = ({ } }; + const handleContactNameClick = () => { + // This currently doesn't work as we need to add the contactId onto the person graphQL endpoint. + // I've asked Andrew to add it here: https://cru-main.slack.com/archives/CG47BDCG6/p1718721024211409 + // You'll need that to run the below function + // setContactFocus(id); + }; + return ( @@ -157,7 +170,9 @@ const Contact: React.FC = ({ > - {name} + + {name} + diff --git a/src/components/Tool/FixPhoneNumbers/FixPhoneNumbers.test.tsx b/src/components/Tool/FixPhoneNumbers/FixPhoneNumbers.test.tsx index e6bb9e260..9ad81f0e6 100644 --- a/src/components/Tool/FixPhoneNumbers/FixPhoneNumbers.test.tsx +++ b/src/components/Tool/FixPhoneNumbers/FixPhoneNumbers.test.tsx @@ -16,7 +16,7 @@ const router = { query: { accountListId }, isReady: true, }; - +const setContactFocus = jest.fn(); const testData: ErgonoMockShape[] = [ { id: 'testid', @@ -90,7 +90,10 @@ describe('FixPhoneNumbers-Home', () => { }, }} > - + @@ -125,7 +128,10 @@ describe('FixPhoneNumbers-Home', () => { }, }} > - + @@ -156,7 +162,10 @@ describe('FixPhoneNumbers-Home', () => { }, }} > - + @@ -188,7 +197,10 @@ describe('FixPhoneNumbers-Home', () => { }, }} > - + @@ -226,7 +238,10 @@ describe('FixPhoneNumbers-Home', () => { }, }} > - + @@ -265,7 +280,10 @@ describe('FixPhoneNumbers-Home', () => { }, }} > - + @@ -295,7 +313,10 @@ describe('FixPhoneNumbers-Home', () => { }, }} > - + diff --git a/src/components/Tool/FixPhoneNumbers/FixPhoneNumbers.tsx b/src/components/Tool/FixPhoneNumbers/FixPhoneNumbers.tsx index 95f425d73..2b08cbca3 100644 --- a/src/components/Tool/FixPhoneNumbers/FixPhoneNumbers.tsx +++ b/src/components/Tool/FixPhoneNumbers/FixPhoneNumbers.tsx @@ -12,6 +12,7 @@ import { } from '@mui/material'; import { Trans, useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; +import { SetContactFocus } from 'pages/accountLists/[accountListId]/tools/useToolsHelper'; import { PersonPhoneNumberInput } from 'src/graphql/types.generated'; import theme from '../../../theme'; import NoData from '../NoData'; @@ -98,10 +99,6 @@ const defaultDeleteModalState = { phoneNumber: '', }; -interface Props { - accountListId: string; -} - export interface PhoneNumberData { id?: string; primary: boolean; @@ -116,7 +113,15 @@ interface PersonPhoneNumbers { toDelete: PersonPhoneNumberInput[]; } -const FixPhoneNumbers: React.FC = ({ accountListId }: Props) => { +interface Props { + accountListId: string; + setContactFocus: SetContactFocus; +} + +const FixPhoneNumbers: React.FC = ({ + accountListId, + setContactFocus, +}: Props) => { const { classes } = useStyles(); const [defaultSource, setDefaultSource] = useState('MPDX'); @@ -311,6 +316,7 @@ const FixPhoneNumbers: React.FC = ({ accountListId }: Props) => { handleDelete={handleDeleteModalOpen} handleAdd={handleAdd} handleChangePrimary={handleChangePrimary} + setContactFocus={setContactFocus} /> ))} diff --git a/src/components/Tool/FixSendNewsletter/Contact.tsx b/src/components/Tool/FixSendNewsletter/Contact.tsx index 5eb49329c..9003836ee 100644 --- a/src/components/Tool/FixSendNewsletter/Contact.tsx +++ b/src/components/Tool/FixSendNewsletter/Contact.tsx @@ -6,11 +6,13 @@ import { Box, Button, Grid, + Link, NativeSelect, Typography, } from '@mui/material'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; +import { SetContactFocus } from 'pages/accountLists/[accountListId]/tools/useToolsHelper'; import theme from '../../../theme'; import { StyledInput } from '../StyledInput'; import { @@ -83,6 +85,7 @@ interface Props { primaryAddress?: ContactPrimaryAddressFragment; source?: string; updateFunction: (id: string, sendNewsletter: string) => Promise; + setContactFocus: SetContactFocus; } const Contact = ({ @@ -92,13 +95,14 @@ const Contact = ({ status, primaryAddress, updateFunction, + setContactFocus, }: Props): ReactElement => { const { t } = useTranslation(); const [newsletter, setNewsletter] = useState('BOTH'); const { classes } = useStyles(); //TODO: Add button functionality - //TODO: Mkae contact name a link to contact page + //TODO: Make contact name a link to contact page const handleChange = ( event: @@ -108,6 +112,10 @@ const Contact = ({ setNewsletter(event.target.value); }; + const handleContactNameClick = () => { + setContactFocus(id); + }; + return ( @@ -129,7 +137,9 @@ const Contact = ({ }} /> - {name} + + {name} + {status} diff --git a/src/components/Tool/FixSendNewsletter/FixSendNewsletter.tsx b/src/components/Tool/FixSendNewsletter/FixSendNewsletter.tsx index 996389433..4eb61810b 100644 --- a/src/components/Tool/FixSendNewsletter/FixSendNewsletter.tsx +++ b/src/components/Tool/FixSendNewsletter/FixSendNewsletter.tsx @@ -12,6 +12,7 @@ import { import { useSnackbar } from 'notistack'; import { Trans, useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; +import { SetContactFocus } from 'pages/accountLists/[accountListId]/tools/useToolsHelper'; import { SendNewsletterEnum } from 'src/graphql/types.generated'; import theme from '../../../theme'; import NoData from '../NoData'; @@ -62,9 +63,13 @@ const useStyles = makeStyles()(() => ({ interface Props { accountListId: string; + setContactFocus: SetContactFocus; } -const FixSendNewsletter: React.FC = ({ accountListId }: Props) => { +const FixSendNewsletter: React.FC = ({ + accountListId, + setContactFocus, +}: Props) => { const { classes } = useStyles(); const { t } = useTranslation(); const { enqueueSnackbar } = useSnackbar(); @@ -190,6 +195,7 @@ const FixSendNewsletter: React.FC = ({ accountListId }: Props) => { } } updateFunction={updateContact} + setContactFocus={setContactFocus} /> ))} diff --git a/src/components/Tool/MergeContacts/Contact.tsx b/src/components/Tool/MergeContacts/Contact.tsx index d758f2b02..9beae2de0 100644 --- a/src/components/Tool/MergeContacts/Contact.tsx +++ b/src/components/Tool/MergeContacts/Contact.tsx @@ -13,11 +13,13 @@ import { Grid, Hidden, IconButton, + Link, Typography, } from '@mui/material'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; +import { SetContactFocus } from 'pages/accountLists/[accountListId]/tools/useToolsHelper'; import { useLocale } from 'src/hooks/useLocale'; import { dateFormatShort } from 'src/lib/intlFormat'; import { contactPartnershipStatus } from 'src/utils/contacts/contactPartnershipStatus'; @@ -76,9 +78,15 @@ interface Props { contact1: RecordInfoFragment; contact2: RecordInfoFragment; update: (id1: string, id2: string, action: string) => void; + setContactFocus: SetContactFocus; } -const Contact: React.FC = ({ contact1, contact2, update }) => { +const Contact: React.FC = ({ + contact1, + contact2, + update, + setContactFocus, +}) => { const [selected, setSelected] = useState('none'); const { t } = useTranslation(); const locale = useLocale(); @@ -106,6 +114,10 @@ const Contact: React.FC = ({ contact1, contact2, update }) => { } }; + const handleContactNameClick = (contactId) => { + setContactFocus(contactId); + }; + return ( @@ -147,7 +159,12 @@ const Contact: React.FC = ({ contact1, contact2, update }) => { width: '100%', }} > - {contact1.name} + handleContactNameClick(contact1.id)} + > + {contact1.name} + {contact1.status && ( @@ -290,7 +307,14 @@ const Contact: React.FC = ({ contact1, contact2, update }) => { {t('Use this one')} )} - {contact2.name} + + handleContactNameClick(contact2.id)} + > + {contact2.name} + + {contact2.status && ( {t('Status: {{status}}', { diff --git a/src/components/Tool/MergeContacts/MergeContacts.tsx b/src/components/Tool/MergeContacts/MergeContacts.tsx index 935e6b96f..5fdf9b1b3 100644 --- a/src/components/Tool/MergeContacts/MergeContacts.tsx +++ b/src/components/Tool/MergeContacts/MergeContacts.tsx @@ -9,6 +9,7 @@ import { } from '@mui/material'; import { Trans, useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; +import { SetContactFocus } from 'pages/accountLists/[accountListId]/tools/useToolsHelper'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; import theme from '../../../theme'; import NoData from '../NoData'; @@ -59,9 +60,13 @@ interface ActionType { interface Props { accountListId: string; + setContactFocus: SetContactFocus; } -const MergeContacts: React.FC = ({ accountListId }: Props) => { +const MergeContacts: React.FC = ({ + accountListId, + setContactFocus, +}: Props) => { const { classes } = useStyles(); const [actions, setActions] = useState>({}); const { t } = useTranslation(); @@ -141,6 +146,7 @@ const MergeContacts: React.FC = ({ accountListId }: Props) => { contact1={duplicate.recordOne} contact2={duplicate.recordTwo} update={updateActions} + setContactFocus={setContactFocus} /> ))} diff --git a/src/components/Tool/MergePeople/MergePeople.tsx b/src/components/Tool/MergePeople/MergePeople.tsx index cfd8b8c8f..5ca8deffa 100644 --- a/src/components/Tool/MergePeople/MergePeople.tsx +++ b/src/components/Tool/MergePeople/MergePeople.tsx @@ -9,6 +9,7 @@ import { } from '@mui/material'; import { Trans, useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; +import { SetContactFocus } from 'pages/accountLists/[accountListId]/tools/useToolsHelper'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; import theme from '../../../theme'; import NoData from '../NoData'; @@ -63,9 +64,13 @@ interface ActionsType { interface Props { accountListId: string; + setContactFocus: SetContactFocus; } -const MergePeople: React.FC = ({ accountListId }: Props) => { +const MergePeople: React.FC = ({ + accountListId, + setContactFocus, +}: Props) => { const { classes } = useStyles(); const [actions, setActions] = useState({}); const { t } = useTranslation(); @@ -145,6 +150,7 @@ const MergePeople: React.FC = ({ accountListId }: Props) => { person1={duplicate.recordOne} person2={duplicate.recordTwo} update={updateActions} + setContactFocus={setContactFocus} /> ))} diff --git a/src/components/Tool/MergePeople/PersonDuplicates.tsx b/src/components/Tool/MergePeople/PersonDuplicates.tsx index 9abe4579e..2ac251edc 100644 --- a/src/components/Tool/MergePeople/PersonDuplicates.tsx +++ b/src/components/Tool/MergePeople/PersonDuplicates.tsx @@ -13,11 +13,13 @@ import { Grid, Hidden, IconButton, + Link, Typography, } from '@mui/material'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; +import { SetContactFocus } from 'pages/accountLists/[accountListId]/tools/useToolsHelper'; import { useLocale } from 'src/hooks/useLocale'; import { dateFormatShort } from 'src/lib/intlFormat'; import theme from '../../../theme'; @@ -75,9 +77,17 @@ interface Props { person1: PersonInfoFragment; person2: PersonInfoFragment; update: (id1: string, id2: string, action: string) => void; + setContactFocus: SetContactFocus; } -const PersonDuplicate: React.FC = ({ person1, person2, update }) => { +const PersonDuplicate: React.FC = ({ + person1, + person2, + update, + // Remove below line when function is being used. + // eslint-disable-next-line @typescript-eslint/no-unused-vars + setContactFocus, +}) => { const [selected, setSelected] = useState('none'); const { t } = useTranslation(); const locale = useLocale(); @@ -105,6 +115,14 @@ const PersonDuplicate: React.FC = ({ person1, person2, update }) => { } }; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const handleContactNameClick = (contactId) => { + // This currently doesn't work as we need to add the contactId onto the person graphQL endpoint. + // I've asked Andrew to add it here: https://cru-main.slack.com/archives/CG47BDCG6/p1718721024211409 + // You'll need that to run the below function + // setContactFocus(contactId); + }; + return ( @@ -146,7 +164,12 @@ const PersonDuplicate: React.FC = ({ person1, person2, update }) => { width: '100%', }} > - {`${person1.firstName} ${person1.lastName}`} + handleContactNameClick('')} + > + {`${person1.firstName} ${person1.lastName}`} + {person1.primaryPhoneNumber ? ( @@ -294,7 +317,12 @@ const PersonDuplicate: React.FC = ({ person1, person2, update }) => { {t('Use this one')} )} - {`${person1.firstName} ${person1.lastName}`} + handleContactNameClick('')} + > + {`${person2.firstName} ${person2.lastName}`} + {person1.primaryPhoneNumber ? ( <>