diff --git a/firm/src/App.js b/firm/src/App.js index 0cbd699..6fd3707 100644 --- a/firm/src/App.js +++ b/firm/src/App.js @@ -3,7 +3,11 @@ import React, { useState, useEffect } from 'react'; import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom'; import PanelAdministratora from './components/PanelAdministratora'; import ZarzadzanieProduktami from './components/ZarzadzanieProduktami'; -import Transakcje from './components/Transakcje'; +import DodawanieProduktu from './components/DodawanieProduktów'; +import EdycjaProduktu from './components/EdycjaProduktu'; +import ZarzadzanieTransakcjami from './components/ZarzadzanieTransakcjami'; +import DodawanieTransakcji from './components/DodawanieTransakcji'; +import EdycjaTransakcji from './components/EdycjaTransakcji'; import NavBar from './components/NavBar'; import Sidebar from './components/Sidebar'; import Wydatki from './components/Wydatki'; @@ -43,22 +47,18 @@ const App = () => { )}
- {/* Przekierowanie na stronę logowania, jeśli token jest pusty */} : } /> - - {/* Strona logowania */} : } /> - - {/* Chronione ścieżki */} - : } /> + : } /> + : } /> + : } /> : } /> : } /> + : } /> + : } /> : } /> : } /> : } /> - - {/* Przekierowanie dla nieznanych ścieżek */} - } />
diff --git a/firm/src/components/DodawanieProduktów.js b/firm/src/components/DodawanieProduktów.js new file mode 100644 index 0000000..a16cfe2 --- /dev/null +++ b/firm/src/components/DodawanieProduktów.js @@ -0,0 +1,130 @@ +import React, { useState } from 'react'; +import axios from 'axios'; +import { useNavigate } from 'react-router-dom'; + +const DodawanieProduktu = () => { + const [error, setError] = useState(null); + const [newProduct, setNewProduct] = useState({ + name: '', + description: '', + price: '', + type: '1', + availability: '', + }); + const navigate = useNavigate(); + + const handleInputChange = (event) => { + const { name, value } = event.target; + setNewProduct({ ...newProduct, [name]: value }); + }; + + const handleAddProduct = async () => { + const { name, description, price, type, availability } = newProduct; + + if (!name || !description || !price || type === '') { + setError('Proszę uzupełnić wszystkie wymagane pola.'); + return; + } + + const payload = { + name, + description, + price, + type: parseInt(type, 10), + ...(type === '1' && { availability: availability || 0 }), + }; + + try { + const token = localStorage.getItem('token'); + if (!token) { + setError('Brak tokena. Użytkownik musi być zalogowany.'); + return; + } + + const config = { + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, + }, + }; + + await axios.post('https://localhost:7039/api/Products', payload, config); + + setNewProduct({ + name: '', + description: '', + price: '', + type: '1', + availability: '', + }); + setError(null); + navigate('/produkty'); + } catch (error) { + console.error('Błąd podczas dodawania produktu:', error); + setError('Wystąpił błąd podczas dodawania produktu. Spróbuj ponownie.'); + } + }; + + return ( +
+

Dodaj nowy produkt lub usługę

+ {error &&

{error}

} +
+ + + + + {newProduct.type === '1' && ( + + )} +
+
+ +
+
+ ); +}; + +export default DodawanieProduktu; diff --git a/firm/src/components/DodawanieTransakcji.js b/firm/src/components/DodawanieTransakcji.js new file mode 100644 index 0000000..adab366 --- /dev/null +++ b/firm/src/components/DodawanieTransakcji.js @@ -0,0 +1,260 @@ +import React, { useState, useEffect } from 'react'; +import axios from 'axios'; +import { useNavigate } from 'react-router-dom'; +import Select from 'react-select'; + +const DodawanieTransakcji = () => { + const [error, setError] = useState(null); + const [newTransaction, setNewTransaction] = useState({ + id: 2, + date: '', + employeeId: '', + paymentType: '', + discount: '', + description: '', + transactionProducts: [ + { + id: 2, + transactionId: 0, + productID: 0, + productName: '', + quantity: '' + } + ], + }); + + const [products, setProducts] = useState([]); + const [isLoading, setIsLoading] = useState(true); + const navigate = useNavigate(); + + useEffect(() => { + const fetchProducts = async () => { + try { + const token = localStorage.getItem('token'); + if (!token) { + setError('Brak tokena. Użytkownik musi być zalogowany.'); + return; + } + + const config = { + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, + }, + }; + + const response = await axios.get('https://localhost:7039/api/Products', config); + const productOptions = response.data.map(product => ({ + value: product.id, + label: product.name, + })); + setProducts(productOptions); + } catch (error) { + setError('Wystąpił błąd podczas ładowania produktów.'); + } finally { + setIsLoading(false); + } + }; + + fetchProducts(); + }, []); + + const handleInputChange = (event) => { + const { name, value } = event.target; + setNewTransaction({ ...newTransaction, [name]: value }); + }; + + const handleProductChange = (index, selectedOption) => { + const updatedTransactionProducts = [...newTransaction.transactionProducts]; + updatedTransactionProducts[index].productID = selectedOption.value; + updatedTransactionProducts[index].productName = selectedOption.label; + setNewTransaction({ + ...newTransaction, + transactionProducts: updatedTransactionProducts, + }); + }; + + const handleAddProduct = () => { + setNewTransaction({ + ...newTransaction, + transactionProducts: [ + ...newTransaction.transactionProducts, + { + id: 2, + transactionId: 0, + productID: 0, + productName: '', + quantity: '' + } + ] + }); + }; + + const handleRemoveProduct = (index) => { + const updatedTransactionProducts = [...newTransaction.transactionProducts]; + updatedTransactionProducts.splice(index, 1); + setNewTransaction({ + ...newTransaction, + transactionProducts: updatedTransactionProducts, + }); + }; + + const handleAddTransaction = async () => { + if (!newTransaction.date || !newTransaction.employeeId || newTransaction.transactionProducts.some(product => !product.productName || !product.quantity)) { + setError('Proszę uzupełnić wszystkie pola.'); + return; + } + + try { + console.log('Nowa transakcja:', newTransaction); + + const token = localStorage.getItem('token'); + if (!token) { + setError('Brak tokena. Użytkownik musi być zalogowany.'); + return; + } + + const config = { + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, + }, + }; + + await axios.post('https://localhost:7039/api/Transaction', newTransaction, config); + + setNewTransaction({ + id: 0, + date: '', + employeeId: '', + transactionProducts: [ + { + id: 0, + transactionId: 0, + productID: 0, + productName: '', + quantity: '' + } + ], + paymentType: '', + discount: '', + description: '', + totalPrice: 0, + }); + navigate('/transakcje'); + } catch (error) { + console.error('Błąd podczas dodawania transakcji:', error); + if (error.response && error.response.data) { + setError(error.response.data); + } else { + setError('Wystąpił nieoczekiwany błąd. Spróbuj ponownie później.'); + } + } + }; + + return ( +
+

Dodaj nową transakcję

+ + {error &&

{error}

} + + + + + + {isLoading ? ( +
Ładowanie produktów...
+ ) : ( + <> + {newTransaction.transactionProducts.map((product, index) => ( +
+ { + const updatedTransactionProducts = [...newTransaction.transactionProducts]; + updatedTransactionProducts[index].quantity = e.target.value; + setNewTransaction({ ...newTransaction, transactionProducts: updatedTransactionProducts }); + }} + placeholder="Ilość" + className="block w-full mb-2 px-4 py-2 border border-gray-300 rounded-lg" + /> + +
+ ))} + + )} + + + + + + + + + + +
+ ); +}; + +export default DodawanieTransakcji; diff --git a/firm/src/components/EdycjaProduktu.js b/firm/src/components/EdycjaProduktu.js new file mode 100644 index 0000000..6f6cc3a --- /dev/null +++ b/firm/src/components/EdycjaProduktu.js @@ -0,0 +1,157 @@ +import React, { useState, useEffect } from 'react'; +import axios from 'axios'; +import { useParams, useNavigate } from 'react-router-dom'; + +const EdycjaProduktu = () => { + const { id } = useParams(); + const [product, setProduct] = useState({ + name: '', + description: '', + price: '', + type: '1', + availability: '', + }); + const [error, setError] = useState(null); + const navigate = useNavigate(); + + useEffect(() => { + const fetchProduct = async () => { + try { + const token = localStorage.getItem('token'); + if (!token) { + setError('Brak tokena. Użytkownik musi być zalogowany.'); + return; + } + + const response = await axios.get(`https://localhost:7039/api/Products/${id}`, { + headers: { + Authorization: `Bearer ${token}`, + }, + }); + setProduct(response.data); + } catch (error) { + console.error('Błąd podczas pobierania produktu:', error); + setError('Wystąpił błąd podczas pobierania danych produktu.'); + } + }; + + fetchProduct(); + }, [id]); + + const handleInputChange = (event) => { + const { name, value } = event.target; + setProduct({ ...product, [name]: value }); + }; + + const handleSaveChanges = async () => { + const { name, description, price, type, availability } = product; + + if (!name || !description || !price || type === '') { + setError('Proszę uzupełnić wszystkie wymagane pola.'); + return; + } + + const payload = { + id, + name, + description, + price, + type: parseInt(type, 10), + ...(type === '1' && { availability: availability || 0 }), + }; + + try { + const token = localStorage.getItem('token'); + if (!token) { + setError('Brak tokena. Użytkownik musi być zalogowany.'); + return; + } + + const config = { + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, + }, + }; + + const response = await axios.put(`https://localhost:7039/api/Products/${id}`, payload, config); + + console.log('Produkt zapisany:', response.data); + + setError(null); + navigate('/produkty'); + } catch (error) { + console.error('Błąd podczas zapisywania zmian:', error); + + if (error.response && error.response.status === 400) { + setError('ID produktu nie zgadza się.'); + } else { + setError('Wystąpił błąd podczas zapisywania zmian. Spróbuj ponownie.'); + } + } + }; + + + return ( +
+

Edycja produktu

+ {error &&

{error}

} +
+ + + + + {product.type === '1' && ( + + )} +
+
+ +
+
+ ); +}; + +export default EdycjaProduktu; diff --git a/firm/src/components/EdycjaTransakcji.js b/firm/src/components/EdycjaTransakcji.js new file mode 100644 index 0000000..faa5de9 --- /dev/null +++ b/firm/src/components/EdycjaTransakcji.js @@ -0,0 +1,243 @@ +import React, { useState, useEffect } from 'react'; +import axios from 'axios'; +import { useParams, useNavigate } from 'react-router-dom'; +import Select from 'react-select'; + +const EdycjaTransakcji = () => { + const { id } = useParams(); + const [transaction, setTransaction] = useState({ + date: '', + employeeId: '', + paymentType: '', + discount: '', + description: '', + transactionProducts: [{ productID: '', productName: '', quantity: '' }], + }); + const [products, setProducts] = useState([]); + const [isLoading, setIsLoading] = useState(true); + const [error, setError] = useState(null); + const navigate = useNavigate(); + + const getToken = () => { + const token = localStorage.getItem('token'); + if (!token) { + setError('Brak tokena. Użytkownik musi być zalogowany.'); + } + return token; + }; + + useEffect(() => { + const fetchTransaction = async () => { + try { + const token = getToken(); + if (!token) return; + + const transactionResponse = await axios.get(`https://localhost:7039/api/transaction/${id}`, { + headers: { + Authorization: `Bearer ${token}`, + }, + }); + console.log('Dane transakcji:', transactionResponse.data); + + const updatedTransaction = { + ...transactionResponse.data, + transactionProducts: transactionResponse.data.transactionProducts.map((transactionProduct) => ({ + productID: transactionProduct.product.id, + productName: transactionProduct.product.name, + quantity: transactionProduct.quantity, + })), + }; + setTransaction(updatedTransaction); + + const productResponse = await axios.get('https://localhost:7039/api/Products', { + headers: { + Authorization: `Bearer ${token}`, + }, + }); + console.log('Produkty:', productResponse.data); + + const productOptions = productResponse.data.map((product) => ({ + value: product.id, + label: product.name, + })); + setProducts(productOptions); + } catch (error) { + console.error('Błąd podczas pobierania transakcji lub produktów:', error); + setError('Wystąpił błąd podczas ładowania danych.'); + } finally { + setIsLoading(false); + } + }; + + fetchTransaction(); + }, [id]); + + + + const handleInputChange = (event) => { + const { name, value } = event.target; + setTransaction({ ...transaction, [name]: value }); + }; + + const handleProductChange = (index, selectedOption) => { + const updatedTransactionProducts = [...transaction.transactionProducts]; + updatedTransactionProducts[index].productID = selectedOption.value; + updatedTransactionProducts[index].productName = selectedOption.label; + setTransaction({ + ...transaction, + transactionProducts: updatedTransactionProducts, + }); + }; + + + const handleAddProduct = () => { + setTransaction({ + ...transaction, + transactionProducts: [ + ...transaction.transactionProducts, + { productID: 0, productName: '', quantity: '' }, + ], + }); + }; + + const handleRemoveProduct = (index) => { + const updatedTransactionProducts = [...transaction.transactionProducts]; + updatedTransactionProducts.splice(index, 1); + setTransaction({ + ...transaction, + transactionProducts: updatedTransactionProducts, + }); + }; + + const handleSaveChanges = async () => { + if (!transaction.date || !transaction.employeeId || transaction.transactionProducts.some(product => !product.productName || !product.quantity)) { + setError('Proszę uzupełnić wszystkie pola.'); + return; + } + + try { + const token = getToken(); + if (!token) { + setError('Brak tokena. Użytkownik musi być zalogowany.'); + return; + } + + const response = await axios.put(`https://localhost:7039/api/transaction/${id}`, transaction, { + headers: { + Authorization: `Bearer ${token}`, + }, + }); + console.log('Zaktualizowana transakcja:', response.data); + navigate('/transakcje'); + } catch (error) { + console.error('Błąd podczas zapisywania zmian:', error); + setError('Wystąpił błąd podczas zapisywania zmian.'); + } + }; + + return ( +
+

Edycja Transakcji

+ + {error &&

{error}

} + + + + + + {isLoading ? ( +
Ładowanie produktów...
+ ) : ( + <> + {transaction.transactionProducts.map((product, index) => ( +
+ { + const updatedTransactionProducts = [...transaction.transactionProducts]; + updatedTransactionProducts[index].quantity = e.target.value; + setTransaction({ ...transaction, transactionProducts: updatedTransactionProducts }); + }} + placeholder="Ilość" + className="block w-full mb-2 px-4 py-2 border border-gray-300 rounded-lg" + /> + +
+ ))} + + )} + + + + + + + + + + +
+ ); +}; + +export default EdycjaTransakcji; diff --git a/firm/src/components/ListaProduktów.js b/firm/src/components/ListaProduktów.js new file mode 100644 index 0000000..5630a1f --- /dev/null +++ b/firm/src/components/ListaProduktów.js @@ -0,0 +1,135 @@ +import React, { useState, useEffect } from 'react'; +import axios from 'axios'; +import editIcon from '../icons/edit.png'; +import koszIcon from '../icons/kosz.png'; +import { useNavigate } from 'react-router-dom'; + +const ListaProduktow = ({ onAdd }) => { + const [products, setProducts] = useState([]); + const [deleteProductId, setDeleteProductId] = useState(null); + const [showModal, setShowModal] = useState(false); + const navigate = useNavigate(); + + const fetchProducts = async () => { + const token = localStorage.getItem('token'); + try { + const response = await axios.get('https://localhost:7039/api/products', { + headers: { Authorization: `Bearer ${token}` }, + }); + setProducts(response.data); + } catch (error) { + console.error('Błąd podczas pobierania produktów:', error); + } + }; + + useEffect(() => { + fetchProducts(); + }, []); + + const handleDeleteProduct = async () => { + const token = localStorage.getItem('token'); + if (!token) { + alert('Brak tokena. Użytkownik musi być zalogowany.'); + return; + } + + if (!deleteProductId) { + console.error('Brak ID produktu do usunięcia!'); + return; + } + + try { + await axios.delete(`https://localhost:7039/api/Products/${deleteProductId}`, { + headers: { Authorization: `Bearer ${token}` }, + }); + fetchProducts(); + setShowModal(false); + setDeleteProductId(null); + } catch (error) { + console.error('Błąd podczas usuwania produktu:', error); + } + }; + + const handleEditProduct = (productId) => { + navigate(`/produkty/edytuj/${productId}`); + }; + + return ( +
+
+

Katalog Produktów

+ +
+
+ + + + + + + + + + + + + {products.map((product) => ( + + + + + + + + + ))} + +
IDProduktOpisCenaDostępność
{product.id}{product.name}{product.description}{parseFloat(product.price).toFixed(2)}{product.availability} + + +
+
+ + {showModal && ( +
+
+

Czy na pewno chcesz usunąć ten produkt?

+
+ + +
+
+
+ )} +
+ ); +}; + +export default ListaProduktow; diff --git a/firm/src/components/ListaTransakcji.js b/firm/src/components/ListaTransakcji.js new file mode 100644 index 0000000..8a756d5 --- /dev/null +++ b/firm/src/components/ListaTransakcji.js @@ -0,0 +1,177 @@ +import React, { useState, useEffect } from 'react'; +import axios from 'axios'; +import editIcon from '../icons/edit.png'; +import koszIcon from '../icons/kosz.png'; +import { useNavigate } from 'react-router-dom'; + +const ListaTransakcji = ({ onAdd}) => { + const [transactions, setTransactions] = useState([]); + const [deleteTransactionId, setDeleteTransactionId] = useState(null); + const [showModal, setShowModal] = useState(false); + const navigate = useNavigate(); + + const fetchTransactions = async () => { + const token = localStorage.getItem('token'); + if (!token) { + console.error('Brak tokena. Użytkownik musi być zalogowany.'); + return; + } + try { + const response = await axios.get('https://localhost:7039/api/Transaction', { + headers: { + Authorization: `Bearer ${token}`, + }, + }); + setTransactions(response.data); + } catch (error) { + console.error('Błąd podczas pobierania transakcji:', error); + } + }; + + const fetchProducts = async () => { + const token = localStorage.getItem('token'); + if (!token) { + console.error('Brak tokena. Użytkownik musi być zalogowany.'); + return; + } + try { + const response = await axios.get('https://localhost:7039/api/Products', { + headers: { + Authorization: `Bearer ${token}`, + }, + }); + response.data.map(product => ({ value: product.id, label: product.name })); + } catch (error) { + console.error('Błąd podczas pobierania produktów:', error); + } + }; + + useEffect(() => { + fetchTransactions(); + fetchProducts(); + }, []); + + const formatDate = (date) => { + const newDate = new Date(date); + return newDate.toLocaleDateString(); + }; + + const formatPrice = (price) => { + return price.toFixed(2).replace('.', ','); + }; + + const handleDeleteTransaction = async () => { + try { + await axios.delete(`https://localhost:7039/api/transaction/${deleteTransactionId}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem('token')}`, + }, + }); + setTransactions(transactions.filter(transaction => transaction.id !== deleteTransactionId)); + setShowModal(false); + setDeleteTransactionId(null); + } catch (error) { + console.error('Błąd podczas usuwania transakcji:', error); + } + }; + + const openDeleteConfirmation = (transactionId) => { + setDeleteTransactionId(transactionId); + setShowModal(true); + }; + + const handleEditTransaction = (transactionId) => { + navigate(`/transakcje/edytuj/${transactionId}`); + }; + + + return ( +
+
+

Lista Transakcji

+ +
+
+
+ + + + + + + + + + + + + + + {transactions.map(transaction => ( + + + + + + + + + + + ))} + +
IDDataProduktIlośćKwotaSposób płatnościNr. Pracownika
{transaction.id}{formatDate(transaction.date)} + {transaction.transactionProducts.map(product => ( +
{product.product.name}
+ ))} +
+ {transaction.transactionProducts.map(product => ( +
{product.quantity}
+ ))} +
{formatPrice(transaction.totalPrice)}{transaction.paymentType}{transaction.employeeId} + + +
+
+
+ + {showModal && ( +
+
+

Czy na pewno chcesz usunąć tę transakcję?

+
+ + +
+
+
+ )} +
+ ); +}; + +export default ListaTransakcji; diff --git a/firm/src/components/Transakcje.js b/firm/src/components/Transakcje.js deleted file mode 100644 index 88077a6..0000000 --- a/firm/src/components/Transakcje.js +++ /dev/null @@ -1,488 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import axios from 'axios'; -import Select from 'react-select'; -import editIcon from "../icons/edit.png"; -import koszIcon from "../icons/kosz.png"; -import plusIcon from "../icons/plus.png"; -import ConfirmationModal from './ConfirmationModal'; - -const Transakcje = () => { - const [transactions, setTransactions] = useState([]); - const [isModalOpen, setIsModalOpen] = useState(false); - const [isEditModalOpen, setIsEditModalOpen] = useState(false); - const [editTransaction, setEditTransaction] = useState(null); - const [error, setError] = useState(null); - const [products, setProducts] = useState([]); - const [deleteTransactionId, setDeleteTransactionId] = useState(null); - const [newTransaction, setNewTransaction] = useState({ - id: 2, - date: "", - employeeId: "", - transactionProducts: [ - { - id: 0, - transactionId: 2, - productID: 0, - productName: "", - quantity: "" - } - ], - paymentType: "", - discount: "", - description: "", - totalPrice: 0 - }); - - const fetchTransactions = async () => { - const token = localStorage.getItem('token'); - if (!token) { - console.error('Brak tokena. Użytkownik musi być zalogowany.'); - return; - } - try { - const response = await axios.get('https://localhost:7039/api/Transaction', { - headers: { - Authorization: `Bearer ${token}` - } - }); - setTransactions(response.data); - } catch (error) { - console.error('Błąd podczas dodawania transakcji:', error); - } - }; - const fetchProducts = async () => { - const token = localStorage.getItem('token'); - if (!token) { - console.error('Brak tokena. Użytkownik musi być zalogowany.'); - return; - } - try { - const response = await axios.get('https://localhost:7039/api/Products', { - headers: { - Authorization: `Bearer ${token}` - } - }); - setProducts(response.data.map(product => ({ value: product.id, label: product.name }))); - } catch (error) { - console.error('Błąd podczas pobierania produktów:', error); - } - }; - - useEffect(() => { - fetchTransactions(); - fetchProducts(); - console.log(); - }, []); - - const handleAddTransaction = async () => { - if (!newTransaction.date || !newTransaction.employeeId || newTransaction.transactionProducts.some(product => !product.productName || !product.quantity)) { - setError('Proszę uzupełnić wszystkie pola.'); - return; - } - try { - console.log('Nowa transakcja:', newTransaction); - await axios.post('https://localhost:7039/api/Transaction', newTransaction); - - fetchTransactions(); - setIsModalOpen(false); - setNewTransaction({ - id: 2, - date: "", - employeeId: "", - transactionProducts: [ - { - id: 2, - transactionId: 0, - productID: 0, - productName: "", - quantity: "" - } - ], - paymentType: "", - discount: "", - description: "", - totalPrice: 0 - }); - } catch (error) { - console.error('Błąd podczas dodawania transakcji:', error); - if (error.response && error.response.data) { - setError(error.response.data); - } else { - setError('Wystąpił nieoczekiwany błąd. Spróbuj ponownie później.'); - } - } - }; - - const formatDate = (dateString) => { - const options = { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }; - const date = new Date(dateString); - return date.toLocaleDateString('pl-PL', options).replace(",", ""); - }; - const formatPrice = (price) => { - return parseFloat(price).toFixed(2); - }; - - const handleAddProduct = () => { - setNewTransaction({ - ...newTransaction, - transactionProducts: [ - ...newTransaction.transactionProducts, - { - id: 2, - transactionId: 0, - productID: 0, - productName: "", - quantity: "" - } - ] - }); - }; - - const handleRemoveProduct = (index) => { - const updatedTransactionProducts = [...newTransaction.transactionProducts]; - updatedTransactionProducts.splice(index, 1); - setNewTransaction({ - ...newTransaction, - transactionProducts: updatedTransactionProducts - }); - }; - - const handleDeleteTransaction = async (transactionId) => { - try { - await axios.delete(`https://localhost:7039/api/Transaction/${transactionId}`); - fetchTransactions(); - setDeleteTransactionId(null); - } catch (error) { - console.error('Błąd podczas usuwania transakcji:', error); - if (error.response && error.response.data) { - setError(error.response.data); - } else { - setError('Wystąpił nieoczekiwany błąd. Spróbuj ponownie później.'); - } - } - }; - const handleEditTransaction = async (transaction) => { - try { - if (!editTransaction) { - setEditTransaction(transaction); - setIsEditModalOpen(true); - return; - } - if (!editTransaction.date || !editTransaction.employeeId || editTransaction.transactionProducts.some(product => !product.productName || !product.quantity) || !editTransaction.paymentType){ - setError('Proszę uzupełnić wszystkie pola.'); - return;} - await axios.put(`https://localhost:7039/api/Transaction/${editTransaction.id}`, editTransaction); - fetchTransactions(); - setIsEditModalOpen(false); - setEditTransaction(null); - setError(null); - - } catch (error) { - console.error('Błąd podczas edycji transakcji:', error); - if (error.response && error.response.data) { - setError(error.response.data); - } else { - setError('Wystąpił nieoczekiwany błąd. Spróbuj ponownie później.'); - } - } - }; - const handleProductChange = (index, selectedOption) => { - const updatedTransactionProducts = [...newTransaction.transactionProducts]; - updatedTransactionProducts[index].productID = selectedOption.value; - updatedTransactionProducts[index].productName = selectedOption.label; - setNewTransaction({ - ...newTransaction, - transactionProducts: updatedTransactionProducts - }); - }; - const handleEditProductChange = (index, selectedOption) => { - const updatedTransactionProducts = [...editTransaction.transactionProducts]; - updatedTransactionProducts[index].productID = selectedOption.value; - updatedTransactionProducts[index].productName = selectedOption.label; - setEditTransaction({ - ...editTransaction, - transactionProducts: updatedTransactionProducts - }); - }; - const openDeleteConfirmation = (transactionId) => { - setDeleteTransactionId(transactionId); - }; - - const closeDeleteConfirmation = () => { - setDeleteTransactionId(null); - }; - - - return ( -
-
-
- Lista Transakcji -
- -
- {error && ( -
-
-

Błąd

-

{error}

- -
-
- )} - {isEditModalOpen && editTransaction && ( -
-
-

Edytuj transakcję

- setEditTransaction({ ...editTransaction, date: e.target.value })} - placeholder="Data" - className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg" - /> - Numer Pracownika - setEditTransaction({ ...editTransaction, employeeId: e.target.value })} - placeholder="Nr. Pracownika" - className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg" - /> - {editTransaction.transactionProducts.map((product, index) => ( -
- { - const newTransactionProducts = [...editTransaction.transactionProducts]; - newTransactionProducts[index].quantity = e.target.value; - setEditTransaction({ ...editTransaction, transactionProducts: newTransactionProducts }); - }} - placeholder="Ilość" - className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg" - /> -
- ))} - setEditTransaction({ ...editTransaction, paymentType: e.target.value })} - placeholder="Sposób płatności" - className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg" - /> - Zniżka - setEditTransaction({ ...editTransaction, discount: e.target.value })} - placeholder="Rabat" - className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg" - /> - setEditTransaction({ ...editTransaction, description: e.target.value })} - placeholder="Opis" - className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg" - /> - - -
-
- )} - - {isModalOpen && ( -
-
-

Dodaj nową transakcję

- setNewTransaction({ ...newTransaction, date: e.target.value })} - placeholder="Data" - className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg" - /> - setNewTransaction({ ...newTransaction, employeeId: e.target.value })} - placeholder="Nr. Pracownika" - className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg" - /> - {newTransaction.transactionProducts.map((product, index) => ( -
- { - const newTransactionProducts = [...newTransaction.transactionProducts]; - newTransactionProducts[index].quantity = e.target.value; - setNewTransaction({ ...newTransaction, transactionProducts: newTransactionProducts }); - }} - placeholder="Ilość" className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg" - /> - -
- ))} - - setNewTransaction({ ...newTransaction, paymentType: e.target.value })} - placeholder="Sposób płatności" - className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg" - /> - setNewTransaction({ ...newTransaction, discount: e.target.value })} - placeholder="Rabat" - className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg" - /> - setNewTransaction({ ...newTransaction, description: e.target.value })} - placeholder="Opis" - className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg" - /> - - -
-
- )} -
-
- - - - - - - - - - - - - - - - {transactions.map(transaction => ( - - - - - - - - - - - - ))} - -
IDDataProduktIlośćKwotaSposób płatnościNr. Pracownika
{transaction.id}{formatDate(transaction.date)} - {transaction.transactionProducts.map(product => ( -
{product.product.name}
- ))} -
- {transaction.transactionProducts.map(product => ( -
{product.quantity}
- ))} -
{formatPrice(transaction.totalPrice)}{transaction.paymentType}{transaction.employeeId}
-
-
-
-
- {deleteTransactionId && ( - {handleDeleteTransaction(deleteTransactionId); setDeleteTransactionId(false);}} - />)} -
- ); - } - -export default Transakcje - - - - - - diff --git a/firm/src/components/ZarzadzanieProduktami.js b/firm/src/components/ZarzadzanieProduktami.js index a3e90e1..0e702af 100644 --- a/firm/src/components/ZarzadzanieProduktami.js +++ b/firm/src/components/ZarzadzanieProduktami.js @@ -1,325 +1,22 @@ -import React, { useState, useEffect } from 'react'; -import axios from 'axios'; -import editIcon from "../icons/edit.png"; -import koszIcon from "../icons/kosz.png"; -import plusIcon from "../icons/plus.png"; -import ConfirmationModal from './ConfirmationModal'; +import React from 'react'; +import { Routes, Route, useNavigate } from 'react-router-dom'; +import ListaProduktow from './ListaProduktów'; +import DodawanieProduktu from './DodawanieProduktów'; +import EdycjaProduktu from './EdycjaProduktu'; const ZarzadzanieProduktami = () => { - const [products, setProducts] = useState([]); - const [isModalOpen, setIsModalOpen] = useState(false); - const [isEditModalOpen, setIsEditModalOpen] = useState(false); - const [error, setError] = useState(null); - const [deleteProductId, setDeleteProductId] = useState(null); - const [newProduct, setNewProduct] = useState({ - name: "", - description: "", - price: "", - type: "", - availability: "" - }); - const [editProduct, setEditProduct] = useState(null); - - const fetchProducts = async () => { - const token = localStorage.getItem('token'); - if (!token) { - console.error('Brak tokena. Użytkownik musi być zalogowany.'); - return; - } - - try { - const response = await axios.get('https://localhost:7039/api/products', { - headers: { - Authorization: `Bearer ${token}` - } - }); - setProducts(response.data); - } catch (error) { - console.error('Błąd podczas pobierania produktów:', error); - } - }; - - useEffect(() => { - fetchProducts(); - }, []); - - const handleInputChange = (event) => { - const { name, value } = event.target; - setNewProduct({ ...newProduct, [name]: value }); - }; - - const handleAddProduct = async () => { - if (!newProduct.name || !newProduct.description || !newProduct.price || !newProduct.type || !newProduct.availability) { - setError('Proszę uzupełnić wszystkie pola.'); - return; - } - try { - const config = { - headers: { - 'Content-Type': 'application/json' - } - }; - await axios.post('https://localhost:7039/api/Products', newProduct, config); - fetchProducts(); - setIsModalOpen(false); - setNewProduct({ - name: "", - availability: "", - price: "", - type: "", - description: "" - }); - } catch (error) { - console.error('Błąd podczas dodawania:', error); - if (error.response && error.response.data) { - setError(error.response.data); - } else { - setError('Wystąpił nieoczekiwany błąd. Spróbuj ponownie później.'); - } - } - }; - - const handleEditProduct = (product) => { - setEditProduct(product); - setIsEditModalOpen(true); - }; - - const handleSaveEditedProduct = async () => { - if (!editProduct.name || !editProduct.description || !editProduct.price || !editProduct.type || !editProduct.availability) { - setError('Proszę uzupełnić wszystkie pola.'); - return; - } - try { - await axios.put(`https://localhost:7039/api/Products/${editProduct.id}`, editProduct); - fetchProducts(); - setIsEditModalOpen(false); - } catch (error) { - console.error('Błąd podczas edycji:', error); - if (error.response && error.response.data) { - setError(error.response.data); - } else { - setError('Wystąpił nieoczekiwany błąd. Spróbuj ponownie później.'); - } - } - }; - - const handleDeleteProduct = async () => { - try { - await axios.delete(`https://localhost:7039/api/Products/${deleteProductId}`); - fetchProducts(); - setDeleteProductId(null); - } catch (error) { - console.error('Błąd podczas usuwania produktu:', error); - if (error.response && error.response.data) { - setError(error.response.data); - } else { - setError('Wystąpił nieoczekiwany błąd. Spróbuj ponownie później.'); - } - } - }; - -const openDeleteConfirmation = (productId) => { - setDeleteProductId(productId); -}; - -const closeDeleteConfirmation = () => { - setDeleteProductId(null); -}; -const formatPrice = (price) => { - return parseFloat(price).toFixed(2); -}; + const navigate = useNavigate(); return ( -
-
-
- Katalog Produktów -
- -
- {error && ( -
-
-

Błąd

-

{error}

- -
-
- )} - {isEditModalOpen && editProduct && ( -
-
-

Edytuj produkt

- setEditProduct({ ...editProduct, name: e.target.value })} - placeholder="Nazwa produktu" - className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg" - /> - setEditProduct({ ...editProduct, description: e.target.value })} - placeholder="Opis" - className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg" - /> - setEditProduct({ ...editProduct, price: e.target.value })} - placeholder="Cena" - className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg" - /> - setEditProduct({ ...editProduct, type: e.target.value })} - placeholder="Typ" - className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg" - /> - setEditProduct({ ...editProduct, availability: e.target.value })} - placeholder="Dostępność" - className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg" - /> - - -
-
- )} - {isModalOpen && ( -
-
-

Dodaj nowy produkt

- - - - - - - -
-
- )} -
-
- - - - - - - - - - - - - - - {products.map(product => ( - - - - - - - - - - - ))} - -
IDProduktOpisCenaKategoriaDostępność
{product.id}{product.name}{product.description}{formatPrice(product.price)}{product.type}{product.availability} -
-
-
- {deleteProductId && ( - {handleDeleteProduct(); setDeleteProductId(false);}} +
+ + navigate('/produkty/dodaj')} onEdit={(id) => navigate(`/produkty/edytuj/${id}`)} />} /> - )} + } /> + } /> +
); }; diff --git a/firm/src/components/ZarzadzanieTransakcjami.js b/firm/src/components/ZarzadzanieTransakcjami.js new file mode 100644 index 0000000..a78db42 --- /dev/null +++ b/firm/src/components/ZarzadzanieTransakcjami.js @@ -0,0 +1,24 @@ +import React from 'react'; +import { Routes, Route, useNavigate } from 'react-router-dom'; +import ListaTransakcji from './ListaTransakcji'; +import DodawanieTransakcji from './DodawanieTransakcji'; +import EdycjaTransakcji from './EdycjaTransakcji'; + +const ZarzadzanieTransakcjami = () => { + const navigate = useNavigate(); + + return ( +
+ + navigate('/transakcje/dodaj')} onEdit={(id) => navigate(`/transakcje/edytuj/${id}`)} />} + /> + } /> + } /> + +
+ ); +}; + +export default ZarzadzanieTransakcjami;