Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Homework 12 routing #126

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
forms
raavmx committed Sep 3, 2024
commit f169bf72fecff81fbc87acdf2b941b161cf28782
1,986 changes: 1,938 additions & 48 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -66,12 +66,17 @@
"webpack-dev-server": "^4.15.0"
},
"dependencies": {
"antd": "^5.20.1",
"classnames": "^2.5.1",
"clsx": "^1.2.1",
"formik": "^2.4.6",
"random-js": "^2.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.52.2",
"react-i18next": "^14.1.2",
"react-redux": "^9.1.2",
"react-router-dom": "^6.26.0",
"unique-names-generator": "^4.7.1"
}
}
21 changes: 21 additions & 0 deletions src/components/Buttons/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React, { FC, ReactNode, ButtonHTMLAttributes } from 'react';
import cn from 'classnames';
import * as styles from './styles.module.scss'
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
children: ReactNode;
variant?: 'primary' | 'secondary' | 'info' | 'disabled';
size?: 'small'|'medium'|'large';
fullWidth?: boolean;
onClick?: () => void;
}

export const Button: FC<ButtonProps> = ({ children, variant = 'primary', fullWidth, className, disabled, ...anyProps }) => {
const buttonClass = cn(styles.button, {variant, disabled }, className);

return (
<button className={buttonClass} {...anyProps}>
{children}
</button>
);
};

40 changes: 40 additions & 0 deletions src/components/Buttons/Button/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
.button {
border-radius: 50px;
font-size: 14px;
font-weight: 600;
height: 37px;
padding: 8px 26px;
cursor: pointer;
width: max-content;
&:active {
box-shadow: 4px 4px 8px 0px rgba(34, 60, 80, 0.2) inset;
}
}

.primary {
background-color: var(--transparent-color-background);
color: var(--primary-color-text);
border: 2px solid var(--primary-color-border);
}
.secondary{
background-color: var(--transparent-color-background);
color: var(--secondary-color-text);
border: 2px solid var(--secondary-color-border);
}
.info{
background-color: var(--info-color-background);
color: var(--white-color-text);
border: 2px solid var(--info-color-border);
}
.disabled{
background-color: var(--secondary-color-background);
color: var(--white-color-text);
border: 2px solid var(--secondary-color-border);
cursor: not-allowed;
&:active {
box-shadow: none;
}
}
.full-width{
width: 100%;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { FC, ReactElement, useState, ChangeEvent } from 'react';
import { ModalWindow } from '../../ModalWindow';
import { Button } from 'antd';

export const ButtonWithInputModal: FC = (): ReactElement => {
const [input, setInput] = useState<string>('');
@@ -18,7 +19,7 @@ export const ButtonWithInputModal: FC = (): ReactElement => {
<input className="w-50" onChange={(e) => handlerChangeInput(e)} value={input} placeholder="Введите текст"></input>
<br />
<br />
<button onClick={() => openModal(true)}>Нажми меня и вылетит птичка</button>
<Button onClick={() => openModal(true)}>Нажми меня</Button>
<ModalWindow visible={visible} onCloseModalWindow={openModal}>
{input}
</ModalWindow>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { Meta } from '@storybook/react';
import { ButtonWithModalAuth } from './ButtonWithModalAuth';

const meta: Meta<typeof ButtonWithModalAuth> = {
title: 'Компоненты/Формы/Авторизация',
component: ButtonWithModalAuth,
tags: ['autodocs'],
};

export default meta;

export const buttonWithModalAuth = {};
22 changes: 22 additions & 0 deletions src/components/Buttons/ButtonWithModalAuth/ButtonWithModalAuth.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React, { FC, ReactElement, useState } from 'react';
import { ModalWindowPortal } from '../../ModalWindowPortal';
import { Button } from 'antd';
import { AuthComponent } from '../../Forms/AuthComponent/AuthComponent';

export const ButtonWithModalAuth: FC = (): ReactElement => {
const [visible, setVisible] = useState<boolean>(false);
const openModal = (visible: boolean): void => {
setVisible(visible);
};

return (
<>
<Button type="primary" onClick={() => openModal(true)}>
Вход/регистрация
</Button>
<ModalWindowPortal visible={visible} onCloseModalWindow={openModal}>
<AuthComponent />
</ModalWindowPortal>
</>
);
};
30 changes: 30 additions & 0 deletions src/components/FormField/NumberFormField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { memo } from 'react';
import { InputNumber } from 'antd';
import { FormItem } from '../FormItem/FormItem';
import { getValidates } from '../../../utils/validation';
import { NumberFormFieldProps } from 'src/shared/types/FormFieldTypes';

export const NumberFormField = memo<NumberFormFieldProps>(
({ onChange, onBlur, touched, value, errors, disabled, submitCount, name, placeholder, title }) => {
const { validateStatus, help } = getValidates(errors, touched, submitCount);

return (
<FormItem title={title} validateStatus={validateStatus} help={help}>
<InputNumber
disabled={disabled}
name={name}
onChange={onChange}
onBlur={onBlur}
value={value}
placeholder={placeholder}
style={{
width: '100%',
}}
type="number"
/>
</FormItem>
);
}
);

NumberFormField.displayName = 'NumberFormField';
26 changes: 26 additions & 0 deletions src/components/FormField/PasswordFormField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { memo } from 'react';
import { Input } from 'antd';
import { FormItem } from '../FormItem/FormItem';
import { getValidates } from '../../utils/validation';
import { FormFieldProps } from '../../types/FormFieldTypes';

export const PasswordFormField = memo<FormFieldProps>(
({ onChange, onBlur, touched, value, errors, disabled, submitCount, name, placeholder, title }) => {
const { validateStatus, help } = getValidates(errors, touched, submitCount);

return (
<FormItem title={title} validateStatus={validateStatus} help={help}>
<Input.Password
disabled={disabled}
name={name}
onChange={onChange}
onBlur={onBlur}
value={value}
placeholder={placeholder}
/>
</FormItem>
);
}
);

PasswordFormField.displayName = 'PasswordFormField';
26 changes: 26 additions & 0 deletions src/components/FormField/SelectFormField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { memo } from 'react';
import { Select } from 'antd';
import { FormItem } from '../FormItem/FormItem';
import { getValidates } from '../../../utils/validation';
import { SelectFieldProps } from 'src/shared/types/FormFieldTypes';

export const SelectFormField = memo<SelectFieldProps>(
({ onChange, onBlur, touched, value, errors, disabled, submitCount, placeholder, title, options }) => {
const { validateStatus, help } = getValidates(errors, touched, submitCount);

return (
<FormItem title={title} validateStatus={validateStatus} help={help}>
<Select
disabled={disabled}
onChange={onChange}
onBlur={onBlur}
value={value}
placeholder={placeholder}
options={options}
/>
</FormItem>
);
}
);

SelectFormField.displayName = 'SelectFormField';
26 changes: 26 additions & 0 deletions src/components/FormField/TextAreaFormField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { memo } from 'react';
import { Input } from 'antd';
import { FormItem } from '../FormItem/FormItem';
import { getValidates } from '../../utils/validation';
import { FormFieldProps } from '../../types/FormFieldTypes';

export const TextAreaFormField = memo<FormFieldProps>(
({ onChange, onBlur, touched, value, errors, disabled, submitCount, name, placeholder, title }) => {
const { validateStatus, help } = getValidates(errors, touched, submitCount);

return (
<FormItem title={title} validateStatus={validateStatus} help={help}>
<Input.TextArea
disabled={disabled}
name={name}
onChange={onChange}
onBlur={onBlur}
value={value}
placeholder={placeholder}
/>
</FormItem>
);
}
);

TextAreaFormField.displayName = 'TextAreaFormField';
26 changes: 26 additions & 0 deletions src/components/FormField/TextFormField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { memo } from 'react';
import { Input } from 'antd';
import { FormItem } from '../FormItem/FormItem';
import { getValidates } from '../../utils/validation';
import { FormFieldProps } from '../../types/FormFieldTypes';

export const TextFormField = memo<FormFieldProps>(
({ onChange, onBlur, touched, value, errors, disabled, submitCount, name, placeholder, title }) => {
const { validateStatus, help } = getValidates(errors, touched, submitCount);

return (
<FormItem title={title} validateStatus={validateStatus} help={help}>
<Input
disabled={disabled}
name={name}
onChange={onChange}
onBlur={onBlur}
value={value}
placeholder={placeholder}
/>
</FormItem>
);
}
);

TextFormField.displayName = 'TextFormField';
22 changes: 22 additions & 0 deletions src/components/FormItem/FormItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React, { memo } from 'react';
import { Form } from 'antd';

export type Help = null | React.ReactNode;
export type ValidateStatus = 'error' | '';

export type FormItemProps = {
className?: string;
title: React.ReactNode | React.ReactNode[];
children: React.ReactNode | React.ReactNode[];
validateStatus: ValidateStatus;
help: Help;
required?: boolean;
};

export const FormItem = memo<FormItemProps>(({ validateStatus, required, help, className, title, children }) => (
<div>
<Form.Item validateStatus={validateStatus} help={help}>
{children}
</Form.Item>
</div>
));
29 changes: 29 additions & 0 deletions src/components/Forms/AuthComponent/AuthComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, { FC } from 'react';
import { Tabs } from 'antd';
import { AuthForm } from '../AuthForm/AuthForm';
import { RegistrationForm } from '../RegistrationForm/RegistrationForm';

const onChange = (key: string) => {
console.log(key);
};

export const AuthComponent: FC = () => {
return (
<Tabs
defaultActiveKey="1"
items={[
{
key: '1',
label: 'Авторизация',
children: <AuthForm />,
},
{
key: '2',
label: 'Регистрация',
children: <RegistrationForm />,
},
]}
onChange={onChange}
/>
);
};
1 change: 1 addition & 0 deletions src/components/Forms/AuthComponent/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { AuthComponent } from './AuthComponent'
18 changes: 18 additions & 0 deletions src/components/Forms/AuthForm/AuthForm.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { Meta,StoryObj } from '@storybook/react';
import { AuthForm } from './AuthForm';


const meta: Meta<typeof AuthForm> = {
title: 'Форма авторизации',
component: AuthForm
};

export default meta;

type Story = StoryObj<typeof meta>

export const Default = {
args: {
primary: true
},
};
Loading