export class WaterTracker { constructor(containerId) { this.container = document.getElementById(containerId); this.state = { current: 0, goal: 3000, // mL bottleSize: 500, // mL }; this.STORAGE_KEY = 'hydroflux_data'; this.loadState(); this.render(); this.attachEvents(); this.updateUI(); } loadState() { const saved = localStorage.getItem(this.STORAGE_KEY); if (saved) { const parsed = JSON.parse(saved); this.state = { ...this.state, ...parsed }; } } saveState() { localStorage.setItem(this.STORAGE_KEY, JSON.stringify(this.state)); this.updateUI(); } addWater() { this.state.current += this.state.bottleSize; this.saveState(); if (navigator.vibrate) navigator.vibrate(50); } removeWater() { this.state.current = Math.max(0, this.state.current - this.state.bottleSize); this.saveState(); if (navigator.vibrate) navigator.vibrate(50); } setBottleSize(size) { if (!size || size <= 0) return; this.state.bottleSize = size; this.saveState(); } getPercentage() { return Math.min(100, Math.max(0, (this.state.current / this.state.goal) * 100)); } updateUI() { // Update Text const currentEl = this.container.querySelector('.water-count'); const percentageEl = this.container.querySelector('.water-percentage'); if (currentEl) currentEl.textContent = `${this.state.current} / ${this.state.goal} mL`; if (percentageEl) percentageEl.textContent = `${Math.round(this.getPercentage())}%`; // Update Wave Animation Height const wave = this.container.querySelector('.wave'); if (wave) { wave.style.top = `${100 - this.getPercentage()}%`; } } render() { this.container.innerHTML = `
0% HYDRATION
0 / 3000 mL
`; this.checkNotificationStatus(); } attachEvents() { this.container.querySelector('#add-water-btn').addEventListener('click', () => { this.addWater(); }); this.container.querySelector('#remove-water-btn').addEventListener('click', () => { this.removeWater(); }); this.container.querySelector('#notify-btn').addEventListener('click', (e) => { this.toggleNotifications(e.currentTarget); }); const input = this.container.querySelector('#bottle-size-input'); input.addEventListener('change', (e) => { this.setBottleSize(parseInt(e.target.value)); }); } // --- Notification Logic --- toggleNotifications(btn) { if (!("Notification" in window)) { alert("This browser does not support desktop notifications"); return; } if (Notification.permission === "granted") { alert("Reminders are active! We'll check every hour."); } else if (Notification.permission !== "denied") { Notification.requestPermission().then(permission => { if (permission === "granted") { this.startReminderLoop(); btn.style.color = "var(--primary-cyan)"; new Notification("HydroFlux", { body: "Smart Hydration Reminders Enabled!" }); } }); } } checkNotificationStatus() { if (Notification.permission === "granted") { const btn = this.container.querySelector('#notify-btn'); if (btn) btn.style.color = "var(--primary-cyan)"; this.startReminderLoop(); } } startReminderLoop() { // Clear existing to avoid duplicates if (this.reminderInterval) clearInterval(this.reminderInterval); // Check every minute if it's been > 1 hour since last drink this.reminderInterval = setInterval(() => { // Pseudo-logic check since we don't store timestamp in this simple version yet // In a real app, you'd check this.state.lastDrinkTime new Notification("HydroFlux Needs You", { body: "Remember to drink water!", icon: "/icon.png" }); }, 3600000); // 1 Hour } }