torgbox-ui 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.storybook/decorators/ReduxDecorator.d.ts +2 -0
- package/dist/.storybook/decorators/ReduxDecorator.js +4 -0
- package/dist/.storybook/decorators/RouterDecorator.d.ts +2 -0
- package/dist/.storybook/decorators/RouterDecorator.js +3 -0
- package/dist/.storybook/decorators/index.d.ts +2 -0
- package/dist/.storybook/decorators/index.js +2 -0
- package/dist/src/Inputs/Button/Button.js +30 -0
- package/dist/src/Inputs/Button/Button.stories.d.ts +21 -0
- package/dist/src/Inputs/Button/Button.stories.js +210 -0
- package/dist/src/Inputs/Button/Icon.stories.d.ts +20 -0
- package/dist/src/Inputs/Button/Icon.stories.js +196 -0
- package/dist/src/Inputs/Button/button.scss +358 -0
- package/dist/src/Inputs/Button/index.js +1 -0
- package/dist/src/Inputs/Checkbox/Checkbox.js +29 -0
- package/dist/src/Inputs/Checkbox/Checkbox.stories.d.ts +11 -0
- package/dist/src/Inputs/Checkbox/Checkbox.stories.js +108 -0
- package/dist/src/Inputs/Checkbox/checkbox.scss +63 -0
- package/dist/src/Inputs/Checkbox/index.js +1 -0
- package/dist/src/Inputs/EmailField/EmailField.js +61 -0
- package/dist/src/Inputs/EmailField/EmailField.stories.d.ts +8 -0
- package/dist/src/Inputs/EmailField/EmailField.stories.js +43 -0
- package/dist/src/Inputs/EmailField/ErrorMessages.js +3 -0
- package/dist/src/Inputs/EmailField/index.js +2 -0
- package/dist/src/Inputs/InnField/ErrorMessages.js +1 -0
- package/dist/src/Inputs/InnField/InnField.js +33 -0
- package/dist/src/Inputs/InnField/InnField.stories.d.ts +8 -0
- package/dist/src/Inputs/InnField/InnField.stories.js +43 -0
- package/dist/src/Inputs/InnField/index.js +2 -0
- package/dist/src/Inputs/NameField/ErrorMessages.js +8 -0
- package/dist/src/Inputs/NameField/NameField.js +54 -0
- package/dist/src/Inputs/NameField/NameField.stories.d.ts +8 -0
- package/dist/src/Inputs/NameField/NameField.stories.js +43 -0
- package/dist/src/Inputs/NameField/index.js +2 -0
- package/dist/src/Inputs/OtpInput/ErrorMessages.js +1 -0
- package/dist/src/Inputs/OtpInput/OtpInput.js +78 -0
- package/dist/src/Inputs/OtpInput/OtpInput.stories.d.ts +8 -0
- package/dist/src/Inputs/OtpInput/OtpInput.stories.js +52 -0
- package/dist/src/Inputs/OtpInput/index.js +2 -0
- package/dist/src/Inputs/OtpInput/otpInput.scss +39 -0
- package/dist/src/Inputs/PasswordField/ErrorMessages.js +2 -0
- package/dist/src/Inputs/PasswordField/PasswordField.js +35 -0
- package/dist/src/Inputs/PasswordField/PasswordField.stories.d.ts +8 -0
- package/dist/src/Inputs/PasswordField/PasswordField.stories.js +43 -0
- package/dist/src/Inputs/PasswordField/index.js +2 -0
- package/dist/src/Inputs/PhoneField/ErrorMessages.js +2 -0
- package/dist/src/Inputs/PhoneField/PhoneField.js +74 -0
- package/dist/src/Inputs/PhoneField/PhoneField.stories.d.ts +8 -0
- package/dist/src/Inputs/PhoneField/PhoneField.stories.js +43 -0
- package/dist/src/Inputs/PhoneField/index.js +2 -0
- package/dist/src/Inputs/RepeatPasswordField/ErrorMessages.js +2 -0
- package/dist/src/Inputs/RepeatPasswordField/RepeatPasswordField.js +22 -0
- package/dist/src/Inputs/RepeatPasswordField/index.js +2 -0
- package/dist/src/Inputs/Selector/Collapse.js +40 -0
- package/dist/src/Inputs/Selector/Collapse.stories.d.ts +8 -0
- package/dist/src/Inputs/Selector/Collapse.stories.js +108 -0
- package/dist/src/Inputs/Selector/Dropdown.js +81 -0
- package/dist/src/Inputs/Selector/Dropdown.stories.d.ts +9 -0
- package/dist/src/Inputs/Selector/Dropdown.stories.js +103 -0
- package/dist/src/Inputs/Selector/Option/Option.js +10 -0
- package/dist/src/Inputs/Selector/Option/Option.stories.d.ts +9 -0
- package/dist/src/Inputs/Selector/Option/Option.stories.js +47 -0
- package/dist/src/Inputs/Selector/Option/option.scss +44 -0
- package/dist/src/Inputs/Selector/index.js +3 -0
- package/dist/src/Inputs/Selector/selector.scss +101 -0
- package/dist/{types → src}/Inputs/TextField/TextField.d.ts +1 -1
- package/dist/src/Inputs/TextField/TextField.js +85 -0
- package/dist/src/Inputs/TextField/TextField.stories.d.ts +12 -0
- package/dist/src/Inputs/TextField/TextField.stories.js +101 -0
- package/dist/src/Inputs/TextField/index.js +1 -0
- package/dist/src/Inputs/TextField/textField.module.scss +157 -0
- package/dist/src/Inputs/TextField/textField.scss +156 -0
- package/dist/src/Inputs/index.js +11 -0
- package/dist/src/Inputs/index.scss +6 -0
- package/dist/src/Pages/ContentPage/ContentPage.js +22 -0
- package/dist/src/Pages/ContentPage/ContentPage.stories.d.ts +6 -0
- package/dist/src/Pages/ContentPage/ContentPage.stories.js +17 -0
- package/dist/src/Pages/ContentPage/contentPage.scss +10 -0
- package/dist/src/Pages/ContentPage/index.js +1 -0
- package/dist/src/Pages/CreatePasswordPage/CreatePasswordPage.js +47 -0
- package/dist/src/Pages/CreatePasswordPage/CreatePasswordPage.stories.d.ts +7 -0
- package/dist/src/Pages/CreatePasswordPage/CreatePasswordPage.stories.js +96 -0
- package/dist/src/Pages/CreatePasswordPage/createPasswordPage.scss +42 -0
- package/dist/src/Pages/CreatePasswordPage/index.js +1 -0
- package/dist/src/Pages/CreateTeamPage/CreateTeamPage.js +46 -0
- package/dist/src/Pages/CreateTeamPage/CreateTeamPage.stories.d.ts +7 -0
- package/dist/src/Pages/CreateTeamPage/CreateTeamPage.stories.js +82 -0
- package/dist/src/Pages/CreateTeamPage/createTeamPage.scss +82 -0
- package/dist/src/Pages/CreateTeamPage/index.js +1 -0
- package/dist/src/Pages/EmailConfirmationPage/EmailConfirmationPage.js +34 -0
- package/dist/src/Pages/EmailConfirmationPage/EmailConfirmationPage.stories.d.ts +8 -0
- package/dist/src/Pages/EmailConfirmationPage/EmailConfirmationPage.stories.js +86 -0
- package/dist/src/Pages/EmailConfirmationPage/emailConfirmationPage.scss +92 -0
- package/dist/src/Pages/EmailConfirmationPage/index.js +1 -0
- package/dist/src/Pages/JoinTeamPage/JoinTeamPage.js +6 -0
- package/dist/src/Pages/JoinTeamPage/JoinTeamPage.stories.d.ts +7 -0
- package/dist/src/Pages/JoinTeamPage/JoinTeamPage.stories.js +24 -0
- package/dist/src/Pages/JoinTeamPage/index.js +1 -0
- package/dist/src/Pages/JoinTeamPage/joinTeamPage.scss +50 -0
- package/dist/src/Pages/LoginPage/LoginPage.js +32 -0
- package/dist/src/Pages/LoginPage/LoginPage.stories.d.ts +7 -0
- package/dist/src/Pages/LoginPage/LoginPage.stories.js +108 -0
- package/dist/src/Pages/LoginPage/index.js +1 -0
- package/dist/src/Pages/LoginPage/loginPage.scss +80 -0
- package/dist/src/Pages/RegisterPage/RegisterPage.js +34 -0
- package/dist/src/Pages/RegisterPage/RegisterPage.stories.d.ts +7 -0
- package/dist/src/Pages/RegisterPage/RegisterPage.stories.js +149 -0
- package/dist/src/Pages/RegisterPage/index.js +1 -0
- package/dist/src/Pages/RegisterPage/registerPage.scss +72 -0
- package/dist/src/Pages/ResetPasswordPage/ResetPasswordPage.js +10 -0
- package/dist/src/Pages/ResetPasswordPage/ResetPasswordPage.stories.d.ts +7 -0
- package/dist/src/Pages/ResetPasswordPage/ResetPasswordPage.stories.js +24 -0
- package/dist/src/Pages/ResetPasswordPage/index.js +1 -0
- package/dist/src/Pages/ResetPasswordPage/resetPasswordPage.scss +41 -0
- package/dist/src/Pages/StartPage/StartPage.js +22 -0
- package/dist/src/Pages/StartPage/StartPage.stories.d.ts +7 -0
- package/dist/src/Pages/StartPage/StartPage.stories.js +48 -0
- package/dist/src/Pages/StartPage/index.js +1 -0
- package/dist/src/Pages/StartPage/startPage.scss +58 -0
- package/dist/src/Pages/index.js +6 -0
- package/dist/src/Pages/index.scss +9 -0
- package/dist/src/Utils/Divider/Divider.js +2 -0
- package/dist/src/Utils/Divider/divider.scss +11 -0
- package/dist/src/Utils/ErrorBanner/ErrorBanner.js +6 -0
- package/dist/src/Utils/ErrorBanner/errorBanner.scss +24 -0
- package/dist/src/Utils/ErrorBanner/index.js +1 -0
- package/dist/src/Utils/Link/Link.js +5 -0
- package/dist/src/Utils/Link/Link.stories.d.ts +8 -0
- package/dist/src/Utils/Link/Link.stories.js +49 -0
- package/dist/src/Utils/Link/index.js +1 -0
- package/dist/src/Utils/Link/index.scss +1 -0
- package/dist/src/Utils/Link/link.scss +21 -0
- package/dist/src/Utils/Modal/Modal.js +24 -0
- package/dist/src/Utils/Modal/Modal.stories.d.ts +6 -0
- package/dist/src/Utils/Modal/Modal.stories.js +38 -0
- package/dist/src/Utils/Modal/index.js +1 -0
- package/dist/src/Utils/Modal/modal.scss +33 -0
- package/dist/src/Utils/Portal/Portal.js +5 -0
- package/dist/src/Utils/SectionPlaceholder/SectionPlaceholder.js +2 -0
- package/dist/src/Utils/SectionPlaceholder/sectionPlaceholder.scss +22 -0
- package/dist/src/Utils/Spinner/Spinner.js +5 -0
- package/dist/src/Utils/Spinner/spinner.scss +41 -0
- package/dist/src/Utils/api.js +7 -0
- package/dist/src/Utils/index.js +7 -0
- package/dist/src/Utils/index.scss +6 -0
- package/dist/src/Widgets/Header/Header.js +18 -0
- package/dist/src/Widgets/Header/Header.stories.d.ts +6 -0
- package/dist/src/Widgets/Header/Header.stories.js +17 -0
- package/dist/src/Widgets/Header/header.scss +50 -0
- package/dist/src/Widgets/Header/index.js +1 -0
- package/dist/src/Widgets/Sidebar/Sidebar.js +25 -0
- package/dist/src/Widgets/Sidebar/Sidebar.stories.d.ts +6 -0
- package/dist/src/Widgets/Sidebar/Sidebar.stories.js +17 -0
- package/dist/src/Widgets/Sidebar/index.js +1 -0
- package/dist/src/Widgets/Sidebar/sidebar.scss +23 -0
- package/dist/src/Widgets/index.js +2 -0
- package/dist/src/Widgets/index.scss +2 -0
- package/dist/src/app/main.js +7 -0
- package/dist/src/app/routes/AppRouter.js +31 -0
- package/dist/src/app/routes/index.js +1 -0
- package/dist/src/app/store/index.js +1 -0
- package/dist/src/app/store/store.js +13 -0
- package/dist/src/assets/scss/index.scss +5 -0
- package/dist/src/assets/scss/settings/fonts.scss +29 -0
- package/dist/src/assets/scss/settings/globals.scss +5 -0
- package/dist/src/assets/scss/settings/helpers.scss +3 -0
- package/dist/src/assets/scss/settings/reset.scss +8 -0
- package/dist/src/assets/scss/settings/variables.scss +91 -0
- package/dist/src/entities/user/api/api.js +41 -0
- package/dist/src/entities/user/api/index.js +1 -0
- package/dist/src/entities/user/index.js +2 -0
- package/dist/src/entities/user/model/index.js +2 -0
- package/dist/src/entities/user/model/selectors.js +2 -0
- package/dist/src/entities/user/model/slice.js +31 -0
- package/dist/src/entities/user/model/types.js +1 -0
- package/dist/src/index.js +3 -0
- package/dist/src/index.scss +6 -0
- package/dist/src/shared/model/api.js +6 -0
- package/dist/src/shared/model/constants.js +1 -0
- package/dist/src/shared/model/index.js +2 -0
- package/dist/src/shared/ui/Avatar/Avatar.js +6 -0
- package/dist/src/shared/ui/Avatar/Avatar.stories.d.ts +6 -0
- package/dist/src/shared/ui/Avatar/Avatar.stories.js +17 -0
- package/dist/src/shared/ui/Avatar/avatar.scss +62 -0
- package/dist/src/shared/ui/index.d.ts +1 -0
- package/dist/src/shared/ui/index.js +1 -0
- package/dist/src/shared/ui/index.scss +1 -0
- package/dist/src/tools/customValidators.js +19 -0
- package/dist/src/tools/getCoords.js +18 -0
- package/dist/src/tools/regExp.js +5 -0
- package/dist/src/ui.js +3 -0
- package/dist/src/ui.scss +4 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +9 -8
- package/dist/torgbox-ui.cjs.js +0 -31
- package/dist/torgbox-ui.css +0 -1
- package/dist/torgbox-ui.es.js +0 -4799
- /package/dist/{types → src}/Inputs/Button/Button.d.ts +0 -0
- /package/dist/{types → src}/Inputs/Button/index.d.ts +0 -0
- /package/dist/{types → src}/Inputs/Checkbox/Checkbox.d.ts +0 -0
- /package/dist/{types → src}/Inputs/Checkbox/index.d.ts +0 -0
- /package/dist/{types → src}/Inputs/EmailField/EmailField.d.ts +0 -0
- /package/dist/{types → src}/Inputs/EmailField/ErrorMessages.d.ts +0 -0
- /package/dist/{types → src}/Inputs/EmailField/index.d.ts +0 -0
- /package/dist/{types → src}/Inputs/InnField/ErrorMessages.d.ts +0 -0
- /package/dist/{types → src}/Inputs/InnField/InnField.d.ts +0 -0
- /package/dist/{types → src}/Inputs/InnField/index.d.ts +0 -0
- /package/dist/{types → src}/Inputs/NameField/ErrorMessages.d.ts +0 -0
- /package/dist/{types → src}/Inputs/NameField/NameField.d.ts +0 -0
- /package/dist/{types → src}/Inputs/NameField/index.d.ts +0 -0
- /package/dist/{types → src}/Inputs/OtpInput/ErrorMessages.d.ts +0 -0
- /package/dist/{types → src}/Inputs/OtpInput/OtpInput.d.ts +0 -0
- /package/dist/{types → src}/Inputs/OtpInput/index.d.ts +0 -0
- /package/dist/{types → src}/Inputs/PasswordField/ErrorMessages.d.ts +0 -0
- /package/dist/{types → src}/Inputs/PasswordField/PasswordField.d.ts +0 -0
- /package/dist/{types → src}/Inputs/PasswordField/index.d.ts +0 -0
- /package/dist/{types → src}/Inputs/PhoneField/ErrorMessages.d.ts +0 -0
- /package/dist/{types → src}/Inputs/PhoneField/PhoneField.d.ts +0 -0
- /package/dist/{types → src}/Inputs/PhoneField/index.d.ts +0 -0
- /package/dist/{types → src}/Inputs/RepeatPasswordField/ErrorMessages.d.ts +0 -0
- /package/dist/{types → src}/Inputs/RepeatPasswordField/RepeatPasswordField.d.ts +0 -0
- /package/dist/{types → src}/Inputs/RepeatPasswordField/index.d.ts +0 -0
- /package/dist/{types → src}/Inputs/Selector/Collapse.d.ts +0 -0
- /package/dist/{types → src}/Inputs/Selector/Dropdown.d.ts +0 -0
- /package/dist/{types → src}/Inputs/Selector/Option/Option.d.ts +0 -0
- /package/dist/{types → src}/Inputs/Selector/index.d.ts +0 -0
- /package/dist/{types → src}/Inputs/TextField/index.d.ts +0 -0
- /package/dist/{types → src}/Inputs/index.d.ts +0 -0
- /package/dist/{types → src}/Pages/ContentPage/ContentPage.d.ts +0 -0
- /package/dist/{types → src}/Pages/ContentPage/index.d.ts +0 -0
- /package/dist/{types → src}/Pages/CreatePasswordPage/CreatePasswordPage.d.ts +0 -0
- /package/dist/{types → src}/Pages/CreatePasswordPage/index.d.ts +0 -0
- /package/dist/{types → src}/Pages/CreateTeamPage/CreateTeamPage.d.ts +0 -0
- /package/dist/{types → src}/Pages/CreateTeamPage/index.d.ts +0 -0
- /package/dist/{types → src}/Pages/EmailConfirmationPage/EmailConfirmationPage.d.ts +0 -0
- /package/dist/{types → src}/Pages/EmailConfirmationPage/index.d.ts +0 -0
- /package/dist/{types → src}/Pages/JoinTeamPage/JoinTeamPage.d.ts +0 -0
- /package/dist/{types → src}/Pages/JoinTeamPage/index.d.ts +0 -0
- /package/dist/{types → src}/Pages/LoginPage/LoginPage.d.ts +0 -0
- /package/dist/{types → src}/Pages/LoginPage/index.d.ts +0 -0
- /package/dist/{types → src}/Pages/RegisterPage/RegisterPage.d.ts +0 -0
- /package/dist/{types → src}/Pages/RegisterPage/index.d.ts +0 -0
- /package/dist/{types → src}/Pages/ResetPasswordPage/ResetPasswordPage.d.ts +0 -0
- /package/dist/{types → src}/Pages/ResetPasswordPage/index.d.ts +0 -0
- /package/dist/{types → src}/Pages/StartPage/StartPage.d.ts +0 -0
- /package/dist/{types → src}/Pages/StartPage/index.d.ts +0 -0
- /package/dist/{types → src}/Pages/index.d.ts +0 -0
- /package/dist/{types → src}/Utils/Divider/Divider.d.ts +0 -0
- /package/dist/{types → src}/Utils/ErrorBanner/ErrorBanner.d.ts +0 -0
- /package/dist/{types → src}/Utils/ErrorBanner/index.d.ts +0 -0
- /package/dist/{types → src}/Utils/Link/Link.d.ts +0 -0
- /package/dist/{types → src}/Utils/Link/index.d.ts +0 -0
- /package/dist/{types → src}/Utils/Modal/Modal.d.ts +0 -0
- /package/dist/{types → src}/Utils/Modal/index.d.ts +0 -0
- /package/dist/{types → src}/Utils/Portal/Portal.d.ts +0 -0
- /package/dist/{types → src}/Utils/SectionPlaceholder/SectionPlaceholder.d.ts +0 -0
- /package/dist/{types → src}/Utils/Spinner/Spinner.d.ts +0 -0
- /package/dist/{types → src}/Utils/api.d.ts +0 -0
- /package/dist/{types → src}/Utils/index.d.ts +0 -0
- /package/dist/{types → src}/Widgets/Header/Header.d.ts +0 -0
- /package/dist/{types → src}/Widgets/Header/index.d.ts +0 -0
- /package/dist/{types → src}/Widgets/Sidebar/Sidebar.d.ts +0 -0
- /package/dist/{types → src}/Widgets/Sidebar/index.d.ts +0 -0
- /package/dist/{types → src}/Widgets/index.d.ts +0 -0
- /package/dist/{types → src}/app/main.d.ts +0 -0
- /package/dist/{types → src}/app/routes/AppRouter.d.ts +0 -0
- /package/dist/{types → src}/app/routes/index.d.ts +0 -0
- /package/dist/{types → src}/app/store/index.d.ts +0 -0
- /package/dist/{types → src}/app/store/store.d.ts +0 -0
- /package/dist/{types → src}/entities/user/api/api.d.ts +0 -0
- /package/dist/{types → src}/entities/user/api/index.d.ts +0 -0
- /package/dist/{types → src}/entities/user/index.d.ts +0 -0
- /package/dist/{types → src}/entities/user/model/index.d.ts +0 -0
- /package/dist/{types → src}/entities/user/model/selectors.d.ts +0 -0
- /package/dist/{types → src}/entities/user/model/slice.d.ts +0 -0
- /package/dist/{types → src}/entities/user/model/types.d.ts +0 -0
- /package/dist/{types → src}/index.d.ts +0 -0
- /package/dist/{types → src}/shared/model/api.d.ts +0 -0
- /package/dist/{types → src}/shared/model/constants.d.ts +0 -0
- /package/dist/{types → src}/shared/model/index.d.ts +0 -0
- /package/dist/{types → src}/shared/ui/Avatar/Avatar.d.ts +0 -0
- /package/dist/{types → src}/shared/ui/Avatar/index.d.ts +0 -0
- /package/dist/{types/shared/ui/index.d.ts → src/shared/ui/Avatar/index.js} +0 -0
- /package/dist/{types → src}/tools/customValidators.d.ts +0 -0
- /package/dist/{types → src}/tools/getCoords.d.ts +0 -0
- /package/dist/{types → src}/tools/regExp.d.ts +0 -0
- /package/dist/{types → src}/ui.d.ts +0 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { expect, userEvent, waitFor, within } from '@storybook/test';
|
|
2
|
+
import { ReduxDecorator } from '../../../.storybook/decorators';
|
|
3
|
+
import { emptyEmailError, notCorrectEmailError } from '../../Inputs/EmailField';
|
|
4
|
+
import { emptyPasswordError, notCorrectPasswordError } from '../../Inputs/PasswordField';
|
|
5
|
+
import { LoginPage } from './LoginPage';
|
|
6
|
+
const meta = {
|
|
7
|
+
component: LoginPage,
|
|
8
|
+
decorators: [ReduxDecorator],
|
|
9
|
+
title: 'Pages/Authorization/LoginPage',
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: 'fullscreen',
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export default meta;
|
|
15
|
+
export const LoginPageDesktop = {
|
|
16
|
+
parameters: {
|
|
17
|
+
design: {
|
|
18
|
+
type: 'figma',
|
|
19
|
+
url: 'https://www.figma.com/file/8cQcICaes5IWFubU66DMdl/Torgbox-CRM?type=design&node-id=12659-15695&mode=design&t=X2OTLYu2aaAWIysR-4',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
play: async ({ canvasElement, step }) => {
|
|
23
|
+
const canvas = within(canvasElement);
|
|
24
|
+
const [emailWrapper, passwordWrapper] = Array.from(canvasElement.querySelectorAll('.text-field-wrapper'));
|
|
25
|
+
const passwordInput = passwordWrapper.querySelector('.text-field__input');
|
|
26
|
+
const emailInput = emailWrapper.querySelector('.text-field__input');
|
|
27
|
+
const submitBtn = canvasElement.querySelector('.btn');
|
|
28
|
+
const eyeIcon = passwordWrapper.querySelector('#eye-icon');
|
|
29
|
+
const checkboxLabel = canvas.getByText('Запомнить меня');
|
|
30
|
+
const delay = 100;
|
|
31
|
+
const checkedSelector = '.checkbox__icon--active';
|
|
32
|
+
const overlaySelector = '.login-page__overlay';
|
|
33
|
+
const errorBannerText = 'Неверный email или пароль';
|
|
34
|
+
const btnLoadingSelector = '.btn__filled--loading';
|
|
35
|
+
const checkIconId = '#check-icon';
|
|
36
|
+
const correctEmail = 'some@email.com';
|
|
37
|
+
const correctPassword = 'qwerty123';
|
|
38
|
+
const incorrectEmail = 'some-email';
|
|
39
|
+
const incorrectPassword = '123';
|
|
40
|
+
await step('Проверяем, заблокирована ли кнопка "Войти" при незаполненных полях формы', async () => {
|
|
41
|
+
await expect(submitBtn).toBeDisabled();
|
|
42
|
+
});
|
|
43
|
+
await step('При пустом значении в поле "Email" выпадает ошибка', async () => {
|
|
44
|
+
await userEvent.click(emailInput, { delay });
|
|
45
|
+
await userEvent.click(passwordInput, { delay });
|
|
46
|
+
await expect(canvas.getByText(emptyEmailError)).toBeInTheDocument();
|
|
47
|
+
});
|
|
48
|
+
await step('При пустом значении в поле "Пароль" выпадает ошибка', async () => {
|
|
49
|
+
await userEvent.click(emailInput, { delay });
|
|
50
|
+
await expect(canvas.getByText(emptyPasswordError)).toBeInTheDocument();
|
|
51
|
+
});
|
|
52
|
+
await step('При некорректном значении в поле "Email" выпадает ошибка', async () => {
|
|
53
|
+
await userEvent.type(emailInput, incorrectEmail, { delay });
|
|
54
|
+
await userEvent.click(passwordInput, { delay });
|
|
55
|
+
await expect(canvas.getByText(notCorrectEmailError)).toBeInTheDocument();
|
|
56
|
+
});
|
|
57
|
+
await step('При некорректном значении в поле "Пароль" выпадает ошибка', async () => {
|
|
58
|
+
await userEvent.type(passwordInput, incorrectPassword, { delay });
|
|
59
|
+
await userEvent.click(emailInput, { delay });
|
|
60
|
+
await expect(canvas.getByText(notCorrectPasswordError)).toBeInTheDocument();
|
|
61
|
+
});
|
|
62
|
+
await step('Кнопка "Войти в CRM" заблокирована при наличии ошибки в любом из полей', async () => {
|
|
63
|
+
await expect(submitBtn).toBeDisabled();
|
|
64
|
+
});
|
|
65
|
+
await step('Кнопка "Войти в CRM" доступна при корректно заполненных полях', async () => {
|
|
66
|
+
await userEvent.clear(emailInput);
|
|
67
|
+
await userEvent.type(emailInput, correctEmail, { delay });
|
|
68
|
+
await userEvent.clear(passwordInput);
|
|
69
|
+
await userEvent.type(passwordInput, correctPassword, { delay });
|
|
70
|
+
await expect(submitBtn).toBeEnabled();
|
|
71
|
+
});
|
|
72
|
+
await step('При корректно заполненных полях отображаются галочки', async () => {
|
|
73
|
+
await expect(emailWrapper.querySelector(checkIconId)).toBeInTheDocument();
|
|
74
|
+
await expect(passwordWrapper.querySelector(checkIconId)).toBeInTheDocument();
|
|
75
|
+
});
|
|
76
|
+
await step('Тип поля "Пароль" изменяется на "text" при клике на иконку-глаз', async () => {
|
|
77
|
+
await userEvent.click(eyeIcon, { delay });
|
|
78
|
+
await expect(passwordInput).toHaveAttribute('type', 'text');
|
|
79
|
+
});
|
|
80
|
+
await step('Тип поля "Пароль" изменяется на "password" при клике на иконку-глаз', async () => {
|
|
81
|
+
await userEvent.click(eyeIcon, { delay });
|
|
82
|
+
await expect(passwordInput).toHaveAttribute('type', 'password');
|
|
83
|
+
});
|
|
84
|
+
await step('При клике на "Запомнить меня" внутри чекбокса появляется галочка', async () => {
|
|
85
|
+
await userEvent.click(checkboxLabel, { delay });
|
|
86
|
+
await expect(canvasElement.querySelector(checkedSelector)).toBeInTheDocument();
|
|
87
|
+
});
|
|
88
|
+
await step('При клике на кнопку "Войти" блокируются все поля и статус кнопки меняется на loading', async () => {
|
|
89
|
+
void userEvent.click(submitBtn, { delay });
|
|
90
|
+
await waitFor(() => {
|
|
91
|
+
void expect(canvasElement.querySelector(overlaySelector)).toBeInTheDocument();
|
|
92
|
+
void expect(canvasElement.querySelector(btnLoadingSelector)).toBeInTheDocument();
|
|
93
|
+
}, { timeout: 2000 });
|
|
94
|
+
});
|
|
95
|
+
await step('При ошибке авторизации появляется баннер с ошибкой', async () => {
|
|
96
|
+
await waitFor(async () => {
|
|
97
|
+
await expect(canvas.getByText(errorBannerText)).toBeInTheDocument();
|
|
98
|
+
}, { timeout: 2000 });
|
|
99
|
+
});
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
export const LoginPageMobile = {
|
|
103
|
+
parameters: {
|
|
104
|
+
viewport: {
|
|
105
|
+
defaultViewport: 'mobile',
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { LoginPage } from './LoginPage';
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
$page-background: $surface-bright;
|
|
2
|
+
$title: $neutral-high;
|
|
3
|
+
$footer-text: $neutral-low;
|
|
4
|
+
$link: $primary-high;
|
|
5
|
+
$error-background: $error-border-low;
|
|
6
|
+
$error-content: $error-high;
|
|
7
|
+
|
|
8
|
+
.login-page {
|
|
9
|
+
background-color: $page-background;
|
|
10
|
+
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
align-items: center;
|
|
14
|
+
|
|
15
|
+
box-sizing: border-box;
|
|
16
|
+
max-width: 400px;
|
|
17
|
+
margin: 0 auto;
|
|
18
|
+
padding: 24px 40px;
|
|
19
|
+
|
|
20
|
+
&__overlay {
|
|
21
|
+
position: fixed;
|
|
22
|
+
top: 0;
|
|
23
|
+
bottom: 0;
|
|
24
|
+
right: 0;
|
|
25
|
+
left: 0;
|
|
26
|
+
background-color: $page-background;
|
|
27
|
+
opacity: 0.6;
|
|
28
|
+
z-index: 1;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&__title {
|
|
32
|
+
margin-bottom: 32px;
|
|
33
|
+
font-size: 28px;
|
|
34
|
+
line-height: 36px;
|
|
35
|
+
color: $title;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&__form {
|
|
39
|
+
width: 100%;
|
|
40
|
+
padding-bottom: 16px;
|
|
41
|
+
display: flex;
|
|
42
|
+
flex-direction: column;
|
|
43
|
+
gap: 28px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&__input-wrapper {
|
|
47
|
+
display: flex;
|
|
48
|
+
justify-content: space-between;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
&__footer {
|
|
52
|
+
display: flex;
|
|
53
|
+
flex-direction: column;
|
|
54
|
+
align-items: center;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
&__text {
|
|
58
|
+
font-size: 12px;
|
|
59
|
+
line-height: 16px;
|
|
60
|
+
color: $footer-text;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@media screen and (max-width: $sm) {
|
|
65
|
+
.login-page {
|
|
66
|
+
max-width: 320px;
|
|
67
|
+
padding: 24px 16px;
|
|
68
|
+
|
|
69
|
+
&__title {
|
|
70
|
+
font-size: 24px;
|
|
71
|
+
line-height: 32px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
&__footer {
|
|
75
|
+
width: 100%;
|
|
76
|
+
flex-direction: row;
|
|
77
|
+
justify-content: space-between;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState, useRef, } from 'react';
|
|
3
|
+
import { useRegisterMutation } from '../../entities/user';
|
|
4
|
+
import { Button, EmailField, NameField, PhoneField, } from '../../Inputs';
|
|
5
|
+
import { ErrorBanner } from '../../Utils';
|
|
6
|
+
export const RegisterPage = () => {
|
|
7
|
+
const [emailValid, setEmailValid] = useState(false);
|
|
8
|
+
const [nameValid, setNameValid] = useState(false);
|
|
9
|
+
const [lastNameValid, setLastNameValid] = useState(false);
|
|
10
|
+
const [phoneNumberValid, setPhoneNumberValid] = useState(false);
|
|
11
|
+
const [formValid, setFormValid] = useState(false);
|
|
12
|
+
const [register, { isError, isLoading }] = useRegisterMutation();
|
|
13
|
+
const formRef = useRef({
|
|
14
|
+
email: '',
|
|
15
|
+
name: '',
|
|
16
|
+
lastName: '',
|
|
17
|
+
phoneNumber: ''
|
|
18
|
+
});
|
|
19
|
+
const getBtnState = () => {
|
|
20
|
+
if (isLoading)
|
|
21
|
+
return 'loading';
|
|
22
|
+
return formValid ? 'idle' : 'disabled';
|
|
23
|
+
};
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
setFormValid([emailValid, nameValid, lastNameValid, phoneNumberValid].every(Boolean));
|
|
26
|
+
}, [emailValid, nameValid, lastNameValid, phoneNumberValid]);
|
|
27
|
+
const handleSendForm = () => {
|
|
28
|
+
if (formValid) {
|
|
29
|
+
const { email, name, phoneNumber, lastName } = formRef.current;
|
|
30
|
+
void register({ email, name, phoneNumber, lastName });
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
return (_jsxs("div", { className: 'register-page', children: [isLoading && _jsx("div", { className: 'login-page__overlay' }), _jsx("h1", { className: 'register-page__title', children: "\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044F \u0430\u043A\u043A\u0430\u0443\u043D\u0442\u0430" }), isError && (_jsx(ErrorBanner, { error: '\u041E\u0448\u0438\u0431\u043A\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438' })), isError && (_jsx(ErrorBanner, { error: '\u041E\u0448\u0438\u0431\u043A\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438' })), _jsxs("form", { className: 'register-page__form', children: [_jsx(EmailField, { onValidated: setEmailValid, onTextValid: (email) => formRef.current.email = email, tabIndex: 1 }), _jsx(NameField, { onValidated: setNameValid, onTextValid: (name) => formRef.current.name = name, nameType: 'firstName', tabIndex: 2 }), _jsx(NameField, { onValidated: setLastNameValid, onTextValid: (lastName) => formRef.current.lastName = lastName, nameType: 'lastName', tabIndex: 3 }), _jsx(PhoneField, { onValidated: setPhoneNumberValid, onTextValid: (phoneNumber) => formRef.current.phoneNumber = phoneNumber, tabIndex: 4 }), _jsx(Button, { label: '\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044C email', size: 'large', state: getBtnState(), fullWidth: true, tabIndex: 5, onClick: handleSendForm })] }), _jsxs("div", { className: 'register-page__footer', children: [_jsx("p", { className: 'register-page__text', children: "\u0423\u0436\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u044B?" }), _jsx("a", { className: 'register-page__link', href: '#', children: "\u0412\u043E\u0439\u0442\u0438 \u0432 \u0430\u043A\u043A\u0430\u0443\u043D\u0442" })] })] }));
|
|
34
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { RegisterPage } from './RegisterPage';
|
|
3
|
+
declare const meta: Meta;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof RegisterPage>;
|
|
6
|
+
export declare const Desktop: Story;
|
|
7
|
+
export declare const Mobile: Story;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { expect, userEvent, waitFor, within } from '@storybook/test';
|
|
2
|
+
import { ReduxDecorator } from '../../../.storybook/decorators';
|
|
3
|
+
import { emptyEmailError, notCorrectEmailError } from '../../Inputs/EmailField';
|
|
4
|
+
import { emptyFirstNameError, emptyLastNameError, notCorrectFirstNameError, notCorrectLastNameError, } from '../../Inputs/NameField';
|
|
5
|
+
import { emptyPhoneError, notCorrectPhoneError } from '../../Inputs/PhoneField';
|
|
6
|
+
import { RegisterPage } from './RegisterPage';
|
|
7
|
+
const meta = {
|
|
8
|
+
component: RegisterPage,
|
|
9
|
+
decorators: [ReduxDecorator],
|
|
10
|
+
title: 'Pages/Authorization/RegisterPage',
|
|
11
|
+
parameters: {
|
|
12
|
+
layout: 'fullscreen',
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
export default meta;
|
|
16
|
+
export const Desktop = {
|
|
17
|
+
parameters: {
|
|
18
|
+
design: {
|
|
19
|
+
type: 'figma',
|
|
20
|
+
url: 'https://www.figma.com/file/8cQcICaes5IWFubU66DMdl/Torgbox-CRM?type=design&node-id=14738-24663&mode=design&t=IrHRiRVwxfX0SzRe-4',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
play: async ({ canvasElement, step }) => {
|
|
24
|
+
const canvas = within(canvasElement);
|
|
25
|
+
const [emailWrapper, firstNameWrapper, lastNameWrapper, phoneWrapper] = Array.from(canvasElement.querySelectorAll('.text-field-wrapper'));
|
|
26
|
+
const emailInput = emailWrapper.querySelector('.text-field__input');
|
|
27
|
+
const firstNameInput = firstNameWrapper.querySelector('.text-field__input');
|
|
28
|
+
const lastNameInput = lastNameWrapper.querySelector('.text-field__input');
|
|
29
|
+
const phoneInput = phoneWrapper.querySelector('.text-field__input');
|
|
30
|
+
const submitBtn = canvasElement.querySelector('.btn');
|
|
31
|
+
const overlaySelector = '.login-page__overlay';
|
|
32
|
+
const errorBannerText = 'Ошибка регистрации';
|
|
33
|
+
const btnLoadingSelector = '.btn__filled--loading';
|
|
34
|
+
const delay = 100;
|
|
35
|
+
const checkIconId = '#check-icon';
|
|
36
|
+
const correctEmail = 'some@email.com';
|
|
37
|
+
const correctFirstName = 'Иван';
|
|
38
|
+
const correctLastName = 'Иванов';
|
|
39
|
+
const correctPhone = '9992228811';
|
|
40
|
+
const incorrectEmail = 'some-email';
|
|
41
|
+
const incorrectName = '123';
|
|
42
|
+
const incorrectPhone = '000';
|
|
43
|
+
await step('Проверяем, заблокирована ли кнопка "Подтвердить email" при незаполненных полях формы', async () => {
|
|
44
|
+
await expect(submitBtn).toBeDisabled();
|
|
45
|
+
});
|
|
46
|
+
await step('При пустом значении в поле "Email" выпадает ошибка', async () => {
|
|
47
|
+
await userEvent.click(emailInput, { delay });
|
|
48
|
+
await userEvent.click(firstNameInput, { delay });
|
|
49
|
+
await expect(canvas.getByText(emptyEmailError)).toBeInTheDocument();
|
|
50
|
+
});
|
|
51
|
+
await step('При пустом значении в поле "Имя" выпадает ошибка', async () => {
|
|
52
|
+
await userEvent.click(lastNameInput, { delay });
|
|
53
|
+
await expect(canvas.getByText(emptyFirstNameError)).toBeInTheDocument();
|
|
54
|
+
});
|
|
55
|
+
await step('При пустом значении в поле "Фамилия" выпадает ошибка', async () => {
|
|
56
|
+
await userEvent.click(phoneInput, { delay });
|
|
57
|
+
await expect(canvas.getByText(emptyLastNameError)).toBeInTheDocument();
|
|
58
|
+
});
|
|
59
|
+
await step('При пустом значении в поле "Мобильный телефон" выпадает ошибка', async () => {
|
|
60
|
+
await userEvent.click(emailInput, { delay });
|
|
61
|
+
await expect(canvas.getByText(emptyPhoneError)).toBeInTheDocument();
|
|
62
|
+
});
|
|
63
|
+
await step('При некорректном значении в поле "Email" выпадает ошибка', async () => {
|
|
64
|
+
await userEvent.type(emailInput, incorrectEmail, { delay });
|
|
65
|
+
await userEvent.click(firstNameInput, { delay });
|
|
66
|
+
await expect(canvas.getByText(notCorrectEmailError)).toBeInTheDocument();
|
|
67
|
+
});
|
|
68
|
+
await step('При корректном значении в поле "Email" появляется галочка', async () => {
|
|
69
|
+
await userEvent.clear(emailInput);
|
|
70
|
+
await userEvent.type(emailInput, correctEmail, { delay });
|
|
71
|
+
await expect(emailWrapper.querySelector(checkIconId)).toBeInTheDocument();
|
|
72
|
+
});
|
|
73
|
+
await step('При некорректном значении в поле "Имя" выпадает ошибка', async () => {
|
|
74
|
+
await userEvent.type(firstNameInput, incorrectName, { delay });
|
|
75
|
+
await userEvent.click(lastNameInput, { delay });
|
|
76
|
+
await expect(canvas.getByText(notCorrectFirstNameError)).toBeInTheDocument();
|
|
77
|
+
});
|
|
78
|
+
await step('При корректном значении в поле "Имя" появляется галочка', async () => {
|
|
79
|
+
await userEvent.clear(firstNameInput);
|
|
80
|
+
await userEvent.type(firstNameInput, correctFirstName, { delay });
|
|
81
|
+
await expect(firstNameWrapper.querySelector(checkIconId)).toBeInTheDocument();
|
|
82
|
+
});
|
|
83
|
+
await step('При некорректном значении в поле "Фамилия" выпадает ошибка', async () => {
|
|
84
|
+
await userEvent.type(lastNameInput, incorrectName, { delay });
|
|
85
|
+
await userEvent.click(phoneInput, { delay });
|
|
86
|
+
await expect(canvas.getByText(notCorrectLastNameError)).toBeInTheDocument();
|
|
87
|
+
});
|
|
88
|
+
await step('При корректном значении в поле "Фамилия" появляется галочка', async () => {
|
|
89
|
+
await userEvent.clear(lastNameInput);
|
|
90
|
+
await userEvent.type(lastNameInput, correctLastName, { delay });
|
|
91
|
+
await expect(lastNameWrapper.querySelector(checkIconId)).toBeInTheDocument();
|
|
92
|
+
});
|
|
93
|
+
await step('При некорректном значении в поле "Мобильный телефон" выпадает ошибка', async () => {
|
|
94
|
+
await userEvent.type(phoneInput, incorrectPhone, { delay });
|
|
95
|
+
await userEvent.click(emailInput, { delay });
|
|
96
|
+
await expect(canvas.getByText(notCorrectPhoneError)).toBeInTheDocument();
|
|
97
|
+
});
|
|
98
|
+
await step('При корректном значении в поле "Мобильный телефон" появляется галочка', async () => {
|
|
99
|
+
await userEvent.clear(phoneInput);
|
|
100
|
+
await userEvent.type(phoneInput, correctPhone, { delay });
|
|
101
|
+
await expect(phoneWrapper.querySelector(checkIconId)).toBeInTheDocument();
|
|
102
|
+
});
|
|
103
|
+
await step('Кнопка "Подтвердить email" доступна при всех корректно заполненных полях', async () => {
|
|
104
|
+
await expect(submitBtn).toBeEnabled();
|
|
105
|
+
});
|
|
106
|
+
await step('Кнопка "Подтвердить email" блокируется при некорректном значении любого поля', async () => {
|
|
107
|
+
await userEvent.type(emailInput, incorrectEmail, { delay });
|
|
108
|
+
await expect(submitBtn).toBeDisabled();
|
|
109
|
+
await userEvent.clear(emailInput);
|
|
110
|
+
await userEvent.type(emailInput, correctEmail, { delay });
|
|
111
|
+
await userEvent.type(firstNameInput, incorrectName, { delay });
|
|
112
|
+
await expect(submitBtn).toBeDisabled();
|
|
113
|
+
await userEvent.clear(firstNameInput);
|
|
114
|
+
await userEvent.type(firstNameInput, correctFirstName, { delay });
|
|
115
|
+
await userEvent.type(lastNameInput, incorrectName, { delay });
|
|
116
|
+
await expect(submitBtn).toBeDisabled();
|
|
117
|
+
await userEvent.clear(lastNameInput);
|
|
118
|
+
await userEvent.type(lastNameInput, correctLastName, { delay });
|
|
119
|
+
await userEvent.clear(phoneInput);
|
|
120
|
+
await userEvent.type(phoneInput, incorrectPhone, { delay });
|
|
121
|
+
await expect(submitBtn).toBeDisabled();
|
|
122
|
+
await userEvent.clear(phoneInput);
|
|
123
|
+
await userEvent.type(phoneInput, correctPhone, { delay });
|
|
124
|
+
});
|
|
125
|
+
await step('При клике на кнопку "Подтвердить email" блокируются все поля и статус кнопки меняется на loading', async () => {
|
|
126
|
+
void userEvent.click(submitBtn, { delay });
|
|
127
|
+
await waitFor(() => {
|
|
128
|
+
void expect(canvasElement.querySelector(overlaySelector)).toBeInTheDocument();
|
|
129
|
+
void expect(canvasElement.querySelector(btnLoadingSelector)).toBeInTheDocument();
|
|
130
|
+
}, { timeout: 2000 });
|
|
131
|
+
});
|
|
132
|
+
await step('При ошибке авторизации появляется баннер с ошибкой', async () => {
|
|
133
|
+
await waitFor(async () => {
|
|
134
|
+
await expect(canvas.getByText(errorBannerText)).toBeInTheDocument();
|
|
135
|
+
}, { timeout: 2000 });
|
|
136
|
+
});
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
export const Mobile = {
|
|
140
|
+
parameters: {
|
|
141
|
+
viewport: {
|
|
142
|
+
defaultViewport: 'mobile',
|
|
143
|
+
},
|
|
144
|
+
design: {
|
|
145
|
+
type: 'figma',
|
|
146
|
+
url: 'https://www.figma.com/file/8cQcICaes5IWFubU66DMdl/Torgbox-CRM?type=design&node-id=14897-8078&mode=design&t=IrHRiRVwxfX0SzRe-4',
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { RegisterPage } from './RegisterPage';
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
.register-page {
|
|
2
|
+
background-color: $surface-bright;
|
|
3
|
+
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
align-items: center;
|
|
7
|
+
|
|
8
|
+
box-sizing: border-box;
|
|
9
|
+
max-width: 400px;
|
|
10
|
+
margin: 0 auto;
|
|
11
|
+
padding: 24px 40px;
|
|
12
|
+
|
|
13
|
+
&__title {
|
|
14
|
+
margin-bottom: 32px;
|
|
15
|
+
font-size: 28px;
|
|
16
|
+
line-height: 36px;
|
|
17
|
+
color: $neutral-high;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&__form {
|
|
21
|
+
width: 100%;
|
|
22
|
+
padding-bottom: 16px;
|
|
23
|
+
display: flex;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
gap: 28px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&__footer {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-direction: column;
|
|
31
|
+
align-items: center;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&__text {
|
|
35
|
+
font-size: 12px;
|
|
36
|
+
line-height: 16px;
|
|
37
|
+
color: $neutral-low;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
&__link {
|
|
41
|
+
font-size: 14px;
|
|
42
|
+
line-height: 20px;
|
|
43
|
+
color: $primary-high;
|
|
44
|
+
|
|
45
|
+
&:hover {
|
|
46
|
+
text-decoration: underline $primary-border-low;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@media screen and (max-width: $sm) {
|
|
52
|
+
.register-page {
|
|
53
|
+
max-width: 320px;
|
|
54
|
+
padding: 24px 16px;
|
|
55
|
+
|
|
56
|
+
&__title {
|
|
57
|
+
font-size: 24px;
|
|
58
|
+
line-height: 32px;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
&__footer {
|
|
62
|
+
width: 100%;
|
|
63
|
+
flex-direction: row;
|
|
64
|
+
justify-content: space-between;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&__text {
|
|
68
|
+
font-size: 14px;
|
|
69
|
+
line-height: 20px;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useRef, useState } from 'react';
|
|
3
|
+
import ChevronLeft from '../../assets/img/chevron-left.svg';
|
|
4
|
+
import { Button, EmailField } from '../../Inputs';
|
|
5
|
+
import { Link } from '../../Utils';
|
|
6
|
+
export const ResetPasswordPage = () => {
|
|
7
|
+
const [emailValid, setEmailValid] = useState(false);
|
|
8
|
+
const emailRef = useRef('');
|
|
9
|
+
return (_jsxs("div", { className: 'reset-password-page', children: [_jsx("h1", { className: 'reset-password-page__title', children: "\u0412\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435 \u043F\u0430\u0440\u043E\u043B\u044F" }), _jsx("p", { className: 'reset-password-page__text', children: "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u0430\u0434\u0440\u0435\u0441 \u044D\u043B\u0435\u043A\u0442\u0440\u043E\u043D\u043D\u043E\u0439 \u043F\u043E\u0447\u0442\u044B, \u0441 \u043A\u043E\u0442\u043E\u0440\u044B\u043C \u0412\u044B \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043E\u0432\u0430\u043B\u0438\u0441\u044C, \u0438 \u043C\u044B \u0432\u044B\u0448\u043B\u0435\u043C \u043D\u0430 \u043D\u0435\u0433\u043E \u0438\u043D\u0441\u0442\u0440\u0443\u043A\u0446\u0438\u044E \u0434\u043B\u044F \u0432\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F \u043F\u0430\u0440\u043E\u043B\u044F." }), _jsxs("form", { className: 'reset-password-page__form', children: [_jsx(EmailField, { onTextValid: (email) => emailRef.current = email, onValidated: setEmailValid, tabIndex: 1, checkEmail: true }), _jsx(Button, { label: '\u0412\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C \u043F\u0430\u0440\u043E\u043B\u044C', state: emailValid ? 'idle' : 'disabled', size: 'large', tabIndex: 2, fullWidth: true })] }), _jsx(Link, { label: '\u0412\u0435\u0440\u043D\u0443\u0442\u044C\u0441\u044F \u043A \u043E\u043A\u043D\u0443 \u0432\u0445\u043E\u0434\u0430', iconComponent: _jsx(ChevronLeft, {}) })] }));
|
|
10
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { ResetPasswordPage } from './ResetPasswordPage';
|
|
3
|
+
declare const meta: Meta;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof ResetPasswordPage>;
|
|
6
|
+
export declare const ResetPasswordPageDesktop: Story;
|
|
7
|
+
export declare const ResetPasswordPageMobile: Story;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ResetPasswordPage } from './ResetPasswordPage';
|
|
2
|
+
const meta = {
|
|
3
|
+
component: ResetPasswordPage,
|
|
4
|
+
title: 'Pages/Authorization/ResetPasswordPage',
|
|
5
|
+
parameters: {
|
|
6
|
+
layout: 'fullscreen',
|
|
7
|
+
},
|
|
8
|
+
};
|
|
9
|
+
export default meta;
|
|
10
|
+
export const ResetPasswordPageDesktop = {
|
|
11
|
+
parameters: {
|
|
12
|
+
design: {
|
|
13
|
+
type: 'figma',
|
|
14
|
+
url: 'https://www.figma.com/file/8cQcICaes5IWFubU66DMdl/Torgbox-CRM?type=design&node-id=12659-18507&mode=design&t=hNpF3IDGWJpyx7qO-4',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
export const ResetPasswordPageMobile = {
|
|
19
|
+
parameters: {
|
|
20
|
+
viewport: {
|
|
21
|
+
defaultViewport: 'mobile',
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ResetPasswordPage } from './ResetPasswordPage';
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
$page-background: $surface-bright;
|
|
2
|
+
$text: $neutral-middle;
|
|
3
|
+
$title: $neutral-high;
|
|
4
|
+
|
|
5
|
+
.reset-password-page {
|
|
6
|
+
background-color: $page-background;
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
align-items: center;
|
|
10
|
+
gap: 16px;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
max-width: 400px;
|
|
13
|
+
margin: 0 auto;
|
|
14
|
+
padding: 24px 40px;
|
|
15
|
+
|
|
16
|
+
&__title {
|
|
17
|
+
text-align: center;
|
|
18
|
+
margin-bottom: 32px;
|
|
19
|
+
font-size: 28px;
|
|
20
|
+
line-height: 36px;
|
|
21
|
+
color: $title;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&__text {
|
|
25
|
+
color: $text;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&__form {
|
|
29
|
+
width: 100%;
|
|
30
|
+
display: flex;
|
|
31
|
+
flex-direction: column;
|
|
32
|
+
gap: 28px;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@media screen and (max-width: $sm) {
|
|
37
|
+
.reset-password-page {
|
|
38
|
+
max-width: 320px;
|
|
39
|
+
padding: 24px 16px;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { useAppDispatch } from '../../app/store';
|
|
4
|
+
import { logout } from '../../entities/user';
|
|
5
|
+
import { Button } from '../../Inputs';
|
|
6
|
+
export const StartPage = (props) => {
|
|
7
|
+
const { email } = props;
|
|
8
|
+
const dispatch = useAppDispatch();
|
|
9
|
+
const [createLoading, setCreateLoading] = useState(false);
|
|
10
|
+
const [joinLoading, setJoinLoading] = useState(false);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
setTimeout(() => {
|
|
13
|
+
setCreateLoading(false);
|
|
14
|
+
setJoinLoading(false);
|
|
15
|
+
}, 2000);
|
|
16
|
+
});
|
|
17
|
+
return (_jsxs("div", { className: 'start-page', children: [(createLoading || joinLoading) && _jsx("div", { className: 'start-page__overlay' }), _jsxs("h1", { className: 'start-page__title', children: ["\u0414\u043E\u0431\u0440\u043E \u043F\u043E\u0436\u0430\u043B\u043E\u0432\u0430\u0442\u044C!", _jsx("br", {}), "\u0427\u0442\u043E \u0436\u0435\u043B\u0430\u0435\u0442\u0435 \u0441\u0434\u0435\u043B\u0430\u0442\u044C?"] }), _jsxs("div", { className: 'start-page__text-wrapper', children: [_jsxs("p", { className: 'start-page__text', children: ["\u0412\u044B \u0432\u043E\u0448\u043B\u0438 \u043A\u0430\u043A ", _jsx("span", { className: 'start-page__email', children: email })] }), _jsx("p", { className: 'start-page__text', children: "\u0420\u044B\u0431\u0430\u0442\u0435\u043A\u0441\u0442 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442\u0441\u044F \u0434\u0438\u0437\u0430\u0439\u043D\u0435\u0440\u0430\u043C\u0438, \u043F\u0440\u043E\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u0449\u0438\u043A\u0430\u043C\u0438 \u0438 \u0444\u0440\u043E\u043D\u0442\u0435\u043D\u0434\u0435\u0440\u0430\u043C\u0438, \u043A\u043E\u0433\u0434\u0430 \u043D\u0443\u0436\u043D\u043E \u0431\u044B\u0441\u0442\u0440\u043E \u0437\u0430\u043F\u043E\u043B\u043D\u0438\u0442\u044C \u043C\u0430\u043A\u0435\u0442\u044B \u0438\u043B\u0438 \u043F\u0440\u043E\u0442\u043E\u0442\u0438\u043F\u044B." })] }), _jsx(Button, { label: '\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043A\u043E\u043C\u0430\u043D\u0434\u0443', size: 'large', state: createLoading ? 'loading' : 'idle', tabIndex: 1, onClick: () => {
|
|
18
|
+
setCreateLoading(true);
|
|
19
|
+
}, fullWidth: true }), _jsx(Button, { label: '\u0412\u0441\u0442\u0443\u043F\u0438\u0442\u044C \u0432 \u043A\u043E\u043C\u0430\u043D\u0434\u0443', size: 'large', state: joinLoading ? 'loading' : 'idle', variant: 'outlined-color', tabIndex: 2, onClick: () => {
|
|
20
|
+
setJoinLoading(true);
|
|
21
|
+
}, fullWidth: true }), _jsx(Button, { label: '\u0412\u044B\u0439\u0442\u0438 \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043C\u044B', size: 'large', variant: 'clear-neutral', tabIndex: 3, onClick: () => dispatch(logout()), fullWidth: true })] }));
|
|
22
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { StartPage } from './StartPage';
|
|
3
|
+
declare const meta: Meta;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof StartPage>;
|
|
6
|
+
export declare const StartPageDesktop: Story;
|
|
7
|
+
export declare const StartPageMobile: Story;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { expect, userEvent } from '@storybook/test';
|
|
2
|
+
import { ReduxDecorator } from '../../../.storybook/decorators';
|
|
3
|
+
import { StartPage } from './StartPage';
|
|
4
|
+
const meta = {
|
|
5
|
+
component: StartPage,
|
|
6
|
+
decorators: [ReduxDecorator],
|
|
7
|
+
title: 'Pages/StartPage',
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'fullscreen',
|
|
10
|
+
},
|
|
11
|
+
args: {
|
|
12
|
+
email: 'test@test.com'
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
export default meta;
|
|
16
|
+
export const StartPageDesktop = {
|
|
17
|
+
parameters: {
|
|
18
|
+
design: {
|
|
19
|
+
type: 'figma',
|
|
20
|
+
url: 'https://www.figma.com/file/8cQcICaes5IWFubU66DMdl/Torgbox-CRM?type=design&node-id=12659-17666&mode=design&t=JjhMuFRzcrbxwTPy-4',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
play: async ({ canvasElement, step }) => {
|
|
24
|
+
const delay = 100;
|
|
25
|
+
const createBtn = canvasElement.querySelector('.btn__filled');
|
|
26
|
+
const joinBtn = canvasElement.querySelector('.btn__outlined-color');
|
|
27
|
+
const overlaySelector = '.start-page__overlay';
|
|
28
|
+
const createBtnLoadingSelector = '.btn__filled--loading';
|
|
29
|
+
const joinBtnLoadingSelector = '.btn__outlined-color--loading';
|
|
30
|
+
await step('При клике на кнопку "Создать команду" блокируются все другие кнопки и статус кнопки меняется на loading', async () => {
|
|
31
|
+
await userEvent.click(createBtn, { delay });
|
|
32
|
+
await expect(canvasElement.querySelector(overlaySelector)).toBeInTheDocument();
|
|
33
|
+
await expect(canvasElement.querySelector(createBtnLoadingSelector)).toBeInTheDocument();
|
|
34
|
+
});
|
|
35
|
+
await step('При клике на кнопку "Вступить в команду" блокируются все другие кнопки и статус кнопки меняется на loading', async () => {
|
|
36
|
+
await userEvent.click(joinBtn, { delay });
|
|
37
|
+
await expect(canvasElement.querySelector(overlaySelector)).toBeInTheDocument();
|
|
38
|
+
await expect(canvasElement.querySelector(joinBtnLoadingSelector)).toBeInTheDocument();
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
export const StartPageMobile = {
|
|
43
|
+
parameters: {
|
|
44
|
+
viewport: {
|
|
45
|
+
defaultViewport: 'mobile',
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { StartPage } from './StartPage';
|