173 lines
7.3 KiB
JavaScript
173 lines
7.3 KiB
JavaScript
const HabitTrackerApp = {
|
|
elements: {
|
|
habitGrid: null,
|
|
addHabitForm: null,
|
|
addHabbitButton: null,
|
|
filterButtons: []
|
|
},
|
|
|
|
currentFilter: 'all',
|
|
|
|
init: function() {
|
|
this.loadElements();
|
|
this.render();
|
|
this.setupEventListeners();
|
|
},
|
|
|
|
setupEventListeners: function() {
|
|
// Обработчики для кнопок фильтров
|
|
this.elements.filterButtons.forEach(button => {
|
|
button.addEventListener('click', (event) => {
|
|
const filter = event.target.dataset.filter;
|
|
this.applyFilter(filter);
|
|
});
|
|
});
|
|
|
|
// Делегирование событий для кнопок в карточках привычек
|
|
this.elements.habitGrid.addEventListener('click', (event) => {
|
|
const habitCard = event.target.closest('.habit-card');
|
|
if (!habitCard) return;
|
|
|
|
const habitId = parseInt(habitCard.dataset.habitId);
|
|
|
|
if (event.target.classList.contains('js-habit-done')) {
|
|
HabitManager.markHabitDone(habitId);
|
|
HabitManager.saveToLocalStorage();
|
|
this.render();
|
|
} else if (event.target.classList.contains('js-habit-delete')) {
|
|
HabitManager.deleteHabit(habitId);
|
|
HabitManager.saveToLocalStorage();
|
|
this.render();
|
|
}
|
|
});
|
|
},
|
|
|
|
loadElements: function() {
|
|
this.elements.habitGrid = document.getElementById('habits-grid');
|
|
this.elements.filterButtons = document.querySelectorAll('.filters__button');
|
|
},
|
|
|
|
applyFilter: function(filter) {
|
|
this.currentFilter = filter;
|
|
|
|
// Обновление активной кнопки фильтра
|
|
this.elements.filterButtons.forEach(button => {
|
|
if (button.dataset.filter === filter) {
|
|
button.classList.remove('button--secondary');
|
|
button.classList.add('button--primary');
|
|
} else {
|
|
button.classList.remove('button--primary');
|
|
button.classList.add('button--secondary');
|
|
}
|
|
});
|
|
|
|
this.render();
|
|
},
|
|
|
|
render: function() {
|
|
const filteredHabits = HabitManager.getFilteredHabits(this.currentFilter);
|
|
|
|
const habitsHTML = filteredHabits.map(habit => {
|
|
const progress = (habit.currentCount / habit.targetCount) * 100;
|
|
|
|
// Определение классов для карточки
|
|
const cardClasses = ['habit-card'];
|
|
if (habit.isCompleted) cardClasses.push('habit-card--completed');
|
|
if (habit.isImportant) cardClasses.push('habit-card--important');
|
|
if (habit.currentStreak >= 3) cardClasses.push('habit-card--streak');
|
|
if (habit.currentCount === 0) cardClasses.push('habit-card--new');
|
|
|
|
// Выбор иконки в зависимости от названия привычки
|
|
let icon = '⭐';
|
|
if (habit.name.includes('Медитация')) icon = '🧘';
|
|
if (habit.name.includes('Учить')) icon = '💻';
|
|
if (habit.name.includes('Спорт')) icon = '💪';
|
|
if (habit.name.includes('Чтение')) icon = '📚';
|
|
|
|
return `
|
|
<div class="${cardClasses.join(' ')}" data-habit-id="${habit.id}">
|
|
<div class="habit-card__header">
|
|
<div class="habit-card__icon">${icon}</div>
|
|
<h3 class="habit-card__title">${habit.name}</h3>
|
|
</div>
|
|
<p class="habit-card__description">${habit.description}</p>
|
|
<div class="habit-card__progress">
|
|
<div class="habit-card__progress-info">
|
|
<span>Прогресс</span>
|
|
<span>${Math.round(progress)}%</span>
|
|
</div>
|
|
<div class="habit-card__progress-bar">
|
|
<div class="habit-card__progress-fill" style="width: ${progress}%"></div>
|
|
</div>
|
|
</div>
|
|
<div class="habit-card__actions">
|
|
<button class="button ${habit.isCompleted ? 'button--success' : 'button--primary'} js-habit-done">
|
|
${habit.isCompleted ? 'Выполнено' : 'Отметить выполнение'}
|
|
</button>
|
|
<button class="button button--danger js-habit-delete">Удалить</button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}).join('');
|
|
|
|
this.elements.habitGrid.innerHTML = habitsHTML;
|
|
|
|
// Обновление статистики в заголовке
|
|
this.updateStats();
|
|
},
|
|
|
|
updateStats: function() {
|
|
const totalHabits = HabitManager.habits.length;
|
|
const completedHabits = HabitManager.habits.filter(h => h.isCompleted).length;
|
|
const totalProgress = totalHabits > 0 ? Math.round((completedHabits / totalHabits) * 100) : 0;
|
|
|
|
document.querySelector('.stats-panel__value:nth-child(1)').textContent = totalHabits;
|
|
document.querySelector('.stats-panel__value:nth-child(2)').textContent = `${totalProgress}%`;
|
|
document.querySelector('.stats-panel__value:nth-child(3)').textContent = HabitManager.stats.currentStreak;
|
|
}
|
|
}
|
|
|
|
HabitTrackerApp.loadFromLocalStorage = function() {
|
|
HabitManager.loadFromLocalStorage();
|
|
|
|
if (HabitManager.habits.length === 0) {
|
|
// Создание демо-привычек
|
|
HabitManager.createHabit('Учить JavaScript', 'Писать код каждый день', 5, true);
|
|
HabitManager.createHabit('Медитация', 'Ежедневная практика медитации по 10 минут', 1, false);
|
|
HabitManager.createHabit('Спорт', 'Тренировка 30 минут', 3, true);
|
|
HabitManager.createHabit('Чтение', 'Читать 20 страниц в день', 7, false);
|
|
HabitManager.saveToLocalStorage();
|
|
}
|
|
}
|
|
|
|
function openModal() {
|
|
const modal = document.getElementById('habit-modal');
|
|
modal.classList.add('modal--open');
|
|
document.body.style.overflow = 'hidden';
|
|
document.getElementById('habit-name').focus();
|
|
}
|
|
|
|
function closeModal() {
|
|
const modal = document.getElementById('habit-modal');
|
|
modal.classList.remove('modal--open');
|
|
document.body.style.overflow = '';
|
|
}
|
|
|
|
document.getElementById('add-habbit-button').addEventListener('click', openModal);
|
|
document.querySelector('.modal__close').addEventListener('click', closeModal);
|
|
document.getElementById('cancel-button').addEventListener('click', closeModal);
|
|
|
|
document.querySelector('.modal__overlay').addEventListener('click',closeModal);
|
|
|
|
document.addEventListener('keydown', function(event) {
|
|
if (event.key === 'Escape') {
|
|
closeModal();
|
|
}
|
|
});
|
|
|
|
document.getElementById('habit-form').addEventListener('submit', function(event) {
|
|
event.preventDefault();
|
|
|
|
alert('Привычка добавлена!');
|
|
closeModal();
|
|
}); |