File size: 8,507 Bytes
7547860
 
 
 
 
d5ed968
 
 
 
95ee9b6
a2d8fd3
d5ed968
 
 
 
 
a2d8fd3
d5ed968
 
 
95ee9b6
 
a2d8fd3
95ee9b6
a2d8fd3
 
d5ed968
95ee9b6
 
 
 
 
 
 
d5ed968
 
95ee9b6
d5ed968
 
 
95ee9b6
 
d5ed968
95ee9b6
d5ed968
216610c
 
 
 
 
 
 
 
 
 
 
 
 
d5ed968
7547860
 
d5ed968
bcde189
95ee9b6
 
 
216610c
a2d8fd3
 
216610c
7547860
 
758c9f3
 
 
a2d8fd3
758c9f3
a2d8fd3
 
758c9f3
 
 
 
 
92deae9
758c9f3
 
a2d8fd3
758c9f3
 
 
 
 
a2d8fd3
758c9f3
 
92deae9
a2d8fd3
 
758c9f3
 
 
 
 
 
 
 
 
a2d8fd3
758c9f3
a2d8fd3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
758c9f3
a2d8fd3
 
 
758c9f3
a2d8fd3
 
 
 
 
 
 
 
 
758c9f3
a2d8fd3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
758c9f3
a2d8fd3
 
 
 
 
 
 
758c9f3
a2d8fd3
758c9f3
 
 
 
 
 
92deae9
a2d8fd3
 
 
 
 
 
758c9f3
a2d8fd3
 
 
 
 
 
 
 
 
 
 
 
 
758c9f3
bcde189
758c9f3
d5ed968
7547860
ae7981b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
<!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>