anycoder-82d8a085 / index.html
akhaliq's picture
akhaliq HF Staff
Upload folder using huggingface_hub
b9f61aa verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PokéDex Tasks - Pokémon Todo Manager</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=VT323&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--poke-red: #FF0000;
--poke-blue: #3B4CCA;
--poke-yellow: #FFDE00;
--poke-black: #000000;
--poke-white: #FFFFFF;
--poke-gray: #9E9E9E;
--poke-light-gray: #F5F5F5;
--poke-dark-gray: #424242;
--poke-grass: #78C850;
--poke-fire: #F08030;
--poke-water: #6890F0;
--poke-electric: #F8D030;
--poke-psychic: #F85888;
--poke-ice: #98D8D8;
--poke-dragon: #7038F8;
--poke-dark: #705848;
--poke-fairy: #EE99AC;
--poke-normal: #A8A878;
--poke-poison: #A040A0;
--poke-ground: #E0C068;
--poke-flying: #A890F0;
--poke-bug: #A8B820;
--poke-rock: #B8A038;
--poke-ghost: #705898;
--poke-steel: #B8B8D0;
--poke-fighting: #C03028;
--background: linear-gradient(135deg, #FFE5E5 0%, #E5F3FF 50%, #FFFACD 100%);
--surface: rgba(255, 255, 255, 0.95);
--surface-hover: rgba(255, 255, 255, 1);
--text-primary: var(--poke-black);
--text-secondary: var(--poke-dark-gray);
--text-tertiary: var(--poke-gray);
--border-color: var(--poke-gray);
--shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.1);
--shadow-md: 0 4px 8px rgba(0, 0, 0, 0.15);
--shadow-lg: 0 8px 16px rgba(0, 0, 0, 0.2);
--shadow-xl: 0 12px 24px rgba(0, 0, 0, 0.25);
--blur-sm: 10px;
--blur-md: 20px;
--radius-sm: 8px;
--radius-md: 12px;
--radius-lg: 20px;
--radius-xl: 30px;
--transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
body {
font-family: 'VT323', monospace;
background: var(--background);
min-height: 100vh;
color: var(--text-primary);
position: relative;
overflow-x: hidden;
font-size: 18px;
line-height: 1.6;
}
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image:
radial-gradient(circle at 20% 20%, rgba(255, 0, 0, 0.1) 0%, transparent 50%),
radial-gradient(circle at 80% 80%, rgba(59, 76, 202, 0.1) 0%, transparent 50%),
radial-gradient(circle at 50% 50%, rgba(255, 222, 0, 0.05) 0%, transparent 50%);
animation: pokeFloat 25s ease-in-out infinite;
z-index: -1;
}
@keyframes pokeFloat {
0%,
100% {
transform: translate(0, 0) rotate(0deg);
}
25% {
transform: translate(-20px, 20px) rotate(1deg);
}
50% {
transform: translate(20px, -20px) rotate(-1deg);
}
75% {
transform: translate(-10px, -10px) rotate(0.5deg);
}
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
header {
text-align: center;
margin-bottom: 3rem;
animation: pikachuEntry 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
@keyframes pikachuEntry {
from {
opacity: 0;
transform: translateY(-50px) scale(0.8);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
.header-content {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1.5rem;
}
.logo {
font-family: 'Press Start 2P', cursive;
font-size: 2rem;
background: linear-gradient(135deg, var(--poke-red), var(--poke-blue));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
display: flex;
align-items: center;
gap: 1rem;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
}
.logo i {
font-size: 2.5rem;
background: linear-gradient(135deg, var(--poke-yellow), var(--poke-red));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
animation: pokeballSpin 3s linear infinite;
}
@keyframes pokeballSpin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.theme-toggle {
background: var(--surface);
border: 3px solid var(--poke-black);
border-radius: 50%;
width: 60px;
height: 60px;
cursor: pointer;
transition: var(--transition);
color: var(--poke-black);
font-size: 1.5rem;
box-shadow: var(--shadow-md);
position: relative;
overflow: hidden;
}
.theme-toggle::before {
content: '';
position: absolute;
top: 50%;
left: 0;
right: 0;
height: 3px;
background: var(--poke-black);
transform: translateY(-50%);
}
.theme-toggle:hover {
transform: scale(1.1) rotate(10deg);
box-shadow: var(--shadow-lg);
}
.theme-toggle:active {
transform: scale(0.95) rotate(-5deg);
}
.stats-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
margin-bottom: 2rem;
animation: pokeSlideIn 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55) 0.2s both;
}
@keyframes pokeSlideIn {
from {
opacity: 0;
transform: translateX(-30px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.stat-card {
background: var(--surface);
border: 3px solid var(--poke-black);
border-radius: var(--radius-lg);
padding: 1.5rem;
text-align: center;
transition: var(--transition);
box-shadow: var(--shadow-md);
position: relative;
overflow: hidden;
}
.stat-card::before {
content: '';
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
background: linear-gradient(45deg, var(--poke-red), var(--poke-blue), var(--poke-yellow));
border-radius: var(--radius-lg);
z-index: -1;
opacity: 0;
transition: opacity 0.3s;
}
.stat-card:hover::before {
opacity: 1;
}
.stat-card:hover {
transform: translateY(-5px) scale(1.05);
box-shadow: var(--shadow-xl);
background: var(--surface-hover);
}
.stat-number {
font-family: 'Press Start 2P', cursive;
font-size: 2rem;
margin-bottom: 0.5rem;
background: linear-gradient(135deg, var(--poke-red), var(--poke-blue));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.stat-label {
font-size: 1.2rem;
color: var(--text-secondary);
font-weight: bold;
text-transform: uppercase;
}
.main-content {
display: grid;
grid-template-columns: 1fr 300px;
gap: 2rem;
animation: pokeFadeIn 1s cubic-bezier(0.68, -0.55, 0.265, 1.55) 0.4s both;
}
@keyframes pokeFadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.todo-section {
background: var(--surface);
border: 3px solid var(--poke-black);
border-radius: var(--radius-xl);
padding: 2rem;
box-shadow: var(--shadow-lg);
position: relative;
}
.todo-section::before {
content: '';
position: absolute;
top: 10px;
left: 10px;
right: 10px;
bottom: 10px;
border: 2px dashed var(--poke-gray);
border-radius: var(--radius-lg);
pointer-events: none;
}
.add-todo-form {
display: flex;
gap: 1rem;
margin-bottom: 2rem;
}
.todo-input-group {
flex: 1;
display: flex;
gap: 0.75rem;
}
.todo-input {
flex: 1;
background: var(--poke-light-gray);
border: 3px solid var(--poke-black);
border-radius: var(--radius-lg);
padding: 0.875rem 1.25rem;
font-size: 1.2rem;
color: var(--text-primary);
transition: var(--transition);
font-weight: bold;
}
.todo-input::placeholder {
color: var(--poke-gray);
}
.todo-input:focus {
outline: none;
background: var(--poke-white);
border-color: var(--poke-blue);
box-shadow: 0 0 0 3px var(--poke-yellow);
transform: scale(1.02);
}
.priority-select,
.category-select {
background: var(--poke-light-gray);
border: 3px solid var(--poke-black);
border-radius: var(--radius-lg);
padding: 0.75rem 1rem;
color: var(--text-primary);
cursor: pointer;
transition: var(--transition);
font-weight: bold;
min-width: 120px;
font-size: 1.1rem;
}
.priority-select:focus,
.category-select:focus {
outline: none;
background: var(--poke-white);
border-color: var(--poke-blue);
box-shadow: 0 0 0 3px var(--poke-yellow);
transform: scale(1.02);
}
.add-btn {
background: linear-gradient(135deg, var(--poke-red), var(--poke-yellow));
border: 3px solid var(--poke-black);
border-radius: var(--radius-lg);
padding: 0.875rem 1.75rem;
color: var(--poke-white);
font-weight: bold;
cursor: pointer;
transition: var(--transition);
display: flex;
align-items: center;
gap: 0.5rem;
box-shadow: var(--shadow-md);
font-size: 1.1rem;
text-transform: uppercase;
position: relative;
overflow: hidden;
}
.add-btn::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
background: rgba(255, 255, 255, 0.3);
border-radius: 50%;
transform: translate(-50%, -50%);
transition: width 0.6s, height 0.6s;
}
.add-btn:hover::before {
width: 300px;
height: 300px;
}
.add-btn:hover {
transform: translateY(-3px) scale(1.05);
box-shadow: var(--shadow-xl);
}
.add-btn:active {
transform: translateY(-1px) scale(1.02);
}
.search-bar {
background: var(--poke-light-gray);
border: 3px solid var(--poke-black);
border-radius: var(--radius-lg);
padding: 0.875rem 1.25rem;
margin-bottom: 1.5rem;
display: flex;
align-items: center;
gap: 1rem;
color: var(--text-secondary);
transition: var(--transition);
}
.search-bar:focus-within {
border-color: var(--poke-blue);
box-shadow: 0 0 0 3px var(--poke-yellow);
transform: scale(1.01);
}
.search-input {
flex: 1;
background: transparent;
border: none;
color: var(--text-primary);
font-size: 1.2rem;
font-weight: bold;
}
.search-input::placeholder {
color: var(--poke-gray);
}
.search-input:focus {
outline: none;
}
.filter-tabs {
display: flex;
gap: 0.5rem;
margin-bottom: 2rem;
flex-wrap: wrap;
}
.filter-tab {
background: var(--poke-light-gray);
border: 3px solid var(--poke-black);
border-radius: var(--radius-md);
padding: 0.625rem 1.25rem;
color: var(--text-secondary);
cursor: pointer;
transition: var(--transition);
font-size: 1.1rem;
font-weight: bold;
text-transform: uppercase;
position: relative;
}
.filter-tab:hover {
background: var(--poke-white);
transform: translateY(-2px);
box-shadow: var(--shadow-md);
}
.filter-tab.active {
background: linear-gradient(135deg, var(--poke-blue), var(--poke-yellow));
color: var(--poke-white);
border-color: var(--poke-black);
box-shadow: var(--shadow-lg);
transform: scale(1.05);
}
.todo-list {
max-height: 500px;
overflow-y: auto;
padding-right: 0.5rem;
}
.todo-list::-webkit-scrollbar {
width: 8px;
}
.todo-list::-webkit-scrollbar-track {
background: var(--poke-light-gray);
border-radius: var(--radius-sm);
}
.todo-list::-webkit-scrollbar-thumb {
background: var(--poke-red);
border-radius: var(--radius-sm);
transition: var(--transition);
}
.todo-list::-webkit-scrollbar-thumb:hover {
background: var(--poke-blue);
}
.todo-item {
background: var(--poke-light-gray);
border: 3px solid var(--poke-black);
border-radius: var(--radius-lg);
padding: 1.25rem;
margin-bottom: 0.75rem;
display: flex;
align-items: center;
gap: 1rem;
transition: var(--transition);
cursor: move;
animation: pokeTaskAppear 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
box-shadow: var(--shadow-sm);
position: relative;
overflow: hidden;
}
.todo-item::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 222, 0, 0.3), transparent);
transition: left 0.5s;
}
.todo-item:hover::before {
left: 100%;
}
@keyframes pokeTaskAppear {
from {
opacity: 0;
transform: translateX(-20px) rotate(-5deg);
}
to {
opacity: 1;
transform: translateX(0) rotate(0);
}
}
.todo-item:hover {
background: var(--poke-white);
transform: translateX(5px) scale(1.02);
box-shadow: var(--shadow-lg);
}
.todo-item.dragging {
opacity: 0.5;
transform: rotate(5deg) scale(0.95);
}
.todo-item.completed {
opacity: 0.7;
background: var(--poke-gray);
}
.todo-item.completed .todo-text {
text-decoration: line-through;
color: var(--poke-dark-gray);
}
.todo-checkbox {
width: 30px;
height: 30px;
border: 3px solid var(--poke-black);
border-radius: 50%;
cursor: pointer;
transition: var(--transition);
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
position: relative;
background: var(--poke-white);
}
.todo-checkbox:hover {
border-color: var(--poke-blue);
transform: scale(1.1);
}
.todo-checkbox.checked {
background: linear-gradient(135deg, var(--poke-grass), var(--poke-water));
border-color: var(--poke-black);
animation: pokeballCatch 0.5s ease-out;
}
@keyframes pokeballCatch {
0% {
transform: scale(1) rotate(0deg);
}
25% {
transform: scale(1.3) rotate(90deg);
}
50% {
transform: scale(0.8) rotate(180deg);
}
75% {
transform: scale(1.1) rotate(270deg);
}
100% {
transform: scale(1) rotate(360deg);
}
}
.todo-checkbox.checked::after {
content: '⚡';
color: var(--poke-yellow);
font-weight: bold;
font-size: 18px;
}
.todo-content {
flex: 1;
}
.todo-text {
color: var(--text-primary);
font-size: 1.2rem;
margin-bottom: 0.5rem;
word-break: break-word;
font-weight: bold;
}
.todo-meta {
display: flex;
gap: 0.75rem;
align-items: center;
flex-wrap: wrap;
}
.todo-date,
.todo-category {
font-size: 1rem;
color: var(--text-secondary);
display: flex;
align-items: center;
gap: 0.25rem;
font-weight: bold;
}
.priority-badge {
padding: 0.25rem 0.625rem;
border-radius: var(--radius-sm);
font-size: 0.9rem;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
border: 2px solid var(--poke-black);
}
.priority-high {
background: linear-gradient(135deg, var(--poke-fire), var(--poke-dragon));
color: var(--poke-white);
}
.priority-medium {
background: linear-gradient(135deg, var(--poke-electric), var(--poke-fighting));
color: var(--poke-white);
}
.priority-low {
background: linear-gradient(135deg, var(--poke-normal), var(--poke-grass));
color: var(--poke-white);
}
.todo-actions {
display: flex;
gap: 0.5rem;
}
.action-btn {
background: var(--poke-light-gray);
border: 2px solid var(--poke-black);
border-radius: var(--radius-md);
padding: 0.5rem;
color: var(--text-secondary);
cursor: pointer;
transition: var(--transition);
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
}
.action-btn:hover {
background: var(--poke-white);
color: var(--text-primary);
transform: scale(1.2) rotate(5deg);
}
.action-btn.delete:hover {
background: var(--poke-fire);
color: var(--poke-white);
border-color: var(--poke-fire);
transform: scale(1.2) rotate(-5deg);
}
.sidebar {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.sidebar-card {
background: var(--surface);
border: 3px solid var(--poke-black);
border-radius: var(--radius-lg);
padding: 1.5rem;
box-shadow: var(--shadow-md);
position: relative;
overflow: hidden;
}
.sidebar-card::after {
content: '';
position: absolute;
top: -50%;
right: -50%;
width: 100%;
height: 100%;
background: radial-gradient(circle, var(--poke-yellow) 0%, transparent 70%);
opacity: 0.1;
animation: pokeGlow 3s ease-in-out infinite;
}
@keyframes pokeGlow {
0%,
100% {
transform: scale(1);
opacity: 0.1;
}
50% {
transform: scale(1.2);
opacity: 0.2;
}
}
.sidebar-title {
font-family: 'Press Start 2P', cursive;
font-size: 1rem;
font-weight: bold;
margin-bottom: 1rem;
color: var(--poke-red);
text-transform: uppercase;
}
.progress-bar {
background: var(--poke-light-gray);
border: 2px solid var(--poke-black);
border-radius: var(--radius-sm);
height: 12px;
overflow: hidden;
margin-bottom: 1rem;
position: relative;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--poke-grass), var(--poke-water), var(--poke-electric));
transition: width 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
position: relative;
overflow: hidden;
}
.progress-fill::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
animation: progressShine 2s linear infinite;
}
@keyframes progressShine {
from {
transform: translateX(-100%);
}
to {
transform: translateX(100%);
}
}
.category-list {
display: flex;
flex-direction: column;
gap: 0.625rem;
}
.category-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.75rem;
border-radius: var(--radius-md);
transition: var(--transition);
border: 2px solid transparent;
}
.category-item:hover {
background: var(--poke-light-gray);
border-color: var(--poke-yellow);
transform: translateX(5px);
}
.category-item span:first-child {
display: flex;
align-items: center;
gap: 0.5rem;
color: var(--text-secondary);
font-weight: bold;
}
.category-item span:last-child {
color: var(--poke-blue);
font-weight: bold;
font-size: 1.2rem;
}
.clear-btn {
background: linear-gradient(135deg, var(--poke-fire), var(--poke-dragon));
border: 3px solid var(--poke-black);
border-radius: var(--radius-lg);
padding: 0.875rem 1.5rem;
color: var(--poke-white);
font-weight: bold;
cursor: pointer;
transition: var(--transition);
width: 100%;
margin-top: 1rem;
box-shadow: var(--shadow-md);
font-size: 1.1rem;
text-transform: uppercase;
position: relative;
overflow: hidden;
}
.clear-btn::before {
content: '🔥';
position: absolute;
top: 50%;
left: -20px;
transform: translateY(-50%);
font-size: 1.5rem;
transition: left 0.3s;
}
.clear-btn:hover::before {
left: 10px;
}
.clear-btn:hover {
transform: translateY(-3px) scale(1.05);
box-shadow: var(--shadow-xl);
}
.clear-btn:active {
transform: translateY(-1px) scale(1.02);
}
.empty-state {
text-align: center;
padding: 3rem;
color: var(--text-tertiary);
}
.empty-state i {
font-size: 4rem;
margin-bottom: 1rem;
opacity: 0.5;
color: var(--poke-blue);
}
.empty-state p {
font-weight: bold;
font-size: 1.3rem;
text-transform: uppercase;
}
.edit-input {
background: var(--poke-white);
border: 3px solid var(--poke-blue);
border-radius: var(--radius-md);
padding: 0.5rem;
color: var(--text-primary);
font-size: 1.2rem;
width: 100%;
font-weight: bold;
box-shadow: 0 0 0 3px var(--poke-yellow);
}
.edit-input:focus {
outline: none;
background: var(--poke-light-gray);
}
@media (max-width: 768px) {
.container {
padding: 1rem;
}
.main-content {
grid-template-columns: 1fr;
}
.stats-container {
grid-template-columns: repeat(2, 1fr);
}
.add-todo-form {
flex-direction: column;
}
.todo-input-group {
flex-direction: column;
}
.filter-tabs {
justify-content: center;
}
.logo {
font-size: 1.5rem;
}
}
@media (max-width: 480px) {
.stats-container {
grid-template-columns: 1fr;
}
}
.toast {
position: fixed;
bottom: 2rem;
right: 2rem;
background: var(--poke-white);
color: var(--text-primary);
padding: 1rem 1.5rem;
border-radius: var(--radius-lg);
box-shadow: var(--shadow-xl);
border: 3px solid var(--poke-black);
transform: translateX(400px);
transition: transform 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
z-index: 1000;
display: flex;
align-items: center;
gap: 1rem;
font-weight: bold;
}
.toast.show {
transform: translateX(0);
animation: toastBounce 0.5s ease-out;
}
@keyframes toastBounce {
0% {
transform: translateX(0) scale(0.8);
}
50% {
transform: translateX(0) scale(1.1);
}
100% {
transform: translateX(0) scale(1);
}
}
.toast i {
font-size: 1.5rem;
color: var(--poke-yellow);
animation: toastIcon 0.5s ease-out;
}
@keyframes toastIcon {
0% {
transform: scale(0) rotate(0deg);
}
50% {
transform: scale(1.3) rotate(180deg);
}
100% {
transform: scale(1) rotate(360deg);
}
}
.anycoder-link {
color: var(--poke-blue);
text-decoration: none;
font-size: 1rem;
opacity: 0.8;
transition: var(--transition);
font-weight: bold;
display: inline-block;
margin-top: 1rem;
padding: 0.5rem 1rem;
border: 2px solid var(--poke-blue);
border-radius: var(--radius-md);
}
.anycoder-link:hover {
color: var(--poke-yellow);
background: var(--poke-blue);
transform: scale(1.05);
opacity: 1;
}
#dueDateInput {
min-width: auto;
font-weight: bold;
}
.quick-stats-item {
display: flex;
justify-content: space-between;
padding: 0.5rem 0;
border-bottom: 2px solid var(--poke-gray);
}
.quick-stats-item:last-child {
border-bottom: none;
}
.quick-stats-label {
color: var(--text-secondary);
font-size: 1.1rem;
font-weight: bold;
}
.quick-stats-value {
color: var(--poke-red);
font-weight: bold;
font-size: 1.3rem;
}
/* Pokémon Type Colors for Categories */
.type-personal {
background: var(--poke-psychic);
}
.type-work {
background: var(--poke-steel);
}
.type-shopping {
background: var(--poke-poison);
}
.type-health {
background: var(--poke-grass);
}
.type-other {
background: var(--poke-normal);
}
</style>
</head>
<body>
<div class="container">
<header>
<div class="header-content">
<div class="logo">
<i class="fas fa-circle-notch"></i>
PokéDex Tasks
</div>
<button class="theme-toggle" onclick="toggleTheme()">
<i class="fas fa-star" id="themeIcon"></i>
</button>
</div>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" class="anycoder-link">
⚡ Built with anycoder ⚡
</a>
</header>
<div class="stats-container">
<div class="stat-card">
<div class="stat-number" id="totalTasks">0</div>
<div class="stat-label">Total Tasks</div>
</div>
<div class="stat-card">
<div class="stat-number" id="completedTasks">0</div>
<div class="stat-label">Caught</div>
</div>
<div class="stat-card">
<div class="stat-number" id="pendingTasks">0</div>
<div class="stat-label">Wild</div>
</div>
<div class="stat-card">
<div class="stat-number" id="completionRate">0%</div>
<div class="stat-label">Caught Rate</div>
</div>
</div>
<div class="main-content">
<div class="todo-section">
<form class="add-todo-form" onsubmit="addTodo(event)">
<div class="todo-input-group">
<input type="text" class="todo-input" id="todoInput" placeholder="What Pokémon to catch?" required>
<select class="priority-select" id="prioritySelect">
<option value="low">Common</option>
<option value="medium" selected>Rare</option>
<option value="high">Legendary</option>
</select>
<select class="category-select" id="categorySelect">
<option value="personal">Psychic</option>
<option value="work">Steel</option>
<option value="shopping">Poison</option>
<option value="health">Grass</option>
<option value="other">Normal</option>
</select>
<input type="date" class="priority-select" id="dueDateInput" style="width: auto;">
</div>
<button type="submit" class="add-btn">
<i class="fas fa-plus"></i>
Catch Task
</button>
</form>
<div class="search-bar">
<i class="fas fa-search"></i>
<input type="text" class="search-input" id="searchInput" placeholder="Search PokéTasks..." oninput="searchTodos()">
</div>
<div class="filter-tabs">
<button class="filter-tab active" onclick="filterTodos('all')">All</button>
<button class="filter-tab" onclick="filterTodos('active')">Wild</button>
<button class="filter-tab" onclick="filterTodos('completed')">Caught</button>
<button class="filter-tab" onclick="filterTodos('today')">Today</button>
<button class="filter-tab" onclick="filterTodos('high')">Legendary</button>
</div>
<div class="todo-list" id="todoList">
<div class="empty-state">
<i class="fas fa-dragon"></i>
<p>No PokéTasks yet!</p>
</div>
</div>
<button class="clear-btn" onclick="clearCompleted()" style="display: none;" id="clearBtn">
Release Caught
</button>
</div>
<div class="sidebar">
<div class="sidebar-card">
<h3 class="sidebar-title">Catch Progress</h3>
<div class="progress-bar">
<div class="progress-fill" id="progressFill" style="width: 0%"></div>
</div>
<p style="font-size: 1.1rem; color: var(--text-secondary); font-weight: bold;">
<span id="progressText">0</span>% PokéDex Complete
</p>
</div>
<div class="sidebar-card">
<h3 class="sidebar-title">PokéTypes</h3>
<div class="category-list" id="categoryList">
<div class="category-item">
<span><i class="fas fa-brain"></i> Psychic</span>
<span id="personalCount">0</span>
</div>
<div class="category-item">
<span><i class="fas fa-shield-alt"></i> Steel</span>
<span id="workCount">0</span>
</div>
<div class="category-item">
<span><i class="fas fa-skull"></i> Poison</span>
<span id="shoppingCount">0</span>
</div>
<div class="category-item">
<span><i class="fas fa-leaf"></i> Grass</span>
<span id="healthCount">0</span>
</div>
<div class="category-item">
<span><i class="fas fa-dove"></i> Normal</span>
<span id="otherCount">0</span>
</div>
</div>
</div>
<div class="sidebar-card">
<h3 class="sidebar-title">Quick Stats</h3>
<div style="display: flex; flex-direction: column; gap: 0;">
<div class="quick-stats-item">
<span class="quick-stats-label">Tasks today</span>
<span class="quick-stats-value" id="todayCount">0</span>
</div>
<div class="quick-stats-item">
<span class="quick-stats-label">Escaped!</span>
<span class="quick-stats-value" id="overdueCount">0</span>
</div>
<div class="quick-stats-item">
<span class="quick-stats-label">Legendary</span>
<span class="quick-stats-value" id="highPriorityCount">0</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="toast" id="toast">
<i class="fas fa-star"></i>
<span id="toastMessage">PokéTask caught!</span>
</div>
<script>
let todos = JSON.parse(localStorage.getItem('todos')) || [];
let currentFilter = 'all';
let draggedItem = null;
// Initialize
document.addEventListener('DOMContentLoaded', () => {
renderTodos();
updateStats();
// Set today's date as default
const today = new Date().toISOString().split('T')[0];
document.getElementById('dueDateInput').value = today;
// Check for saved theme preference
if (localStorage.getItem('theme') === 'dark') {
document.body.style.filter = 'invert(1) hue-rotate(180deg)';
document.getElementById('themeIcon').className = 'fas fa-moon';
}
});
function addTodo(event) {
event.preventDefault();
const input = document.getElementById('todoInput');
const priority = document.getElementById('prioritySelect').value;
const category = document.getElementById('categorySelect').value;
const dueDate = document.getElementById('dueDateInput').value;
const todo = {
id: Date.now(),
text: input.value,
completed: false,
priority: priority,
category: category,
dueDate: dueDate,
createdAt: new Date().toISOString()
};
todos.unshift(todo);
saveTodos();
renderTodos();
updateStats();
input.value = '';
showToast('PokéTask caught successfully!');
// Reset date to today
const today = new Date().toISOString().split('T')[0];
document.getElementById('dueDateInput').value = today;
}
function toggleTodo(id) {
const todo = todos.find(t => t.id === id);
if (todo) {
todo.completed = !todo.completed;
saveTodos();
renderTodos();
updateStats();
showToast(todo.completed ? 'PokéTask caught! ⚡' : 'PokéTask released!');
}
}
function deleteTodo(id) {
todos = todos.filter(t => t.id !== id);
saveTodos();
renderTodos();
updateStats();
showToast('PokéTask vanished!');
}
function editTodo(id) {
const todo = todos.find(t => t.id === id);
const todoElement = document.querySelector(`[data-id="${id}"]`);
const textElement = todoElement.querySelector('.todo-text');
const input = document.createElement('input');
input.type = 'text';
input.className = 'edit-input';
input.value = todo.text;
textElement.replaceWith(input);
input.focus();
input.select();
const saveEdit = () => {
if (input.value.trim()) {
todo.text = input.value;
saveTodos();
renderTodos();
showToast('PokéTask evolved!');
} else {
renderTodos();
}
};
input.addEventListener('blur', saveEdit);
input.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
saveEdit();
}
});
}
function filterTodos(filter) {
currentFilter = filter;
// Update active tab
document.querySelectorAll('.filter-tab').forEach(tab => {
tab.classList.remove('active');
});
event.target.classList.add('active');
renderTodos();
}
function searchTodos() {
const searchTerm = document.getElementById('searchInput').value.toLowerCase();
renderTodos(searchTerm);
}
function clearCompleted() {
const completedCount = todos.filter(t => t.completed).length;
todos = todos.filter(t => !t.completed);
saveTodos();
renderTodos();
updateStats();
showToast(`Released ${completedCount} caught PokéTasks!`);
}
function renderTodos(searchTerm = '') {
const todoList = document.getElementById('todoList');
let filteredTodos = [...todos];
// Apply filter
if (currentFilter === 'active') {
filteredTodos = filteredTodos.filter(t => !t.completed);
} else if (currentFilter === 'completed') {
filteredTodos = filteredTodos.filter(t => t.completed);
} else if (currentFilter === 'today') {
const today = new Date().toISOString().split('T')[0];
filteredTodos = filteredTodos.filter(t => t.dueDate === today);
} else if (currentFilter === 'high') {
filteredTodos = filteredTodos.filter(t => t.priority === 'high');
}
// Apply search
if (searchTerm) {
filteredTodos = filteredTodos.filter(t =>
t.text.toLowerCase().includes(searchTerm) ||
t.category.toLowerCase().includes(searchTerm)
);
}
// Sort by priority and date
filteredTodos.sort((a, b) => {
const priorityOrder = { high: 0, medium: 1, low: 2 };
if (priorityOrder[a.priority] !== priorityOrder[b.priority]) {
return priorityOrder[a.priority] - priorityOrder[b.priority];
}
return new Date(a.dueDate) - new Date(b.dueDate);
});
if (filteredTodos.length === 0) {
todoList.innerHTML = `
<div class="empty-state">
<i class="fas fa-dragon"></i>
<p>No PokéTasks found!</p>
</div>
`;
} else {
todoList.innerHTML = filteredTodos.map(todo => {
const isOverdue = new Date(todo.dueDate) < new Date() && !todo.completed;
const formattedDate = formatDate(todo.dueDate);
return `
<div class="todo-item ${todo.completed ? 'completed' : ''}"
data-id="${todo.id}"
draggable="true"
ondragstart="handleDragStart(event)"
ondragover="handleDragOver(event)"
ondrop="handleDrop(event)"
ondragend="handleDragEnd(event)">
<div class="todo-checkbox ${todo.completed ? 'checked' : ''}"
onclick="toggleTodo(${todo.id})"></div>
<div class="todo-content">
<div class="todo-text">${escapeHtml(todo.text)}</div>
<div class="todo-meta">
<span class="priority-badge priority-${todo.priority}">
${todo.priority === 'high' ? 'Legendary' : todo.priority === 'medium' ? 'Rare' : 'Common'}
</span>
<span class="todo-category">
<i class="fas fa-${getCategoryIcon(todo.category)}"></i>
${todo.category}
</