feat(frontend): add mui
This commit is contained in:
parent
35291a103a
commit
021038f4ad
@ -1,5 +1,8 @@
|
||||
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 { ru } from 'date-fns/locale/ru';
|
||||
|
||||
import { AuthContextProvider } from '@/shared/context/AuthContext';
|
||||
|
||||
@ -10,7 +13,9 @@ const queryClient = new QueryClient();
|
||||
const App = () => (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<AuthContextProvider>
|
||||
<Routing />
|
||||
<LocalizationProvider adapterLocale={ru} dateAdapter={AdapterDateFns}>
|
||||
<Routing />
|
||||
</LocalizationProvider>
|
||||
</AuthContextProvider>
|
||||
</QueryClientProvider>
|
||||
);
|
||||
|
||||
@ -9,10 +9,11 @@ export { useEditBankCard } from './hooks/useEditBankCard';
|
||||
|
||||
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 type { DeleteBankCardFormProps } 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';
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
export type { AddBankCardFormValues } from './ui/AddBankCardForm.ui';
|
||||
export type { AddBankCardFormProps } from './ui/AddBankCardForm.ui';
|
||||
export { default as AddBankCardForm } from './ui/AddBankCardForm.ui';
|
||||
|
||||
@ -5,7 +5,9 @@ import type {
|
||||
RefObject,
|
||||
} 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';
|
||||
|
||||
@ -49,29 +51,41 @@ const AddBankCardForm: FC<AddBankCardFormProps> = (props) => {
|
||||
return (
|
||||
<form
|
||||
className={classes.form}
|
||||
data-testid={DataTestId.ADD_BANK_CARD_FORM}
|
||||
onSubmit={onFormSubmitHandler}
|
||||
ref={ref}
|
||||
{...formProps}
|
||||
>
|
||||
<h2>Добавить карту</h2>
|
||||
<Typography variant="h6">
|
||||
Добавить карту
|
||||
</Typography>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
label="Название"
|
||||
name="name"
|
||||
required
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
defaultValue={0}
|
||||
disabled={disabled}
|
||||
inputMode="numeric"
|
||||
label="Баланс"
|
||||
name="balance"
|
||||
step="0.01"
|
||||
type="number"
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1 +1,2 @@
|
||||
export type { DeleteBankCardFormProps } from './ui/DeleteBankCardForm.ui';
|
||||
export { default as DeleteBankCardForm } from './ui/DeleteBankCardForm.ui';
|
||||
|
||||
@ -5,6 +5,10 @@ import type {
|
||||
RefObject,
|
||||
} from 'react';
|
||||
|
||||
import { Button, Typography } from '@mui/material';
|
||||
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
|
||||
import type { BankCard } from '../../../types';
|
||||
|
||||
export type DeleteBankCardFormProps = BaseFormProps & {
|
||||
@ -31,10 +35,17 @@ const DeleteBankCardForm: FC<DeleteBankCardFormProps> = (props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={onFormSubmitHandler} ref={ref} {...restProps}>
|
||||
<h2>Удалить список расходов</h2>
|
||||
<form
|
||||
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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
export type { EditBankCardFormValues } from './ui/EditBankCardForm.ui';
|
||||
export type { EditBankCardFormProps } from './ui/EditBankCardForm.ui';
|
||||
export { default as EditBankCardForm } from './ui/EditBankCardForm.ui';
|
||||
|
||||
@ -5,9 +5,11 @@ import type {
|
||||
RefObject,
|
||||
} from 'react';
|
||||
|
||||
import { Button, TextField, Typography } from '@mui/material';
|
||||
|
||||
import type { BankCard } from '@/entity/cards';
|
||||
|
||||
import { Input } from '@/shared/ui/Input';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
|
||||
import classes from './EditBankCardForm.module.css';
|
||||
|
||||
@ -53,30 +55,42 @@ const EditBankCardForm: FC<EditBankCardFormProps> = (props) => {
|
||||
return (
|
||||
<form
|
||||
className={classes.form}
|
||||
data-testid={DataTestId.EDIT_BANK_CARD_FORM}
|
||||
onSubmit={onFormSubmitHandler}
|
||||
ref={ref}
|
||||
{...restProps}
|
||||
>
|
||||
<h2>Добавить карту</h2>
|
||||
<Typography variant="h6">
|
||||
Добавить карту
|
||||
</Typography>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
defaultValue={bankCard.name}
|
||||
disabled={disabled}
|
||||
label="Название"
|
||||
name="name"
|
||||
required
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
defaultValue={bankCard.balance}
|
||||
disabled={disabled}
|
||||
inputMode="numeric"
|
||||
label="Баланс"
|
||||
name="balance"
|
||||
step="0.01"
|
||||
type="number"
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<button disabled={disabled} type="submit">Сохранить</button>
|
||||
<Button
|
||||
data-testid={DataTestId.EDIT_BANK_CARD_SUBMIT_BUTTON}
|
||||
disabled={disabled}
|
||||
fullWidth
|
||||
type="submit"
|
||||
variant="contained"
|
||||
>
|
||||
Сохранить
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
@ -10,9 +10,10 @@ export { useEditCash } from './hooks/useEditCash';
|
||||
export type { CashItem, CashList } from './types';
|
||||
|
||||
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 { 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';
|
||||
|
||||
@ -5,7 +5,9 @@ import type {
|
||||
RefObject,
|
||||
} 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';
|
||||
|
||||
@ -49,29 +51,40 @@ const AddCashForm: FC<AddCashFormProps> = (props) => {
|
||||
return (
|
||||
<form
|
||||
className={classes.form}
|
||||
data-testid={DataTestId.ADD_CASH_FORM}
|
||||
onSubmit={onFormSubmitHandler}
|
||||
ref={ref}
|
||||
{...formProps}
|
||||
>
|
||||
<h2>Добавить наличные</h2>
|
||||
<Typography variant="h6">
|
||||
Добавить наличные
|
||||
</Typography>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
label="Название"
|
||||
name="name"
|
||||
required
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
defaultValue={0}
|
||||
disabled={disabled}
|
||||
inputMode="numeric"
|
||||
label="Баланс"
|
||||
name="balance"
|
||||
step="0.01"
|
||||
type="number"
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<button disabled={disabled} type="submit">Добавить</button>
|
||||
<Button
|
||||
data-testid={DataTestId.ADD_CASH_SUBMIT_BUTTON}
|
||||
disabled={disabled}
|
||||
type="submit"
|
||||
variant="contained"
|
||||
>
|
||||
Добавить
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1 +1,2 @@
|
||||
export type { DeleteCashFormProps } from './ui/DeleteCashForm.ui';
|
||||
export { default as DeleteCashForm } from './ui/DeleteCashForm.ui';
|
||||
|
||||
@ -5,6 +5,10 @@ import type {
|
||||
RefObject,
|
||||
} from 'react';
|
||||
|
||||
import { Button, Typography } from '@mui/material';
|
||||
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
|
||||
import type { CashItem } from '../../../types';
|
||||
|
||||
export type DeleteCashFormProps = BaseFormProps & {
|
||||
@ -31,10 +35,17 @@ const DeleteCashForm: FC<DeleteCashFormProps> = (props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={onFormSubmitHandler} ref={ref} {...restProps}>
|
||||
<h2>Удалить наличные</h2>
|
||||
<form
|
||||
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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -5,9 +5,11 @@ import type {
|
||||
RefObject,
|
||||
} from 'react';
|
||||
|
||||
import { Button, TextField, Typography } from '@mui/material';
|
||||
|
||||
import type { CashItem } from '@/entity/cash';
|
||||
|
||||
import { Input } from '@/shared/ui/Input';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
|
||||
import classes from './EditCashForm.module.css';
|
||||
|
||||
@ -53,30 +55,41 @@ const EditCashForm: FC<EditCashFormProps> = (props) => {
|
||||
return (
|
||||
<form
|
||||
className={classes.form}
|
||||
data-testid={DataTestId.EDIT_CASH_FORM}
|
||||
onSubmit={onFormSubmitHandler}
|
||||
ref={ref}
|
||||
{...restProps}
|
||||
>
|
||||
<h2>Редактировать наличные</h2>
|
||||
<Typography variant="h6">
|
||||
Редактировать наличные
|
||||
</Typography>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
defaultValue={cash.name}
|
||||
disabled={disabled}
|
||||
label="Название"
|
||||
name="name"
|
||||
required
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
defaultValue={cash.balance}
|
||||
disabled={disabled}
|
||||
inputMode="numeric"
|
||||
label="Баланс"
|
||||
name="balance"
|
||||
step="0.01"
|
||||
type="number"
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<button disabled={disabled} type="submit">Сохранить</button>
|
||||
<Button
|
||||
data-testid={DataTestId.EDIT_CASH_SUBMIT_BUTTON}
|
||||
disabled={disabled}
|
||||
type="submit"
|
||||
variant="contained"
|
||||
>
|
||||
Сохранить
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
@ -7,11 +7,12 @@ export { useDeleteExpenseItem } from './hooks/useDeleteExpenseItem';
|
||||
export { useEditExpenseItem } from './hooks/useEditExpenseItem';
|
||||
|
||||
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 type { DeleteExpenseItemFormProps } 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';
|
||||
|
||||
@ -1,11 +1,21 @@
|
||||
import type { SelectChangeEvent } from '@mui/material';
|
||||
import type {
|
||||
ChangeEventHandler,
|
||||
FC,
|
||||
FormEventHandler,
|
||||
FormHTMLAttributes,
|
||||
RefObject,
|
||||
} from 'react';
|
||||
|
||||
import {
|
||||
Button,
|
||||
FormControl,
|
||||
InputLabel,
|
||||
MenuItem,
|
||||
Select,
|
||||
TextField,
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers';
|
||||
import {
|
||||
useMemo,
|
||||
useState,
|
||||
@ -15,9 +25,8 @@ import type { ExpenseListItem } from '@/entity/expenses/item';
|
||||
|
||||
import { useBankCards } from '@/entity/cards';
|
||||
import { useCash } from '@/entity/cash';
|
||||
import { Input } from '@/shared/ui/Input';
|
||||
import { Select } from '@/shared/ui/Select';
|
||||
import { formatRub } from '@/shared/utils';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
import { formatRub, getUTCDate } from '@/shared/utils';
|
||||
|
||||
import classes from './AddExpenseItemForm.module.css';
|
||||
|
||||
@ -89,7 +98,7 @@ const AddExpenseItemForm: FC<AddExpenseItemFormProps> = (props) => {
|
||||
amount: Number(amount),
|
||||
count: Number(count),
|
||||
currency: 'RUB',
|
||||
date: new Date(date).toISOString(),
|
||||
date: getUTCDate(date),
|
||||
description,
|
||||
// @ts-ignore todo
|
||||
payment: getPayment(),
|
||||
@ -100,31 +109,33 @@ const AddExpenseItemForm: FC<AddExpenseItemFormProps> = (props) => {
|
||||
const { data: bankCards } = useBankCards();
|
||||
const { data: cash } = useCash();
|
||||
|
||||
const bankCardOptions = bankCards?.map((card) => ({
|
||||
label: `${card.name} (${formatRub(card.balance)})`,
|
||||
value: card.id,
|
||||
}));
|
||||
const bankCardOptions = bankCards?.map((card) => (
|
||||
<MenuItem key={card.id} value={card.id}>
|
||||
{`${card.name} (${formatRub(card.balance)})`}
|
||||
</MenuItem>
|
||||
));
|
||||
|
||||
const cashOptions = cash?.map((cashItem) => ({
|
||||
label: `${cashItem.name} (${formatRub(cashItem.balance)})`,
|
||||
value: cashItem.id,
|
||||
}));
|
||||
const cashOptions = cash?.map((cashItem) => (
|
||||
<MenuItem key={cashItem.id} value={cashItem.id}>
|
||||
{`${cashItem.name} (${formatRub(cashItem.balance)})`}
|
||||
</MenuItem>
|
||||
));
|
||||
|
||||
const paymentOptions = useMemo(() => {
|
||||
const options = [{ label: 'Без оплаты', value: 'none' }];
|
||||
const options = [<MenuItem key="none" value="none">Без оплаты</MenuItem>];
|
||||
|
||||
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) {
|
||||
options.push({ label: 'Наличные', value: 'CASH' });
|
||||
options.push(<MenuItem key="CASH" value="CASH">Наличные</MenuItem>);
|
||||
}
|
||||
|
||||
return options;
|
||||
}, [bankCardOptions, cashOptions]);
|
||||
|
||||
const onChangePaymentHandler: ChangeEventHandler<HTMLSelectElement> = (event) => {
|
||||
const onChangePaymentHandler = (event: SelectChangeEvent<'BANK_CARD' | 'CASH' | 'none'>) => {
|
||||
const { value } = event.target;
|
||||
if (value === 'none') {
|
||||
setPaymentType(null);
|
||||
@ -135,80 +146,126 @@ const AddExpenseItemForm: FC<AddExpenseItemFormProps> = (props) => {
|
||||
};
|
||||
|
||||
const renderCardSelect = () => (
|
||||
<Select
|
||||
label="Карта"
|
||||
name="bank-card"
|
||||
options={bankCardOptions ?? []}
|
||||
/>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel id="bank-card-label">Карта</InputLabel>
|
||||
|
||||
<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 = () => (
|
||||
<Select
|
||||
label="Наличные"
|
||||
name="cash"
|
||||
options={cashOptions ?? []}
|
||||
/>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel id="cash-label">Наличные</InputLabel>
|
||||
|
||||
<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 (
|
||||
<form
|
||||
className={classes.form}
|
||||
data-testid={DataTestId.ADD_EXPENSE_ITEM_FORM}
|
||||
onSubmit={onFormSubmitHandler}
|
||||
ref={ref}
|
||||
{...formProps}
|
||||
>
|
||||
<h2>Добавить список расходов</h2>
|
||||
<Typography variant="h6">
|
||||
Добавить список расходов
|
||||
</Typography>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
label="Название"
|
||||
name="title"
|
||||
required
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
label="Описание"
|
||||
name="description"
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<Input
|
||||
defaultValue={new Date().toISOString().split('T')[0]}
|
||||
<DatePicker
|
||||
defaultValue={new Date()}
|
||||
disabled={disabled}
|
||||
label="Дата"
|
||||
name="date"
|
||||
required
|
||||
type="date"
|
||||
slotProps={{ textField: { required: true, size: 'small' } }}
|
||||
/>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
inputMode="numeric"
|
||||
label="Сумма"
|
||||
name="amount"
|
||||
required
|
||||
step="0.01"
|
||||
size="small"
|
||||
type="number"
|
||||
/>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
defaultValue={1}
|
||||
disabled={disabled}
|
||||
inputMode="numeric"
|
||||
label="Количество"
|
||||
name="count"
|
||||
size="small"
|
||||
type="number"
|
||||
/>
|
||||
|
||||
<Select
|
||||
label="Способ оплаты"
|
||||
name="paymentMethod"
|
||||
onChange={onChangePaymentHandler}
|
||||
options={paymentOptions}
|
||||
/>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel id="payment-type-label">Способ оплаты</InputLabel>
|
||||
|
||||
<Select
|
||||
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 === '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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -5,6 +5,10 @@ import type {
|
||||
RefObject,
|
||||
} from 'react';
|
||||
|
||||
import { Button, Typography } from '@mui/material';
|
||||
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
|
||||
import type { ExpenseListItem } from '../../types';
|
||||
|
||||
export type DeleteExpenseItemFormProps = BaseFormProps & {
|
||||
@ -30,10 +34,27 @@ const DeleteExpenseItemForm: FC<DeleteExpenseItemFormProps> = (props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={onFormSubmitHandler} ref={ref} {...restProps}>
|
||||
<h2>Удалить элемент ?</h2>
|
||||
<form
|
||||
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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -5,7 +5,11 @@ import type {
|
||||
RefObject,
|
||||
} 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';
|
||||
|
||||
@ -53,7 +57,7 @@ const EditExpenseItemForm: FC<EditExpenseItemFormProps> = (props) => {
|
||||
amount: Number(amount),
|
||||
count: Number(count),
|
||||
currency: 'RUB',
|
||||
date: new Date(date).toISOString(),
|
||||
date: getUTCDate(date),
|
||||
description,
|
||||
title,
|
||||
});
|
||||
@ -63,52 +67,67 @@ const EditExpenseItemForm: FC<EditExpenseItemFormProps> = (props) => {
|
||||
return (
|
||||
<form
|
||||
className={classes.form}
|
||||
data-testid={DataTestId.EDIT_EXPENSE_ITEM_FORM}
|
||||
onSubmit={onFormSubmitHandler}
|
||||
ref={ref}
|
||||
{...formProps}
|
||||
>
|
||||
<h2>Добавить список расходов</h2>
|
||||
<Typography variant="h6">
|
||||
Добавить список расходов
|
||||
</Typography>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
defaultValue={item.title}
|
||||
disabled={disabled}
|
||||
label="Название"
|
||||
name="title"
|
||||
required
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
defaultValue={item.description ?? ''}
|
||||
disabled={disabled}
|
||||
label="Описание"
|
||||
name="description"
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<Input
|
||||
defaultValue={new Date(item.date).toISOString().split('T')[0]}
|
||||
<DatePicker
|
||||
defaultValue={new Date(item.date)}
|
||||
disabled={disabled}
|
||||
label="Дата"
|
||||
name="date"
|
||||
type="date"
|
||||
slotProps={{ textField: { required: true, size: 'small' } }}
|
||||
/>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
defaultValue={item.amount}
|
||||
disabled={disabled}
|
||||
inputMode="numeric"
|
||||
label="Сумма"
|
||||
name="amount"
|
||||
step="0.01"
|
||||
type="number"
|
||||
required
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
defaultValue={item.count ?? 1}
|
||||
disabled={disabled}
|
||||
label="Количество"
|
||||
name="count"
|
||||
size="small"
|
||||
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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -10,10 +10,11 @@ export { useExpensesList } from './hooks/useExpensesList';
|
||||
|
||||
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 type { DeleteExpenseListFormProps } 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';
|
||||
|
||||
@ -5,7 +5,9 @@ import type {
|
||||
RefObject,
|
||||
} 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';
|
||||
|
||||
@ -46,15 +48,32 @@ const AddExpensesListForm: FC<AddExpenseListFormProps> = (props) => {
|
||||
return (
|
||||
<form
|
||||
className={classes.form}
|
||||
data-testid={DataTestId.ADD_EXPENSES_LIST_FORM}
|
||||
onSubmit={onFormSubmitHandler}
|
||||
ref={ref}
|
||||
{...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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -5,8 +5,12 @@ import type {
|
||||
RefObject,
|
||||
} from 'react';
|
||||
|
||||
import { Button, Typography } from '@mui/material';
|
||||
|
||||
import type { ExpenseList } from '@/entity/expenses/list';
|
||||
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
|
||||
export type DeleteExpenseListFormProps = BaseFormProps & {
|
||||
disabled?: boolean;
|
||||
list: ExpenseList;
|
||||
@ -31,10 +35,17 @@ const DeleteExpensesListForm: FC<DeleteExpenseListFormProps> = (props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={onFormSubmitHandler} ref={ref} {...restProps}>
|
||||
<h2>Удалить список расходов</h2>
|
||||
<form
|
||||
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
|
||||
? (
|
||||
<p>
|
||||
<Typography sx={{ mt: 1 }} variant="body2">
|
||||
В нем содержится
|
||||
{' '}
|
||||
|
||||
@ -59,12 +70,23 @@ const DeleteExpensesListForm: FC<DeleteExpenseListFormProps> = (props) => {
|
||||
|
||||
{' '}
|
||||
расходов
|
||||
</p>
|
||||
</Typography>
|
||||
)
|
||||
: 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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -5,9 +5,11 @@ import type {
|
||||
RefObject,
|
||||
} from 'react';
|
||||
|
||||
import { Button, TextField, Typography } from '@mui/material';
|
||||
|
||||
import type { ExpenseList } from '@/entity/expenses/list';
|
||||
|
||||
import { Input } from '@/shared/ui/Input';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
|
||||
import classes from './EditExpenseListForm.module.css';
|
||||
|
||||
@ -48,20 +50,32 @@ const EditExpensesListForm: FC<EditExpensesListFormProps> = (props) => {
|
||||
return (
|
||||
<form
|
||||
className={classes.form}
|
||||
data-testid={DataTestId.EDIT_EXPENSES_LIST_FORM}
|
||||
onSubmit={onFormSubmitHandler}
|
||||
ref={ref}
|
||||
{...restProps}
|
||||
>
|
||||
<h2>Редактировать список расходов</h2>
|
||||
<Typography variant="h6">
|
||||
Редактировать список расходов
|
||||
</Typography>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
defaultValue={list.title}
|
||||
disabled={disabled}
|
||||
label="Название"
|
||||
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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -9,9 +9,11 @@ export { useEditIncomeItem } from './hooks/useEditIncomeItem';
|
||||
export type { IncomeListItem } from './types';
|
||||
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 type { DeleteIncomeItemFormProps } 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';
|
||||
|
||||
@ -5,7 +5,11 @@ import type {
|
||||
RefObject,
|
||||
} 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';
|
||||
|
||||
@ -47,7 +51,7 @@ const AddIncomeItemForm: FC<AddIncomeItemFormProps> = (props) => {
|
||||
onSubmit?.({
|
||||
amount: Number(amount),
|
||||
currency: 'RUB',
|
||||
date: new Date(date).toISOString(),
|
||||
date: getUTCDate(date),
|
||||
description,
|
||||
title,
|
||||
});
|
||||
@ -57,43 +61,57 @@ const AddIncomeItemForm: FC<AddIncomeItemFormProps> = (props) => {
|
||||
return (
|
||||
<form
|
||||
className={classes.form}
|
||||
data-testid={DataTestId.ADD_INCOME_ITEM_FORM}
|
||||
onSubmit={onFormSubmitHandler}
|
||||
ref={ref}
|
||||
{...formProps}
|
||||
>
|
||||
<h2>Добавить список доходов</h2>
|
||||
<Typography variant="h6">
|
||||
Добавить список доходов
|
||||
</Typography>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
label="Название"
|
||||
name="title"
|
||||
required
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
label="Описание"
|
||||
name="description"
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<Input
|
||||
<DatePicker
|
||||
disabled={disabled}
|
||||
disableFuture
|
||||
format="dd.MM.yyyy"
|
||||
label="Дата"
|
||||
name="date"
|
||||
required
|
||||
type="date"
|
||||
slotProps={{ textField: { required: true, size: 'small' } }}
|
||||
/>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
inputMode="numeric"
|
||||
label="Сумма"
|
||||
name="amount"
|
||||
required
|
||||
step="0.01"
|
||||
size="small"
|
||||
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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -5,6 +5,10 @@ import type {
|
||||
RefObject,
|
||||
} from 'react';
|
||||
|
||||
import { Button, Typography } from '@mui/material';
|
||||
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
|
||||
import type { IncomeListItem } from '../../types';
|
||||
|
||||
export type DeleteIncomeItemFormProps = BaseFormProps & {
|
||||
@ -30,10 +34,25 @@ const DeleteIncomeItemForm: FC<DeleteIncomeItemFormProps> = (props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={onFormSubmitHandler} ref={ref} {...restProps}>
|
||||
<h2>Удалить элемент ?</h2>
|
||||
<form
|
||||
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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -5,7 +5,11 @@ import type {
|
||||
RefObject,
|
||||
} 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';
|
||||
|
||||
@ -50,7 +54,7 @@ const EditIncomeItemForm: FC<EditIncomeItemFormProps> = (props) => {
|
||||
await onSubmit?.({
|
||||
amount: Number(amount),
|
||||
currency: 'RUB',
|
||||
date: new Date(date).toISOString(),
|
||||
date: getUTCDate(date),
|
||||
description,
|
||||
title,
|
||||
});
|
||||
@ -60,44 +64,58 @@ const EditIncomeItemForm: FC<EditIncomeItemFormProps> = (props) => {
|
||||
return (
|
||||
<form
|
||||
className={classes.form}
|
||||
data-testid={DataTestId.EDIT_INCOME_ITEM_FORM}
|
||||
onSubmit={onFormSubmitHandler}
|
||||
ref={ref}
|
||||
{...formProps}
|
||||
>
|
||||
<h2>Изменить доход</h2>
|
||||
<Typography variant="h6">
|
||||
Изменить доход
|
||||
</Typography>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
defaultValue={item.title}
|
||||
disabled={disabled}
|
||||
label="Название"
|
||||
name="title"
|
||||
required
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
defaultValue={item.description ?? ''}
|
||||
disabled={disabled}
|
||||
label="Описание"
|
||||
name="description"
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<Input
|
||||
defaultValue={new Date(item.date).toISOString().split('T')[0]}
|
||||
<DatePicker
|
||||
defaultValue={new Date(item.date)}
|
||||
disabled={disabled}
|
||||
label="Дата"
|
||||
name="date"
|
||||
type="date"
|
||||
slotProps={{ textField: { required: true, size: 'small' } }}
|
||||
/>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
defaultValue={item.amount}
|
||||
disabled={disabled}
|
||||
inputMode="numeric"
|
||||
label="Сумма"
|
||||
name="amount"
|
||||
step="0.01"
|
||||
size="small"
|
||||
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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -9,7 +9,7 @@ export const useAddIncomesList = () => {
|
||||
|
||||
return useMutation({
|
||||
mutationFn: addIncomeList,
|
||||
mutationKey: [QueryKeys.ExpenseList],
|
||||
mutationKey: [QueryKeys.IncomesList],
|
||||
onSuccess: async () => {
|
||||
await queryClient.invalidateQueries({ queryKey: [QueryKeys.IncomesList] });
|
||||
},
|
||||
|
||||
@ -10,10 +10,11 @@ export { useIncomesList } from './hooks/useIncomesList';
|
||||
|
||||
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 type { DeleteIncomeListFormProps } 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';
|
||||
|
||||
@ -5,7 +5,9 @@ import type {
|
||||
RefObject,
|
||||
} 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';
|
||||
|
||||
@ -46,15 +48,31 @@ const AddIncomeListForm: FC<AddIncomeListFormProps> = (props) => {
|
||||
return (
|
||||
<form
|
||||
className={classes.form}
|
||||
data-testid={DataTestId.ADD_INCOME_LIST_FORM}
|
||||
onSubmit={onFormSubmitHandler}
|
||||
ref={ref}
|
||||
{...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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -5,6 +5,10 @@ import type {
|
||||
RefObject,
|
||||
} from 'react';
|
||||
|
||||
import { Button, Typography } from '@mui/material';
|
||||
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
|
||||
import type { IncomeList } from '../../../types';
|
||||
|
||||
export type DeleteIncomeListFormProps = BaseFormProps & {
|
||||
@ -31,10 +35,17 @@ const DeleteIncomeListForm: FC<DeleteIncomeListFormProps> = (props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={onFormSubmitHandler} ref={ref} {...restProps}>
|
||||
<h2>Удалить список доходов</h2>
|
||||
<form
|
||||
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
|
||||
? (
|
||||
<p>
|
||||
<Typography sx={{ mt: 1 }} variant="body1">
|
||||
В нем содержится
|
||||
{' '}
|
||||
|
||||
@ -59,12 +70,22 @@ const DeleteIncomeListForm: FC<DeleteIncomeListFormProps> = (props) => {
|
||||
|
||||
{' '}
|
||||
доходов
|
||||
</p>
|
||||
</Typography>
|
||||
)
|
||||
: 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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -5,13 +5,15 @@ import type {
|
||||
RefObject,
|
||||
} 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 classes from './EditIncomeListForm.module.css';
|
||||
|
||||
export type EditExpensesListFormProps = BaseFormProps & {
|
||||
export type EditIncomeListFormProps = BaseFormProps & {
|
||||
disabled?: boolean;
|
||||
list: IncomeList;
|
||||
onSubmit: (data: EditIncomeListFormValues) => Promise<void> | void;
|
||||
@ -24,7 +26,7 @@ export type EditIncomeListFormValues = {
|
||||
|
||||
type BaseFormProps = Omit<FormHTMLAttributes<HTMLFormElement>, 'onSubmit'>;
|
||||
|
||||
const EditExpensesListForm: FC<EditExpensesListFormProps> = (props) => {
|
||||
const EditIncomeListForm: FC<EditIncomeListFormProps> = (props) => {
|
||||
const {
|
||||
disabled,
|
||||
list,
|
||||
@ -48,22 +50,34 @@ const EditExpensesListForm: FC<EditExpensesListFormProps> = (props) => {
|
||||
return (
|
||||
<form
|
||||
className={classes.form}
|
||||
data-testid={DataTestId.EDIT_INCOME_LIST_FORM}
|
||||
onSubmit={onFormSubmitHandler}
|
||||
ref={ref}
|
||||
{...restProps}
|
||||
>
|
||||
<h2>Редактировать список доходов</h2>
|
||||
<Typography variant="h6">
|
||||
Редактировать список доходов
|
||||
</Typography>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
defaultValue={list.title}
|
||||
disabled={disabled}
|
||||
label="Название"
|
||||
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>
|
||||
);
|
||||
};
|
||||
|
||||
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 { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useAddBankCardButton } from '../hooks/useAddBankCardButton';
|
||||
|
||||
type AddBankCardButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||
type AddBankCardButtonProps = ButtonProps & {
|
||||
ref?: Ref<HTMLButtonElement>;
|
||||
};
|
||||
|
||||
@ -22,14 +26,15 @@ const AddBankCardButton: FC<AddBankCardButtonProps> = (props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
<Button
|
||||
data-testid={DataTestId.ADD_BANK_CARD_BUTTON}
|
||||
onClick={onClickHandler}
|
||||
ref={ref}
|
||||
type="button"
|
||||
variant="contained"
|
||||
{...restProps}
|
||||
>
|
||||
Добавить
|
||||
</button>
|
||||
</Button>
|
||||
|
||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||
<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 { DeleteBankCardForm } from '@/entity/cards';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useDeleteBankCardButton } from '../hooks/useDeleteBankCardButton';
|
||||
|
||||
export type DeleteBankCardButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||
export type DeleteBankCardButtonProps = ButtonProps & {
|
||||
bankCard: BankCard;
|
||||
ref?: Ref<HTMLButtonElement>;
|
||||
};
|
||||
@ -30,9 +34,16 @@ const DeleteBankCardButton: FC<DeleteBankCardButtonProps> = (props) => {
|
||||
|
||||
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}>
|
||||
<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 { EditBankCardForm } from '@/entity/cards';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useEditBankCardButton } from '../hooks/useEditBankCardButton';
|
||||
|
||||
export type EditBankCardButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||
export type EditBankCardButtonProps = ButtonProps & {
|
||||
bankCard: BankCard;
|
||||
ref?: Ref<HTMLButtonElement>;
|
||||
};
|
||||
@ -29,9 +33,15 @@ const EditBankCardButton: FC<EditBankCardButtonProps> = (props) => {
|
||||
|
||||
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}>
|
||||
<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 { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useAddCashButton } from '../hooks/useAddCashButton';
|
||||
|
||||
type AddCashButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||
type AddCashButtonProps = ButtonProps & {
|
||||
ref?: Ref<HTMLButtonElement>;
|
||||
};
|
||||
|
||||
@ -22,14 +26,15 @@ const AddCashButton: FC<AddCashButtonProps> = (props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
<Button
|
||||
data-testid={DataTestId.ADD_CASH_BUTTON}
|
||||
onClick={onClickHandler}
|
||||
ref={ref}
|
||||
type="button"
|
||||
variant="contained"
|
||||
{...restProps}
|
||||
>
|
||||
Добавить
|
||||
</button>
|
||||
</Button>
|
||||
|
||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||
<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 { DeleteCashForm } from '@/entity/cash';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useDeleteCashButton } from '../hooks/useDeleteCashButton';
|
||||
|
||||
export type DeleteCashButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||
export type DeleteCashButtonProps = ButtonProps & {
|
||||
cash: CashItem;
|
||||
ref?: Ref<HTMLButtonElement>;
|
||||
};
|
||||
@ -30,9 +34,16 @@ const DeleteCashButton: FC<DeleteCashButtonProps> = (props) => {
|
||||
|
||||
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}>
|
||||
<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 { EditCashForm } from '@/entity/cash';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useEditCashButton } from '../hooks/useEditCashButton';
|
||||
|
||||
export type EditCashButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||
export type EditCashButtonProps = ButtonProps & {
|
||||
cash: CashItem;
|
||||
ref?: Ref<HTMLButtonElement>;
|
||||
};
|
||||
@ -29,9 +33,15 @@ const EditCashButton: FC<EditCashButtonProps> = (props) => {
|
||||
|
||||
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}>
|
||||
<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 { AddExpenseItemForm } from '@/entity/expenses/item';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useAddExpenseItemButton } from '../hooks/useAddExpenseItemButton';
|
||||
|
||||
type AddExpenseItemButtonProps = BaseButtonProps & {
|
||||
type AddExpenseItemButtonProps = ButtonProps & {
|
||||
listId: ExpenseList['id'];
|
||||
ref?: RefObject<HTMLButtonElement>;
|
||||
};
|
||||
|
||||
type BaseButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
|
||||
|
||||
const AddExpenseItemButton: FC<AddExpenseItemButtonProps> = (props) => {
|
||||
const {
|
||||
listId,
|
||||
@ -32,14 +34,15 @@ const AddExpenseItemButton: FC<AddExpenseItemButtonProps> = (props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
<Button
|
||||
data-testid={DataTestId.ADD_EXPENSE_ITEM_BUTTON}
|
||||
onClick={onClickHandler}
|
||||
ref={ref}
|
||||
type="button"
|
||||
variant="contained"
|
||||
{...buttonProps}
|
||||
>
|
||||
Добавить элемент
|
||||
</button>
|
||||
</Button>
|
||||
|
||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||
<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 { DeleteExpenseItemForm } from '@/entity/expenses/item';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useDeleteExpenseItemButton } from '../hooks/useDeleteExpenseItemButton';
|
||||
|
||||
type BaseButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
|
||||
|
||||
type DeleteExpenseItemButtonProps = BaseButtonProps & {
|
||||
type DeleteExpenseItemButtonProps = ButtonProps & {
|
||||
item: ExpenseListItem;
|
||||
ref?: RefObject<HTMLButtonElement>;
|
||||
};
|
||||
@ -30,14 +32,16 @@ const DeleteExpenseItemButton: FC<DeleteExpenseItemButtonProps> = (props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
<Button
|
||||
color="error"
|
||||
data-testid={DataTestId.DELETE_EXPENSE_ITEM_BUTTON}
|
||||
onClick={onClickHandler}
|
||||
ref={ref}
|
||||
type="button"
|
||||
size="small"
|
||||
{...restProps}
|
||||
>
|
||||
Удалить
|
||||
</button>
|
||||
</Button>
|
||||
|
||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||
<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 { EditExpenseItemForm } from '@/entity/expenses/item';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useEditExpenseItemButton } from '../hooks/useEditExpenseItemButton';
|
||||
|
||||
type BaseButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
|
||||
|
||||
type EditExpenseItemButtonProps = BaseButtonProps & {
|
||||
type EditExpenseItemButtonProps = ButtonProps & {
|
||||
item: ExpenseListItem;
|
||||
ref?: RefObject<HTMLButtonElement>;
|
||||
};
|
||||
@ -32,15 +34,16 @@ const EditExpenseItemButton: FC<EditExpenseItemButtonProps> = (props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
<Button
|
||||
data-testid={DataTestId.EDIT_EXPENSE_ITEM_BUTTON}
|
||||
disabled={isPending}
|
||||
onClick={onClickHandler}
|
||||
ref={ref}
|
||||
type="button"
|
||||
size="small"
|
||||
{...restProps}
|
||||
>
|
||||
Редактировать
|
||||
</button>
|
||||
</Button>
|
||||
|
||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||
<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 { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useAddExpensesListButton } from '../hooks/useAddExpensesListButton';
|
||||
|
||||
type AddExpensesListButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||
type AddExpensesListButtonProps = ButtonProps & {
|
||||
ref?: Ref<HTMLButtonElement>;
|
||||
};
|
||||
|
||||
@ -22,9 +26,14 @@ const AddExpensesListButton: FC<AddExpensesListButtonProps> = (props) => {
|
||||
|
||||
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}>
|
||||
<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 { DeleteExpensesListForm } from '@/entity/expenses/list';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useDeleteExpensesListButton } from '../hooks/useDeleteExpensesListButton';
|
||||
|
||||
type DeleteExpensesListButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||
type DeleteExpensesListButtonProps = ButtonProps & {
|
||||
list: ExpenseList;
|
||||
ref?: Ref<HTMLButtonElement>;
|
||||
};
|
||||
@ -25,9 +30,16 @@ const DeleteExpensesListButton = (props: DeleteExpensesListButtonProps) => {
|
||||
|
||||
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}>
|
||||
<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 { EditExpensesListForm } from '@/entity/expenses/list';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useEditExpensesListButton } from '../hooks/useEditExpensesListButton';
|
||||
|
||||
type EditExpensesListButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||
type EditExpensesListButtonProps = ButtonProps & {
|
||||
list: ExpenseList;
|
||||
ref?: Ref<HTMLButtonElement>;
|
||||
};
|
||||
@ -25,9 +30,15 @@ const EditExpensesListButton: FC<EditExpensesListButtonProps> = (props) => {
|
||||
|
||||
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}>
|
||||
<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 { AddIncomeItemForm } from '@/entity/incomes/item';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useAddIncomeItemButton } from '../hooks/useAddIncomeItemButton';
|
||||
|
||||
type AddIncomeItemButtonProps = BaseButtonProps & {
|
||||
type AddIncomeItemButtonProps = ButtonProps & {
|
||||
listId: IncomeList['id'];
|
||||
ref?: RefObject<HTMLButtonElement>;
|
||||
};
|
||||
|
||||
type BaseButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
|
||||
|
||||
const AddIncomeItemButton: FC<AddIncomeItemButtonProps> = (props) => {
|
||||
const {
|
||||
listId,
|
||||
@ -32,14 +34,15 @@ const AddIncomeItemButton: FC<AddIncomeItemButtonProps> = (props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
<Button
|
||||
data-testid={DataTestId.ADD_INCOME_ITEM_BUTTON}
|
||||
onClick={onClickHandler}
|
||||
ref={ref}
|
||||
type="button"
|
||||
variant="contained"
|
||||
{...buttonProps}
|
||||
>
|
||||
Добавить элемент
|
||||
</button>
|
||||
Добавить
|
||||
</Button>
|
||||
|
||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||
<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 { DeleteIncomeItemForm } from '@/entity/incomes/item';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useDeleteIncomeItemButton } from '../hooks/useDeleteIncomeItemButton';
|
||||
|
||||
type BaseButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
|
||||
|
||||
type DeleteIncomeItemButtonProps = BaseButtonProps & {
|
||||
type DeleteIncomeItemButtonProps = ButtonProps & {
|
||||
item: IncomeListItem;
|
||||
ref?: RefObject<HTMLButtonElement>;
|
||||
};
|
||||
@ -30,14 +32,16 @@ const DeleteIncomeItemButton: FC<DeleteIncomeItemButtonProps> = (props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
<Button
|
||||
color="error"
|
||||
data-testid={DataTestId.DELETE_INCOME_ITEM_BUTTON}
|
||||
onClick={onClickHandler}
|
||||
ref={ref}
|
||||
type="button"
|
||||
size="small"
|
||||
{...restProps}
|
||||
>
|
||||
Удалить
|
||||
</button>
|
||||
</Button>
|
||||
|
||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||
<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 { EditIncomeItemForm } from '@/entity/incomes/item';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useIncomeItemButton } from '../hooks/useIncomeItemButton';
|
||||
|
||||
type BaseButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
|
||||
|
||||
type EditIncomeItemButtonProps = BaseButtonProps & {
|
||||
type EditIncomeItemButtonProps = ButtonProps & {
|
||||
item: IncomeListItem;
|
||||
ref?: RefObject<HTMLButtonElement>;
|
||||
};
|
||||
@ -32,15 +34,16 @@ const EditIncomeItemButton: FC<EditIncomeItemButtonProps> = (props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
<Button
|
||||
data-testid={DataTestId.EDIT_INCOME_ITEM_BUTTON}
|
||||
disabled={isPending}
|
||||
onClick={onClickHandler}
|
||||
ref={ref}
|
||||
type="button"
|
||||
size="small"
|
||||
{...restProps}
|
||||
>
|
||||
Редактировать
|
||||
</button>
|
||||
</Button>
|
||||
|
||||
<Modal onClose={onCloseModalHandler} open={isOpen}>
|
||||
<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 { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useAddIncomeListButton } from '../hooks/useAddIncomeListButton';
|
||||
|
||||
type AddIncomeListButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||
type AddIncomeListButtonProps = ButtonProps & {
|
||||
ref?: Ref<HTMLButtonElement>;
|
||||
};
|
||||
|
||||
@ -22,9 +26,14 @@ const AddIncomeListButton: FC<AddIncomeListButtonProps> = (props) => {
|
||||
|
||||
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}>
|
||||
<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 { DeleteIncomeListForm } from '@/entity/incomes/list';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useIncomeListButton } from '../hooks/useIncomeListButton';
|
||||
|
||||
type DeleteIncomeListButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||
type DeleteIncomeListButtonProps = ButtonProps & {
|
||||
list: IncomeList;
|
||||
ref?: Ref<HTMLButtonElement>;
|
||||
};
|
||||
@ -25,9 +29,15 @@ const DeleteIncomeListButton = (props: DeleteIncomeListButtonProps) => {
|
||||
|
||||
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}>
|
||||
<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 { EditIncomeListForm } from '@/entity/incomes/list';
|
||||
import { DataTestId } from '@/shared/constants';
|
||||
import { Modal } from '@/shared/ui/Modal';
|
||||
|
||||
import { useIncomeListButton } from '../hooks/useIncomeListButton';
|
||||
|
||||
type EditIncomeListButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||
type EditIncomeListButtonProps = ButtonProps & {
|
||||
list: IncomeList;
|
||||
ref?: Ref<HTMLButtonElement>;
|
||||
};
|
||||
@ -25,9 +29,14 @@ const EditIncomeListButton: FC<EditIncomeListButtonProps> = (props) => {
|
||||
|
||||
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}>
|
||||
<EditIncomeListForm disabled={isPending} list={list} onSubmit={onFormSubmitHandler} />
|
||||
|
||||
@ -2,6 +2,10 @@ import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
|
||||
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');
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import { Button, Typography } from '@mui/material';
|
||||
import { NavLink } from 'react-router';
|
||||
|
||||
import { PAGES } from '@/shared/router';
|
||||
import { LoginForm } from '@/widgets/auth/LoginForm';
|
||||
|
||||
import classes from './LoginPage.module.css';
|
||||
@ -7,12 +9,16 @@ import classes from './LoginPage.module.css';
|
||||
const LoginPage = () => (
|
||||
<div className={classes.overlay}>
|
||||
<div className={classes.contentWrapper}>
|
||||
<h1>Вход в аккаунт</h1>
|
||||
<Typography sx={{ mb: 2 }} variant="h4">
|
||||
Вход в аккаунт
|
||||
</Typography>
|
||||
|
||||
<LoginForm />
|
||||
|
||||
<NavLink end to="/register">
|
||||
Регистрация
|
||||
<NavLink end to={PAGES.Register}>
|
||||
<Button size="small" sx={{ mt: 1 }}>
|
||||
Регистрация
|
||||
</Button>
|
||||
</NavLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import { Button, Typography } from '@mui/material';
|
||||
import { NavLink } from 'react-router';
|
||||
|
||||
import { PAGES } from '@/shared/router';
|
||||
import { RegisterForm } from '@/widgets/auth/RegisterForm';
|
||||
|
||||
import classes from './RegisterPage.module.css';
|
||||
@ -7,12 +9,16 @@ import classes from './RegisterPage.module.css';
|
||||
const RegisterPage = () => (
|
||||
<div className={classes.overlay}>
|
||||
<div className={classes.contentWrapper}>
|
||||
<h1>Регистрация аккаунта</h1>
|
||||
<Typography sx={{ mb: 2 }} variant="h4">
|
||||
Регистрация аккаунта
|
||||
</Typography>
|
||||
|
||||
<RegisterForm />
|
||||
|
||||
<NavLink end to="/login">
|
||||
Вход
|
||||
<NavLink end to={PAGES.Login}>
|
||||
<Button size="small" sx={{ mt: 1 }}>
|
||||
Вход
|
||||
</Button>
|
||||
</NavLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import type { FC } from 'react';
|
||||
|
||||
import { Typography } from '@mui/material';
|
||||
|
||||
import { useBankCards } from '@/entity/cards';
|
||||
import { AddBankCardButton } from '@/features/bank-cards/AddBankCardButton';
|
||||
import { Spinner } from '@/shared/ui/Spinner';
|
||||
@ -23,16 +25,14 @@ const BankCardsPage: FC = () => {
|
||||
|
||||
return (
|
||||
<AppLayout>
|
||||
<div>
|
||||
<h1>Мои карты</h1>
|
||||
<Typography variant="h4">
|
||||
Мои карты
|
||||
</Typography>
|
||||
|
||||
<div>
|
||||
<AddBankCardButton />
|
||||
</div>
|
||||
<AddBankCardButton sx={{ mb: 2, mt: 2 }} />
|
||||
|
||||
{renderContent()}
|
||||
{renderContent()}
|
||||
|
||||
</div>
|
||||
</AppLayout>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import type { FC } from 'react';
|
||||
|
||||
import { Typography } from '@mui/material';
|
||||
|
||||
import { useCash } from '@/entity/cash';
|
||||
import { AddCashButton } from '@/features/cash/AddCashButton';
|
||||
import { Spinner } from '@/shared/ui/Spinner';
|
||||
@ -23,16 +25,14 @@ const CashPage: FC = () => {
|
||||
|
||||
return (
|
||||
<AppLayout>
|
||||
<div>
|
||||
<h1>Мои наличные</h1>
|
||||
<Typography variant="h4">
|
||||
Мои наличные
|
||||
</Typography>
|
||||
|
||||
<div>
|
||||
<AddCashButton />
|
||||
</div>
|
||||
<AddCashButton sx={{ mb: 2, mt: 2 }} />
|
||||
|
||||
{renderContent()}
|
||||
{renderContent()}
|
||||
|
||||
</div>
|
||||
</AppLayout>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { Typography } from '@mui/material';
|
||||
import { useParams } from 'react-router';
|
||||
|
||||
import type { ExpensePageParams } from '@/shared/router';
|
||||
@ -30,14 +31,14 @@ const ExpensePage = () => {
|
||||
|
||||
return (
|
||||
<AppLayout>
|
||||
<div>
|
||||
<h1>Списки расходов</h1>
|
||||
<Typography variant="h4">
|
||||
Списки расходов
|
||||
</Typography>
|
||||
|
||||
<AddExpenseItemButton listId={id} />
|
||||
<AddExpenseItemButton listId={id} sx={{ mb: 2, mt: 2 }} />
|
||||
|
||||
{renderContent()}
|
||||
{renderContent()}
|
||||
|
||||
</div>
|
||||
</AppLayout>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import { Typography } from '@mui/material';
|
||||
|
||||
import { useExpensesList } from '@/entity/expenses/list';
|
||||
import { AddExpensesListButton } from '@/features/expenses/list/AddExpensesListButton';
|
||||
import { Spinner } from '@/shared/ui/Spinner';
|
||||
@ -21,16 +23,13 @@ const ExpensesPage = () => {
|
||||
|
||||
return (
|
||||
<AppLayout>
|
||||
<div>
|
||||
<h1>Списки расходов</h1>
|
||||
<Typography variant="h4">
|
||||
Списки расходов
|
||||
</Typography>
|
||||
|
||||
<div>
|
||||
<AddExpensesListButton />
|
||||
</div>
|
||||
<AddExpensesListButton sx={{ mb: 2, mt: 2 }} />
|
||||
|
||||
{renderContent()}
|
||||
|
||||
</div>
|
||||
{renderContent()}
|
||||
</AppLayout>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import { Typography } from '@mui/material';
|
||||
|
||||
import { AppLayout } from '@/widgets/AppLayout';
|
||||
|
||||
const HomePage = () => (
|
||||
<AppLayout>
|
||||
<div>
|
||||
<h1>Home Page</h1>
|
||||
</div>
|
||||
<Typography variant="h4">
|
||||
Домашняя страница
|
||||
</Typography>
|
||||
</AppLayout>
|
||||
);
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { Typography } from '@mui/material';
|
||||
import { useParams } from 'react-router';
|
||||
|
||||
import type { IncomePageParams } from '@/shared/router';
|
||||
@ -30,14 +31,14 @@ const IncomePage = () => {
|
||||
|
||||
return (
|
||||
<AppLayout>
|
||||
<div>
|
||||
<h1>Списки расходов</h1>
|
||||
<Typography variant="h4">
|
||||
Списки расходов
|
||||
</Typography>
|
||||
|
||||
<AddIncomeItemButton listId={id} />
|
||||
<AddIncomeItemButton listId={id} sx={{ mb: 2, mt: 2 }} />
|
||||
|
||||
{renderContent()}
|
||||
{renderContent()}
|
||||
|
||||
</div>
|
||||
</AppLayout>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import { Typography } from '@mui/material';
|
||||
|
||||
import { useIncomesList } from '@/entity/incomes/list';
|
||||
import { AddIncomeListButton } from '@/features/incomes/list/AddIncomeListButton';
|
||||
import { Spinner } from '@/shared/ui/Spinner';
|
||||
@ -21,16 +23,14 @@ const IncomesPage = () => {
|
||||
|
||||
return (
|
||||
<AppLayout>
|
||||
<div>
|
||||
<h1>Списки дохода</h1>
|
||||
<Typography variant="h4">
|
||||
Списки дохода
|
||||
</Typography>
|
||||
|
||||
<div>
|
||||
<AddIncomeListButton />
|
||||
</div>
|
||||
<AddIncomeListButton sx={{ mb: 2, mt: 2 }} />
|
||||
|
||||
{renderContent()}
|
||||
{renderContent()}
|
||||
|
||||
</div>
|
||||
</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 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;
|
||||
onClose: () => void;
|
||||
open: boolean;
|
||||
};
|
||||
|
||||
const Modal: FC<ModalProps> = (props) => {
|
||||
const { children, onClose, open } = props;
|
||||
|
||||
if (!open) {
|
||||
return null;
|
||||
}
|
||||
const {
|
||||
children, onClose, open, ...restProps
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div className={classes.wrapper} onClick={onClose} role="dialog">
|
||||
<div className={classes.content} onClick={(e) => { e.stopPropagation(); }}>
|
||||
<span className={classes.closeIcon} onClick={onClose}>×</span>
|
||||
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
<MuiModal
|
||||
closeAfterTransition
|
||||
onClose={onClose}
|
||||
open={open}
|
||||
{...restProps}
|
||||
>
|
||||
<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 { formatDate } from './formatters/date';
|
||||
|
||||
export { getUTCDate } from './helpers/getUTCDate';
|
||||
|
||||
@ -4,4 +4,5 @@
|
||||
|
||||
.content {
|
||||
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 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 = () => (
|
||||
<div className={classes.wrapper}>
|
||||
<ul>
|
||||
<li>
|
||||
<NavLink to={PAGES.Home}>
|
||||
Главная
|
||||
</NavLink>
|
||||
</li>
|
||||
|
||||
<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>
|
||||
<List>
|
||||
{elements.map(({ icon, title, to }) => (
|
||||
<ListItem disablePadding key={to}>
|
||||
<ListItemLink icon={icon} primary={title} to={to} />
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { FC } from 'react';
|
||||
|
||||
import { Input } from '@/shared/ui/Input';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
|
||||
import { useLoginForm } from './hooks/useLoginForm';
|
||||
import classes from './LoginForm.module.css';
|
||||
@ -10,28 +10,36 @@ const LoginForm: FC = () => {
|
||||
|
||||
return (
|
||||
<form className={classes.form} onSubmit={onSubmitHandler}>
|
||||
<Input
|
||||
<TextField
|
||||
disabled={isPending}
|
||||
id="email"
|
||||
inputMode="email"
|
||||
label="Почта"
|
||||
name="email"
|
||||
type="text"
|
||||
required
|
||||
size="small"
|
||||
variant="standard"
|
||||
/>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
disabled={isPending}
|
||||
id="password"
|
||||
label="Пароль"
|
||||
name="password"
|
||||
required
|
||||
size="small"
|
||||
type="password"
|
||||
variant="standard"
|
||||
/>
|
||||
|
||||
<button
|
||||
<Button
|
||||
disabled={isPending}
|
||||
size="small"
|
||||
sx={{ mt: 2 }}
|
||||
type="submit"
|
||||
variant="contained"
|
||||
>
|
||||
Войти
|
||||
</button>
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { FC } from 'react';
|
||||
|
||||
import { Input } from '@/shared/ui/Input';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
|
||||
import { useRegisterForm } from './hooks/useRegisterForm';
|
||||
import classes from './RegisterForm.module.css';
|
||||
@ -10,25 +10,36 @@ const RegisterForm: FC = () => {
|
||||
|
||||
return (
|
||||
<form className={classes.form} onSubmit={onSubmitHandler}>
|
||||
<Input
|
||||
<TextField
|
||||
disabled={isPending}
|
||||
id="email"
|
||||
inputMode="email"
|
||||
label="Почта"
|
||||
name="email"
|
||||
type="text"
|
||||
required
|
||||
size="small"
|
||||
variant="standard"
|
||||
/>
|
||||
|
||||
<Input
|
||||
<TextField
|
||||
disabled={isPending}
|
||||
id="password"
|
||||
label="Пароль"
|
||||
name="password"
|
||||
required
|
||||
size="small"
|
||||
type="password"
|
||||
variant="standard"
|
||||
/>
|
||||
|
||||
<button disabled={isPending} type="submit">
|
||||
<Button
|
||||
disabled={isPending}
|
||||
size="small"
|
||||
sx={{ mt: 2 }}
|
||||
type="submit"
|
||||
variant="contained"
|
||||
>
|
||||
Зарегистрироваться
|
||||
</button>
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user