Регистрация и вход работают
This commit is contained in:
parent
5be5bb06bb
commit
0abb511375
126
cucumber-frontend/package-lock.json
generated
126
cucumber-frontend/package-lock.json
generated
@ -15,9 +15,11 @@
|
||||
"@types/node": "^16.18.115",
|
||||
"@types/react": "^18.3.12",
|
||||
"antd": "^5.21.6",
|
||||
"axios": "^1.7.7",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.27.0",
|
||||
"react-scripts": "^5.0.1",
|
||||
"typescript": "^4.9.5",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
@ -3392,6 +3394,15 @@
|
||||
"react-dom": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.20.0.tgz",
|
||||
"integrity": "sha512-mUnk8rPJBI9loFDZ+YzPGdeniYK+FTmRD1TMCz7ev2SNIozyKKpnGgsxO34u6Z4z/t0ITuu7voi/AshfsGsgFg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-babel": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
|
||||
@ -3760,16 +3771,6 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@testing-library/dom/node_modules/aria-query": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
|
||||
"integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"dequal": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@testing-library/jest-dom": {
|
||||
"version": "5.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz",
|
||||
@ -4105,9 +4106,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "16.18.115",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.115.tgz",
|
||||
"integrity": "sha512-NF5ajYn+dq0tRfswdyp8Df75h7D9z+L8TCIwrXoh46ZLK6KZVXkRhf/luXaZytvm/keUo9vU4m1Bg39St91a5w==",
|
||||
"version": "16.18.116",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.116.tgz",
|
||||
"integrity": "sha512-mLigUvhoaADRewggiby+XfAAFOUOMCm/SwL5DAJ+CMUGjSLIGMsJVN7BOKftuQSHGjUmS/W7hVht8fcNbi/MRA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node-forge": {
|
||||
@ -5014,12 +5015,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/aria-query": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz",
|
||||
"integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==",
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
|
||||
"integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
"dependencies": {
|
||||
"dequal": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/array-buffer-byte-length": {
|
||||
@ -5308,6 +5309,17 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.7.7",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
|
||||
"integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/axobject-query": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
|
||||
@ -5850,9 +5862,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001673",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001673.tgz",
|
||||
"integrity": "sha512-WTrjUCSMp3LYX0nE12ECkV0a+e6LC85E0Auz75555/qr78Oc8YWhEPNfDd6SHdtlCMSzqtuXY0uyEMNRcsKpKw==",
|
||||
"version": "1.0.30001675",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001675.tgz",
|
||||
"integrity": "sha512-/wV1bQwPrkLiQMjaJF5yUMVM/VdRPOCU8QZ+PmG6uW6DvYSrNY1bpwHI/3mOcUosLaJCzYDi5o91IQB51ft6cg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@ -7001,7 +7013,6 @@
|
||||
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
||||
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
@ -7864,6 +7875,15 @@
|
||||
"eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz",
|
||||
"integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-react": {
|
||||
"version": "7.37.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.2.tgz",
|
||||
@ -8775,9 +8795,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.2.tgz",
|
||||
"integrity": "sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ==",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
|
||||
"integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
@ -11301,6 +11321,20 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/jsdom/node_modules/form-data": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.2.tgz",
|
||||
"integrity": "sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsesc": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
|
||||
@ -13994,6 +14028,12 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/psl": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
|
||||
@ -14910,6 +14950,38 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.27.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.27.0.tgz",
|
||||
"integrity": "sha512-YA+HGZXz4jaAkVoYBE98VQl+nVzI+cVI2Oj/06F5ZM+0u3TgedN9Y9kmMRo2mnkSK2nCpNQn0DVob4HCsY/WLw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.20.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "6.27.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.27.0.tgz",
|
||||
"integrity": "sha512-+bvtFWMC0DgAFrfKXKG9Fc+BcXWRUO1aJIihbB79xaeq0v5UzfvnM5houGUm1Y461WVRcgAQ+Clh5rdb1eCx4g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.20.0",
|
||||
"react-router": "6.27.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8",
|
||||
"react-dom": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-scripts": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
|
||||
|
@ -10,9 +10,11 @@
|
||||
"@types/node": "^16.18.115",
|
||||
"@types/react": "^18.3.12",
|
||||
"antd": "^5.21.6",
|
||||
"axios": "^1.7.7",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.27.0",
|
||||
"react-scripts": "^5.0.1",
|
||||
"typescript": "^4.9.5",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
|
62
cucumber-frontend/src/API/api.ts
Normal file
62
cucumber-frontend/src/API/api.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import axios, { AxiosError, AxiosRequestHeaders } from 'axios';
|
||||
import IUser from '../models/IUser';
|
||||
import IFarm from '../models/IFarm';
|
||||
import LoginRequest from '../Requests/LoginRequest';
|
||||
import IRegisterRequest from '../Requests/RegisterRequest';
|
||||
|
||||
const API_BASE_URL = 'https://localhost:7113/api';
|
||||
|
||||
const getHeaders = (): { [key: string]: string } => {
|
||||
return {
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
};
|
||||
export const getFarms = async (): Promise<IFarm[]> => {
|
||||
try {
|
||||
const response = await axios.get(`${API_BASE_URL}/farms`, { headers: getHeaders() });
|
||||
return response.data;
|
||||
} catch (error: unknown) {
|
||||
const axiosError = error as AxiosError;
|
||||
console.error('Error fetching farms:', axiosError.message);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const getUser = async (userId: number): Promise<IUser> => {
|
||||
try {
|
||||
const response = await axios.get(`${API_BASE_URL}/Auth/user/${userId}`, { headers: getHeaders() });
|
||||
return response.data;
|
||||
} catch (error: unknown) {
|
||||
const axiosError = error as AxiosError;
|
||||
console.error('Error fetching user:', axiosError.message);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const createUser = async (userData: IRegisterRequest): Promise<IUser> => {
|
||||
try {
|
||||
const response = await axios.post(`${API_BASE_URL}/Auth/register`, userData, { headers: getHeaders() });
|
||||
return response.data;
|
||||
} catch (error: unknown) {
|
||||
const axiosError = error as AxiosError;
|
||||
console.error('Error creating user:', axiosError.message);
|
||||
if (axiosError.response) {
|
||||
// Логируем дополнительные данные об ошибке
|
||||
console.error('Response data:', axiosError.response.data);
|
||||
console.error('Response status:', axiosError.response.status);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export const loginUser = async (userData: LoginRequest): Promise<string> => {
|
||||
try {
|
||||
const response = await axios.post(`${API_BASE_URL}/Auth/login`, userData, { headers: getHeaders() });
|
||||
return response.data; // JWT токен
|
||||
} catch (error: unknown) {
|
||||
const axiosError = error as AxiosError;
|
||||
console.error('Error logging in:', axiosError.message);
|
||||
throw error;
|
||||
}
|
||||
};
|
@ -1,11 +1,20 @@
|
||||
import React from 'react';
|
||||
import './App.css';
|
||||
import { Routes } from 'react-router-dom';
|
||||
import { Navigate, Route, Routes } from 'react-router-dom';
|
||||
import {LoginPage} from './pages/Login';
|
||||
import {RegisterPage} from './pages/Register';
|
||||
import {AppLayout} from './components/Layout';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="App">
|
||||
<Routes>
|
||||
<Route path="/" element={<AppLayout />}>
|
||||
<Route index element={<Navigate to="/login" />} />
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
<Route path="/register" element={<RegisterPage />} />
|
||||
</Route>
|
||||
|
||||
</Routes>
|
||||
</div>
|
||||
);
|
||||
|
6
cucumber-frontend/src/Requests/LoginRequest.ts
Normal file
6
cucumber-frontend/src/Requests/LoginRequest.ts
Normal file
@ -0,0 +1,6 @@
|
||||
interface ILoginRequest {
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export default ILoginRequest;
|
7
cucumber-frontend/src/Requests/RegisterRequest.ts
Normal file
7
cucumber-frontend/src/Requests/RegisterRequest.ts
Normal file
@ -0,0 +1,7 @@
|
||||
interface IRegisterRequest {
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export default IRegisterRequest;
|
8
cucumber-frontend/src/components/Footer.tsx
Normal file
8
cucumber-frontend/src/components/Footer.tsx
Normal file
@ -0,0 +1,8 @@
|
||||
export function Footer () {
|
||||
return (
|
||||
<footer className="footer">
|
||||
<p>© {new Date().getFullYear()} Cucumber</p>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
|
22
cucumber-frontend/src/components/Header.tsx
Normal file
22
cucumber-frontend/src/components/Header.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export function Header () {
|
||||
return (
|
||||
<header className="header">
|
||||
<div className="logo">
|
||||
<Link to="/">Cucumber App</Link>
|
||||
</div>
|
||||
<nav className="nav">
|
||||
<ul>
|
||||
<li>
|
||||
<Link to="/login">Login</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/register">Register</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
);
|
||||
};
|
19
cucumber-frontend/src/components/Layout.tsx
Normal file
19
cucumber-frontend/src/components/Layout.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
import { Layout } from 'antd';
|
||||
import { Outlet } from 'react-router-dom';
|
||||
import {Header} from './Header';
|
||||
import {Footer} from './Footer';
|
||||
|
||||
export function AppLayout () {
|
||||
return (
|
||||
<Layout>
|
||||
<Header />
|
||||
<Layout.Content>
|
||||
<Outlet />
|
||||
</Layout.Content>
|
||||
<Footer />
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
export default AppLayout;
|
@ -11,3 +11,27 @@ code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
|
||||
header {
|
||||
text-align: center;
|
||||
background-color: #282c34;
|
||||
min-height: 10vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: white;
|
||||
}
|
||||
|
||||
footer {
|
||||
text-align: center;
|
||||
background-color: #282c34;
|
||||
min-height: 10vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: white;
|
||||
}
|
11
cucumber-frontend/src/models/IFarm.tsx
Normal file
11
cucumber-frontend/src/models/IFarm.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
import type IUser from "./IUser";
|
||||
|
||||
interface IFarm {
|
||||
id: string;
|
||||
name: string;
|
||||
userId: number;
|
||||
user: IUser | null;
|
||||
rasberryMacAddr: string;
|
||||
}
|
||||
|
||||
export default IFarm;
|
11
cucumber-frontend/src/models/IUser.tsx
Normal file
11
cucumber-frontend/src/models/IUser.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
import type IFarm from "./IFarm";
|
||||
|
||||
interface IUser {
|
||||
id: number;
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
farms: IFarm[];
|
||||
}
|
||||
|
||||
export default IUser
|
66
cucumber-frontend/src/pages/Login.tsx
Normal file
66
cucumber-frontend/src/pages/Login.tsx
Normal file
@ -0,0 +1,66 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { Button, Form, Input } from 'antd';
|
||||
import { loginUser } from '../API/api';
|
||||
import ILoginRequest from '../Requests/LoginRequest';
|
||||
|
||||
export function LoginPage () {
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const navigate = useNavigate();
|
||||
|
||||
const onFinish = async () => {
|
||||
// Создаём объект с данными для отправки на сервер
|
||||
const userData: ILoginRequest = {
|
||||
email,
|
||||
password,
|
||||
};
|
||||
|
||||
try {
|
||||
const token = await loginUser(userData);
|
||||
// Сохраняем токен
|
||||
localStorage.setItem('token', token);
|
||||
alert('Вы успешно вошли в систему!');
|
||||
navigate('/'); // Перенаправляем на главную страницу
|
||||
} catch (error) {
|
||||
console.error('Error logging in:', error);
|
||||
alert('Ошибка при входе в систему. Проверьте введенные данные.');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="login-page">
|
||||
<h1>Login</h1>
|
||||
<Form onFinish={onFinish}>
|
||||
<Form.Item
|
||||
label="Email"
|
||||
name="email"
|
||||
rules={[{ required: true, type: 'email', message: 'Пожалуйста, введите корректный email!' }]}
|
||||
>
|
||||
<Input value={email} onChange={e => setEmail(e.target.value)} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="Password"
|
||||
name="password"
|
||||
rules={[{ required: true, min: 8, message: 'Пароль должен содержать не менее 8 символов!' }]}
|
||||
>
|
||||
<Input
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={e => setPassword(e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Button type="primary" htmlType="submit">
|
||||
Войти
|
||||
</Button>
|
||||
</Form.Item>
|
||||
<p>
|
||||
Нет аккаунта? <Link to="/register">Зарегистрируйтесь</Link>
|
||||
</p>
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoginPage;
|
70
cucumber-frontend/src/pages/Register.tsx
Normal file
70
cucumber-frontend/src/pages/Register.tsx
Normal file
@ -0,0 +1,70 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { Button, Form, Input } from 'antd';
|
||||
import { createUser } from '../API/api';
|
||||
import IRegisterRequest from '../Requests/RegisterRequest';
|
||||
|
||||
export function RegisterPage () {
|
||||
const [name, setName] = useState('');
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleFinish = async () => {
|
||||
// Create the user data object to send to the API
|
||||
const userData: IRegisterRequest = {
|
||||
name,
|
||||
email,
|
||||
password,
|
||||
};
|
||||
|
||||
try {
|
||||
if (!navigator.onLine) {
|
||||
alert('No internet connection');
|
||||
return;
|
||||
}
|
||||
const response = await createUser(userData); // Pass the userData object
|
||||
|
||||
if (response) {
|
||||
navigate('/login'); // Redirect to the login page after successful registration
|
||||
alert('Пользователь успешно зарегестрирован!');
|
||||
} else {
|
||||
console.error('Error registering:');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error registering:', error);
|
||||
alert('Error registering');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="register-page">
|
||||
<h1>Register</h1>
|
||||
<Form onFinish={handleFinish}>
|
||||
<Form.Item label="Name" name="name" rules={[{ required: true, message: 'Пожалуйста, введите имя!' }]}>
|
||||
<Input value={name} onChange={e => setName(e.target.value)} />
|
||||
</Form.Item>
|
||||
<Form.Item label="Email" name="email" rules={[{ required: true, type: 'email', message: 'Пожалуйста, введите корректный адрес почты!' }]}>
|
||||
<Input value={email} onChange={e => setEmail(e.target.value)} />
|
||||
</Form.Item>
|
||||
<Form.Item label="Password" name="password" rules={[{ required: true, min: 8, message: 'Пароль должен содержать не менее 8 символов!' }]}>
|
||||
<Input
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={e => setPassword(e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Button type="primary" htmlType="submit">
|
||||
Регистрация
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<p>
|
||||
Уже есть аккаунт? <Link to="/login">Войдите</Link>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default RegisterPage;
|
1184
package-lock.json
generated
1184
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,9 +0,0 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"antd": "^5.21.6",
|
||||
"react-router-dom": "^6.27.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.3.12"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user