Загрузить файлы в «/»
This commit is contained in:
173
app.js
Normal file
173
app.js
Normal file
@@ -0,0 +1,173 @@
|
||||
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();
|
||||
});
|
||||
Reference in New Issue
Block a user