Files
123/app.js

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();
});