From 4cf62d87a87fe07e5e972ede1364262f352e36da Mon Sep 17 00:00:00 2001 From: Safronov Date: Mon, 6 Apr 2026 15:56:24 +0300 Subject: [PATCH 01/10] Add toggle button for password, little style for btn showPassword, moved to separate fail - url --- src/api/url.js | 1 + src/components/Authorization.tsx | 60 ++++++++++++++---------- src/components/authorization.module.scss | 20 +++++++- 3 files changed, 55 insertions(+), 26 deletions(-) create mode 100644 src/api/url.js diff --git a/src/api/url.js b/src/api/url.js new file mode 100644 index 0000000..fcd33c6 --- /dev/null +++ b/src/api/url.js @@ -0,0 +1 @@ +export const url = `http://localhost:3000`; diff --git a/src/components/Authorization.tsx b/src/components/Authorization.tsx index 0dc8069..b968504 100644 --- a/src/components/Authorization.tsx +++ b/src/components/Authorization.tsx @@ -2,16 +2,16 @@ import { useForm } from 'react-hook-form'; import { ErrorMessage } from '@hookform/error-message'; import { useState } from 'react'; import styles from './authorization.module.scss'; -import photo from '../assets/hidepassword.svg'; +import { url } from '../api/url'; + interface UserLogin { name: string; password: string; } -const URL = `http://localhost:3000`; - function Authorization() { const [error, setError] = useState(''); + const [showPassword, setShowPassword] = useState(false); const { register, @@ -26,9 +26,11 @@ function Authorization() { }, }); + const togglePassword = () => setShowPassword((prev) => !prev); + const onSubmit = async (data: UserLogin) => { try { - const response = await fetch(`${URL}/login`, { + const response = await fetch(`${url}/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: data.name, password: data.password }), @@ -43,7 +45,6 @@ function Authorization() { reset(); setError(''); } catch (error) { - console.error('Ошибка при логине:', error); setError(error.message); } }; @@ -57,7 +58,7 @@ function Authorization() {
diff --git a/src/components/authorization.module.scss b/src/components/authorization.module.scss index a09cba1..21dddc2 100644 --- a/src/components/authorization.module.scss +++ b/src/components/authorization.module.scss @@ -29,9 +29,11 @@ } .passwordIcon{ + border: none; + background: none; position: absolute; top: 4px; - right: 5px; + right: 0px; stroke:#727272; fill: none; transition: all .2s ease-in-out; @@ -40,4 +42,20 @@ cursor: pointer; stroke:red; } +} + +.passwordIconActive{ + border: none; + background: none; + position: absolute; + top: 4px; + right: 0px; + stroke:red; + fill: none; + transition: all .2s ease-in-out; + + &:hover{ + cursor: pointer; + stroke:727272; + } } \ No newline at end of file From 2bb54abb4e0081fdff612e6902978adf9564808f Mon Sep 17 00:00:00 2001 From: Safronov Date: Tue, 7 Apr 2026 17:02:22 +0300 Subject: [PATCH 02/10] Add registration form, styles, and extract components --- src/App.tsx | 5 +- src/components/Authorization.tsx | 148 ----------------- .../authorization/Authorization.tsx | 151 ++++++++++++++++++ .../authorization.module.scss | 48 +++++- src/components/authorization/index.tsx | 1 + src/components/emailInput/EmailInput.tsx | 38 +++++ src/components/emailInput/index.tsx | 1 + src/components/nameInput/NameInput.tsx | 42 +++++ src/components/nameInput/index.tsx | 1 + .../PasswordConfirmInput.tsx | 106 ++++++++++++ src/components/passwordConfirmInput/index.tsx | 1 + .../passwordInput/PasswordInput.tsx | 51 ++++++ src/components/passwordInput/index.tsx | 1 + src/components/registration/Registration.tsx | 93 +++++++++++ src/components/registration/index.tsx | 1 + .../registration/registration.module.scss | 126 +++++++++++++++ src/index.css | 4 +- 17 files changed, 663 insertions(+), 155 deletions(-) delete mode 100644 src/components/Authorization.tsx create mode 100644 src/components/authorization/Authorization.tsx rename src/components/{ => authorization}/authorization.module.scss (59%) create mode 100644 src/components/authorization/index.tsx create mode 100644 src/components/emailInput/EmailInput.tsx create mode 100644 src/components/emailInput/index.tsx create mode 100644 src/components/nameInput/NameInput.tsx create mode 100644 src/components/nameInput/index.tsx create mode 100644 src/components/passwordConfirmInput/PasswordConfirmInput.tsx create mode 100644 src/components/passwordConfirmInput/index.tsx create mode 100644 src/components/passwordInput/PasswordInput.tsx create mode 100644 src/components/passwordInput/index.tsx create mode 100644 src/components/registration/Registration.tsx create mode 100644 src/components/registration/index.tsx create mode 100644 src/components/registration/registration.module.scss diff --git a/src/App.tsx b/src/App.tsx index e5fa125..eb299b7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,9 +1,10 @@ -import Authorization from './components/Authorization'; +// import { Authorization } from './components/authorization'; +import { Registration } from './components/registration'; function App() { return (
- +
); } diff --git a/src/components/Authorization.tsx b/src/components/Authorization.tsx deleted file mode 100644 index b968504..0000000 --- a/src/components/Authorization.tsx +++ /dev/null @@ -1,148 +0,0 @@ -import { useForm } from 'react-hook-form'; -import { ErrorMessage } from '@hookform/error-message'; -import { useState } from 'react'; -import styles from './authorization.module.scss'; -import { url } from '../api/url'; - -interface UserLogin { - name: string; - password: string; -} - -function Authorization() { - const [error, setError] = useState(''); - const [showPassword, setShowPassword] = useState(false); - - const { - register, - handleSubmit, - reset, - formState: { errors }, - } = useForm({ - mode: 'onChange', - defaultValues: { - name: '', - password: '', - }, - }); - - const togglePassword = () => setShowPassword((prev) => !prev); - - const onSubmit = async (data: UserLogin) => { - try { - const response = await fetch(`${url}/login`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ name: data.name, password: data.password }), - }); - - const responseData = await response.json(); - - if (!response.ok) { - throw new Error(responseData.message || 'Ошибка входа'); - } - localStorage.setItem('token', responseData.token); - reset(); - setError(''); - } catch (error) { - setError(error.message); - } - }; - - return ( -
-
-

ВХОД

- {error &&

{error}

} -
-
-
- - {message}} - /> -
- -
- - -
- -
-
- ); -} - -export default Authorization; diff --git a/src/components/authorization/Authorization.tsx b/src/components/authorization/Authorization.tsx new file mode 100644 index 0000000..8ba9a4d --- /dev/null +++ b/src/components/authorization/Authorization.tsx @@ -0,0 +1,151 @@ +import { useState } from 'react'; +import { url } from '../../api/url'; +import { useForm } from 'react-hook-form'; +import { ErrorMessage } from '@hookform/error-message'; +import styles from './authorization.module.scss'; + +interface UserLogin { + name: string; + password: string; +} + +function Authorization() { + const [error, setError] = useState(''); + const [showPassword, setShowPassword] = useState(false); + + const { + register, + handleSubmit, + reset, + formState: { errors }, + } = useForm({ + mode: 'onChange', + defaultValues: { + name: '', + password: '', + }, + }); + + const togglePassword = () => setShowPassword((prev) => !prev); + + const onSubmit = async (data: UserLogin) => { + try { + const response = await fetch(`${url}/login`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ name: data.name, password: data.password }), + }); + + const responseData = await response.json(); + + if (!response.ok) { + throw new Error(responseData.message || 'Ошибка входа'); + } + localStorage.setItem('token', responseData.token); + reset(); + setError(''); + } catch (error) { + setError(error.message); + } + }; + + return ( +
+
+

ВХОД

+ {error &&

{error}

} +
+
+
+ + + {message}} + /> +
+ +
+ +
+ +
+
+ ); +} + +export default Authorization; diff --git a/src/components/authorization.module.scss b/src/components/authorization/authorization.module.scss similarity index 59% rename from src/components/authorization.module.scss rename to src/components/authorization/authorization.module.scss index 21dddc2..cf00204 100644 --- a/src/components/authorization.module.scss +++ b/src/components/authorization/authorization.module.scss @@ -1,3 +1,16 @@ +.form{ + width: 250px; +} + + +input{ + outline: none; + outline: none; + font-size: 16; + color: black; + padding: 10px; + border-radius: 5px; +} .wrapperHeader{ position: relative; display: inline-block; @@ -24,15 +37,27 @@ color: red; } -.password{ +.span{ + display: inline-block; + margin-bottom: 5px; +} + +.password, .name{ + width: 250px; + +} + +.labelPassword,.labelName { position: relative; + display: flex; + flex-direction: column; } .passwordIcon{ border: none; background: none; position: absolute; - top: 4px; + bottom: 6px; right: 0px; stroke:#727272; fill: none; @@ -48,7 +73,7 @@ border: none; background: none; position: absolute; - top: 4px; + bottom: 6px; right: 0px; stroke:red; fill: none; @@ -58,4 +83,21 @@ cursor: pointer; stroke:727272; } +} + +.btnIn{ + cursor: pointer; + border: none; + color: #fff; + background: #000; + padding: 10px; + border-radius: 10px; + transition: all .2s ease-in; + + + &:hover{ + background: #cbcbcb; + color: #000; + z-index: 100; + } } \ No newline at end of file diff --git a/src/components/authorization/index.tsx b/src/components/authorization/index.tsx new file mode 100644 index 0000000..4334e2e --- /dev/null +++ b/src/components/authorization/index.tsx @@ -0,0 +1 @@ +export { default as Authorization } from './Authorization'; diff --git a/src/components/emailInput/EmailInput.tsx b/src/components/emailInput/EmailInput.tsx new file mode 100644 index 0000000..1751a01 --- /dev/null +++ b/src/components/emailInput/EmailInput.tsx @@ -0,0 +1,38 @@ +import { ErrorMessage } from '@hookform/error-message'; + +interface PropsDate { + register: any; + errors: any; + styles: any; +} + +function EmailInput({ register, errors, styles }: PropsDate) { + return ( +
+ + + ( + {message} + )} + /> +
+ ); +} + +export default EmailInput; diff --git a/src/components/emailInput/index.tsx b/src/components/emailInput/index.tsx new file mode 100644 index 0000000..b057f63 --- /dev/null +++ b/src/components/emailInput/index.tsx @@ -0,0 +1 @@ +export { default as EmailInput } from './EmailInput'; diff --git a/src/components/nameInput/NameInput.tsx b/src/components/nameInput/NameInput.tsx new file mode 100644 index 0000000..74b0160 --- /dev/null +++ b/src/components/nameInput/NameInput.tsx @@ -0,0 +1,42 @@ +import { ErrorMessage } from '@hookform/error-message'; + +interface PropsDate { + register: any; + errors: any; + styles: any; +} + +function NameInput({ register, errors, styles }: PropsDate) { + return ( +
+ + + ( + {message} + )} + /> +
+ ); +} + +export default NameInput; diff --git a/src/components/nameInput/index.tsx b/src/components/nameInput/index.tsx new file mode 100644 index 0000000..864afb0 --- /dev/null +++ b/src/components/nameInput/index.tsx @@ -0,0 +1 @@ +export { default as NameInput } from './NameInput'; diff --git a/src/components/passwordConfirmInput/PasswordConfirmInput.tsx b/src/components/passwordConfirmInput/PasswordConfirmInput.tsx new file mode 100644 index 0000000..98e4dc7 --- /dev/null +++ b/src/components/passwordConfirmInput/PasswordConfirmInput.tsx @@ -0,0 +1,106 @@ +import { ErrorMessage } from '@hookform/error-message'; + +interface PropsDate { + register: any; + errors: any; + showPassword: any; + styles: any; + togglePassword: any; + watch: any; +} +function PasswordConfirmInput({ + register, + errors, + togglePassword, + watch, + styles, + showPassword, +}: PropsDate) { + return ( +
+ + + ( +

+ {message} +

+ )} + /> +
+ ); +} + +export default PasswordConfirmInput; diff --git a/src/components/passwordConfirmInput/index.tsx b/src/components/passwordConfirmInput/index.tsx new file mode 100644 index 0000000..37ae342 --- /dev/null +++ b/src/components/passwordConfirmInput/index.tsx @@ -0,0 +1 @@ +export { default as PasswordConfirmInput } from './PasswordConfirmInput'; diff --git a/src/components/passwordInput/PasswordInput.tsx b/src/components/passwordInput/PasswordInput.tsx new file mode 100644 index 0000000..52699f7 --- /dev/null +++ b/src/components/passwordInput/PasswordInput.tsx @@ -0,0 +1,51 @@ +import { ErrorMessage } from '@hookform/error-message'; + +interface PropsDate { + register: any; + errors: any; + showPassword: any; + styles: any; +} + +function passwordInput({ register, errors, styles, showPassword }: PropsDate) { + return ( +
+ + + ( +

+ {message} +

+ )} + /> +
+ ); +} + +export default passwordInput; diff --git a/src/components/passwordInput/index.tsx b/src/components/passwordInput/index.tsx new file mode 100644 index 0000000..c281b2c --- /dev/null +++ b/src/components/passwordInput/index.tsx @@ -0,0 +1 @@ +export { default as PasswordInput } from './passwordInput'; diff --git a/src/components/registration/Registration.tsx b/src/components/registration/Registration.tsx new file mode 100644 index 0000000..fb1d9f5 --- /dev/null +++ b/src/components/registration/Registration.tsx @@ -0,0 +1,93 @@ +import { useCallback, useState } from 'react'; +import { url } from '../../api/url'; +import { useForm } from 'react-hook-form'; + +import { EmailInput } from '../emailInput'; +import { PasswordInput } from '../passwordInput'; +import { NameInput } from '../nameInput'; +import { PasswordConfirmInput } from '../passwordConfirmInput'; +import styles from './registration.module.scss'; + +interface UserLogin { + name: string; + password: string; + email: string; + passwordConfirm: string; +} + +function Registration() { + const [showPassword, setShowPassword] = useState(false); + + const { + register, + handleSubmit, + reset, + watch, + formState: { errors }, + } = useForm({ + mode: 'onChange', + defaultValues: { + name: '', + password: '', + email: '', + passwordConfirm: '', + }, + }); + + const togglePassword = useCallback( + () => setShowPassword((prev) => !prev), + [showPassword], + ); + + const onSubmit = async (data: UserLogin) => { + try { + const response = await fetch(`${url}/login`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ name: data.name, password: data.password }), + }); + + const responseData = await response.json(); + + if (!response.ok) { + throw new Error(responseData.message || 'Ошибка входа'); + } + localStorage.setItem('token', responseData.token); + reset(); + setError(''); + } catch (error) { + setError(error.message); + } + }; + + return ( +
+

Регистрация

+ +
+ + + + + + + +
+ ); +} + +export default Registration; diff --git a/src/components/registration/index.tsx b/src/components/registration/index.tsx new file mode 100644 index 0000000..23c7d57 --- /dev/null +++ b/src/components/registration/index.tsx @@ -0,0 +1 @@ +export { default as Registration } from './Registration'; diff --git a/src/components/registration/registration.module.scss b/src/components/registration/registration.module.scss new file mode 100644 index 0000000..8ce68de --- /dev/null +++ b/src/components/registration/registration.module.scss @@ -0,0 +1,126 @@ + +.form{ + width: 250px; + display: none; +} + +.block{ + position: relative; +} + +input{ + outline: none; + outline: none; + font-size: 16; + color: black; + padding: 10px; + border-radius: 5px; +} +.wrapperHeader{ + position: relative; + display: inline-block; + text-align: center; + margin-bottom: 20px; + width: 250px; +} +.title{ + color:#000; + width: 100%; + font-size: 30px; + text-align: center; + font-weight: 300; + margin-bottom: 20px; +} + + +.passwordConfirm{ + margin-bottom: 15px; +} +.errorPasswordConfirm{ + position: absolute; + left: 0; + bottom: -16px; + color: red; + font-size: 13px; + display: inline-flex; +} +.errorPassword{ + position: relative; + color: red; + font-size: 13px; + display: inline-flex; +} + +.error{ + position: absolute; + left: 0; + bottom: -18px; + color: red; + font-size: 13px; + display: inline-flex; +} + +.span{ + display: inline-block; + margin-bottom: 5px; +} + +.password, .name{ + width: 250px; + +} + +.label { + position: relative; + display: flex; + flex-direction: column; +} + +.passwordIcon{ + border: none; + background: none; + position: absolute; + bottom: 6px; + right: 0px; + stroke:#727272; + fill: none; + transition: all .2s ease-in-out; + + &:hover{ + cursor: pointer; + stroke:red; + } +} + +.passwordIconActive{ + border: none; + background: none; + position: absolute; + bottom: 6px; + right: 0px; + stroke:red; + fill: none; + transition: all .2s ease-in-out; + + &:hover{ + cursor: pointer; + stroke:727272; + } +} + +.btnIn{ + cursor: pointer; + border: none; + color: #fff; + background: #000; + padding: 10px; + border-radius: 10px; + transition: all .2s ease-in; + + + &:hover{ + background: #cbcbcb; + color: #000; + z-index: 100; + } +} \ No newline at end of file diff --git a/src/index.css b/src/index.css index 6884284..213a9f9 100644 --- a/src/index.css +++ b/src/index.css @@ -37,11 +37,11 @@ body{ position: relative; } -.error{ +/* .error{ position: absolute; left: 0; bottom: -30px; font-size: 13px; display: inline-flex; color: red; -} \ No newline at end of file +} */ \ No newline at end of file From e0dc757bcbe04754fcb723c0a6792ae5ab0e91c9 Mon Sep 17 00:00:00 2001 From: Safronov Date: Thu, 9 Apr 2026 16:50:13 +0300 Subject: [PATCH 03/10] Revert component decomposition for registration form; add server registration logic --- server/package-lock.json | 35 +++ server/package.json | 1 + server/server.js | 55 ++++- src/App.tsx | 6 +- .../authorization/Authorization.tsx | 21 +- .../authorization/authorization.module.scss | 26 ++- src/components/emailInput/EmailInput.tsx | 38 --- src/components/emailInput/index.tsx | 1 - src/components/nameInput/NameInput.tsx | 42 ---- src/components/nameInput/index.tsx | 1 - .../PasswordConfirmInput.tsx | 106 --------- src/components/passwordConfirmInput/index.tsx | 1 - .../passwordInput/PasswordInput.tsx | 51 ---- src/components/passwordInput/index.tsx | 1 - src/components/registration/Registration.tsx | 218 +++++++++++++++--- .../registration/registration.module.scss | 6 +- 16 files changed, 313 insertions(+), 296 deletions(-) delete mode 100644 src/components/emailInput/EmailInput.tsx delete mode 100644 src/components/emailInput/index.tsx delete mode 100644 src/components/nameInput/NameInput.tsx delete mode 100644 src/components/nameInput/index.tsx delete mode 100644 src/components/passwordConfirmInput/PasswordConfirmInput.tsx delete mode 100644 src/components/passwordConfirmInput/index.tsx delete mode 100644 src/components/passwordInput/PasswordInput.tsx delete mode 100644 src/components/passwordInput/index.tsx diff --git a/server/package-lock.json b/server/package-lock.json index fb578d9..d54b40b 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "bcrypt": "^6.0.0", "bcryptjs": "^3.0.3", "jsonwebtoken": "^9.0.3" }, @@ -44,6 +45,20 @@ "undici-types": "~7.18.0" } }, + "node_modules/bcrypt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-6.0.0.tgz", + "integrity": "sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^8.3.0", + "node-gyp-build": "^4.8.4" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/bcryptjs": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.3.tgz", @@ -159,6 +174,26 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/node-addon-api": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.7.0.tgz", + "integrity": "sha512-9MdFxmkKaOYVTV+XVRG8ArDwwQ77XIgIPyKASB1k3JPq3M8fGQQQE3YpMOrKm6g//Ktx8ivZr8xo1Qmtqub+GA==", + "license": "MIT", + "engines": { + "node": "^18 || ^20 || >= 21" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", diff --git a/server/package.json b/server/package.json index 8cae84e..930f919 100644 --- a/server/package.json +++ b/server/package.json @@ -11,6 +11,7 @@ "license": "ISC", "type": "commonjs", "dependencies": { + "bcrypt": "^6.0.0", "bcryptjs": "^3.0.3", "jsonwebtoken": "^9.0.3" }, diff --git a/server/server.js b/server/server.js index 33f4713..edabd75 100644 --- a/server/server.js +++ b/server/server.js @@ -1,6 +1,7 @@ const http = require('http'); const jwt = require('jsonwebtoken'); +const bcrypt = require('bcrypt'); const JWT_SECRET = 'my_super_secret_key'; const PORT = 3000; @@ -9,12 +10,11 @@ const users = [ { id: 1, name: 'Alex', + email: 'test@mail.ru', password: '123456', }, ]; -console.log(users); - function parseBody(req) { return new Promise((resolve, reject) => { let body = ''; @@ -58,8 +58,57 @@ const server = http.createServer(async (req, res) => { }); sendJSON(res, 200, { token }); } else { - sendJSON(res, 401, { message: 'Неверный email or пароль' }); + sendJSON(res, 401, { message: 'Неверный email или пароль' }); + } + return; + } + + if (req.method === 'POST' && req.url === '/registration') { + const { name, email, password } = await parseBody(req); + + if (!name || !email || !password) { + return sendJSON(res, 400, { message: 'Необходимо заполнить все поля' }); } + + const findName = users.find((u) => u.name === name); + const findEmail = users.find((u) => u.email === email); + + if (findName) { + sendJSON(res, 409, { + message: 'Пользователь с таким именем уже существует', + }); + } + + if (findEmail) { + sendJSON(res, 409, { + message: 'Пользователь с таким email уже существует', + }); + } + + const hashedPassword = await bcrypt.hash(password, 10); + + const newUser = { + id: Date.now(), + name, + email, + password: hashedPassword, + }; + + const token = jwt.sign( + { + id: newUser.id, + name: newUser.name, + email: newUser.email, + }, + JWT_SECRET, + { expiresIn: '1h' }, + ); + + sendJSON(res, 201, { + message: 'Регистрация прошла успешно', + token, + user: { id: newUser.id, name: newUser.name, email: newUser.email }, + }); return; } diff --git a/src/App.tsx b/src/App.tsx index eb299b7..13d8bb7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,10 +1,10 @@ -// import { Authorization } from './components/authorization'; -import { Registration } from './components/registration'; +import { Authorization } from './components/authorization'; +// import { Registration } from './components/registration'; function App() { return (
- +
); } diff --git a/src/components/authorization/Authorization.tsx b/src/components/authorization/Authorization.tsx index 8ba9a4d..b3d81c5 100644 --- a/src/components/authorization/Authorization.tsx +++ b/src/components/authorization/Authorization.tsx @@ -1,7 +1,8 @@ -import { useState } from 'react'; +import { useCallback, useState } from 'react'; import { url } from '../../api/url'; import { useForm } from 'react-hook-form'; import { ErrorMessage } from '@hookform/error-message'; + import styles from './authorization.module.scss'; interface UserLogin { @@ -26,7 +27,10 @@ function Authorization() { }, }); - const togglePassword = () => setShowPassword((prev) => !prev); + const togglePassword = useCallback( + () => setShowPassword((prev) => !prev), + [], + ); const onSubmit = async (data: UserLogin) => { try { @@ -41,6 +45,7 @@ function Authorization() { if (!response.ok) { throw new Error(responseData.message || 'Ошибка входа'); } + console.log(data); localStorage.setItem('token', responseData.token); reset(); setError(''); @@ -55,9 +60,9 @@ function Authorization() {

ВХОД

{error &&

{error}

} -
-
-