tables / templets /index.html
Subbu1304's picture
Update templets/index.html
228101b verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Restaurant Table Booking</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background: linear-gradient(135deg, #6e8efb, #a777e3);
color: #fff;
display: flex;
flex-direction: column;
align-items: center;
min-height: 100vh;
}
.container {
text-align: center;
padding: 20px;
}
h1 {
font-size: 2.5em;
margin-bottom: 20px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.tables {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 20px;
}
.table {
background: rgba(255, 255, 255, 0.1);
border-radius: 10px;
padding: 20px;
width: 120px;
text-align: center;
cursor: pointer;
transition: transform 0.3s, background 0.3s;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
}
.table:hover {
transform: scale(1.1);
background: rgba(255, 255, 255, 0.2);
}
.table h3 {
margin: 0;
font-size: 1.2em;
}
.table p {
margin: 5px 0 0;
font-size: 0.9em;
color: #ddd;
}
.availability-text {
font-size: 0.8em;
color: #ffd700; /* Yellow for visibility */
margin-top: 10px;
}
/* Modal Styles */
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal-content {
background: #fff;
color: #333;
border-radius: 10px;
padding: 20px;
width: 90%;
max-width: 500px;
max-height: 80vh;
overflow-y: auto;
position: relative;
}
.modal-content h2 {
margin-top: 0;
color: #6e8efb;
}
.close {
position: absolute;
top: 10px;
right: 15px;
font-size: 1.5em;
cursor: pointer;
color: #333;
}
.menu-item {
margin: 10px 0;
}
.menu-item h4 {
margin: 5px 0;
color: #a777e3;
}
select, button {
padding: 10px;
margin: 10px 0;
border: none;
border-radius: 5px;
font-size: 1em;
}
select {
width: 100%;
background: #f0f0f0;
}
button {
background: #6e8efb;
color: #fff;
cursor: pointer;
transition: background 0.3s;
}
button:hover {
background: #a777e3;
}
.availability {
margin: 10px 0;
font-size: 0.9em;
color: #555;
}
</style>
</head>
<body>
<div class="container">
<h1>Restaurant Table Booking</h1>
<div class="tables" id="tables">
<!-- Tables will be populated dynamically -->
</div>
</div>
<!-- Modal for Menu and Booking -->
<div id="modal" class="modal">
<div class="modal-content">
<span class="close" onclick="closeModal()">×</span>
<h2 id="modal-title">Table Menu</h2>
<div id="availability" class="availability"></div>
<h3>Menu</h3>
<div id="menu">
<div class="menu-item">
<h4>Margherita Pizza</h4>
<p>Classic pizza with tomato, mozzarella, and basil. $12</p>
</div>
<div class="menu-item">
<h4>Caesar Salad</h4>
<p>Fresh romaine, croutons, and Caesar dressing. $8</p>
</div>
<div class="menu-item">
<h4>Spaghetti Carbonara</h4>
<p>Pasta with creamy sauce, pancetta, and parmesan. $15</p>
</div>
</div>
<h3>Book Table</h3>
<select id="time-slot">
<!-- Time slots will be populated dynamically -->
</select>
<button onclick="bookTable()">Book Now</button>
</div>
</div>
<script>
const tables = [
{ id: 1, name: "Table 1" },
{ id: 2, name: "Table 2" },
{ id: 3, name: "Table 3" },
{ id: 4, name: "Table 4" },
{ id: 5, name: "Table 5" }
];
// Populate tables
const tablesContainer = document.getElementById("tables");
tables.forEach(table => {
const tableDiv = document.createElement("div");
tableDiv.className = "table";
tableDiv.id = `table-${table.id}`;
tableDiv.innerHTML = `
<h3>${table.name}</h3>
<p>Click to view menu</p>
<p class="availability-text" id="availability-${table.id}">Loading...</p>
`;
tableDiv.onclick = () => openModal(table.id, table.name);
tablesContainer.appendChild(tableDiv);
});
let currentTableId = null;
// Update live availability for all tables
async function updateLiveAvailability() {
for (const table of tables) {
try {
const response = await fetch(`/api/availability/${table.id}`);
const data = await response.json();
const availabilityText = document.getElementById(`availability-${table.id}`);
if (data.next_slot) {
availabilityText.textContent = `Next: ${data.next_slot}`;
availabilityText.style.color = "#ffd700";
} else {
availabilityText.textContent = "Booked";
availabilityText.style.color = "#ff4d4d";
}
} catch (error) {
console.error(`Error fetching availability for table ${table.id}:`, error);
document.getElementById(`availability-${table.id}`).textContent = "Error";
}
}
}
// Initial load and periodic updates
updateLiveAvailability();
setInterval(updateLiveAvailability, 30000); // Update every 30 seconds
// Open modal with menu and availability
async function openModal(tableId, tableName) {
currentTableId = tableId;
document.getElementById("modal-title").textContent = `${tableName} Menu`;
document.getElementById("modal").style.display = "flex";
// Fetch availability
try {
const response = await fetch(`/api/availability/${tableId}`);
const data = await response.json();
const availableSlots = data.available_slots;
// Update availability display
const availabilityDiv = document.getElementById("availability");
availabilityDiv.innerHTML = availableSlots.length > 0
? `Available slots: ${availableSlots.join(", ")}`
: "No available slots";
// Populate time slot dropdown
const timeSlotSelect = document.getElementById("time-slot");
timeSlotSelect.innerHTML = "";
if (availableSlots.length > 0) {
availableSlots.forEach(slot => {
const option = document.createElement("option");
option.value = slot;
option.textContent = slot;
timeSlotSelect.appendChild(option);
});
} else {
const option = document.createElement("option");
option.value = "";
option.textContent = "No slots available";
timeSlotSelect.appendChild(option);
}
} catch (error) {
console.error("Error fetching availability:", error);
document.getElementById("availability").innerHTML = "Error loading availability";
}
}
// Close modal
function closeModal() {
document.getElementById("modal").style.display = "none";
currentTableId = null;
}
// Book table
async function bookTable() {
if (!currentTableId) return;
const timeSlot = document.getElementById("time-slot").value;
if (!timeSlot) {
alert("Please select a time slot");
return;
}
try {
const response = await fetch("/api/book", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ table_id: currentTableId, time_slot: timeSlot })
});
const result = await response.json();
if (result.success) {
alert(`Table ${currentTableId} booked for ${timeSlot}`);
closeModal();
updateLiveAvailability(); // Refresh availability after booking
} else {
alert("Booking failed: " + result.message);
}
} catch (error) {
console.error("Error booking table:", error);
alert("Error booking table");
}
}
// Close modal when clicking outside
window.onclick = function(event) {
if (event.target === document.getElementById("modal")) {
closeModal();
}
};
</script>
</body>
</html>