Files
hotel-hacienda/frontend/Frontend-Hotel/src/pages/Expenses/PurchaseEntries.jsx
Consultoria AS 0211bea186 Commit inicial - Sistema de Gestion Hotelera Hacienda San Angel
- Backend Node.js/Express con PostgreSQL
- Frontend React 19 con Vite
- Docker Compose para orquestacion
- Documentacion completa en README.md
- Scripts SQL para base de datos
- Configuracion de ejemplo (.env.example)
2026-01-17 18:52:34 -08:00

157 lines
4.8 KiB
JavaScript

import React, { useEffect, useState } from 'react';
import ConfirmationModal from '../../components/Modals/ConfirmationModal';
import Table from '../../components/Table/HotelTable';
import { Link } from 'react-router-dom';
import axios from 'axios';
import { useContext } from 'react';
import { langContext } from '../../context/LenguageContext';
//**////** */ */ REVISAR DELIVERED NULL
export default function PurchaseEntries() {
const { lang } = useContext(langContext);
const [purchases, setPurchases] = useState([]);
const [searchTerm, setSearchTerm] = useState('');
const [modalOpen, setModalOpen] = useState(false);
const [checking, setChecking] = useState(null);
const [selectedId, setSelectedId] = useState(null);
const loadPurchases = () => {
fetch(import.meta.env.VITE_API_BASE_URL + '/purchases/getpurchases')
.then(res => res.json())
.then(resData => {
const mapped = resData.data.map(item => ({
id: item.id_purchase_dt,
expense_id: item.id_expense,
name: item.product_name,
quantity: item.quantity,
delivered: item.delivered,
check: 0,
}));
setPurchases(mapped);
})
.catch(err => console.error('Error loading expense report:', err));
};
useEffect(() => {
loadPurchases();
}, []);
const filteredPurchases = purchases.filter(purchase =>
purchase.name.toLowerCase().includes(searchTerm.toLowerCase())
);
const columns = [
{ header: lang === "en" ? "PURCHASE ID" : "ID DE COMPRA", key: 'id' },
{ header: lang === "en" ? "EXPENSE ID" : "ID DE GASTO", key: 'expense_id' },
{ header: lang === "en" ? "PRODUCT" : "PRODUCTO", key: 'name' },
{ header: lang === "en" ? "REQUESTED" : "SOLICITADOS", key: 'quantity' },
{ header: lang === "en" ? "DELIVERED" : "ENTREGADOS", key: 'delivered' },
{
header: lang === "en" ? "CHECKING" : "RECIBIENDO",
key: 'check',
render: (check, row) => (
<input
type="number"
value={check} // opcional, para mantener sincronía
onChange={(e) => handleCheckingChange(row.id, e.target.value)}
placeholder={lang === "en" ? "Checking" : "Recibiendo"}
/>
),
},
{
header: lang === "en" ? "CONFIRM RECEIVED" : "CONFIRMAR RECEPCIÓN",
key: 'id',
headerStyle: { textAlign: 'center' },
render: (id, row) => (
<div style={{ textAlign: 'center' }}>
<button
className='status-button'
onClick={() => handleOpenModal(id, row.check)}
>
{lang === "en" ? "CONFIRM" : "CONFIRMAR"}
</button>
</div>
),
},
];
const handleCheckingChange = (id, value) => {
setPurchases(prev =>
prev.map(p =>
p.id === id ? { ...p, check: value } : p
)
);
};
const handleOpenModal = (id, check) => {
setSelectedId(id);
setChecking(check);
setModalOpen(true);
};
const handleConfirm = () => {
if (!selectedId || !checking) return;
axios.put(`${import.meta.env.VITE_API_BASE_URL}/purchases/entry/${selectedId}`, {
checking: parseInt(checking)
})
.then((res) => {
console.log(res.data.message || 'Estado actualizado correctamente');
//Actualizar purchases
loadPurchases();
// Cerrar el modal y limpiar selección
setModalOpen(false);
setSelectedId(null);
setChecking(null);
})
.catch((err) => {
console.error(`Error al actualizar el estado del gasto ${selectedId}:`, err);
alert('❌ Error al actualizar el estado. Intenta nuevamente.');
});
};
const handleCancel = () => {
setModalOpen(false);
};
return (
<div className="report-page">
<h2>{lang === "en" ? "Purchase Entries" : "Entradas de compras"}</h2>
<div style={{ marginBottom: '20px' }}>
<input
type="text"
placeholder={lang === "en" ? "Search by product name..." : "Buscar por nombre del producto..."}
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
style={{
padding: '10px 16px',
border: 'none',
borderRadius: '30px',
backgroundColor: 'white',
boxShadow: '0 0 0 2px #f4f4f4',
fontSize: '14px',
color: '#333',
fontFamily: "'Segoe UI', Tahoma, Geneva, Verdana, sans-serif",
fontWeight: 'bold',
minWidth: '250px',
width: '100%',
maxWidth: '400px'
}}
/>
</div>
<Table columns={columns} data={filteredPurchases} />
<ConfirmationModal
isOpen={modalOpen}
statusType={checking}
onConfirm={handleConfirm}
onCancel={handleCancel}
/>
</div>
);
}