anycoder-8238e1a6 / index.html
Lee6x's picture
Upload folder using huggingface_hub
253cbdb verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TaskFlow Pro - Advanced Task Management</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--primary: #6366f1;
--primary-dark: #4f46e5;
--secondary: #8b5cf6;
--success: #10b981;
--warning: #f59e0b;
--danger: #ef4444;
--dark: #1f2937;
--light: #f3f4f6;
--white: #ffffff;
--gray: #6b7280;
--border: #e5e7eb;
--shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
--radius: 12px;
--transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
color: var(--dark);
transition: var(--transition);
}
body.dark-mode {
--dark: #f3f4f6;
--light: #1f2937;
--white: #111827;
--border: #374151;
--gray: #9ca3af;
background: linear-gradient(135deg, #1e1b4b 0%, #312e81 100%);
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 20px;
}
header {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: var(--radius);
padding: 20px 30px;
margin-bottom: 30px;
box-shadow: var(--shadow-lg);
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 20px;
animation: slideDown 0.5s ease-out;
}
body.dark-mode header {
background: rgba(17, 24, 39, 0.95);
}
.logo {
display: flex;
align-items: center;
gap: 12px;
font-size: 24px;
font-weight: bold;
color: var(--primary);
}
.logo i {
font-size: 32px;
animation: pulse 2s infinite;
}
.header-actions {
display: flex;
gap: 15px;
align-items: center;
}
.theme-toggle {
background: var(--primary);
color: white;
border: none;
padding: 10px 15px;
border-radius: 50px;
cursor: pointer;
transition: var(--transition);
font-size: 18px;
}
.theme-toggle:hover {
background: var(--primary-dark);
transform: rotate(180deg);
}
.stats-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.stat-card {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: var(--radius);
padding: 20px;
box-shadow: var(--shadow);
transition: var(--transition);
animation: fadeInUp 0.5s ease-out;
animation-fill-mode: both;
}
body.dark-mode .stat-card {
background: rgba(17, 24, 39, 0.95);
}
.stat-card:hover {
transform: translateY(-5px);
box-shadow: var(--shadow-lg);
}
.stat-card:nth-child(1) { animation-delay: 0.1s; }
.stat-card:nth-child(2) { animation-delay: 0.2s; }
.stat-card:nth-child(3) { animation-delay: 0.3s; }
.stat-card:nth-child(4) { animation-delay: 0.4s; }
.stat-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.stat-icon {
width: 40px;
height: 40px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
}
.stat-icon.blue { background: rgba(99, 102, 241, 0.1); color: var(--primary); }
.stat-icon.green { background: rgba(16, 185, 129, 0.1); color: var(--success); }
.stat-icon.yellow { background: rgba(245, 158, 11, 0.1); color: var(--warning); }
.stat-icon.red { background: rgba(239, 68, 68, 0.1); color: var(--danger); }
.stat-value {
font-size: 32px;
font-weight: bold;
color: var(--dark);
}
.stat-label {
color: var(--gray);
font-size: 14px;
}
.main-content {
display: grid;
grid-template-columns: 350px 1fr;
gap: 30px;
animation: fadeIn 0.5s ease-out;
}
.sidebar {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: var(--radius);
padding: 25px;
box-shadow: var(--shadow);
height: fit-content;
position: sticky;
top: 20px;
}
body.dark-mode .sidebar {
background: rgba(17, 24, 39, 0.95);
}
.add-task-form {
margin-bottom: 30px;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: 500;
color: var(--dark);
}
.form-control {
width: 100%;
padding: 10px 15px;
border: 2px solid var(--border);
border-radius: 8px;
font-size: 14px;
transition: var(--transition);
background: var(--white);
color: var(--dark);
}
body.dark-mode .form-control {
background: var(--dark);
color: var(--light);
}
.form-control:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
}
.priority-select {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
}
.priority-btn {
padding: 8px;
border: 2px solid var(--border);
background: var(--white);
border-radius: 8px;
cursor: pointer;
transition: var(--transition);
font-size: 12px;
font-weight: 500;
}
body.dark-mode .priority-btn {
background: var(--dark);
}
.priority-btn.active.low {
background: var(--success);
color: white;
border-color: var(--success);
}
.priority-btn.active.medium {
background: var(--warning);
color: white;
border-color: var(--warning);
}
.priority-btn.active.high {
background: var(--danger);
color: white;
border-color: var(--danger);
}
.category-select {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
.category-btn {
padding: 8px;
border: 2px solid var(--border);
background: var(--white);
border-radius: 8px;
cursor: pointer;
transition: var(--transition);
font-size: 12px;
}
body.dark-mode .category-btn {
background: var(--dark);
}
.category-btn.active {
background: var(--primary);
color: white;
border-color: var(--primary);
}
.btn-primary {
width: 100%;
padding: 12px;
background: linear-gradient(135deg, var(--primary), var(--secondary));
color: white;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: var(--transition);
position: relative;
overflow: hidden;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(99, 102, 241, 0.3);
}
.btn-primary::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.3);
transform: translate(-50%, -50%);
transition: width 0.6s, height 0.6s;
}
.btn-primary:active::after {
width: 300px;
height: 300px;
}
.tasks-container {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: var(--radius);
padding: 25px;
box-shadow: var(--shadow);
}
body.dark-mode .tasks-container {
background: rgba(17, 24, 39, 0.95);
}
.tasks-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
flex-wrap: wrap;
gap: 15px;
}
.search-box {
position: relative;
flex: 1;
max-width: 300px;
}
.search-box input {
width: 100%;
padding: 10px 15px 10px 40px;
border: 2px solid var(--border);
border-radius: 25px;
font-size: 14px;
transition: var(--transition);
}
body.dark-mode .search-box input {
background: var(--dark);
color: var(--light);
}
.search-box i {
position: absolute;
left: 15px;
top: 50%;
transform: translateY(-50%);
color: var(--gray);
}
.filter-tabs {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.filter-tab {
padding: 8px 16px;
background: var(--light);
border: none;
border-radius: 20px;
cursor: pointer;
transition: var(--transition);
font-size: 14px;
font-weight: 500;
}
body.dark-mode .filter-tab {
background: var(--dark);
}
.filter-tab.active {
background: var(--primary);
color: white;
}
.filter-tab:hover:not(.active) {
background: var(--border);
}
.tasks-list {
display: grid;
gap: 15px;
}
.task-item {
background: var(--white);
border: 2px solid var(--border);
border-radius: var(--radius);
padding: 15px;
transition: var(--transition);
cursor: move;
position: relative;
overflow: hidden;
}
body.dark-mode .task-item {
background: var(--dark);
}
.task-item.dragging {
opacity: 0.5;
transform: scale(0.95);
}
.task-item:hover {
border-color: var(--primary);
box-shadow: var(--shadow);
transform: translateX(5px);
}
.task-item.completed {
opacity: 0.7;
}
.task-item.completed .task-title {
text-decoration: line-through;
color: var(--gray);
}
.task-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 10px;
}
.task-title {
font-size: 16px;
font-weight: 600;
color: var(--dark);
flex: 1;
margin-right: 10px;
}
.task-actions {
display: flex;
gap: 8px;
}
.task-btn {
width: 32px;
height: 32px;
border: none;
background: var(--light);
border-radius: 8px;
cursor: pointer;
transition: var(--transition);
display: flex;
align-items: center;
justify-content: center;
color: var(--gray);
}
body.dark-mode .task-btn {
background: var(--dark);
}
.task-btn:hover {
background: var(--primary);
color: white;
transform: scale(1.1);
}
.task-meta {
display: flex;
gap: 15px;
align-items: center;
flex-wrap: wrap;
}
.task-priority {
padding: 4px 10px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
}
.priority-low {
background: rgba(16, 185, 129, 0.1);
color: var(--success);
}
.priority-medium {
background: rgba(245, 158, 11, 0.1);
color: var(--warning);
}
.priority-high {
background: rgba(239, 68, 68, 0.1);
color: var(--danger);
}
.task-category {
padding: 4px 10px;
background: rgba(99, 102, 241, 0.1);
color: var(--primary);
border-radius: 12px;
font-size: 12px;
font-weight: 500;
}
.task-date {
display: flex;
align-items: center;
gap: 5px;
color: var(--gray);
font-size: 13px;
}
.progress-bar {
height: 4px;
background: var(--border);
border-radius: 2px;
margin-top: 10px;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--primary), var(--secondary));
border-radius: 2px;
transition: width 0.3s ease;
}
.empty-state {
text-align: center;
padding: 60px 20px;
color: var(--gray);
}
.empty-state i {
font-size: 64px;
margin-bottom: 20px;
opacity: 0.3;
}
.toast {
position: fixed;
bottom: 30px;
right: 30px;
background: var(--white);
padding: 15px 20px;
border-radius: var(--radius);
box-shadow: var(--shadow-lg);
display: flex;
align-items: center;
gap: 15px;
transform: translateX(400px);
transition: transform 0.3s ease;
z-index: 1000;
}
body.dark-mode .toast {
background: var(--dark);
}
.toast.show {
transform: translateX(0);
}
.toast-icon {
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: white;
}
.toast-icon.success { background: var(--success); }
.toast-icon.error { background: var(--danger); }
.toast-icon.info { background: var(--primary); }
.chart-container {
margin-top: 30px;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: var(--radius);
padding: 25px;
box-shadow: var(--shadow);
}
body.dark-mode .chart-container {
background: rgba(17, 24, 39, 0.95);
}
.chart-header {
font-size: 18px;
font-weight: 600;
margin-bottom: 20px;
color: var(--dark);
}
.chart-bars {
display: flex;
align-items: flex-end;
justify-content: space-around;
height: 200px;
gap: 20px;
}
.chart-bar {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
}
.bar {
width: 100%;
background: linear-gradient(180deg, var(--primary), var(--secondary));
border-radius: 8px 8px 0 0;
transition: var(--transition);
position: relative;
animation: growBar 1s ease-out;
}
.bar:hover {
transform: scaleY(1.05);
filter: brightness(1.1);
}
.bar-label {
font-size: 12px;
color: var(--gray);
font-weight: 500;
}
.bar-value {
position: absolute;
top: -25px;
left: 50%;
transform: translateX(-50%);
font-size: 14px;
font-weight: 600;
color: var(--dark);
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.1); }
}
@keyframes growBar {
from {
height: 0;
}
}
@media (max-width: 968px) {
.main-content {
grid-template-columns: 1fr;
}
.sidebar {
position: static;
}
.stats-container {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 640px) {
.container {
padding: 10px;
}
header {
padding: 15px 20px;
}
.stats-container {
grid-template-columns: 1fr;
}
.tasks-header {
flex-direction: column;
align-items: stretch;
}
.search-box {
max-width: 100%;
}
.filter-tabs {
justify-content: center;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<div class="logo">
<i class="fas fa-tasks"></i>
<span>TaskFlow Pro</span>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" style="text-decoration: none; color: var(--primary); font-size: 14px; margin-left: 10px;">
Built with anycoder
</a>
</div>
<div class="header-actions">
<button class="theme-toggle" onclick="toggleTheme()">
<i class="fas fa-moon" id="themeIcon"></i>
</button>
</div>
</header>
<div class="stats-container">
<div class="stat-card">
<div class="stat-header">
<div>
<div class="stat-value" id="totalTasks">0</div>
<div class="stat-label">Total Tasks</div>
</div>
<div class="stat-icon blue">
<i class="fas fa-list"></i>
</div>
</div>
</div>
<div class="stat-card">
<div class="stat-header">
<div>
<div class="stat-value" id="completedTasks">0</div>
<div class="stat-label">Completed</div>
</div>
<div class="stat-icon green">
<i class="fas fa-check-circle"></i>
</div>
</div>
</div>
<div class="stat-card">
<div class="stat-header">
<div>
<div class="stat-value" id="pendingTasks">0</div>
<div class="stat-label">Pending</div>
</div>
<div class="stat-icon yellow">
<i class="fas fa-clock"></i>
</div>
</div>
</div>
<div class="stat-card">
<div class="stat-header">
<div>
<div class="stat-value" id="completionRate">0%</div>
<div class="stat-label">Completion Rate</div>
</div>
<div class="stat-icon red">
<i class="fas fa-chart-line"></i>
</div>
</div>
</div>
</div>
<div class="main-content">
<aside class="sidebar">
<div class="add-task-form">
<h3 style="margin-bottom: 20px; color: var(--dark);">Add New Task</h3>
<div class="form-group">
<label>Task Title</label>
<input type="text" class="form-control" id="taskTitle" placeholder="Enter task title...">
</div>
<div class="form-group">
<label>Description</label>
<input type="text" class="form-control" id="taskDescription" placeholder="Enter description...">
</div>
<div class="form-group">
<label>Priority</label>
<div class="priority-select">
<button class="priority-btn" data-priority="low" onclick="selectPriority(this)">Low</button>
<button class="priority-btn" data-priority="medium" onclick="selectPriority(this)">Medium</button>
<button class="priority-btn" data-priority="high" onclick="selectPriority(this)">High</button>
</div>
</div>
<div class="form-group">
<label>Category</label>
<div class="category-select">
<button class="category-btn" data-category="work" onclick="selectCategory(this)">Work</button>
<button class="category-btn" data-category="personal" onclick="selectCategory(this)">Personal</button>
<button class="category-btn" data-category="shopping" onclick="selectCategory(this)">Shopping</button>
<button class="category-btn" data-category="health" onclick="selectCategory(this)">Health</button>
</div>
</div>
<div class="form-group">
<label>Due Date</label>
<input type="date" class="form-control" id="taskDate">
</div>
<button class="btn-primary" onclick="addTask()">
<i class="fas fa-plus"></i> Add Task
</button>
</div>
</aside>
<main class="tasks-container">
<div class="tasks-header">
<h3 style="color: var(--dark);">Tasks</h3>
<div class="search-box">
<i class="fas fa-search"></i>
<input type="text" placeholder="Search tasks..." id="searchInput" onkeyup="searchTasks()">
</div>
<div class="filter-tabs">
<button class="filter-tab active" onclick="filterTasks('all', this)">All</button>
<button class="filter-tab" onclick="filterTasks('pending', this)">Pending</button>
<button class="filter-tab" onclick="filterTasks('completed', this)">Completed</button>
</div>
</div>
<div class="tasks-list" id="tasksList">
<div class="empty-state">
<i class="fas fa-inbox"></i>
<h3>No tasks yet</h3>
<p>Add your first task to get started!</p>
</div>
</div>
</main>
</div>
<div class="chart-container">
<h3 class="chart-header">Task Distribution by Category</h3>
<div class="chart-bars" id="chartBars">
<!-- Chart bars will be generated dynamically -->
</div>
</div>
</div>
<div class="toast" id="toast">
<div class="toast-icon" id="toastIcon">
<i class="fas fa-check"></i>
</div>
<div class="toast-message" id="toastMessage">Task added successfully!</div>
</div>
<script>
// Initialize app
let tasks = JSON.parse(localStorage.getItem('tasks')) || [];
let selectedPriority = 'medium';
let selectedCategory = 'work';
let currentFilter = 'all';
// Initialize theme
if (localStorage.getItem('darkMode') === 'true') {
document.body.classList.add('dark-mode');
document.getElementById('themeIcon').className = 'fas fa-sun';
}
// Initialize with sample tasks if empty
if (tasks.length === 0) {
tasks = [
{
id: Date.now(),
title: 'Welcome to TaskFlow Pro!',
description: 'Start organizing your tasks efficiently',
priority: 'high',
category: 'personal',
date: getDateTomorrow(),
completed: false
},
{
id: Date.now() + 1,
title: 'Complete project documentation',
description: 'Write comprehensive docs for the new feature',
priority: 'medium',
category: 'work',
date: getDateAfterDays(3),
completed: false
},
{
id: Date.now() + 2,
title: 'Buy groceries',
description: 'Milk, bread, eggs, and vegetables',
priority: 'low',
category: 'shopping',
date: getDateTomorrow(),
completed: false
}
];
saveTasks();
}
function getDateTomorrow() {
const date = new Date();
date.setDate(date.getDate() + 1);
return date.toISOString().split('T')[0];
}
function getDateAfterDays(days) {
const date = new Date();
date.setDate(date.getDate() + days);
return date.toISOString().split('T')[0];
}
function toggleTheme() {
document.body.classList.toggle('dark-mode');
const isDark = document.body.classList.contains('dark-mode');
localStorage.setItem('darkMode', isDark);
document.getElementById('themeIcon').className = isDark ? 'fas fa-sun' : 'fas fa-moon';
}
function selectPriority(btn) {
document.querySelectorAll('.priority-btn').forEach(b => b.classList.remove('active', 'low', 'medium', 'high'));
btn.classList.add('active', btn.dataset.priority);
selectedPriority = btn.dataset.priority;
}
function selectCategory(btn) {
document.querySelectorAll('.category-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
selectedCategory = btn.dataset.category;
}
function addTask() {
const title = document.getElementById('taskTitle').value.trim();
const description = document.getElementById('taskDescription').value.trim();
const date = document.getElementById('taskDate').value;
if (!title) {
showToast('Please enter a task title', 'error');
return;
}
const task = {
id: Date.now(),
title,
description,
priority: selectedPriority,
category: selectedCategory,
date: date || getDateTomorrow(),
completed: false
};
tasks.unshift(task);
saveTasks();
renderTasks();
updateStats();
updateChart();
clearForm();
showToast('Task added successfully!', 'success');
}
function clearForm() {
document.getElementById('taskTitle').value = '';
document.getElementById('taskDescription').value = '';
document.getElementById('taskDate').value = '';
document.querySelectorAll('.priority-btn').forEach(b => b.classList.remove('active', 'low', 'medium', 'high'));
document.querySelectorAll('.category-btn').forEach(b => b.classList.remove('active'));
selectedPriority = 'medium';
selectedCategory = 'work';
}
function toggleTask(id) {
const task = tasks.find(t => t.id === id);
if (task) {
task.completed = !task.completed;
saveTasks();
renderTasks();
updateStats();
updateChart();
showToast(task.completed ? 'Task completed!' : 'Task marked as pending', 'info');
}
}
function deleteTask(id) {
tasks = tasks.filter(t => t.id !== id);
saveTasks();
renderTasks();
updateStats();
updateChart();
showToast('Task deleted', 'success');
}
function editTask(id) {
const task = tasks.find(t => t.id === id);
if (task) {
document.getElementById('taskTitle').value = task.title;
document.getElementById('taskDescription').value = task.description;
document.getElementById('taskDate').value = task.date;
document.querySelectorAll('.priority-btn').forEach(b => {
b.classList.remove('active', 'low', 'medium', 'high');
if (b.dataset.priority === task.priority) {
b.classList.add('active', task.priority);
selectedPriority = task.priority;
}
});
document.querySelectorAll('.category-btn').forEach(b => {
b.classList.remove('active');
if (b.dataset.category === task.category) {
b.classList.add('active');
selectedCategory = task.category;
}
});
deleteTask(id);
}
}
function searchTasks() {
const searchTerm = document.getElementById('searchInput').value.toLowerCase();
const filteredTasks = tasks.filter(task => {
const matchesSearch = task.title.toLowerCase().includes(searchTerm) ||
task.description.toLowerCase().includes(searchTerm);
const matchesFilter = currentFilter === 'all' ||
(currentFilter === 'completed' && task.completed) ||
(currentFilter === 'pending' && !task.completed);
return matchesSearch && matchesFilter;
});
renderFilteredTasks(filteredTasks);
}
function filterTasks(filter, btn) {
currentFilter = filter;
document.querySelectorAll('.filter-tab').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
searchTasks();
}
function renderFilteredTasks(filteredTasks) {
const tasksList = document.getElementById('tasksList');
if (filteredTasks.length === 0) {
tasksList.innerHTML = `
<div class="empty-state">
<i class="fas fa-inbox"></i>
<h3>No tasks found</h3>
<p>${currentFilter === 'all' ? 'Add your first task to get started!' : 'No tasks match your filter'}</p>
</div>
`;
return;
}
tasksList.innerHTML = filteredTasks.map(task => `
<div class="task-item ${task.completed ? 'completed' : ''}" draggable="true" ondragstart="drag(event)" ondragover="allowDrop(event)" ondrop="drop(event, ${task.id})">
<div class="task-header">
<div class="task-title">${task.title}</div>
<div class="task-actions">
<button class="task-btn" onclick="toggleTask(${task.id})">
<i class="fas ${task.completed ? 'fa-undo' : 'fa-check'}"></i>
</button>
<button class="task-btn" onclick="editTask(${task.id})">
<i class="fas fa-edit"></i>
</button>
<button class="task-btn" onclick="deleteTask(${task.id})">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
${task.description ? `<p style="color: var(--gray); font-size: 14px; margin-bottom: 10px;">${task.description}</p>` : ''}
<div class="task-meta">
<span class="task-priority priority-${task.priority}">${task.priority.toUpperCase()}</span>
<span class="task-category">${task.category}</span>
<div class="task-date">
<i class="far fa-calendar"></i>
<span>${formatDate(task.date)}</span>
</div>
</div>
<div class="progress-bar">
<div class="progress-fill" style="width: ${task.completed ? '100' : '0'}%"></div>
</div>
</div>
`).join('');
}
function renderTasks() {
searchTasks();
}
function formatDate(dateString) {
const date = new Date(dateString);
const today = new Date();
const tomorrow = new Date(today);
tomorrow.setDate(tomorrow.getDate() + 1);
if (date.toDateString() === today.toDateString()) {
return 'Today';
} else if (date.toDateString() === tomorrow.toDateString()) {
return 'Tomorrow';
} else {
return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
}
}
function updateStats() {
const total = tasks.length;
const completed = tasks.filter(t => t.completed).length;
const pending = total - completed;
const rate = total > 0 ? Math.round((completed / total) * 100) : 0;
document.getElementById('totalTasks').textContent = total;
document.getElementById('completedTasks').textContent = completed;
document.getElementById('pendingTasks').textContent = pending;
document.getElementById('completionRate').textContent = rate + '%';
}
function updateChart() {
const categories = ['work', 'personal', 'shopping', 'health'];
const chartBars = document.getElementById('chartBars');
const categoryCounts = categories.map(category =>
tasks.filter(t => t.category === category).length
);
const maxCount = Math.max(...categoryCounts, 1);
chartBars.innerHTML = categories.map((category, index) => {
const count = categoryCounts[index];
const height = (count / maxCount) * 100;
return `
<div class="chart-bar">
<div class="bar" style="height: ${height}%">
<span class="bar-value">${count}</span>
</div>
<span class="bar-label">${category.charAt(0).toUpperCase() + category.slice(1)}</span>
</div>
`;
}).join('');
}
function saveTasks() {
localStorage.setItem('tasks',