SIH2024 / templates /user-dashboard.html
Neurolingua's picture
Update templates/user-dashboard.html
8528d7b verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>User Dashboard - E. Coli Detection Portal</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<style>
#background-video {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
z-index: -1; /* Send the video to the background */
}
/* Container Styling */
body {
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
}
.dashboard-card {
backdrop-filter: blur(10px);
background-color: rgba(255, 255, 255, 0.2); /* Reduce opacity for transparency */
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); /* Optional shadow for better contrast */
}
.chatbot-container {
display: flex;
height: 100vh;
}
.chat-sidebar {
width: 260px;
background-color: #1A1A1A;
padding: 20px;
}
.chat-main {
flex-grow: 1;
display: flex;
flex-direction: column;
}
.chat-messages {
flex-grow: 1;
overflow-y: auto;
padding: 20px;
background-color: #343541;
}
.chat-input-area {
padding: 20px;
background-color: #343541;
}
.chatbot-fab {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 1000;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.speaker-icon {
cursor: pointer;
margin-left: 10px;
color: white;
}
</style>
</head>
<body class="min-h-screen flex items-center justify-center p-4">
<video autoplay loop muted id="background-video">
<source src="{{ url_for('static', filename='dashboard.mp4') }}" type="video/mp4">
Your browser does not support the video tag.
</video>
<div class="container mx-auto max-w-2xl">
<div class="dashboard-card rounded-xl shadow-2xl p-8">
<div class="text-center mb-6">
<h1 class="text-3xl font-bold text-gray-800">User Dashboard</h1>
<p class="text-gray-600 mt-2">E. Coli Detection Portal</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="bg-blue-100 p-6 rounded-lg shadow-md">
<h2 class="text-xl font-semibold text-blue-800 mb-4">Profile Information</h2>
<div id="userProfileDetails">
<p class="mb-2"><strong>Name:</strong> Sharvesh</p>
<p class="mb-2"><strong>Phone:</strong> 9342540825</p>
<p class="mb-2"><strong>State:</strong> Tamil Nadu</p>
<p class="mb-2"><strong>Town:</strong> Pollachi</p>
</div>
</div>
<div class="bg-green-100 p-6 rounded-lg shadow-md">
<h2 class="text-xl font-semibold text-green-800 mb-4">Quick Actions</h2>
<div class="space-y-4">
<button onclick="startNewTest()" class="w-full bg-green-500 text-white p-3 rounded-lg hover:bg-green-600 transition duration-300">
Start New E. Coli Test
</button>
<button onclick="toggleTestResults()" class="w-full bg-blue-500 text-white p-3 rounded-lg hover:bg-blue-600 transition duration-300">
<span id="testResultsButtonText">View Previous Tests</span>
</button>
</div>
</div>
</div>
<div id="testResults" class="mt-8 hidden">
<h2 class="text-2xl font-bold text-gray-800 mb-4">Recent Test Results</h2>
<div id="testResultsContent" class="bg-gray-100 p-4 rounded-lg">
<!-- Test results will be dynamically populated here -->
</div>
</div>
</div>
</div>
<!-- Floating Chatbot Button -->
<button id="chatbotFab" class="chatbot-fab bg-blue-500 text-white p-3 rounded-full hover:bg-blue-600 transition duration-300">
<i class="fas fa-robot"></i>
</button>
<!-- Chatbot Modal -->
<div id="chatbotModal" class="fixed inset-0 z-50 bg-black bg-opacity-50 flex items-center justify-center hidden">
<div class="w-full h-full max-w-6xl max-h-[90vh] bg-white rounded-lg overflow-hidden">
<div class="chatbot-container">
<!-- Sidebar -->
<div class="chat-sidebar text-white">
<div class="mb-6">
<button id="newChatBtn" class="w-full bg-gray-700 text-white p-3 rounded-lg mb-4 hover:bg-gray-600 transition duration-300">
<i class="fas fa-plus mr-2"></i>New Chat
</button>
</div>
<div>
<h3 class="text-lg font-semibold mb-4">Chat History</h3>
<ul id="chatHistory">
<li class="p-2 hover:bg-gray-700 rounded cursor-pointer">Chat 1</li>
<li class="p-2 hover:bg-gray-700 rounded cursor-pointer">Chat 2</li>
</ul>
</div>
</div>
<!-- Main Chatbot Area -->
<div class="chat-main">
<div class="chat-messages" id="chatMessages">
<div class="text-white text-center py-10">
<h2 class="text-2xl mb-4">How can I help you today?</h2>
<p>Ask me anything about E. Coli detection or water quality</p>
</div>
</div>
<div class="chat-input-area">
<div class="relative">
<textarea
id="chatInput"
class="w-full p-4 pr-12 text-white bg-gray-700 rounded-lg focus:outline-none"
placeholder="Type your message..."
rows="3"></textarea>
<button id="sendMessageBtn" class="absolute right-4 top-4 bg-blue-600 text-white p-3 rounded-full hover:bg-blue-700">
<i class="fas fa-paper-plane"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="module">
import { initializeApp } from "https://www.gstatic.com/firebasejs/11.0.2/firebase-app.js";
import {
getFirestore,
collection,
query,
orderBy,
limit,
getDocs,
onSnapshot,
doc,
getDoc
} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-firestore.js";
const firebaseConfig = {
apiKey: "AIzaSyBVazIeGCASyfCka3nU_INuZytrTdSVmXo",
authDomain: "snippetscript-37175.firebaseapp.com",
projectId: "snippetscript-37175",
storageBucket: "snippetscript-37175.appspot.com",
messagingSenderId: "154274113551",
appId: "1:154274113551:web:4e9582f3a24f7d12695b7a",
measurementId: "G-PSR30H9GH6"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
// Dynamically load user profile
// Function to load user profile from Firestore using the phone number as the document ID
async function loadUserProfile(phone) {
try {
// Reference the document in the 'users' collection with the phone as the document ID
const userProfileRef = doc(db, 'users', phone);
// Fetch the document snapshot
const docSnap = await getDoc(userProfileRef);
// Check if the document exists
if (docSnap.exists()) {
// Extract the user data
const data = docSnap.data();
// Update the HTML content to display the user's profile
document.getElementById('userProfileDetails').innerHTML = `
<p class="mb-2"><strong>Name:</strong> ${data.name || 'N/A'}</p>
<p class="mb-2"><strong>Phone:</strong> ${data.phone || 'N/A'}</p>
<p class="mb-2"><strong>Pincode:</strong> ${data.pincode || 'N/A'}</p>
<p class="mb-2"><strong>State:</strong> ${data.state || 'N/A'}</p>
<p class="mb-2"><strong>Town:</strong> ${data.town || 'N/A'}</p>
`;
} else {
// If the document doesn't exist, show a "not found" message
document.getElementById('userProfileDetails').innerHTML = '<p class="text-gray-600">User profile not found.</p>';
}
} catch (error) {
// Log the error to the console and display an error message to the user
console.error("Error fetching user profile:", error);
document.getElementById('userProfileDetails').innerHTML = '<p class="text-red-600">An error occurred while fetching the user profile. Please try again later.</p>';
}
loadUserProfile('9342540825'); // Fetches the user profile for this phone number
}
// Dynamically load Thingspeak data
async function loadPreviousTests() {
const thingspeakQuery = query(
collection(db, 'thingspeak_data'),
orderBy('timestamp', 'desc'),
limit(5)
);
onSnapshot(thingspeakQuery, (querySnapshot) => {
const testResultsContent = document.getElementById('testResultsContent');
if (querySnapshot.empty) {
testResultsContent.innerHTML = `<p class="text-gray-600">No previous test results available.</p>`;
return;
}
let tableHTML = `
<table class="w-full">
<thead>
<tr class="bg-gray-200">
<th class="p-2 text-left">Entry ID</th>
<th class="p-2 text-left">Field 1</th>
<th class="p-2 text-left">Field 2</th>
<th class="p-2 text-left">Timestamp</th>
</tr>
</thead>
<tbody>
`;
querySnapshot.forEach((doc) => {
const data = doc.data();
const timestamp = data.timestamp ? new Date(data.timestamp.seconds * 1000).toLocaleString() : 'N/A';
tableHTML += `
<tr class="border-b">
<td class="p-2">${data.entry_id || 'N/A'}</td>
<td class="p-2">${data.field1 || 'N/A'}</td>
<td class="p-2">${data.field2 || 'N/A'}</td>
<td class="p-2">${timestamp}</td>
</tr>
`;
});
tableHTML += `</tbody></table>`;
testResultsContent.innerHTML = tableHTML;
});
}
// Dashboard actions
function startNewTest() {
alert('Place the water sample in the kit. The results will be updated here shortly.');
}
function toggleTestResults() {
const testResultsDiv = document.getElementById('testResults');
testResultsDiv.classList.toggle('hidden');
if (!testResultsDiv.classList.contains('hidden')) {
document.getElementById('testResultsButtonText').textContent = 'Hide Previous Tests';
loadPreviousTests();
} else {
document.getElementById('testResultsButtonText').textContent = 'View Previous Tests';
}
}
// Chatbot functionality
document.addEventListener('DOMContentLoaded', function() {
const chatbotFab = document.getElementById('chatbotFab');
const chatbotModal = document.getElementById('chatbotModal');
const newChatBtn = document.getElementById('newChatBtn');
const sendMessageBtn = document.getElementById('sendMessageBtn');
const chatInput = document.getElementById('chatInput');
const chatMessages = document.getElementById('chatMessages');
// Toggle Chatbot Modal
chatbotFab.addEventListener('click', function() {
chatbotModal.classList.toggle('hidden');
});
// Close Chatbot Modal on clicking outside
chatbotModal.addEventListener('click', function(event) {
if (event.target === chatbotModal) {
chatbotModal.classList.add('hidden');
}
});
// New Chat functionality
newChatBtn.addEventListener('click', function() {
chatMessages.innerHTML = `
<div class="text-white text-center py-10">
<h2 class="text-2xl mb-4">How can I help you today?</h2>
<p>Ask me anything about E. Coli detection or water quality</p>
</div>
`;
});
// Send Message functionality
sendMessageBtn.addEventListener('click', sendMessage);
chatInput.addEventListener('keypress', function(event) {
if (event.key === 'Enter' && !event.shiftKey) {
event.preventDefault();
sendMessage();
}
});
function sendMessage() {
const userMessage = chatInput.value.trim();
if (userMessage) {
// Add user message to chat
chatMessages.innerHTML += `
<div class="text-white mb-4 text-right">
<div class="inline-block bg-blue-600 p-3 rounded-lg max-w-[70%]">
${userMessage}
</div>
</div>
`;
// Clear input
chatInput.value = '';
// Send message to backend
fetch('/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ query: userMessage })
})
.then(response => response.json())
.then(data => {
if (data.response) {
// Add bot response to chat with speaker icon
const botMessage = data.response;
chatMessages.innerHTML += `
<div class="text-white mb-4 text-left">
<div class="inline-block bg-gray-700 p-3 rounded-lg max-w-[70%]">
${botMessage}
<i class="fas fa-volume-up speaker-icon" onclick="speakMessage('${botMessage}')"></i>
</div>
</div>
`;
} else {
chatMessages.innerHTML += `
<div class="text-white mb-4 text-left">
<div class="inline-block bg-red-600 p-3 rounded-lg max-w-[70%]">
Error: ${data.error || "Unable to process your request"}
</div>
</div>
`;
}
// Scroll to bottom
chatMessages.scrollTop = chatMessages.scrollHeight;
})
.catch(error => {
console.error("Error:", error);
chatMessages.innerHTML += `
<div class="text-white mb-4 text-left">
<div class="inline-block bg-red-600 p-3 rounded-lg max-w-[70%]">
An error occurred. Please try again later.
</div>
</div>
`;
});
// Scroll to bottom
chatMessages.scrollTop = chatMessages.scrollHeight;
}
}
// Function to read out the bot's message
window.speakMessage = function(message) {
const utterance = new SpeechSynthesisUtterance(message);
utterance.voice = speechSynthesis.getVoices()[0];
speechSynthesis.speak(utterance);
}
});
// Initialize dynamic content loading
loadUserProfile();
window.startNewTest = startNewTest;
window.toggleTestResults = toggleTestResults;
</script>
</body>
</html>