Вторая партия фронта.

This commit is contained in:
Programmist73 2023-04-19 20:10:05 +04:00
parent 307acf867a
commit 81f8008aab
16 changed files with 588 additions and 13 deletions

View File

@ -3,9 +3,11 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>React App</title>
<link href="../src/styles/App.css">
<title>Premium store of our games! :)</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
</html>

View File

@ -0,0 +1,41 @@
import React from 'react';
import '../styles/App.css';
import { NavLink } from 'react-router-dom';
//компонент с кнопками навигации по сайту
const MainHead = (props) => {
return(
<div>
<div>
<h1 className="Main-label">Мир танков</h1>
</div>
<form className="collapse navbar-collapse">
<nav className="navbar navbar-expand-lg justify-content-around">
<button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation" style={{backgroundColor: '#379dc2'}}>
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="Main_head navbar-nav me-auto align-items-center">
{
props.links.map(route =>
<li key={route.path}
className="nav-item">
<div className="Button_Main_Group container p-2" div="div">
<NavLink className="nav-link btn border border-3 border-dark fs-4 lh-15" role="button"
to={route.path}>
{route.label}
</NavLink>
</div>
</li>
)
}
</ul>
</div>
</nav>
</form>
</div>
)
}
export default MainHead;

View File

@ -0,0 +1,37 @@
.client-card{
display: flex;
width: 100%;
padding: 15px;
margin-top: 5px;
border: 5px solid;
border-color: #14A76C;
border-radius: 10px;
justify-content: space-around;
align-items: center;
font-family: Courier, monospace;
font-weight: 900;
}
.client-attribute{
padding: 5px;
border-radius: 10px;
background-color: #FF652F;
font-family: Courier, monospace;
font-weight: 900;
align-items: center;
}
.client-button-group{
display: flex;
width: 20%;
justify-content: space-around;
align-items: center;
}
.client-button{
padding: 10px;
border-radius: 10px;
background-color: #FF652F;
font-family: Courier, monospace;
font-weight: 900;
}

View File

@ -0,0 +1,61 @@
import React, { useState } from 'react';
import axios from 'axios';
import './ClientItem.css';
import ModalClient from './ModalClient';
import ModalTankNation from '../Nation/ModalTankNation';
const ClientItem = (data) => {
const [client, setClient] = useState(null);
//состояние для контроля вызова модального окна
const[modal, setModal] = useState(false);
//состояние для вызова окна показа списка танков нации
const[modalNation, setModalNation] = useState(false);
function deleteClient(){
axios.delete('http://localhost:8080/client/' + data.clientItem.id)
.then((response) => {
console.log("Удаление уровня с id " + data.clientItem.id)
});
}
return (
<div className="client-card">
<p className="client-attribute"> id: {data.clientItem.id} </p>
<p className="client-attribute"> Никнейм: {data.clientItem.nickName} </p>
<p className="client-attribute"> Баланс: {data.clientItem.balance} </p>
<p className="client-attribute"> Почта: {data.clientItem.email} </p>
<div className='client-button-group'>
<button className="client-button" type="button"
onClick={() => setModal(true)}
>
Редактировать
</button>
<button className="client-button" type="button"
onClick={deleteClient}
>
Удалить
</button>
<button className="nation-button" type="button"
onClick={() => setModalNation(true)}
>
Список танков
</button>
<ModalClient
data={data.clientItem}
visible={modal}
setVisible={setModal}
/>
<ModalTankNation
data={data.clientItem}
visible={modalNation}
setVisible={setModalNation}
/>
</div>
</div>
);
};
export default ClientItem

View File

@ -0,0 +1,22 @@
import React, { useEffect} from 'react';
import ClientItem from './ClientItem';
const ClientList = (clients) => {
return (
<div>
<div>
<h1 style={{textAlign: 'center', fontFamily: 'courier, monospace', background: '#FF652F', borderRadius: '10px'}}>
Список существующих клиентов:
</h1>
</div>
{clients.clientItems.map((clientItem) =>
<ClientItem
clientItem={clientItem}
key={clientItem.id}
/>
)}
</div>
);
}
export default ClientList;

View File

@ -0,0 +1,106 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import cl from '../GameClient/ModalClient.module.css';
import '../../AddClient.css';
const ModalClient = ({data, visible, setVisible}) => {
//для обновления уровня
const [clientNickName, setClientNickName] = useState(data.nickName);
const [clientEmail, setClientEmail] = useState(data.email);
const [clientBalance, setClientBalance] = useState(data.balance);
const [clientTank, setClientTank] = useState(null);
const [tankItems, setTankItems] = useState([]);
useEffect(() => {
console.log('Обращение к БД');
axios.get('http://localhost:8080/tank/')
.then((responce) => {
console.log(responce.data);
setTankItems(responce.data)
});
}, [])
//для контроля видимости модалки
const rootClasses = [cl.myModal];
if(visible)
{
rootClasses.push(cl.active);
}
//добавление нового уровня
function updateLevel(){
axios.put('http://localhost:8080/client/' + data.id + '?nickName='
+ clientNickName + '&email=' + clientEmail + '&balance=' + clientBalance + '&tankId=' + clientTank)
.then((response) => {
console.log("Обновление клиента с id " + data.id)
});
setVisible(false);
}
const getChoiceNation = (newId) => {
setClientTank(tankItems[newId - 1].id);
}
return (
<div className={rootClasses.join(' ')} onClick={() => setVisible(false)}>
<div className={cl.myModalContent} onClick={(e) => e.stopPropagation()}>
<p style={{marginTop: "10px"}}>
Никнейм:
<input
className="add-client-input"
value={clientNickName}
onChange={e => setClientNickName(e.target.value)}
/>
</p>
<p style={{marginTop: "10px"}}>
Почта:
<input
className="add-client-input"
value={clientEmail}
onChange={e => setClientEmail(e.target.value)}
/>
</p>
<p style={{marginTop: "10px"}}>
Баланс:
<input
className="add-client-input"
value={clientBalance}
onChange={e => setClientBalance(e.target.value)}
/>
</p>
<p style={{fontWeight: "900"}}>
Выберите новый танк:
<select
onChange={(event) => getChoiceNation(event.target.selectedIndex)}
>
<option selected>Выберите танк</option>
{tankItems.map((tankItem) =>
<option
value={tankItem.name}
key={tankItem.id}
>
{tankItem.name}
</option>
)}
</select>
</p>
<button
style={{marginTop: "10px"}}
className={cl.modalButton}
type="button"
onClick={updateLevel}
>
Сохранить
</button>
</div>
</div>
);
}
export default ModalClient

View File

@ -0,0 +1,34 @@
.myModal{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: none;
background: rgba(0, 0, 0, 0.8);
}
.myModal.active{
display: flex;
justify-content: center;
align-items: center;
}
.myModalContent{
display: inline-block;
padding: 15px;
background: #FF652F;
border-radius: 16px;
min-width: 300px;
min-height: 100px;
justify-content: space-between;
align-items: center;
}
.modalButton{
padding: 5px;
border-radius: 10px;
background-color: #FFE430;
font-family: Courier, monospace;
font-weight: 900;
}

View File

@ -0,0 +1,37 @@
.level-card{
display: flex;
width: 100%;
padding: 15px;
margin-top: 5px;
border: 5px solid;
border-color: #14A76C;
border-radius: 10px;
justify-content: space-around;
align-items: center;
font-family: Courier, monospace;
font-weight: 900;
}
.level-attribute{
padding: 5px;
border-radius: 10px;
background-color: #FF652F;
font-family: Courier, monospace;
font-weight: 900;
align-items: center;
}
.level-button-group{
display: flex;
width: 20%;
justify-content: space-around;
align-items: center;
}
.level-button{
padding: 10px;
border-radius: 10px;
background-color: #FF652F;
font-family: Courier, monospace;
font-weight: 900;
}

View File

@ -0,0 +1,46 @@
import React, { useState } from 'react';
import axios from 'axios';
import './LevelItem.css';
import ModalLevel from './ModalLevel';
//отвечает за отдельно взятый уровень (вывод карточки с ним)
const LevelItem = (data) => {
const [level, setLevel] = useState(null);
//состояние для контроля вызова модального окна
const[modal, setModal] = useState(false);
function deleteLevel(){
axios.delete('http://localhost:8080/level/' + data.levelItem.id)
.then((response) => {
console.log("Удаление уровня с id " + data.levelItem.id)
});
}
return (
<div className="level-card">
<p className="level-attribute"> id: {data.levelItem.id} </p>
<p className="level-attribute"> уровень: {data.levelItem.level} </p>
<div className='level-button-group'>
<button className="level-button" type="button"
onClick={() => setModal(true)}
>
Редактировать
</button>
<button className="level-button" type="button"
onClick={deleteLevel}
>
Удалить
</button>
<ModalLevel
data={data.levelItem}
visible={modal}
setVisible={setModal}
/>
</div>
</div>
);
};
export default LevelItem;

View File

@ -0,0 +1,25 @@
import React, { useEffect} from 'react';
import LevelItem from './LevelItem';
//const host = import.meta.env.VITE_API_URL;
//отвечает за список всех уровней. Передаём сюда пропсом массив уровней
const LevelList = (levels) => {
return (
<div>
<div>
<h1 style={{textAlign: 'center', fontFamily: 'courier, monospace', background: '#FF652F', borderRadius: '10px'}}>
Список существующих уровней:
</h1>
</div>
{levels.levelItems.map((levelItem) =>
<LevelItem
levelItem={levelItem}
key={levelItem.id}
/>
)}
</div>
);
};
export default LevelList;

View File

@ -0,0 +1,49 @@
import React, { useState } from 'react';
import axios from 'axios';
import cl from './ModalLevel.module.css';
import '../../AddLevel.css';
const ModalLevel = ({data, visible, setVisible}) => {
//для обновления уровня
const [level, setLevel] = useState(data.level);
//для контроля видимости модалки
const rootClasses = [cl.myModal];
if(visible)
{
rootClasses.push(cl.active);
}
//добавление нового уровня
function updateLevel(){
setLevel()
axios.put('http://localhost:8080/level/' + data.id + '?Level=' + level)
.then((response) => {
console.log("Обновление уровня с id " + data.id)
});
setVisible(false);
}
return (
<div className={rootClasses.join(' ')} onClick={() => setVisible(false)}>
<div className={cl.myModalContent} onClick={(e) => e.stopPropagation()}>
<input
className="add-level-input"
value={level}
onChange={e => setLevel(e.target.value)}
/>
<button
className={cl.modalButton}
type="button"
onClick={updateLevel}
>
Сохранить
</button>
</div>
</div>
);
};
export default ModalLevel;

View File

@ -0,0 +1,34 @@
.myModal{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: none;
background: rgba(0, 0, 0, 0.8);
}
.myModal.active{
display: flex;
justify-content: center;
align-items: center;
}
.myModalContent{
display: flex;
padding: 15px;
background: #FF652F;
border-radius: 16px;
min-width: 300px;
min-height: 100px;
justify-content: space-between;
align-items: center;
}
.modalButton{
padding: 5px;
border-radius: 10px;
background-color: #FFE430;
font-family: Courier, monospace;
font-weight: 900;
}

View File

@ -0,0 +1,50 @@
import React, { useState } from 'react';
import axios from 'axios';
import cl from './ModalNation.module.css';
import '../../AddNation.css';
const ModalNation = ({data, visible, setVisible}) => {
//для обновления уровня
const [nation, setNation] = useState(data.nation);
const nullId = 0;
//для контроля видимости модалки
const rootClasses = [cl.myModal];
if(visible)
{
rootClasses.push(cl.active);
}
//добавление новой нации
function updateLevel(){
setNation()
axios.put('http://localhost:8080/nation/' + data.id + '?nation=' + nation + '&tankId=' + nullId)
.then((response) => {
console.log("Обновление нации с id " + data.id)
});
setVisible(false);
}
return (
<div className={rootClasses.join(' ')} onClick={() => setVisible(false)}>
<div className={cl.myModalContent} onClick={(e) => e.stopPropagation()}>
<input
className="add-nation-input"
value={nation}
onChange={e => setNation(e.target.value)}
/>
<button
className={cl.modalButton}
type="button"
onClick={updateLevel}
>
Сохранить
</button>
</div>
</div>
);
}
export default ModalNation

View File

@ -0,0 +1,34 @@
.myModal{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: none;
background: rgba(0, 0, 0, 0.8);
}
.myModal.active{
display: flex;
justify-content: center;
align-items: center;
}
.myModalContent{
display: flex;
padding: 15px;
background: #FF652F;
border-radius: 16px;
min-width: 300px;
min-height: 100px;
justify-content: space-between;
align-items: center;
}
.modalButton{
padding: 5px;
border-radius: 10px;
background-color: #FFE430;
font-family: Courier, monospace;
font-weight: 900;
}

View File

@ -0,0 +1,8 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<App />
);

View File

@ -1,11 +0,0 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<App />
//document.getElementById('root'); - для работы этого надо поставит запятую после <App/>
//и делаем import 'react-dom', вместо 'react-dom/client'
);