diff --git a/README.md b/README.md index e59ba00..3bbbcae 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,146 @@ -# MicroClub IT Section 2025-2026 +Description -Welcome to the official repository of the **IT Section** at [MicroClub](https://microclub.info/) - the first scientific club in Algeria, founded in 1985 at USTHB. +Task Manager Web Site is a web application that allows users to create, edit, delete, and track tasks in different categories. It also includes a progress bar and a dark mode to enhance user experience. -## About +The project is built with HTML, CSS, and JavaScript, without external frameworks, and uses localStorage to save tasks locally. -This repository showcases all activities, events, workshops, and challenges organized by the IT section during the 2025-2026 academic year. +Screenshots +### Light Mode -## Sub-Sections +![Light Mode Screenshot](img/Screenshot%202026-02-21%20024738.png) -The IT section is divided into four specialized sub-sections: +### Dark Mode -- **AI** - Artificial Intelligence and Machine Learning -- **Mobile** - Mobile Application Development -- **Web** - Web Development and Technologies -- **Security** - Cybersecurity and Network Security +![Dark Mode Screenshot](img/Screenshot%202026-02-21%20024643.png) -## What You'll Find Here +Replace path-to-your-light-mode-image.png and path-to-your-dark-mode-image.png with the actual paths to your screenshots. -- Workshop materials and resources -- Event documentation -- Challenge problems and solutions -- Training content -- Project showcases +Features -_Learning IT, Experiencing IT, Sharing IT._ +Add a Task + +Enter a task name and select a category. + +Click the Add button to add it to the list. + +Edit a Task + +Click Edit to modify the task name or category. + +Click Save to save changes. + +Delete a Task + +Click Delete to remove a task from the list. + +Mark Task as Completed + +Click the ✔ button to mark a task as "completed". + +Click again to return it to "pending". + +Filter Tasks + +Use the All, Pending, and Completed buttons to filter tasks by status. + +Progress Bar + +Shows the percentage of tasks completed compared to the total. + +Dark Mode + +Toggle between light and dark themes using the button at the top right. + +The dark mode state is saved in localStorage. + +Responsive Design + +The interface is centered and adapts to different screen sizes. + +Project Structure +/project-root +│ +├─ index.html # Main HTML structure +├─ style.css # Styles and theme (light/dark) +├─ script.js # JavaScript logic for tasks and interactions +├─ img/ # Icons for light/dark mode +│ ├─ dark_mode_24dp.svg +│ └─ light_mode_24dp.svg +└─ README.md # Project documentation +HTML + +Main structure: + +#main-panel contains all main content. + +#header for the title and separator line. + +#control contains the add form and filter buttons. + +#tasks displays the task list. + +#progress displays the progress bar. + +Input and select: + + for task name. + + + + +
+ +
+
+ +
+
+ +
+ + `; + } else { + todohtml += ` +
+
+ +
+
${todo.name}
+
${todo.cate}
+
+
+
+ `; + } + }); + + document.querySelector(".task").innerHTML = todohtml; + document.querySelectorAll(".red-button").forEach((deletebutton, index) => { + deletebutton.addEventListener("click", () => { + const todoToDelete = filteredList[index]; + const realIndex = toDolist2.indexOf(todoToDelete); + toDolist2.splice(realIndex, 1); + saveTasks(); + renderTodolist(); + }); + }); + document.querySelectorAll(".edit-button").forEach((btn, index) => { + btn.addEventListener("click", () => { + const todoEdit = filteredList[index]; + const realIndex = toDolist2.indexOf(todoEdit); + editingIndex = index; + console.log("clicked edit", index); + renderTodolist(); + }); + }); + document.querySelectorAll(".save-button").forEach((save) => { + save.addEventListener("click", () => { + const newName = document.querySelector(".edit-name").value; + const newCate = document.querySelector(".edit-cate").value; + + toDolist2[editingIndex].name = newName; + toDolist2[editingIndex].cate = newCate; + saveTasks(); + + editingIndex = null; + renderTodolist(); + }); + }); + document.querySelectorAll(".mark-btn, .marked-btn").forEach((btn, index) => { + btn.addEventListener("click", () => { + const todo = filteredList[index]; + + + if (todo.status === "pending") { + todo.status = "completed"; + } else { + todo.status = "pending"; + } + saveTasks(); + + + renderTodolist(); + }); +}); + const totalTasks = toDolist2.length; + const completedTasks = toDolist2.filter( + (todo) => todo.status === "completed", + ).length; + const progressPercent = + totalTasks === 0 ? 0 : Math.round((completedTasks / totalTasks) * 100); + document.getElementById("on-top").style.width = progressPercent + "%"; +} + +document.querySelector(".add-button").addEventListener("click", () => { + addList2(); +}); + +function addList2() { + const inputElement = document.getElementById("todoElement2"); + const name = inputElement.value; + + const categoryInputElement = document.getElementById("category"); + const cate = categoryInputElement.value; + + toDolist2.push({ + name, + cate, + status: "pending", + }); + saveTasks(); + + inputElement.value = ""; + + renderTodolist(); +} +let change = document.querySelector(".add-button"); + +document.querySelector(".filter-btn").addEventListener("click", () => { + showmePending = "all"; + renderTodolist(); +}); + +document.querySelector(".Pending-btn").addEventListener("click", () => { + showmePending = "pending"; + renderTodolist(); +}); + +document.querySelector(".Completed-btn").addEventListener("click", () => { + showmePending = "completed"; + renderTodolist(); +}); +const filterButtons = document.querySelectorAll(".filter button"); + +filterButtons.forEach((button) => { + button.addEventListener("click", () => { + + + filterButtons.forEach((btn) => { + btn.classList.remove("active"); + }); + + button.classList.add("active"); + + if (button.id === "all") { + showmePending = "all"; + } else if (button.id === "Pending") { + showmePending = "pending"; + } else if (button.id === "Completed") { + showmePending = "completed"; + } + + renderTodolist(); + }); +}); +let darkmode = localStorage.getItem('darkmode') +const themeSwitch = document.getElementById('theme-switch') + +const enableDarkmode = () => { + document.body.classList.add('darkmode') + localStorage.setItem('darkmode', 'active') +} + +const disableDarkmode = () => { + document.body.classList.remove('darkmode') + localStorage.setItem('darkmode', null) +} + +if(darkmode === "active") enableDarkmode() + +themeSwitch.addEventListener("click", () => { + darkmode = localStorage.getItem('darkmode') + darkmode !== "active" ? enableDarkmode() : disableDarkmode() +}) \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..c84090d --- /dev/null +++ b/style.css @@ -0,0 +1,340 @@ +:root { + --h1-color: #2d4162; + --base-color: #d9e2f1; + --back-ground-color: #fcfcfe; + --shadow-color: #adadad; + --add-btn-color: #1d66f2; + --delete-btn-color: #f14f54; + --mark-btn-color: #d9e2f1; + --border-color: e2e2e2; + --marked-btn-color: #1d66f2; + --text-color: #e5e7eb; + --progres-color:#eee; + --ontop-color :#2268f2; + --filter-btn-color:#4b5563; + --back-filter-color:#2563eb; + --line-color: #e8e8e8; + --edit-color:#e5e7eb ; + --edit-txt-color:#2d4162; + --pro-text-color:#2d4162; +} +.darkmode { +--base-color: #07081B; +--h1-color :#BF92F8; + --back-ground-color: #0F0B2B; + --shadow-color: rgba(123, 47, 247, 0.35); + + --add-btn-color: #7B2FF7; + --delete-btn-color: #FF4D6D; + + --mark-btn-color: #1B1035; + --marked-btn-color: #7B2FF7; + + --border-color: #2A1E4A; + + --text-color: #E0C3FF; + + --progres-color: #2A1E4A; + --ontop-color: #7B2FF7; + + --filter-btn-color: #A78BFA; + --back-filter-color: #7B2FF7; +--edit-color:#201050 ; + --edit-txt-color:#775CA7; + --line-color: #1C1238; + --pro-text-color:#E0C3FF; +} + +body { + margin: 0; + height: 100vh; + display: flex; + justify-content: center; + align-items: center; + background-color: var(--base-color); + font-family: Arial, Helvetica, sans-serif; + +} +h1{ + text-align: center; + font-size: 28px; + color: var(--h1-color); + font-weight: 800; + margin-top: 10px; + margin-bottom: 30px; + +} +#main-panel { + width: 550px; + padding: 30px; + background-color: var(--back-ground-color); + border-radius: 10px; + box-shadow: 0 10px 30px var(--shadow-color); +} +.edit-panel { + display: grid; + grid-template-columns: 20px 150px 100px 70px 70px; + column-gap: 15px; + row-gap: 15px; + margin-bottom: 15px; + align-items: stretch; +} +.input { + display: grid; + grid-template-columns: 1fr 170px 70px; + column-gap: 15px; + row-gap: 15px; + margin-bottom: 15px; + align-items: stretch; +} +.task-content { + display: grid; + padding: 10px; + grid-template-columns: 20px 120px 90px 70px 70px; + column-gap: 15px; + justify-content: space-between; + row-gap: 15px; + margin-bottom: 15px; + margin-right: 15px; + align-items: stretch; + width: 500px; + margin-left: 20px; + border-radius: 7px; + border-width: 0px; + border-color: var(--border-color); + box-shadow: 0px 0px 5px 1px var(--shadow-color); + align-items: center; + color: var(--pro-text-color); +} + +.placeholder { + font-size: 15px; + font-family: inter; + background-color:var(--back-ground-color); + color: var(--text-color); + padding: 6px; + border-radius: 7px; + border-width: 0px; + border-color: var(--border-color); + box-shadow: 0px 0px 5px 1px var(--shadow-color); + +} +#category{ + font-size: 15px; + font-family: inter; + color: var(--text-color); + background-color:var(--back-ground-color); + padding: 6px; + border-radius: 7px; + border-width: 0px; + border-color: var(--border-color); + box-shadow: 0px 0px 5px 1px var(--shadow-color); + +} +.add-button { + + background: var(--add-btn-color); + color: white; + border: none; + border-radius: 8px; + font-weight: 600; + cursor: pointer; + transition: opacity 0.2s; +} +.edit-button{ + background-color:var(--edit-color); + color:var(--edit-txt-color); + border: none; + font-size: 13px; + border-radius: 7px; + padding: 7px; + cursor: pointer; + width: 100%; +} +.add-button:hover { + opacity: 0.9; +} +.red-button { + background-color: var(--delete-btn-color); + color: white; + border: none; + font-size: 13px; + border-radius: 7px; + padding: 7px; + cursor: pointer; + width: 100%; +} + +.mark-btn { + background-color: var(--mark-btn-color); + height: 20px; + width: 20px; + border: 1px solid var(--border-color); + cursor: pointer; + margin-top: 4px; + margin-left: 7px; + border-radius: 5px; +} + +.marked-btn { + background-color: var(--marked-btn-color); + color: white; + height: 20px; + width: 20px; + border: none; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + font-size: 12px; + margin-top: 4px; + border-radius: 5px; + margin-left: 7px; +} +#container-progress { + height: 20px; + background-color: var(--border-color); + position: relative; +} +#background { + width: 100%; + height: 20px; + background-color:var(--progres-color); + border-radius: 10px; + position: relative; + overflow: hidden; +} + +#on-top { + height: 100%; + background-color: var(--ontop-color); + transition: width 0.3s ease; +} +.filter { + display: flex; + justify-content: center; + align-items: center; + + overflow: hidden; + width: 100%; + max-width: 350px; + margin: 20px auto; +} +.filter button { + display: flex; + justify-content: center; + align-items: center; + padding: 10px 30px; + border-radius: 5px; + margin: 5px; ; + border: none; + background: transparent; + cursor: pointer; + font-size: 12px; + color: var(--filter-btn-color); + transition: all 0.2s ease; +} + +.filter button.active { + background: var(--back-filter-color); + color: white; +} +.line { + height: 0.5px; + background-color: var(--line-color); + margin-top: 15px; + margin-bottom: 15px; + +} +.todoElement { + flex: 2; + height: 40px; + padding: 0 15px; + border-radius: 8px; + border: 1px solid var(--border-color); + font-family: 'Inter'; + outline: none; +} +#theme-switch{ + height: 50px; + width: 50px; + padding: 0; + border-radius: 50%; + background-color: var(--edit-txt-color); + border-width: 0.5px; + display: flex; + justify-content: center; + align-items: center; + position: fixed; + top: 20px; + right: 20px; +} +#theme-switch img{ + fill: var(--primary-color); +} +#theme-switch img:last-child{ + display: none; +} +.darkmode #theme-switch img:first-child{ + display: none; +} +.darkmode #theme-switch img:last-child{ + display: block; +} +.prog{ + color: var(--pro-text-color); +} +.edit-panel{ + display: grid; + padding: 10px; + + + justify-content: space-between; + + margin-bottom: 15px; + margin-right: 15px; + align-items: stretch; + width: 520px; + margin-left: 10px; + border-radius: 7px; + border-width: 0px; + border-color: var(--border-color); + box-shadow: 0px 0px 5px 1px var(--shadow-color); + align-items: center; + color: var(--pro-text-color); +} +.edit-name{ + font-size: 15px; + width: 120px; + font-family: inter; + background-color:var(--back-ground-color); + color: var(--text-color); + padding: 6px; + border-radius: 7px; + border-width: 0px; + border-color: var(--border-color); + box-shadow: 0px 0px 5px 1px var(--shadow-color); + +} +.edit-cate{ + font-size: 15px; + width: 80px; + font-family: inter; + background-color:var(--back-ground-color); + color: var(--text-color); + padding: 6px; + border-radius: 7px; + border-width: 0px; + border-color: var(--border-color); + box-shadow: 0px 0px 5px 1px var(--shadow-color); +} +.save-button{ + background-color:var(--edit-color); + color:var(--edit-txt-color); + border: none; + font-size: 13px; + border-radius: 7px; + padding: 7px; + cursor: pointer; + width: 100%; +} \ No newline at end of file diff --git a/todo.html b/todo.html new file mode 100644 index 0000000..a2de908 --- /dev/null +++ b/todo.html @@ -0,0 +1,73 @@ + + + + + + + + + + Task Manager web site + +
+ +
+ +
+ + +
+
+ + + + + +
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+

Progress:

+
+
+
+
+
+ + + +