-
Notifications
You must be signed in to change notification settings - Fork 112
Open
Description
<title>Daily Task Planner</title>
<style>
/* --- CSS STYLING START --- */
:root {
--primary: #6c5ce7;
--secondary: #a29bfe;
--bg-body: #dfe6e9;
--bg-card: #ffffff;
--text: #2d3436;
--text-light: #636e72;
--danger: #ff7675;
--success: #00b894;
--radius: 12px;
--shadow: 0 10px 20px rgba(0,0,0,0.08);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background-color: var(--bg-body);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 20px;
}
.container {
width: 100%;
max-width: 450px;
background: var(--bg-card);
border-radius: var(--radius);
box-shadow: var(--shadow);
overflow: hidden;
}
/* Header */
header {
background: var(--primary);
padding: 2rem;
text-align: center;
color: white;
position: relative;
}
header h1 {
font-size: 1.5rem;
margin-bottom: 5px;
}
header p {
font-size: 0.9rem;
opacity: 0.9;
}
.date-display {
margin-top: 10px;
font-size: 0.85rem;
background: rgba(255,255,255,0.2);
display: inline-block;
padding: 4px 12px;
border-radius: 20px;
}
/* Input Section */
.input-area {
padding: 20px;
display: flex;
gap: 10px;
border-bottom: 1px solid #f0f0f0;
}
.input-area input {
flex: 1;
padding: 12px 15px;
border: 2px solid #eee;
border-radius: 8px;
outline: none;
font-size: 1rem;
transition: 0.3s;
}
.input-area input:focus {
border-color: var(--primary);
}
.add-btn {
background: var(--primary);
color: white;
border: none;
width: 50px;
border-radius: 8px;
cursor: pointer;
font-size: 1.2rem;
transition: 0.3s;
}
.add-btn:hover {
background: #5649c0;
}
/* Filter Tabs */
.filters {
display: flex;
padding: 10px 20px;
gap: 10px;
justify-content: center;
background: #fafafa;
}
.filter-btn {
border: none;
background: none;
color: var(--text-light);
cursor: pointer;
padding: 5px 12px;
border-radius: 15px;
font-size: 0.9rem;
font-weight: 500;
}
.filter-btn.active {
color: var(--primary);
background: rgba(108, 92, 231, 0.1);
}
/* Task List */
.task-list {
list-style: none;
max-height: 400px;
overflow-y: auto;
padding: 0;
}
.task-item {
display: flex;
align-items: center;
padding: 15px 20px;
border-bottom: 1px solid #f0f0f0;
transition: 0.3s;
animation: slideIn 0.3s ease forwards;
}
@keyframes slideIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes slideOut {
to { opacity: 0; transform: translateX(20px); }
}
.task-item:hover {
background: #fafafa;
}
/* Custom Checkbox */
.checkbox-custom {
width: 22px;
height: 22px;
border: 2px solid var(--secondary);
border-radius: 50%;
margin-right: 15px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
transition: 0.3s;
}
.task-item.completed .checkbox-custom {
background: var(--success);
border-color: var(--success);
}
.task-item.completed .task-text {
text-decoration: line-through;
color: #b2bec3;
}
.check-icon {
color: white;
font-size: 12px;
display: none;
}
.task-item.completed .check-icon {
display: block;
}
.task-text {
flex: 1;
font-size: 1rem;
color: var(--text);
word-break: break-all;
cursor: pointer;
}
.delete-btn {
background: none;
border: none;
color: #ff7675;
cursor: pointer;
padding: 5px;
opacity: 0;
transition: 0.3s;
}
.task-item:hover .delete-btn {
opacity: 1;
}
/* Footer / Empty State */
.footer {
padding: 15px 20px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 0.85rem;
color: var(--text-light);
border-top: 1px solid #f0f0f0;
}
.clear-btn {
border: none;
background: none;
color: var(--text-light);
cursor: pointer;
font-size: 0.85rem;
}
.clear-btn:hover {
color: var(--danger);
text-decoration: underline;
}
/* Scrollbar Style */
.task-list::-webkit-scrollbar {
width: 6px;
}
.task-list::-webkit-scrollbar-thumb {
background-color: #ccc;
border-radius: 10px;
}
/* --- CSS STYLING END --- */
</style>
<div class="container">
<header>
<h1>My Tasks</h1>
<div class="date-display" id="date-display">Loading Date...</div>
</header>
<div class="input-area">
<input type="text" id="task-input" placeholder="Add a new task...">
<button class="add-btn" id="add-btn">+</button>
</div>
<div class="filters">
<button class="filter-btn active" onclick="filterTasks('all')">All</button>
<button class="filter-btn" onclick="filterTasks('active')">Active</button>
<button class="filter-btn" onclick="filterTasks('completed')">Completed</button>
</div>
<ul class="task-list" id="task-list">
<!-- Tasks JS se ayenge -->
</ul>
<div class="footer">
<span id="items-left">0 items left</span>
<button class="clear-btn" onclick="clearCompleted()">Clear Completed</button>
</div>
</div>
<script>
/* --- JAVASCRIPT LOGIC START --- */
// DOM Elements
const taskInput = document.getElementById('task-input');
const addBtn = document.getElementById('add-btn');
const taskList = document.getElementById('task-list');
const itemsLeftSpan = document.getElementById('items-left');
const dateDisplay = document.getElementById('date-display');
const filterBtns = document.querySelectorAll('.filter-btn');
// State
let tasks = JSON.parse(localStorage.getItem('myTodos')) || [];
let currentFilter = 'all';
// Initialize
window.addEventListener('DOMContentLoaded', () => {
renderTasks();
displayDate();
});
// Date Display
function displayDate() {
const options = { weekday: 'long', month: 'short', day: 'numeric' };
dateDisplay.textContent = new Date().toLocaleDateString('en-US', options);
}
// Event Listeners
addBtn.addEventListener('click', addTask);
taskInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') addTask();
});
// Function: Add Task
function addTask() {
const text = taskInput.value.trim();
if (text === '') {
taskInput.style.borderColor = '#ff7675';
setTimeout(() => taskInput.style.borderColor = '#eee', 1000);
return;
}
const newTask = {
id: Date.now(),
text: text,
completed: false
};
tasks.push(newTask);
saveAndRender();
taskInput.value = '';
taskInput.focus();
}
// Function: Toggle Complete
function toggleTask(id) {
tasks = tasks.map(task => {
if (task.id === id) {
return { ...task, completed: !task.completed };
}
return task;
});
saveAndRender();
}
// Function: Delete Task
function deleteTask(id) {
const taskElement = document.querySelector(`[data-id="${id}"]`);
if (taskElement) {
taskElement.style.animation = 'slideOut 0.3s ease forwards';
taskElement.addEventListener('animationend', () => {
tasks = tasks.filter(task => task.id !== id);
saveAndRender();
});
} else {
tasks = tasks.filter(task => task.id !== id);
saveAndRender();
}
}
// Function: Clear Completed
function clearCompleted() {
tasks = tasks.filter(task => !task.completed);
saveAndRender();
}
// Function: Filter Tasks
function filterTasks(filter) {
currentFilter = filter;
// Update Active Button UI
filterBtns.forEach(btn => btn.classList.remove('active'));
// Find button with matching text logic (simple way)
event.target.classList.add('active');
renderTasks();
}
// Function: Render (Update UI)
function renderTasks() {
taskList.innerHTML = '';
let filteredTasks = tasks;
if (currentFilter === 'active') {
filteredTasks = tasks.filter(t => !t.completed);
} else if (currentFilter === 'completed') {
filteredTasks = tasks.filter(t => t.completed);
}
// Update Items Left Count
const activeCount = tasks.filter(t => !t.completed).length;
itemsLeftSpan.textContent = `${activeCount} item${activeCount !== 1 ? 's' : ''} left`;
if (filteredTasks.length === 0) {
taskList.innerHTML = '<li style="text-align:center; padding:20px; color:#ccc;">No tasks found.</li>';
return;
}
filteredTasks.forEach(task => {
const li = document.createElement('li');
li.className = `task-item ${task.completed ? 'completed' : ''}`;
li.setAttribute('data-id', task.id);
li.innerHTML = `
<div class="checkbox-custom" onclick="toggleTask(${task.id})">
<span class="check-icon">✓</span>
</div>
<span class="task-text" onclick="toggleTask(${task.id})">${escapeHtml(task.text)}</span>
<button class="delete-btn" onclick="deleteTask(${task.id})">
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path></svg>
</button>
`;
taskList.appendChild(li);
});
}
// Helper: Save & Render
function saveAndRender() {
localStorage.setItem('myTodos', JSON.stringify(tasks));
renderTasks();
}
// Helper: Prevent XSS
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
/* --- JAVASCRIPT LOGIC END --- */
</script>
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels