VoiceMenu2sathish / templates /menu_page.html
DSatishchandra's picture
Update templates/menu_page.html
a2d8fd3 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Dining Assistant</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f9;
text-align: center;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container {
text-align: center;
background-color: #fff;
padding: 40px;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
width: 80%;
max-width: 600px;
}
h1 {
color: #333;
}
.mic-button {
width: 80px;
height: 80px;
border-radius: 50%;
background-color: #007bff;
color: white;
font-size: 40px;
border: none;
cursor: pointer;
}
.status {
margin-top: 20px;
font-size: 1.2rem;
color: #555;
}
.menu-items-container {
margin-top: 30px;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.menu-item {
background-color: #f9f9f9;
padding: 20px;
border-radius: 10px;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
text-align: left;
}
</style>
</head>
<body>
<div class="container">
<h1>AI Dining Assistant</h1>
<button class="mic-button" id="mic-button">🎤</button>
<div class="status" id="status">Press the mic button to start...</div>
<div class="menu-items-container" id="menu-items">
<!-- Menu items will be populated here dynamically -->
</div>
</div>
<script>
const micButton = document.getElementById('mic-button');
const status = document.getElementById('status');
const menuItemsContainer = document.getElementById('menu-items');
let isListening = false;
let selectedItem = '';
let quantity = 0;
micButton.addEventListener('click', () => {
if (!isListening) {
isListening = true;
greetUser();
}
});
// Greet user
function greetUser() {
const utterance = new SpeechSynthesisUtterance("Hi, welcome to Biryani Hub! Can I know your name so I can greet you personally?");
speechSynthesis.speak(utterance);
utterance.onend = () => {
status.textContent = "Listening for your name...";
startListeningForName();
};
}
// Start listening for user input (name)
async function startListeningForName() {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const mediaRecorder = new MediaRecorder(stream, { mimeType: "audio/webm;codecs=opus" });
const audioChunks = [];
mediaRecorder.ondataavailable = (event) => audioChunks.push(event.data);
mediaRecorder.onstop = async () => {
const audioBlob = new Blob(audioChunks, { type: "audio/webm" });
const formData = new FormData();
formData.append("audio", audioBlob);
status.textContent = "Processing your name... Please wait.";
try {
const result = await fetch("/process-audio", { method: "POST", body: formData });
const data = await result.json();
selectedItem = data.name;
status.textContent = `Hello ${selectedItem}! How can I help you today?`;
suggestFood();
} catch (error) {
status.textContent = "Sorry, I couldn’t understand that. Could you please repeat?";
isListening = false;
}
};
mediaRecorder.start();
setTimeout(() => mediaRecorder.stop(), 5000); // Stop recording after 5 seconds
}
// Suggest food items to the user
function suggestFood() {
fetch('/menu') // GET request to fetch menu items from the server
.then(response => response.json())
.then(data => {
menuItemsContainer.innerHTML = "";
data.forEach(item => {
const menuItemDiv = document.createElement('div');
menuItemDiv.classList.add('menu-item');
menuItemDiv.innerHTML = `
<h3>${item.Name}</h3>
<p><strong>Price:</strong> $${item.Price__c}</p>
<p><strong>Ingredients:</strong> ${item.Ingredients__c}</p>
<p><strong>Category:</strong> ${item.Category__c}</p>
<button class="order-btn" data-item="${item.Name}" onclick="takeOrder('${item.Name}')">Order</button>
`;
menuItemsContainer.appendChild(menuItemDiv);
});
speakMenuItems(data);
});
}
// Read out the menu items
function speakMenuItems(items) {
const utterance = new SpeechSynthesisUtterance("Here are the menu items:");
speechSynthesis.speak(utterance);
items.forEach(item => {
const itemUtterance = new SpeechSynthesisUtterance(`${item.Name}, Price: $${item.Price__c}, Ingredients: ${item.Ingredients__c}`);
speechSynthesis.speak(itemUtterance);
});
}
// Handle user order
function takeOrder(item) {
selectedItem = item;
const utterance = new SpeechSynthesisUtterance(`You selected ${item}. How many would you like?`);
speechSynthesis.speak(utterance);
status.textContent = `You selected ${item}. How many would you like?`;
startListeningForQuantity();
}
// Start listening for quantity
async function startListeningForQuantity() {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const mediaRecorder = new MediaRecorder(stream, { mimeType: "audio/webm;codecs=opus" });
const audioChunks = [];
mediaRecorder.ondataavailable = (event) => audioChunks.push(event.data);
mediaRecorder.onstop = async () => {
const audioBlob = new Blob(audioChunks, { type: "audio/webm" });
const formData = new FormData();
formData.append("audio", audioBlob);
status.textContent = "Processing your quantity... Please wait.";
try {
const result = await fetch("/process-audio", { method: "POST", body: formData });
const data = await result.json();
quantity = parseInt(data.quantity);
status.textContent = `You want ${quantity} of ${selectedItem}. Please confirm your order.`;
confirmOrder();
} catch (error) {
status.textContent = "Sorry, I couldn’t understand that. Could you please repeat?";
isListening = false;
}
};
mediaRecorder.start();
setTimeout(() => mediaRecorder.stop(), 5000); // Stop recording after 5 seconds
}
// Confirm the order and send it to the backend
function confirmOrder() {
const orderDetails = {
item: selectedItem,
quantity: quantity
};
fetch('/order', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(orderDetails)
})
.then(response => response.json())
.then(data => {
status.textContent = `Order placed for ${quantity} of ${selectedItem}.`;
})
.catch(error => {
status.textContent = "Error placing order.";
});
}
</script>
</body>
</html>