diff --git a/public/images/pie-chart.png b/public/images/pie-chart.png
index e9821fd..1809511 100644
Binary files a/public/images/pie-chart.png and b/public/images/pie-chart.png differ
diff --git a/public/images/profile.png b/public/images/profile.png
index 5e60eb7..f603980 100644
Binary files a/public/images/profile.png and b/public/images/profile.png differ
diff --git a/public/images/sector.png b/public/images/sector.png
index 6084390..bf926ae 100644
Binary files a/public/images/sector.png and b/public/images/sector.png differ
diff --git a/public/images/supplier.png b/public/images/supplier.png
index e152300..1d829a4 100644
Binary files a/public/images/supplier.png and b/public/images/supplier.png differ
diff --git a/public/images/userpage.png b/public/images/userpage.png
index a024e26..2407263 100644
Binary files a/public/images/userpage.png and b/public/images/userpage.png differ
diff --git a/src/components/ProductCategory/ProductCategory.js b/src/components/ProductCategory/ProductCategory.js
index 5859847..8f420c2 100644
--- a/src/components/ProductCategory/ProductCategory.js
+++ b/src/components/ProductCategory/ProductCategory.js
@@ -390,6 +390,7 @@ function ProductCategory(props) {
props.onCategoryUpdated(props.categoryKey, categoryName, categoryImage)
closeCategoryModal()
+ window.location.reload()
flashInfo()
} catch (err) {
console.log(err)
diff --git a/src/components/ProductCell/ProductCell.js b/src/components/ProductCell/ProductCell.js
index 1949d39..d8d11cc 100644
--- a/src/components/ProductCell/ProductCell.js
+++ b/src/components/ProductCell/ProductCell.js
@@ -1,9 +1,41 @@
+import { useState, useEffect } from "react";
+import { useParams } from 'react-router-dom';
+import api from "../../services/api";
+import FlashMessage from '../../components/FlashMessage/FlashMessage';
+import ProductModal from "../ProductModal/ProductModal";
+
const ProductCell = ({ aoClickar,product }) => {
const onProductClick = () => {
aoClickar(product.product_id);
-
-
+ }
+
+ /**
+ * Renderização da flash message
+ */
+ const [flash, setFlash] = useState(null)
+
+ const showFlashMessage = (message, type) => {
+ setFlash(null)
+ setTimeout(() => {
+ setFlash({ message, type })
+ }, 0)
+ }
+
+ const flashSuccess = () => {
+ showFlashMessage('Item adicionado com sucesso!','success');
+ }
+
+ const flashError = () => {
+ showFlashMessage('Um erro aconteceu','error');
+ };
+
+ const flashInfo = () => {
+ showFlashMessage('Item atualizado', 'info');
+ }
+
+ const flashDelete = () => {
+ showFlashMessage('Item deletado', 'success');
}
const abbreviateNumber =(value,bool) => {
@@ -22,20 +54,439 @@ const ProductCell = ({ aoClickar,product }) => {
newValue += suffixes[suffixNum];
bool===true?bool='R$ ':bool='';
return bool + preffixes[suffixNum]+ ' ' + newValue;
- }
+ }
+ /**
+ * Retorna todas as unidades
+ */
+ const [units, setUnits] = useState([])
+
+ const fetchUnits = async () => {
+ try {
+ await api
+ .get('/unit')
+ .then(response => setUnits(response.data))
+ } catch(err) {
+ console.log(err)
+ }
+ }
+
+ /**
+ * Retorna todos os fornecedores
+ */
+
+ const [suppliers, setSuppliers] = useState([])
+
+ const fetchSuppliers = async () => {
+ try {
+ await api
+ .get('/supplier')
+ .then(response => setSuppliers(response.data))
+ } catch(err) {
+ console.log(err)
+ }
+ }
+ /**
+ * Retorna todos os setores
+ */
+
+ const [sectors, setSector] = useState([])
+
+ const fetchSector = async () => {
+ try {
+ await api
+ .get('/sector')
+ .then(response => setSector(response.data))
+ } catch(err) {
+ console.log(err)
+ }
+ }
+
+ const [local, setLocals] = useState([])
+
+ const fetchLocals = async () => {
+ try {
+ await api
+ .get('/local')
+ .then(response => setLocals(response.data))
+ } catch(err) {
+ console.log(err)
+ }
+ }
+
+ /**
+ * Hook de useEffect para ativar as funções quando o componente é renderizado
+ */
+ useEffect(() => {
+ const fetchData = async () => {
+ await fetchUnits()
+ await fetchSuppliers()
+ await fetchSector()
+ await fetchLocals()
+ }
+ fetchData()
+ }, [])
+
+ const [isProdEditModalOpen, setIsProdEditModalOpen] = useState(false);
+ const [currentProduct, setCurrentProduct] = useState(null);
+ const parseCurrencyToFloat = (value) => {
+ return parseFloat(value.replace("R$", "").replace(".", "").replace(",", "."));
+ }
+ const [productName, setProductName] = useState('');
+ const [productDescription, setProductDescription] = useState('');
+ const [productUnitId, setProductUnitId] = useState('');
+ const [productSupplierId, setProductSupplierId] = useState('');
+ const [productLocalId, setProductLocalId] = useState('');
+ const [productSectorId, setProductSectorId] = useState('');
+ const [isPerishable, setIsPerishable] = useState(false);
+ const [productCostValue, setProductCostValue] = useState('');
+ const [productSellValue, setProductSellValue] = useState('');
+ const [productStock, setProductStock] = useState('');
+ const [productStockMin, setProductStockMin] = useState('');
+ const [quantityMax, setQuantityMax] = useState('');
+ const [productImage, setProductImage] = useState(null);
+ const [imagePreview, setImagePreview] = useState(null);
+ const [expirationDate, setExpirationDate] = useState('');
+ const {id} = useParams();
+
+ const openProdEditModal = () => {
+ // setCurrentProduct(product);
+ setProductName(product.product_name);
+ setProductUnitId(product.unit_id);
+ setProductSupplierId(product.supplier_id);
+ setProductLocalId(product.supplier_id);
+ setProductSectorId(product.supplier_id);
+ setIsPerishable(product.is_perishable);
+ setProductCostValue(product.prod_cost_value);
+ setProductSellValue(product.prod_sell_value);
+ setProductStock(product.product_stock);
+ setProductStockMin(product.product_stock_min);
+ setQuantityMax(product.quantity_max);
+
+ const imageUrl = product.product_img ? `http://localhost:3001${product.product_img}` : null;
+ setProductImage(imageUrl);
+ setImagePreview(imageUrl);
+
+ if (product.description === null) {
+ setProductDescription('');
+ }
+
+ setIsProdEditModalOpen(true);
+ };
+
+ const closeProdEditModal = () => {
+ setIsProdEditModalOpen(false);
+ setCurrentProduct(null);
+ };
+
+ const handleProdUpdate = async (e) => {
+ e.preventDefault();
+
+ const updatedProductData = new FormData();
+ updatedProductData.append('product_name', productName);
+ updatedProductData.append('description', productDescription);
+ updatedProductData.append('category_id', id);
+ updatedProductData.append('supplier_id', productSupplierId);
+ updatedProductData.append('is_perishable', isPerishable);
+ updatedProductData.append('unit_id', productUnitId);
+ updatedProductData.append("prod_cost_value", productCostValue);
+ updatedProductData.append("prod_sell_value", productSellValue);
+ updatedProductData.append('local_id', productLocalId);
+ updatedProductData.append('sector_id', productSectorId);
+ updatedProductData.append('product_stock', productStock);
+ updatedProductData.append('product_stock_min', productStockMin);
+ updatedProductData.append('quantity_max', quantityMax);
+
+ if (productImage instanceof File) {
+ updatedProductData.append('product_img', productImage);
+ }
+
+ try {
+ await api
+ .put(`/products/${product.product_id}`, updatedProductData, {
+ headers: {
+ 'Content-Type': 'multipart/form-data',
+ },
+ })
+ .then((response) => console.log(response));
+ flashInfo();
+ closeProdEditModal();
+ window.location.reload()
+ } catch (err) {
+ console.log(err);
+ flashError();
+ }
+ };
+
+ const formatCurrency = (value) => {
+ const formattedValue = parseFloat(value.replace(/[^\d]/g, '') / 100).toLocaleString('pt-BR', {
+ style: 'currency',
+ currency: 'BRL'
+ });
+ return formattedValue;
+ };
+
+ useEffect(() => {
+ if (productImage instanceof File) {
+ const previewUrl = URL.createObjectURL(productImage)
+ setImagePreview(previewUrl)
+ return () => URL.revokeObjectURL(previewUrl)
+ } else if (typeof productImage === 'string') {
+ setImagePreview(productImage)
+ } else {
+ setImagePreview(null)
+ }
+ }, [productImage])
+
return (
-
+
-
+
{product.product_name}
+
{abbreviateNumber(product.product_stock) +" Und."}
{abbreviateNumber(product.prod_cost_value ,true)}
-
-
+
+
+
+ {/* Modal para editar produto */}
+ {isProdEditModalOpen && (
+
+
+
+
document.getElementById('product-image-input').click()}
+ >
+
{
+ const file = e.target.files[0]
+ if (file) {
+ setProductImage(file)
+ setImagePreview(URL.createObjectURL(file))
+ }
+ }}
+ name="product-image"
+ />
+ {imagePreview ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+
+ Nome do produto
+
+ setProductName(e.target.value)}
+ />
+
+
+
+
+ Unidade
+
+ setProductUnitId(parseInt(e.target.value))}
+ className="p-[4px] shadow-[0px_2px_2px_2px_rgba(0,0,0,0.25)] ring ring-2 ring-[#BF823C] focus:ring-[#3E1A00] outline-none quinteral-color-bg rounded font-pixel text-xl transition-all duration-[100ms] ease-in-out alt-color-5"
+ >
+ Selecionar unidade
+ {units.map((unit) => (
+ {unit.unit_type}
+ ))}
+
+
+
+
+
+ Fornecedor
+
+ setProductSupplierId(parseInt(e.target.value))}
+ className="p-[4px] shadow-[0px_2px_2px_2px_rgba(0,0,0,0.25)] ring ring-2 ring-[#BF823C] focus:ring-[#3E1A00] outline-none quinteral-color-bg rounded font-pixel text-xl transition-all duration-[100ms] ease-in-out alt-color-5"
+ >
+ Selecionar fornecedor
+ {suppliers.map((supplier) => (
+ {supplier.supplier_name}
+ ))}
+
+
+
+
+
+
+
+ É perecível
+ setIsPerishable(e.target.checked)}
+ />
+
+
+
+ {isPerishable && (
+
+
+ Data de Validade
+
+ setExpirationDate(e.target.value)}
+ />
+
+ )}
+
+
+
+
+
+ Local
+
+ setProductLocalId(parseInt(e.target.value))}
+ className="p-[4px] shadow-[0px_2px_2px_2px_rgba(0,0,0,0.25)] ring ring-2 ring-[#BF823C] focus:ring-[#3E1A00] outline-none quinteral-color-bg rounded font-pixel text-xl transition-all duration-[100ms] ease-in-out alt-color-5"
+ >
+ Selecionar local
+ {local.map((local) => (
+ {local.local_name}
+ ))}
+
+
+
+
+
+ Setor
+
+ setProductSectorId(parseInt(e.target.value))}
+ className="p-[4px] shadow-[0px_2px_2px_2px_rgba(0,0,0,0.25)] ring ring-2 ring-[#BF823C] focus:ring-[#3E1A00] outline-none quinteral-color-bg rounded font-pixel text-xl transition-all duration-[100ms] ease-in-out alt-color-5"
+ >
+ Selecionar setor
+ {sectors.map((sector) => (
+ {sector.sector_name}
+ ))}
+
+
+
+
+
+
+
+ )}
+
+ {/* Componente flash message, verifica se o estado flash é true e então renderiza a flash message */}
+ {flash && (
+
setFlash(null)}
+ />
+ )}
);
}
diff --git a/src/components/ProductModal/ProductModal.css b/src/components/ProductModal/ProductModal.css
new file mode 100644
index 0000000..287d286
--- /dev/null
+++ b/src/components/ProductModal/ProductModal.css
@@ -0,0 +1,38 @@
+@media screen and (max-width: 1822px) {
+ .modal-box .prod-modal {
+ max-width: 75%;
+ }
+}
+
+@media screen and (max-width: 1520px) {
+ .modal-box .prod-modal {
+ max-width: 95%;
+ }
+}
+
+@media screen and (max-width: 1222px) {
+ .modal-main-container {
+ flex-direction: column;
+ }
+
+ .modal-main-container > div {
+ width: 100%;
+
+ }
+
+ .modal-main-container > div:first-child > div {
+ margin: 0 auto;
+ }
+}
+
+@media screen and (max-width: 512px) {
+ .modal-action {
+ justify-content: center;
+ }
+}
+
+@media screen and (max-width: 470px) {
+ .preco-container {
+ flex-direction: column;
+ }
+}
\ No newline at end of file
diff --git a/src/components/ProductModal/ProductModal.js b/src/components/ProductModal/ProductModal.js
new file mode 100644
index 0000000..b11a1bb
--- /dev/null
+++ b/src/components/ProductModal/ProductModal.js
@@ -0,0 +1,24 @@
+import React from 'react'
+import './ProductModal.css'
+
+function ProductModal(props) {
+ return (
+
+
+ )
+}
+
+export default ProductModal
\ No newline at end of file
diff --git a/src/components/ProductTable/ProductTable2.js b/src/components/ProductTable/ProductTable2.js
index 2944ab0..6b3ab4f 100644
--- a/src/components/ProductTable/ProductTable2.js
+++ b/src/components/ProductTable/ProductTable2.js
@@ -1,12 +1,13 @@
import { useState, useEffect } from 'react';
import ProductCell from '../ProductCell/ProductCell';
-import SearchBar from '../SearchBar/SearchBar';
import { useParams } from 'react-router-dom';
import Modalsbtn from '../Modal/Modalsbtn';
import Loading from '../Loading/Loading';
import api from '../../services/api';
import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/solid'; // Icones da Filtragem
import ModalProducts from '../ModalProducts/ModalProducts';
+import ProductModal from '../ProductModal/ProductModal';
+import SearchBar from '../SearchBarAlt/SearchBarAlt';
const ProductTable = () => {
const [modal, setIsModalOpen] = useState(false);
@@ -23,6 +24,7 @@ const ProductTable = () => {
const [currentPage, setCurrentPage] = useState(1);
const [itemsPerPage, setItemsPerPage] = useState(20); // Default to 20 for desktop
+
const { id } = useParams();
console.log(productInfo);
@@ -145,15 +147,214 @@ const ProductTable = () => {
return pages;
};
+ /**
+ * Retorna todas as unidades
+ */
+ const [units, setUnits] = useState([])
+
+ const fetchUnits = async () => {
+ try {
+ await api
+ .get('/unit')
+ .then(response => setUnits(response.data))
+ } catch(err) {
+ console.log(err)
+ }
+ }
+
+ /**
+ * Retorna todos os fornecedores
+ */
+
+ const [suppliers, setSuppliers] = useState([])
+
+ const fetchSuppliers = async () => {
+ try {
+ await api
+ .get('/supplier')
+ .then(response => setSuppliers(response.data))
+ } catch(err) {
+ console.log(err)
+ }
+ }
+
+ /**
+ * Retorna todos os setores
+ */
+
+ const [sectors, setSector] = useState([])
+
+ const fetchSector = async () => {
+ try {
+ await api
+ .get('/sector')
+ .then(response => setSector(response.data))
+ } catch(err) {
+ console.log(err)
+ }
+ }
+
+ const [local, setLocals] = useState([])
+
+ const fetchLocals = async () => {
+ try {
+ await api
+ .get('/local')
+ .then(response => setLocals(response.data))
+ } catch(err) {
+ console.log(err)
+ }
+ }
+
+ /**
+ * Hook de useEffect para ativar as funções quando o componente é renderizado
+ */
+ useEffect(() => {
+ const fetchData = async () => {
+ // setLoading(true)
+ await fetchUnits()
+ await fetchSuppliers()
+ await fetchProducts()
+ await fetchSector()
+ await fetchLocals()
+ }
+ fetchData()
+ }, [])
+
useEffect(() => {
fetchProducts();
}, [id]);
console.log('products', productInfo);
+ /**
+ * Abre e fecha o modal de produtos
+ */
+ const [registerModal, setRegisterModal] = useState(false)
+ const openRegisterModal = () => setRegisterModal(true)
+ const closeRegisterModal = () => {
+ setProductName('')
+ setProductDescription('')
+ setProductUnitId('')
+ setProductSupplierId('')
+ setIsPerishable(false)
+ setProductSellValue('')
+ setProductCostValue('')
+ setProductSectorId('')
+ setProductLocalId('')
+ setProductBrand('')
+ setProductModel('')
+ setProductImage(null)
+ setProductStock('')
+ setProductStockMin('')
+ setQuantityMax('')
+ setRegisterModal(false)
+ }
+
+ /**
+ * Registra o produto
+ */
+ const [productDescription, setProductDescription] = useState(null)
+ const [productUnitId, setProductUnitId] = useState('')
+ const [productSupplierId, setProductSupplierId] = useState('')
+ const [isPerishable, setIsPerishable] = useState(false)
+ const [productBrand, setProductBrand] = useState('')
+ const [productModel, setProductModel] = useState('')
+ const [productCostValue, setProductCostValue] = useState('')
+ const [productSellValue, setProductSellValue] = useState('')
+ const [productLocalId, setProductLocalId] = useState('')
+ const [productSectorId, setProductSectorId] = useState('')
+ const [expirationDate, setExpirationDate] = useState('')
+ const [productImage, setProductImage] = useState(null)
+ const [productStock, setProductStock] = useState(null)
+ const [productStockMin, setProductStockMin] = useState(null)
+ const [quantityMax, setQuantityMax] = useState(null)
+
+ const handleProductRegistration = async(e) => {
+ e.preventDefault()
+
+ const formData = new FormData();
+ formData.append('product_name', productname);
+ formData.append('description', productDescription);
+ formData.append('category_id', id);
+ formData.append('supplier_id', productSupplierId);
+ formData.append('is_perishable', isPerishable);
+ formData.append('unit_id', productUnitId);
+ formData.append('prod_model', productModel);
+ formData.append('prod_brand', productBrand);
+ formData.append("prod_cost_value", parseCurrencyToFloat(productCostValue));
+ formData.append("prod_sell_value", parseCurrencyToFloat(productSellValue));
+ formData.append('local_id', productLocalId);
+ formData.append('sector_id', productSectorId);
+ formData.append('product_stock', parseInt(productStock));
+ formData.append('product_stock_min', parseInt(productStockMin));
+ formData.append('quantity_max', parseInt(quantityMax));
+ if (productImage) {
+ formData.append('product_img', productImage);
+ }
+
+ try {
+ await api.post("/products", formData, {
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ }
+ })
+ .then(response => {setProducts((prevProducts) => [response.data, ...prevProducts])})
+
+
+ setProductName('')
+ setProductDescription('')
+ setProductUnitId('')
+ setProductSupplierId('')
+ setIsPerishable(false)
+ setProductSellValue('')
+ setProductCostValue('')
+ setProductSectorId('')
+ setProductLocalId('')
+ setProductBrand('')
+ setProductModel('')
+ setProductImage(null)
+ setProductStock('')
+ setProductStockMin('')
+ setQuantityMax('')
+ closeModal()
+ flashSuccess()
+ } catch (err) {
+ console.log(err)
+ flashError()
+ }
+ }
+
+ const formatCurrency = (value) => {
+ const formattedValue = parseFloat(value.replace(/[^\d]/g, '') / 100).toLocaleString('pt-BR', {
+ style: 'currency',
+ currency: 'BRL'
+ });
+ return formattedValue;
+ };
+
+ const parseCurrencyToFloat = (value) => {
+ return parseFloat(value.replace("R$", "").replace(".", "").replace(",", "."));
+ }
+
+ useEffect(() => {
+ if (productImage instanceof File) {
+ const previewUrl = URL.createObjectURL(productImage)
+ setImagePreview(previewUrl)
+ return () => URL.revokeObjectURL(previewUrl)
+ } else if (typeof productImage === 'string') {
+ setImagePreview(productImage)
+ } else {
+ setImagePreview(null)
+ }
+ }, [productImage])
+
return (
-
+
{currentItems.map((product, index) => (
@@ -203,6 +404,227 @@ const ProductTable = () => {
{productInfo ?
:
}
)}
+
+ {/* Modal de produto */}
+ {registerModal && (
+
+
+
+
document.getElementById('product-image-input').click()}
+ >
+
{
+ setProductImage(e.target.files[0]);
+ }}
+ name="product-image"
+ />
+
+
+ {imagePreview && (
+
+
+
+ )}
+
+
+
+
+
+
+ Nome do produto
+
+ setProductName(e.target.value)}
+ />
+
+
+
+
+ Unidade
+
+ setProductUnitId(parseInt(e.target.value))}
+ className="p-[4px] shadow-[0px_2px_2px_2px_rgba(0,0,0,0.25)] ring ring-2 ring-[#BF823C] focus:ring-[#3E1A00] outline-none quinteral-color-bg rounded font-pixel text-xl transition-all duration-[100ms] ease-in-out alt-color-5"
+ >
+ Selecionar unidade
+ {units.map((unit) => (
+ {unit.unit_type}
+ ))}
+
+
+
+
+
+ Fornecedor
+
+ setProductSupplierId(parseInt(e.target.value))}
+ className="p-[4px] shadow-[0px_2px_2px_2px_rgba(0,0,0,0.25)] ring ring-2 ring-[#BF823C] focus:ring-[#3E1A00] outline-none quinteral-color-bg rounded font-pixel text-xl transition-all duration-[100ms] ease-in-out alt-color-5"
+ >
+ Selecionar fornecedor
+ {suppliers.map((supplier) => (
+ {supplier.supplier_name}
+ ))}
+
+
+
+
+
+
+
+ É perecível
+ setIsPerishable(e.target.checked)}
+ />
+
+
+
+ {isPerishable && (
+
+
+ Data de Validade
+
+ setExpirationDate(e.target.value)}
+ />
+
+ )}
+
+
+
+
+
+ Local
+
+ setProductLocalId(parseInt(e.target.value))}
+ className="p-[4px] shadow-[0px_2px_2px_2px_rgba(0,0,0,0.25)] ring ring-2 ring-[#BF823C] focus:ring-[#3E1A00] outline-none quinteral-color-bg rounded font-pixel text-xl transition-all duration-[100ms] ease-in-out alt-color-5"
+ >
+ Selecionar local
+ {local.map((local) => (
+ {local.local_name}
+ ))}
+
+
+
+
+
+ Setor
+
+ setProductSectorId(parseInt(e.target.value))}
+ className="p-[4px] shadow-[0px_2px_2px_2px_rgba(0,0,0,0.25)] ring ring-2 ring-[#BF823C] focus:ring-[#3E1A00] outline-none quinteral-color-bg rounded font-pixel text-xl transition-all duration-[100ms] ease-in-out alt-color-5"
+ >
+ Selecionar setor
+ {sectors.map((sector) => (
+ {sector.sector_name}
+ ))}
+
+
+
+
+
+
+
+ )}
);
};
diff --git a/src/components/ProductTable/ProductTableMvSt.js b/src/components/ProductTable/ProductTableMvSt.js
index 94cfb00..68d2506 100644
--- a/src/components/ProductTable/ProductTableMvSt.js
+++ b/src/components/ProductTable/ProductTableMvSt.js
@@ -55,6 +55,10 @@ function ProductTableMvSt() {
return pages;
};
+<<<<<<< HEAD
+
+=======
+>>>>>>> 845b428272a5465f464facb6ff0aa4423bd10ac8
const downloadPDF = async () => {
try {
const response = await Axios.get('http://localhost:3001/stock-movements/pdf', {
@@ -214,7 +218,7 @@ function ProductTableMvSt() {
{movement.batch ? movement.batch.batch_id : 'N/A'}
{movement.movement_type}
{movement.user ? movement.user.username : 'N/A'}
-
{new Date(movement.movement_date).toLocaleString()}
+
{movement.movement_date}
{movement.category ? movement.category.category_name : 'N/A'}
))}
@@ -222,41 +226,37 @@ function ProductTableMvSt() {
-
- {/* Paginação */}
-
+
-
+
- {paginationRange().map((page, index) =>
- page === '...' ? (
- ...
- ) : (
- goToPage(page)}
- className={`px-4 py-2 rounded-lg ${currentPage === page ? 'bg-[#4e2d19] text-[#FFC376]' : 'text-[#6B3710] hover:bg-[#C17B46]'}`}
- >
- {page}
-
- )
- )}
+ {paginationRange().map((page, index) => (
+ goToPage(page)}
+ className={`px-4 py-2 rounded-md ${
+ page === currentPage ? 'bg-[#6B3710] text-white' : 'bg-[#F5A66D] text-[#6B3710]'
+ }`}
+ disabled={page === '...'}
+ >
+ {page}
+
+ ))}
-
+
-
{isModalOpen && selectedMovement && (
@@ -285,4 +285,4 @@ function ProductTableMvSt() {
);
}
-export default ProductTableMvSt;
+export default ProductTableMvSt;
\ No newline at end of file
diff --git a/src/components/Sidebar/Sidebari.js b/src/components/Sidebar/Sidebari.js
index 1df306a..fe32ed5 100644
--- a/src/components/Sidebar/Sidebari.js
+++ b/src/components/Sidebar/Sidebari.js
@@ -111,7 +111,7 @@ function Sidebari({ content }) {
}
+ icon={
}
component={
}
>
Fornecedores
@@ -127,7 +127,7 @@ function Sidebari({ content }) {
{(role === 'admin' || role === 'gerente') && (
}
+ icon={
}
label="Gerenciar"
className="poppins-semibold"
@@ -137,7 +137,7 @@ function Sidebari({ content }) {
}}
>
}
+ icon={
}
className="poppins-semibold"
component={
}
onMouseEnter={(e) => e.currentTarget.style.backgroundColor = '#3E1900'}
@@ -176,7 +176,7 @@ function Sidebari({ content }) {
{collapsed ? 'Config' : 'Configurações'}
*/}
}
+ icon={
}
className="poppins-semibold"
component={
}
onMouseEnter={(e) => e.currentTarget.style.backgroundColor = '#3E1900'}
@@ -196,7 +196,7 @@ function Sidebari({ content }) {
{collapsed ? 'Fornecedores' : 'Fornecedores'}
}
+ icon={
}
className="poppins-semibold"
component={
}
onMouseEnter={(e) => e.currentTarget.style.backgroundColor = '#3E1900'}
diff --git a/src/components/UserProfileIcon/UserProfileIcon.js b/src/components/UserProfileIcon/UserProfileIcon.js
index 2926a91..40e5a64 100644
--- a/src/components/UserProfileIcon/UserProfileIcon.js
+++ b/src/components/UserProfileIcon/UserProfileIcon.js
@@ -45,6 +45,7 @@ function UserProfileIcon() {
setUser(null);
navigate('/login');
};
+
if (!user) {
return null;
@@ -144,6 +145,7 @@ function UserProfileIcon() {
{user.user_img ? (
+
-
-
-
-
-
-
+
+
+
@@ -83,7 +81,7 @@ function Analytics() {
-
+
);
}
diff --git a/src/pages/BuyAndSell/BuyAndSell.js b/src/pages/BuyAndSell/BuyAndSell.js
index 55200e4..d46ca4c 100644
--- a/src/pages/BuyAndSell/BuyAndSell.js
+++ b/src/pages/BuyAndSell/BuyAndSell.js
@@ -37,11 +37,8 @@ function BuyAndSell() {
-
{/* Barra de pesquisa (componente que você pode personalizar se necessário) */}
{/* Passando os produtos como prop para o ProductTable */}
-
-
diff --git a/src/pages/UserProfile/UserProfile.js b/src/pages/UserProfile/UserProfile.js
index b8fcfd6..6d795bb 100644
--- a/src/pages/UserProfile/UserProfile.js
+++ b/src/pages/UserProfile/UserProfile.js
@@ -1,11 +1,155 @@
-import React from 'react'
-import MainPage from '../MainPage/MainPage'
+import React, { useState, useContext } from "react";
+import MainPage from "../MainPage/MainPage";
+import { UserContext } from "../../context/userContext";
+import api from "../../services/api";
function UserProfile() {
+ const { user, setUser } = useContext(UserContext);
+ const [username, setUsername] = useState(user?.username || "");
+ const [isEditing, setIsEditing] = useState(false);
+ const [loading, setLoading] = useState(false);
+ const [success, setSuccess] = useState(false);
+ const [error, setError] = useState(null);
+ const [image, setImage] = useState(null); // Para armazenar a imagem selecionada
+
+ const handleEdit = async () => {
+ console.log("Iniciando edição de usuário...");
+ console.log("Enviando dados:", { user_id: user.user_id, username });
+
+ setLoading(true);
+ setError(null);
+ setSuccess(false);
+
+ try {
+ const response = await api.put(`/users/${user.user_id}`, { username });
+ console.log("Resposta da API:", response.data);
+ setUser({ ...user, username: response.data.username });
+ setSuccess(true);
+ setIsEditing(false);
+ } catch (err) {
+ console.error("Erro na requisição:", err.response || err.message);
+ setError("Erro ao atualizar o nome. Tente novamente.");
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const handleImageChange = (e) => {
+ const file = e.target.files[0];
+ if (file) {
+ setImage(file); // Armazena o arquivo real
+ }
+ };
+
+ const handleImageUpload = async () => {
+ if (!image) return;
+
+ setLoading(true);
+ setError(null);
+ setSuccess(false);
+
+ try {
+ const formData = new FormData();
+ formData.append("user_img", image); // Envia o arquivo real como 'file'
+
+ // Ajuste a URL conforme a API do seu backend
+ const response = await api.put(`/users/${user.user_id}`, formData, {
+ headers: {
+ 'Content-Type': 'multipart/form-data',
+ },
+ });
+
+ console.log("Imagem atualizada com sucesso:", response.data);
+ setUser({ ...user, user_img: response.data.user_img }); // Atualiza o usuário com a nova imagem
+ setSuccess(true);
+ } catch (err) {
+ console.error("Erro ao carregar a imagem:", err);
+ setError("Erro ao atualizar a imagem. Tente novamente.");
+ } finally {
+ setLoading(false);
+ }
+ };
+
return (
+
+
+ {/* Exibição de imagem do usuário ou imagem padrão */}
+
+
+ {/* Botão para alterar imagem */}
+
+
+
+ Alterar ou Inserir Foto
+
+ {image && (
+
+ {loading ? "Carregando..." : "Salvar Imagem"}
+
+ )}
+
+
+
+
{user?.role}
+ {isEditing ? (
+ setUsername(e.target.value)}
+ className="border rounded p-2 w-full mb-2 bg-[#F4E1C1] text-[#6B3710] poppins-semibold"
+ />
+ ) : (
+ {user?.username}
+ )}
+
+
+
+ {isEditing ? (
+ <>
+
+ {loading ? "Salvando..." : "Salvar"}
+
+ setIsEditing(false)}
+ className="ml-2 bg-gray-500 text-white px-4 py-2 rounded transition-all hover:bg-gray-400"
+ >
+ Cancelar
+
+ >
+ ) : (
+ setIsEditing(true)}
+ className="bg-[#6B3710] text-[#FFC376] px-4 py-2 rounded transition-all hover:bg-[#C17B46]"
+ >
+ Editar Nome
+
+ )}
+
+ {error &&
{error}
}
+ {success &&
Atualizado com sucesso!
}
+
+
- )
+ );
}
-export default UserProfile
+export default UserProfile;