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..a0637c21b 100644 --- a/src/components/Form/Buttons/styles/BasicButton.style.tsx +++ b/src/components/Form/Buttons/styles/BasicButton.style.tsx @@ -5,25 +5,30 @@ 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), }, 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, fontWeight: 700, fontSize: '18px', - fontFamily: 'Raleway', }, '&:hover': { backgroundColor: '#ffaa00', }, + [theme.breakpoints.down('sm')]: { + flex: '0 1 auto', + padding: theme.spacing(2, 3.1), + '& .MuiButton-label': { + 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..243ac13b6 --- /dev/null +++ b/src/components/Form/Buttons/styles/CancelButton.style.tsx @@ -0,0 +1,25 @@ +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', + }, + '&:hover': { + backgroundColor: theme.palette.info.main, + }, + [theme.breakpoints.down('sm')]: { + flex: '0 1 auto', + '& .MuiButton-label': { + 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/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: { diff --git a/src/views/Profile/PersonalInfo/PersonalInfo.tsx b/src/views/Profile/PersonalInfo/PersonalInfo.tsx index 0e507704e..5e8d9c2b6 100644 --- a/src/views/Profile/PersonalInfo/PersonalInfo.tsx +++ b/src/views/Profile/PersonalInfo/PersonalInfo.tsx @@ -1,17 +1,18 @@ 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'; +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(); @@ -44,7 +46,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 ?? '', @@ -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 = { @@ -200,6 +203,20 @@ export const PersonalInfo: React.FC = ({ author }) => { [errorMessages], ); + useEffect(() => { + const handleBeforeUnload = (e: BeforeUnloadEvent) => { + if (!_isEqual(previousAuthorValues, newAuthorValues)) { + e.preventDefault(); + e.returnValue = + 'Зміни не збережені. Ви впевнені, що хочете залишити сторінку?'; + } + }; + window.addEventListener('beforeunload', handleBeforeUnload); + return () => { + window.removeEventListener('beforeunload', handleBeforeUnload); + }; + }, [newAuthorValues, previousAuthorValues]); + return (
@@ -363,7 +380,14 @@ export const PersonalInfo: React.FC = ({ author }) => { /> + + {author && ( + window.close()} + /> + )}