Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
VITE_API_KEY="AIzaSyBMt_g1TJldovTJBzSI_e5jPNfzXxo4ChI"
VITE_AUTH_DOMAIN="restaurantecarol2024.firebaseapp.com"
VITE_PROJECT_ID="restaurantecarol2024"
VITE_STORAGE_BUCKET="restaurantecarol2024.appspot.com"
VITE_MESSAGING_SENDER_ID="144840930265"
VITE_APP_ID="1:144840930265:web:d4c7fe54f38e23bda25fc8"
29 changes: 22 additions & 7 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { useState } from 'react'
import viteLogo from '/vite.svg'
import './App.css'
import { useState } from 'react';
import viteLogo from '/vite.svg';
import './App.css';
import React from 'react';
import OrderForm from './orderForm';
import OrderList from './OrderList'; // Importacion del componente

function App() {
const [count, setCount] = useState(0)
const [count, setCount] = useState(0);

return (
<>
<div>
<a href="https://vitejs.dev" target="_blank">
<a href="https://vitejs.dev" target="_blank" rel="noopener noreferrer">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
</div>
Expand All @@ -24,8 +27,20 @@ function App() {
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>

<div>
<h1>Bienvenido al Restaurante</h1>
<p>Por favor, realiza tu pedido a continuación:</p>

<OrderForm /> {/* Componente del formulario de pedidos */}

<h2>Pedidos registrados:</h2>
<OrderList /> {/* Componente para mostrar los pedidos */}

<footer>Gracias por visitarnos</footer>
</div>
</>
)
);
}

export default App
export default App;
128 changes: 128 additions & 0 deletions src/OrderList.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import React, { useState, useEffect } from 'react';
import { collection, getDocs, doc, deleteDoc, updateDoc } from 'firebase/firestore';
import { db } from './firebaseConfig';
import OrderForm from './orderForm'; // Importa el formulario existente

const OrderList = () => {
const [orders, setOrders] = useState([]); // Lista de pedidos
const [selectedOrder, setSelectedOrder] = useState(null); // Pedido seleccionado
const [editing, setEditing] = useState(false); // Estado para saber si estamos editando
const [loading, setLoading] = useState(true); // Estado de carga

// Función para recuperar los pedidos desde Firestore
const fetchOrders = async () => {
try {
const querySnapshot = await getDocs(collection(db, 'orders'));
const ordersData = querySnapshot.docs.map(doc => ({
id: doc.id,
...doc.data()
}));
setOrders(ordersData);
} catch (error) {
console.error("Error al recuperar los pedidos:", error.message);
} finally {
setLoading(false);
}
};

// Llama a fetchOrders al cargar el componente
useEffect(() => {
fetchOrders();
}, []);

// Función para manejar clic en un pedido
const handleSelectOrder = (order) => {
setSelectedOrder(order); // Establece el pedido seleccionado
};

// Función para eliminar un pedido
const handleDeleteOrder = async (id) => {
const confirmDelete = window.confirm('¿Estás seguro de que deseas eliminar este pedido?');
if (confirmDelete) {
try {
await deleteDoc(doc(db, 'orders', id));
alert('Pedido eliminado exitosamente.');
setOrders(orders.filter(order => order.id !== id)); // Actualiza la lista localmente
setSelectedOrder(null); // Limpia el detalle si el pedido estaba seleccionado
} catch (error) {
console.error("Error al eliminar el pedido:", error.message);
}
}
};

// Función para manejar clic en Update
const handleUpdateOrder = () => {
setEditing(true); // Cambia al modo de edición
};

// Función para manejar la actualización del pedido
const handleSubmitUpdatedOrder = async (updatedOrder) => {
try {
await updateDoc(doc(db, 'orders', updatedOrder.id), updatedOrder);
alert('Pedido actualizado exitosamente.');
setEditing(false); // Salir del modo de edición
setSelectedOrder(null); // Regresa a la lista
fetchOrders(); // Actualiza la lista
} catch (error) {
console.error("Error al actualizar el pedido:", error.message);
}
};

// Renderizado condicional
if (loading) {
return <p>Cargando pedidos...</p>;
}

return (
<div>
<h2>Pedidos existentes</h2>

{!selectedOrder && !editing ? (
// Lista de pedidos
orders.length > 0 ? (
<ul>
{orders.map(order => (
<li key={order.id} style={{ marginBottom: '20px', cursor: 'pointer' }} onClick={() => handleSelectOrder(order)}>
<p><strong>Nombre del cliente:</strong> {order.customerName}</p>
<p><strong>Número de artículos:</strong> {order.items.length}</p>
<p><strong>Total:</strong> ${order.total}</p>
</li>
))}
</ul>
) : (
<p>No hay pedidos registrados.</p>
)
) : selectedOrder && !editing ? (
// Detalle del pedido seleccionado
<div>
<h3>Detalle del Pedido</h3>
<p><strong>Nombre del cliente:</strong> {selectedOrder.customerName}</p>
<p><strong>Artículos:</strong> {selectedOrder.items.join(', ')}</p>
<p><strong>Total:</strong> ${selectedOrder.total}</p>
<p><strong>Modalidad:</strong> {selectedOrder.modality}</p>
<p><strong>Creado en:</strong> {selectedOrder.createdAt?.toDate().toLocaleString()}</p>
<p><strong>Actualizado en:</strong> {selectedOrder.updatedAt?.toDate().toLocaleString()}</p>

{/* Botones de acción */}
<button onClick={handleUpdateOrder} style={{ marginRight: '10px' }}>Update</button>
<button onClick={() => handleDeleteOrder(selectedOrder.id)}>Delete</button>
<button onClick={() => setSelectedOrder(null)} style={{ marginTop: '20px' }}>
Volver a la lista
</button>
</div>
) : (
// Modo de edición
<OrderForm
initialData={selectedOrder} // Enviar los datos existentes al formulario
onSubmit={handleSubmitUpdatedOrder} // Llama a la función para guardar los cambios
onCancel={() => {
setEditing(false);
setSelectedOrder(null); // Regresa al detalle si se cancela
}}
/>
)}
</div>
);
};

export default OrderList;
24 changes: 24 additions & 0 deletions src/firebaseConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Importación de las funciones necesarias de Firebase
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getAuth } from "firebase/auth";

// Configuración de Firebase usando variables de entorno
const firebaseConfig = {
apiKey: import.meta.env.VITE_API_KEY,
authDomain: import.meta.env.VITE_AUTH_DOMAIN,
projectId: import.meta.env.VITE_PROJECT_ID,
storageBucket: import.meta.env.VITE_STORAGE_BUCKET,
messagingSenderId: import.meta.env.VITE_MESSAGING_SENDER_ID,
appId: import.meta.env.VITE_APP_ID,
};

// Inicialización de la app de Firebase
const app = initializeApp(firebaseConfig);

// Inicialización de Firestore y Auth
export const db = getFirestore(app);
export const auth = getAuth(app);

// Exportación de la app por si se necesita usarla en otros lugares
export default app;
163 changes: 163 additions & 0 deletions src/orderForm.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import React, { useState, useEffect } from 'react';
import { collection, addDoc, doc, updateDoc, serverTimestamp } from 'firebase/firestore';
import { db } from './firebaseConfig';

const OrderForm = ({ initialData = null, onSubmit, onCancel }) => {
const [customerName, setCustomerName] = useState(initialData?.customerName || '');
const [selectedItems, setSelectedItems] = useState(initialData?.items || []);
const [total, setTotal] = useState(initialData?.total || 0);
const [modality, setModality] = useState(initialData?.modality || '');
const [loading, setLoading] = useState(false);

const menuItems = [
{ name: 'Hamburguesa simple', price: 100 },
{ name: 'Hot dog', price: 70 },
{ name: 'Hamburguesa doble', price: 150 },
{ name: 'Papas fritas frescas', price: 80 },
{ name: 'Soda', price: 25 }
];

// Calcula el total dinámicamente al cambiar los elementos seleccionados
useEffect(() => {
const totalAmount = selectedItems.reduce((sum, item) => {
const menuItem = menuItems.find(menuItem => menuItem.name === item);
return sum + (menuItem ? menuItem.price : 0);
}, 0);
setTotal(totalAmount);
}, [selectedItems]);

// Maneja la selección de elementos del menú
const handleCheckboxChange = (itemName) => {
setSelectedItems(prevItems =>
prevItems.includes(itemName)
? prevItems.filter(item => item !== itemName)
: [...prevItems, itemName]
);
};

// Maneja el envío del formulario
const handleSubmit = async (e) => {
e.preventDefault();

if (!customerName.trim() || selectedItems.length === 0) {
alert("Por favor, completa todos los campos obligatorios.");
return;
}

setLoading(true);
try {
if (initialData) {
// Actualización de un pedido existente
const docRef = doc(db, 'orders', initialData.id);
await updateDoc(docRef, {
customerName,
items: selectedItems,
total,
modality,
updatedAt: serverTimestamp()
});
alert('Pedido actualizado exitosamente.');
} else {
// Creación de un nuevo pedido
await addDoc(collection(db, 'orders'), {
customerName,
items: selectedItems,
total,
modality,
createdAt: serverTimestamp(),
updatedAt: serverTimestamp()
});
alert('Pedido enviado exitosamente.');
}

// Llama a la función de envío proporcionada
if (onSubmit) {
onSubmit({
id: initialData?.id || null,
customerName,
items: selectedItems,
total,
modality
});
}

// Limpia el formulario después de enviar
setCustomerName('');
setSelectedItems([]);
setTotal(0);
setModality('');
} catch (error) {
console.error("Error al enviar el pedido:", error.message);
} finally {
setLoading(false);
}
};

return (
<form onSubmit={handleSubmit}>
<div>
<label>Nombre del cliente:</label>
<input
type="text"
value={customerName}
onChange={(e) => setCustomerName(e.target.value)}
required
/>
</div>

<div>
<label>Selecciona los elementos del menú:</label>
{menuItems.map((item) => (
<label key={item.name}>
<input
type="checkbox"
value={item.name}
checked={selectedItems.includes(item.name)}
onChange={() => handleCheckboxChange(item.name)}
/>
{item.name} - ${item.price}
</label>
))}
</div>

<div>
<label>Importe total: ${total}</label>
</div>

<div>
<label>Modalidad:</label>
<label>
<input
type="radio"
value="recogida"
checked={modality === "recogida"}
onChange={(e) => setModality(e.target.value)}
required
/>
Recogida
</label>
<label>
<input
type="radio"
value="entrega"
checked={modality === "entrega"}
onChange={(e) => setModality(e.target.value)}
required
/>
Entrega
</label>
</div>

<button type="submit" disabled={loading}>
{loading ? 'Procesando...' : initialData ? 'Actualizar pedido' : 'Enviar pedido'}
</button>
{onCancel && (
<button type="button" onClick={onCancel}>
Cancelar
</button>
)}
</form>
);
};

export default OrderForm;