From 2f6fa59ff1f7d27a935bb71b9fdea6a365698a31 Mon Sep 17 00:00:00 2001 From: Yurii Hryshchenko Date: Fri, 22 Sep 2023 14:36:37 +0300 Subject: [PATCH 1/4] Add button to cancel changes, add eventListener to handle closing tab and asking user via popup to stay or close the tab. --- src/components/Form/Buttons/BasicButton.tsx | 1 - src/components/Form/Buttons/CancelButton.tsx | 24 +++++++++++++++ .../Buttons/__tests__/CancelButton.test.tsx | 27 +++++++++++++++++ src/components/Form/Buttons/index.ts | 1 + .../Form/Buttons/styles/BasicButton.style.tsx | 10 ++++++- .../Buttons/styles/CancelButton.style.tsx | 27 +++++++++++++++++ src/locales/uk/parts/common.ts | 1 + .../Profile/PersonalInfo/PersonalInfo.tsx | 30 +++++++++++++++---- .../styles/PersonalInfo.styles.ts | 10 +++++-- 9 files changed, 121 insertions(+), 10 deletions(-) create mode 100644 src/components/Form/Buttons/CancelButton.tsx create mode 100644 src/components/Form/Buttons/__tests__/CancelButton.test.tsx create mode 100644 src/components/Form/Buttons/styles/CancelButton.style.tsx diff --git a/src/components/Form/Buttons/BasicButton.tsx b/src/components/Form/Buttons/BasicButton.tsx index 964330b0e..8417a8332 100644 --- a/src/components/Form/Buttons/BasicButton.tsx +++ b/src/components/Form/Buttons/BasicButton.tsx @@ -37,7 +37,6 @@ export const BasicButton: React.FC = ({ className={clsx(getRootClass(), className)} type="submit" variant="contained" - fullWidth disabled={disabled} onClick={onClick} > diff --git a/src/components/Form/Buttons/CancelButton.tsx b/src/components/Form/Buttons/CancelButton.tsx new file mode 100644 index 000000000..43d3335b9 --- /dev/null +++ b/src/components/Form/Buttons/CancelButton.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { Button } from '@material-ui/core'; +import { useStyles } from './styles/CancelButton.style'; + +type CancelButtonPropsType = { + label: string; + onClick?: React.MouseEventHandler; +}; +export const CancelButton: React.FC = ({ + label, + onClick, +}) => { + const classes = useStyles(); + + return ( + + ); +}; diff --git a/src/components/Form/Buttons/__tests__/CancelButton.test.tsx b/src/components/Form/Buttons/__tests__/CancelButton.test.tsx new file mode 100644 index 000000000..a402b96c3 --- /dev/null +++ b/src/components/Form/Buttons/__tests__/CancelButton.test.tsx @@ -0,0 +1,27 @@ +import { render, screen } from '@testing-library/react'; +import React from 'react'; +import userEvent, { TargetElement } from '@testing-library/user-event'; +import { CancelButton } from '../CancelButton'; + +describe('Test for CancelButton component', () => { + it('Should render a button', () => { + const { container } = render(); + expect(container.firstChild).toHaveClass('CancelButton-cancelButton-1'); + }); + + it('Should render a label properly', () => { + render(); + const label = screen.getByText('Hello world'); + + expect(label).toBeInTheDocument(); + }); + + it('Should handle onClick', () => { + const handleClick = jest.fn(); + const { container } = render( + , + ); + userEvent.click(container.firstChild as TargetElement); + expect(handleClick).toBeCalled(); + }); +}); diff --git a/src/components/Form/Buttons/index.ts b/src/components/Form/Buttons/index.ts index c0cfceb8a..1520fcaa5 100644 --- a/src/components/Form/Buttons/index.ts +++ b/src/components/Form/Buttons/index.ts @@ -1 +1,2 @@ export { BasicButton } from './BasicButton'; +export { CancelButton } from './CancelButton'; diff --git a/src/components/Form/Buttons/styles/BasicButton.style.tsx b/src/components/Form/Buttons/styles/BasicButton.style.tsx index 975d9ff1e..0959d2885 100644 --- a/src/components/Form/Buttons/styles/BasicButton.style.tsx +++ b/src/components/Form/Buttons/styles/BasicButton.style.tsx @@ -12,8 +12,8 @@ export const useStyles = makeStyles( basicSignButton: { padding: theme.spacing(3.2, 8.8), borderRadius: theme.spacing(10), + flex: '0 1 300px', marginRight: 0, - alignSelf: 'flex-end', backgroundColor: '#FF5C00', '& .MuiButton-label': { color: theme.palette.common.white, @@ -24,6 +24,14 @@ export const useStyles = makeStyles( '&:hover': { backgroundColor: '#ffaa00', }, + [theme.breakpoints.down('sm')]: { + flex: '0 1 auto', + padding: theme.spacing(2, 3.1), + '& .MuiButton-label': { + fontWeight: 600, + fontSize: '15px', + }, + }, }, }), { diff --git a/src/components/Form/Buttons/styles/CancelButton.style.tsx b/src/components/Form/Buttons/styles/CancelButton.style.tsx new file mode 100644 index 000000000..e598cd257 --- /dev/null +++ b/src/components/Form/Buttons/styles/CancelButton.style.tsx @@ -0,0 +1,27 @@ +import { makeStyles, Theme } from '@material-ui/core'; + +export const useStyles = makeStyles( + (theme: Theme) => ({ + cancelButton: { + flex: '0 1 300px', + backgroundColor: theme.palette.info.light, + '& .MuiButton-label': { + color: theme.palette.common.white, + fontWeight: 700, + fontSize: '18px', + fontFamily: 'Raleway', + }, + '&:hover': { + backgroundColor: theme.palette.info.main, + }, + [theme.breakpoints.down('sm')]: { + flex: '0 1 auto', + '& .MuiButton-label': { + fontWeight: 600, + fontSize: '15px', + }, + }, + }, + }), + { name: 'CancelButton' }, +); diff --git a/src/locales/uk/parts/common.ts b/src/locales/uk/parts/common.ts index ddab2d382..4e080f516 100644 --- a/src/locales/uk/parts/common.ts +++ b/src/locales/uk/parts/common.ts @@ -58,6 +58,7 @@ export const common = { enterTagName: 'Введіть назву тега', showMore: 'Показати ще', acceptChanges: 'Підтвердити зміни', + cancelChanges: 'Скасувати зміни', selectedMaterials: 'Обрані матеріали', publishedMaterials: 'Опубліковані матеріали', unPublishedMaterials: 'Неопубліковані матеріали', diff --git a/src/views/Profile/PersonalInfo/PersonalInfo.tsx b/src/views/Profile/PersonalInfo/PersonalInfo.tsx index 0e507704e..bf5cb586c 100644 --- a/src/views/Profile/PersonalInfo/PersonalInfo.tsx +++ b/src/views/Profile/PersonalInfo/PersonalInfo.tsx @@ -1,14 +1,14 @@ import React, { useEffect, useMemo, useState } from 'react'; import { Avatar, - Grid, - TextField, - InputLabel, Box, + Grid, IconButton, + InputLabel, + TextField, Typography, } from '@material-ui/core'; -import { BasicButton } from 'components/Form'; +import { BasicButton, CancelButton } from 'components/Form'; import { PhotoCamera } from '@material-ui/icons'; import { uploadImageToImgur } from 'old/lib/utilities/Imgur/uploadImageToImgur'; import { getStringFromFile } from 'old/lib/utilities/Imgur/getStringFromFile'; @@ -44,7 +44,7 @@ export const PersonalInfo: React.FC = ({ author }) => { twitter: false, linkedin: false, }); - const [toggleButton, setToggleButton] = useState(true); + const [toggleButton, setToggleButton] = useState(false); const [newAuthorValues, setNewAuthorValues] = useState({ avatar: author?.avatar ?? '', @@ -200,6 +200,19 @@ export const PersonalInfo: React.FC = ({ author }) => { [errorMessages], ); + useEffect(() => { + const handleBeforeUnload = (e: BeforeUnloadEvent) => { + e.preventDefault(); + e.returnValue = + 'Зміни не збережені. Ви впевнені, що хочете залишити сторінку?'; + }; + + window.addEventListener('beforeunload', handleBeforeUnload); + return () => { + window.removeEventListener('beforeunload', handleBeforeUnload); + }; + }, []); + return (
@@ -363,7 +376,14 @@ export const PersonalInfo: React.FC = ({ author }) => { /> + + {author && ( + window.close()} + /> + )} Date: Fri, 22 Sep 2023 21:44:12 +0300 Subject: [PATCH 2/4] Make compare current state with previous state to show popup. Make bold font for all devices. --- .../Form/Buttons/styles/BasicButton.style.tsx | 1 - .../Form/Buttons/styles/CancelButton.style.tsx | 1 - src/views/Profile/PersonalInfo/PersonalInfo.tsx | 14 +++++++++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/components/Form/Buttons/styles/BasicButton.style.tsx b/src/components/Form/Buttons/styles/BasicButton.style.tsx index 0959d2885..45a74b6f6 100644 --- a/src/components/Form/Buttons/styles/BasicButton.style.tsx +++ b/src/components/Form/Buttons/styles/BasicButton.style.tsx @@ -28,7 +28,6 @@ export const useStyles = makeStyles( flex: '0 1 auto', padding: theme.spacing(2, 3.1), '& .MuiButton-label': { - fontWeight: 600, fontSize: '15px', }, }, diff --git a/src/components/Form/Buttons/styles/CancelButton.style.tsx b/src/components/Form/Buttons/styles/CancelButton.style.tsx index e598cd257..05b06384c 100644 --- a/src/components/Form/Buttons/styles/CancelButton.style.tsx +++ b/src/components/Form/Buttons/styles/CancelButton.style.tsx @@ -17,7 +17,6 @@ export const useStyles = makeStyles( [theme.breakpoints.down('sm')]: { flex: '0 1 auto', '& .MuiButton-label': { - fontWeight: 600, fontSize: '15px', }, }, diff --git a/src/views/Profile/PersonalInfo/PersonalInfo.tsx b/src/views/Profile/PersonalInfo/PersonalInfo.tsx index bf5cb586c..f99a709ce 100644 --- a/src/views/Profile/PersonalInfo/PersonalInfo.tsx +++ b/src/views/Profile/PersonalInfo/PersonalInfo.tsx @@ -12,6 +12,7 @@ import { BasicButton, CancelButton } from 'components/Form'; import { PhotoCamera } from '@material-ui/icons'; import { uploadImageToImgur } from 'old/lib/utilities/Imgur/uploadImageToImgur'; import { getStringFromFile } from 'old/lib/utilities/Imgur/getStringFromFile'; +import _isEqual from 'lodash/isEqual'; import { useStyles } from './styles/PersonalInfo.styles'; import { ErrorField } from './ErrorField'; import { regex } from './constants/regex'; @@ -26,6 +27,7 @@ import i18n, { langTokens } from '../../../locales/localizationInit'; import RegionCityHandler from './RegionCityHandler'; import { validation } from './constants/validation'; import { validateInput } from './utilities/validateInput'; +import { usePrevious } from '../../../old/lib/hooks/usePrevious'; export const PersonalInfo: React.FC = ({ author }) => { const classes = useStyles(); @@ -57,6 +59,7 @@ export const PersonalInfo: React.FC = ({ author }) => { socialNetwork: author?.socialNetworks ?? [null, null, null, null, null], work: author?.mainInstitution.name ?? '', }); + const previousAuthorValues = usePrevious(newAuthorValues); const errorMessages = useMemo(() => { const errors: IErrorFields = { @@ -202,16 +205,17 @@ export const PersonalInfo: React.FC = ({ author }) => { useEffect(() => { const handleBeforeUnload = (e: BeforeUnloadEvent) => { - e.preventDefault(); - e.returnValue = - 'Зміни не збережені. Ви впевнені, що хочете залишити сторінку?'; + if (!_isEqual(previousAuthorValues, newAuthorValues)) { + e.preventDefault(); + e.returnValue = + 'Зміни не збережені. Ви впевнені, що хочете залишити сторінку?'; + } }; - window.addEventListener('beforeunload', handleBeforeUnload); return () => { window.removeEventListener('beforeunload', handleBeforeUnload); }; - }, []); + }, [newAuthorValues]); return ( From 5cb56b2658c12249b8552825cc736a57cd03938f Mon Sep 17 00:00:00 2001 From: Yurii Hryshchenko Date: Sat, 23 Sep 2023 12:16:23 +0300 Subject: [PATCH 3/4] Make fontFamily for buttons globally --- src/components/Form/Buttons/styles/BasicButton.style.tsx | 2 -- src/components/Form/Buttons/styles/CancelButton.style.tsx | 1 - src/styles/theme/index.ts | 3 +++ 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Form/Buttons/styles/BasicButton.style.tsx b/src/components/Form/Buttons/styles/BasicButton.style.tsx index 45a74b6f6..a0637c21b 100644 --- a/src/components/Form/Buttons/styles/BasicButton.style.tsx +++ b/src/components/Form/Buttons/styles/BasicButton.style.tsx @@ -5,7 +5,6 @@ export const useStyles = makeStyles( basicAcceptButton: { marginTop: theme.spacing(7), padding: theme.spacing(3.7, 2.8), - fontFamily: 'Raleway', fontWeight: 600, fontSize: theme.spacing(3.6), }, @@ -19,7 +18,6 @@ export const useStyles = makeStyles( color: theme.palette.common.white, fontWeight: 700, fontSize: '18px', - fontFamily: 'Raleway', }, '&:hover': { backgroundColor: '#ffaa00', diff --git a/src/components/Form/Buttons/styles/CancelButton.style.tsx b/src/components/Form/Buttons/styles/CancelButton.style.tsx index 05b06384c..243ac13b6 100644 --- a/src/components/Form/Buttons/styles/CancelButton.style.tsx +++ b/src/components/Form/Buttons/styles/CancelButton.style.tsx @@ -9,7 +9,6 @@ export const useStyles = makeStyles( color: theme.palette.common.white, fontWeight: 700, fontSize: '18px', - fontFamily: 'Raleway', }, '&:hover': { backgroundColor: theme.palette.info.main, diff --git a/src/styles/theme/index.ts b/src/styles/theme/index.ts index c8ec52b3b..24c177cc5 100644 --- a/src/styles/theme/index.ts +++ b/src/styles/theme/index.ts @@ -25,6 +25,9 @@ export const MAIN_THEME = createTheme({ borderRadius: 0, textTransform: 'none', }, + label: { + fontFamily: 'Raleway', + }, }, MuiIconButton: { root: { From c08e17a41b570b07495849276c7352ea01093e13 Mon Sep 17 00:00:00 2001 From: Yurii Hryshchenko Date: Sat, 23 Sep 2023 21:23:22 +0300 Subject: [PATCH 4/4] add previousAuthorValues to useEffect deps --- src/views/Profile/PersonalInfo/PersonalInfo.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/Profile/PersonalInfo/PersonalInfo.tsx b/src/views/Profile/PersonalInfo/PersonalInfo.tsx index f99a709ce..5e8d9c2b6 100644 --- a/src/views/Profile/PersonalInfo/PersonalInfo.tsx +++ b/src/views/Profile/PersonalInfo/PersonalInfo.tsx @@ -215,7 +215,7 @@ export const PersonalInfo: React.FC = ({ author }) => { return () => { window.removeEventListener('beforeunload', handleBeforeUnload); }; - }, [newAuthorValues]); + }, [newAuthorValues, previousAuthorValues]); return (