Compare commits
30 Commits
Author | SHA1 | Date | |
---|---|---|---|
85f0c97e6f | |||
d75c758ee1 | |||
6d178b58aa | |||
9b72e39432 | |||
167ca7eb82 | |||
843ec51b8c | |||
9560588d41 | |||
b4e48f5c5e | |||
9f643c860d | |||
4d76a86c8e | |||
ce8c5ca468 | |||
15b5ebd034 | |||
81f8008aab | |||
307acf867a | |||
01470af3bb | |||
a0ff253478 | |||
973e2c6a16 | |||
8a23075ac6 | |||
43cc05427d | |||
e2d99cec86 | |||
8ecf9e9cab | |||
d0f9fb2bd0 | |||
2844d545ce | |||
c4e3593fa4 | |||
8fa5b5f8c4 | |||
663fd6ad72 | |||
b79d35d1af | |||
9297fb06ae | |||
438e1ed4d4 | |||
eea6638930 |
3
.idea/.gitignore
vendored
Normal file
3
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
10
.idea/compiler.xml
Normal file
10
.idea/compiler.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<bytecodeTargetLevel>
|
||||||
|
<module name="spring_online_calculator" target="17" />
|
||||||
|
<module name="spring_online_calculator.main" target="17" />
|
||||||
|
<module name="spring_online_calculator.test" target="17" />
|
||||||
|
</bytecodeTargetLevel>
|
||||||
|
</component>
|
||||||
|
</project>
|
8
.idea/discord.xml
Normal file
8
.idea/discord.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="DiscordProjectSettings">
|
||||||
|
<option name="show" value="ASK" />
|
||||||
|
<option name="nameOverrideEnabled" value="true" />
|
||||||
|
<option name="description" value="" />
|
||||||
|
</component>
|
||||||
|
</project>
|
19
.idea/gradle.xml
Normal file
19
.idea/gradle.xml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
|
<component name="GradleSettings">
|
||||||
|
<option name="linkedExternalProjectsSettings">
|
||||||
|
<GradleProjectSettings>
|
||||||
|
<option name="delegatedBuild" value="true" />
|
||||||
|
<option name="testRunner" value="GRADLE" />
|
||||||
|
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$/spring_online_calculator" />
|
||||||
|
<option name="modules">
|
||||||
|
<set>
|
||||||
|
<option value="$PROJECT_DIR$/spring_online_calculator" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</GradleProjectSettings>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
15
.idea/inspectionProfiles/Project_Default.xml
Normal file
15
.idea/inspectionProfiles/Project_Default.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="myValues">
|
||||||
|
<value>
|
||||||
|
<list size="1">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="th:text" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="myCustomValuesEnabled" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
20
.idea/jarRepositories.xml
Normal file
20
.idea/jarRepositories.xml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RemoteRepositoriesConfiguration">
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="central" />
|
||||||
|
<option name="name" value="Maven Central repository" />
|
||||||
|
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="jboss.community" />
|
||||||
|
<option name="name" value="JBoss Community repository" />
|
||||||
|
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="MavenRepo" />
|
||||||
|
<option name="name" value="MavenRepo" />
|
||||||
|
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
||||||
|
</remote-repository>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/jpa-buddy.xml
Normal file
6
.idea/jpa-buddy.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JpaBuddyIdeaProjectConfig">
|
||||||
|
<option name="defaultUnitInitialized" value="true" />
|
||||||
|
</component>
|
||||||
|
</project>
|
8
.idea/misc.xml
Normal file
8
.idea/misc.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="temurin-17" project-jdk-type="JavaSDK" />
|
||||||
|
<component name="ProjectType">
|
||||||
|
<option name="id" value="jpab" />
|
||||||
|
</component>
|
||||||
|
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/С репозитория.iml" filepath="$PROJECT_DIR$/.idea/С репозитория.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
124
.idea/uiDesigner.xml
Normal file
124
.idea/uiDesigner.xml
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Palette2">
|
||||||
|
<group name="Swing">
|
||||||
|
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="Button" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="RadioButton" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="CheckBox" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="Label" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||||
|
<preferred-size width="200" height="200" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||||
|
<preferred-size width="200" height="200" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||||
|
<preferred-size width="-1" height="20" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||||
|
</item>
|
||||||
|
</group>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
9
.idea/С репозитория.iml
Normal file
9
.idea/С репозитория.iml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "online_calculator",
|
"name": "premuim_store",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@testing-library/jest-dom": "^5.16.5",
|
"@testing-library/jest-dom": "^5.16.5",
|
||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
|
"axios": "^1.3.5",
|
||||||
|
"cors": "^2.8.5",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-router-dom": "^6.10.0",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
@ -3,9 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<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>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
2
front/premium_store/src/.env
Normal file
2
front/premium_store/src/.env
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
VITE_NODE_ENV=development
|
||||||
|
VITE_API_URL=http://localhost:8080
|
46
front/premium_store/src/App.js
Normal file
46
front/premium_store/src/App.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import React, {useState} from 'react';
|
||||||
|
import { useRoutes, Outlet, BrowserRouter } from 'react-router-dom';
|
||||||
|
import AddLevel from './components/AddLevel';
|
||||||
|
import MainHead from './components/MainHead';
|
||||||
|
import AddNation from './components/AddNation';
|
||||||
|
import AddTank from './components/AddTank';
|
||||||
|
import AddClient from './components/AddClient';
|
||||||
|
import PageForChecking from './components/PageForChecking';
|
||||||
|
|
||||||
|
function Router(props) {
|
||||||
|
return useRoutes(props.rootRoute);
|
||||||
|
}
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
const routes = [
|
||||||
|
{ index: true, element: <AddLevel /> },
|
||||||
|
{ path: 'levels', element: <AddLevel />, label: 'Обзор уровней' },
|
||||||
|
{ path: 'nations', element: <AddNation />, label: 'Обзор наций' },
|
||||||
|
{ path: 'tanks', element: <AddTank />, label: 'Обзор танков'},
|
||||||
|
{ path: 'clients', element: <AddClient />, label: 'Обзор клиентов'},
|
||||||
|
{ path: 'checkPage', element: <PageForChecking />, label: 'Фильтр по танкам'}
|
||||||
|
];
|
||||||
|
|
||||||
|
const links = routes.filter(route => route.hasOwnProperty('label'));
|
||||||
|
|
||||||
|
const rootRoute = [
|
||||||
|
{ path: '/', element: render(links), children: routes }
|
||||||
|
];
|
||||||
|
|
||||||
|
function render(links) {
|
||||||
|
return (
|
||||||
|
<div className="App">
|
||||||
|
<MainHead links={links}/>
|
||||||
|
<Outlet/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BrowserRouter>
|
||||||
|
<Router rootRoute={ rootRoute } />
|
||||||
|
</BrowserRouter>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
14
front/premium_store/src/components/AddClient.css
Normal file
14
front/premium_store/src/components/AddClient.css
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
.add-client-input{
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
border: 3px solid;
|
||||||
|
border-radius: 10px;
|
||||||
|
border-color: #505050;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-level-button{
|
||||||
|
border-radius: 10px;
|
||||||
|
border-color: #505050;
|
||||||
|
background-color: #FFE430;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
113
front/premium_store/src/components/AddClient.jsx
Normal file
113
front/premium_store/src/components/AddClient.jsx
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import axios from 'axios';
|
||||||
|
import '../styles/App.css';
|
||||||
|
import ClientList from './items/GameClient/ClientList';
|
||||||
|
import './AddClient.css';
|
||||||
|
|
||||||
|
export default function AddClient() {
|
||||||
|
const [clientItems, setClientItems] = useState([]);
|
||||||
|
|
||||||
|
//для создания нового уровня
|
||||||
|
const [clientNickName, setClientNickName] = useState();
|
||||||
|
|
||||||
|
const [clientEmail, setClientEmail] = useState();
|
||||||
|
|
||||||
|
const [clientBalance, setClientBalance] = useState();
|
||||||
|
|
||||||
|
|
||||||
|
//загрузка всех имеющихся уровней при старте
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('Обращение к БД');
|
||||||
|
axios.get('http://localhost:8080/client/')
|
||||||
|
.then((responce) => {
|
||||||
|
console.log(responce.data);
|
||||||
|
setClientItems(responce.data)
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
//обновить список уровней
|
||||||
|
function CheckArray(){
|
||||||
|
console.log('Обращение к БД');
|
||||||
|
axios.get('http://localhost:8080/client/')
|
||||||
|
.then((responce) => {
|
||||||
|
console.log(responce.data);
|
||||||
|
setClientItems(responce.data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//добавление нового уровня
|
||||||
|
function addNewClient(){
|
||||||
|
console.log(clientNickName);
|
||||||
|
console.log(clientEmail);
|
||||||
|
console.log(clientBalance);
|
||||||
|
|
||||||
|
if(clientNickName === ''){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {//http://localhost:8080/client/?nickName=11&email=11&balance=11
|
||||||
|
axios.post('http://localhost:8080/client/?nickName=' + clientNickName + '&email=' + clientEmail + '&balance=' + clientBalance)
|
||||||
|
.then((response) => {
|
||||||
|
CheckArray();
|
||||||
|
setClientNickName('');
|
||||||
|
setClientEmail('');
|
||||||
|
setClientBalance('');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//добавили условную отрисовку
|
||||||
|
return(
|
||||||
|
<div>
|
||||||
|
<div className="Group_create_level">
|
||||||
|
<h1>Генератор клиентов</h1>
|
||||||
|
<div>
|
||||||
|
<p style={{fontWeight: "900", marginTop:"10px"}}>
|
||||||
|
Введите никнейм клиента:
|
||||||
|
<input
|
||||||
|
className="add-client-input"
|
||||||
|
value={clientNickName}
|
||||||
|
onChange={e => setClientNickName(e.target.value)}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
<p style={{fontWeight: "900", marginTop:"10px"}}>
|
||||||
|
Введите почту клиента:
|
||||||
|
<input
|
||||||
|
className="add-client-input"
|
||||||
|
value={clientEmail}
|
||||||
|
onChange={e => setClientEmail(e.target.value)}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
<p style={{fontWeight: "900", marginTop:"10px"}}>
|
||||||
|
Введите баланс клиента:
|
||||||
|
<input
|
||||||
|
className="add-client-input"
|
||||||
|
value={clientBalance}
|
||||||
|
onChange={e => setClientBalance(e.target.value)}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button className='add-level-button'
|
||||||
|
onClick={addNewClient}
|
||||||
|
>
|
||||||
|
Создать клиента
|
||||||
|
</button>
|
||||||
|
<button className='add-level-button'
|
||||||
|
onClick={CheckArray}
|
||||||
|
>
|
||||||
|
Вывести всех клиентов
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="Card_list">
|
||||||
|
{clientItems.length !== 0
|
||||||
|
?
|
||||||
|
<ClientList clientItems={clientItems}
|
||||||
|
/>
|
||||||
|
:
|
||||||
|
<h1 style={{textAlign: 'center'}}>В БД отсутствуют какие-либо клиенты!</h1>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
14
front/premium_store/src/components/AddLevel.css
Normal file
14
front/premium_store/src/components/AddLevel.css
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
.add-level-input{
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
border: 3px solid;
|
||||||
|
border-radius: 10px;
|
||||||
|
border-color: #505050;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-level-button{
|
||||||
|
border-radius: 10px;
|
||||||
|
border-color: #505050;
|
||||||
|
background-color: #FFE430;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
89
front/premium_store/src/components/AddLevel.jsx
Normal file
89
front/premium_store/src/components/AddLevel.jsx
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import axios from 'axios';
|
||||||
|
import '../styles/App.css';
|
||||||
|
import LevelList from './items/Level/LevelList';
|
||||||
|
import './AddLevel.css';
|
||||||
|
|
||||||
|
//компонент для просмотра, создания и удаления уровней
|
||||||
|
const AddLevel = () => {
|
||||||
|
const [levelItems, setLevelItems] = useState([]);
|
||||||
|
|
||||||
|
//для создания нового уровня
|
||||||
|
const [level, setLevel] = useState({level: ''});
|
||||||
|
|
||||||
|
//загрузка всех имеющихся уровней при старте
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('Обращение к БД');
|
||||||
|
axios.get('http://localhost:8080/level/')
|
||||||
|
.then((responce) => {
|
||||||
|
console.log(responce.data);
|
||||||
|
setLevelItems(responce.data)
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
//обновить список уровней
|
||||||
|
function CheckArray(){
|
||||||
|
console.log('Обращение к БД');
|
||||||
|
axios.get('http://localhost:8080/level/')
|
||||||
|
.then((responce) => {
|
||||||
|
console.log(responce.data);
|
||||||
|
setLevelItems(responce.data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//добавление нового уровня
|
||||||
|
function addNewLevel(){
|
||||||
|
if(level.level === ''){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
axios.post('http://localhost:8080/level/?Level=' + parseInt(level.level, 10))
|
||||||
|
.then((response) => {
|
||||||
|
CheckArray();
|
||||||
|
setLevel({level: ''});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//добавили условную отрисовку
|
||||||
|
return(
|
||||||
|
<div>
|
||||||
|
<div className="Group_create_level">
|
||||||
|
<h1>Генератор уровней</h1>
|
||||||
|
<div>
|
||||||
|
<p style={{fontWeight: "900"}}>
|
||||||
|
Введите уровень:
|
||||||
|
<input
|
||||||
|
className="add-level-input"
|
||||||
|
value={level.level}
|
||||||
|
onChange={e => setLevel({level: e.target.value})}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button className='add-level-button'
|
||||||
|
onClick={addNewLevel}
|
||||||
|
>
|
||||||
|
Создать уровень
|
||||||
|
</button>
|
||||||
|
<button className='add-level-button'
|
||||||
|
onClick={CheckArray}
|
||||||
|
>
|
||||||
|
Вывести все уровни
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="Card_list">
|
||||||
|
{levelItems.length !== 0
|
||||||
|
?
|
||||||
|
<LevelList levelItems={levelItems}
|
||||||
|
/>
|
||||||
|
:
|
||||||
|
<h1 style={{textAlign: 'center'}}>В БД отсутствуют какие-либо уровни!</h1>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddLevel;
|
14
front/premium_store/src/components/AddNation.css
Normal file
14
front/premium_store/src/components/AddNation.css
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
.add-nation-input{
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
border: 3px solid;
|
||||||
|
border-radius: 10px;
|
||||||
|
border-color: #505050;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-level-button{
|
||||||
|
border-radius: 10px;
|
||||||
|
border-color: #505050;
|
||||||
|
background-color: #FFE430;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
89
front/premium_store/src/components/AddNation.jsx
Normal file
89
front/premium_store/src/components/AddNation.jsx
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import axios from 'axios';
|
||||||
|
import '../styles/App.css';
|
||||||
|
import NationList from './items/Nation/NationList';
|
||||||
|
import './AddNation.css';
|
||||||
|
|
||||||
|
//компонент для просмотра, создания и удаления уровней
|
||||||
|
const AddNation = () => {
|
||||||
|
const [nationItems, setNationItems] = useState([]);
|
||||||
|
|
||||||
|
//для создания нового уровня
|
||||||
|
const [nation, setNation] = useState({nation: ''});
|
||||||
|
|
||||||
|
//загрузка всех имеющихся уровней при старте
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('Обращение к БД');
|
||||||
|
axios.get('http://localhost:8080/nation/')
|
||||||
|
.then((responce) => {
|
||||||
|
console.log(responce.data);
|
||||||
|
setNationItems(responce.data)
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
//обновить список уровней
|
||||||
|
function CheckArray(){
|
||||||
|
console.log('Обращение к БД');
|
||||||
|
axios.get('http://localhost:8080/nation/')
|
||||||
|
.then((responce) => {
|
||||||
|
console.log(responce.data);
|
||||||
|
setNationItems(responce.data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//добавление нового уровня
|
||||||
|
function addNewNation(){
|
||||||
|
if(nation.nation === ''){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
axios.post('http://localhost:8080/nation/?nation=' + nation.nation)
|
||||||
|
.then((response) => {
|
||||||
|
CheckArray();
|
||||||
|
setNation({nation: ''});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//добавили условную отрисовку
|
||||||
|
return(
|
||||||
|
<div>
|
||||||
|
<div className="Group_create_level">
|
||||||
|
<h1>Генератор наций</h1>
|
||||||
|
<div>
|
||||||
|
<p style={{fontWeight: "900"}}>
|
||||||
|
Введите нацию:
|
||||||
|
<input
|
||||||
|
className="add-nation-input"
|
||||||
|
value={nation.nation}
|
||||||
|
onChange={e => setNation({nation: e.target.value})}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button className='add-level-button'
|
||||||
|
onClick={addNewNation}
|
||||||
|
>
|
||||||
|
Создать нацию
|
||||||
|
</button>
|
||||||
|
<button className='add-level-button'
|
||||||
|
onClick={CheckArray}
|
||||||
|
>
|
||||||
|
Вывести все нации
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="Card_list">
|
||||||
|
{nationItems.length !== 0
|
||||||
|
?
|
||||||
|
<NationList nationItems={nationItems}
|
||||||
|
/>
|
||||||
|
:
|
||||||
|
<h1 style={{textAlign: 'center'}}>В БД отсутствуют какие-либо нации!</h1>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddNation;
|
15
front/premium_store/src/components/AddTank.css
Normal file
15
front/premium_store/src/components/AddTank.css
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
.add-tank-input{
|
||||||
|
margin-top: 10px;
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
border: 3px solid;
|
||||||
|
border-radius: 10px;
|
||||||
|
border-color: #505050;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-level-button{
|
||||||
|
border-radius: 10px;
|
||||||
|
border-color: #505050;
|
||||||
|
background-color: #FFE430;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
198
front/premium_store/src/components/AddTank.jsx
Normal file
198
front/premium_store/src/components/AddTank.jsx
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
import React, { useState, useEffect, useRef} from 'react';
|
||||||
|
import axios from 'axios';
|
||||||
|
import '../styles/App.css';
|
||||||
|
import TankList from './items/Tank/TankList';
|
||||||
|
import './AddTank.css';
|
||||||
|
|
||||||
|
const AddTank = () => {
|
||||||
|
const [tankItems, setTankItems] = useState([]);
|
||||||
|
|
||||||
|
//для создания нового танка
|
||||||
|
const [tankName, setTankName] = useState({tankName: ''});
|
||||||
|
|
||||||
|
const [tankCost, setTankCost] = useState({tankCost: ''});
|
||||||
|
|
||||||
|
const [nationItems, setNationItems] = useState([]);
|
||||||
|
|
||||||
|
const [levelItems, setLevelItems] = useState([]);
|
||||||
|
|
||||||
|
//храним выбранные нацию и уровень для нового танка
|
||||||
|
const [chooiceNation, setChooiceNation] = useState();
|
||||||
|
const [chooiceLevel, setChooiceLevel] = useState();
|
||||||
|
|
||||||
|
const [fileByte, setFileByte] = useState(null);
|
||||||
|
const inputRef = useRef();
|
||||||
|
|
||||||
|
//загрузка всех имеющихся танков, а также уровней и наций при старте
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('Обращение к БД');
|
||||||
|
axios.get('http://localhost:8080/tank/')
|
||||||
|
.then((responce) => {
|
||||||
|
console.log(responce.data);
|
||||||
|
setTankItems(responce.data)
|
||||||
|
});
|
||||||
|
axios.get('http://localhost:8080/level/')
|
||||||
|
.then((responce) => {
|
||||||
|
console.log(responce.data);
|
||||||
|
setLevelItems(responce.data)
|
||||||
|
});
|
||||||
|
axios.get('http://localhost:8080/nation/')
|
||||||
|
.then((responce) => {
|
||||||
|
console.log(responce.data);
|
||||||
|
setNationItems(responce.data)
|
||||||
|
});
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
//обновить список танков
|
||||||
|
function CheckArray(){
|
||||||
|
console.log('Обращение к БД');
|
||||||
|
axios.get('http://localhost:8080/tank/')
|
||||||
|
.then((responce) => {
|
||||||
|
console.log(responce.data);
|
||||||
|
setTankItems(responce.data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//добавление нового танка
|
||||||
|
async function addNewTank(){
|
||||||
|
console.log(tankName);
|
||||||
|
console.log(tankCost);
|
||||||
|
console.log(chooiceNation);
|
||||||
|
console.log(chooiceLevel);
|
||||||
|
//console.log(imageURL);
|
||||||
|
|
||||||
|
//const header = new Headers({ "Access-Control-Allow-Origin": "*" });
|
||||||
|
|
||||||
|
axios.post("http://localhost:8080/tank/?firstName=" + tankName.tankName +
|
||||||
|
"&id=" + chooiceNation.id + "&nationId=" + chooiceNation + "&levelId=" + chooiceLevel +
|
||||||
|
"&cost=" + tankCost.tankCost)
|
||||||
|
.then((response) => {
|
||||||
|
console.log("Успешное добавление");
|
||||||
|
console.log(response.data);
|
||||||
|
CheckArray();
|
||||||
|
setTankCost({tankCost: ''});
|
||||||
|
setTankName({tankName: ''});
|
||||||
|
});
|
||||||
|
|
||||||
|
//}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
//хранит картинку для танка
|
||||||
|
const [imageURL, setImageURL] = useState();
|
||||||
|
|
||||||
|
const fileReader = new FileReader();
|
||||||
|
fileReader.onloadend = () => {
|
||||||
|
const tempval = fileReader.result
|
||||||
|
setImageURL(tempval);
|
||||||
|
};
|
||||||
|
|
||||||
|
function handleOnChange(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
const file = event.target.files[0];
|
||||||
|
fileReader.readAsDataURL(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getChoiceNation = (newId) => {
|
||||||
|
setChooiceNation(nationItems[newId - 1].id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getChoiceLevel = (newId) => {
|
||||||
|
setChooiceLevel(levelItems[newId - 1].id);
|
||||||
|
}
|
||||||
|
|
||||||
|
//для добавления картинок
|
||||||
|
/*<p style={{fontWeight: "900", marginTop: "10px"}}>
|
||||||
|
Выберите изображение:
|
||||||
|
<input className="add-tank-input" id="formFileSm" type="file"
|
||||||
|
accept="image/jpeg, image/png, image/jpg"
|
||||||
|
value=''
|
||||||
|
style={{marginTop: "10px"}}
|
||||||
|
//onChange={e => setTank({tankImage: e.target.value})}
|
||||||
|
//onChange={() => setTank({tankImage: inputRef.current.files[0]})}
|
||||||
|
onChange={handleOnChange}
|
||||||
|
//ref={inputRef}
|
||||||
|
/>
|
||||||
|
</p>*/
|
||||||
|
|
||||||
|
//добавили условную отрисовку
|
||||||
|
return(
|
||||||
|
<div>
|
||||||
|
<div className="Group_create_level">
|
||||||
|
<h1>Генератор танков</h1>
|
||||||
|
<div>
|
||||||
|
<p style={{fontWeight: "900"}}>
|
||||||
|
Выберите нацию:
|
||||||
|
<select
|
||||||
|
onChange={(event) => getChoiceNation(event.target.selectedIndex)}
|
||||||
|
>
|
||||||
|
<option selected>Выберите нацию</option>
|
||||||
|
{nationItems.map((nationItem) =>
|
||||||
|
<option
|
||||||
|
value={nationItem.nation}
|
||||||
|
key={nationItem.id}
|
||||||
|
>
|
||||||
|
{nationItem.nation}
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<p style={{fontWeight: "900"}}>
|
||||||
|
Выберите уровень:
|
||||||
|
<select style={{marginTop: "10px"}}
|
||||||
|
onChange={(event) => getChoiceLevel(event.target.selectedIndex)}
|
||||||
|
>
|
||||||
|
<option selected>Выберите уровень</option>
|
||||||
|
{levelItems.map((levelItem) =>
|
||||||
|
<option
|
||||||
|
value={levelItem.level}
|
||||||
|
key={levelItem.id}
|
||||||
|
>
|
||||||
|
{levelItem.level}
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<p style={{fontWeight: "900"}}>
|
||||||
|
Введите название:
|
||||||
|
<input
|
||||||
|
className="add-tank-input"
|
||||||
|
value={tankName.tankName}
|
||||||
|
onChange={e => setTankName({tankName: e.target.value})}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
<p style={{fontWeight: "900"}}>
|
||||||
|
Введите стоимость:
|
||||||
|
<input
|
||||||
|
className="add-tank-input"
|
||||||
|
value={tankCost.tankCost}
|
||||||
|
onChange={e => setTankCost({tankCost: e.target.value})}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button className='add-level-button'
|
||||||
|
onClick={addNewTank}
|
||||||
|
>
|
||||||
|
Создать танк
|
||||||
|
</button>
|
||||||
|
<button className='add-level-button'
|
||||||
|
onClick={CheckArray}
|
||||||
|
>
|
||||||
|
Вывести все танки
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="Card_list">
|
||||||
|
{tankItems.length !== 0
|
||||||
|
?
|
||||||
|
<TankList tankItems={tankItems}
|
||||||
|
/>
|
||||||
|
:
|
||||||
|
<h1 style={{textAlign: 'center'}}>В БД отсутствуют какие-либо танки!</h1>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AddTank
|
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;
|
133
front/premium_store/src/components/PageForChecking.jsx
Normal file
133
front/premium_store/src/components/PageForChecking.jsx
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
import React, { useState, useEffect, useRef} from 'react';
|
||||||
|
import axios from 'axios';
|
||||||
|
import '../styles/App.css';
|
||||||
|
import TankList from './items/Tank/TankList';
|
||||||
|
import './AddTank.css';
|
||||||
|
|
||||||
|
const PageForChecking = () => {
|
||||||
|
|
||||||
|
const[tankItems, setTankItems] = useState([]);
|
||||||
|
|
||||||
|
const [nationItems, setNationItems] = useState([]);
|
||||||
|
|
||||||
|
const [levelItems, setLevelItems] = useState([]);
|
||||||
|
|
||||||
|
const [chooiceNation, setChooiceNation] = useState();
|
||||||
|
|
||||||
|
const [chooiceFirstLevel, setChooiceFirstLevel] = useState();
|
||||||
|
|
||||||
|
const [chooiceSecondLevel, setChooiceSecondLevel] = useState();
|
||||||
|
|
||||||
|
//загрузка всех имеющихся танков, а также уровней и наций при старте
|
||||||
|
useEffect(() => {
|
||||||
|
axios.get('http://localhost:8080/level/')
|
||||||
|
.then((responce) => {
|
||||||
|
console.log(responce.data);
|
||||||
|
setLevelItems(responce.data)
|
||||||
|
});
|
||||||
|
axios.get('http://localhost:8080/nation/')
|
||||||
|
.then((responce) => {
|
||||||
|
console.log(responce.data);
|
||||||
|
setNationItems(responce.data)
|
||||||
|
});
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const getChoiceNation = (newId) => {
|
||||||
|
setChooiceNation(nationItems[newId - 1].nation);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getChooiceFirstLevel = (newId) => {
|
||||||
|
setChooiceFirstLevel(levelItems[newId - 1].level);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getChooiceSecondLevel = (newId) => {
|
||||||
|
setChooiceSecondLevel(levelItems[newId - 1].level);
|
||||||
|
}
|
||||||
|
|
||||||
|
function findList(){
|
||||||
|
console.log(chooiceNation);
|
||||||
|
console.log(chooiceFirstLevel);
|
||||||
|
console.log(chooiceSecondLevel);
|
||||||
|
|
||||||
|
axios.get('http://localhost:8080/tank/filteredList/?nation=' + chooiceNation + '&firstLevel=' + chooiceFirstLevel + '&secondLevel=' + chooiceSecondLevel)
|
||||||
|
.then((response) => {
|
||||||
|
setTankItems(response.data)
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(tankItems)
|
||||||
|
}
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div>
|
||||||
|
<div className="Group_create_level">
|
||||||
|
<h1>Фильтрация танков</h1>
|
||||||
|
<div>
|
||||||
|
<p style={{fontWeight: "900"}}>
|
||||||
|
Выберите нацию:
|
||||||
|
<select
|
||||||
|
onChange={(event) => getChoiceNation(event.target.selectedIndex)}
|
||||||
|
>
|
||||||
|
<option selected>Выберите нацию</option>
|
||||||
|
{nationItems.map((nationItem) =>
|
||||||
|
<option
|
||||||
|
value={nationItem.nation}
|
||||||
|
key={nationItem.id}
|
||||||
|
>
|
||||||
|
{nationItem.nation}
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<p style={{fontWeight: "900"}}>
|
||||||
|
Выберите начальный диапазон уровней:
|
||||||
|
<select style={{marginTop: "10px"}}
|
||||||
|
onChange={(event) => getChooiceFirstLevel(event.target.selectedIndex)}
|
||||||
|
>
|
||||||
|
<option selected>Выберите уровень</option>
|
||||||
|
{levelItems.map((levelItem) =>
|
||||||
|
<option
|
||||||
|
value={levelItem.level}
|
||||||
|
key={levelItem.id}
|
||||||
|
>
|
||||||
|
{levelItem.level}
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<p style={{fontWeight: "900"}}>
|
||||||
|
Выберите конечный диапазон уровней:
|
||||||
|
<select style={{marginTop: "10px"}}
|
||||||
|
onChange={(event) => getChooiceSecondLevel(event.target.selectedIndex)}
|
||||||
|
>
|
||||||
|
<option selected>Выберите уровень</option>
|
||||||
|
{levelItems.map((levelItem) =>
|
||||||
|
<option
|
||||||
|
value={levelItem.level}
|
||||||
|
key={levelItem.id}
|
||||||
|
>
|
||||||
|
{levelItem.level}
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button className='add-level-button'
|
||||||
|
onClick={findList}
|
||||||
|
>
|
||||||
|
Найти танки
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="Card_list">
|
||||||
|
{tankItems.length !== 0
|
||||||
|
?
|
||||||
|
<TankList tankItems={tankItems}
|
||||||
|
/>
|
||||||
|
:
|
||||||
|
<h1 style={{textAlign: 'center'}}>Отсутствуют какие-либо танки при таком фильтре!</h1>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PageForChecking
|
@ -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;
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import cl from './ModalNation.module.css';
|
||||||
|
import '../../AddNation.css';
|
||||||
|
import TankList from '../Tank/TankList';
|
||||||
|
import { useFetcher } from 'react-router-dom';
|
||||||
|
|
||||||
|
const ModalTankNation = ({data, visible, setVisible}) => {
|
||||||
|
//для обновления уровня
|
||||||
|
const [nation, setNation] = useState(data.tanks);
|
||||||
|
|
||||||
|
//для контроля видимости модалки
|
||||||
|
const rootClasses = [cl.myModal];
|
||||||
|
|
||||||
|
//загрузка всех имеющихся танков, а также уровней и наций при старте
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("Загрузка МОДАЛКИ №1")
|
||||||
|
console.log(nation);
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
if(visible)
|
||||||
|
{
|
||||||
|
rootClasses.push(cl.active);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={rootClasses.join(' ')} onClick={() => setVisible(false)}>
|
||||||
|
<div className={cl.myModalContent} onClick={(e) => e.stopPropagation()}>
|
||||||
|
{nation.length !== 0
|
||||||
|
?
|
||||||
|
<TankList
|
||||||
|
label={"Список танков у нации"}
|
||||||
|
tankItems={nation}
|
||||||
|
/>
|
||||||
|
:
|
||||||
|
<h1 style={{textAlign: 'center'}}>В БД отсутствуют какие-либо танки данной нации!</h1>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ModalTankNation
|
@ -0,0 +1,38 @@
|
|||||||
|
.nation-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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nation-attribute{
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #FF652F;
|
||||||
|
font-family: Courier, monospace;
|
||||||
|
font-weight: 900;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nation-button-group{
|
||||||
|
display: flex;
|
||||||
|
margin: 10px;
|
||||||
|
width: 20%;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nation-button{
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #FF652F;
|
||||||
|
font-family: Courier, monospace;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import axios from 'axios';
|
||||||
|
import './NationItem.css';
|
||||||
|
import ModalNation from './ModalNation';
|
||||||
|
import ModalTankNation from './ModalTankNation';
|
||||||
|
|
||||||
|
//отвечает за отдельно взятую нацию (вывод карточки с ним)
|
||||||
|
const NationItem = (data) => {
|
||||||
|
const [nation, setNation] = useState(null);
|
||||||
|
|
||||||
|
//состояние для контроля вызова модального окна
|
||||||
|
const[modal, setModal] = useState(false);
|
||||||
|
|
||||||
|
//состояние для вызова окна показа списка танков нации
|
||||||
|
const[modalNation, setModalNation] = useState(false);
|
||||||
|
|
||||||
|
function deleteNation(){
|
||||||
|
axios.delete('http://localhost:8080/nation/' + data.nationItem.id)
|
||||||
|
.then((response) => {
|
||||||
|
console.log("Удаление нации с id " + data.nationItem.id)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="nation-card">
|
||||||
|
<p className="nation-attribute"> id: {data.nationItem.id} </p>
|
||||||
|
<p className="nation-attribute"> нация: {data.nationItem.nation} </p>
|
||||||
|
<div className='nation-button-group'>
|
||||||
|
<button className="nation-button" type="button"
|
||||||
|
onClick={() => setModal(true)}
|
||||||
|
>
|
||||||
|
Редактировать
|
||||||
|
</button>
|
||||||
|
<button className="nation-button" type="button"
|
||||||
|
onClick={deleteNation}
|
||||||
|
>
|
||||||
|
Удалить
|
||||||
|
</button>
|
||||||
|
<button className="nation-button" type="button"
|
||||||
|
onClick={() => setModalNation(true)}
|
||||||
|
>
|
||||||
|
Список танков
|
||||||
|
</button>
|
||||||
|
<ModalNation
|
||||||
|
data={data.nationItem}
|
||||||
|
visible={modal}
|
||||||
|
setVisible={setModal}
|
||||||
|
/>
|
||||||
|
<ModalTankNation
|
||||||
|
data={data.nationItem}
|
||||||
|
visible={modalNation}
|
||||||
|
setVisible={setModalNation}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NationItem
|
@ -0,0 +1,22 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import NationItem from './NationItem';
|
||||||
|
|
||||||
|
const NationList = (nations) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<h1 style={{textAlign: 'center', fontFamily: 'courier, monospace', background: '#FF652F', borderRadius: '10px'}}>
|
||||||
|
Список существующих наций:
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
{nations.nationItems.map((nationItem) =>
|
||||||
|
<NationItem
|
||||||
|
nationItem={nationItem}
|
||||||
|
key={nationItem.id}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NationList
|
125
front/premium_store/src/components/items/Tank/ModalTank.jsx
Normal file
125
front/premium_store/src/components/items/Tank/ModalTank.jsx
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import axios from 'axios';
|
||||||
|
import cl from './ModalTank.module.css';
|
||||||
|
import '../../AddTank.css';
|
||||||
|
|
||||||
|
const ModalTank = ({data, visible, setVisible}) => {
|
||||||
|
//для обновления танка
|
||||||
|
const [tankName, setTankName] = useState(data.name);
|
||||||
|
|
||||||
|
const [tankCost, setTankCost] = useState(data.cost);
|
||||||
|
|
||||||
|
const [chooiceNation, setChoiceNation] = useState(data.nation.id);
|
||||||
|
|
||||||
|
const [chooiceLevel, setChoiceLevel] = useState(data.nation.id);
|
||||||
|
|
||||||
|
const [nationItems, setNationItems] = useState([]);
|
||||||
|
|
||||||
|
const [levelItems, setLevelItems] = useState([]);
|
||||||
|
|
||||||
|
//загрузка всех имеющихся танков, а также уровней и наций при старте
|
||||||
|
useEffect(() => {
|
||||||
|
axios.get('http://localhost:8080/level/')
|
||||||
|
.then((responce) => {
|
||||||
|
console.log(responce.data);
|
||||||
|
setLevelItems(responce.data)
|
||||||
|
});
|
||||||
|
axios.get('http://localhost:8080/nation/')
|
||||||
|
.then((responce) => {
|
||||||
|
console.log(responce.data);
|
||||||
|
setNationItems(responce.data)
|
||||||
|
});
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
//для контроля видимости модалки
|
||||||
|
const rootClasses = [cl.myModal];
|
||||||
|
|
||||||
|
if(visible)
|
||||||
|
{
|
||||||
|
rootClasses.push(cl.active);
|
||||||
|
}
|
||||||
|
|
||||||
|
//добавление нового танка
|
||||||
|
function updateLevel(){
|
||||||
|
setTankName()
|
||||||
|
axios.put('http://localhost:8080/tank/' + data.id + '?firstName=' + tankName + '&nationId='
|
||||||
|
+ chooiceNation + '&levelId=' + chooiceLevel + '&cost=' + tankCost)
|
||||||
|
.then((response) => {
|
||||||
|
console.log("Обновление танка с id " + data.id)
|
||||||
|
});
|
||||||
|
setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getChoiceNation = (newId) => {
|
||||||
|
setChoiceNation(nationItems[newId - 1].id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getChoiceLevel = (newId) => {
|
||||||
|
setChoiceLevel(levelItems[newId - 1].id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={rootClasses.join(' ')} onClick={() => setVisible(false)}>
|
||||||
|
<div className={cl.myModalContent} onClick={(e) => e.stopPropagation()}>
|
||||||
|
<p>
|
||||||
|
Название:
|
||||||
|
<input
|
||||||
|
className="add-tank-input"
|
||||||
|
value={tankName}
|
||||||
|
onChange={e => setTankName(e.target.value)}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Стоимость:
|
||||||
|
<input
|
||||||
|
className="add-tank-input"
|
||||||
|
value={tankCost}
|
||||||
|
onChange={e => setTankCost(e.target.value)}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
<p style={{fontWeight: "900"}}>
|
||||||
|
Выберите нацию:
|
||||||
|
<select
|
||||||
|
onChange={(event) => getChoiceNation(event.target.selectedIndex)}
|
||||||
|
>
|
||||||
|
<option selected>Выберите нацию</option>
|
||||||
|
{nationItems.map((nationItem) =>
|
||||||
|
<option
|
||||||
|
value={nationItem.nation}
|
||||||
|
key={nationItem.id}
|
||||||
|
>
|
||||||
|
{nationItem.nation}
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<p style={{fontWeight: "900"}}>
|
||||||
|
Выберите уровень:
|
||||||
|
<select style={{marginTop: "10px"}}
|
||||||
|
onChange={(event) => getChoiceLevel(event.target.selectedIndex)}
|
||||||
|
>
|
||||||
|
<option selected>Выберите уровень</option>
|
||||||
|
{levelItems.map((levelItem) =>
|
||||||
|
<option
|
||||||
|
value={levelItem.level}
|
||||||
|
key={levelItem.id}
|
||||||
|
>
|
||||||
|
{levelItem.level}
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
className={cl.modalButton}
|
||||||
|
type="button"
|
||||||
|
onClick={updateLevel}
|
||||||
|
>
|
||||||
|
Сохранить
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ModalTank
|
@ -0,0 +1,33 @@
|
|||||||
|
.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;
|
||||||
|
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/Tank/TankItem.css
Normal file
37
front/premium_store/src/components/items/Tank/TankItem.css
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
.tank-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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tank-attribute{
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #FF652F;
|
||||||
|
font-family: Courier, monospace;
|
||||||
|
font-weight: 900;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tank-button-group{
|
||||||
|
display: flex;
|
||||||
|
width: 20%;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tank-button{
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #FF652F;
|
||||||
|
font-family: Courier, monospace;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
48
front/premium_store/src/components/items/Tank/TankItem.jsx
Normal file
48
front/premium_store/src/components/items/Tank/TankItem.jsx
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import axios from 'axios';
|
||||||
|
import './TankItem.css';
|
||||||
|
import ModalTank from './ModalTank';
|
||||||
|
|
||||||
|
const TankItem = (data) => {
|
||||||
|
|
||||||
|
const [tank, setTank] = useState(null);
|
||||||
|
|
||||||
|
//состояние для контроля вызова модального окна
|
||||||
|
const[modal, setModal] = useState(false);
|
||||||
|
|
||||||
|
function deleteTank(){
|
||||||
|
axios.delete('http://localhost:8080/tank/' + data.tankItem.id)
|
||||||
|
.then((response) => {
|
||||||
|
console.log("Удаление танка с id " + data.tankItem.id)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="tank-card">
|
||||||
|
<p className="tank-attribute"> id: {data.tankItem.id} </p>
|
||||||
|
<p className="tank-attribute"> название: {data.tankItem.name} </p>
|
||||||
|
<p className="tank-attribute"> уровень: {data.tankItem.level.level} </p>
|
||||||
|
<p className="tank-attribute"> нация: {data.tankItem.nation.nation} </p>
|
||||||
|
<p className="tank-attribute"> стоимость: {data.tankItem.cost} </p>
|
||||||
|
<div className='tank-button-group'>
|
||||||
|
<button className="tank-button" type="button"
|
||||||
|
onClick={() => setModal(true)}
|
||||||
|
>
|
||||||
|
Редактировать
|
||||||
|
</button>
|
||||||
|
<button className="tank-button" type="button"
|
||||||
|
onClick={deleteTank}
|
||||||
|
>
|
||||||
|
Удалить
|
||||||
|
</button>
|
||||||
|
<ModalTank
|
||||||
|
data={data.tankItem}
|
||||||
|
visible={modal}
|
||||||
|
setVisible={setModal}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TankItem
|
22
front/premium_store/src/components/items/Tank/TankList.jsx
Normal file
22
front/premium_store/src/components/items/Tank/TankList.jsx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import TankItem from './TankItem';
|
||||||
|
|
||||||
|
const TankList = (tanks) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<h1 style={{textAlign: 'center', fontFamily: 'courier, monospace', background: '#FF652F', borderRadius: '10px'}}>
|
||||||
|
Список существующих наций:
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
{tanks.tankItems.map((tankItem) =>
|
||||||
|
<TankItem
|
||||||
|
tankItem={tankItem}
|
||||||
|
key={tankItem.id}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TankList;
|
BIN
front/premium_store/src/images/wot-268-4.jpg
Normal file
BIN
front/premium_store/src/images/wot-268-4.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 497 KiB |
BIN
front/premium_store/src/images/wot-is-4.jpg
Normal file
BIN
front/premium_store/src/images/wot-is-4.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 474 KiB |
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 />
|
||||||
|
);
|
90
front/premium_store/src/styles/App.css
Normal file
90
front/premium_store/src/styles/App.css
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*#505050*/
|
||||||
|
|
||||||
|
#root{
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: #151719;
|
||||||
|
background-image: url("../images/wot-is-4.jpg");
|
||||||
|
background-size: cover;
|
||||||
|
background-attachment: fixed;
|
||||||
|
font-family: Courier, monospace;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body{
|
||||||
|
margin: 0; /* Убираем отступы */
|
||||||
|
height: 100%; /* Высота страницы */
|
||||||
|
}
|
||||||
|
|
||||||
|
.App{
|
||||||
|
width: 1200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Group_create_level{
|
||||||
|
display: flex;
|
||||||
|
padding: 15px;
|
||||||
|
background-color: #FFE430;
|
||||||
|
opacity: 0.8;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-top: 15px;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Card_list{
|
||||||
|
padding: 15px;
|
||||||
|
border: 5px solid;
|
||||||
|
border-color: #14A76C;
|
||||||
|
background-color: #151719;
|
||||||
|
opacity: 0.9;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-top: 15px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Main_head{
|
||||||
|
display: flex;
|
||||||
|
padding: 15px;
|
||||||
|
margin-top: 30px;
|
||||||
|
border: 5px solid;
|
||||||
|
border-color: #FF652F;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #151719;
|
||||||
|
opacity: 0.9;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Button_Main_Group{
|
||||||
|
padding: 5px;
|
||||||
|
border-color: #FF652F;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #FF652F;
|
||||||
|
font-family: Courier, monospace;
|
||||||
|
font-weight: bold;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-level-button{
|
||||||
|
padding: 10px;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Main-label{
|
||||||
|
display: flex;
|
||||||
|
padding-top: 16px;
|
||||||
|
font-size: 7vw;
|
||||||
|
font-variant: small-caps;
|
||||||
|
font-stretch: ultra-expanded;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
color: #505050;
|
||||||
|
-webkit-text-stroke-width: 3.0px;
|
||||||
|
-webkit-text-stroke-color: #000000;
|
||||||
|
}
|
@ -1,10 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
function App() {
|
|
||||||
return (
|
|
||||||
<div className="App">
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default 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'
|
|
||||||
);
|
|
||||||
|
|
2
spring_online_calculator/.gitignore
vendored
2
spring_online_calculator/.gitignore
vendored
@ -35,3 +35,5 @@ out/
|
|||||||
|
|
||||||
### VS Code ###
|
### VS Code ###
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
|
*.db
|
@ -1,10 +1,10 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'org.springframework.boot' version '2.6.5'
|
||||||
id 'org.springframework.boot' version '2.7.8'
|
|
||||||
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
|
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
|
||||||
|
id 'java'
|
||||||
}
|
}
|
||||||
|
|
||||||
group = 'com.example'
|
group = 'ru.ulstu.is'
|
||||||
version = '0.0.1-SNAPSHOT'
|
version = '0.0.1-SNAPSHOT'
|
||||||
sourceCompatibility = '17'
|
sourceCompatibility = '17'
|
||||||
|
|
||||||
@ -12,9 +12,29 @@ repositories {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
enabled = false
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||||
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
|
||||||
|
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||||
|
implementation 'com.h2database:h2:2.1.210'
|
||||||
|
|
||||||
|
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
||||||
|
implementation 'org.springframework.boot:spring-boot-devtools'
|
||||||
|
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
|
||||||
|
|
||||||
|
implementation 'org.webjars:bootstrap:5.1.3'
|
||||||
|
implementation 'org.webjars:jquery:3.6.0'
|
||||||
|
implementation 'org.webjars:font-awesome:6.1.0'
|
||||||
|
|
||||||
|
implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.6.5'
|
||||||
|
|
||||||
|
implementation 'org.hibernate.validator:hibernate-validator'
|
||||||
|
implementation 'org.springdoc:springdoc-openapi-ui:1.6.5'
|
||||||
|
|
||||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
6
spring_online_calculator/gradlew
vendored
6
spring_online_calculator/gradlew
vendored
@ -205,12 +205,6 @@ set -- \
|
|||||||
org.gradle.wrapper.GradleWrapperMain \
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
"$@"
|
"$@"
|
||||||
|
|
||||||
# Stop when "xargs" is not available.
|
|
||||||
if ! command -v xargs >/dev/null 2>&1
|
|
||||||
then
|
|
||||||
die "xargs is not available"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Use "xargs" to parse quoted args.
|
# Use "xargs" to parse quoted args.
|
||||||
#
|
#
|
||||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
14
spring_online_calculator/gradlew.bat
vendored
14
spring_online_calculator/gradlew.bat
vendored
@ -14,7 +14,7 @@
|
|||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%"=="" @echo off
|
@if "%DEBUG%" == "" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@rem Gradle startup script for Windows
|
@rem Gradle startup script for Windows
|
||||||
@ -25,7 +25,7 @@
|
|||||||
if "%OS%"=="Windows_NT" setlocal
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%"=="" set DIRNAME=.
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
|||||||
|
|
||||||
set JAVA_EXE=java.exe
|
set JAVA_EXE=java.exe
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if %ERRORLEVEL% equ 0 goto execute
|
if "%ERRORLEVEL%" == "0" goto execute
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
@ -75,15 +75,13 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
:fail
|
:fail
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
rem the _cmd.exe /c_ return code!
|
rem the _cmd.exe /c_ return code!
|
||||||
set EXIT_CODE=%ERRORLEVEL%
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
exit /b 1
|
||||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
|
||||||
exit /b %EXIT_CODE%
|
|
||||||
|
|
||||||
:mainEnd
|
:mainEnd
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
@ -1 +1 @@
|
|||||||
rootProject.name = 'spring_online_calculator'
|
rootProject.name = 'premium_store'
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
package com.example.spring_online_calculator;
|
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
|
||||||
public class SpringOnlineCalculatorApplication {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
SpringApplication.run(SpringOnlineCalculatorApplication.class, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,11 @@
|
|||||||
|
package premium_store;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class PremiumStoreApplication {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(PremiumStoreApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package premium_store;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
//отключение Cors фильтра - не позволяет организовавыть взаимодействие с разных доменов
|
||||||
|
@Configuration
|
||||||
|
public class WebConfiguration implements WebMvcConfigurer {
|
||||||
|
public static final String REST_API = "/api";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addCorsMappings(CorsRegistry registry) {
|
||||||
|
registry.addMapping("/**").allowedMethods("*");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
|||||||
|
package premium_store.controller.DTO;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import premium_store.model.GameClient;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
//класс, который соединяет танки клиента в одну строчку (нам так захотелось)
|
||||||
|
public class ClientDTO {
|
||||||
|
private long id;
|
||||||
|
private String nickName;
|
||||||
|
private String email;
|
||||||
|
private Integer balance;
|
||||||
|
private List<TankDTO> tanks;
|
||||||
|
|
||||||
|
public ClientDTO(){ }
|
||||||
|
|
||||||
|
public ClientDTO(GameClient gameClient){
|
||||||
|
this.id = gameClient.getId();
|
||||||
|
this.nickName = gameClient.getNickName();
|
||||||
|
this.email = gameClient.getEmail();
|
||||||
|
this.balance = gameClient.getBalance();
|
||||||
|
this.tanks = gameClient.getTanks().stream()
|
||||||
|
.map(TankDTO::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||||
|
public long getId(){
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNickName(){
|
||||||
|
return nickName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNickName(String nickName) {
|
||||||
|
this.nickName = nickName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail(){
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getBalance(){
|
||||||
|
return balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBalance(Integer balance) {
|
||||||
|
this.balance = balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TankDTO> getTanks(){
|
||||||
|
return tanks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getIdLastTanks(){
|
||||||
|
return tanks.get(tanks.size() - 1).getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTanks(List<TankDTO> tanks) {
|
||||||
|
this.tanks = tanks;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package premium_store.controller.DTO;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import premium_store.model.Nation;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class FullNationDTO {
|
||||||
|
public Long id;
|
||||||
|
public String nation;
|
||||||
|
public List<TankDTO> tanks;
|
||||||
|
|
||||||
|
public FullNationDTO(){ }
|
||||||
|
|
||||||
|
public FullNationDTO(Nation nation){
|
||||||
|
this.id = nation.getId();
|
||||||
|
this.nation = nation.getNation();
|
||||||
|
this.tanks = nation.getTanksOfThisNation().stream()
|
||||||
|
.map(TankDTO::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNation() {
|
||||||
|
return nation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNation(String nation) {
|
||||||
|
this.nation = nation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TankDTO> getTanksOfThisNation() {
|
||||||
|
return tanks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTanks(List<TankDTO> tanks) {
|
||||||
|
this.tanks = tanks;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package premium_store.controller.DTO;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import premium_store.model.TankLevel;
|
||||||
|
|
||||||
|
public class LevelDTO {
|
||||||
|
private Long id;
|
||||||
|
private int level;
|
||||||
|
|
||||||
|
public LevelDTO(){}
|
||||||
|
|
||||||
|
public LevelDTO(TankLevel level){
|
||||||
|
this.id = level.getId();
|
||||||
|
this.level = level.getLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||||
|
public Long getId(){
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id){
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLevel(){
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLevel(int level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package premium_store.controller.DTO;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import premium_store.model.Nation;
|
||||||
|
|
||||||
|
public class SimpleNationDTO {
|
||||||
|
private Long id;
|
||||||
|
private String nation;
|
||||||
|
|
||||||
|
public SimpleNationDTO(){}
|
||||||
|
|
||||||
|
public SimpleNationDTO(Nation nation){
|
||||||
|
this.id = nation.getId();
|
||||||
|
this.nation = nation.getNation();
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||||
|
public Long getId(){
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id){
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNation(){
|
||||||
|
return nation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNation(String nation){
|
||||||
|
this.nation = nation;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package premium_store.controller.DTO;
|
||||||
|
|
||||||
|
public class SortDTO {
|
||||||
|
private String nation;
|
||||||
|
private int firstLevel;
|
||||||
|
private int secondLevel;
|
||||||
|
|
||||||
|
public SortDTO(){}
|
||||||
|
|
||||||
|
public SortDTO(String nation, int firstLevel, int secondLevel){
|
||||||
|
this.nation = nation;
|
||||||
|
this.firstLevel = firstLevel;
|
||||||
|
this.secondLevel = secondLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNation(){
|
||||||
|
return nation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFirstLevel() {
|
||||||
|
return firstLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSecondLevel() {
|
||||||
|
return secondLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNation(String nation){
|
||||||
|
this.nation = nation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstLevel(int firstLevel){
|
||||||
|
this.firstLevel = firstLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecondLevel(int secondLevel) {
|
||||||
|
this.secondLevel = secondLevel;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package premium_store.controller.DTO;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import premium_store.model.GameClient;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
//класс, который соединяет танки клиента в одну строчку (нам так захотелось)
|
||||||
|
public class SupportClientDTO {
|
||||||
|
private long id;
|
||||||
|
private String nickName;
|
||||||
|
private String email;
|
||||||
|
private Integer balance;
|
||||||
|
private Long tankId;
|
||||||
|
|
||||||
|
public SupportClientDTO(){ }
|
||||||
|
|
||||||
|
public SupportClientDTO(GameClient gameClient){
|
||||||
|
this.id = gameClient.getId();
|
||||||
|
this.nickName = gameClient.getNickName();
|
||||||
|
this.email = gameClient.getEmail();
|
||||||
|
this.balance = gameClient.getBalance();
|
||||||
|
|
||||||
|
if(gameClient.getTanks().size() >= 1){
|
||||||
|
this.tankId = gameClient.getTanks().get(gameClient.getTanks().size() - 1).getId();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.tankId = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||||
|
public long getId(){
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNickName(){
|
||||||
|
return nickName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNickName(String nickName) {
|
||||||
|
this.nickName = nickName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail(){
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getBalance(){
|
||||||
|
return balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBalance(Integer balance) {
|
||||||
|
this.balance = balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getTankId(){
|
||||||
|
return tankId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTankId(Long tankId) {
|
||||||
|
this.tankId = tankId;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package premium_store.controller.DTO;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import premium_store.model.Tank;
|
||||||
|
|
||||||
|
public class SupportTankDTO {
|
||||||
|
private long id;
|
||||||
|
private String name;
|
||||||
|
private Long nationId;
|
||||||
|
private Long levelId;
|
||||||
|
private int cost;
|
||||||
|
|
||||||
|
public SupportTankDTO(){}
|
||||||
|
|
||||||
|
public SupportTankDTO(Tank tank){
|
||||||
|
this.id = tank.getId();
|
||||||
|
this.nationId = tank.getNation().getId();
|
||||||
|
this.levelId = tank.getLevel().getId();
|
||||||
|
this.name = tank.getName();
|
||||||
|
this.cost = tank.getCost();
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||||
|
public Long getId(){
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName(){
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getNationId(){
|
||||||
|
return nationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNationId(Long nationId) {
|
||||||
|
this.nationId = nationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getLevelId(){
|
||||||
|
return levelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLevelId(Long levelId) {
|
||||||
|
this.levelId = levelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCost(){
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCost(int cost) {
|
||||||
|
this.cost = cost;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package premium_store.controller.DTO;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import premium_store.model.Tank;
|
||||||
|
|
||||||
|
public class TankDTO {
|
||||||
|
private long id;
|
||||||
|
private String name;
|
||||||
|
private SimpleNationDTO nation;
|
||||||
|
private LevelDTO level;
|
||||||
|
private int cost;
|
||||||
|
|
||||||
|
public TankDTO(){}
|
||||||
|
|
||||||
|
public TankDTO(Tank tank){
|
||||||
|
this.id = tank.getId();
|
||||||
|
this.nation = new SimpleNationDTO(tank.getNation());
|
||||||
|
this.level = new LevelDTO(tank.getLevel());
|
||||||
|
this.name = tank.getName();
|
||||||
|
this.cost = tank.getCost();
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||||
|
public long getId(){
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName(){
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleNationDTO getNation(){
|
||||||
|
return nation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNation(SimpleNationDTO nation) {
|
||||||
|
this.nation = nation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LevelDTO getLevel(){
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLevel(LevelDTO level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCost(){
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCost(int cost) {
|
||||||
|
this.cost = cost;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
package premium_store.controller.controller;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import premium_store.controller.DTO.*;
|
||||||
|
import premium_store.service.GameClientService;
|
||||||
|
import premium_store.service.TankService;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/client")
|
||||||
|
public class ClientMvcController {
|
||||||
|
private final GameClientService gameClientService;
|
||||||
|
private final TankService tankService;
|
||||||
|
|
||||||
|
public ClientMvcController(GameClientService gameClientService, TankService tankService){
|
||||||
|
this.gameClientService = gameClientService;
|
||||||
|
this.tankService = tankService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public String getClients(Model model){
|
||||||
|
model.addAttribute("clients",
|
||||||
|
gameClientService.findAllClients().stream()
|
||||||
|
.map(ClientDTO::new)
|
||||||
|
.toList());
|
||||||
|
|
||||||
|
return "client";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = {"/edit", "/edit/{id}"})
|
||||||
|
public String editClient(@PathVariable(required = false) Long id, Model model){
|
||||||
|
if(id == null || id <= 0){
|
||||||
|
model.addAttribute("supportClientDTO", new SupportClientDTO());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
model.addAttribute("clientId", id);
|
||||||
|
model.addAttribute("supportClientDTO", new SupportClientDTO(gameClientService.findClient(id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<TankDTO> tanks = tankService.findAllTanks().stream()
|
||||||
|
.map(TankDTO::new)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
model.addAttribute("tanks", tanks);
|
||||||
|
|
||||||
|
return "client-edit";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = {"/tanksOfClient", "/tanksOfClient/{id}"})
|
||||||
|
public String editTanksOfClient(@PathVariable(required = false) Long id, Model model){
|
||||||
|
if(id == null || id <= 0){
|
||||||
|
model.addAttribute("clientDTO", new ClientDTO());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
model.addAttribute("clientId", id);
|
||||||
|
model.addAttribute("clientDTO", new ClientDTO(gameClientService.findClient(id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return "tanks-of-client-edit";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = {"", "/{id}"})
|
||||||
|
public String saveClient(@PathVariable(required = false) Long id,
|
||||||
|
@ModelAttribute @Valid SupportClientDTO clientDTO,
|
||||||
|
BindingResult bindingResult,
|
||||||
|
Model model){
|
||||||
|
if(bindingResult.hasErrors()){
|
||||||
|
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||||
|
return "client-edit";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(id == null || id <= 0){
|
||||||
|
gameClientService.addClient(clientDTO.getNickName(), clientDTO.getNickName(), clientDTO.getBalance());
|
||||||
|
} else {
|
||||||
|
gameClientService.updateClient(clientDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "redirect:/client";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/delete/{id}")
|
||||||
|
public String deleteClient(@PathVariable Long id){
|
||||||
|
gameClientService.deleteClient(id);
|
||||||
|
return "redirect:/tank";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package premium_store.controller.controller;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import premium_store.WebConfiguration;
|
||||||
|
import premium_store.controller.DTO.ClientDTO;
|
||||||
|
import premium_store.service.GameClientService;
|
||||||
|
import premium_store.service.TankService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping(WebConfiguration.REST_API + "/client")
|
||||||
|
public class GameClientController {
|
||||||
|
private final GameClientService gameClientService;
|
||||||
|
private final TankService tankService;
|
||||||
|
|
||||||
|
public GameClientController(GameClientService gameClientService, TankService tankService){
|
||||||
|
this.gameClientService = gameClientService;
|
||||||
|
this.tankService = tankService;
|
||||||
|
}
|
||||||
|
|
||||||
|
//аннотация PathVariable связывает значения id из URL и Long id
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public ClientDTO getClient(@PathVariable Long id) {
|
||||||
|
return new ClientDTO(gameClientService.findClient(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
//с помощью Java Stream преобразуем набор пришедших данных в объекты StudentDto
|
||||||
|
@GetMapping("/")
|
||||||
|
public List<ClientDTO> getClients() {
|
||||||
|
return gameClientService.findAllClients().stream()
|
||||||
|
.map(ClientDTO::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/")
|
||||||
|
public ClientDTO createClient(@RequestParam("nickName") String nickName,
|
||||||
|
@RequestParam("email") String email,
|
||||||
|
@RequestParam("balance") Integer balance) {
|
||||||
|
return new ClientDTO(gameClientService.addClient(nickName, email, balance));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public ClientDTO updateClient(@PathVariable Long id,
|
||||||
|
@RequestParam("nickName") String nickName,
|
||||||
|
@RequestParam("email") String email,
|
||||||
|
@RequestParam("balance") Integer balance,
|
||||||
|
@RequestParam("tankId") Long tankId) {
|
||||||
|
return new ClientDTO(gameClientService.updateClient(id, nickName, email, balance, tankService.findTank(tankId)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public ClientDTO deleteClient(@PathVariable Long id) {
|
||||||
|
return new ClientDTO(gameClientService.deleteClient(id));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
package premium_store.controller.controller;
|
||||||
|
|
||||||
|
import net.bytebuddy.implementation.bind.MethodDelegationBinder;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import premium_store.controller.DTO.FullNationDTO;
|
||||||
|
import premium_store.controller.DTO.LevelDTO;
|
||||||
|
import premium_store.controller.DTO.SimpleNationDTO;
|
||||||
|
import premium_store.service.NationService;
|
||||||
|
import premium_store.service.TankLevelService;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/level")
|
||||||
|
public class LevelMvcController {
|
||||||
|
private final TankLevelService levelService;
|
||||||
|
|
||||||
|
public LevelMvcController(TankLevelService levelService){
|
||||||
|
this.levelService = levelService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public String getLevels(Model model){
|
||||||
|
model.addAttribute("levels",
|
||||||
|
levelService.findAllLevels().stream()
|
||||||
|
.map(LevelDTO::new)
|
||||||
|
.toList());
|
||||||
|
return "level";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = {"/edit", "/edit/{id}"})
|
||||||
|
public String editLevel(@PathVariable(required = false) Long id, Model model){
|
||||||
|
if(id == null || id <= 0){
|
||||||
|
model.addAttribute("levelDTO", new LevelDTO());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
model.addAttribute("levelId", id);
|
||||||
|
model.addAttribute("levelDTO", new LevelDTO(levelService.findLevel(id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return "level-edit";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = {"", "/{id}"})
|
||||||
|
public String saveLevel(@PathVariable(required = false) Long id,
|
||||||
|
@ModelAttribute @Valid LevelDTO levelDTO,
|
||||||
|
BindingResult bindingResult,
|
||||||
|
Model model){
|
||||||
|
if(bindingResult.hasErrors()){
|
||||||
|
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||||
|
return "level-edit";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(id == null || id <= 0){
|
||||||
|
levelService.addLevel(levelDTO.getLevel());
|
||||||
|
} else {
|
||||||
|
levelService.updateLevel(id, levelDTO.getLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
return "redirect:/level";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/delete/{id}")
|
||||||
|
public String deleteLevel(@PathVariable Long id){
|
||||||
|
levelService.deleteLevel(id);
|
||||||
|
return "redirect:/level";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package premium_store.controller.controller;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import premium_store.WebConfiguration;
|
||||||
|
import premium_store.controller.DTO.FullNationDTO;
|
||||||
|
import premium_store.service.NationService;
|
||||||
|
import premium_store.service.TankService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
//привязываем наш контроллер к придуманному корневому URL благодаря аннотациям
|
||||||
|
//здесь происходит внедрение зависимости нашего сервиса
|
||||||
|
//так же здесь прописываем вызовы методов CRUD в привязке к URL
|
||||||
|
@RestController
|
||||||
|
@CrossOrigin
|
||||||
|
@RequestMapping(WebConfiguration.REST_API + "/nation")
|
||||||
|
public class NationController {
|
||||||
|
private final NationService nationService;
|
||||||
|
private final TankService tankService;
|
||||||
|
|
||||||
|
public NationController(NationService nationService, TankService tankService){
|
||||||
|
this.nationService = nationService;
|
||||||
|
this.tankService = tankService;
|
||||||
|
}
|
||||||
|
|
||||||
|
//аннотация PathVariable связывает значения id из URL и Long id
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public FullNationDTO getNation(@PathVariable Long id) {
|
||||||
|
return new FullNationDTO(nationService.findNation(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
//с помощью Java Stream преобразуем набор пришедших данных в объекты StudentDto
|
||||||
|
@GetMapping("/")
|
||||||
|
public List<FullNationDTO> getNations() {
|
||||||
|
return nationService.findAllNations().stream()
|
||||||
|
.map(FullNationDTO::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/")
|
||||||
|
public FullNationDTO createNation(@RequestParam("nation") String nation) {
|
||||||
|
return new FullNationDTO(nationService.addNation(nation));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public FullNationDTO updateNation(@PathVariable Long id,
|
||||||
|
@RequestParam("nation") String nation,
|
||||||
|
@RequestParam(value = "tankId", required = false) Long tankId ) {
|
||||||
|
return new FullNationDTO(nationService.updateNation(id, nation, (tankId > 0) ? tankService.findTank(tankId) : null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public FullNationDTO deleteNation(@PathVariable Long id) {
|
||||||
|
return new FullNationDTO(nationService.deleteNation(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,82 @@
|
|||||||
|
package premium_store.controller.controller;
|
||||||
|
|
||||||
|
import net.bytebuddy.implementation.bind.MethodDelegationBinder;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import premium_store.controller.DTO.FullNationDTO;
|
||||||
|
import premium_store.controller.DTO.SimpleNationDTO;
|
||||||
|
import premium_store.service.NationService;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/nation")
|
||||||
|
public class NationMvcController {
|
||||||
|
private final NationService nationService;
|
||||||
|
|
||||||
|
public NationMvcController(NationService nationService){
|
||||||
|
this.nationService = nationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public String getNations(Model model){
|
||||||
|
model.addAttribute("nations",
|
||||||
|
nationService.findAllNations().stream()
|
||||||
|
.map(FullNationDTO::new)
|
||||||
|
.toList());
|
||||||
|
return "nation";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = {"/edit", "/edit/{id}"})
|
||||||
|
public String editNation(@PathVariable(required = false) Long id, Model model){
|
||||||
|
if(id == null || id <= 0){
|
||||||
|
model.addAttribute("simpleNationDTO", new SimpleNationDTO());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
model.addAttribute("nationId", id);
|
||||||
|
model.addAttribute("simpleNationDTO", new SimpleNationDTO(nationService.findNation(id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return "nation-edit";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = {"/editTank", "/editTank/{id}"})
|
||||||
|
public String editTankNation(@PathVariable(required = false) Long id, Model model){
|
||||||
|
if(id == null || id <= 0){
|
||||||
|
model.addAttribute("fullNationDTO", new FullNationDTO());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
model.addAttribute("nationId", id);
|
||||||
|
model.addAttribute("fullNationDTO", new FullNationDTO(nationService.findNation(id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return "nation-tank-edit";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = {"", "/{id}"})
|
||||||
|
public String saveNation(@PathVariable(required = false) Long id,
|
||||||
|
@ModelAttribute @Valid SimpleNationDTO simpleNationDTO,
|
||||||
|
BindingResult bindingResult,
|
||||||
|
Model model){
|
||||||
|
if(bindingResult.hasErrors()){
|
||||||
|
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||||
|
return "nation-edit";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(id == null || id <= 0){
|
||||||
|
nationService.addNation(simpleNationDTO.getNation());
|
||||||
|
} else {
|
||||||
|
nationService.updateNation(id, simpleNationDTO.getNation(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "redirect:/nation";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/delete/{id}")
|
||||||
|
public String deleteNation(@PathVariable Long id){
|
||||||
|
nationService.deleteNation(id);
|
||||||
|
return "redirect:/nation";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package premium_store.controller.controller;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import premium_store.WebConfiguration;
|
||||||
|
import premium_store.controller.DTO.TankDTO;
|
||||||
|
import premium_store.service.NationService;
|
||||||
|
import premium_store.service.TankLevelService;
|
||||||
|
import premium_store.service.TankService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@CrossOrigin
|
||||||
|
@RequestMapping(WebConfiguration.REST_API + "/tank")
|
||||||
|
public class TankController {
|
||||||
|
private final TankService tankService;
|
||||||
|
private final TankLevelService tankLevelService;
|
||||||
|
private final NationService nationService;
|
||||||
|
|
||||||
|
public TankController(TankService tankService, TankLevelService tankLevelService, NationService nationService){
|
||||||
|
this.tankService = tankService;
|
||||||
|
this.tankLevelService = tankLevelService;
|
||||||
|
this.nationService = nationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
//аннотация PathVariable связывает значения id из URL и Long id
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public TankDTO getTank(@PathVariable Long id) {
|
||||||
|
return new TankDTO(tankService.findTank(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
//с помощью Java Stream преобразуем набор пришедших данных в объекты TankDTO
|
||||||
|
@GetMapping("/")
|
||||||
|
public List<TankDTO> getTanks() {
|
||||||
|
return tankService.findAllTanks().stream()
|
||||||
|
.map(TankDTO::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/filteredList/")
|
||||||
|
public List<TankDTO> getFilteredTanks(@RequestParam("nation") String nation,
|
||||||
|
@RequestParam("firstLevel") int firstLevel,
|
||||||
|
@RequestParam("secondLevel") int secondLevel) {
|
||||||
|
return tankService.findListTank(nation, firstLevel, secondLevel).stream()
|
||||||
|
.map(TankDTO::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/")
|
||||||
|
public TankDTO createTank(@RequestParam("firstName") String name,
|
||||||
|
@RequestParam("nationId") Long nationId,
|
||||||
|
@RequestParam("levelId") Long tankLevelId,
|
||||||
|
@RequestParam("cost") int cost
|
||||||
|
) {
|
||||||
|
return new TankDTO(tankService.addTank(name, nationService.findNation(nationId), tankLevelService.findLevel(tankLevelId), cost));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public TankDTO updateTank(@PathVariable Long id,
|
||||||
|
@RequestParam("firstName") String name,
|
||||||
|
@RequestParam("nationId") Long nationId,
|
||||||
|
@RequestParam("levelId") Long tankLevelId,
|
||||||
|
@RequestParam("cost") int cost
|
||||||
|
) {
|
||||||
|
return new TankDTO(tankService.updateTank(id, name, nationService.findNation(nationId), tankLevelService.findLevel(tankLevelId), cost));
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public TankDTO deleteTank(@PathVariable Long id) {
|
||||||
|
return new TankDTO(tankService.deleteTank(id));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package premium_store.controller.controller;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import premium_store.WebConfiguration;
|
||||||
|
import premium_store.controller.DTO.LevelDTO;
|
||||||
|
import premium_store.service.TankLevelService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
//привязываем наш контроллер к придуманному корневому URL благодаря аннотациям
|
||||||
|
//здесь происходит внедрение зависимости нашего сервиса
|
||||||
|
//так же здесь прописываем вызовы методов CRUD в привязке к URL
|
||||||
|
@RestController
|
||||||
|
@RequestMapping(WebConfiguration.REST_API + "/level")
|
||||||
|
public class TankLevelController {
|
||||||
|
private final TankLevelService tankLevelService;
|
||||||
|
|
||||||
|
public TankLevelController(TankLevelService tankLevelService){
|
||||||
|
this.tankLevelService = tankLevelService;
|
||||||
|
}
|
||||||
|
|
||||||
|
//аннотация PathVariable связывает значения id из URL и Long id
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public LevelDTO getLevel(@PathVariable Long id) {
|
||||||
|
return new LevelDTO(tankLevelService.findLevel(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
//с помощью Java Stream преобразуем набор пришедших данных в объекты StudentDto
|
||||||
|
@GetMapping("/")
|
||||||
|
public List<LevelDTO> getLevels() {
|
||||||
|
return tankLevelService.findAllLevels().stream()
|
||||||
|
.map(LevelDTO::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/")
|
||||||
|
public LevelDTO createLevel(@RequestParam("Level") int level) {
|
||||||
|
return new LevelDTO(tankLevelService.addLevel(level));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public LevelDTO updateLevel(@PathVariable Long id,
|
||||||
|
@RequestParam("Level") int level) {
|
||||||
|
return new LevelDTO(tankLevelService.updateLevel(id, level));
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public LevelDTO deleteLevel(@PathVariable Long id) {
|
||||||
|
return new LevelDTO(tankLevelService.deleteLevel(id));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,113 @@
|
|||||||
|
package premium_store.controller.controller;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import premium_store.controller.DTO.*;
|
||||||
|
import premium_store.service.NationService;
|
||||||
|
import premium_store.service.TankLevelService;
|
||||||
|
import premium_store.service.TankService;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/tank")
|
||||||
|
public class TankMvcController {
|
||||||
|
private final TankService tankService;
|
||||||
|
private final NationService nationService;
|
||||||
|
private final TankLevelService tankLevelService;
|
||||||
|
|
||||||
|
public TankMvcController(TankService tankService, NationService nationService, TankLevelService tankLevelService){
|
||||||
|
this.tankService = tankService;
|
||||||
|
this.nationService = nationService;
|
||||||
|
this.tankLevelService = tankLevelService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public String getTanks(Model model){
|
||||||
|
model.addAttribute("tanks",
|
||||||
|
tankService.findAllTanks().stream()
|
||||||
|
.map(TankDTO::new)
|
||||||
|
.toList());
|
||||||
|
|
||||||
|
List<SimpleNationDTO> nations = nationService.findAllNations().stream()
|
||||||
|
.map(SimpleNationDTO::new)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
model.addAttribute("nations", nations);
|
||||||
|
|
||||||
|
List<LevelDTO> levels = tankLevelService.findAllLevels().stream()
|
||||||
|
.map(LevelDTO::new)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
model.addAttribute("levels", levels);
|
||||||
|
|
||||||
|
model.addAttribute("sortDTO", new SortDTO());
|
||||||
|
|
||||||
|
return "tank";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = {"/edit", "/edit/{id}"})
|
||||||
|
public String editTank(@PathVariable(required = false) Long id, Model model){
|
||||||
|
if(id == null || id <= 0){
|
||||||
|
model.addAttribute("supportTankDTO", new SupportTankDTO());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
model.addAttribute("tankId", id);
|
||||||
|
model.addAttribute("supportTankDTO", new SupportTankDTO(tankService.findTank(id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<SimpleNationDTO> nations = nationService.findAllNations().stream()
|
||||||
|
.map(SimpleNationDTO::new)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
model.addAttribute("nations", nations);
|
||||||
|
|
||||||
|
List<LevelDTO> levels = tankLevelService.findAllLevels().stream()
|
||||||
|
.map(LevelDTO::new)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
model.addAttribute("levels", levels);
|
||||||
|
|
||||||
|
return "tank-edit";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/filteredList")
|
||||||
|
public String getFilteredTanks(@ModelAttribute SortDTO sortDTO,
|
||||||
|
Model model) {
|
||||||
|
List<TankDTO> tanks = tankService.findListTank(sortDTO.getNation(), sortDTO.getFirstLevel(), sortDTO.getSecondLevel()).stream()
|
||||||
|
.map(TankDTO::new)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
model.addAttribute("tanks", tanks);
|
||||||
|
|
||||||
|
return "filter";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = {"", "/{id}"})
|
||||||
|
public String saveTank(@PathVariable(required = false) Long id,
|
||||||
|
@ModelAttribute @Valid SupportTankDTO tankDTO,
|
||||||
|
BindingResult bindingResult,
|
||||||
|
Model model){
|
||||||
|
if(bindingResult.hasErrors()){
|
||||||
|
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||||
|
return "tank-edit";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(id == null || id <= 0){
|
||||||
|
tankService.addTank(tankDTO);
|
||||||
|
} else {
|
||||||
|
tankService.updateTank(tankDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "redirect:/tank";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/delete/{id}")
|
||||||
|
public String deleteTank(@PathVariable Long id){
|
||||||
|
tankService.deleteTank(id);
|
||||||
|
return "redirect:/tank";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
package premium_store.model;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "GAMECLIENTS")
|
||||||
|
public class GameClient {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(name = "nickName", nullable = false, length = 255)
|
||||||
|
private String nickName;
|
||||||
|
|
||||||
|
@Column(name = "email", nullable = false, length = 255)
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
@Column(name = "balance")
|
||||||
|
private Integer balance;
|
||||||
|
|
||||||
|
@ManyToMany(fetch = FetchType.EAGER)
|
||||||
|
private List<Tank> tanks = new ArrayList<>();
|
||||||
|
|
||||||
|
public GameClient(){ }
|
||||||
|
|
||||||
|
public GameClient(String nickName, String email, Integer balance){
|
||||||
|
this.nickName = nickName;
|
||||||
|
this.email = email;
|
||||||
|
this.balance = balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId(){
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNickName(){
|
||||||
|
return nickName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNickName(String nickName){
|
||||||
|
this.nickName = nickName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail(){
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email){
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getBalance(){
|
||||||
|
return balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBalance(Integer balance){
|
||||||
|
this.balance = balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Tank> getTanks(){
|
||||||
|
return tanks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTanks(Tank tank){
|
||||||
|
this.tanks.add(tank);
|
||||||
|
}
|
||||||
|
|
||||||
|
//метод для сравнения
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
GameClient gameClient = (GameClient) o;
|
||||||
|
|
||||||
|
return Objects.equals(id, gameClient.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
//преобразование данных по объекту в строчку
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Client{" +
|
||||||
|
"id=" + id +
|
||||||
|
", nickName='" + nickName + '\'' +
|
||||||
|
", email='" + email + '\'' +
|
||||||
|
", balance='" + balance + '\'' +
|
||||||
|
", tanks='" + tanks.stream().map(Object::toString).collect(Collectors.joining(", ")) + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
|||||||
|
package premium_store.model;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "NATIONS")
|
||||||
|
public class Nation {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(name = "nation")
|
||||||
|
private String nation;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "nation", fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
|
||||||
|
private List<Tank> tanksOfThisNation = new ArrayList<>();
|
||||||
|
|
||||||
|
public Nation() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Nation(String nation) {
|
||||||
|
this.nation = nation;
|
||||||
|
}
|
||||||
|
|
||||||
|
//возвращает id
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
//возвращает нацию
|
||||||
|
public String getNation() {
|
||||||
|
return nation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNation(String nation) {
|
||||||
|
this.nation = nation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Tank> getTanksOfThisNation(){
|
||||||
|
return tanksOfThisNation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTanksOfThisNation(Tank newTank){
|
||||||
|
this.tanksOfThisNation.add(newTank);
|
||||||
|
}
|
||||||
|
|
||||||
|
//метод для сравнения
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Nation nation = (Nation) o;
|
||||||
|
|
||||||
|
return Objects.equals(id, nation.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
//преобразование данных по объекту в строчку
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Nation{" +
|
||||||
|
"id=" + id +
|
||||||
|
", nation='" + nation + '\'' +
|
||||||
|
", tanksOfThisNation='" + tanksOfThisNation.stream().map(Object::toString).collect(Collectors.joining(", ")) + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,101 @@
|
|||||||
|
package premium_store.model;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "TANKS")
|
||||||
|
public class Tank {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
|
@JoinColumn(name = "nation")
|
||||||
|
private Nation nation;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
|
@JoinColumn(name = "tankLevel")
|
||||||
|
private TankLevel tankLevel;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private int cost;
|
||||||
|
|
||||||
|
public Tank() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tank(String name, Nation nation, TankLevel tankLevel, int cost) {
|
||||||
|
this.name = name;
|
||||||
|
this.nation = nation;
|
||||||
|
this.tankLevel = tankLevel;
|
||||||
|
this.cost = cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId(){
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCost() {
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCost(int cost) {
|
||||||
|
this.cost = cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TankLevel getLevel() {
|
||||||
|
return tankLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLevel(TankLevel tankLevel) {
|
||||||
|
this.tankLevel = tankLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Nation getNation() {
|
||||||
|
return nation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNation(Nation nation) {
|
||||||
|
this.nation = nation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
|
||||||
|
if (!(o instanceof Tank tank)) return false;
|
||||||
|
|
||||||
|
return Objects.equals(getId(), tank.getId()) && Objects.equals(getName(), tank.getName())
|
||||||
|
&& Objects.equals(getCost(), tank.getCost())
|
||||||
|
&& Objects.equals(getLevel(), tank.getLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
//преобразование данных по объекту в строчку
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Tank{" +
|
||||||
|
"id=" + id +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
", nation='" + nation.getNation() + '\'' +
|
||||||
|
", level='" + tankLevel.getLevel() + '\'' +
|
||||||
|
", cost='" + cost + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
|||||||
|
package premium_store.model;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "TANKLEVELS")
|
||||||
|
public class TankLevel {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(name = "level", nullable = false)
|
||||||
|
private int level;
|
||||||
|
|
||||||
|
public TankLevel() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public TankLevel(int level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
//возвращает id
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
//возвращает нацию
|
||||||
|
public int getLevel() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLevel(int level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
//метод для сравнения
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
TankLevel tankLevel = (TankLevel) o;
|
||||||
|
|
||||||
|
return Objects.equals(id, tankLevel.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
//преобразование данных по объекту в строчку
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Level{" +
|
||||||
|
"id=" + id +
|
||||||
|
", level='" + level + '}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
|||||||
|
package premium_store.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import premium_store.model.GameClient;
|
||||||
|
|
||||||
|
public interface GameClientRepository extends JpaRepository<GameClient, Long> {
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package premium_store.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import premium_store.model.Nation;
|
||||||
|
|
||||||
|
//класс для взаимодействия с БД вместо низкоуровневого EntityManager
|
||||||
|
//передаём тип класса и тип id его элементов
|
||||||
|
public interface NationRepository extends JpaRepository<Nation, Long> {
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package premium_store.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import premium_store.model.TankLevel;
|
||||||
|
|
||||||
|
//класс для взаимодействия с БД вместо низкоуровневого EntityManager
|
||||||
|
//передаём тип класса и тип id его элементов
|
||||||
|
public interface TankLevelRepository extends JpaRepository<TankLevel, Long> {
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package premium_store.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import premium_store.model.Tank;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface TankRepository extends JpaRepository<Tank, Long> {
|
||||||
|
@Query("SELECT t FROM Tank t WHERE t.nation.nation = :nation AND t.tankLevel.level BETWEEN :llevelid AND :l2levelid")
|
||||||
|
List<Tank> checkNationAndLevel(
|
||||||
|
@Param("nation") String nation,
|
||||||
|
@Param("llevelid") int levelOne,
|
||||||
|
@Param("l2levelid") int levelTwo);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,109 @@
|
|||||||
|
package premium_store.service;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import premium_store.controller.DTO.ClientDTO;
|
||||||
|
import premium_store.controller.DTO.SupportClientDTO;
|
||||||
|
import premium_store.model.GameClient;
|
||||||
|
import premium_store.model.Tank;
|
||||||
|
import premium_store.repository.GameClientRepository;
|
||||||
|
import premium_store.repository.TankRepository;
|
||||||
|
import premium_store.service.exception.ClientNotFoundException;
|
||||||
|
import premium_store.util.validation.ValidatorUtil;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class GameClientService {
|
||||||
|
private final GameClientRepository gameClientRepository;
|
||||||
|
private final TankRepository tankRepository;
|
||||||
|
private final ValidatorUtil validatorUtil;
|
||||||
|
|
||||||
|
public GameClientService(GameClientRepository gameClientRepository, TankRepository tankRepository, ValidatorUtil validatorUtil){
|
||||||
|
this.gameClientRepository = gameClientRepository;
|
||||||
|
this.tankRepository = tankRepository;
|
||||||
|
this.validatorUtil = validatorUtil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public GameClient addClient(String newNickName, String newEmail, Integer newBallance) {
|
||||||
|
final GameClient gameClient = new GameClient(newNickName, newEmail, newBallance);
|
||||||
|
validatorUtil.validate(gameClient);
|
||||||
|
|
||||||
|
return gameClientRepository.save(gameClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public GameClient findClient(Long id) {
|
||||||
|
final Optional<GameClient> client = gameClientRepository.findById(id);
|
||||||
|
|
||||||
|
return client.orElseThrow(() -> new ClientNotFoundException(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public List<GameClient> findAllClients() {
|
||||||
|
return gameClientRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public GameClient updateClient(Long id, String newNickName, String newEmail, Integer newBalance, Tank newTank) {
|
||||||
|
if (id <= 0) {
|
||||||
|
throw new IllegalArgumentException("Invalid id");
|
||||||
|
}
|
||||||
|
|
||||||
|
final GameClient currentGameClient = findClient(id);
|
||||||
|
|
||||||
|
if (StringUtils.hasText(newNickName)){
|
||||||
|
currentGameClient.setNickName(newNickName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(StringUtils.hasText(newEmail)){
|
||||||
|
currentGameClient.setEmail(newEmail);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newBalance != null){
|
||||||
|
currentGameClient.setBalance(newBalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newTank != null){
|
||||||
|
currentGameClient.setTanks(newTank);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gameClientRepository.save(currentGameClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public GameClient updateClient(SupportClientDTO clientDTO) {
|
||||||
|
if (clientDTO.getId() <= 0) {
|
||||||
|
throw new IllegalArgumentException("Invalid id");
|
||||||
|
}
|
||||||
|
|
||||||
|
final GameClient currentGameClient = findClient(clientDTO.getId());
|
||||||
|
|
||||||
|
currentGameClient.setNickName(clientDTO.getNickName());
|
||||||
|
currentGameClient.setEmail(clientDTO.getEmail());
|
||||||
|
currentGameClient.setBalance(clientDTO.getBalance());
|
||||||
|
|
||||||
|
if(clientDTO.getTankId() != null){
|
||||||
|
currentGameClient.setTanks(tankRepository.getById(clientDTO.getTankId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return gameClientRepository.save(currentGameClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public GameClient deleteClient(Long id) {
|
||||||
|
final GameClient currentGameClient = findClient(id);
|
||||||
|
gameClientRepository.delete(currentGameClient);
|
||||||
|
|
||||||
|
return currentGameClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
//прямой sql-запрос на удаление всех записей в таблице
|
||||||
|
@Transactional
|
||||||
|
public void deleteAllClients() {
|
||||||
|
gameClientRepository.deleteAll();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
package premium_store.service;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import premium_store.model.Nation;
|
||||||
|
import premium_store.model.Tank;
|
||||||
|
import premium_store.repository.NationRepository;
|
||||||
|
import premium_store.service.exception.NationNotFoundException;
|
||||||
|
import premium_store.util.validation.ValidatorUtil;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class NationService {
|
||||||
|
private final NationRepository nationRepository;
|
||||||
|
private final ValidatorUtil validatorUtil;
|
||||||
|
|
||||||
|
public NationService(NationRepository nationRepository, ValidatorUtil validatorUtil){
|
||||||
|
this.nationRepository = nationRepository;
|
||||||
|
this.validatorUtil = validatorUtil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Nation addNation(String nameNation){
|
||||||
|
final Nation nation = new Nation(nameNation);
|
||||||
|
validatorUtil.validate(nation);
|
||||||
|
|
||||||
|
return nationRepository.save(nation);
|
||||||
|
}
|
||||||
|
|
||||||
|
//здесь используем Optional - спец. тип данных, позволяющий определять, вернулось ли что-то при вызове метода, или вернулся null
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public Nation findNation(Long id){
|
||||||
|
final Optional<Nation> nation = nationRepository.findById(id);
|
||||||
|
|
||||||
|
//благодаря Optional можем вызвать orElseThrow, который в случае null сделает проброс кастомного исключения
|
||||||
|
return nation.orElseThrow(() -> new NationNotFoundException(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public List<Nation> findAllNations() {
|
||||||
|
return nationRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Nation updateNation(Long id, String newNation, Tank newTank) {
|
||||||
|
if(id <= 0){
|
||||||
|
throw new IllegalArgumentException(String.format("Incorrect id: [%s]", id));
|
||||||
|
}
|
||||||
|
|
||||||
|
final Nation currentNation = findNation(id);
|
||||||
|
|
||||||
|
if (StringUtils.hasText(newNation)) {
|
||||||
|
currentNation.setNation(newNation);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newTank != null){
|
||||||
|
currentNation.setTanksOfThisNation(newTank);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nationRepository.save(currentNation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Nation deleteNation(Long id) {
|
||||||
|
final Nation currentNation = findNation(id);
|
||||||
|
nationRepository.delete(currentNation);
|
||||||
|
|
||||||
|
return currentNation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void deleteAllNations() {
|
||||||
|
nationRepository.deleteAll();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
package premium_store.service;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import premium_store.model.TankLevel;
|
||||||
|
import premium_store.repository.TankLevelRepository;
|
||||||
|
import premium_store.service.exception.LevelNotFoundException;
|
||||||
|
import premium_store.util.validation.ValidatorUtil;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
//сервис после удаления EntityManager и добавления нашего репозитория. То есть у него уже все методы работы с полями прописаны за нас?
|
||||||
|
@Service
|
||||||
|
public class TankLevelService {
|
||||||
|
private final TankLevelRepository tankLevelRepository;
|
||||||
|
private final ValidatorUtil validatorUtil;
|
||||||
|
|
||||||
|
public TankLevelService(TankLevelRepository tankLevelRepository, ValidatorUtil validatorUtil){
|
||||||
|
this.tankLevelRepository = tankLevelRepository;
|
||||||
|
this.validatorUtil = validatorUtil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public TankLevel addLevel(int newLevel) {
|
||||||
|
final TankLevel tankLevel = new TankLevel(newLevel);
|
||||||
|
validatorUtil.validate(tankLevel);
|
||||||
|
|
||||||
|
return tankLevelRepository.save(tankLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
//здесь используем Optional - спец. тип данных, позволяющий определять, вернулось ли что-то при вызове метода, или вернулся null
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public TankLevel findLevel(Long id) {
|
||||||
|
final Optional<TankLevel> level = tankLevelRepository.findById(id);
|
||||||
|
|
||||||
|
//благодаря Optional можем вызвать orElseThrow, который в случае null сделает проброс кастомного исключения
|
||||||
|
return level.orElseThrow(() -> new LevelNotFoundException(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public List<TankLevel> findAllLevels() {
|
||||||
|
return tankLevelRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public TankLevel updateLevel(Long id, int newLevel) {
|
||||||
|
final TankLevel currentTankLevel = findLevel(id);
|
||||||
|
currentTankLevel.setLevel(newLevel);
|
||||||
|
validatorUtil.validate(currentTankLevel);
|
||||||
|
|
||||||
|
return tankLevelRepository.save(currentTankLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public TankLevel deleteLevel(Long id) {
|
||||||
|
final TankLevel currentTankLevel = findLevel(id);
|
||||||
|
tankLevelRepository.delete(currentTankLevel);
|
||||||
|
|
||||||
|
return currentTankLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void deleteAllLevels() {
|
||||||
|
tankLevelRepository.deleteAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,126 @@
|
|||||||
|
package premium_store.service;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import premium_store.controller.DTO.SupportTankDTO;
|
||||||
|
import premium_store.controller.DTO.TankDTO;
|
||||||
|
import premium_store.model.TankLevel;
|
||||||
|
import premium_store.model.Nation;
|
||||||
|
import premium_store.model.Tank;
|
||||||
|
import premium_store.repository.NationRepository;
|
||||||
|
import premium_store.repository.TankLevelRepository;
|
||||||
|
import premium_store.repository.TankRepository;
|
||||||
|
import premium_store.service.exception.TankNotFoundException;
|
||||||
|
import premium_store.util.validation.ValidatorUtil;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class TankService {
|
||||||
|
private final TankRepository tankRepository;
|
||||||
|
private final NationRepository nationRepository;
|
||||||
|
private final TankLevelRepository levelRepository;
|
||||||
|
private final ValidatorUtil validatorUtil;
|
||||||
|
|
||||||
|
public TankService(TankRepository tankRepository, NationRepository nationRepository, TankLevelRepository levelRepository, ValidatorUtil validatorUtil){
|
||||||
|
this.tankRepository = tankRepository;
|
||||||
|
this.nationRepository = nationRepository;
|
||||||
|
this.levelRepository = levelRepository;
|
||||||
|
this.validatorUtil = validatorUtil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Tank addTank(String newName, Nation newNation, TankLevel newTankLevel, int newCost) {
|
||||||
|
final Tank tank = new Tank(newName, newNation, newTankLevel, newCost);
|
||||||
|
validatorUtil.validate(tank);
|
||||||
|
|
||||||
|
return tankRepository.save(tank);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Tank addTank(SupportTankDTO tankDTO) {
|
||||||
|
final Tank tank = new Tank(tankDTO.getName(), nationRepository.getById(tankDTO.getNationId()),
|
||||||
|
levelRepository.getById(tankDTO.getLevelId()), tankDTO.getCost());
|
||||||
|
validatorUtil.validate(tank);
|
||||||
|
|
||||||
|
return tankRepository.save(tank);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public Tank findTank(Long id) {
|
||||||
|
final Optional<Tank> tank = tankRepository.findById(id);
|
||||||
|
|
||||||
|
return tank.orElseThrow(() -> new TankNotFoundException(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public List<Tank> findAllTanks() {
|
||||||
|
return tankRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Tank updateTank(Long id, String newName, Nation newNation,
|
||||||
|
TankLevel newLevel, int newCost) {
|
||||||
|
if (id <= 0) {
|
||||||
|
throw new IllegalArgumentException("Invalid id");
|
||||||
|
}
|
||||||
|
|
||||||
|
final Tank currentTank = findTank(id);
|
||||||
|
|
||||||
|
if (StringUtils.hasText(newName)){
|
||||||
|
currentTank.setName(newName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newNation != null){
|
||||||
|
currentTank.setNation(newNation);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newLevel != null){
|
||||||
|
currentTank.setLevel(newLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newCost > 0){
|
||||||
|
currentTank.setCost(newCost);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tankRepository.save(currentTank);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Tank updateTank(SupportTankDTO tankDTO) {
|
||||||
|
if (tankDTO.getId() <= 0) {
|
||||||
|
throw new IllegalArgumentException("Invalid id");
|
||||||
|
}
|
||||||
|
|
||||||
|
final Tank currentTank = findTank(tankDTO.getId());
|
||||||
|
|
||||||
|
currentTank.setName(tankDTO.getName());
|
||||||
|
currentTank.setNation(nationRepository.getById(tankDTO.getNationId()));
|
||||||
|
currentTank.setLevel(levelRepository.getById(tankDTO.getLevelId()));
|
||||||
|
currentTank.setCost(tankDTO.getCost());
|
||||||
|
|
||||||
|
return tankRepository.save(currentTank);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Tank deleteTank(Long id) {
|
||||||
|
final Tank currentTank = findTank(id);
|
||||||
|
tankRepository.delete(currentTank);
|
||||||
|
|
||||||
|
return currentTank;
|
||||||
|
}
|
||||||
|
|
||||||
|
//запрос на удаление всех записей в таблице
|
||||||
|
@Transactional
|
||||||
|
public void deleteAllTanks() {
|
||||||
|
tankRepository.deleteAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public List<Tank> findListTank(String nationName, int levelFirst, int levelSecond) {
|
||||||
|
return tankRepository.checkNationAndLevel(nationName, levelFirst, levelSecond);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
|||||||
|
package premium_store.service.exception;
|
||||||
|
|
||||||
|
public class ClientNotFoundException extends RuntimeException {
|
||||||
|
public ClientNotFoundException(Long id) {
|
||||||
|
super(String.format("Client with id [%s] is not found", id));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package premium_store.service.exception;
|
||||||
|
|
||||||
|
//класс-обработчик ошибки, когда вытаемся вытащить студента из бд по некорректному id
|
||||||
|
//наследуем от RuntimeException, т. к. он позволяет его проще вызывать
|
||||||
|
public class LevelNotFoundException extends RuntimeException {
|
||||||
|
public LevelNotFoundException(Long id) {
|
||||||
|
super(String.format("Level with id [%s] is not found", id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
|||||||
|
package premium_store.service.exception;
|
||||||
|
|
||||||
|
public class NationNotFoundException extends RuntimeException {
|
||||||
|
public NationNotFoundException(Long id) {
|
||||||
|
super(String.format("Nation with id [%s] is not found", id));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package premium_store.service.exception;
|
||||||
|
|
||||||
|
public class TankNotFoundException extends RuntimeException {
|
||||||
|
public TankNotFoundException(Long id) {
|
||||||
|
super(String.format("Tank with id [%s] is not found", id));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package premium_store.util.error;
|
||||||
|
|
||||||
|
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import premium_store.service.exception.ClientNotFoundException;
|
||||||
|
import premium_store.service.exception.LevelNotFoundException;
|
||||||
|
import premium_store.service.exception.NationNotFoundException;
|
||||||
|
import premium_store.service.exception.TankNotFoundException;
|
||||||
|
import premium_store.util.validation.ValidationException;
|
||||||
|
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
//контроллер для обработки разнообразных ошибок при работе с запросами к БД
|
||||||
|
@ControllerAdvice(annotations = RestController.class)
|
||||||
|
public class AdviceController {
|
||||||
|
//метод handleException будет вызываться при возникновении исключений типа LevelNotFoundException и т. д.
|
||||||
|
@ExceptionHandler({
|
||||||
|
LevelNotFoundException.class,
|
||||||
|
NationNotFoundException.class,
|
||||||
|
ClientNotFoundException.class,
|
||||||
|
TankNotFoundException.class,
|
||||||
|
ValidationException.class
|
||||||
|
})
|
||||||
|
public ResponseEntity<Object> handleException(Throwable e) {
|
||||||
|
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
//при исключении автоматической валидации данных
|
||||||
|
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||||
|
public ResponseEntity<Object> handleBindException(MethodArgumentNotValidException e) {
|
||||||
|
final ValidationException validationException = new ValidationException(
|
||||||
|
e.getBindingResult().getAllErrors().stream()
|
||||||
|
.map(DefaultMessageSourceResolvable::getDefaultMessage)
|
||||||
|
.collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
return handleException(validationException);
|
||||||
|
}
|
||||||
|
|
||||||
|
//обработка неизвестных ошибок
|
||||||
|
@ExceptionHandler(Exception.class)
|
||||||
|
public ResponseEntity<Object> handleUnknownException(Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
|
||||||
|
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package premium_store.util.validation;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
//класс для передачи списка ошибок, если они возникают
|
||||||
|
public class ValidationException extends RuntimeException {
|
||||||
|
public ValidationException(Set<String> errors) {
|
||||||
|
super(String.join("\n", errors));
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user