This commit is contained in:
Vladiysss
2026-04-17 20:44:31 +03:00
parent d478c1570a
commit d9d1f5b1b2
16 changed files with 187 additions and 81 deletions

View File

@@ -15,7 +15,7 @@
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
"scripts": { "scripts": {
"start": "PORT=24452 react-scripts start", "start": "react-scripts start --port=3000",
"build": "react-scripts build --port=24452", "build": "react-scripts build --port=24452",
"test": "react-scripts test --port=24452", "test": "react-scripts test --port=24452",
"eject": "react-scripts eject --port=24452" "eject": "react-scripts eject --port=24452"

View File

@@ -7,7 +7,7 @@ import Profile from './Profile';
import Registration from './Registration'; import Registration from './Registration';
import Mainpage from './Mainpage'; import Mainpage from './Mainpage';
import KBBoardsList from './KBBoardsList'; import KBBoardsList from './KBBoardsList';
import KBBoard from './KBBoard/KBBoard'; import KBBoard from './KBBoard';
import OtherProfile from './OtherProfile'; import OtherProfile from './OtherProfile';
function App() { function App() {

View File

@@ -85,3 +85,7 @@ export const deleteBoardsAPI = async (boardId) => {
export const meAPI = () => { export const meAPI = () => {
return axios.get('/api/users/me'); return axios.get('/api/users/me');
}; };
export const getWsTicketAPI = async () => {
return axios.get('/api/boards/ws-ticket');
};

View File

@@ -6,7 +6,7 @@ import {
createTaskAPI, updateTaskAPI, deleteTaskAPI, createTaskAPI, updateTaskAPI, deleteTaskAPI,
createCategoryAPI, updateCategoryAPI, deleteCategoryAPI, createCategoryAPI, updateCategoryAPI, deleteCategoryAPI,
addMemberAPI, assignMemberAPI, unassignMemberAPI, deleteMemberAPI, quitMemberAPI addMemberAPI, assignMemberAPI, unassignMemberAPI, deleteMemberAPI, quitMemberAPI
} from './BoardAPI'; } from './API';
export const useBoardLogic = (id, setError, setInfo, setCategories, setLoading, setItems) => { export const useBoardLogic = (id, setError, setInfo, setCategories, setLoading, setItems) => {
const navigate = useNavigate(); const navigate = useNavigate();

View File

@@ -1,8 +1,9 @@
import {useEffect, useState } from 'react'; import {useEffect, useState } from 'react';
import {useNavigate, useParams} from 'react-router-dom'; import {useNavigate, useParams} from 'react-router-dom';
import {useBoardLogic} from './BoardLogic'; import {useBoardLogic} from './Logic';
import Header from './../Header'; import Header from '../Header';
import './../css/Board.css'; import './../css/Board.css';
import {getWsTicketAPI} from "./API";
const KBBoard = () => { const KBBoard = () => {
const navigate = useNavigate(); const navigate = useNavigate();
@@ -84,8 +85,14 @@ const KBBoard = () => {
const [socket, setSocket] = useState(null); const [socket, setSocket] = useState(null);
useEffect(() => { useEffect(() => {
let ws;
const connect = async () => {
try {
const res = await getWsTicketAPI();
const token = res.data.token;
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const ws = new WebSocket(`${protocol}//ws.back.fool-stack.ru/api/boards/ws/` + id); ws = new WebSocket(`${protocol}//26.22.232.18:24454/api/boards/ws/${id}?token=${token}`);
//ws = new WebSocket(`${protocol}//ws.back.fool-stack.ru/api/boards/ws/${id}?token=${token}`);
ws.onopen = () => { ws.onopen = () => {
console.log('WebSocket соединение установлено'); console.log('WebSocket соединение установлено');
setSocket(ws); setSocket(ws);
@@ -96,7 +103,12 @@ const KBBoard = () => {
}; };
ws.onclose = () => console.log('WebSocket соединение закрыто'); ws.onclose = () => console.log('WebSocket соединение закрыто');
ws.onerror = (error) => console.error('Ошибка WebSocket:', error); ws.onerror = (error) => console.error('Ошибка WebSocket:', error);
return () => ws.close(); } catch (e) {
console.error('Не удалось получить ws-ticket:', e);
}
};
connect();
return () => ws && ws.close();
}, [id, loadBoardData]); }, [id, loadBoardData]);
useEffect(() => { useEffect(() => {

6
src/Login/API.js Normal file
View File

@@ -0,0 +1,6 @@
import axios from 'axios';
export const loginAPI = async (username, password) => {
const newUser = { username, password };
return axios.post('/api/users/login', newUser, { withCredentials: true });
};

26
src/Login/Logic.js Normal file
View File

@@ -0,0 +1,26 @@
import { useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { loginAPI } from './API';
export const useLogic = (setError, setLoading) => {
const navigate = useNavigate();
const login = useCallback(async (username, password) => {
setError('');
setLoading(true);
try {
await loginAPI(username, password);
setTimeout(() => {
navigate('/kanban-boards-list');
}, 500);
} catch (err) {
setError(err.response.data.detail || 'Ошибка входа');
} finally {
setLoading(false);
}
}, [setLoading, setError, navigate]);
return {
login
};
};

View File

@@ -1,7 +1,8 @@
import { useState } from 'react'; import { useState } from 'react';
import axios from 'axios';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import Header from './Header'; import Header from '../Header';
import { useLogic } from './Logic';
const Login = () => { const Login = () => {
const navigate = useNavigate(); const navigate = useNavigate();
@@ -10,25 +11,15 @@ const Login = () => {
const [error, setError] = useState(''); const [error, setError] = useState('');
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const { login } = useLogic(setError, setLoading);
const handleRegisterClick = () => { const handleRegisterClick = () => {
navigate('/registration'); // Переход к регистрации navigate('/registration'); // Переход к регистрации
}; };
const handleLogin = async (e) => { const handleLogin = async (e) => {
e.preventDefault(); e.preventDefault();
setError(''); await login(username, password);
setLoading(true);
try {
const newUser = { username, password };
await axios.post('/api/users/login', newUser, { withCredentials: true });
setTimeout(() => {
navigate('/kanban-boards-list');
}, 500);
} catch (err) {
setError(err.response.data.detail || 'Ошибка входа');
} finally {
setLoading(false);
}
}; };
return ( return (

6
src/Registration/API.js Normal file
View File

@@ -0,0 +1,6 @@
import axios from 'axios';
export const registrationAPI = async (username, display_name, password, password_confirm) => {
const newUser = { username, display_name, password, password_confirm};
await axios.post('/api/users/register', newUser);
};

25
src/Registration/Logic.js Normal file
View File

@@ -0,0 +1,25 @@
import { useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { registrationAPI } from './API';
export const useLogic = (setError, setLoading) => {
const navigate = useNavigate();
const registration = useCallback(async (username, display_name, password, password_confirm) => {
setLoading(true);
setError(null);
try {
await registrationAPI(username, display_name, password, password_confirm);
alert("Регистрация прошла успешно")
navigate('/login');
} catch (err) {
setError(err.response.data.detail || 'Пароль должен иметь длинну от 8 до 16 символов, содержать заглавные и строчные буквы, цифры и спец символ(_-?.!@\'`)');
} finally {
setLoading(false);
}
}, [ setLoading, setError, navigate]);
return {
registration
};
};

View File

@@ -1,7 +1,7 @@
import { useState } from 'react'; import { useState } from 'react';
import axios from 'axios';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import Header from './Header'; import { useLogic } from './Logic';
import Header from './../Header';
const Registration = () => { const Registration = () => {
const navigate = useNavigate(); const navigate = useNavigate();
@@ -12,29 +12,14 @@ const Registration = () => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [error, setError] = useState(null); const [error, setError] = useState(null);
// Добавление пользователя const { registration } = useLogic(setError, setLoading);
const addUser = async (e) => {
const handleReg = async (e) => {
e.preventDefault(); e.preventDefault();
setLoading(true); await registration(username, display_name, password, password_confirm);
setError(null);
try {
const newUser = { username, display_name, password, password_confirm};
await axios.post('/api/users/register', newUser);
alert('Регистрация успешна! Перейдите на страницу входа.');
navigate('/login');
setuserName('');
setPassword('');
setPassword_confirm('');
} catch (err) {
setError(err.response.data.detail || 'Пароль должен иметь длинну от 8 до 16 символов, содержать заглавные и строчные буквы, цифры и спец символ(_-?.!@\'`)');
} finally {
setLoading(false);
}
}; };
const handleLoginClick = () => { const handleLoginClick = () => { navigate('/login') };
navigate('/login'); // Переход к входу
};
return ( return (
<><Header /> <><Header />
@@ -43,7 +28,7 @@ const Registration = () => {
{ {
error && <div className="error">{error}</div> error && <div className="error">{error}</div>
} }
<form onSubmit={addUser}> <form onSubmit={handleReg}>
<div> <div>
<label>Логин:</label> <label>Логин:</label>
<input <input

View File

@@ -1,21 +0,0 @@
import { useState, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import axios from 'axios';
import Header from './../Header';
import './../css/my.css';
const Name = () => {
const [user, setUser] = useState(null);
const [error, setError] = useState('');
return (
<>
<Header />
<div className="">
</div>
</>
);
}
export default Name;

6
src/_template/API.js Normal file
View File

@@ -0,0 +1,6 @@
import axios from 'axios';
export const functionAPI = async (first, second) => {
const data = { first, second };
return axios.post('/api/target/func', data);
};

25
src/_template/Logic.js Normal file
View File

@@ -0,0 +1,25 @@
import { useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { functionAPI } from './API';
export const useLogic = (setError, setLoading) => {
const navigate = useNavigate();
const function1 = useCallback(async (first, second) => {
setLoading(true);
try {
await functionAPI(first, second);
setTimeout(() => {
navigate('/kanban-boards-list');
}, 500);
} catch (err) {
setError(err.response.data.detail || 'Ошибка');
} finally {
setLoading(false);
}
}, [setLoading, setError, navigate]);
return {
function1
};
};

39
src/_template/index.js Normal file
View File

@@ -0,0 +1,39 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import Header from '../Header';
import { useLogic } from './Logic';
const Name = () => {
const navigate = useNavigate();
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
const { function1 } = useLogic(setError, setLoading);
const handleClick = () => {
navigate('/target'); // Переход
};
const handleFunction1 = async (e) => {
e.preventDefault();
await function1(first, second);
};
return (
<>
<Header />
<div className="">
<h2>Заголовок</h2>
{
error && <div className="error">{error}</div>
}
<div>
...
</div>
</div>
</>
);
};
export default Name;

View File

@@ -4,8 +4,9 @@ module.exports = function(app) {
app.use( app.use(
'/api', '/api',
createProxyMiddleware({ createProxyMiddleware({
target: 'https://back.fool-stack.ru', target: 'http://26.22.232.18:24454',
ws: true, //target: 'https://back.fool-stack.ru',
//ws: true,
changeOrigin: true, changeOrigin: true,
pathRewrite: { '^/api': '/api' }, pathRewrite: { '^/api': '/api' },
}) })
@@ -13,7 +14,8 @@ module.exports = function(app) {
app.use( app.use(
'/static/avatars', '/static/avatars',
createProxyMiddleware({ createProxyMiddleware({
target: 'https://back.fool-stack.ru', target: 'http://26.22.232.18:24454',
//target: 'https://back.fool-stack.ru',
changeOrigin: true, changeOrigin: true,
}) })
); );