<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Habit Tracker Pro</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; background-color: #f4f4f4; }
.container { max-width: 800px; margin: auto; background: white; padding: 20px; border-radius: 10px; box-shadow: 0 0 10px rgba(0,0,0,0.1); }
.habit { margin: 10px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px; display: flex; justify-content: space-between; align-items: center; }
.streak { color: green; font-weight: bold; }
.progress-bar { width: 200px; background: #eee; border-radius: 5px; overflow: hidden; }
.progress { height: 20px; background: linear-gradient(to right, #4CAF50, #8BC34A); transition: width 0.3s; }
button { margin: 5px; padding: 10px; cursor: pointer; border: none; border-radius: 5px; background: #007bff; color: white; }
button:hover { background: #0056b3; }
.delete { background: #dc3545; }
.delete:hover { background: #c82333; }
.add-form { display: flex; margin-bottom: 20px; }
.add-form input { flex: 1; padding: 10px; }
.stats { margin-top: 20px; }
.chart { margin: 10px 0; }
.calendar { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; margin-top: 20px; }
.day { padding: 10px; border: 1px solid #ddd; text-align: center; cursor: pointer; }
.day.done { background: #4CAF50; color: white; }
.day.missed { background: #f44336; color: white; }
.tabs { display: flex; margin-bottom: 20px; }
.tab { padding: 10px; cursor: pointer; background: #eee; border-radius: 5px 5px 0 0; }
.tab.active { background: white; border-bottom: 2px solid #007bff; }
.tab-content { display: none; }
.tab-content.active { display: block; }
</style>
</head>
<body>
<div class="container">
<h1>Habit Tracker Pro</h1>
<div class="tabs">
<div class="tab active" onclick="showTab('habits')">Habits</div>
<div class="tab" onclick="showTab('stats')">Stats</div>
<div class="tab" onclick="showTab('calendar')">Calendar</div>
</div>
<div id="habits-tab" class="tab-content active">
<div class="add-form">
<input type="text" id="habitInput" placeholder="Enter a new habit">
<select id="categorySelect">
<option value="Health">Health</option>
<option value="Productivity">Productivity</option>
<option value="Learning">Learning</option>
<option value="Other">Other</option>
</select>
<button onclick="addHabit()">Add Habit</button>
</div>
<div id="habits"></div>
</div>
<div id="stats-tab" class="tab-content">
<div class="stats">
<h2>Overall Stats</h2>
<canvas id="statsChart" width="400" height="200"></canvas>
</div>
</div>
<div id="calendar-tab" class="tab-content">
<h2>Monthly View</h2>
<button onclick="prevMonth()">Prev</button>
<span id="monthYear"></span>
<button onclick="nextMonth()">Next</button>
<div id="calendar"></div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
let habits = JSON.parse(localStorage.getItem('habits')) || [];
let currentMonth = new Date().getMonth();
let currentYear = new Date().getFullYear();
let selectedHabitIndex = -1;
function renderHabits() {
const container = document.getElementById('habits');
container.innerHTML = '';
habits.forEach((habit, index) => {
const div = document.createElement('div');
div.className = 'habit';
const progressPercent = habit.history ? (habit.history.filter(d => d.done).length / habit.history.length * 100) : 0;
div.innerHTML = `
<div>
<strong>${habit.name}</strong> (${habit.category})<br>
<span class="streak">Streak: ${habit.streak}</span>
<div class="progress-bar"><div class="progress" style="width: ${progressPercent}%"></div></div>
</div>
<div>
<button onclick="markDone(${index})">Mark Done</button>
<button onclick="resetHabit(${index})">Reset</button>
<button class="delete" onclick="deleteHabit(${index})">Delete</button>
<button onclick="viewCalendar(${index})">View Calendar</button>
</div>
`;
container.appendChild(div);
});
}
function addHabit() {
const input = document.getElementById('habitInput');
const category = document.getElementById('categorySelect').value;
if (input.value.trim()) {
habits.push({ name: input.value.trim(), category, streak: 0, history: [] });
localStorage.setItem('habits', JSON.stringify(habits));
input.value = '';
renderHabits();
updateStats();
}
}
function markDone(index) {
const today = new Date().toDateString();
if (!habits[index].history.some(d => d.date === today)) {
habits[index].history.push({ date: today, done: true });
habits[index].streak++;
}
localStorage.setItem('habits', JSON.stringify(habits));
renderHabits();
updateStats();
if (selectedHabitIndex === index) renderCalendarView();
}
function resetHabit(index) {
habits[index].streak = 0;
localStorage.setItem('habits', JSON.stringify(habits));
renderHabits();
updateStats();
}
function deleteHabit(index) {
habits.splice(index, 1);
localStorage.setItem('habits', JSON.stringify(habits));
renderHabits();
updateStats();
}
function updateStats() {
const ctx = document.getElementById('statsChart').getContext('2d');
const data = habits.map(h => h.streak);
new Chart(ctx, {
type: 'bar',
data: {
labels: habits.map(h => h.name),
datasets: [{
label: 'Streaks',
data: data,
backgroundColor: 'rgba(75, 192, 192, 0.2)',
borderColor: 'rgba(75, 192, 192, 1)',
borderWidth: 1
}]
}
});
}
function showTab(tab) {
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
document.querySelector(`.${tab}`).classList.add('active');
document.getElementById(`${tab}-tab`).classList.add('active');
if (tab === 'stats') updateStats();
if (tab === 'calendar') renderCalendarView();
}
function viewCalendar(index) {
selectedHabitIndex = index;
showTab('calendar');
}
function renderCalendarView() {
const calendar = document.getElementById('calendar');
calendar.innerHTML = '';
const daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate();
const firstDay = new Date(currentYear, currentMonth, 1).getDay();
document.getElementById('monthYear').textContent = new Date(currentYear, currentMonth).toLocaleString('default', { month: 'long', year: 'numeric' });
for (let i = 0; i < firstDay; i++) {
const empty = document.createElement('div');
calendar.appendChild(empty);
}
for (let day = 1; day <= daysInMonth; day++) {
const dayDiv = document.createElement('div');
dayDiv.className = 'day';
dayDiv.textContent = day;
const dateStr = new Date(currentYear, currentMonth, day).toDateString();
if (selectedHabitIndex >= 0 && habits[selectedHabitIndex].history.some(d => d.date === dateStr && d.done)) {
dayDiv.classList.add('done');
} else if (selectedHabitIndex >= 0 && habits[selectedHabitIndex].history.some(d => d.date === dateStr && !d.done)) {
dayDiv.classList.add('missed');
}
calendar.appendChild(dayDiv);
}
}
function prevMonth() {
currentMonth--;
if (currentMonth < 0) {
currentMonth = 11;
currentYear--;
}
renderCalendarView();
}
function nextMonth() {
currentMonth++;
if (currentMonth > 11) {
currentMonth = 0;
currentYear++;
}
renderCalendarView();
}
renderHabits();
</script>
</body>
</html>