feat: add hook useShowToast.ts
All checks were successful
it-academy/dry-wash-pl/pipeline/pr-main This commit looks good

This commit is contained in:
Ильназ 2025-02-08 22:18:32 +03:00
parent a00aaff29d
commit ed8ae95436
9 changed files with 65 additions and 102 deletions

View File

@ -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": "Введите ФИО",

View File

@ -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<string>(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]);

View File

@ -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]);

View File

@ -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]);

View File

@ -14,7 +14,7 @@ const MasterItem = ({ name, phone, id, schedule }) => {
return (
<Tr>
<Td>
<EditableWrapper id={id} as={'name'} value={name} />
<EditableWrapper id={id} fieldName={'name'} value={name} />
</Td>
<Td>
{schedule?.length > 0 ? (
@ -30,7 +30,7 @@ const MasterItem = ({ name, phone, id, schedule }) => {
)}
</Td>
<Td>
<EditableWrapper id={id} as={'phone'} value={phone} />
<EditableWrapper id={id} fieldName={'phone'} value={phone} />
</Td>
<Td>
<MasterActionsMenu id={id} />

View File

@ -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]);

View File

@ -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 (
<Box p='8'>

View File

@ -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;

28
src/hooks/useShowToast.ts Normal file
View File

@ -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;