Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width,initial-scale=1" /> | |
| <title>Profile - CTRL + ALT + HEAL</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
| </head> | |
| <body class="bg-[#F7F8F9] text-gray-800 min-h-screen"> | |
| <!-- Navbar --> | |
| <nav class="bg-white border border-gray-200 px-6 py-4 mb-6"> | |
| <div class="container mx-auto flex justify-between items-center"> | |
| <a href="index.html" class="text-2xl font-bold text-[#6B9080]" | |
| >CTRL + ALT + HEAL</a | |
| > | |
| <ul class="flex space-x-6 text-sm font-medium text-gray-700"> | |
| <li><a href="index.html" class="hover:text-[#6B9080]">Home</a></li> | |
| <li> | |
| <a href="analyzer.html" class="hover:text-[#6B9080]">Analyzer</a> | |
| </li> | |
| <li> | |
| <a href="profile.html" class="hover:text-[#6B9080]">Profile</a> | |
| </li> | |
| <li><button onclick="logout()" class="text-red-500">Logout</button></li> | |
| </ul> | |
| </div> | |
| </nav> | |
| <div class="container mx-auto px-6"> | |
| <!-- VIEW MODE --> | |
| <div id="profileViewSection"> | |
| <div class="flex items-start space-x-6 mb-10"> | |
| <!-- Avatar & Edit Button --> | |
| <div class="flex flex-col items-center"> | |
| <div class="w-32 h-32 bg-gray-300 rounded-full"></div> | |
| <button | |
| id="editProfileBtn" | |
| class="mt-2 bg-[#6B9080] text-white px-4 py-2 rounded hover:bg-[#5b7e6a] transition" | |
| > | |
| Edit Profile | |
| </button> | |
| <a href="analyzer.html" | |
| ><button | |
| class="mt-2 bg-[#6B9080] text-white px-4 py-2 rounded hover:bg-[#5b7e6a] transition" | |
| > | |
| Go To Analyzer | |
| </button> | |
| </a> | |
| </div> | |
| <!-- User Info --> | |
| <div> | |
| <h1 class="text-3xl font-semibold text-gray-800 mb-4"> | |
| Your Profile | |
| </h1> | |
| <p class="text-gray-700 mb-2"> | |
| Name: <span id="userName" class="font-medium">Loading...</span> | |
| </p> | |
| <p class="text-gray-700 mb-2"> | |
| DOB: <span id="userDOB" class="font-medium">Loding...</span> | |
| </p> | |
| <!-- <p class="text-gray-700 mb-2"> | |
| Big Things We Should Fix: | |
| <span id="userFix" class="font-medium"></span> | |
| </p> | |
| <p class="text-gray-700 mb-6"> | |
| Health Goals: <span id="userGoals" class="font-medium"></span> | |
| </p> --> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- EDIT MODE --> | |
| <div id="profileEditSection" class="hidden mb-10"> | |
| <div class="flex flex-col sm:flex-row items-start space-x-6"> | |
| <!-- Avatar Placeholder --> | |
| <div class="flex flex-col items-center mb-4 sm:mb-0"> | |
| <div class="w-32 h-32 bg-gray-300 rounded-full"></div> | |
| </div> | |
| <!-- Edit Form --> | |
| <div class="flex-1"> | |
| <h1 class="text-3xl font-semibold text-gray-800 mb-4"> | |
| Edit Profile | |
| </h1> | |
| <div class="space-y-4"> | |
| <div> | |
| <label | |
| for="inputName" | |
| class="block text-sm font-medium text-gray-600" | |
| >Name</label | |
| > | |
| <input | |
| type="text" | |
| id="inputName" | |
| class="w-full border border-gray-300 rounded px-3 py-2 focus:ring-2 focus:ring-[#6B9080] focus:outline-none" | |
| /> | |
| </div> | |
| <div> | |
| <label | |
| for="inputDOB" | |
| class="block text-sm font-medium text-gray-600" | |
| >Date of Birth</label | |
| > | |
| <input | |
| type="date" | |
| id="inputDOB" | |
| class="w-full border border-gray-300 rounded px-3 py-2 focus:ring-2 focus:ring-[#6B9080] focus:outline-none" | |
| /> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="flex space-x-2 mt-4"> | |
| <button | |
| id="saveProfileBtn" | |
| class="bg-[#6B9080] text-white px-4 py-2 rounded hover:bg-[#5b7e6a] transition" | |
| > | |
| Save | |
| </button> | |
| <button | |
| id="cancelProfileBtn" | |
| class="bg-gray-300 text-gray-700 px-4 py-2 rounded hover:bg-gray-400 transition" | |
| > | |
| Cancel | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Chart Section --> | |
| <div class="mt-10" id="chartSection"> | |
| <!-- Card Wrapper --> | |
| <div class="bg-white border border-gray-200 rounded-lg p-6 mb-6"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-4"> | |
| Health Progress | |
| </h2> | |
| <!-- Controls Row --> | |
| <div | |
| class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-6" | |
| > | |
| <!-- Date & Score Inputs --> | |
| <div class="flex flex-1 gap-2"> | |
| <input | |
| type="date" | |
| id="entryDate" | |
| class="flex-1 border border-gray-300 rounded px-3 py-2 focus:ring-2 focus:ring-[#6B9080] focus:outline-none" | |
| /> | |
| <input | |
| type="number" | |
| id="entryScore" | |
| min="0" | |
| max="100" | |
| placeholder="Score" | |
| class="w-24 border border-gray-300 rounded px-3 py-2 focus:ring-2 focus:ring-[#6B9080] focus:outline-none" | |
| /> | |
| </div> | |
| <!-- Buttons --> | |
| <div class="flex gap-2"> | |
| <button | |
| id="addEntryBtn" | |
| class="bg-[#6B9080] text-white px-4 py-2 rounded hover:bg-[#5b7e6a] transition" | |
| > | |
| Add Entry | |
| </button> | |
| <button | |
| id="resetChartBtn" | |
| class="bg-red-500 text-white px-4 py-2 rounded hover:bg-red-600 transition" | |
| > | |
| Reset Chart | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Chart Canvas --> | |
| <div class="overflow-x-auto"> | |
| <canvas id="progressChart" class="w-full h-64"></canvas> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script type="module"> | |
| import { initializeApp } from 'https://www.gstatic.com/firebasejs/9.22.0/firebase-app.js'; | |
| import { getAuth, onAuthStateChanged, signOut } from 'https://www.gstatic.com/firebasejs/9.22.0/firebase-auth.js'; | |
| import { getFirestore, doc, getDoc, updateDoc } from 'https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js'; | |
| const firebaseConfig = { | |
| apiKey: "AIzaSyAPhM_Ee7cLzyKHs5zyFy8g5ZOk9-pubRI", | |
| authDomain: "login-tutorial-7a9e1.firebaseapp.com", | |
| projectId: "login-tutorial-7a9e1", | |
| storageBucket: "login-tutorial-7a9e1.firebasestorage.app", | |
| messagingSenderId: "491093197824", | |
| appId: "1:491093197824:web:9f866..." | |
| }; | |
| const app = initializeApp(firebaseConfig); | |
| const auth = getAuth(app); | |
| const db = getFirestore(app); | |
| let currentUser = null; | |
| onAuthStateChanged(auth, async (user) => { | |
| if (user) { | |
| currentUser = user; | |
| await loadUserProfile(); | |
| } else { | |
| window.location.href = 'login.html'; | |
| } | |
| }); | |
| async function loadUserProfile() { | |
| try { | |
| const userDoc = await getDoc(doc(db, 'users', currentUser.uid)); | |
| if (userDoc.exists()) { | |
| const userData = userDoc.data(); | |
| document.getElementById("userName").textContent = userData.name || "Name not set"; | |
| document.getElementById("userDOB").textContent = userData.dob || "DOB not set"; | |
| localStorage.setItem("userName", userData.name || ""); | |
| localStorage.setItem("userDOB", userData.dob || ""); | |
| } | |
| } catch (error) { | |
| console.error("Error loading user profile:", error); | |
| } | |
| } | |
| window.saveProfile = async (name, dob) => { | |
| try { | |
| await updateDoc(doc(db, 'users', currentUser.uid), { | |
| name: name, | |
| dob: dob | |
| }); | |
| localStorage.setItem("userName", name); | |
| localStorage.setItem("userDOB", dob); | |
| return true; | |
| } catch (error) { | |
| console.error("Error updating profile:", error); | |
| return false; | |
| } | |
| }; | |
| window.logout = async () => { | |
| try { | |
| await signOut(auth); | |
| localStorage.clear(); | |
| window.location.href = 'login.html'; | |
| } catch (error) { | |
| console.error("Error signing out:", error); | |
| } | |
| }; | |
| function loadProgressData() { | |
| return JSON.parse(localStorage.getItem("progressData") || "[]"); | |
| } | |
| function saveProgressData(data) { | |
| localStorage.setItem("progressData", JSON.stringify(data)); | |
| } | |
| function resetProgressData() { | |
| localStorage.removeItem("progressData"); | |
| } | |
| document.addEventListener("DOMContentLoaded", () => { | |
| const profileView = document.getElementById("profileViewSection"); | |
| const profileEdit = document.getElementById("profileEditSection"); | |
| const editBtn = document.getElementById("editProfileBtn"); | |
| const saveBtn = document.getElementById("saveProfileBtn"); | |
| const cancelBtn = document.getElementById("cancelProfileBtn"); | |
| const inputName = document.getElementById("inputName"); | |
| const inputDOB = document.getElementById("inputDOB"); | |
| // const inputFix = document.getElementById("inputFix"); | |
| // const inputGoals = document.getElementById("inputGoals"); | |
| editBtn.addEventListener("click", () => { | |
| inputName.value = document.getElementById("userName").textContent; | |
| inputDOB.value = document.getElementById("userDOB").textContent; | |
| profileView.classList.add("hidden"); | |
| profileEdit.classList.remove("hidden"); | |
| }); | |
| saveBtn.addEventListener("click", async () => { | |
| const nameVal = inputName.value.trim(); | |
| const dobVal = inputDOB.value; | |
| const success = await window.saveProfile(nameVal, dobVal); | |
| if (success) { | |
| document.getElementById("userName").textContent = nameVal || "Name not set"; | |
| document.getElementById("userDOB").textContent = dobVal || "DOB not set"; | |
| profileEdit.classList.add("hidden"); | |
| profileView.classList.remove("hidden"); | |
| } else { | |
| alert("Error saving profile. Please try again."); | |
| } | |
| }); | |
| cancelBtn.addEventListener("click", () => { | |
| profileEdit.classList.add("hidden"); | |
| profileView.classList.remove("hidden"); | |
| }); | |
| const chartSection = document.getElementById("chartSection"); | |
| const welcomeMessage = document.getElementById("welcomeMessage"); | |
| const isNewUser = localStorage.getItem("isNewUser") === "true"; | |
| if (isNewUser) { | |
| welcomeMessage.classList.remove("hidden"); | |
| chartSection.classList.add("hidden"); | |
| } | |
| //chart logic(line graph) | |
| const stored = loadProgressData(); | |
| const labels = stored.map((e) => e.date); | |
| const dataPoints = [ | |
| {x:50, y:7}, | |
| {x:70, y:30}, | |
| ]; | |
| const ctx = document.getElementById("progressChart").getContext("2d"); | |
| const progressChart = new Chart(ctx, { | |
| type: "line", | |
| data: { | |
| labels, | |
| datasets: [ | |
| { | |
| label: "Health Score", | |
| data: dataPoints, | |
| borderColor: "#6B9080", | |
| fill: true, | |
| tension: 0.4, | |
| }, | |
| ], | |
| }, | |
| options: { | |
| scales: { y: { beginAtZero: true, max: 100 } }, | |
| }, | |
| }); | |
| document.getElementById("addEntryBtn").addEventListener("click", () => { | |
| const date = document.getElementById("entryDate").value; | |
| const score = parseInt( | |
| document.getElementById("entryScore").value, | |
| 10 | |
| ); | |
| if (!date || isNaN(score)) { | |
| alert("Please select a date and enter a valid score."); | |
| return; | |
| } | |
| stored.push({ date, score }); | |
| saveProgressData(stored); | |
| progressChart.data.labels.push(date); | |
| progressChart.data.datasets[0].data.push(score); | |
| progressChart.update(); | |
| document.getElementById("entryDate").value = ""; | |
| document.getElementById("entryScore").value = ""; | |
| if (isNewUser) { | |
| localStorage.setItem("isNewUser", "false"); | |
| welcomeMessage.classList.add("hidden"); | |
| chartSection.classList.remove("hidden"); | |
| } | |
| }); | |
| // Reset Button | |
| document | |
| .getElementById("resetChartBtn") | |
| .addEventListener("click", () => { | |
| if (!confirm("Are you sure you want to clear all progress data?")) | |
| return; | |
| resetProgressData(); | |
| progressChart.data.labels = []; | |
| progressChart.data.datasets[0].data = []; | |
| progressChart.update(); | |
| }); | |
| }); | |
| </script> | |
| </body> | |
| </html> |