anycoder-f87f4e78 / index.html
moha77edhassan's picture
Upload folder using huggingface_hub
b57eee7 verified
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>مُنظم المهام اليومية | Daily Task Manager</title>
<!-- استدعاء خط Cairo من جوجل (سيعمل كخط افتراضي للنظام في حالة عدم وجود إنترنت) -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@300;400;600;700&display=swap" rel="stylesheet">
<style>
/*
* ==========================================
* CSS Variables & Reset
* ==========================================
*/
:root {
--primary-color: #4facfe;
--primary-gradient: linear-gradient(to right, #4facfe 0%, #00f2fe 100%);
--secondary-color: #e0f7fa;
--text-color: #2c3e50;
--text-light: #7f8c8d;
--bg-color: #f4f7f6;
--white: #ffffff;
--danger: #ff6b6b;
--success: #2ecc71;
--shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
--shadow-hover: 0 15px 35px rgba(0, 0, 0, 0.12);
--radius: 16px;
--transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
outline: none;
}
body {
font-family: 'Cairo', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: var(--bg-color);
color: var(--text-color);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: flex-start;
padding: 40px 20px;
overflow-x: hidden;
}
/*
* ==========================================
* Main Container
* ==========================================
*/
.app-container {
background: var(--white);
width: 100%;
max-width: 500px;
border-radius: var(--radius);
box-shadow: var(--shadow);
overflow: hidden;
position: relative;
transition: var(--transition);
}
/* Header Section */
header {
background: var(--primary-gradient);
padding: 30px;
text-align: center;
color: var(--white);
position: relative;
}
header h1 {
font-size: 1.8rem;
font-weight: 700;
margin-bottom: 5px;
text-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
header p {
font-size: 0.9rem;
opacity: 0.9;
}
.anycoder-link {
display: inline-block;
margin-top: 10px;
font-size: 0.8rem;
color: var(--white);
text-decoration: none;
background: rgba(255, 255, 255, 0.2);
padding: 4px 12px;
border-radius: 20px;
transition: var(--transition);
}
.anycoder-link:hover {
background: rgba(255, 255, 255, 0.4);
transform: translateY(-2px);
}
/* Input Section */
.input-group {
padding: 25px;
display: flex;
gap: 10px;
background: var(--white);
border-bottom: 1px solid #f0f0f0;
}
#task-input {
flex: 1;
padding: 14px 20px;
border: 2px solid #eef2f5;
border-radius: 12px;
font-family: inherit;
font-size: 1rem;
transition: var(--transition);
background: #fafafa;
}
#task-input:focus {
border-color: var(--primary-color);
background: var(--white);
box-shadow: 0 0 0 4px rgba(79, 172, 254, 0.1);
}
#add-btn {
background: var(--primary-gradient);
border: none;
color: var(--white);
width: 50px;
height: 50px;
border-radius: 12px;
cursor: pointer;
font-size: 1.5rem;
display: flex;
align-items: center;
justify-content: center;
transition: var(--transition);
box-shadow: 0 4px 15px rgba(79, 172, 254, 0.3);
}
#add-btn:hover {
transform: translateY(-2px) scale(1.05);
box-shadow: 0 6px 20px rgba(79, 172, 254, 0.4);
}
#add-btn:active {
transform: translateY(0);
}
/* Stats Bar */
.stats-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 25px;
background: #fafafa;
font-size: 0.9rem;
color: var(--text-light);
border-bottom: 1px solid #f0f0f0;
}
#clear-btn {
background: transparent;
border: none;
color: var(--danger);
cursor: pointer;
font-family: inherit;
font-size: 0.85rem;
font-weight: 600;
padding: 5px 10px;
border-radius: 6px;
transition: var(--transition);
}
#clear-btn:hover {
background: rgba(255, 107, 107, 0.1);
}
/* Task List */
#task-list {
list-style: none;
padding: 0;
margin: 0;
max-height: 60vh;
overflow-y: auto;
}
/* Custom Scrollbar */
#task-list::-webkit-scrollbar {
width: 6px;
}
#task-list::-webkit-scrollbar-track {
background: transparent;
}
#task-list::-webkit-scrollbar-thumb {
background-color: #e0e0e0;
border-radius: 20px;
}
.task-item {
display: flex;
align-items: center;
padding: 18px 25px;
border-bottom: 1px solid #f5f5f5;
transition: var(--transition);
animation: slideIn 0.3s ease-out forwards;
background: var(--white);
}
.task-item:hover {
background: #fafbfc;
}
.task-item.completed {
background: #f9f9f9;
}
.task-item.completed .task-text {
text-decoration: line-through;
color: #bdc3c7;
}
/* Custom Checkbox */
.checkbox-wrapper {
position: relative;
margin-left: 15px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.checkbox-wrapper input {
display: none;
}
.checkmark {
width: 22px;
height: 22px;
background-color: #eee;
border-radius: 6px;
position: relative;
transition: var(--transition);
display: flex;
align-items: center;
justify-content: center;
}
.checkbox-wrapper input:checked ~ .checkmark {
background: var(--success);
border-color: var(--success);
}
.checkmark::after {
content: '✔';
font-size: 14px;
color: white;
display: none;
}
.checkbox-wrapper input:checked ~ .checkmark::after {
display: block;
}
.task-text {
flex: 1;
font-size: 1rem;
color: var(--text-color);
transition: var(--transition);
word-break: break-word;
}
.delete-btn {
background: transparent;
border: none;
color: #e74c3c;
cursor: pointer;
font-size: 1.2rem;
opacity: 0;
transform: translateX(10px);
transition: var(--transition);
padding: 5px;
margin-right: 10px;
border-radius: 6px;
}
.task-item:hover .delete-btn {
opacity: 1;
transform: translateX(0);
}
.delete-btn:hover {
background: rgba(231, 76, 60, 0.1);
}
/* Empty State */
.empty-state {
text-align: center;
padding: 50px 20px;
color: var(--text-light);
display: none; /* Hidden by default */
flex-direction: column;
align-items: center;
}
.empty-state svg {
width: 80px;
height: 80px;
margin-bottom: 15px;
fill: #ecf0f1;
}
/* Animations */
@keyframes slideIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeOut {
to {
opacity: 0;
transform: translateX(-20px);
}
}
.task-item.deleting {
animation: fadeOut 0.3s ease forwards;
}
/* Responsive */
@media (max-width: 480px) {
body {
padding: 15px;
}
header {
padding: 20px;
}
header h1 {
font-size: 1.5rem;
}
.delete-btn {
opacity: 1; /* Always show delete button on mobile */
transform: translateX(0);
}
}
</style>
</head>
<body>
<div class="app-container">
<header>
<h1>مهامي اليومية</h1>
<p>نظم وقتك، حقق أهدافك</p>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">Built with anycoder</a>
</header>
<div class="input-group">
<input type="text" id="task-input" placeholder="أضف مهمة جديدة..." maxlength="50">
<button id="add-btn">
<!-- SVG Plus Icon -->
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
<line x1="12" y1="5" x2="12" y2="19"></line>
<line x1="5" y1="12" x2="19" y2="12"></line>
</svg>
</button>
</div>
<div class="stats-bar">
<span id="tasks-count">0 مهام متبقية</span>
<button id="clear-btn">مسح الكل</button>
</div>
<ul id="task-list">
<!-- Tasks will be injected here by JS -->
</ul>
<!-- Empty State Message -->
<div id="empty-msg" class="empty-state">
<svg viewBox="0 0 24 24">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6h-2zm0 8h2v2h-2z"/>
</svg>
<h3>لا توجد مهام حالياً</h3>
<p>ابدأ بإضافة مهمة جديدة لتبدأ يومك بنشاط</p>
</div>
</div>
<script>
/**
* ==========================================
* JavaScript Logic
* ==========================================
*/
// DOM Elements
const taskInput = document.getElementById('task-input');
const addBtn = document.getElementById('add-btn');
const taskList = document.getElementById('task-list');
const tasksCount = document.getElementById('tasks-count');
const clearBtn = document.getElementById('clear-btn');
const emptyMsg = document.getElementById('empty-msg');
// State
let tasks = [];
// Initialize App
document.addEventListener('DOMContentLoaded', () => {
loadTasks();
renderTasks();
});
// Event Listeners
addBtn.addEventListener('click', addTask);
taskInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') addTask();
});
clearBtn.addEventListener('click', clearAllTasks);
/**
* Load tasks from LocalStorage
*/
function loadTasks() {
const storedTasks = localStorage.getItem('myTasks');
if (storedTasks) {
tasks = JSON.parse(storedTasks);
}
}
/**
* Save tasks to LocalStorage
*/
function saveTasks() {
localStorage.setItem('myTasks', JSON.stringify(tasks));
updateStats();
}
/**
* Add a new task
*/
function addTask() {
const text = taskInput.value.trim();
if (text === '') {
// Shake animation for empty input
taskInput.style.borderColor = 'var(--danger)';
setTimeout(() => taskInput.style.borderColor = '#eef2f5', 500);
return;
}
const newTask = {
id: Date.now(),
text: text,
completed: false
};
tasks.unshift(newTask); // Add to beginning of array
saveTasks();
renderTasks();
taskInput.value = '';
taskInput.focus();
}
/**
* Toggle task completion status
*/
function toggleTask(id) {
tasks = tasks.map(task => {
if (task.id === id) {
return { ...task, completed: !task.completed };
}
return task;
});
saveTasks();
renderTasks();
}
/**
* Delete a specific task
*/
function deleteTask(id, element) {
// Add removing animation class
element.classList.add('deleting');
// Wait for animation to finish before removing from data
setTimeout(() => {
tasks = tasks.filter(task => task.id !== id);
saveTasks();
renderTasks();
}, 300);
}
/**
* Clear all tasks
*/
function clearAllTasks() {
if (tasks.length === 0) return;
if(confirm('هل أنت متأكد من حذف جميع المهام؟')) {
tasks = [];
saveTasks();
renderTasks();
}
}
/**
* Update the stats counter
*/
function updateStats() {
const remaining = tasks.filter(t => !t.completed).length;
tasksCount.textContent = `${remaining} مهام متبقية`;
}
/**
* Render tasks to the DOM
*/
function renderTasks() {
taskList.innerHTML = '';
// Handle Empty State
if (tasks.length === 0) {
emptyMsg.style.display = 'flex';
taskList.style.display = 'none';
} else {
emptyMsg.style.display = 'none';
taskList.style.display = 'block';
tasks.forEach(task => {
const li = document.createElement('li');
li.className = `task-item ${task.completed ? 'completed' : ''}`;
li.innerHTML = `
<label class="checkbox-wrapper">
<input type="checkbox" ${task.completed ? 'checked' : ''} onchange="toggleTask(${task.id})">
<span class="checkmark"></span>
</label>
<span class="task-text">${escapeHtml(task.text)}</span>
<button class="delete-btn" onclick="deleteTask(${task.id}, this.parentElement)">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="3 6 5 6 21 6"></polyline>
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
</svg>
</button>
`;
taskList.appendChild(li);
});
}
updateStats();
}
/**
* Security helper to prevent XSS
*/
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
</script>
</body>
</html>