Четвёртая лабораторная работа. Frontend.
This commit is contained in:
parent
c6b23e8d96
commit
d652956ae9
Binary file not shown.
@ -28,6 +28,21 @@ public class ProductController {
|
|||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//сделать запрос + пагинация
|
||||||
|
@GetMapping("/getWithStores")
|
||||||
|
public List<ProductDTO> getProductsWithStores(){
|
||||||
|
return productService.getAllProducts().stream().filter(prod -> prod.getStore() != null)
|
||||||
|
.map(ProductDTO::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/getWithoutStores")
|
||||||
|
public List<ProductDTO> getProductsWithoutStores(){
|
||||||
|
return productService.getAllProducts().stream().filter(prod -> prod.getStore() == null)
|
||||||
|
.map(ProductDTO::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public ProductDTO createProduct(@RequestParam("productName") String productName){
|
public ProductDTO createProduct(@RequestParam("productName") String productName){
|
||||||
final Product product = productService.addProduct(productName);
|
final Product product = productService.addProduct(productName);
|
||||||
|
@ -44,9 +44,9 @@ public class StoreController {
|
|||||||
return new StoreDTO(storeService.updateStore(id, storeName));
|
return new StoreDTO(storeService.updateStore(id, storeName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/{storeId}-{productId}")
|
@PutMapping("/add")
|
||||||
public ProductDTO addProduct(@PathVariable Long storeId,
|
public ProductDTO addProduct(@RequestParam("storeId") Long storeId,
|
||||||
@PathVariable Long productId){
|
@RequestParam("productId") Long productId){
|
||||||
return new ProductDTO(storeService.addProduct(storeId, productId));
|
return new ProductDTO(storeService.addProduct(storeId, productId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,12 +7,14 @@ public class OrderedDTO {
|
|||||||
public final int quantity;
|
public final int quantity;
|
||||||
public final String productName;
|
public final String productName;
|
||||||
public final String customerFIO;
|
public final String customerFIO;
|
||||||
|
public final String storeName;
|
||||||
|
|
||||||
public OrderedDTO(Ordered ordered){
|
public OrderedDTO(Ordered ordered){
|
||||||
this.id = ordered.getId();
|
this.id = ordered.getId();
|
||||||
this.quantity = ordered.getQuantity();
|
this.quantity = ordered.getQuantity();
|
||||||
this.productName = ordered.getProduct().getName();
|
this.productName = ordered.getProduct().getName();
|
||||||
this.customerFIO = ordered.getCustomer().getLastName() + ordered.getCustomer().getFirstName() + ordered.getCustomer().getMiddleName();
|
this.storeName = ordered.getProduct().getStore().getStoreName();
|
||||||
|
this.customerFIO = ordered.getCustomer().getLastName() + " " + ordered.getCustomer().getFirstName() + " " + ordered.getCustomer().getMiddleName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
@ -30,4 +32,8 @@ public class OrderedDTO {
|
|||||||
public String getCustomerFIO() {
|
public String getCustomerFIO() {
|
||||||
return customerFIO;
|
return customerFIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getStoreName() {
|
||||||
|
return storeName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,13 @@ import java.util.List;
|
|||||||
|
|
||||||
public class ProductDTO {
|
public class ProductDTO {
|
||||||
public final Long id;
|
public final Long id;
|
||||||
public final String name;
|
public final String productName;
|
||||||
public final String storeName;
|
public final String storeName;
|
||||||
|
|
||||||
public ProductDTO(Product product){
|
public ProductDTO(Product product){
|
||||||
this.id = product.getId();
|
this.id = product.getId();
|
||||||
this.name = product.getName();
|
this.productName = product.getName();
|
||||||
this.storeName = product.getStore().getStoreName();
|
this.storeName = product.getStore() == null ? null : product.getStore().getStoreName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
@ -20,7 +20,7 @@ public class ProductDTO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return productName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStoreName() {
|
public String getStoreName() {
|
||||||
|
@ -38,8 +38,10 @@ public class Product {
|
|||||||
}
|
}
|
||||||
@PreRemove
|
@PreRemove
|
||||||
public void removeStore(){
|
public void removeStore(){
|
||||||
|
if (this.store != null) {
|
||||||
this.store.getProducts().remove(this);
|
this.store.getProducts().remove(this);
|
||||||
this.store = null;
|
this.store = null;
|
||||||
|
}
|
||||||
removeOrders();
|
removeOrders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.example.ipLab.StoreDataBase.Model;
|
package com.example.ipLab.StoreDataBase.Model;
|
||||||
|
|
||||||
import com.example.ipLab.StoreDataBase.Service.ProductService;
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
|
||||||
@ -18,7 +17,9 @@ public class Store {
|
|||||||
private String storeName;
|
private String storeName;
|
||||||
@OneToMany(fetch = FetchType.EAGER, mappedBy = "store", cascade = CascadeType.ALL, orphanRemoval = true)
|
@OneToMany(fetch = FetchType.EAGER, mappedBy = "store", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
private List<Product> products;
|
private List<Product> products;
|
||||||
public Store(){}
|
public Store(){
|
||||||
|
this.products = new ArrayList<>();
|
||||||
|
}
|
||||||
public Store(String storeName){
|
public Store(String storeName){
|
||||||
this.storeName = storeName;
|
this.storeName = storeName;
|
||||||
this.products = new ArrayList<>();
|
this.products = new ArrayList<>();
|
||||||
@ -47,7 +48,7 @@ public class Store {
|
|||||||
products) {
|
products) {
|
||||||
product.removeStore();
|
product.removeStore();
|
||||||
}
|
}
|
||||||
products = null;
|
products = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStoreName(String storeName) {
|
public void setStoreName(String storeName) {
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import { useRoutes, Outlet, BrowserRouter } from 'react-router-dom';
|
import { useRoutes, Outlet, BrowserRouter } from 'react-router-dom';
|
||||||
import Header from './components/common/Header';
|
import Header from './components/common/Header';
|
||||||
import Footer from './components/common/Footer';
|
import CustomerPage from './components/pages/customerPage';
|
||||||
import CustomerPage from './components/pages/customerPage'
|
import StorePage from './components/pages/storePage';
|
||||||
|
import ProductPage from './components/pages/productPage';
|
||||||
|
import OrderPage from './components/pages/orderPage';
|
||||||
|
import AddToStorePage from './components/pages/addToStorePage'
|
||||||
import './styleSite.css';
|
import './styleSite.css';
|
||||||
|
|
||||||
function Router(props) {
|
function Router(props) {
|
||||||
@ -12,9 +15,10 @@ export default function App() {
|
|||||||
const routes = [
|
const routes = [
|
||||||
{ index: true, element: <CustomerPage/> },
|
{ index: true, element: <CustomerPage/> },
|
||||||
{ path: 'customer', element: <CustomerPage/>, label:'Покупатели'},
|
{ path: 'customer', element: <CustomerPage/>, label:'Покупатели'},
|
||||||
// { path: 'shop', element: <Shop/>, label: 'Магазины' },
|
{ path: 'store', element: <StorePage/>, label: 'Магазины' },
|
||||||
// { path: 'product', element: <Product/>, label: 'Товары'},
|
{ path: 'product', element: <ProductPage/>, label: 'Товары' },
|
||||||
// { path: 'order', element: <Order/>, label: 'Заказы'}
|
{ path: 'order', element: <OrderPage/>, label: 'Заказы'},
|
||||||
|
{ path: 'addToStore', element: <AddToStorePage/>, label: 'Доставка'}
|
||||||
];
|
];
|
||||||
const links = routes.filter(route => route.hasOwnProperty('label'));
|
const links = routes.filter(route => route.hasOwnProperty('label'));
|
||||||
const rootRoute = [
|
const rootRoute = [
|
||||||
@ -29,7 +33,6 @@ export default function App() {
|
|||||||
<div className="container-fluid">
|
<div className="container-fluid">
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</div>
|
</div>
|
||||||
<Footer/>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ export default function Header(props){
|
|||||||
<img src="logo.png" alt="*" width="60" height="60" className="align-text-top"></img>
|
<img src="logo.png" alt="*" width="60" height="60" className="align-text-top"></img>
|
||||||
</a>
|
</a>
|
||||||
<div id="logoName">
|
<div id="logoName">
|
||||||
<a href="mainPage">boxStore</a>
|
<a href="customer">boxStore</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<nav className="navbar navbar-expand-md">
|
<nav className="navbar navbar-expand-md">
|
||||||
|
15
frontend/src/components/common/ToolbarOrder.jsx
Normal file
15
frontend/src/components/common/ToolbarOrder.jsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import styles from './Toolbar.module.css';
|
||||||
|
|
||||||
|
export default function ToolbarOrder(props) {
|
||||||
|
function add() {
|
||||||
|
props.onAdd();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="btn-group my-2 mx-4" role="group">
|
||||||
|
<button type="button" className={`btn btn-success ${styles.btn}`} onClick={add}>
|
||||||
|
Добавить
|
||||||
|
</button>
|
||||||
|
</div >
|
||||||
|
);
|
||||||
|
}
|
116
frontend/src/components/common/orderTable.jsx
Normal file
116
frontend/src/components/common/orderTable.jsx
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import Modal from './Modal';
|
||||||
|
import DataService from '../../services/DataService';
|
||||||
|
import OrderToolbar from './ToolbarOrder';
|
||||||
|
import Table from './Table';
|
||||||
|
|
||||||
|
export default function CustomerTable(props){
|
||||||
|
const [items, setItems] = useState([]);
|
||||||
|
const [modalHeader, setModalHeader] = useState('');
|
||||||
|
const [modalConfirm, setModalConfirm] = useState('');
|
||||||
|
const [modalVisible, setModalVisible] = useState(false);
|
||||||
|
const [isEdit, setEdit] = useState(false);
|
||||||
|
|
||||||
|
let selectedItems = [];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadItems();
|
||||||
|
loadOptions();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
function loadItems() {
|
||||||
|
DataService.readAll(props.getAllUrl, props.transformer)
|
||||||
|
.then(data => setItems(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadOptions(){
|
||||||
|
props.loadOptions(await DataService.readAll(props.getCustomerUrl, props.transformerCustomer), await DataService.readAll(props.getProductUrl, props.transformerProduct));
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveItem() {
|
||||||
|
if (!isEdit) {
|
||||||
|
DataService.create(props.url, "?productId=" + props.data.productId + "&customerId=" + props.data.customerId + "&quantity=" + props.data.quantity).then(() => loadItems());
|
||||||
|
} else {
|
||||||
|
DataService.update(props.getUrl + props.data.id, "?productId=" + props.data.productId + "&customerId=" + props.data.customerId + "&quantity=" + props.data.quantity).then(() => loadItems());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleAdd() {
|
||||||
|
setEdit(false);
|
||||||
|
setModalHeader('Заказ');
|
||||||
|
setModalConfirm('Заказать');
|
||||||
|
setModalVisible(true);
|
||||||
|
props.onAdd();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleEdit() {
|
||||||
|
if (selectedItems.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
edit(selectedItems[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function edit(editedId) {
|
||||||
|
DataService.read(props.getUrl + editedId, props.transformer)
|
||||||
|
.then(data => {
|
||||||
|
setEdit(true);
|
||||||
|
setModalHeader('Редактирование заказа');
|
||||||
|
setModalConfirm('Сохранить');
|
||||||
|
setModalVisible(true);
|
||||||
|
props.onEdit(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleRemove() {
|
||||||
|
if (selectedItems.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (confirm('Удалить выбранные элементы?')) {
|
||||||
|
const promises = [];
|
||||||
|
selectedItems.forEach(item => {
|
||||||
|
promises.push(DataService.delete(props.getUrl + item));
|
||||||
|
});
|
||||||
|
Promise.all(promises).then((results) => {
|
||||||
|
selectedItems.length = 0;
|
||||||
|
loadItems();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleTableClick(tableSelectedItems) {
|
||||||
|
selectedItems = tableSelectedItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleTableDblClick(tableSelectedItem) {
|
||||||
|
edit(tableSelectedItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleModalHide() {
|
||||||
|
setModalVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleModalDone() {
|
||||||
|
saveItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
return(
|
||||||
|
<>
|
||||||
|
<OrderToolbar
|
||||||
|
onAdd={handleAdd}/>
|
||||||
|
<Table
|
||||||
|
headers={props.headers}
|
||||||
|
items={items}
|
||||||
|
selectable={true}
|
||||||
|
onClick={handleTableClick}
|
||||||
|
onDblClick={handleTableDblClick}/>
|
||||||
|
<Modal
|
||||||
|
header={modalHeader}
|
||||||
|
confirm={modalConfirm}
|
||||||
|
visible={modalVisible}
|
||||||
|
onHide={handleModalHide}
|
||||||
|
onDone={handleModalDone}>
|
||||||
|
{props.children}
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
113
frontend/src/components/common/productTable.jsx
Normal file
113
frontend/src/components/common/productTable.jsx
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import Modal from './Modal';
|
||||||
|
import DataService from '../../services/DataService';
|
||||||
|
import Toolbar from './Toolbar';
|
||||||
|
import Table from './Table';
|
||||||
|
|
||||||
|
export default function CustomerTable(props){
|
||||||
|
const [items, setItems] = useState([]);
|
||||||
|
const [modalHeader, setModalHeader] = useState('');
|
||||||
|
const [modalConfirm, setModalConfirm] = useState('');
|
||||||
|
const [modalVisible, setModalVisible] = useState(false);
|
||||||
|
const [isEdit, setEdit] = useState(false);
|
||||||
|
|
||||||
|
let selectedItems = [];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadItems();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
function loadItems() {
|
||||||
|
DataService.readAll(props.getAllUrl, props.transformer)
|
||||||
|
.then(data => setItems(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveItem() {
|
||||||
|
if (!isEdit) {
|
||||||
|
DataService.create(props.url, "?productName=" + props.data.productName).then(() => loadItems());
|
||||||
|
} else {
|
||||||
|
DataService.update(props.getUrl + props.data.id, "?productName=" + props.data.productName).then(() => loadItems());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleAdd() {
|
||||||
|
setEdit(false);
|
||||||
|
setModalHeader('Добавления товара');
|
||||||
|
setModalConfirm('Добавить');
|
||||||
|
setModalVisible(true);
|
||||||
|
props.onAdd();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleEdit() {
|
||||||
|
if (selectedItems.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
edit(selectedItems[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function edit(editedId) {
|
||||||
|
DataService.read(props.getUrl + editedId, props.transformer)
|
||||||
|
.then(data => {
|
||||||
|
setEdit(true);
|
||||||
|
setModalHeader('Редактирование пользователя');
|
||||||
|
setModalConfirm('Сохранить');
|
||||||
|
setModalVisible(true);
|
||||||
|
props.onEdit(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleRemove() {
|
||||||
|
if (selectedItems.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (confirm('Удалить выбранные элементы?')) {
|
||||||
|
const promises = [];
|
||||||
|
selectedItems.forEach(item => {
|
||||||
|
promises.push(DataService.delete(props.getUrl + item));
|
||||||
|
});
|
||||||
|
Promise.all(promises).then((results) => {
|
||||||
|
selectedItems.length = 0;
|
||||||
|
loadItems();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleTableClick(tableSelectedItems) {
|
||||||
|
selectedItems = tableSelectedItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleTableDblClick(tableSelectedItem) {
|
||||||
|
edit(tableSelectedItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleModalHide() {
|
||||||
|
setModalVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleModalDone() {
|
||||||
|
saveItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
return(
|
||||||
|
<>
|
||||||
|
<Toolbar
|
||||||
|
onAdd={handleAdd}
|
||||||
|
onEdit={handleEdit}
|
||||||
|
onRemove={handleRemove}/>
|
||||||
|
<Table
|
||||||
|
headers={props.headers}
|
||||||
|
items={items}
|
||||||
|
selectable={true}
|
||||||
|
onClick={handleTableClick}
|
||||||
|
onDblClick={handleTableDblClick}/>
|
||||||
|
<Modal
|
||||||
|
header={modalHeader}
|
||||||
|
confirm={modalConfirm}
|
||||||
|
visible={modalVisible}
|
||||||
|
onHide={handleModalHide}
|
||||||
|
onDone={handleModalDone}>
|
||||||
|
{props.children}
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
113
frontend/src/components/common/storeTable.jsx
Normal file
113
frontend/src/components/common/storeTable.jsx
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import Modal from './Modal';
|
||||||
|
import DataService from '../../services/DataService';
|
||||||
|
import Toolbar from './Toolbar';
|
||||||
|
import Table from './Table';
|
||||||
|
|
||||||
|
export default function CustomerTable(props){
|
||||||
|
const [items, setItems] = useState([]);
|
||||||
|
const [modalHeader, setModalHeader] = useState('');
|
||||||
|
const [modalConfirm, setModalConfirm] = useState('');
|
||||||
|
const [modalVisible, setModalVisible] = useState(false);
|
||||||
|
const [isEdit, setEdit] = useState(false);
|
||||||
|
|
||||||
|
let selectedItems = [];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadItems();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
function loadItems() {
|
||||||
|
DataService.readAll(props.getAllUrl, props.transformer)
|
||||||
|
.then(data => setItems(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveItem() {
|
||||||
|
if (!isEdit) {
|
||||||
|
DataService.create(props.url, "?storeName=" + props.data.storeName).then(() => loadItems());
|
||||||
|
} else {
|
||||||
|
DataService.update(props.getUrl + props.data.id, "?storeName=" + props.data.storeName).then(() => loadItems());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleAdd() {
|
||||||
|
setEdit(false);
|
||||||
|
setModalHeader('Регистрация магазина');
|
||||||
|
setModalConfirm('Зарегестрировать');
|
||||||
|
setModalVisible(true);
|
||||||
|
props.onAdd();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleEdit() {
|
||||||
|
if (selectedItems.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
edit(selectedItems[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function edit(editedId) {
|
||||||
|
DataService.read(props.getUrl + editedId, props.transformer)
|
||||||
|
.then(data => {
|
||||||
|
setEdit(true);
|
||||||
|
setModalHeader('Редактирование пользователя');
|
||||||
|
setModalConfirm('Сохранить');
|
||||||
|
setModalVisible(true);
|
||||||
|
props.onEdit(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleRemove() {
|
||||||
|
if (selectedItems.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (confirm('Удалить выбранные элементы?')) {
|
||||||
|
const promises = [];
|
||||||
|
selectedItems.forEach(item => {
|
||||||
|
promises.push(DataService.delete(props.getUrl + item));
|
||||||
|
});
|
||||||
|
Promise.all(promises).then((results) => {
|
||||||
|
selectedItems.length = 0;
|
||||||
|
loadItems();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleTableClick(tableSelectedItems) {
|
||||||
|
selectedItems = tableSelectedItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleTableDblClick(tableSelectedItem) {
|
||||||
|
edit(tableSelectedItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleModalHide() {
|
||||||
|
setModalVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleModalDone() {
|
||||||
|
saveItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
return(
|
||||||
|
<>
|
||||||
|
<Toolbar
|
||||||
|
onAdd={handleAdd}
|
||||||
|
onEdit={handleEdit}
|
||||||
|
onRemove={handleRemove}/>
|
||||||
|
<Table
|
||||||
|
headers={props.headers}
|
||||||
|
items={items}
|
||||||
|
selectable={true}
|
||||||
|
onClick={handleTableClick}
|
||||||
|
onDblClick={handleTableDblClick}/>
|
||||||
|
<Modal
|
||||||
|
header={modalHeader}
|
||||||
|
confirm={modalConfirm}
|
||||||
|
visible={modalVisible}
|
||||||
|
onHide={handleModalHide}
|
||||||
|
onDone={handleModalDone}>
|
||||||
|
{props.children}
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
87
frontend/src/components/pages/addToStorePage.jsx
Normal file
87
frontend/src/components/pages/addToStorePage.jsx
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import Product from "../../models/product"
|
||||||
|
import Store from "../../models/store"
|
||||||
|
import DataService from '../../services/DataService';
|
||||||
|
import { useState, useEffect} from "react";
|
||||||
|
|
||||||
|
export default function AddToStorePage(){
|
||||||
|
const getStoreUrl = 'store';
|
||||||
|
const getProductUrl = 'product/getWithoutStores'
|
||||||
|
const url = 'store/add'
|
||||||
|
const [storeOptions, setStoreOptions] = useState([])
|
||||||
|
const [productOptions, setProductOptions] = useState([])
|
||||||
|
const transformerProduct = (data) => new Product(data);
|
||||||
|
const transformerStore = (data) => new Store(data);
|
||||||
|
useEffect(() => {
|
||||||
|
loadOptions();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
async function loadOptions(){
|
||||||
|
loadSelOptions(await DataService.readAll(getStoreUrl, transformerStore), await DataService.readAll(getProductUrl, transformerProduct));
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadSelOptions(dataStore, dataProduct){
|
||||||
|
const results1 = [];
|
||||||
|
//console.log(dataProduct);
|
||||||
|
dataStore.forEach((value) => {
|
||||||
|
results1.push({
|
||||||
|
key: value.storeName,
|
||||||
|
value: value.id,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
console.log(results1);
|
||||||
|
setStoreOptions(results1);
|
||||||
|
const results2 = [];
|
||||||
|
console.log(dataProduct);
|
||||||
|
dataProduct.forEach((value) => {
|
||||||
|
results2.push({
|
||||||
|
key: value.productName,
|
||||||
|
value: value.id,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
setProductOptions(results2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function add(){
|
||||||
|
var storeId = document.getElementById("storeId").value;
|
||||||
|
var productId = document.getElementById("productId").value;
|
||||||
|
|
||||||
|
DataService.update(url, "?storeId=" + storeId + "&productId=" + productId);
|
||||||
|
window.location.replace("/product");
|
||||||
|
}
|
||||||
|
|
||||||
|
return(
|
||||||
|
<>
|
||||||
|
<div className="col-md-4">
|
||||||
|
<label className="form-label" forhtml="storeId">Магазин</label>
|
||||||
|
<select className="form-select" id="storeId" required>
|
||||||
|
{
|
||||||
|
storeOptions.map((option) => {
|
||||||
|
return(
|
||||||
|
<option key={option.value} value={option.value}>
|
||||||
|
{option.key}
|
||||||
|
</option>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
<label className="form-label" forhtml="productId">Товар</label>
|
||||||
|
<select className="form-select" id="productId" required>
|
||||||
|
{
|
||||||
|
productOptions.map((option) => {
|
||||||
|
return(
|
||||||
|
<option key={option.value} value={option.value}>
|
||||||
|
{option.key}
|
||||||
|
</option>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
<button className={`btn btn-success`} onClick={add}>
|
||||||
|
Добавить в магазин
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
108
frontend/src/components/pages/orderPage.jsx
Normal file
108
frontend/src/components/pages/orderPage.jsx
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
import Order from "../../models/order"
|
||||||
|
import Product from "../../models/product"
|
||||||
|
import Customer from "../../models/customer";
|
||||||
|
import OrderTable from '../common/orderTable'
|
||||||
|
import { useState, useEffect} from "react";
|
||||||
|
|
||||||
|
export default function OrderPage(){
|
||||||
|
const url = 'order';
|
||||||
|
const getUrl = 'order/';
|
||||||
|
const getCustomerUrl = 'customer';
|
||||||
|
const getProductUrl = 'product/getWithStores'
|
||||||
|
const transformer = (data) => new Order(data);
|
||||||
|
const transformerProduct = (data) => new Product(data);
|
||||||
|
const transformerCustomer = (data) => new Customer(data);
|
||||||
|
const catalogOrderHeaders = [
|
||||||
|
{ name: 'customerFIO', label: 'ФИО покупателя' },
|
||||||
|
{ name: 'storeName', label: 'Магазина'},
|
||||||
|
{ name: 'productName', label: 'Товар'}
|
||||||
|
];
|
||||||
|
|
||||||
|
const [data, setData] = useState(new Order());
|
||||||
|
const [customerOptions, setCustomerOptions] = useState([])
|
||||||
|
const [productOptions, setProductOptions] = useState([])
|
||||||
|
|
||||||
|
function loadOptions(dataCustomer, dataProduct){
|
||||||
|
const results1 = [];
|
||||||
|
console.log(dataCustomer);
|
||||||
|
//console.log(dataProduct);
|
||||||
|
dataCustomer.forEach((value) => {
|
||||||
|
results1.push({
|
||||||
|
key: value.lastName + " " + value.firstName + " " + value.middleName,
|
||||||
|
value: value.id,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
console.log(results1);
|
||||||
|
setCustomerOptions(results1);
|
||||||
|
const results2 = [];
|
||||||
|
dataProduct.forEach((value) => {
|
||||||
|
results2.push({
|
||||||
|
key: value.productName,
|
||||||
|
value: value.id,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
setProductOptions(results2);
|
||||||
|
//console.log(customerOptions);
|
||||||
|
//console.log(productOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleOnAdd() {
|
||||||
|
setData(new Order());
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleOnEdit(data) {
|
||||||
|
setData(new Order(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleFormChange(event) {
|
||||||
|
setData({ ...data, [event.target.id]: event.target.value })
|
||||||
|
}
|
||||||
|
return(
|
||||||
|
<article className="h-100 mt-0 mb-0 d-flex flex-column justify-content-between">
|
||||||
|
<OrderTable headers={catalogOrderHeaders}
|
||||||
|
getAllUrl={url}
|
||||||
|
url={url}
|
||||||
|
getUrl={getUrl}
|
||||||
|
getCustomerUrl={getCustomerUrl}
|
||||||
|
getProductUrl={getProductUrl}
|
||||||
|
transformer={transformer}
|
||||||
|
transformerCustomer={transformerCustomer}
|
||||||
|
transformerProduct={transformerProduct}
|
||||||
|
data={data}
|
||||||
|
onAdd={handleOnAdd}
|
||||||
|
loadOptions={loadOptions}
|
||||||
|
onEdit={handleOnEdit}>
|
||||||
|
<div className="col-md-4">
|
||||||
|
<label className="form-label" forhtml="customerId">Покупатель</label>
|
||||||
|
<select className="form-select" id="customerId" value={data.customerId} onChange={handleFormChange} required>
|
||||||
|
{
|
||||||
|
customerOptions.map((option) => {
|
||||||
|
return(
|
||||||
|
<option key={option.value} value={option.value}>
|
||||||
|
{option.key}
|
||||||
|
</option>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
<label className="form-label" forhtml="productId">Продукт</label>
|
||||||
|
<select className="form-select" id="productId" value={data.customerId} onChange={handleFormChange} required>
|
||||||
|
{
|
||||||
|
productOptions.map((option) => {
|
||||||
|
return(
|
||||||
|
<option key={option.value} value={option.value}>
|
||||||
|
{option.key}
|
||||||
|
</option>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
<label className="form-label" forhtml="quantity">Количество</label>
|
||||||
|
<input className="form-control" type="number" id="quantity" value={data.quantity} onChange={handleFormChange} placeholder="1" step="1" min="1" required="required"/>
|
||||||
|
</div>
|
||||||
|
</OrderTable>
|
||||||
|
</article>
|
||||||
|
)
|
||||||
|
}
|
44
frontend/src/components/pages/productPage.jsx
Normal file
44
frontend/src/components/pages/productPage.jsx
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import Product from "../../models/product"
|
||||||
|
import ProductTable from '../common/productTable'
|
||||||
|
import { useState, useEffect} from "react";
|
||||||
|
|
||||||
|
export default function ProductPage(){
|
||||||
|
const url = 'product';
|
||||||
|
const getUrl = 'product/';
|
||||||
|
const transformer = (data) => new Product(data);
|
||||||
|
const catalogProductHeaders = [
|
||||||
|
{ name: 'productName', label: 'Название товара' },
|
||||||
|
{ name: 'storeName', label: 'Название магазина' }
|
||||||
|
];
|
||||||
|
|
||||||
|
const [data, setData] = useState(new Product());
|
||||||
|
|
||||||
|
function handleOnAdd() {
|
||||||
|
setData(new Product());
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleOnEdit(data) {
|
||||||
|
setData(new Product(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleFormChange(event) {
|
||||||
|
setData({ ...data, [event.target.id]: event.target.value })
|
||||||
|
}
|
||||||
|
return(
|
||||||
|
<article className="h-100 mt-0 mb-0 d-flex flex-column justify-content-between">
|
||||||
|
<ProductTable headers={catalogProductHeaders}
|
||||||
|
getAllUrl={url}
|
||||||
|
url={url}
|
||||||
|
getUrl={getUrl}
|
||||||
|
transformer={transformer}
|
||||||
|
data={data}
|
||||||
|
onAdd={handleOnAdd}
|
||||||
|
onEdit={handleOnEdit}>
|
||||||
|
<div className="col-md-4">
|
||||||
|
<label className="form-label" forhtml="productName">Название</label>
|
||||||
|
<input className="form-control" type="text" id="productName" value={data.lastName} onChange={handleFormChange} required="required"/>
|
||||||
|
</div>
|
||||||
|
</ProductTable>
|
||||||
|
</article>
|
||||||
|
)
|
||||||
|
}
|
43
frontend/src/components/pages/storePage.jsx
Normal file
43
frontend/src/components/pages/storePage.jsx
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import Store from "../../models/store"
|
||||||
|
import StoreTable from '../common/storeTable'
|
||||||
|
import { useState, useEffect} from "react";
|
||||||
|
|
||||||
|
export default function StorePage(){
|
||||||
|
const url = 'store';
|
||||||
|
const getUrl = 'store/';
|
||||||
|
const transformer = (data) => new Store(data);
|
||||||
|
const catalogStoreHeaders = [
|
||||||
|
{ name: 'storeName', label: 'Название магазина' }
|
||||||
|
];
|
||||||
|
|
||||||
|
const [data, setData] = useState(new Store());
|
||||||
|
|
||||||
|
function handleOnAdd() {
|
||||||
|
setData(new Store());
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleOnEdit(data) {
|
||||||
|
setData(new Store(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleFormChange(event) {
|
||||||
|
setData({ ...data, [event.target.id]: event.target.value })
|
||||||
|
}
|
||||||
|
return(
|
||||||
|
<article className="h-100 mt-0 mb-0 d-flex flex-column justify-content-between">
|
||||||
|
<StoreTable headers={catalogStoreHeaders}
|
||||||
|
getAllUrl={url}
|
||||||
|
url={url}
|
||||||
|
getUrl={getUrl}
|
||||||
|
transformer={transformer}
|
||||||
|
data={data}
|
||||||
|
onAdd={handleOnAdd}
|
||||||
|
onEdit={handleOnEdit}>
|
||||||
|
<div className="col-md-4">
|
||||||
|
<label className="form-label" forhtml="storeName">Название</label>
|
||||||
|
<input className="form-control" type="text" id="storeName" value={data.lastName} onChange={handleFormChange} required="required"/>
|
||||||
|
</div>
|
||||||
|
</StoreTable>
|
||||||
|
</article>
|
||||||
|
)
|
||||||
|
}
|
8
frontend/src/models/order.js
Normal file
8
frontend/src/models/order.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export default class Store {
|
||||||
|
constructor(data) {
|
||||||
|
this.id = data?.id;
|
||||||
|
this.storeName = data?.storeName || '';
|
||||||
|
this.customerFIO = data?.customerFIO || '';
|
||||||
|
this.productName = data?.productName || '';
|
||||||
|
}
|
||||||
|
}
|
7
frontend/src/models/product.js
Normal file
7
frontend/src/models/product.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export default class Product {
|
||||||
|
constructor(data) {
|
||||||
|
this.id = data?.id;
|
||||||
|
this.productName = data?.productName || '';
|
||||||
|
this.storeName = data?.storeName || '';
|
||||||
|
}
|
||||||
|
}
|
7
frontend/src/models/store.js
Normal file
7
frontend/src/models/store.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export default class Store {
|
||||||
|
constructor(data) {
|
||||||
|
this.id = data?.id;
|
||||||
|
this.storeName = data?.storeName || '';
|
||||||
|
this.products = data?.products || null;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user