Compare commits

..

No commits in common. "main" and "feature/test" have entirely different histories.

5 changed files with 71 additions and 144 deletions

View File

@ -86,15 +86,6 @@
"dry-wash.arm.master.drawer.inputPhone.placeholder": "Enter Phone Number", "dry-wash.arm.master.drawer.inputPhone.placeholder": "Enter Phone Number",
"dry-wash.arm.master.drawer.button.save": "Save", "dry-wash.arm.master.drawer.button.save": "Save",
"dry-wash.arm.master.drawer.button.cancel": "Cancel", "dry-wash.arm.master.drawer.button.cancel": "Cancel",
"dry-wash.arm.master.drawer.toast.create-master": "Master created",
"dry-wash.arm.master.drawer.toast.error.empty-fields": "Fields cannot be empty",
"dry-wash.arm.master.drawer.toast.error.base": "Error",
"dry-wash.arm.master.drawer.toast.error.create-master": "Error creating master",
"dry-wash.arm.master.drawer.toast.error.create-master-details": "Failed to add master. Please try again",
"dry-wash.arm.master.drawer.form.name.required": "Master name is required",
"dry-wash.arm.master.drawer.form.phone.required": "Phone number is required",
"dry-wash.arm.master.drawer.form.phone.pattern": "Invalid phone number",
"dry-wash.arm.master.drawer.form.name.minLength": "Name must contain at least 2 characters",
"dry-wash.arm.master.sideBar.orders": "Orders", "dry-wash.arm.master.sideBar.orders": "Orders",
"dry-wash.arm.master.sideBar.master": "Masters", "dry-wash.arm.master.sideBar.master": "Masters",
"dry-wash.arm.master.sideBar.title": "Dry Master", "dry-wash.arm.master.sideBar.title": "Dry Master",

View File

@ -36,15 +36,6 @@
"dry-wash.arm.master.drawer.inputPhone.placeholder": "Введите номер телефона", "dry-wash.arm.master.drawer.inputPhone.placeholder": "Введите номер телефона",
"dry-wash.arm.master.drawer.button.save": "Сохранить", "dry-wash.arm.master.drawer.button.save": "Сохранить",
"dry-wash.arm.master.drawer.button.cancel": "Отменить", "dry-wash.arm.master.drawer.button.cancel": "Отменить",
"dry-wash.arm.master.drawer.toast.create-master": "Мастер создан",
"dry-wash.arm.master.drawer.toast.error.empty-fields": "Поля не могут быть пустыми",
"dry-wash.arm.master.drawer.toast.error.base": "Ошибка",
"dry-wash.arm.master.drawer.toast.error.create-master": "Ошибка при создании мастера",
"dry-wash.arm.master.drawer.toast.error.create-master-details": "Не удалось добавить мастера. Попробуйте еще раз",
"dry-wash.arm.master.drawer.form.name.required": "Имя мастера обязательно",
"dry-wash.arm.master.drawer.form.phone.required": "Телефон обязателен",
"dry-wash.arm.master.drawer.form.phone.pattern": "Некорректный номер телефона",
"dry-wash.arm.master.drawer.form.name.minLength": "Имя должно содержать минимум 2 символа",
"dry-wash.arm.master.sideBar.orders": "Заказы", "dry-wash.arm.master.sideBar.orders": "Заказы",
"dry-wash.arm.master.sideBar.master": "Мастера", "dry-wash.arm.master.sideBar.master": "Мастера",
"dry-wash.arm.master.sideBar.title": "Сухой мастер", "dry-wash.arm.master.sideBar.title": "Сухой мастер",

View File

@ -1,5 +1,4 @@
import React, { useEffect } from 'react'; import React, { useEffect, useState } from 'react';
import { useForm, SubmitHandler } from 'react-hook-form';
import { import {
Button, Button,
FormControl, FormControl,
@ -15,136 +14,107 @@ import {
useToast, useToast,
InputGroup, InputGroup,
InputLeftElement, InputLeftElement,
FormErrorMessage,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { PhoneIcon } from '@chakra-ui/icons'; import { PhoneIcon } from '@chakra-ui/icons';
import { api } from '../../__data__/service/api'; import { api } from '../../__data__/service/api';
import showToast from '../../helpers/showToast';
import { DrawerInputs } from '../../models/arm/form';
interface MasterDrawerProps {
isOpen: boolean;
onClose: () => void;
}
const MasterDrawer = ({ isOpen, onClose }: MasterDrawerProps) => {
const {
register,
handleSubmit,
reset,
formState: { errors },
} = useForm<DrawerInputs>();
const { t } = useTranslation('~', {
keyPrefix: 'dry-wash.arm.master.drawer',
});
const onSubmit: SubmitHandler<DrawerInputs> = async (data) => {
const trimMaster = {
name: data.name.trim(),
phone: data.phone.trim(),
};
const isEmptyFields = trimMaster.name === '' || trimMaster.phone === '';
if (isEmptyFields) {
showToast({
toast,
title: t('toast.error.base'),
description: t('toast.error.empty-fields'),
status: 'error',
});
return;
}
await addMaster(trimMaster);
};
const MasterDrawer = ({ isOpen, onClose }) => {
const [addMaster, { error, isSuccess }] = api.useAddMasterMutation(); const [addMaster, { error, isSuccess }] = api.useAddMasterMutation();
const toast = useToast(); const toast = useToast();
const [newMaster, setNewMaster] = useState({ name: '', phone: '' });
const handleSave = async () => {
const trimMaster = {
phone: newMaster.phone.trim(),
name: newMaster.name.trim(),
};
if (trimMaster.name === '' || trimMaster.phone === '') {
return;
}
addMaster(trimMaster);
};
useEffect(() => { useEffect(() => {
if (isSuccess) { if (isSuccess) {
showToast({ toast({
toast, title: 'Мастер создан.',
title: t('toast.create-master'), description: `Мастер "${newMaster.name}" успешно добавлен.`,
status: 'success', status: 'success',
duration: 5000,
isClosable: true,
position: 'top-right',
}); });
reset();
onClose(); onClose();
} }
}, [isSuccess]); }, [isSuccess]);
useEffect(() => { useEffect(() => {
if (error) { if (error) {
showToast({ toast({
toast, title: 'Ошибка при создании мастера.',
title: t('toast.error.create-master'), description: 'Не удалось добавить мастера. Попробуйте еще раз.',
description: t('toast.error.create-master-details'),
status: 'error', status: 'error',
duration: 5000,
isClosable: true,
position: 'top-right',
}); });
console.error(error); console.error(error);
} }
}, [error]); }, [error]);
const { t } = useTranslation('~', {
keyPrefix: 'dry-wash.arm.master.drawer',
});
return ( return (
<Drawer isOpen={isOpen} onClose={onClose} size='md'> <Drawer isOpen={isOpen} onClose={onClose} size='md'>
<DrawerOverlay /> <DrawerOverlay />
<DrawerContent> <DrawerContent>
<form onSubmit={handleSubmit(onSubmit)}>
<DrawerCloseButton /> <DrawerCloseButton />
<DrawerHeader>{t('title')}</DrawerHeader> <DrawerHeader>{t('title')}</DrawerHeader>
<DrawerBody> <DrawerBody>
<FormControl mb='4' isInvalid={!!errors.name}> <FormControl mb='4'>
<FormLabel>{t('inputName.label')}</FormLabel> <FormLabel>{t('inputName.label')}</FormLabel>
<Input <Input
{...register('name', { // isInvalid
required: t('form.name.required'), value={newMaster.name}
minLength: { onChange={(e) =>
value: 2, setNewMaster({ ...newMaster, name: e.target.value })
message: t('form.name.minLength'), }
},
})}
placeholder={t('inputName.placeholder')} placeholder={t('inputName.placeholder')}
/> />
<FormErrorMessage>
{errors.name && errors.name.message}
</FormErrorMessage>
</FormControl> </FormControl>
<FormControl isInvalid={!!errors.phone}> <FormControl>
<FormLabel>{t('inputPhone.label')}</FormLabel> <FormLabel>{t('inputPhone.label')}</FormLabel>
<InputGroup> <InputGroup>
<InputLeftElement pointerEvents='none'> <InputLeftElement pointerEvents='none'>
<PhoneIcon color='gray.300' /> <PhoneIcon color='gray.300' />
</InputLeftElement> </InputLeftElement>
<Input <Input
{...register('phone', { // isInvalid
required: t('form.phone.required'), value={newMaster.phone}
pattern: { onChange={(e) =>
value: /^(\+7|8)\d{10}$/, setNewMaster({ ...newMaster, phone: e.target.value })
message: t('form.phone.pattern'), }
},
setValueAs: (value) => value.replace(/[^\d+]/g, ''),
})}
placeholder={t('inputPhone.placeholder')} placeholder={t('inputPhone.placeholder')}
/> />
</InputGroup> </InputGroup>
<FormErrorMessage>
{errors.phone && errors.phone.message}
</FormErrorMessage>
</FormControl> </FormControl>
</DrawerBody> </DrawerBody>
<DrawerFooter> <DrawerFooter>
<Button colorScheme='teal' mr={3} type='submit'> <Button colorScheme='teal' mr={3} onClick={handleSave}>
{t('button.save')} {t('button.save')}
</Button> </Button>
<Button variant='ghost' onClick={onClose}> <Button variant='ghost' onClick={onClose}>
{t('button.cancel')} {t('button.cancel')}
</Button> </Button>
</DrawerFooter> </DrawerFooter>
</form>
</DrawerContent> </DrawerContent>
</Drawer> </Drawer>
); );

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;

View File

@ -1,4 +0,0 @@
export type DrawerInputs = {
phone: string;
name: string;
};