diff --git a/ z2/app/index.html b/ z2/app/index.html new file mode 100644 index 0000000..5ccc0c1 --- /dev/null +++ b/ z2/app/index.html @@ -0,0 +1,30 @@ + + + + + + To-Do List + + + +
+

What should i do list (Reminder)

+

What needs to be done today

+ +
+ + +
+ +
+ + + +
+ + +
+ + + + diff --git a/ z2/app/script.js b/ z2/app/script.js new file mode 100644 index 0000000..e731b7e --- /dev/null +++ b/ z2/app/script.js @@ -0,0 +1,120 @@ +// Получение элементов из HTML +const taskForm = document.getElementById("task-form"); +const taskInput = document.getElementById("task-input"); +const taskList = document.getElementById("task-list"); +const filterButtons = document.querySelectorAll(".filter"); + +// Загрузка задач из LocalStorage +let tasks = JSON.parse(localStorage.getItem("tasks")) || []; + +// Переменная для отслеживания перетаскиваемой задачи +let draggedTaskIndex = null; + +// Функция для отображения задач +function displayTasks(filter = "all") { + taskList.innerHTML = ""; + const filteredTasks = tasks.filter(task => + filter === "all" || (filter === "active" && !task.completed) || (filter === "completed" && task.completed) + ); + + filteredTasks.forEach((task, index) => { + const taskItem = document.createElement("li"); + taskItem.classList.add("task-item"); + taskItem.draggable = true; // Сделать элемент перетаскиваемым + + if (task.completed) taskItem.classList.add("completed"); + + taskItem.innerHTML = ` + ${task.text} +
+ + +
+ `; + + // Добавление событий для drag-and-drop + taskItem.addEventListener("dragstart", () => handleDragStart(index)); + taskItem.addEventListener("dragover", (e) => handleDragOver(e)); + taskItem.addEventListener("drop", () => handleDrop(index)); + taskItem.addEventListener("dragend", handleDragEnd); + + taskList.appendChild(taskItem); + }); +} + +// Обработчик начала перетаскивания +function handleDragStart(index) { + draggedTaskIndex = index; +} + +// Обработчик, предотвращающий действия по умолчанию (нужен для drop) +function handleDragOver(e) { + e.preventDefault(); +} + +// Обработчик окончания перетаскивания +function handleDrop(index) { + if (draggedTaskIndex !== null && draggedTaskIndex !== index) { + const draggedTask = tasks[draggedTaskIndex]; + tasks.splice(draggedTaskIndex, 1); + tasks.splice(index, 0, draggedTask); + saveTasks(); + displayTasks(); + } + draggedTaskIndex = null; +} + +// Обработчик окончания перетаскивания +function handleDragEnd() { + draggedTaskIndex = null; +} + +// Добавление новой задачи +taskForm.addEventListener("submit", (e) => { + e.preventDefault(); + const taskText = taskInput.value.trim(); + if (!taskText) return; + + const newTask = { + id: Date.now().toString(), + text: taskText, + completed: false + }; + tasks.push(newTask); + saveTasks(); + displayTasks(); + taskInput.value = ""; +}); + +// Переключение статуса задачи на выполнено +function toggleComplete(taskId) { + tasks = tasks.map(task => + task.id === taskId ? { ...task, completed: !task.completed } : task + ); + saveTasks(); + displayTasks(); +} + +// Удаление задачи +function deleteTask(taskId) { + tasks = tasks.filter(task => task.id !== taskId); + saveTasks(); + displayTasks(); +} + +// Сохранение задач в LocalStorage +function saveTasks() { + localStorage.setItem("tasks", JSON.stringify(tasks)); +} + +// Добавление события для фильтров +filterButtons.forEach(button => { + button.addEventListener("click", () => { + filterButtons.forEach(btn => btn.classList.remove("active")); + button.classList.add("active"); + displayTasks(button.dataset.filter); + }); +}); + +// Инициализация +displayTasks(); diff --git a/ z2/app/style.css b/ z2/app/style.css new file mode 100644 index 0000000..64c2fac --- /dev/null +++ b/ z2/app/style.css @@ -0,0 +1,167 @@ + + +body { + font-family: "Helvetica Neue", sans-serif; + background: linear-gradient(to bottom, #f7f7f7, #e1e1e1); /* Градиентный фон в стиле Apple */ + display: flex; + align-items: center; + justify-content: center; + min-height: 100vh; +} + +.app-container { + background-color: #ffffff; /* Белый фон для контейнера */ + padding: 40px; /* Увеличено для большего пространства */ + border-radius: 20px; + width: 100%; + max-width: 500px; /* Увеличена ширина контейнера */ + box-shadow: 0px 15px 20px rgba(0, 0, 0, 0.3); + border: 1px solid #d9d9d9; +} + +h1 { + font-family: "Helvetica", sans-serif; + text-align: center; + margin-bottom: 20px; + font-size: 30px; /* Увеличен размер заголовка */ + color: #4a4a4a; + text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.2); +} + +.subtitle { + font-size: 16px; /* Увеличен размер подзаголовка */ + color: #6d6d72; + text-align: center; + margin-bottom: 20px; + font-weight: 300; +} + +form { + display: flex; + gap: 10px; + margin-bottom: 20px; +} + +#task-input { + flex-grow: 1; + padding: 15px; /* Увеличено для удобства ввода */ + border-radius: 8px; + border: 1px solid #c7c7c7; + background-color: #f0f0f0; /* Светлый фон для ввода */ + font-size: 18px; /* Увеличен размер текста */ + box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.1); +} + +form button { + padding: 15px 25px; /* Увеличены размеры кнопок */ + border: none; + background: linear-gradient(to bottom, #4da6ff, #0066cc); + color: #ffffff; + border-radius: 12px; + cursor: pointer; + font-weight: bold; + text-shadow: 0px -1px 1px rgba(0, 0, 0, 0.3); + box-shadow: 0px 5px 8px rgba(0, 0, 0, 0.2); + transition: all 0.2s ease; + font-size: 16px; /* Увеличен размер текста на кнопках */ +} + +form button:active { + background: linear-gradient(to bottom, #0066cc, #4da6ff); + box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2); + transform: translateY(2px); +} + +.filter-buttons { + display: flex; + justify-content: space-around; + margin: 20px 0; +} + +.filter { + background: linear-gradient(to bottom, #e6e6e6, #d1d1d1); + border: 1px solid #c3c3c3; + padding: 10px 20px; /* Увеличены размеры кнопок фильтров */ + color: #4a4a4a; + border-radius: 12px; + cursor: pointer; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.6); + box-shadow: 0px 3px 5px rgba(0, 0, 0, 0.15); + transition: all 0.2s ease; + font-size: 16px; /* Увеличен размер текста на кнопках фильтров */ +} + +.filter.active, .filter:hover { + background: linear-gradient(to bottom, #4da6ff, #0066cc); + color: #ffffff; +} + +#task-list { + list-style: none; + max-height: 400px; /* Увеличена высота списка задач */ + overflow-y: auto; + padding: 10px 0; + background-color: #ffffff; + border-radius: 8px; + border: 1px solid #e2e2e2; +} + +.task-item { + padding: 15px; /* Добавляем отступы для элементов задач */ + border-radius: 10px; /* Скругление углов */ + background-color: #ffffff; /* Исходный цвет фона задачи */ + margin-bottom: 10px; /* Отступ между задачами */ + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* Тень для задач */ + transition: background 0.3s ease; /* Плавный переход фона */ +} + +/* Добавляем эффект наведения для задачи */ +.task-item:hover { + background: linear-gradient(to bottom, #4da6ff, #0066cc); /* Градиентный фон при наведении */ + color: #ffffff; /* Изменение цвета текста при наведении */ +} +.task-item.completed { + text-decoration: line-through; + color: #a09b8d; +} + +.task-actions { + display: flex; + gap: 15px; /* Увеличено расстояние между кнопками */ +} + +.task-actions button { + background: none; + border: none; + cursor: pointer; + font-size: 1.5em; /* Увеличен размер иконок действий */ +} + +.task-actions button.complete-btn { + color: #60a36e; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.2); +} + +.task-actions button.delete-btn { + color: #d9534f; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.2); +} + + + +body { + font-family: "Helvetica Neue", sans-serif; + background-image: url('file:///D:/kapli-vody-59.webp'); /* Полный путь к изображению */ + background-size: cover; + background-position: center; + display: flex; + align-items: center; + justify-content: center; + min-height: 100vh; +} + + + + +