Spaces:
Sleeping
Sleeping
<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> | |