voicechat / templates /index.html
Gopikanth123's picture
Update templates/index.html
6fe1f69 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TAJ HOTEL CHATBOT</title>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
<script src="https://code.responsivevoice.org/responsivevoice.js?key=q1DbMp6Z"></script>
<style>
:root {
--primary-color: #007bff; /* Default blue */
--bot-message-bg: #f0f2f5; /* Light Gray */
--user-message-bg: #007bff; /* User Blue */
--user-message-text: #fff; /* User Message White */
--accent-color: #6a0dad; /* Default Purple */
--background-color: #fff; /* Default Background White */
--shadow-color: rgba(0, 0, 0, 0.2); /* Default Shadow */
--input-bg: #f0f2f5; /* Default Input Background */
--input-border: #ccc; /* Default Input Border */
}
/* Themes */
.theme-calm-azure {
--background-color: #E3F2FD;
--bot-message-bg: #BBDEFB;
--user-message-bg: #2196F3;
--user-message-text: #FFFFFF;
--input-bg: #FFFFFF;
--input-border: #BDBDBD;
--accent-color: #1976D2;
}
.theme-elegant-charcoal {
--background-color: #263238;
--bot-message-bg: #37474F;
--user-message-bg: #FF5722;
--user-message-text: #FFFFFF;
--input-bg: #455A64;
--input-border: #CFD8DC;
--accent-color: #FF9800;
}
.theme-fresh-greenery {
--background-color: #E8F5E9;
--bot-message-bg: #C8E6C9;
--user-message-bg: #4CAF50;
--user-message-text: #FFFFFF;
--input-bg: #FFFFFF;
--input-border: #A5D6A7;
--accent-color: #388E3C;
}
.theme-soft-lavender {
--background-color: #F3E5F5;
--bot-message-bg: #E1BEE7;
--user-message-bg: #9C27B0;
--user-message-text: #FFFFFF;
--input-bg: #FFFFFF;
--input-border: #D1C4E9;
--accent-color: #7B1FA2;
}
.theme-bright-summer {
--background-color: #FFEB3B;
--bot-message-bg: #FFF9C4;
--user-message-bg: #F44336;
--user-message-text: #FFFFFF;
--input-bg: #FFFFFF;
--input-border: #FBC02D;
--accent-color: #C62828;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Roboto', sans-serif;
background-color: var(--background-color);
transition: background 0.5s ease;
overflow: hidden; /* Prevent scroll on body */
}
.container {
display: flex;
flex-direction: column;
height: 100vh;
width: 100%;
overflow: hidden; /* Prevent scroll on container */
}
/* Header */
.header {
background: var(--accent-color);
color: #fff;
font-size: 1.5rem;
font-weight: 700;
text-align: center;
padding: 20px;
box-shadow: 0 4px 8px var(--shadow-color);
position: relative;
z-index: 1000;
}
/* Chatbox */
.chat-box {
flex: 1;
display: flex;
flex-direction: column;
overflow-y: auto;
padding: 20px;
background: linear-gradient(to bottom right, #f5f7fa, #c3cfe2);
border-radius: 10px;
margin: 20px;
box-shadow: 0 4px 8px var(--shadow-color);
position: relative;
z-index: 10;
}
.message {
max-width: 75%;
padding: 12px 18px;
border-radius: 20px;
box-shadow: 0 3px 6px var(--shadow-color);
margin-bottom: 10px;
opacity: 0;
animation: fadeIn 0.3s forwards; /* Changed to forwards for delay effect */
}
.user-message {
align-self: flex-end;
background: var(--user-message-bg);
color: var(--user-message-text);
border-radius: 15px 20px 20px 20px;
animation: slideInRight 0.5s forwards; /* Sliding effect on user message */
}
.bot-message {
align-self: flex-start;
background: var(--bot-message-bg);
color: #333;
border-radius: 20px 15px 20px 20px;
animation: slideInLeft 0.5s forwards; /* Sliding effect on bot message */
}
/* Footer */
.footer {
background: #ffffff;
padding: 15px;
display: flex;
justify-content: center;
align-items: center;
box-shadow: 0 -4px 8px var(--shadow-color);
position: relative;
z-index: 1000;
}
.footer input[type="text"] {
width: 75%;
padding: 15px;
border: 1px solid var(--input-border);
border-radius: 20px;
margin-right: 10px;
box-shadow: 0 2px 4px var(--shadow-color);
transition: border 0.3s, box-shadow 0.3s; /* Added shadow transition */
background-color: var(--input-bg);
outline: none;
}
.footer input[type="text"]:focus {
border-color: var(--accent-color);
box-shadow: 0 0 10px var(--accent-color);
}
button {
background: var(--accent-color);
color: #fff;
border: none;
padding: 10px 20px;
border-radius: 20px;
font-size: 1rem;
cursor: pointer;
box-shadow: 0 4px 10px var(--shadow-color);
transition: background 0.3s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
button:hover {
background: #4b0082;
transform: scale(1.05);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); /* Shadow effect on hover */
}
/* Settings */
.settings {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
background: #f0f2f5;
box-shadow: 0 2px 5px var(--shadow-color);
position: relative;
z-index: 1000;
}
.color-picker,
.theme-toggle {
display: flex;
align-items: center;
position:relative;
}
.color-circle {
width: 20px;
height: 20px;
border-radius: 50%;
margin: 0 5px;
cursor: pointer;
box-shadow: 0 2px 5px var(--shadow-color);
transition: transform 0.3s; /* Adding circle hover effect */
}
.color-circle:hover {
transform: scale(1.2); /* Scale up on hover */
}
/* Animations */
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideInRight {
from {
opacity: 0;
transform: translateX(100%);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slideInLeft {
from {
opacity: 0;
transform: translateX(-100%);
}
to {
opacity: 1;
transform: translateX(0);
}
}
/* Background animation */
@keyframes backgroundAnimate {
0% {
background-color: rgba(255, 255, 255, 0.05);
}
50% {
background-color: rgba(255, 255, 255, 0.1);
}
100% {
background-color: rgba(255, 255, 255, 0.05);
}
}
/* VFX related styles */
.vfx {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
animation: backgroundAnimate 5s infinite; /* Continuously animate background */
z-index: 0; /* Background layer */
}
</style>
</head>
<body>
<div class="vfx"></div> <!-- Background effects -->
<div class="container">
<!-- Settings -->
<div class="settings">
<div class="theme-toggle">
<label for="theme-select">Select Theme:</label>
<select id="theme-select">
<option value="default">Default</option>
<option value="calm-azure">Calm Azure</option>
<option value="elegant-charcoal">Elegant Charcoal</option>
<option value="fresh-greenery">Fresh Greenery</option>
<option value="soft-lavender">Soft Lavender</option>
<option value="bright-summer">Bright Summer</option>
</select>
</div>
<div>
<!-- Language dropdown -->
<label for="language-select">Select Language:</label>
<select id="language-select">
<option value="english">English</option>
<option value="hindi">Hindi</option>
<option value="bengali">Bengali</option>
<option value="telugu">Telugu</option>
<option value="marathi">Marathi</option>
<option value="tamil">Tamil</option>
<option value="gujarati">Gujarati</option>
<option value="kannada">Kannada</option>
<option value="malayalam">Malayalam</option>
<option value="punjabi">Punjabi</option>
<option value="odia">Odia</option>
<option value="urdu">Urdu</option>
<option value="assamese">Assamese</option>
<option value="sanskrit">Sanskrit</option>
<option value="arabic">Arabic</option>
<option value="chinese">Chinese</option>
<option value="dutch">Dutch</option>
<option value="french">French</option>
<option value="filipino">Filipino</option>
<option value="greek">Greek</option>
<option value="indonesian">Indonesian</option>
<option value="italian">Italian</option>
<option value="japanese">Japanese</option>
<option value="korean">Korean</option>
<option value="latin">Latin</option>
<option value="nepali">Nepali</option>
<option value="portuguese">Portuguese</option>
<option value="romanian">Romanian</option>
<option value="russian">Russian</option>
<option value="spanish">Spanish</option>
<option value="swedish">Swedish</option>
<option value="thai">Thai</option>
<option value="ukrainian">Ukrainian</option>
<option value="turkish">Turkish</option>
</select>
</div>
<div class="color-picker">
<label>Accent Color:</label>
<div class="color-circle" style="background-color: #6a0dad;" onclick="changeColor('#6a0dad')"></div>
<div class="color-circle" style="background-color: #ff4500;" onclick="changeColor('#ff4500')"></div>
<div class="color-circle" style="background-color: #007bff;" onclick="changeColor('#007bff')"></div>
<div class="color-circle" style="background-color: #28a745;" onclick="changeColor('#28a745')"></div>
</div>
</div>
<!-- Header -->
<div class="header">TAJ HOTEL CHATBOT</div>
<!-- Chatbox -->
<div class="chat-box" id="chat-box"></div>
<!-- Footer -->
<div class="footer">
<input type="text" id="user-input" placeholder="Type your message..." />
<button id="send-btn">Send</button>
<button id="voice-btn">🎤 Start Voice Input</button>
</div>
</div>
<script>
const chatBox = document.getElementById('chat-box');
const voiceBtn = document.getElementById('voice-btn');
const sendBtn = document.getElementById('send-btn');
const userInput = document.getElementById('user-input');
const themeSelect = document.getElementById('theme-select');
const languageSelect = document.getElementById('language-select');
// Add message to chatbox
function addMessage(sender, text) {
const msgDiv = document.createElement('div');
msgDiv.classList.add('message', sender);
msgDiv.textContent = text;
chatBox.appendChild(msgDiv);
chatBox.scrollTop = chatBox.scrollHeight; // Scroll to the bottom of the chat
}
// Initialize speech recognition
const recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
function setRecognitionLanguage() {
const selectedLanguage = languageSelect.value;
switch (selectedLanguage) {
case 'telugu': recognition.lang = 'te-IN'; break;
case 'hindi': recognition.lang = 'hi-IN'; break;
case 'bengali': recognition.lang = 'bn-IN'; break;
case 'marathi': recognition.lang = 'mr-IN'; break;
case 'tamil': recognition.lang = 'ta-IN'; break;
case 'gujarati': recognition.lang = 'gu-IN'; break;
case 'kannada': recognition.lang = 'kn-IN'; break;
case 'malayalam': recognition.lang = 'ml-IN'; break;
case 'punjabi': recognition.lang = 'pa-IN'; break;
case 'odia': recognition.lang = 'or-IN'; break;
case 'urdu': recognition.lang = 'ur-IN'; break;
case 'assamese': recognition.lang = 'as-IN'; break;
case 'sanskrit': recognition.lang = 'sa-IN'; break;
case 'arabic': recognition.lang = 'ar-SA'; break;
case 'chinese': recognition.lang = 'zh-CN'; break;
case 'dutch': recognition.lang = 'nl-NL'; break;
case 'french': recognition.lang = 'fr-FR'; break;
case 'filipino': recognition.lang = 'fil-PH'; break;
case 'greek': recognition.lang = 'el-GR'; break;
case 'indonesian': recognition.lang = 'id-ID'; break;
case 'italian': recognition.lang = 'it-IT'; break;
case 'japanese': recognition.lang = 'ja-JP'; break;
case 'korean': recognition.lang = 'ko-KR'; break;
case 'latin': recognition.lang = 'la'; break;
case 'nepali': recognition.lang = 'ne-NP'; break;
case 'portuguese': recognition.lang = 'pt-PT'; break;
case 'romanian': recognition.lang = 'ro-RO'; break;
case 'russian': recognition.lang = 'ru-RU'; break;
case 'spanish': recognition.lang = 'es-ES'; break;
case 'swedish': recognition.lang = 'sv-SE'; break;
case 'thai': recognition.lang = 'th-TH'; break;
case 'ukrainian': recognition.lang = 'uk-UA'; break;
case 'turkish': recognition.lang = 'tr-TR'; break;
case 'english':
default: recognition.lang = 'en-US'; break; // Default to English
}
}
// Event listener for voice input button
voiceBtn.addEventListener('click', () => {
setRecognitionLanguage(); // Set language
recognition.start(); // Start recognition
});
// Handle results from speech recognition
recognition.addEventListener('result', (e) => {
const transcript = e.results[0][0].transcript;
addMessage('user-message', transcript);
sendUserMessage(transcript);
});
// Handle errors in speech recognition
recognition.addEventListener('error', (event) => {
console.error("Speech recognition error", event);
});
// Change the accent color
function changeColor(color) {
document.documentElement.style.setProperty('--accent-color', color);
}
// Change the theme
function changeTheme(theme) {
document.documentElement.classList.remove('theme-calm-azure', 'theme-elegant-charcoal', 'theme-fresh-greenery', 'theme-soft-lavender', 'theme-bright-summer');
if (theme !== 'default') {
document.documentElement.classList.add('theme-' + theme);
}
}
// Function to send user input and selected language to backend
function sendUserMessage(message) {
const selectedLanguage = languageSelect.value; // Get the selected language
// Send the message and selected language to the backend
fetch('/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
message,
language: selectedLanguage, // Include the selected language in the request body
}),
})
.then(response => response.json())
.then(data => {
const botResponse = data.response;
addMessage('bot-message', botResponse);
speakResponse(botResponse, selectedLanguage);
})
.catch(error => {
console.error("Error:", error);
addMessage('bot-message', "Sorry, I couldn't process that.");
});
}
// // Function to get the voice list and match the language
// function getVoiceForLanguage(lang) {
// const voices = window.speechSynthesis.getVoices();
// const matchingVoice = voices.find(voice => voice.lang === lang); // Match exact language code
// return matchingVoice || null; // Return first match or null if not found
// }
// // Text-to-Speech function
// function speak(text, lang) {
// const utterance = new SpeechSynthesisUtterance(text);
// const selectedVoice = getVoiceForLanguage(lang);
// if (selectedVoice) {
// utterance.voice = selectedVoice; // Set the matching voice
// utterance.lang = lang; // Set the language
// } else {
// console.warn(`No voice found for language: ${lang}. Falling back to default.`);
// utterance.lang = 'en-US'; // Fallback to English
// }
// utterance.pitch = 1; // Set pitch
// utterance.rate = 1; // Set rate
// window.speechSynthesis.speak(utterance); // Speak the text
// }
// // Language Handling Function
// function speakResponse(text, selectedLanguage) {
// let lang;
// switch (selectedLanguage) {
// case 'hindi': lang = 'hi-IN'; break;
// case 'bengali': lang = 'bn-IN'; break;
// case 'telugu': lang = 'te-IN'; break;
// case 'marathi': lang = 'mr-IN'; break;
// case 'tamil': lang = 'ta-IN'; break;
// case 'gujarati': lang = 'gu-IN'; break;
// case 'kannada': lang = 'kn-IN'; break;
// case 'malayalam': lang = 'ml-IN'; break;
// case 'punjabi': lang = 'pa-IN'; break;
// case 'odia': lang = 'or-IN'; break;
// case 'urdu': lang = 'ur-IN'; break;
// case 'assamese': lang = 'as-IN'; break;
// case 'sanskrit': lang = 'sa-IN'; break;
// default: lang = 'en-US'; break; // English (default)
// }
// speak(text, lang); // Call the speak function with the determined language
// }
// // Ensure voices are loaded before running the TTS
// window.speechSynthesis.onvoiceschanged = () => {
// const voices = window.speechSynthesis.getVoices();
// voices.forEach(voice => {
// console.log(`Voice: ${voice.name}, Language: ${voice.lang}`);
// });
// };
// // Function to initialize and fetch voices
// function initializeVoices() {
// return new Promise((resolve) => {
// const voices = window.speechSynthesis.getVoices();
// if (voices.length) {
// resolve(voices);
// } else {
// window.speechSynthesis.onvoiceschanged = () => {
// resolve(window.speechSynthesis.getVoices());
// };
// }
// });
// }
// // Function to get the voice for a given language
// function getVoiceForLanguage(lang, voices) {
// const voice = voices.find(voice => voice.lang === lang);
// if (voice) {
// return voice;
// }
// console.warn(`No voice found for language: ${lang}.`);
// return null;
// }
// // Text-to-Speech function
// async function speak(text, lang) {
// const voices = await initializeVoices();
// const selectedVoice = getVoiceForLanguage(lang, voices);
// const utterance = new SpeechSynthesisUtterance(text);
// if (selectedVoice) {
// utterance.voice = selectedVoice;
// utterance.lang = selectedVoice.lang;
// } else {
// console.warn(`Falling back to default language.`);
// utterance.lang = 'en-US';
// }
// utterance.pitch = 1; // Set pitch
// utterance.rate = 1; // Set rate
// window.speechSynthesis.speak(utterance); // Speak the text
// }
// Language Handling Function
function speakResponse(text, selectedLanguage) {
// Dictionary mapping specified languages to their respective voices
const languageVoiceMap = {
hindi: 'Hindi Female',
tamil: 'Tamil Female',
arabic: 'Arabic Female',
chinese: 'Chinese Female',
dutch: 'Dutch Female',
french: 'French Female',
filipino: 'Filipino Female',
greek: 'Greek Female',
indonesian: 'Indonesian Female',
italian: 'Italian Female',
japanese: 'Japanese Female',
korean: 'Korean Female',
portuguese: 'Portuguese Female',
romanian: 'Romanian Female',
russian: 'Russian Female',
spanish: 'Spanish Female',
swedish: 'Swedish Female',
thai: 'Thai Female',
ukrainian: 'Ukrainian Female',
turkish: 'Turkish Female'
};
// Get the voice for the selected language
const voice = languageVoiceMap[selectedLanguage.toLowerCase()];
// Check if the language has a specified voice
if (voice) {
responsiveVoice.speak(text, voice);
} else {
// Use default behavior for unspecified languages
responsiveVoice.speak(text);
}
}
// // Test voices and log them
// initializeVoices().then(voices => {
// console.log("Available voices:");
// voices.forEach(voice => console.log(`Voice: ${voice.name}, Language: ${voice.lang}`));
// });
// Event listeners for buttons
sendBtn.addEventListener('click', () => {
const message = userInput.value.trim();
if (message) {
addMessage('user-message', message);
sendUserMessage(message);
userInput.value = ''; // Clear input field after sending
}
});
// Handle pressing 'Enter' key for sending messages
userInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
sendBtn.click(); // Trigger button click
}
});
// Update theme when selected from dropdown
themeSelect.addEventListener('change', (e) => {
changeTheme(e.target.value);
});
</script>
</body>
</html>