Skip to content

Commit

Permalink
MPDX-8226 Edit Partnership Info & Contact Header (#1081)
Browse files Browse the repository at this point in the history
* Contact Header improve styles

* Contact Details Tab improve styles and organization

* Edit Contact Other Modal add new fields

* Edit Partnership Info Modal add new fields

* Prevent contact address from showing null

* Unstar title and syntax changes
  • Loading branch information
caleballdrin committed Sep 19, 2024
1 parent d6e415c commit e584ed2
Show file tree
Hide file tree
Showing 50 changed files with 1,140 additions and 1,108 deletions.
4 changes: 2 additions & 2 deletions src/components/Contacts/CelebrationIcons/CelebrationIcons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ export const CelebrationIcons: React.FC<Props> = ({ contact }) => {
<>
{contactHasAnniversary() ? (
<IconContainer>
<RingIcon color="disabled" titleAccess={t('Ring')} />
<RingIcon color="disabled" titleAccess={t('Anniversary')} />
</IconContainer>
) : null}
{contactHasBirthday() ? (
<IconContainer>
<Cake color="disabled" titleAccess={t('Cake')} />
<Cake color="disabled" titleAccess={t('Birthday')} />
</IconContainer>
) : null}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ it('should display ring', () => {
});
const { getByRole } = render(<CelebrationIcons contact={mock} />);

expect(getByRole('img', { hidden: true, name: 'Cake' })).toBeVisible();
expect(getByRole('img', { hidden: true, name: 'Ring' })).toBeVisible();
expect(getByRole('img', { hidden: true, name: 'Birthday' })).toBeVisible();
expect(getByRole('img', { hidden: true, name: 'Anniversary' })).toBeVisible();
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React from 'react';
import { ThemeProvider } from '@mui/material/styles';
import { LocalizationProvider } from '@mui/x-date-pickers';
import { AdapterLuxon } from '@mui/x-date-pickers/AdapterLuxon';
import { render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { SnackbarProvider } from 'notistack';
Expand Down Expand Up @@ -129,111 +131,117 @@ describe('ContactDetails', () => {
expect(queryByTestId('Skeleton')).toBeNull();
});

it('should open edit contact details modal', async () => {
it('should open Edit Partnership modal', async () => {
const { queryByText, getAllByLabelText } = render(
<SnackbarProvider>
<TestRouter router={router}>
<ThemeProvider theme={theme}>
<GqlMockedProvider<{
GetContactDetailsHeader: GetContactDetailsHeaderQuery;
}>
mocks={mocks}
>
<ContactsWrapper>
<ContactDetailProvider>
<ContactDetailsHeader
accountListId={accountListId}
contactId={contactId}
onClose={() => {}}
setContactDetailsLoaded={() => {}}
contactDetailsLoaded={false}
/>
</ContactDetailProvider>
</ContactsWrapper>
</GqlMockedProvider>
</ThemeProvider>
</TestRouter>
<LocalizationProvider dateAdapter={AdapterLuxon}>
<TestRouter router={router}>
<ThemeProvider theme={theme}>
<GqlMockedProvider<{
GetContactDetailsHeader: GetContactDetailsHeaderQuery;
}>
mocks={mocks}
>
<ContactsWrapper>
<ContactDetailProvider>
<ContactDetailsHeader
accountListId={accountListId}
contactId={contactId}
onClose={() => {}}
setContactDetailsLoaded={() => {}}
contactDetailsLoaded={false}
/>
</ContactDetailProvider>
</ContactsWrapper>
</GqlMockedProvider>
</ThemeProvider>
</TestRouter>
</LocalizationProvider>
</SnackbarProvider>,
);
await waitFor(() =>
expect(getAllByLabelText('Edit Icon')[0]).toBeInTheDocument(),
expect(getAllByLabelText('Edit Partnership Info')[0]).toBeInTheDocument(),
);
userEvent.click(getAllByLabelText('Edit Icon')[0]);
userEvent.click(getAllByLabelText('Edit Partnership Info')[0]);
await waitFor(() =>
expect(queryByText('Edit Contact Details')).toBeInTheDocument(),
expect(queryByText('Edit Partnership')).toBeInTheDocument(),
);
});

it('should close edit contact address modal', async () => {
it('should close Edit Partnership modal', async () => {
const { queryByText, getAllByLabelText, getByLabelText } = render(
<SnackbarProvider>
<TestRouter router={router}>
<ThemeProvider theme={theme}>
<GqlMockedProvider<{
GetContactDetailsHeader: GetContactDetailsHeaderQuery;
}>
mocks={mocks}
>
<ContactsWrapper>
<ContactDetailProvider>
<ContactDetailsHeader
accountListId={accountListId}
contactId={contactId}
onClose={() => {}}
setContactDetailsLoaded={() => {}}
contactDetailsLoaded={false}
/>
</ContactDetailProvider>
</ContactsWrapper>
</GqlMockedProvider>
</ThemeProvider>
</TestRouter>
<LocalizationProvider dateAdapter={AdapterLuxon}>
<TestRouter router={router}>
<ThemeProvider theme={theme}>
<GqlMockedProvider<{
GetContactDetailsHeader: GetContactDetailsHeaderQuery;
}>
mocks={mocks}
>
<ContactsWrapper>
<ContactDetailProvider>
<ContactDetailsHeader
accountListId={accountListId}
contactId={contactId}
onClose={() => {}}
setContactDetailsLoaded={() => {}}
contactDetailsLoaded={false}
/>
</ContactDetailProvider>
</ContactsWrapper>
</GqlMockedProvider>
</ThemeProvider>
</TestRouter>
</LocalizationProvider>
</SnackbarProvider>,
);
await waitFor(() =>
expect(getAllByLabelText('Edit Icon')[0]).toBeInTheDocument(),
expect(getAllByLabelText('Edit Partnership Info')[0]).toBeInTheDocument(),
);
userEvent.click(getAllByLabelText('Edit Icon')[0]);
userEvent.click(getAllByLabelText('Edit Partnership Info')[0]);
await waitFor(() =>
expect(queryByText('Edit Contact Details')).toBeInTheDocument(),
expect(queryByText('Edit Partnership')).toBeInTheDocument(),
);
userEvent.click(getByLabelText('Close'));
await waitFor(() =>
expect(queryByText('Edit Contact Details')).not.toBeInTheDocument(),
expect(queryByText('Edit Partnership')).not.toBeInTheDocument(),
);
});
it('should render avatar', async () => {
const { queryByText, getAllByLabelText } = render(
<SnackbarProvider>
<TestRouter router={router}>
<ThemeProvider theme={theme}>
<GqlMockedProvider<{
GetContactDetailsHeader: GetContactDetailsHeaderQuery;
}>
mocks={mocks}
>
<ContactsWrapper>
<ContactDetailProvider>
<ContactDetailsHeader
accountListId={accountListId}
contactId={contactId}
onClose={() => {}}
setContactDetailsLoaded={() => {}}
contactDetailsLoaded={false}
/>
</ContactDetailProvider>
</ContactsWrapper>
</GqlMockedProvider>
</ThemeProvider>
</TestRouter>
<LocalizationProvider dateAdapter={AdapterLuxon}>
<TestRouter router={router}>
<ThemeProvider theme={theme}>
<GqlMockedProvider<{
GetContactDetailsHeader: GetContactDetailsHeaderQuery;
}>
mocks={mocks}
>
<ContactsWrapper>
<ContactDetailProvider>
<ContactDetailsHeader
accountListId={accountListId}
contactId={contactId}
onClose={() => {}}
setContactDetailsLoaded={() => {}}
contactDetailsLoaded={false}
/>
</ContactDetailProvider>
</ContactsWrapper>
</GqlMockedProvider>
</ThemeProvider>
</TestRouter>
</LocalizationProvider>
</SnackbarProvider>,
);
await waitFor(() =>
expect(getAllByLabelText('Edit Icon')[0]).toBeInTheDocument(),
expect(getAllByLabelText('Edit Partnership Info')[0]).toBeInTheDocument(),
);
userEvent.click(getAllByLabelText('Edit Icon')[0]);
userEvent.click(getAllByLabelText('Edit Partnership Info')[0]);
await waitFor(() =>
expect(queryByText('Edit Contact Details')).toBeInTheDocument(),
expect(queryByText('Edit Partnership Info')).toBeInTheDocument(),
);

const avatarImage = document.querySelector('img') as HTMLImageElement;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import Close from '@mui/icons-material/Close';
import { Avatar, Box, IconButton, Skeleton, Typography } from '@mui/material';
import { styled } from '@mui/material/styles';
Expand All @@ -7,18 +7,13 @@ import { StatusEnum } from 'src/graphql/types.generated';
import { ContactContextTypesEnum } from 'src/lib/contactContextTypes';
import theme from '../../../../theme';
import { StarContactIconButton } from '../../StarContactIconButton/StarContactIconButton';
import {
ContactDetailContext,
ContactDetailsType,
} from '../ContactDetailContext';
import { EditContactDetailsModal } from '../ContactDetailsTab/People/Items/EditContactDetailsModal/EditContactDetailsModal';
import { EditIcon } from '../ContactDetailsTab/StyledComponents';
import { EditPartnershipInfoModal } from '../ContactDonationsTab/PartnershipInfo/EditPartnershipInfoModal/EditPartnershipInfoModal';
import { useGetContactDetailsHeaderQuery } from './ContactDetailsHeader.generated';
import { ContactDetailsMoreAcitions } from './ContactDetailsMoreActions/ContactDetailsMoreActions';
import { ContactHeaderAddressSection } from './ContactHeaderSection/ContactHeaderAddressSection';
import { ContactHeaderEmailSection } from './ContactHeaderSection/ContactHeaderEmailSection';
import { ContactHeaderNewsletterSection } from './ContactHeaderSection/ContactHeaderNewsletterSection';
import { ContactHeaderPartnerSection } from './ContactHeaderSection/ContactHeaderPartnerSection';
import { ContactHeaderPhoneSection } from './ContactHeaderSection/ContactHeaderPhoneSection';
import { ContactHeaderStatusSection } from './ContactHeaderSection/ContactHeaderStatusSection';

Expand Down Expand Up @@ -46,18 +41,18 @@ const HeaderBarButtonsWrap = styled(Box)(({}) => ({
}));
const ContactAvatar = styled(Avatar)(({}) => ({
backgroundColor: theme.palette.secondary.dark,
height: 64,
width: 64,
borderRadius: 32,
height: 50,
width: 50,
borderRadius: 25,
}));
const PrimaryContactName = styled(Typography)(({}) => ({
display: 'inline',
marginLeft: 18,
fontWeight: 'bold',
}));
const CloseButtonIcon = styled(Close)(({}) => ({
width: 14,
height: 14,
width: 24,
height: 24,
color: theme.palette.text.primary,
}));
const HeaderSectionWrap = styled(Box)(({}) => ({
Expand All @@ -78,9 +73,8 @@ export const ContactDetailsHeader: React.FC<Props> = ({
const loading = !data;
const { t } = useTranslation();

const { editModalOpen, setEditModalOpen } = React.useContext(
ContactDetailContext,
) as ContactDetailsType;
const [editPartnershipModalOpen, setEditPartnershipModalOpen] =
useState(false);

useEffect(() => {
if (!loading && !contactDetailsLoaded) {
Expand All @@ -90,11 +84,11 @@ export const ContactDetailsHeader: React.FC<Props> = ({
}, [loading]);

return (
<Box style={{ padding: 24, backgroundColor: 'transparent' }}>
<Box sx={{ padding: 2, backgroundColor: 'transparent' }}>
<HeaderBar>
<ContactAvatar alt={data?.contact.name} src={data?.contact.avatar} />
<HeaderBarContactWrap>
{!data ? (
{!data?.contact ? (
<Box data-testid="Skeleton">
<Skeleton
variant="text"
Expand All @@ -106,19 +100,22 @@ export const ContactDetailsHeader: React.FC<Props> = ({
}}
/>
</Box>
) : data.contact ? (
) : (
<>
<PrimaryContactName data-testid="ContactName" variant="h5">
{data.contact.name}
{data?.contact.name}
</PrimaryContactName>
<IconButton
onClick={() => setEditModalOpen(true)}
aria-label={t('Edit Icon')}
onClick={() => setEditPartnershipModalOpen(true)}
aria-label={t('Edit Partnership Info')}
>
<EditIcon />
<EditIcon
titleAccess={t('Edit Partnership Info')}
sx={{ width: '24px', height: '24px' }}
/>
</IconButton>
</>
) : null}
)}
</HeaderBarContactWrap>
<HeaderBarButtonsWrap>
<StarContactIconButton
Expand Down Expand Up @@ -156,10 +153,6 @@ export const ContactDetailsHeader: React.FC<Props> = ({
/>
</Box>
<Box flex={1}>
<ContactHeaderPartnerSection
loading={loading}
contact={data?.contact}
/>
<ContactHeaderStatusSection
loading={loading}
contact={data?.contact}
Expand All @@ -170,12 +163,10 @@ export const ContactDetailsHeader: React.FC<Props> = ({
/>
</Box>
</HeaderSectionWrap>
{data && (
<EditContactDetailsModal
accountListId={accountListId}
contact={data.contact}
isOpen={editModalOpen}
handleClose={() => setEditModalOpen(false)}
{data?.contact && editPartnershipModalOpen && (
<EditPartnershipInfoModal
contact={data?.contact}
handleClose={() => setEditPartnershipModalOpen(false)}
/>
)}
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ type AddMenuItem = {
};

const MoreButtonIcon = styled(MoreVert)(({ theme }) => ({
width: 16,
height: 16,
width: 24,
height: 24,
color: theme.palette.text.primary,
}));

Expand Down Expand Up @@ -265,7 +265,7 @@ export const ContactDetailsMoreAcitions: React.FC<
aria-haspopup="true"
onClick={(event) => setAnchorEl(event.currentTarget)}
>
<MoreButtonIcon titleAccess="More Actions" />
<MoreButtonIcon titleAccess={t('More Actions')} />
</IconButton>
<MenuContainer
id="add-menu"
Expand Down
Loading

0 comments on commit e584ed2

Please sign in to comment.