feat(frontend): add mui
This commit is contained in:
parent
35291a103a
commit
021038f4ad
@ -1,5 +1,8 @@
|
|||||||
import './normalize.css';
|
import './normalize.css';
|
||||||
|
import { LocalizationProvider } from '@mui/x-date-pickers';
|
||||||
|
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
||||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||||
|
import { ru } from 'date-fns/locale/ru';
|
||||||
|
|
||||||
import { AuthContextProvider } from '@/shared/context/AuthContext';
|
import { AuthContextProvider } from '@/shared/context/AuthContext';
|
||||||
|
|
||||||
@ -10,7 +13,9 @@ const queryClient = new QueryClient();
|
|||||||
const App = () => (
|
const App = () => (
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<AuthContextProvider>
|
<AuthContextProvider>
|
||||||
<Routing />
|
<LocalizationProvider adapterLocale={ru} dateAdapter={AdapterDateFns}>
|
||||||
|
<Routing />
|
||||||
|
</LocalizationProvider>
|
||||||
</AuthContextProvider>
|
</AuthContextProvider>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -9,10 +9,11 @@ export { useEditBankCard } from './hooks/useEditBankCard';
|
|||||||
|
|
||||||
export type { BankCard, BankCards } from './types';
|
export type { BankCard, BankCards } from './types';
|
||||||
|
|
||||||
export type { AddBankCardFormValues } from './ui/AddBankCardForm';
|
export type { AddBankCardFormProps, AddBankCardFormValues } from './ui/AddBankCardForm';
|
||||||
export { AddBankCardForm } from './ui/AddBankCardForm';
|
export { AddBankCardForm } from './ui/AddBankCardForm';
|
||||||
|
|
||||||
|
export type { DeleteBankCardFormProps } from './ui/DeleteBankCardForm';
|
||||||
export { DeleteBankCardForm } from './ui/DeleteBankCardForm';
|
export { DeleteBankCardForm } from './ui/DeleteBankCardForm';
|
||||||
|
|
||||||
export type { EditBankCardFormValues } from './ui/EditBankCardForm';
|
export type { EditBankCardFormProps, EditBankCardFormValues } from './ui/EditBankCardForm';
|
||||||
export { EditBankCardForm } from './ui/EditBankCardForm';
|
export { EditBankCardForm } from './ui/EditBankCardForm';
|
||||||
|
|||||||
@ -1,2 +1,3 @@
|
|||||||
export type { AddBankCardFormValues } from './ui/AddBankCardForm.ui';
|
export type { AddBankCardFormValues } from './ui/AddBankCardForm.ui';
|
||||||
|
export type { AddBankCardFormProps } from './ui/AddBankCardForm.ui';
|
||||||
export { default as AddBankCardForm } from './ui/AddBankCardForm.ui';
|
export { default as AddBankCardForm } from './ui/AddBankCardForm.ui';
|
||||||
|
|||||||
@ -5,7 +5,9 @@ import type {
|
|||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
import { Input } from '@/shared/ui/Input';
|
import { Button, TextField, Typography } from '@mui/material';
|
||||||
|
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
|
|
||||||
import classes from './AddBankCardForm.module.css';
|
import classes from './AddBankCardForm.module.css';
|
||||||
|
|
||||||
@ -49,29 +51,41 @@ const AddBankCardForm: FC<AddBankCardFormProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
className={classes.form}
|
className={classes.form}
|
||||||
|
data-testid={DataTestId.ADD_BANK_CARD_FORM}
|
||||||
onSubmit={onFormSubmitHandler}
|
onSubmit={onFormSubmitHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
{...formProps}
|
{...formProps}
|
||||||
>
|
>
|
||||||
<h2>Добавить карту</h2>
|
<Typography variant="h6">
|
||||||
|
Добавить карту
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Название"
|
label="Название"
|
||||||
name="name"
|
name="name"
|
||||||
required
|
required
|
||||||
|
size="small"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
defaultValue={0}
|
defaultValue={0}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
inputMode="numeric"
|
||||||
label="Баланс"
|
label="Баланс"
|
||||||
name="balance"
|
name="balance"
|
||||||
step="0.01"
|
size="small"
|
||||||
type="number"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Добавить</button>
|
<Button
|
||||||
|
data-testid={DataTestId.ADD_BANK_CARD_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Добавить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1 +1,2 @@
|
|||||||
|
export type { DeleteBankCardFormProps } from './ui/DeleteBankCardForm.ui';
|
||||||
export { default as DeleteBankCardForm } from './ui/DeleteBankCardForm.ui';
|
export { default as DeleteBankCardForm } from './ui/DeleteBankCardForm.ui';
|
||||||
|
|||||||
@ -5,6 +5,10 @@ import type {
|
|||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
|
import { Button, Typography } from '@mui/material';
|
||||||
|
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
|
|
||||||
import type { BankCard } from '../../../types';
|
import type { BankCard } from '../../../types';
|
||||||
|
|
||||||
export type DeleteBankCardFormProps = BaseFormProps & {
|
export type DeleteBankCardFormProps = BaseFormProps & {
|
||||||
@ -31,10 +35,17 @@ const DeleteBankCardForm: FC<DeleteBankCardFormProps> = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={onFormSubmitHandler} ref={ref} {...restProps}>
|
<form
|
||||||
<h2>Удалить список расходов</h2>
|
data-testid={DataTestId.DELETE_BANK_CARD_FORM}
|
||||||
|
onSubmit={onFormSubmitHandler}
|
||||||
|
ref={ref}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
<Typography variant="h6">
|
||||||
|
Удалить список расходов
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<p>
|
<Typography variant="body1">
|
||||||
Вы действительно хотите удалить банковскую карту
|
Вы действительно хотите удалить банковскую карту
|
||||||
{' '}
|
{' '}
|
||||||
|
|
||||||
@ -44,9 +55,19 @@ const DeleteBankCardForm: FC<DeleteBankCardFormProps> = (props) => {
|
|||||||
|
|
||||||
{' '}
|
{' '}
|
||||||
?
|
?
|
||||||
</p>
|
</Typography>
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Удалить</button>
|
<Button
|
||||||
|
color="error"
|
||||||
|
data-testid={DataTestId.DELETE_BANK_CARD_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
fullWidth
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Удалить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,2 +1,3 @@
|
|||||||
export type { EditBankCardFormValues } from './ui/EditBankCardForm.ui';
|
export type { EditBankCardFormValues } from './ui/EditBankCardForm.ui';
|
||||||
|
export type { EditBankCardFormProps } from './ui/EditBankCardForm.ui';
|
||||||
export { default as EditBankCardForm } from './ui/EditBankCardForm.ui';
|
export { default as EditBankCardForm } from './ui/EditBankCardForm.ui';
|
||||||
|
|||||||
@ -5,9 +5,11 @@ import type {
|
|||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
|
import { Button, TextField, Typography } from '@mui/material';
|
||||||
|
|
||||||
import type { BankCard } from '@/entity/cards';
|
import type { BankCard } from '@/entity/cards';
|
||||||
|
|
||||||
import { Input } from '@/shared/ui/Input';
|
import { DataTestId } from '@/shared/constants';
|
||||||
|
|
||||||
import classes from './EditBankCardForm.module.css';
|
import classes from './EditBankCardForm.module.css';
|
||||||
|
|
||||||
@ -53,30 +55,42 @@ const EditBankCardForm: FC<EditBankCardFormProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
className={classes.form}
|
className={classes.form}
|
||||||
|
data-testid={DataTestId.EDIT_BANK_CARD_FORM}
|
||||||
onSubmit={onFormSubmitHandler}
|
onSubmit={onFormSubmitHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
<h2>Добавить карту</h2>
|
<Typography variant="h6">
|
||||||
|
Добавить карту
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
defaultValue={bankCard.name}
|
defaultValue={bankCard.name}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Название"
|
label="Название"
|
||||||
name="name"
|
name="name"
|
||||||
required
|
required
|
||||||
|
size="small"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
defaultValue={bankCard.balance}
|
defaultValue={bankCard.balance}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
inputMode="numeric"
|
||||||
label="Баланс"
|
label="Баланс"
|
||||||
name="balance"
|
name="balance"
|
||||||
step="0.01"
|
size="small"
|
||||||
type="number"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Сохранить</button>
|
<Button
|
||||||
|
data-testid={DataTestId.EDIT_BANK_CARD_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
fullWidth
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Сохранить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -10,9 +10,10 @@ export { useEditCash } from './hooks/useEditCash';
|
|||||||
export type { CashItem, CashList } from './types';
|
export type { CashItem, CashList } from './types';
|
||||||
|
|
||||||
export { AddCashForm } from './ui/AddCashForm';
|
export { AddCashForm } from './ui/AddCashForm';
|
||||||
export type { AddCashFormValues } from './ui/AddCashForm';
|
export type { AddCashFormProps, AddCashFormValues } from './ui/AddCashForm';
|
||||||
|
|
||||||
|
export type { DeleteCashFormProps } from './ui/DeleteCashForm';
|
||||||
export { DeleteCashForm } from './ui/DeleteCashForm';
|
export { DeleteCashForm } from './ui/DeleteCashForm';
|
||||||
|
|
||||||
export { EditCashForm } from './ui/EditCashForm';
|
export { EditCashForm } from './ui/EditCashForm';
|
||||||
export type { EditCashFormValues } from './ui/EditCashForm';
|
export type { EditCashFormProps, EditCashFormValues } from './ui/EditCashForm';
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
export type { AddCashFormValues } from './ui/AddCashForm.ui';
|
export type { AddCashFormProps, AddCashFormValues } from './ui/AddCashForm.ui';
|
||||||
export { default as AddCashForm } from './ui/AddCashForm.ui';
|
export { default as AddCashForm } from './ui/AddCashForm.ui';
|
||||||
|
|||||||
@ -5,7 +5,9 @@ import type {
|
|||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
import { Input } from '@/shared/ui/Input';
|
import { Button, TextField, Typography } from '@mui/material';
|
||||||
|
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
|
|
||||||
import classes from './AddCashForm.module.css';
|
import classes from './AddCashForm.module.css';
|
||||||
|
|
||||||
@ -49,29 +51,40 @@ const AddCashForm: FC<AddCashFormProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
className={classes.form}
|
className={classes.form}
|
||||||
|
data-testid={DataTestId.ADD_CASH_FORM}
|
||||||
onSubmit={onFormSubmitHandler}
|
onSubmit={onFormSubmitHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
{...formProps}
|
{...formProps}
|
||||||
>
|
>
|
||||||
<h2>Добавить наличные</h2>
|
<Typography variant="h6">
|
||||||
|
Добавить наличные
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Название"
|
label="Название"
|
||||||
name="name"
|
name="name"
|
||||||
required
|
required
|
||||||
|
size="small"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
defaultValue={0}
|
defaultValue={0}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
inputMode="numeric"
|
||||||
label="Баланс"
|
label="Баланс"
|
||||||
name="balance"
|
name="balance"
|
||||||
step="0.01"
|
size="small"
|
||||||
type="number"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Добавить</button>
|
<Button
|
||||||
|
data-testid={DataTestId.ADD_CASH_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Добавить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1 +1,2 @@
|
|||||||
|
export type { DeleteCashFormProps } from './ui/DeleteCashForm.ui';
|
||||||
export { default as DeleteCashForm } from './ui/DeleteCashForm.ui';
|
export { default as DeleteCashForm } from './ui/DeleteCashForm.ui';
|
||||||
|
|||||||
@ -5,6 +5,10 @@ import type {
|
|||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
|
import { Button, Typography } from '@mui/material';
|
||||||
|
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
|
|
||||||
import type { CashItem } from '../../../types';
|
import type { CashItem } from '../../../types';
|
||||||
|
|
||||||
export type DeleteCashFormProps = BaseFormProps & {
|
export type DeleteCashFormProps = BaseFormProps & {
|
||||||
@ -31,10 +35,17 @@ const DeleteCashForm: FC<DeleteCashFormProps> = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={onFormSubmitHandler} ref={ref} {...restProps}>
|
<form
|
||||||
<h2>Удалить наличные</h2>
|
data-testid={DataTestId.DELETE_CASH_FORM}
|
||||||
|
onSubmit={onFormSubmitHandler}
|
||||||
|
ref={ref}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
<Typography variant="h6">
|
||||||
|
Удалить наличные
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<p>
|
<Typography variant="body1">
|
||||||
Вы действительно хотите удалить наличные
|
Вы действительно хотите удалить наличные
|
||||||
{' '}
|
{' '}
|
||||||
|
|
||||||
@ -44,9 +55,19 @@ const DeleteCashForm: FC<DeleteCashFormProps> = (props) => {
|
|||||||
|
|
||||||
{' '}
|
{' '}
|
||||||
?
|
?
|
||||||
</p>
|
</Typography>
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Удалить</button>
|
<Button
|
||||||
|
color="error"
|
||||||
|
data-testid={DataTestId.DELETE_CASH_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
fullWidth
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Удалить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
export type { EditCashFormValues } from './ui/EditCashForm.ui';
|
export type { EditCashFormProps, EditCashFormValues } from './ui/EditCashForm.ui';
|
||||||
export { default as EditCashForm } from './ui/EditCashForm.ui';
|
export { default as EditCashForm } from './ui/EditCashForm.ui';
|
||||||
|
|||||||
@ -5,9 +5,11 @@ import type {
|
|||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
|
import { Button, TextField, Typography } from '@mui/material';
|
||||||
|
|
||||||
import type { CashItem } from '@/entity/cash';
|
import type { CashItem } from '@/entity/cash';
|
||||||
|
|
||||||
import { Input } from '@/shared/ui/Input';
|
import { DataTestId } from '@/shared/constants';
|
||||||
|
|
||||||
import classes from './EditCashForm.module.css';
|
import classes from './EditCashForm.module.css';
|
||||||
|
|
||||||
@ -53,30 +55,41 @@ const EditCashForm: FC<EditCashFormProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
className={classes.form}
|
className={classes.form}
|
||||||
|
data-testid={DataTestId.EDIT_CASH_FORM}
|
||||||
onSubmit={onFormSubmitHandler}
|
onSubmit={onFormSubmitHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
<h2>Редактировать наличные</h2>
|
<Typography variant="h6">
|
||||||
|
Редактировать наличные
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
defaultValue={cash.name}
|
defaultValue={cash.name}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Название"
|
label="Название"
|
||||||
name="name"
|
name="name"
|
||||||
required
|
required
|
||||||
|
size="small"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
defaultValue={cash.balance}
|
defaultValue={cash.balance}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
inputMode="numeric"
|
||||||
label="Баланс"
|
label="Баланс"
|
||||||
name="balance"
|
name="balance"
|
||||||
step="0.01"
|
size="small"
|
||||||
type="number"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Сохранить</button>
|
<Button
|
||||||
|
data-testid={DataTestId.EDIT_CASH_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Сохранить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -7,11 +7,12 @@ export { useDeleteExpenseItem } from './hooks/useDeleteExpenseItem';
|
|||||||
export { useEditExpenseItem } from './hooks/useEditExpenseItem';
|
export { useEditExpenseItem } from './hooks/useEditExpenseItem';
|
||||||
|
|
||||||
export type { ExpenseListItem } from './types';
|
export type { ExpenseListItem } from './types';
|
||||||
export type { AddExpenseItemFormValues } from './ui/AddExpenseItemForm/AddExpenseItemForm.ui';
|
|
||||||
|
|
||||||
|
export type { AddExpenseItemFormProps, AddExpenseItemFormValues } from './ui/AddExpenseItemForm/AddExpenseItemForm.ui';
|
||||||
export { default as AddExpenseItemForm } from './ui/AddExpenseItemForm/AddExpenseItemForm.ui';
|
export { default as AddExpenseItemForm } from './ui/AddExpenseItemForm/AddExpenseItemForm.ui';
|
||||||
|
|
||||||
|
export type { DeleteExpenseItemFormProps } from './ui/DeleteExpenseItemForm/DeleteExpenseItemForm.ui';
|
||||||
export { default as DeleteExpenseItemForm } from './ui/DeleteExpenseItemForm/DeleteExpenseItemForm.ui';
|
export { default as DeleteExpenseItemForm } from './ui/DeleteExpenseItemForm/DeleteExpenseItemForm.ui';
|
||||||
|
|
||||||
export type { EditExpenseItemFormValues } from './ui/EditExpenseItemForm/EditExpenseItemForm.ui';
|
export type { EditExpenseItemFormProps, EditExpenseItemFormValues } from './ui/EditExpenseItemForm/EditExpenseItemForm.ui';
|
||||||
|
|
||||||
export { default as EditExpenseItemForm } from './ui/EditExpenseItemForm/EditExpenseItemForm.ui';
|
export { default as EditExpenseItemForm } from './ui/EditExpenseItemForm/EditExpenseItemForm.ui';
|
||||||
|
|||||||
@ -1,11 +1,21 @@
|
|||||||
|
import type { SelectChangeEvent } from '@mui/material';
|
||||||
import type {
|
import type {
|
||||||
ChangeEventHandler,
|
|
||||||
FC,
|
FC,
|
||||||
FormEventHandler,
|
FormEventHandler,
|
||||||
FormHTMLAttributes,
|
FormHTMLAttributes,
|
||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
FormControl,
|
||||||
|
InputLabel,
|
||||||
|
MenuItem,
|
||||||
|
Select,
|
||||||
|
TextField,
|
||||||
|
Typography,
|
||||||
|
} from '@mui/material';
|
||||||
|
import { DatePicker } from '@mui/x-date-pickers';
|
||||||
import {
|
import {
|
||||||
useMemo,
|
useMemo,
|
||||||
useState,
|
useState,
|
||||||
@ -15,9 +25,8 @@ import type { ExpenseListItem } from '@/entity/expenses/item';
|
|||||||
|
|
||||||
import { useBankCards } from '@/entity/cards';
|
import { useBankCards } from '@/entity/cards';
|
||||||
import { useCash } from '@/entity/cash';
|
import { useCash } from '@/entity/cash';
|
||||||
import { Input } from '@/shared/ui/Input';
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Select } from '@/shared/ui/Select';
|
import { formatRub, getUTCDate } from '@/shared/utils';
|
||||||
import { formatRub } from '@/shared/utils';
|
|
||||||
|
|
||||||
import classes from './AddExpenseItemForm.module.css';
|
import classes from './AddExpenseItemForm.module.css';
|
||||||
|
|
||||||
@ -89,7 +98,7 @@ const AddExpenseItemForm: FC<AddExpenseItemFormProps> = (props) => {
|
|||||||
amount: Number(amount),
|
amount: Number(amount),
|
||||||
count: Number(count),
|
count: Number(count),
|
||||||
currency: 'RUB',
|
currency: 'RUB',
|
||||||
date: new Date(date).toISOString(),
|
date: getUTCDate(date),
|
||||||
description,
|
description,
|
||||||
// @ts-ignore todo
|
// @ts-ignore todo
|
||||||
payment: getPayment(),
|
payment: getPayment(),
|
||||||
@ -100,31 +109,33 @@ const AddExpenseItemForm: FC<AddExpenseItemFormProps> = (props) => {
|
|||||||
const { data: bankCards } = useBankCards();
|
const { data: bankCards } = useBankCards();
|
||||||
const { data: cash } = useCash();
|
const { data: cash } = useCash();
|
||||||
|
|
||||||
const bankCardOptions = bankCards?.map((card) => ({
|
const bankCardOptions = bankCards?.map((card) => (
|
||||||
label: `${card.name} (${formatRub(card.balance)})`,
|
<MenuItem key={card.id} value={card.id}>
|
||||||
value: card.id,
|
{`${card.name} (${formatRub(card.balance)})`}
|
||||||
}));
|
</MenuItem>
|
||||||
|
));
|
||||||
|
|
||||||
const cashOptions = cash?.map((cashItem) => ({
|
const cashOptions = cash?.map((cashItem) => (
|
||||||
label: `${cashItem.name} (${formatRub(cashItem.balance)})`,
|
<MenuItem key={cashItem.id} value={cashItem.id}>
|
||||||
value: cashItem.id,
|
{`${cashItem.name} (${formatRub(cashItem.balance)})`}
|
||||||
}));
|
</MenuItem>
|
||||||
|
));
|
||||||
|
|
||||||
const paymentOptions = useMemo(() => {
|
const paymentOptions = useMemo(() => {
|
||||||
const options = [{ label: 'Без оплаты', value: 'none' }];
|
const options = [<MenuItem key="none" value="none">Без оплаты</MenuItem>];
|
||||||
|
|
||||||
if (bankCardOptions && bankCardOptions.length > 0) {
|
if (bankCardOptions && bankCardOptions.length > 0) {
|
||||||
options.push({ label: 'Банковская карта', value: 'BANK_CARD' });
|
options.push(<MenuItem key="BANK_CARD" value="BANK_CARD">Банковская карта</MenuItem>);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cashOptions && cashOptions.length > 0) {
|
if (cashOptions && cashOptions.length > 0) {
|
||||||
options.push({ label: 'Наличные', value: 'CASH' });
|
options.push(<MenuItem key="CASH" value="CASH">Наличные</MenuItem>);
|
||||||
}
|
}
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}, [bankCardOptions, cashOptions]);
|
}, [bankCardOptions, cashOptions]);
|
||||||
|
|
||||||
const onChangePaymentHandler: ChangeEventHandler<HTMLSelectElement> = (event) => {
|
const onChangePaymentHandler = (event: SelectChangeEvent<'BANK_CARD' | 'CASH' | 'none'>) => {
|
||||||
const { value } = event.target;
|
const { value } = event.target;
|
||||||
if (value === 'none') {
|
if (value === 'none') {
|
||||||
setPaymentType(null);
|
setPaymentType(null);
|
||||||
@ -135,80 +146,126 @@ const AddExpenseItemForm: FC<AddExpenseItemFormProps> = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderCardSelect = () => (
|
const renderCardSelect = () => (
|
||||||
<Select
|
<FormControl fullWidth>
|
||||||
label="Карта"
|
<InputLabel id="bank-card-label">Карта</InputLabel>
|
||||||
name="bank-card"
|
|
||||||
options={bankCardOptions ?? []}
|
<Select
|
||||||
/>
|
data-testid="bank-card-select"
|
||||||
|
defaultValue={bankCards?.[0].id}
|
||||||
|
disabled={disabled}
|
||||||
|
inputProps={{ 'data-testid': 'bank-card-select-input' }}
|
||||||
|
labelId="bank-card-label"
|
||||||
|
name="bank-card"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
{bankCardOptions}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
);
|
);
|
||||||
|
|
||||||
const renderCashSelect = () => (
|
const renderCashSelect = () => (
|
||||||
<Select
|
<FormControl fullWidth>
|
||||||
label="Наличные"
|
<InputLabel id="cash-label">Наличные</InputLabel>
|
||||||
name="cash"
|
|
||||||
options={cashOptions ?? []}
|
<Select
|
||||||
/>
|
data-testid="cash-select"
|
||||||
|
defaultValue={cash?.[0].id}
|
||||||
|
disabled={disabled}
|
||||||
|
inputProps={{ 'data-testid': 'cash-select-input' }}
|
||||||
|
labelId="cash-label"
|
||||||
|
name="cash"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
{cashOptions ?? []}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
className={classes.form}
|
className={classes.form}
|
||||||
|
data-testid={DataTestId.ADD_EXPENSE_ITEM_FORM}
|
||||||
onSubmit={onFormSubmitHandler}
|
onSubmit={onFormSubmitHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
{...formProps}
|
{...formProps}
|
||||||
>
|
>
|
||||||
<h2>Добавить список расходов</h2>
|
<Typography variant="h6">
|
||||||
|
Добавить список расходов
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Название"
|
label="Название"
|
||||||
name="title"
|
name="title"
|
||||||
required
|
required
|
||||||
|
size="small"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Описание"
|
label="Описание"
|
||||||
name="description"
|
name="description"
|
||||||
|
size="small"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<DatePicker
|
||||||
defaultValue={new Date().toISOString().split('T')[0]}
|
defaultValue={new Date()}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Дата"
|
label="Дата"
|
||||||
name="date"
|
name="date"
|
||||||
required
|
slotProps={{ textField: { required: true, size: 'small' } }}
|
||||||
type="date"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
inputMode="numeric"
|
||||||
label="Сумма"
|
label="Сумма"
|
||||||
name="amount"
|
name="amount"
|
||||||
required
|
required
|
||||||
step="0.01"
|
size="small"
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
defaultValue={1}
|
defaultValue={1}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
inputMode="numeric"
|
||||||
label="Количество"
|
label="Количество"
|
||||||
name="count"
|
name="count"
|
||||||
|
size="small"
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Select
|
<FormControl fullWidth>
|
||||||
label="Способ оплаты"
|
<InputLabel id="payment-type-label">Способ оплаты</InputLabel>
|
||||||
name="paymentMethod"
|
|
||||||
onChange={onChangePaymentHandler}
|
<Select
|
||||||
options={paymentOptions}
|
data-testid="payment-type-select"
|
||||||
/>
|
defaultValue="none"
|
||||||
|
disabled={disabled}
|
||||||
|
inputProps={{ 'data-testid': 'payment-type-select-input' }}
|
||||||
|
labelId="payment-type-label"
|
||||||
|
name="paymentMethod"
|
||||||
|
onChange={onChangePaymentHandler}
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
{paymentOptions}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
{paymentType === 'BANK_CARD' && renderCardSelect()}
|
{paymentType === 'BANK_CARD' && renderCardSelect()}
|
||||||
|
|
||||||
{paymentType === 'CASH' && renderCashSelect()}
|
{paymentType === 'CASH' && renderCashSelect()}
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Добавить</button>
|
<Button
|
||||||
|
data-testid={DataTestId.ADD_EXPENSE_ITEM_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
size="small"
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Добавить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,6 +5,10 @@ import type {
|
|||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
|
import { Button, Typography } from '@mui/material';
|
||||||
|
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
|
|
||||||
import type { ExpenseListItem } from '../../types';
|
import type { ExpenseListItem } from '../../types';
|
||||||
|
|
||||||
export type DeleteExpenseItemFormProps = BaseFormProps & {
|
export type DeleteExpenseItemFormProps = BaseFormProps & {
|
||||||
@ -30,10 +34,27 @@ const DeleteExpenseItemForm: FC<DeleteExpenseItemFormProps> = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={onFormSubmitHandler} ref={ref} {...restProps}>
|
<form
|
||||||
<h2>Удалить элемент ?</h2>
|
data-testid={DataTestId.DELETE_EXPENSE_ITEM_FORM}
|
||||||
|
onSubmit={onFormSubmitHandler}
|
||||||
|
ref={ref}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
<Typography variant="h6">
|
||||||
|
Удалить элемент ?
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Удалить</button>
|
<Button
|
||||||
|
color="error"
|
||||||
|
data-testid={DataTestId.DELETE_EXPENSE_ITEM_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
fullWidth
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Удалить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,7 +5,11 @@ import type {
|
|||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
import { Input } from '@/shared/ui/Input';
|
import { Button, TextField, Typography } from '@mui/material';
|
||||||
|
import { DatePicker } from '@mui/x-date-pickers';
|
||||||
|
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
|
import { getUTCDate } from '@/shared/utils';
|
||||||
|
|
||||||
import type { ExpenseListItem } from '../../types';
|
import type { ExpenseListItem } from '../../types';
|
||||||
|
|
||||||
@ -53,7 +57,7 @@ const EditExpenseItemForm: FC<EditExpenseItemFormProps> = (props) => {
|
|||||||
amount: Number(amount),
|
amount: Number(amount),
|
||||||
count: Number(count),
|
count: Number(count),
|
||||||
currency: 'RUB',
|
currency: 'RUB',
|
||||||
date: new Date(date).toISOString(),
|
date: getUTCDate(date),
|
||||||
description,
|
description,
|
||||||
title,
|
title,
|
||||||
});
|
});
|
||||||
@ -63,52 +67,67 @@ const EditExpenseItemForm: FC<EditExpenseItemFormProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
className={classes.form}
|
className={classes.form}
|
||||||
|
data-testid={DataTestId.EDIT_EXPENSE_ITEM_FORM}
|
||||||
onSubmit={onFormSubmitHandler}
|
onSubmit={onFormSubmitHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
{...formProps}
|
{...formProps}
|
||||||
>
|
>
|
||||||
<h2>Добавить список расходов</h2>
|
<Typography variant="h6">
|
||||||
|
Добавить список расходов
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
defaultValue={item.title}
|
defaultValue={item.title}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Название"
|
label="Название"
|
||||||
name="title"
|
name="title"
|
||||||
|
required
|
||||||
|
size="small"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
defaultValue={item.description ?? ''}
|
defaultValue={item.description ?? ''}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Описание"
|
label="Описание"
|
||||||
name="description"
|
name="description"
|
||||||
|
size="small"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<DatePicker
|
||||||
defaultValue={new Date(item.date).toISOString().split('T')[0]}
|
defaultValue={new Date(item.date)}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Дата"
|
label="Дата"
|
||||||
name="date"
|
name="date"
|
||||||
type="date"
|
slotProps={{ textField: { required: true, size: 'small' } }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
defaultValue={item.amount}
|
defaultValue={item.amount}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
inputMode="numeric"
|
||||||
label="Сумма"
|
label="Сумма"
|
||||||
name="amount"
|
name="amount"
|
||||||
step="0.01"
|
required
|
||||||
type="number"
|
size="small"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
defaultValue={item.count ?? 1}
|
defaultValue={item.count ?? 1}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Количество"
|
label="Количество"
|
||||||
name="count"
|
name="count"
|
||||||
|
size="small"
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Сохранить</button>
|
<Button
|
||||||
|
data-testid={DataTestId.EDIT_EXPENSE_ITEM_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Сохранить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -10,10 +10,11 @@ export { useExpensesList } from './hooks/useExpensesList';
|
|||||||
|
|
||||||
export type { ExpenseList } from './types';
|
export type { ExpenseList } from './types';
|
||||||
|
|
||||||
export type { AddExpenseListFormValues } from './ui/AddExpensesListForm/ui/AddExpensesListForm.ui';
|
export type { AddExpenseListFormProps, AddExpenseListFormValues } from './ui/AddExpensesListForm/ui/AddExpensesListForm.ui';
|
||||||
export { default as AddExpensesListForm } from './ui/AddExpensesListForm/ui/AddExpensesListForm.ui';
|
export { default as AddExpensesListForm } from './ui/AddExpensesListForm/ui/AddExpensesListForm.ui';
|
||||||
|
|
||||||
|
export type { DeleteExpenseListFormProps } from './ui/DeleteExpensesListForm/ui/DeleteExpensesListForm.ui';
|
||||||
export { default as DeleteExpensesListForm } from './ui/DeleteExpensesListForm/ui/DeleteExpensesListForm.ui';
|
export { default as DeleteExpensesListForm } from './ui/DeleteExpensesListForm/ui/DeleteExpensesListForm.ui';
|
||||||
|
|
||||||
export type { EditExpenseListFormValues } from './ui/EditExpensesListForm/ui/EditExpensesListForm.ui';
|
export type { EditExpenseListFormValues, EditExpensesListFormProps } from './ui/EditExpensesListForm/ui/EditExpensesListForm.ui';
|
||||||
export { default as EditExpensesListForm } from './ui/EditExpensesListForm/ui/EditExpensesListForm.ui';
|
export { default as EditExpensesListForm } from './ui/EditExpensesListForm/ui/EditExpensesListForm.ui';
|
||||||
|
|||||||
@ -5,7 +5,9 @@ import type {
|
|||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
import { Input } from '@/shared/ui/Input';
|
import { Button, TextField, Typography } from '@mui/material';
|
||||||
|
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
|
|
||||||
import classes from './AddExpenseListForm.module.css';
|
import classes from './AddExpenseListForm.module.css';
|
||||||
|
|
||||||
@ -46,15 +48,32 @@ const AddExpensesListForm: FC<AddExpenseListFormProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
className={classes.form}
|
className={classes.form}
|
||||||
|
data-testid={DataTestId.ADD_EXPENSES_LIST_FORM}
|
||||||
onSubmit={onFormSubmitHandler}
|
onSubmit={onFormSubmitHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
<h2>Добавить список расходов</h2>
|
<Typography variant="h6">
|
||||||
|
Добавить список расходов
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<Input disabled={disabled} label="Название" name="title" />
|
<TextField
|
||||||
|
disabled={disabled}
|
||||||
|
label="Название"
|
||||||
|
name="title"
|
||||||
|
required
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Добавить</button>
|
<Button
|
||||||
|
data-testid={DataTestId.ADD_EXPENSES_LIST_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
size="small"
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Добавить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,8 +5,12 @@ import type {
|
|||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
|
import { Button, Typography } from '@mui/material';
|
||||||
|
|
||||||
import type { ExpenseList } from '@/entity/expenses/list';
|
import type { ExpenseList } from '@/entity/expenses/list';
|
||||||
|
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
|
|
||||||
export type DeleteExpenseListFormProps = BaseFormProps & {
|
export type DeleteExpenseListFormProps = BaseFormProps & {
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
list: ExpenseList;
|
list: ExpenseList;
|
||||||
@ -31,10 +35,17 @@ const DeleteExpensesListForm: FC<DeleteExpenseListFormProps> = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={onFormSubmitHandler} ref={ref} {...restProps}>
|
<form
|
||||||
<h2>Удалить список расходов</h2>
|
data-testid={DataTestId.DELETE_EXPENSES_LIST_FORM}
|
||||||
|
onSubmit={onFormSubmitHandler}
|
||||||
|
ref={ref}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
<Typography variant="h6">
|
||||||
|
Удалить список расходов
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<p>
|
<Typography sx={{ mt: 2 }} variant="body2">
|
||||||
Вы действительно хотите удалить список расходов
|
Вы действительно хотите удалить список расходов
|
||||||
{' '}
|
{' '}
|
||||||
|
|
||||||
@ -44,12 +55,12 @@ const DeleteExpensesListForm: FC<DeleteExpenseListFormProps> = (props) => {
|
|||||||
|
|
||||||
{' '}
|
{' '}
|
||||||
?
|
?
|
||||||
</p>
|
</Typography>
|
||||||
|
|
||||||
{
|
{
|
||||||
list.items && list.items.length > 0
|
list.items && list.items.length > 0
|
||||||
? (
|
? (
|
||||||
<p>
|
<Typography sx={{ mt: 1 }} variant="body2">
|
||||||
В нем содержится
|
В нем содержится
|
||||||
{' '}
|
{' '}
|
||||||
|
|
||||||
@ -59,12 +70,23 @@ const DeleteExpensesListForm: FC<DeleteExpenseListFormProps> = (props) => {
|
|||||||
|
|
||||||
{' '}
|
{' '}
|
||||||
расходов
|
расходов
|
||||||
</p>
|
</Typography>
|
||||||
)
|
)
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Удалить</button>
|
<Button
|
||||||
|
color="error"
|
||||||
|
data-testid={DataTestId.DELETE_EXPENSES_LIST_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Удалить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,9 +5,11 @@ import type {
|
|||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
|
import { Button, TextField, Typography } from '@mui/material';
|
||||||
|
|
||||||
import type { ExpenseList } from '@/entity/expenses/list';
|
import type { ExpenseList } from '@/entity/expenses/list';
|
||||||
|
|
||||||
import { Input } from '@/shared/ui/Input';
|
import { DataTestId } from '@/shared/constants';
|
||||||
|
|
||||||
import classes from './EditExpenseListForm.module.css';
|
import classes from './EditExpenseListForm.module.css';
|
||||||
|
|
||||||
@ -48,20 +50,32 @@ const EditExpensesListForm: FC<EditExpensesListFormProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
className={classes.form}
|
className={classes.form}
|
||||||
|
data-testid={DataTestId.EDIT_EXPENSES_LIST_FORM}
|
||||||
onSubmit={onFormSubmitHandler}
|
onSubmit={onFormSubmitHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
<h2>Редактировать список расходов</h2>
|
<Typography variant="h6">
|
||||||
|
Редактировать список расходов
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
defaultValue={list.title}
|
defaultValue={list.title}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Название"
|
label="Название"
|
||||||
name="title"
|
name="title"
|
||||||
|
required
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Сохранить</button>
|
<Button
|
||||||
|
data-testid={DataTestId.EDIT_EXPENSES_LIST_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
size="small"
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Сохранить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -9,9 +9,11 @@ export { useEditIncomeItem } from './hooks/useEditIncomeItem';
|
|||||||
export type { IncomeListItem } from './types';
|
export type { IncomeListItem } from './types';
|
||||||
export type { AddIncomeItemFormValues } from './ui/AddIncomeItemForm/AddIncomeItemForm.ui';
|
export type { AddIncomeItemFormValues } from './ui/AddIncomeItemForm/AddIncomeItemForm.ui';
|
||||||
|
|
||||||
|
export type { AddIncomeItemFormProps } from './ui/AddIncomeItemForm/AddIncomeItemForm.ui';
|
||||||
export { default as AddIncomeItemForm } from './ui/AddIncomeItemForm/AddIncomeItemForm.ui';
|
export { default as AddIncomeItemForm } from './ui/AddIncomeItemForm/AddIncomeItemForm.ui';
|
||||||
|
export type { DeleteIncomeItemFormProps } from './ui/DeleteIncomeItemForm/DeleteIncomeItemForm.ui';
|
||||||
export { default as DeleteIncomeItemForm } from './ui/DeleteIncomeItemForm/DeleteIncomeItemForm.ui';
|
export { default as DeleteIncomeItemForm } from './ui/DeleteIncomeItemForm/DeleteIncomeItemForm.ui';
|
||||||
|
|
||||||
export type { EditIncomeItemFormValues } from './ui/EditIncomeItemForm/EditIncomeItemForm.ui';
|
export type { EditIncomeItemFormProps, EditIncomeItemFormValues } from './ui/EditIncomeItemForm/EditIncomeItemForm.ui';
|
||||||
|
|
||||||
export { default as EditIncomeItemForm } from './ui/EditIncomeItemForm/EditIncomeItemForm.ui';
|
export { default as EditIncomeItemForm } from './ui/EditIncomeItemForm/EditIncomeItemForm.ui';
|
||||||
|
|||||||
@ -5,7 +5,11 @@ import type {
|
|||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
import { Input } from '@/shared/ui/Input';
|
import { Button, TextField, Typography } from '@mui/material';
|
||||||
|
import { DatePicker } from '@mui/x-date-pickers';
|
||||||
|
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
|
import { getUTCDate } from '@/shared/utils';
|
||||||
|
|
||||||
import classes from './AddIncomeItemForm.module.css';
|
import classes from './AddIncomeItemForm.module.css';
|
||||||
|
|
||||||
@ -47,7 +51,7 @@ const AddIncomeItemForm: FC<AddIncomeItemFormProps> = (props) => {
|
|||||||
onSubmit?.({
|
onSubmit?.({
|
||||||
amount: Number(amount),
|
amount: Number(amount),
|
||||||
currency: 'RUB',
|
currency: 'RUB',
|
||||||
date: new Date(date).toISOString(),
|
date: getUTCDate(date),
|
||||||
description,
|
description,
|
||||||
title,
|
title,
|
||||||
});
|
});
|
||||||
@ -57,43 +61,57 @@ const AddIncomeItemForm: FC<AddIncomeItemFormProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
className={classes.form}
|
className={classes.form}
|
||||||
|
data-testid={DataTestId.ADD_INCOME_ITEM_FORM}
|
||||||
onSubmit={onFormSubmitHandler}
|
onSubmit={onFormSubmitHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
{...formProps}
|
{...formProps}
|
||||||
>
|
>
|
||||||
<h2>Добавить список доходов</h2>
|
<Typography variant="h6">
|
||||||
|
Добавить список доходов
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Название"
|
label="Название"
|
||||||
name="title"
|
name="title"
|
||||||
required
|
required
|
||||||
|
size="small"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Описание"
|
label="Описание"
|
||||||
name="description"
|
name="description"
|
||||||
|
size="small"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<DatePicker
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
disableFuture
|
||||||
|
format="dd.MM.yyyy"
|
||||||
label="Дата"
|
label="Дата"
|
||||||
name="date"
|
name="date"
|
||||||
required
|
slotProps={{ textField: { required: true, size: 'small' } }}
|
||||||
type="date"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
inputMode="numeric"
|
||||||
label="Сумма"
|
label="Сумма"
|
||||||
name="amount"
|
name="amount"
|
||||||
required
|
required
|
||||||
step="0.01"
|
size="small"
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Добавить</button>
|
<Button
|
||||||
|
data-testid={DataTestId.ADD_INCOME_ITEM_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Добавить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,6 +5,10 @@ import type {
|
|||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
|
import { Button, Typography } from '@mui/material';
|
||||||
|
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
|
|
||||||
import type { IncomeListItem } from '../../types';
|
import type { IncomeListItem } from '../../types';
|
||||||
|
|
||||||
export type DeleteIncomeItemFormProps = BaseFormProps & {
|
export type DeleteIncomeItemFormProps = BaseFormProps & {
|
||||||
@ -30,10 +34,25 @@ const DeleteIncomeItemForm: FC<DeleteIncomeItemFormProps> = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={onFormSubmitHandler} ref={ref} {...restProps}>
|
<form
|
||||||
<h2>Удалить элемент ?</h2>
|
data-testid={DataTestId.DELETE_INCOME_ITEM_FORM}
|
||||||
|
onSubmit={onFormSubmitHandler}
|
||||||
|
ref={ref}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
<Typography variant="h6">
|
||||||
|
Удалить элемент ?
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Удалить</button>
|
<Button
|
||||||
|
color="error"
|
||||||
|
data-testid={DataTestId.DELETE_INCOME_ITEM_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Удалить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,7 +5,11 @@ import type {
|
|||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
import { Input } from '@/shared/ui/Input';
|
import { Button, TextField, Typography } from '@mui/material';
|
||||||
|
import { DatePicker } from '@mui/x-date-pickers';
|
||||||
|
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
|
import { getUTCDate } from '@/shared/utils';
|
||||||
|
|
||||||
import type { IncomeListItem } from '../../types';
|
import type { IncomeListItem } from '../../types';
|
||||||
|
|
||||||
@ -50,7 +54,7 @@ const EditIncomeItemForm: FC<EditIncomeItemFormProps> = (props) => {
|
|||||||
await onSubmit?.({
|
await onSubmit?.({
|
||||||
amount: Number(amount),
|
amount: Number(amount),
|
||||||
currency: 'RUB',
|
currency: 'RUB',
|
||||||
date: new Date(date).toISOString(),
|
date: getUTCDate(date),
|
||||||
description,
|
description,
|
||||||
title,
|
title,
|
||||||
});
|
});
|
||||||
@ -60,44 +64,58 @@ const EditIncomeItemForm: FC<EditIncomeItemFormProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
className={classes.form}
|
className={classes.form}
|
||||||
|
data-testid={DataTestId.EDIT_INCOME_ITEM_FORM}
|
||||||
onSubmit={onFormSubmitHandler}
|
onSubmit={onFormSubmitHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
{...formProps}
|
{...formProps}
|
||||||
>
|
>
|
||||||
<h2>Изменить доход</h2>
|
<Typography variant="h6">
|
||||||
|
Изменить доход
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
defaultValue={item.title}
|
defaultValue={item.title}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Название"
|
label="Название"
|
||||||
name="title"
|
name="title"
|
||||||
|
required
|
||||||
|
size="small"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
defaultValue={item.description ?? ''}
|
defaultValue={item.description ?? ''}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Описание"
|
label="Описание"
|
||||||
name="description"
|
name="description"
|
||||||
|
size="small"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<DatePicker
|
||||||
defaultValue={new Date(item.date).toISOString().split('T')[0]}
|
defaultValue={new Date(item.date)}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Дата"
|
label="Дата"
|
||||||
name="date"
|
name="date"
|
||||||
type="date"
|
slotProps={{ textField: { required: true, size: 'small' } }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
defaultValue={item.amount}
|
defaultValue={item.amount}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
inputMode="numeric"
|
||||||
label="Сумма"
|
label="Сумма"
|
||||||
name="amount"
|
name="amount"
|
||||||
step="0.01"
|
size="small"
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Сохранить</button>
|
<Button
|
||||||
|
data-testid={DataTestId.EDIT_INCOME_ITEM_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Сохранить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -9,7 +9,7 @@ export const useAddIncomesList = () => {
|
|||||||
|
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: addIncomeList,
|
mutationFn: addIncomeList,
|
||||||
mutationKey: [QueryKeys.ExpenseList],
|
mutationKey: [QueryKeys.IncomesList],
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
await queryClient.invalidateQueries({ queryKey: [QueryKeys.IncomesList] });
|
await queryClient.invalidateQueries({ queryKey: [QueryKeys.IncomesList] });
|
||||||
},
|
},
|
||||||
|
|||||||
@ -10,10 +10,11 @@ export { useIncomesList } from './hooks/useIncomesList';
|
|||||||
|
|
||||||
export type { IncomeList } from './types';
|
export type { IncomeList } from './types';
|
||||||
|
|
||||||
export type { AddIncomeListFormValues } from './ui/AddIncomeListForm/ui/AddIncomeListForm.ui';
|
export type { AddIncomeListFormProps, AddIncomeListFormValues } from './ui/AddIncomeListForm/ui/AddIncomeListForm.ui';
|
||||||
export { default as AddIncomeListForm } from './ui/AddIncomeListForm/ui/AddIncomeListForm.ui';
|
export { default as AddIncomeListForm } from './ui/AddIncomeListForm/ui/AddIncomeListForm.ui';
|
||||||
|
|
||||||
|
export type { DeleteIncomeListFormProps } from './ui/DeleteIncomeListForm/ui/DeleteIncomeListForm.ui';
|
||||||
export { default as DeleteIncomeListForm } from './ui/DeleteIncomeListForm/ui/DeleteIncomeListForm.ui';
|
export { default as DeleteIncomeListForm } from './ui/DeleteIncomeListForm/ui/DeleteIncomeListForm.ui';
|
||||||
|
|
||||||
export type { EditIncomeListFormValues } from './ui/EditIncomeListForm/ui/EditIncomeListForm.ui';
|
export type { EditIncomeListFormProps, EditIncomeListFormValues } from './ui/EditIncomeListForm/ui/EditIncomeListForm.ui';
|
||||||
export { default as EditIncomeListForm } from './ui/EditIncomeListForm/ui/EditIncomeListForm.ui';
|
export { default as EditIncomeListForm } from './ui/EditIncomeListForm/ui/EditIncomeListForm.ui';
|
||||||
|
|||||||
@ -5,7 +5,9 @@ import type {
|
|||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
import { Input } from '@/shared/ui/Input';
|
import { Button, TextField, Typography } from '@mui/material';
|
||||||
|
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
|
|
||||||
import classes from './AddIncomeListForm.module.css';
|
import classes from './AddIncomeListForm.module.css';
|
||||||
|
|
||||||
@ -46,15 +48,31 @@ const AddIncomeListForm: FC<AddIncomeListFormProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
className={classes.form}
|
className={classes.form}
|
||||||
|
data-testid={DataTestId.ADD_INCOME_LIST_FORM}
|
||||||
onSubmit={onFormSubmitHandler}
|
onSubmit={onFormSubmitHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
<h2>Добавить список доходов</h2>
|
<Typography variant="h6">
|
||||||
|
Добавить список доходов
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<Input disabled={disabled} label="Название" name="title" />
|
<TextField
|
||||||
|
disabled={disabled}
|
||||||
|
label="Название"
|
||||||
|
name="title"
|
||||||
|
required
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Добавить</button>
|
<Button
|
||||||
|
data-testid={DataTestId.ADD_INCOME_LIST_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Добавить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,6 +5,10 @@ import type {
|
|||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
|
import { Button, Typography } from '@mui/material';
|
||||||
|
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
|
|
||||||
import type { IncomeList } from '../../../types';
|
import type { IncomeList } from '../../../types';
|
||||||
|
|
||||||
export type DeleteIncomeListFormProps = BaseFormProps & {
|
export type DeleteIncomeListFormProps = BaseFormProps & {
|
||||||
@ -31,10 +35,17 @@ const DeleteIncomeListForm: FC<DeleteIncomeListFormProps> = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={onFormSubmitHandler} ref={ref} {...restProps}>
|
<form
|
||||||
<h2>Удалить список доходов</h2>
|
data-testid={DataTestId.DELETE_INCOME_LIST_FORM}
|
||||||
|
onSubmit={onFormSubmitHandler}
|
||||||
|
ref={ref}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
<Typography variant="h6">
|
||||||
|
Удалить список доходов
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<p>
|
<Typography sx={{ mt: 2 }} variant="body1">
|
||||||
Вы действительно хотите удалить список доходов
|
Вы действительно хотите удалить список доходов
|
||||||
{' '}
|
{' '}
|
||||||
|
|
||||||
@ -44,12 +55,12 @@ const DeleteIncomeListForm: FC<DeleteIncomeListFormProps> = (props) => {
|
|||||||
|
|
||||||
{' '}
|
{' '}
|
||||||
?
|
?
|
||||||
</p>
|
</Typography>
|
||||||
|
|
||||||
{
|
{
|
||||||
list.items && list.items.length > 0
|
list.items && list.items.length > 0
|
||||||
? (
|
? (
|
||||||
<p>
|
<Typography sx={{ mt: 1 }} variant="body1">
|
||||||
В нем содержится
|
В нем содержится
|
||||||
{' '}
|
{' '}
|
||||||
|
|
||||||
@ -59,12 +70,22 @@ const DeleteIncomeListForm: FC<DeleteIncomeListFormProps> = (props) => {
|
|||||||
|
|
||||||
{' '}
|
{' '}
|
||||||
доходов
|
доходов
|
||||||
</p>
|
</Typography>
|
||||||
)
|
)
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Удалить</button>
|
<Button
|
||||||
|
color="error"
|
||||||
|
data-testid={DataTestId.DELETE_INCOME_LIST_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
fullWidth
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Удалить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,13 +5,15 @@ import type {
|
|||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
import { Input } from '@/shared/ui/Input';
|
import { Button, TextField, Typography } from '@mui/material';
|
||||||
|
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
|
|
||||||
import type { IncomeList } from '../../../types';
|
import type { IncomeList } from '../../../types';
|
||||||
|
|
||||||
import classes from './EditIncomeListForm.module.css';
|
import classes from './EditIncomeListForm.module.css';
|
||||||
|
|
||||||
export type EditExpensesListFormProps = BaseFormProps & {
|
export type EditIncomeListFormProps = BaseFormProps & {
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
list: IncomeList;
|
list: IncomeList;
|
||||||
onSubmit: (data: EditIncomeListFormValues) => Promise<void> | void;
|
onSubmit: (data: EditIncomeListFormValues) => Promise<void> | void;
|
||||||
@ -24,7 +26,7 @@ export type EditIncomeListFormValues = {
|
|||||||
|
|
||||||
type BaseFormProps = Omit<FormHTMLAttributes<HTMLFormElement>, 'onSubmit'>;
|
type BaseFormProps = Omit<FormHTMLAttributes<HTMLFormElement>, 'onSubmit'>;
|
||||||
|
|
||||||
const EditExpensesListForm: FC<EditExpensesListFormProps> = (props) => {
|
const EditIncomeListForm: FC<EditIncomeListFormProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
disabled,
|
disabled,
|
||||||
list,
|
list,
|
||||||
@ -48,22 +50,34 @@ const EditExpensesListForm: FC<EditExpensesListFormProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
className={classes.form}
|
className={classes.form}
|
||||||
|
data-testid={DataTestId.EDIT_INCOME_LIST_FORM}
|
||||||
onSubmit={onFormSubmitHandler}
|
onSubmit={onFormSubmitHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
<h2>Редактировать список доходов</h2>
|
<Typography variant="h6">
|
||||||
|
Редактировать список доходов
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
defaultValue={list.title}
|
defaultValue={list.title}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label="Название"
|
label="Название"
|
||||||
name="title"
|
name="title"
|
||||||
|
required
|
||||||
|
size="small"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button disabled={disabled} type="submit">Сохранить</button>
|
<Button
|
||||||
|
data-testid={DataTestId.EDIT_INCOME_LIST_SUBMIT_BUTTON}
|
||||||
|
disabled={disabled}
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Сохранить
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default EditExpensesListForm;
|
export default EditIncomeListForm;
|
||||||
|
|||||||
@ -1,11 +1,15 @@
|
|||||||
import type { ButtonHTMLAttributes, FC, Ref } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { FC, Ref } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import { AddBankCardForm } from '@/entity/cards';
|
import { AddBankCardForm } from '@/entity/cards';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useAddBankCardButton } from '../hooks/useAddBankCardButton';
|
import { useAddBankCardButton } from '../hooks/useAddBankCardButton';
|
||||||
|
|
||||||
type AddBankCardButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
type AddBankCardButtonProps = ButtonProps & {
|
||||||
ref?: Ref<HTMLButtonElement>;
|
ref?: Ref<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -22,14 +26,15 @@ const AddBankCardButton: FC<AddBankCardButtonProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button
|
<Button
|
||||||
|
data-testid={DataTestId.ADD_BANK_CARD_BUTTON}
|
||||||
onClick={onClickHandler}
|
onClick={onClickHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
type="button"
|
variant="contained"
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
Добавить
|
Добавить
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<AddBankCardForm disabled={isPending} onSubmit={onFormSubmitHandler} />
|
<AddBankCardForm disabled={isPending} onSubmit={onFormSubmitHandler} />
|
||||||
|
|||||||
@ -1,13 +1,17 @@
|
|||||||
import type { ButtonHTMLAttributes, FC, Ref } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { FC, Ref } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import type { BankCard } from '@/entity/cards';
|
import type { BankCard } from '@/entity/cards';
|
||||||
|
|
||||||
import { DeleteBankCardForm } from '@/entity/cards';
|
import { DeleteBankCardForm } from '@/entity/cards';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useDeleteBankCardButton } from '../hooks/useDeleteBankCardButton';
|
import { useDeleteBankCardButton } from '../hooks/useDeleteBankCardButton';
|
||||||
|
|
||||||
export type DeleteBankCardButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
export type DeleteBankCardButtonProps = ButtonProps & {
|
||||||
bankCard: BankCard;
|
bankCard: BankCard;
|
||||||
ref?: Ref<HTMLButtonElement>;
|
ref?: Ref<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
@ -30,9 +34,16 @@ const DeleteBankCardButton: FC<DeleteBankCardButtonProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button onClick={onClickHandler} type="button" {...restProps}>
|
<Button
|
||||||
|
color="error"
|
||||||
|
data-testid={DataTestId.DELETE_BANK_CARD_BUTTON}
|
||||||
|
onClick={onClickHandler}
|
||||||
|
ref={ref}
|
||||||
|
size="small"
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
Удалить
|
Удалить
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<DeleteBankCardForm
|
<DeleteBankCardForm
|
||||||
|
|||||||
@ -1,13 +1,17 @@
|
|||||||
import type { ButtonHTMLAttributes, FC, Ref } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { FC, Ref } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import type { BankCard } from '@/entity/cards';
|
import type { BankCard } from '@/entity/cards';
|
||||||
|
|
||||||
import { EditBankCardForm } from '@/entity/cards';
|
import { EditBankCardForm } from '@/entity/cards';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useEditBankCardButton } from '../hooks/useEditBankCardButton';
|
import { useEditBankCardButton } from '../hooks/useEditBankCardButton';
|
||||||
|
|
||||||
export type EditBankCardButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
export type EditBankCardButtonProps = ButtonProps & {
|
||||||
bankCard: BankCard;
|
bankCard: BankCard;
|
||||||
ref?: Ref<HTMLButtonElement>;
|
ref?: Ref<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
@ -29,9 +33,15 @@ const EditBankCardButton: FC<EditBankCardButtonProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button onClick={onClickHandler} type="button" {...restProps}>
|
<Button
|
||||||
|
data-testid={DataTestId.EDIT_BANK_CARD_BUTTON}
|
||||||
|
onClick={onClickHandler}
|
||||||
|
ref={ref}
|
||||||
|
size="small"
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
Редактировать
|
Редактировать
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<EditBankCardForm
|
<EditBankCardForm
|
||||||
|
|||||||
@ -1,11 +1,15 @@
|
|||||||
import type { ButtonHTMLAttributes, FC, Ref } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { FC, Ref } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import { AddCashForm } from '@/entity/cash';
|
import { AddCashForm } from '@/entity/cash';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useAddCashButton } from '../hooks/useAddCashButton';
|
import { useAddCashButton } from '../hooks/useAddCashButton';
|
||||||
|
|
||||||
type AddCashButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
type AddCashButtonProps = ButtonProps & {
|
||||||
ref?: Ref<HTMLButtonElement>;
|
ref?: Ref<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -22,14 +26,15 @@ const AddCashButton: FC<AddCashButtonProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button
|
<Button
|
||||||
|
data-testid={DataTestId.ADD_CASH_BUTTON}
|
||||||
onClick={onClickHandler}
|
onClick={onClickHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
type="button"
|
variant="contained"
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
Добавить
|
Добавить
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<AddCashForm disabled={isPending} onSubmit={onFormSubmitHandler} />
|
<AddCashForm disabled={isPending} onSubmit={onFormSubmitHandler} />
|
||||||
|
|||||||
@ -1,13 +1,17 @@
|
|||||||
import type { ButtonHTMLAttributes, FC, Ref } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { FC, Ref } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import type { CashItem } from '@/entity/cash';
|
import type { CashItem } from '@/entity/cash';
|
||||||
|
|
||||||
import { DeleteCashForm } from '@/entity/cash';
|
import { DeleteCashForm } from '@/entity/cash';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useDeleteCashButton } from '../hooks/useDeleteCashButton';
|
import { useDeleteCashButton } from '../hooks/useDeleteCashButton';
|
||||||
|
|
||||||
export type DeleteCashButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
export type DeleteCashButtonProps = ButtonProps & {
|
||||||
cash: CashItem;
|
cash: CashItem;
|
||||||
ref?: Ref<HTMLButtonElement>;
|
ref?: Ref<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
@ -30,9 +34,16 @@ const DeleteCashButton: FC<DeleteCashButtonProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button onClick={onClickHandler} type="button" {...restProps}>
|
<Button
|
||||||
|
color="error"
|
||||||
|
data-testid={DataTestId.DELETE_CASH_BUTTON}
|
||||||
|
onClick={onClickHandler}
|
||||||
|
ref={ref}
|
||||||
|
size="small"
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
Удалить
|
Удалить
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<DeleteCashForm
|
<DeleteCashForm
|
||||||
|
|||||||
@ -1,13 +1,17 @@
|
|||||||
import type { ButtonHTMLAttributes, FC, Ref } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { FC, Ref } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import type { CashItem } from '@/entity/cash';
|
import type { CashItem } from '@/entity/cash';
|
||||||
|
|
||||||
import { EditCashForm } from '@/entity/cash';
|
import { EditCashForm } from '@/entity/cash';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useEditCashButton } from '../hooks/useEditCashButton';
|
import { useEditCashButton } from '../hooks/useEditCashButton';
|
||||||
|
|
||||||
export type EditCashButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
export type EditCashButtonProps = ButtonProps & {
|
||||||
cash: CashItem;
|
cash: CashItem;
|
||||||
ref?: Ref<HTMLButtonElement>;
|
ref?: Ref<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
@ -29,9 +33,15 @@ const EditCashButton: FC<EditCashButtonProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button onClick={onClickHandler} type="button" {...restProps}>
|
<Button
|
||||||
|
data-testid={DataTestId.EDIT_CASH_BUTTON}
|
||||||
|
onClick={onClickHandler}
|
||||||
|
ref={ref}
|
||||||
|
size="small"
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
Редактировать
|
Редактировать
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<EditCashForm
|
<EditCashForm
|
||||||
|
|||||||
@ -1,19 +1,21 @@
|
|||||||
import type { ButtonHTMLAttributes, FC, RefObject } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { FC, RefObject } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import type { ExpenseList } from '@/entity/expenses/list';
|
import type { ExpenseList } from '@/entity/expenses/list';
|
||||||
|
|
||||||
import { AddExpenseItemForm } from '@/entity/expenses/item';
|
import { AddExpenseItemForm } from '@/entity/expenses/item';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useAddExpenseItemButton } from '../hooks/useAddExpenseItemButton';
|
import { useAddExpenseItemButton } from '../hooks/useAddExpenseItemButton';
|
||||||
|
|
||||||
type AddExpenseItemButtonProps = BaseButtonProps & {
|
type AddExpenseItemButtonProps = ButtonProps & {
|
||||||
listId: ExpenseList['id'];
|
listId: ExpenseList['id'];
|
||||||
ref?: RefObject<HTMLButtonElement>;
|
ref?: RefObject<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type BaseButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
|
|
||||||
|
|
||||||
const AddExpenseItemButton: FC<AddExpenseItemButtonProps> = (props) => {
|
const AddExpenseItemButton: FC<AddExpenseItemButtonProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
listId,
|
listId,
|
||||||
@ -32,14 +34,15 @@ const AddExpenseItemButton: FC<AddExpenseItemButtonProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button
|
<Button
|
||||||
|
data-testid={DataTestId.ADD_EXPENSE_ITEM_BUTTON}
|
||||||
onClick={onClickHandler}
|
onClick={onClickHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
type="button"
|
variant="contained"
|
||||||
{...buttonProps}
|
{...buttonProps}
|
||||||
>
|
>
|
||||||
Добавить элемент
|
Добавить элемент
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<AddExpenseItemForm disabled={isPending} onSubmit={onFormSubmitHandler} />
|
<AddExpenseItemForm disabled={isPending} onSubmit={onFormSubmitHandler} />
|
||||||
|
|||||||
@ -1,15 +1,17 @@
|
|||||||
import type { ButtonHTMLAttributes, FC, RefObject } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { FC, RefObject } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import type { ExpenseListItem } from '@/entity/expenses/item';
|
import type { ExpenseListItem } from '@/entity/expenses/item';
|
||||||
|
|
||||||
import { DeleteExpenseItemForm } from '@/entity/expenses/item';
|
import { DeleteExpenseItemForm } from '@/entity/expenses/item';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useDeleteExpenseItemButton } from '../hooks/useDeleteExpenseItemButton';
|
import { useDeleteExpenseItemButton } from '../hooks/useDeleteExpenseItemButton';
|
||||||
|
|
||||||
type BaseButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
|
type DeleteExpenseItemButtonProps = ButtonProps & {
|
||||||
|
|
||||||
type DeleteExpenseItemButtonProps = BaseButtonProps & {
|
|
||||||
item: ExpenseListItem;
|
item: ExpenseListItem;
|
||||||
ref?: RefObject<HTMLButtonElement>;
|
ref?: RefObject<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
@ -30,14 +32,16 @@ const DeleteExpenseItemButton: FC<DeleteExpenseItemButtonProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button
|
<Button
|
||||||
|
color="error"
|
||||||
|
data-testid={DataTestId.DELETE_EXPENSE_ITEM_BUTTON}
|
||||||
onClick={onClickHandler}
|
onClick={onClickHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
type="button"
|
size="small"
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
Удалить
|
Удалить
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<DeleteExpenseItemForm disabled={isPending} item={item} onSubmit={onFormSubmitHandler} />
|
<DeleteExpenseItemForm disabled={isPending} item={item} onSubmit={onFormSubmitHandler} />
|
||||||
|
|||||||
@ -1,15 +1,17 @@
|
|||||||
import type { ButtonHTMLAttributes, FC, RefObject } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { FC, RefObject } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import type { ExpenseListItem } from '@/entity/expenses/item';
|
import type { ExpenseListItem } from '@/entity/expenses/item';
|
||||||
|
|
||||||
import { EditExpenseItemForm } from '@/entity/expenses/item';
|
import { EditExpenseItemForm } from '@/entity/expenses/item';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useEditExpenseItemButton } from '../hooks/useEditExpenseItemButton';
|
import { useEditExpenseItemButton } from '../hooks/useEditExpenseItemButton';
|
||||||
|
|
||||||
type BaseButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
|
type EditExpenseItemButtonProps = ButtonProps & {
|
||||||
|
|
||||||
type EditExpenseItemButtonProps = BaseButtonProps & {
|
|
||||||
item: ExpenseListItem;
|
item: ExpenseListItem;
|
||||||
ref?: RefObject<HTMLButtonElement>;
|
ref?: RefObject<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
@ -32,15 +34,16 @@ const EditExpenseItemButton: FC<EditExpenseItemButtonProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button
|
<Button
|
||||||
|
data-testid={DataTestId.EDIT_EXPENSE_ITEM_BUTTON}
|
||||||
disabled={isPending}
|
disabled={isPending}
|
||||||
onClick={onClickHandler}
|
onClick={onClickHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
type="button"
|
size="small"
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
Редактировать
|
Редактировать
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<EditExpenseItemForm disabled={isPending} item={item} onSubmit={onFormSubmitHandler} />
|
<EditExpenseItemForm disabled={isPending} item={item} onSubmit={onFormSubmitHandler} />
|
||||||
|
|||||||
@ -1,11 +1,15 @@
|
|||||||
import type { ButtonHTMLAttributes, FC, Ref } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { FC, Ref } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import { AddExpensesListForm } from '@/entity/expenses/list';
|
import { AddExpensesListForm } from '@/entity/expenses/list';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useAddExpensesListButton } from '../hooks/useAddExpensesListButton';
|
import { useAddExpensesListButton } from '../hooks/useAddExpensesListButton';
|
||||||
|
|
||||||
type AddExpensesListButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
type AddExpensesListButtonProps = ButtonProps & {
|
||||||
ref?: Ref<HTMLButtonElement>;
|
ref?: Ref<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -22,9 +26,14 @@ const AddExpensesListButton: FC<AddExpensesListButtonProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button onClick={onClickHandler} type="button" {...restProps}>
|
<Button
|
||||||
|
data-testid={DataTestId.ADD_EXPENSES_LIST_BUTTON}
|
||||||
|
onClick={onClickHandler}
|
||||||
|
variant="contained"
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
Добавить
|
Добавить
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<AddExpensesListForm disabled={isPending} onSubmit={onFormSubmitHandler} />
|
<AddExpensesListForm disabled={isPending} onSubmit={onFormSubmitHandler} />
|
||||||
|
|||||||
@ -1,13 +1,18 @@
|
|||||||
import type { ButtonHTMLAttributes, Ref } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { Ref } from 'react';
|
||||||
|
|
||||||
|
import DeleteIcon from '@mui/icons-material/Delete';
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import type { ExpenseList } from '@/entity/expenses/list';
|
import type { ExpenseList } from '@/entity/expenses/list';
|
||||||
|
|
||||||
import { DeleteExpensesListForm } from '@/entity/expenses/list';
|
import { DeleteExpensesListForm } from '@/entity/expenses/list';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useDeleteExpensesListButton } from '../hooks/useDeleteExpensesListButton';
|
import { useDeleteExpensesListButton } from '../hooks/useDeleteExpensesListButton';
|
||||||
|
|
||||||
type DeleteExpensesListButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
type DeleteExpensesListButtonProps = ButtonProps & {
|
||||||
list: ExpenseList;
|
list: ExpenseList;
|
||||||
ref?: Ref<HTMLButtonElement>;
|
ref?: Ref<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
@ -25,9 +30,16 @@ const DeleteExpensesListButton = (props: DeleteExpensesListButtonProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button onClick={onClickHandler} type="button" {...restProps}>
|
<Button
|
||||||
|
color="error"
|
||||||
|
data-testid={DataTestId.DELETE_EXPENSES_LIST_BUTTON}
|
||||||
|
onClick={onClickHandler}
|
||||||
|
size="small"
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
<DeleteIcon fontSize="small" />
|
||||||
Удалить
|
Удалить
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<DeleteExpensesListForm
|
<DeleteExpensesListForm
|
||||||
|
|||||||
@ -1,13 +1,18 @@
|
|||||||
import type { ButtonHTMLAttributes, FC, Ref } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { FC, Ref } from 'react';
|
||||||
|
|
||||||
|
import EditIcon from '@mui/icons-material/Edit';
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import type { ExpenseList } from '@/entity/expenses/list';
|
import type { ExpenseList } from '@/entity/expenses/list';
|
||||||
|
|
||||||
import { EditExpensesListForm } from '@/entity/expenses/list';
|
import { EditExpensesListForm } from '@/entity/expenses/list';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useEditExpensesListButton } from '../hooks/useEditExpensesListButton';
|
import { useEditExpensesListButton } from '../hooks/useEditExpensesListButton';
|
||||||
|
|
||||||
type EditExpensesListButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
type EditExpensesListButtonProps = ButtonProps & {
|
||||||
list: ExpenseList;
|
list: ExpenseList;
|
||||||
ref?: Ref<HTMLButtonElement>;
|
ref?: Ref<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
@ -25,9 +30,15 @@ const EditExpensesListButton: FC<EditExpensesListButtonProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button onClick={onClickHandler} type="button" {...restProps}>
|
<Button
|
||||||
|
data-testid={DataTestId.EDIT_EXPENSES_LIST_BUTTON}
|
||||||
|
onClick={onClickHandler}
|
||||||
|
size="small"
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
<EditIcon fontSize="small" />
|
||||||
Редактировать
|
Редактировать
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<EditExpensesListForm disabled={isPending} list={list} onSubmit={onFormSubmitHandler} />
|
<EditExpensesListForm disabled={isPending} list={list} onSubmit={onFormSubmitHandler} />
|
||||||
|
|||||||
@ -1,19 +1,21 @@
|
|||||||
import type { ButtonHTMLAttributes, FC, RefObject } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { FC, RefObject } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import type { IncomeList } from '@/entity/incomes/list';
|
import type { IncomeList } from '@/entity/incomes/list';
|
||||||
|
|
||||||
import { AddIncomeItemForm } from '@/entity/incomes/item';
|
import { AddIncomeItemForm } from '@/entity/incomes/item';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useAddIncomeItemButton } from '../hooks/useAddIncomeItemButton';
|
import { useAddIncomeItemButton } from '../hooks/useAddIncomeItemButton';
|
||||||
|
|
||||||
type AddIncomeItemButtonProps = BaseButtonProps & {
|
type AddIncomeItemButtonProps = ButtonProps & {
|
||||||
listId: IncomeList['id'];
|
listId: IncomeList['id'];
|
||||||
ref?: RefObject<HTMLButtonElement>;
|
ref?: RefObject<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type BaseButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
|
|
||||||
|
|
||||||
const AddIncomeItemButton: FC<AddIncomeItemButtonProps> = (props) => {
|
const AddIncomeItemButton: FC<AddIncomeItemButtonProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
listId,
|
listId,
|
||||||
@ -32,14 +34,15 @@ const AddIncomeItemButton: FC<AddIncomeItemButtonProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button
|
<Button
|
||||||
|
data-testid={DataTestId.ADD_INCOME_ITEM_BUTTON}
|
||||||
onClick={onClickHandler}
|
onClick={onClickHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
type="button"
|
variant="contained"
|
||||||
{...buttonProps}
|
{...buttonProps}
|
||||||
>
|
>
|
||||||
Добавить элемент
|
Добавить
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<AddIncomeItemForm disabled={isPending} onSubmit={onFormSubmitHandler} />
|
<AddIncomeItemForm disabled={isPending} onSubmit={onFormSubmitHandler} />
|
||||||
|
|||||||
@ -1,15 +1,17 @@
|
|||||||
import type { ButtonHTMLAttributes, FC, RefObject } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { FC, RefObject } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import type { IncomeListItem } from '@/entity/incomes/item';
|
import type { IncomeListItem } from '@/entity/incomes/item';
|
||||||
|
|
||||||
import { DeleteIncomeItemForm } from '@/entity/incomes/item';
|
import { DeleteIncomeItemForm } from '@/entity/incomes/item';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useDeleteIncomeItemButton } from '../hooks/useDeleteIncomeItemButton';
|
import { useDeleteIncomeItemButton } from '../hooks/useDeleteIncomeItemButton';
|
||||||
|
|
||||||
type BaseButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
|
type DeleteIncomeItemButtonProps = ButtonProps & {
|
||||||
|
|
||||||
type DeleteIncomeItemButtonProps = BaseButtonProps & {
|
|
||||||
item: IncomeListItem;
|
item: IncomeListItem;
|
||||||
ref?: RefObject<HTMLButtonElement>;
|
ref?: RefObject<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
@ -30,14 +32,16 @@ const DeleteIncomeItemButton: FC<DeleteIncomeItemButtonProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button
|
<Button
|
||||||
|
color="error"
|
||||||
|
data-testid={DataTestId.DELETE_INCOME_ITEM_BUTTON}
|
||||||
onClick={onClickHandler}
|
onClick={onClickHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
type="button"
|
size="small"
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
Удалить
|
Удалить
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<DeleteIncomeItemForm disabled={isPending} item={item} onSubmit={onFormSubmitHandler} />
|
<DeleteIncomeItemForm disabled={isPending} item={item} onSubmit={onFormSubmitHandler} />
|
||||||
|
|||||||
@ -1,15 +1,17 @@
|
|||||||
import type { ButtonHTMLAttributes, FC, RefObject } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { FC, RefObject } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import type { IncomeListItem } from '@/entity/incomes/item';
|
import type { IncomeListItem } from '@/entity/incomes/item';
|
||||||
|
|
||||||
import { EditIncomeItemForm } from '@/entity/incomes/item';
|
import { EditIncomeItemForm } from '@/entity/incomes/item';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useIncomeItemButton } from '../hooks/useIncomeItemButton';
|
import { useIncomeItemButton } from '../hooks/useIncomeItemButton';
|
||||||
|
|
||||||
type BaseButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
|
type EditIncomeItemButtonProps = ButtonProps & {
|
||||||
|
|
||||||
type EditIncomeItemButtonProps = BaseButtonProps & {
|
|
||||||
item: IncomeListItem;
|
item: IncomeListItem;
|
||||||
ref?: RefObject<HTMLButtonElement>;
|
ref?: RefObject<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
@ -32,15 +34,16 @@ const EditIncomeItemButton: FC<EditIncomeItemButtonProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button
|
<Button
|
||||||
|
data-testid={DataTestId.EDIT_INCOME_ITEM_BUTTON}
|
||||||
disabled={isPending}
|
disabled={isPending}
|
||||||
onClick={onClickHandler}
|
onClick={onClickHandler}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
type="button"
|
size="small"
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
Редактировать
|
Редактировать
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<EditIncomeItemForm disabled={isPending} item={item} onSubmit={onFormSubmitHandler} />
|
<EditIncomeItemForm disabled={isPending} item={item} onSubmit={onFormSubmitHandler} />
|
||||||
|
|||||||
@ -1,11 +1,15 @@
|
|||||||
import type { ButtonHTMLAttributes, FC, Ref } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { FC, Ref } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import { AddIncomeListForm } from '@/entity/incomes/list';
|
import { AddIncomeListForm } from '@/entity/incomes/list';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useAddIncomeListButton } from '../hooks/useAddIncomeListButton';
|
import { useAddIncomeListButton } from '../hooks/useAddIncomeListButton';
|
||||||
|
|
||||||
type AddIncomeListButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
type AddIncomeListButtonProps = ButtonProps & {
|
||||||
ref?: Ref<HTMLButtonElement>;
|
ref?: Ref<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -22,9 +26,14 @@ const AddIncomeListButton: FC<AddIncomeListButtonProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button onClick={onClickHandler} type="button" {...restProps}>
|
<Button
|
||||||
|
data-testid={DataTestId.ADD_INCOME_LIST_BUTTON}
|
||||||
|
onClick={onClickHandler}
|
||||||
|
variant="contained"
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
Добавить
|
Добавить
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<AddIncomeListForm disabled={isPending} onSubmit={onFormSubmitHandler} />
|
<AddIncomeListForm disabled={isPending} onSubmit={onFormSubmitHandler} />
|
||||||
|
|||||||
@ -1,13 +1,17 @@
|
|||||||
import type { ButtonHTMLAttributes, Ref } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { Ref } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import type { IncomeList } from '@/entity/incomes/list';
|
import type { IncomeList } from '@/entity/incomes/list';
|
||||||
|
|
||||||
import { DeleteIncomeListForm } from '@/entity/incomes/list';
|
import { DeleteIncomeListForm } from '@/entity/incomes/list';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useIncomeListButton } from '../hooks/useIncomeListButton';
|
import { useIncomeListButton } from '../hooks/useIncomeListButton';
|
||||||
|
|
||||||
type DeleteIncomeListButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
type DeleteIncomeListButtonProps = ButtonProps & {
|
||||||
list: IncomeList;
|
list: IncomeList;
|
||||||
ref?: Ref<HTMLButtonElement>;
|
ref?: Ref<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
@ -25,9 +29,15 @@ const DeleteIncomeListButton = (props: DeleteIncomeListButtonProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button onClick={onClickHandler} type="button" {...restProps}>
|
<Button
|
||||||
|
color="error"
|
||||||
|
data-testid={DataTestId.DELETE_INCOME_LIST_BUTTON}
|
||||||
|
onClick={onClickHandler}
|
||||||
|
size="small"
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
Удалить
|
Удалить
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<DeleteIncomeListForm
|
<DeleteIncomeListForm
|
||||||
|
|||||||
@ -1,13 +1,17 @@
|
|||||||
import type { ButtonHTMLAttributes, FC, Ref } from 'react';
|
import type { ButtonProps } from '@mui/material';
|
||||||
|
import type { FC, Ref } from 'react';
|
||||||
|
|
||||||
|
import { Button } from '@mui/material';
|
||||||
|
|
||||||
import type { IncomeList } from '@/entity/incomes/list';
|
import type { IncomeList } from '@/entity/incomes/list';
|
||||||
|
|
||||||
import { EditIncomeListForm } from '@/entity/incomes/list';
|
import { EditIncomeListForm } from '@/entity/incomes/list';
|
||||||
|
import { DataTestId } from '@/shared/constants';
|
||||||
import { Modal } from '@/shared/ui/Modal';
|
import { Modal } from '@/shared/ui/Modal';
|
||||||
|
|
||||||
import { useIncomeListButton } from '../hooks/useIncomeListButton';
|
import { useIncomeListButton } from '../hooks/useIncomeListButton';
|
||||||
|
|
||||||
type EditIncomeListButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
type EditIncomeListButtonProps = ButtonProps & {
|
||||||
list: IncomeList;
|
list: IncomeList;
|
||||||
ref?: Ref<HTMLButtonElement>;
|
ref?: Ref<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
@ -25,9 +29,14 @@ const EditIncomeListButton: FC<EditIncomeListButtonProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button onClick={onClickHandler} type="button" {...restProps}>
|
<Button
|
||||||
|
data-testid={DataTestId.EDIT_INCOME_LIST_BUTTON}
|
||||||
|
onClick={onClickHandler}
|
||||||
|
size="small"
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
Редактировать
|
Редактировать
|
||||||
</button>
|
</Button>
|
||||||
|
|
||||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||||
<EditIncomeListForm disabled={isPending} list={list} onSubmit={onFormSubmitHandler} />
|
<EditIncomeListForm disabled={isPending} list={list} onSubmit={onFormSubmitHandler} />
|
||||||
|
|||||||
@ -2,6 +2,10 @@ import React from 'react';
|
|||||||
import ReactDOM from 'react-dom/client';
|
import ReactDOM from 'react-dom/client';
|
||||||
|
|
||||||
import { App } from '@/app/App';
|
import { App } from '@/app/App';
|
||||||
|
import '@fontsource/roboto/300.css';
|
||||||
|
import '@fontsource/roboto/400.css';
|
||||||
|
import '@fontsource/roboto/500.css';
|
||||||
|
import '@fontsource/roboto/700.css';
|
||||||
|
|
||||||
const rootEl = document.getElementById('root');
|
const rootEl = document.getElementById('root');
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
|
import { Button, Typography } from '@mui/material';
|
||||||
import { NavLink } from 'react-router';
|
import { NavLink } from 'react-router';
|
||||||
|
|
||||||
|
import { PAGES } from '@/shared/router';
|
||||||
import { LoginForm } from '@/widgets/auth/LoginForm';
|
import { LoginForm } from '@/widgets/auth/LoginForm';
|
||||||
|
|
||||||
import classes from './LoginPage.module.css';
|
import classes from './LoginPage.module.css';
|
||||||
@ -7,12 +9,16 @@ import classes from './LoginPage.module.css';
|
|||||||
const LoginPage = () => (
|
const LoginPage = () => (
|
||||||
<div className={classes.overlay}>
|
<div className={classes.overlay}>
|
||||||
<div className={classes.contentWrapper}>
|
<div className={classes.contentWrapper}>
|
||||||
<h1>Вход в аккаунт</h1>
|
<Typography sx={{ mb: 2 }} variant="h4">
|
||||||
|
Вход в аккаунт
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<LoginForm />
|
<LoginForm />
|
||||||
|
|
||||||
<NavLink end to="/register">
|
<NavLink end to={PAGES.Register}>
|
||||||
Регистрация
|
<Button size="small" sx={{ mt: 1 }}>
|
||||||
|
Регистрация
|
||||||
|
</Button>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
|
import { Button, Typography } from '@mui/material';
|
||||||
import { NavLink } from 'react-router';
|
import { NavLink } from 'react-router';
|
||||||
|
|
||||||
|
import { PAGES } from '@/shared/router';
|
||||||
import { RegisterForm } from '@/widgets/auth/RegisterForm';
|
import { RegisterForm } from '@/widgets/auth/RegisterForm';
|
||||||
|
|
||||||
import classes from './RegisterPage.module.css';
|
import classes from './RegisterPage.module.css';
|
||||||
@ -7,12 +9,16 @@ import classes from './RegisterPage.module.css';
|
|||||||
const RegisterPage = () => (
|
const RegisterPage = () => (
|
||||||
<div className={classes.overlay}>
|
<div className={classes.overlay}>
|
||||||
<div className={classes.contentWrapper}>
|
<div className={classes.contentWrapper}>
|
||||||
<h1>Регистрация аккаунта</h1>
|
<Typography sx={{ mb: 2 }} variant="h4">
|
||||||
|
Регистрация аккаунта
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<RegisterForm />
|
<RegisterForm />
|
||||||
|
|
||||||
<NavLink end to="/login">
|
<NavLink end to={PAGES.Login}>
|
||||||
Вход
|
<Button size="small" sx={{ mt: 1 }}>
|
||||||
|
Вход
|
||||||
|
</Button>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
|
|
||||||
|
import { Typography } from '@mui/material';
|
||||||
|
|
||||||
import { useBankCards } from '@/entity/cards';
|
import { useBankCards } from '@/entity/cards';
|
||||||
import { AddBankCardButton } from '@/features/bank-cards/AddBankCardButton';
|
import { AddBankCardButton } from '@/features/bank-cards/AddBankCardButton';
|
||||||
import { Spinner } from '@/shared/ui/Spinner';
|
import { Spinner } from '@/shared/ui/Spinner';
|
||||||
@ -23,16 +25,14 @@ const BankCardsPage: FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout>
|
<AppLayout>
|
||||||
<div>
|
<Typography variant="h4">
|
||||||
<h1>Мои карты</h1>
|
Мои карты
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<div>
|
<AddBankCardButton sx={{ mb: 2, mt: 2 }} />
|
||||||
<AddBankCardButton />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{renderContent()}
|
{renderContent()}
|
||||||
|
|
||||||
</div>
|
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
|
|
||||||
|
import { Typography } from '@mui/material';
|
||||||
|
|
||||||
import { useCash } from '@/entity/cash';
|
import { useCash } from '@/entity/cash';
|
||||||
import { AddCashButton } from '@/features/cash/AddCashButton';
|
import { AddCashButton } from '@/features/cash/AddCashButton';
|
||||||
import { Spinner } from '@/shared/ui/Spinner';
|
import { Spinner } from '@/shared/ui/Spinner';
|
||||||
@ -23,16 +25,14 @@ const CashPage: FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout>
|
<AppLayout>
|
||||||
<div>
|
<Typography variant="h4">
|
||||||
<h1>Мои наличные</h1>
|
Мои наличные
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<div>
|
<AddCashButton sx={{ mb: 2, mt: 2 }} />
|
||||||
<AddCashButton />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{renderContent()}
|
{renderContent()}
|
||||||
|
|
||||||
</div>
|
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { Typography } from '@mui/material';
|
||||||
import { useParams } from 'react-router';
|
import { useParams } from 'react-router';
|
||||||
|
|
||||||
import type { ExpensePageParams } from '@/shared/router';
|
import type { ExpensePageParams } from '@/shared/router';
|
||||||
@ -30,14 +31,14 @@ const ExpensePage = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout>
|
<AppLayout>
|
||||||
<div>
|
<Typography variant="h4">
|
||||||
<h1>Списки расходов</h1>
|
Списки расходов
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<AddExpenseItemButton listId={id} />
|
<AddExpenseItemButton listId={id} sx={{ mb: 2, mt: 2 }} />
|
||||||
|
|
||||||
{renderContent()}
|
{renderContent()}
|
||||||
|
|
||||||
</div>
|
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { Typography } from '@mui/material';
|
||||||
|
|
||||||
import { useExpensesList } from '@/entity/expenses/list';
|
import { useExpensesList } from '@/entity/expenses/list';
|
||||||
import { AddExpensesListButton } from '@/features/expenses/list/AddExpensesListButton';
|
import { AddExpensesListButton } from '@/features/expenses/list/AddExpensesListButton';
|
||||||
import { Spinner } from '@/shared/ui/Spinner';
|
import { Spinner } from '@/shared/ui/Spinner';
|
||||||
@ -21,16 +23,13 @@ const ExpensesPage = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout>
|
<AppLayout>
|
||||||
<div>
|
<Typography variant="h4">
|
||||||
<h1>Списки расходов</h1>
|
Списки расходов
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<div>
|
<AddExpensesListButton sx={{ mb: 2, mt: 2 }} />
|
||||||
<AddExpensesListButton />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{renderContent()}
|
{renderContent()}
|
||||||
|
|
||||||
</div>
|
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
|
import { Typography } from '@mui/material';
|
||||||
|
|
||||||
import { AppLayout } from '@/widgets/AppLayout';
|
import { AppLayout } from '@/widgets/AppLayout';
|
||||||
|
|
||||||
const HomePage = () => (
|
const HomePage = () => (
|
||||||
<AppLayout>
|
<AppLayout>
|
||||||
<div>
|
<Typography variant="h4">
|
||||||
<h1>Home Page</h1>
|
Домашняя страница
|
||||||
</div>
|
</Typography>
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { Typography } from '@mui/material';
|
||||||
import { useParams } from 'react-router';
|
import { useParams } from 'react-router';
|
||||||
|
|
||||||
import type { IncomePageParams } from '@/shared/router';
|
import type { IncomePageParams } from '@/shared/router';
|
||||||
@ -30,14 +31,14 @@ const IncomePage = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout>
|
<AppLayout>
|
||||||
<div>
|
<Typography variant="h4">
|
||||||
<h1>Списки расходов</h1>
|
Списки расходов
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<AddIncomeItemButton listId={id} />
|
<AddIncomeItemButton listId={id} sx={{ mb: 2, mt: 2 }} />
|
||||||
|
|
||||||
{renderContent()}
|
{renderContent()}
|
||||||
|
|
||||||
</div>
|
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { Typography } from '@mui/material';
|
||||||
|
|
||||||
import { useIncomesList } from '@/entity/incomes/list';
|
import { useIncomesList } from '@/entity/incomes/list';
|
||||||
import { AddIncomeListButton } from '@/features/incomes/list/AddIncomeListButton';
|
import { AddIncomeListButton } from '@/features/incomes/list/AddIncomeListButton';
|
||||||
import { Spinner } from '@/shared/ui/Spinner';
|
import { Spinner } from '@/shared/ui/Spinner';
|
||||||
@ -21,16 +23,14 @@ const IncomesPage = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout>
|
<AppLayout>
|
||||||
<div>
|
<Typography variant="h4">
|
||||||
<h1>Списки дохода</h1>
|
Списки дохода
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<div>
|
<AddIncomeListButton sx={{ mb: 2, mt: 2 }} />
|
||||||
<AddIncomeListButton />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{renderContent()}
|
{renderContent()}
|
||||||
|
|
||||||
</div>
|
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
export { default as Input } from './ui/Input.ui';
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
.wrapper {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
import type { FC, HTMLProps } from 'react';
|
|
||||||
|
|
||||||
import classes from './Input.styles.module.css';
|
|
||||||
|
|
||||||
type InputProps = HTMLProps<HTMLInputElement> & {
|
|
||||||
label: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const Input: FC<InputProps> = (props) => {
|
|
||||||
const { id, label, ...rest } = props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<label className={classes.wrapper} htmlFor={id}>
|
|
||||||
{label}
|
|
||||||
|
|
||||||
<input
|
|
||||||
id={id}
|
|
||||||
{...rest}
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Input;
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
.wrapper {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
background-color: white;
|
|
||||||
z-index: 2;
|
|
||||||
border-radius: 10px;
|
|
||||||
position: relative;
|
|
||||||
padding: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.closeIcon {
|
|
||||||
position: absolute;
|
|
||||||
top: 10px;
|
|
||||||
right: 10px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
13
frontend/src/shared/ui/Modal/ui/Modal.style.ts
Normal file
13
frontend/src/shared/ui/Modal/ui/Modal.style.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
const modalStyle = {
|
||||||
|
bgcolor: 'background.paper',
|
||||||
|
border: '2px solid #000',
|
||||||
|
boxShadow: 24,
|
||||||
|
left: '50%',
|
||||||
|
p: 4,
|
||||||
|
position: 'absolute',
|
||||||
|
top: '50%',
|
||||||
|
transform: 'translate(-50%, -50%)',
|
||||||
|
width: 400,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default modalStyle;
|
||||||
@ -1,28 +1,33 @@
|
|||||||
|
import type { ModalProps as MuiModalProps } from '@mui/material';
|
||||||
import type { FC, ReactNode } from 'react';
|
import type { FC, ReactNode } from 'react';
|
||||||
|
|
||||||
import classes from './Modal.module.css';
|
import { Box, Modal as MuiModal } from '@mui/material';
|
||||||
|
import Fade from '@mui/material/Fade';
|
||||||
|
|
||||||
type ModalProps = {
|
import modalStyle from './Modal.style';
|
||||||
|
|
||||||
|
type ModalProps = MuiModalProps & {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
onClose: () => void;
|
|
||||||
open: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const Modal: FC<ModalProps> = (props) => {
|
const Modal: FC<ModalProps> = (props) => {
|
||||||
const { children, onClose, open } = props;
|
const {
|
||||||
|
children, onClose, open, ...restProps
|
||||||
if (!open) {
|
} = props;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.wrapper} onClick={onClose} role="dialog">
|
<MuiModal
|
||||||
<div className={classes.content} onClick={(e) => { e.stopPropagation(); }}>
|
closeAfterTransition
|
||||||
<span className={classes.closeIcon} onClick={onClose}>×</span>
|
onClose={onClose}
|
||||||
|
open={open}
|
||||||
{children}
|
{...restProps}
|
||||||
</div>
|
>
|
||||||
</div>
|
<Fade in={open}>
|
||||||
|
<Box sx={modalStyle}>
|
||||||
|
{children}
|
||||||
|
</Box>
|
||||||
|
</Fade>
|
||||||
|
</MuiModal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
export { default as Select } from './ui/Select.ui';
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
.wrapper {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
import type { FC, HTMLProps, RefObject } from 'react';
|
|
||||||
|
|
||||||
import classes from './Select.module.css';
|
|
||||||
|
|
||||||
type Option = {
|
|
||||||
label: string;
|
|
||||||
value: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type SelectProps = HTMLProps<HTMLSelectElement> & {
|
|
||||||
label: string;
|
|
||||||
options: Option[];
|
|
||||||
ref?: RefObject<HTMLSelectElement>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const Select: FC<SelectProps> = (props) => {
|
|
||||||
const {
|
|
||||||
id,
|
|
||||||
label,
|
|
||||||
options,
|
|
||||||
ref,
|
|
||||||
...refProps
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<label className={classes.wrapper} htmlFor={id}>
|
|
||||||
{label}
|
|
||||||
|
|
||||||
<select
|
|
||||||
id={id}
|
|
||||||
ref={ref}
|
|
||||||
{...refProps}
|
|
||||||
>
|
|
||||||
{options.map((option) => (
|
|
||||||
<option key={option.value} value={option.value}>
|
|
||||||
{option.label}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Select;
|
|
||||||
13
frontend/src/shared/utils/helpers/getUTCDate.ts
Normal file
13
frontend/src/shared/utils/helpers/getUTCDate.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { parse } from 'date-fns';
|
||||||
|
|
||||||
|
export function getUTCDate(date: string) {
|
||||||
|
const parsedDate = parse(date, 'dd.MM.yyyy', new Date());
|
||||||
|
|
||||||
|
return new Date(
|
||||||
|
Date.UTC(
|
||||||
|
parsedDate.getFullYear(),
|
||||||
|
parsedDate.getMonth(),
|
||||||
|
parsedDate.getDate(),
|
||||||
|
),
|
||||||
|
).toISOString();
|
||||||
|
}
|
||||||
@ -4,3 +4,5 @@ export const wait = async (time: number) => new Promise((res) => {
|
|||||||
|
|
||||||
export { formatRub } from './formatters/currency';
|
export { formatRub } from './formatters/currency';
|
||||||
export { formatDate } from './formatters/date';
|
export { formatDate } from './formatters/date';
|
||||||
|
|
||||||
|
export { getUTCDate } from './helpers/getUTCDate';
|
||||||
|
|||||||
@ -4,4 +4,5 @@
|
|||||||
|
|
||||||
.content {
|
.content {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,42 +1,70 @@
|
|||||||
import { NavLink } from 'react-router';
|
import type { ReactElement } from 'react';
|
||||||
|
|
||||||
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
|
import CreditCardIcon from '@mui/icons-material/CreditCard';
|
||||||
|
import CurrencyRubleIcon from '@mui/icons-material/CurrencyRuble';
|
||||||
|
import HomeIcon from '@mui/icons-material/Home';
|
||||||
|
import RemoveIcon from '@mui/icons-material/Remove';
|
||||||
|
import {
|
||||||
|
List, ListItem, ListItemButton, ListItemIcon, ListItemText,
|
||||||
|
} from '@mui/material';
|
||||||
|
import { NavLink, useLocation } from 'react-router';
|
||||||
|
|
||||||
import { PAGES } from '@/shared/router';
|
import { PAGES } from '@/shared/router';
|
||||||
|
|
||||||
import classes from './SideBar.module.css';
|
import classes from './SideBar.module.css';
|
||||||
|
|
||||||
|
type ListItemLinkProps = {
|
||||||
|
icon?: ReactElement;
|
||||||
|
primary: string;
|
||||||
|
to: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ListItemLink = (props: ListItemLinkProps) => {
|
||||||
|
const { icon, primary, to } = props;
|
||||||
|
const location = useLocation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ListItemButton
|
||||||
|
component={NavLink}
|
||||||
|
selected={location.pathname === to}
|
||||||
|
to={to}
|
||||||
|
>
|
||||||
|
{icon
|
||||||
|
? (
|
||||||
|
<ListItemIcon>
|
||||||
|
{icon}
|
||||||
|
</ListItemIcon>
|
||||||
|
)
|
||||||
|
: null}
|
||||||
|
|
||||||
|
<ListItemText primary={primary} />
|
||||||
|
</ListItemButton>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
type Element = {
|
||||||
|
icon?: ReactElement;
|
||||||
|
title: string;
|
||||||
|
to: string;
|
||||||
|
};
|
||||||
|
const elements: Element[] = [
|
||||||
|
{ icon: <HomeIcon />, title: 'Главная', to: PAGES.Home },
|
||||||
|
{ icon: <AddIcon />, title: 'Доходы', to: PAGES.Incomes },
|
||||||
|
{ icon: <RemoveIcon />, title: 'Расходы', to: PAGES.Expenses },
|
||||||
|
{ icon: <CreditCardIcon />, title: 'Карты', to: PAGES.BankCards },
|
||||||
|
{ icon: <CurrencyRubleIcon />, title: 'Наличные', to: PAGES.Cash },
|
||||||
|
];
|
||||||
|
|
||||||
const SideBar = () => (
|
const SideBar = () => (
|
||||||
<div className={classes.wrapper}>
|
<div className={classes.wrapper}>
|
||||||
<ul>
|
<List>
|
||||||
<li>
|
{elements.map(({ icon, title, to }) => (
|
||||||
<NavLink to={PAGES.Home}>
|
<ListItem disablePadding key={to}>
|
||||||
Главная
|
<ListItemLink icon={icon} primary={title} to={to} />
|
||||||
</NavLink>
|
</ListItem>
|
||||||
</li>
|
))}
|
||||||
|
</List>
|
||||||
<li>
|
|
||||||
<NavLink to={PAGES.Incomes}>
|
|
||||||
Доходы
|
|
||||||
</NavLink>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<NavLink to={PAGES.Expenses}>
|
|
||||||
Расходы
|
|
||||||
</NavLink>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<NavLink to={PAGES.BankCards}>
|
|
||||||
Карты
|
|
||||||
</NavLink>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<NavLink to={PAGES.Cash}>
|
|
||||||
Наличные
|
|
||||||
</NavLink>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
|
|
||||||
import { Input } from '@/shared/ui/Input';
|
import { Button, TextField } from '@mui/material';
|
||||||
|
|
||||||
import { useLoginForm } from './hooks/useLoginForm';
|
import { useLoginForm } from './hooks/useLoginForm';
|
||||||
import classes from './LoginForm.module.css';
|
import classes from './LoginForm.module.css';
|
||||||
@ -10,28 +10,36 @@ const LoginForm: FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<form className={classes.form} onSubmit={onSubmitHandler}>
|
<form className={classes.form} onSubmit={onSubmitHandler}>
|
||||||
<Input
|
<TextField
|
||||||
disabled={isPending}
|
disabled={isPending}
|
||||||
id="email"
|
inputMode="email"
|
||||||
label="Почта"
|
label="Почта"
|
||||||
name="email"
|
name="email"
|
||||||
type="text"
|
required
|
||||||
|
size="small"
|
||||||
|
variant="standard"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
disabled={isPending}
|
disabled={isPending}
|
||||||
id="password"
|
id="password"
|
||||||
label="Пароль"
|
label="Пароль"
|
||||||
name="password"
|
name="password"
|
||||||
|
required
|
||||||
|
size="small"
|
||||||
type="password"
|
type="password"
|
||||||
|
variant="standard"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button
|
<Button
|
||||||
disabled={isPending}
|
disabled={isPending}
|
||||||
|
size="small"
|
||||||
|
sx={{ mt: 2 }}
|
||||||
type="submit"
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
>
|
>
|
||||||
Войти
|
Войти
|
||||||
</button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
|
|
||||||
import { Input } from '@/shared/ui/Input';
|
import { Button, TextField } from '@mui/material';
|
||||||
|
|
||||||
import { useRegisterForm } from './hooks/useRegisterForm';
|
import { useRegisterForm } from './hooks/useRegisterForm';
|
||||||
import classes from './RegisterForm.module.css';
|
import classes from './RegisterForm.module.css';
|
||||||
@ -10,25 +10,36 @@ const RegisterForm: FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<form className={classes.form} onSubmit={onSubmitHandler}>
|
<form className={classes.form} onSubmit={onSubmitHandler}>
|
||||||
<Input
|
<TextField
|
||||||
disabled={isPending}
|
disabled={isPending}
|
||||||
id="email"
|
inputMode="email"
|
||||||
label="Почта"
|
label="Почта"
|
||||||
name="email"
|
name="email"
|
||||||
type="text"
|
required
|
||||||
|
size="small"
|
||||||
|
variant="standard"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<TextField
|
||||||
disabled={isPending}
|
disabled={isPending}
|
||||||
id="password"
|
id="password"
|
||||||
label="Пароль"
|
label="Пароль"
|
||||||
name="password"
|
name="password"
|
||||||
|
required
|
||||||
|
size="small"
|
||||||
type="password"
|
type="password"
|
||||||
|
variant="standard"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button disabled={isPending} type="submit">
|
<Button
|
||||||
|
disabled={isPending}
|
||||||
|
size="small"
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
Зарегистрироваться
|
Зарегистрироваться
|
||||||
</button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user