Вторая партия фронта.
This commit is contained in:
parent
307acf867a
commit
81f8008aab
@ -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>
|
41
front/premium_store/src/components/MainHead.jsx
Normal file
41
front/premium_store/src/components/MainHead.jsx
Normal 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;
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
@ -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
|
@ -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;
|
||||
}
|
37
front/premium_store/src/components/items/Level/LevelItem.css
Normal file
37
front/premium_store/src/components/items/Level/LevelItem.css
Normal 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;
|
||||
}
|
46
front/premium_store/src/components/items/Level/LevelItem.jsx
Normal file
46
front/premium_store/src/components/items/Level/LevelItem.jsx
Normal 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;
|
25
front/premium_store/src/components/items/Level/LevelList.jsx
Normal file
25
front/premium_store/src/components/items/Level/LevelList.jsx
Normal 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;
|
@ -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;
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
8
front/premium_store/src/index.js
Normal file
8
front/premium_store/src/index.js
Normal 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 />
|
||||
);
|
@ -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'
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user