diff --git a/locales/ru.json b/locales/ru.json index 6b03952..56f22d2 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -25,10 +25,16 @@ "dry-wash.arm.master.table.header.phone": "Телефон", "dry-wash.arm.master.table.header.actions": "Действия", "dry-wash.arm.master.table.actionsMenu.delete": "Удалить мастера", + "dry-wash.arm.master.table.actionsMenu.toast.success": "Мастер удалён", + "dry-wash.arm.master.table.actionsMenu.toast.error.title": "Ошибка!", + "dry-wash.arm.master.table.actionsMenu.toast.error.description": "Не удалось удалить мастера. Попробуйте ещё раз.", "dry-wash.arm.master.schedule.empty": "Свободен", "dry-wash.arm.master.editable.aria.cancel": "Отменить изменения", "dry-wash.arm.master.editable.aria.save": "Сохранить изменения", "dry-wash.arm.master.editable.aria.edit": "Редактировать", + "dry-wash.arm.master.editable.toast.success": "Успешно!", + "dry-wash.arm.master.editable.toast.error.description": "Не удалось обновить данные", + "dry-wash.arm.master.editable.toast.error.title": "Ошибка!", "dry-wash.arm.master.drawer.title": "Добавить нового мастера", "dry-wash.arm.master.drawer.inputName.label": "ФИО", "dry-wash.arm.master.drawer.inputName.placeholder": "Введите ФИО", diff --git a/src/components/Editable/Editable.tsx b/src/components/Editable/Editable.tsx index 61b6fad..8fb77ec 100644 --- a/src/components/Editable/Editable.tsx +++ b/src/components/Editable/Editable.tsx @@ -9,20 +9,20 @@ import { useEditableControls, ButtonGroup, Stack, - useToast, } from '@chakra-ui/react'; import { CheckIcon, CloseIcon, EditIcon } from '@chakra-ui/icons'; import { useTranslation } from 'react-i18next'; import { useUpdateMasterMutation } from '../../__data__/service/api'; +import useShowToast from '../../hooks/useShowToast'; interface EditableWrapperProps { value: string; - as: 'phone' | 'name'; + fieldName: 'phone' | 'name'; id: string; } -const EditableWrapper = ({ value, as, id }: EditableWrapperProps) => { +const EditableWrapper = ({ value, fieldName, id }: EditableWrapperProps) => { const [updateMaster, { isError, isSuccess, error }] = useUpdateMasterMutation(); @@ -30,41 +30,27 @@ const EditableWrapper = ({ value, as, id }: EditableWrapperProps) => { keyPrefix: 'dry-wash.arm.master.editable', }); - const toast = useToast(); + const showToast = useShowToast(); const [currentValue, setCurrentValue] = useState(value); const handleSubmit = async (newValue: string) => { if (currentValue === newValue) return; - await updateMaster({ id, [as]: newValue }); + await updateMaster({ id, [fieldName]: newValue }); setCurrentValue(newValue); }; useEffect(() => { if (isSuccess) { - toast({ - title: 'Успешно!', - description: 'Данные обновлены.', - status: 'success', - duration: 2000, - isClosable: true, - position: 'top-right', - }); + showToast(t('toast.success'), 'success'); } }, [isSuccess]); useEffect(() => { if (isError) { - toast({ - title: 'Ошибка!', - description: 'Не удалось обновить данные.', - status: 'error', - duration: 2000, - isClosable: true, - position: 'top-right', - }); - console.error('Ошибка при обновлении данных:', error); + showToast(t('toast.error.title'), 'error', t('toast.error.description')); + console.error(t('toast.error.description'), error); } }, [isError, error]); diff --git a/src/components/MasterActionsMenu/MasterActionsMenu.tsx b/src/components/MasterActionsMenu/MasterActionsMenu.tsx index 503a810..de66905 100644 --- a/src/components/MasterActionsMenu/MasterActionsMenu.tsx +++ b/src/components/MasterActionsMenu/MasterActionsMenu.tsx @@ -5,12 +5,12 @@ import { MenuList, MenuItem, IconButton, - useToast, } from '@chakra-ui/react'; import { EditIcon } from '@chakra-ui/icons'; import { useTranslation } from 'react-i18next'; import { useDeleteMasterMutation } from '../../__data__/service/api'; +import useShowToast from '../../hooks/useShowToast'; interface MasterActionsMenu { id: string; @@ -24,7 +24,7 @@ const MasterActionsMenu = ({ id }: MasterActionsMenu) => { const [deleteMaster, { isSuccess, isError, error, isLoading }] = useDeleteMasterMutation(); - const toast = useToast(); + const showToast = useShowToast(); const handleClickDelete = async () => { await deleteMaster({ id }); @@ -32,27 +32,13 @@ const MasterActionsMenu = ({ id }: MasterActionsMenu) => { useEffect(() => { if (isSuccess) { - toast({ - title: 'Мастер удалён.', - description: `Мастер с ID "${id}" успешно удалён.`, - status: 'success', - duration: 5000, - isClosable: true, - position: 'top-right', - }); + showToast(t('toast.success'), 'success'); } }, [isSuccess]); useEffect(() => { if (isError) { - toast({ - title: 'Ошибка удаления мастера.', - description: 'Не удалось удалить мастера. Попробуйте ещё раз.', - status: 'error', - duration: 5000, - isClosable: true, - position: 'top-right', - }); + showToast(t('toast.error.title'), 'error', t('toast.error.description')); console.error(error); } }, [isError]); diff --git a/src/components/MasterDrawer/MasterDrawer.tsx b/src/components/MasterDrawer/MasterDrawer.tsx index 482073d..c1c3c1d 100644 --- a/src/components/MasterDrawer/MasterDrawer.tsx +++ b/src/components/MasterDrawer/MasterDrawer.tsx @@ -12,7 +12,6 @@ import { DrawerFooter, DrawerHeader, DrawerOverlay, - useToast, InputGroup, InputLeftElement, FormErrorMessage, @@ -21,8 +20,8 @@ import { useTranslation } from 'react-i18next'; import { PhoneIcon } from '@chakra-ui/icons'; import { api } from '../../__data__/service/api'; -import showToast from '../../helpers/showToast'; import { DrawerInputs } from '../../models/arm/form'; +import useShowToast from '../../hooks/useShowToast'; interface MasterDrawerProps { isOpen: boolean; @@ -50,12 +49,7 @@ const MasterDrawer = ({ isOpen, onClose }: MasterDrawerProps) => { const isEmptyFields = trimMaster.name === '' || trimMaster.phone === ''; if (isEmptyFields) { - showToast({ - toast, - title: t('toast.error.base'), - description: t('toast.error.empty-fields'), - status: 'error', - }); + showToast(t('toast.error.base'), 'error', t('toast.error.empty-fields')); return; } @@ -63,15 +57,11 @@ const MasterDrawer = ({ isOpen, onClose }: MasterDrawerProps) => { }; const [addMaster, { error, isSuccess }] = api.useAddMasterMutation(); - const toast = useToast(); + const showToast = useShowToast(); useEffect(() => { if (isSuccess) { - showToast({ - toast, - title: t('toast.create-master'), - status: 'success', - }); + showToast(t('toast.create-master'), 'success'); reset(); onClose(); } @@ -79,12 +69,11 @@ const MasterDrawer = ({ isOpen, onClose }: MasterDrawerProps) => { useEffect(() => { if (error) { - showToast({ - toast, - title: t('toast.error.create-master'), - description: t('toast.error.create-master-details'), - status: 'error', - }); + showToast( + t('toast.error.create-master'), + 'error', + t('toast.error.create-master-details'), + ); console.error(error); } }, [error]); diff --git a/src/components/MasterItem/MasterItem.tsx b/src/components/MasterItem/MasterItem.tsx index 80c5bdc..8c2f781 100644 --- a/src/components/MasterItem/MasterItem.tsx +++ b/src/components/MasterItem/MasterItem.tsx @@ -14,7 +14,7 @@ const MasterItem = ({ name, phone, id, schedule }) => { return ( - + {schedule?.length > 0 ? ( @@ -30,7 +30,7 @@ const MasterItem = ({ name, phone, id, schedule }) => { )} - + diff --git a/src/components/Masters/Masters.tsx b/src/components/Masters/Masters.tsx index e6a8cee..48f46f4 100644 --- a/src/components/Masters/Masters.tsx +++ b/src/components/Masters/Masters.tsx @@ -10,7 +10,6 @@ import { Button, useDisclosure, Flex, - useToast, Td, Text, Spinner, @@ -20,6 +19,7 @@ import { useTranslation } from 'react-i18next'; import MasterItem from '../MasterItem'; import MasterDrawer from '../MasterDrawer'; import { useGetMastersQuery } from '../../__data__/service/api'; +import useShowToast from '../../hooks/useShowToast'; const TABLE_HEADERS = [ 'name' as const, @@ -30,7 +30,8 @@ const TABLE_HEADERS = [ const Masters = () => { const { isOpen, onOpen, onClose } = useDisclosure(); - const toast = useToast(); + const showToast = useShowToast(); + const { t } = useTranslation('~', { keyPrefix: 'dry-wash.arm.master', }); @@ -39,12 +40,7 @@ const Masters = () => { useEffect(() => { if (error) { - toast({ - title: t('error.title'), - status: 'error', - isClosable: true, - position: 'bottom-right', - }); + showToast(t('error.title'), 'error'); } }, [error]); diff --git a/src/components/Orders/Orders.tsx b/src/components/Orders/Orders.tsx index e4a37be..309719e 100644 --- a/src/components/Orders/Orders.tsx +++ b/src/components/Orders/Orders.tsx @@ -10,7 +10,6 @@ import { Spinner, Text, Td, - useToast, } from '@chakra-ui/react'; import { useTranslation } from 'react-i18next'; import dayjs from 'dayjs'; @@ -22,6 +21,7 @@ import { useGetMastersQuery, useGetOrdersQuery, } from '../../__data__/service/api'; +import useShowToast from '../../hooks/useShowToast'; const TABLE_HEADERS = [ 'carNumber' as const, @@ -36,7 +36,7 @@ const Orders = () => { const { t } = useTranslation('~', { keyPrefix: 'dry-wash.arm.order', }); - const toast = useToast(); + const showToast = useShowToast(); const [currentDate, setCurrentDate] = useState(new Date()); const { @@ -61,16 +61,9 @@ const Orders = () => { useEffect(() => { if (isError) { - toast({ - title: t('error.title'), - // description: errorMessage, - status: 'error', - duration: 5000, - isClosable: true, - position: 'bottom-right', - }); + showToast(t('error.title'), 'error'); } - }, [isError, ordersError, mastersError, toast, t]); + }, [isError, ordersError, mastersError, t]); return ( diff --git a/src/helpers/showToast.ts b/src/helpers/showToast.ts deleted file mode 100644 index eed5aca..0000000 --- a/src/helpers/showToast.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { UseToastOptions } from '@chakra-ui/react'; - -interface ShowToast { - toast: (options: UseToastOptions) => void; - title: string; - description?: string; - status: 'info' | 'warning' | 'success' | 'error'; -} - -const showToast = ({ toast, title, description, status }: ShowToast) => { - toast({ - title, - description, - status, - duration: 5000, - isClosable: true, - position: 'top-right', - }); -}; - -export default showToast; diff --git a/src/hooks/useShowToast.ts b/src/hooks/useShowToast.ts new file mode 100644 index 0000000..3914ff7 --- /dev/null +++ b/src/hooks/useShowToast.ts @@ -0,0 +1,28 @@ +import { useToast } from '@chakra-ui/react'; +import { useCallback } from 'react'; + +const useShowToast = () => { + const toast = useToast(); + + const showToast = useCallback( + ( + title: string, + status: 'info' | 'warning' | 'success' | 'error', + description?: string, + ) => { + toast({ + title, + description, + status, + duration: 5000, + isClosable: true, + position: 'top-right', + }); + }, + [toast], + ); + + return showToast; +}; + +export default useShowToast;