Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 137 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -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:

<input> for task name.

<select> to choose task category.

Buttons

Add, Edit, Save, Delete, Mark, and filters (All, Pending, Completed).

CSS

CSS variables (:root) for easy theme management (light/dark).

Grid layout used to align tasks and edit panel.

Buttons and input fields styled with border-radius, box-shadow, and dynamic colors.

Dark mode toggled with .darkmode class on body.

Progress bar with #background and #on-top to visualize task completion.

JavaScript

Tasks array: toDolist2 stored in localStorage.

Main functions:

saveTasks() – Saves tasks to localStorage.

renderTodolist() – Renders tasks based on the selected filter.

addList2() – Adds a new task.

Task editing:

editingIndex is used to track the task being edited.

Update task name and category in real-time.

Marking tasks:

Toggle between "pending" and "completed".

Automatically updates the progress bar.

Filtering:

Handles All, Pending, and Completed buttons.

Active filter highlighted with active class.

Dark mode:

State saved in localStorage.

Toggles .darkmode class on body.

Event listeners:

click events for adding, editing, saving, deleting, marking, and filtering tasks.

Dynamic DOM updates for instant feedback.
Binary file added img/Screenshot 2026-02-21 024643.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Screenshot 2026-02-21 024738.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions img/dark_mode_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions img/dark_mode_24dp_E8EAED_FILL1_wght400_GRAD0_opsz24.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions img/light-mode-svgrepo-com.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions img/light_mode_24dp_E3E3E3_FILL1_wght400_GRAD0_opsz24.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions img/light_mode_24dp_E8EAED_FILL1_wght400_GRAD0_opsz24.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions img/moon-night-mode-space-rocket-svgrepo-com.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
202 changes: 202 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
const toDolist2 = JSON.parse(localStorage.getItem("tasks")) || [];
let editingIndex = null;
let showmePending;
let thePending;
renderTodolist();
function saveTasks() {
localStorage.setItem("tasks", JSON.stringify(toDolist2));
}
function renderTodolist() {
let todohtml = "";
let filteredList = toDolist2;

if (showmePending === "pending") {
filteredList = toDolist2.filter((todo) => todo.status === "pending");
} else if (showmePending === "completed") {
filteredList = toDolist2.filter((todo) => todo.status === "completed");
}
filteredList.forEach((todo, index) => {
const name2 = todo.name;
const element = todo.cate;
const isCompleted = todo.status === "completed";
const buttonClass = isCompleted ? "marked-btn" : "mark-btn";
const checkMark = isCompleted ? "✔" : "";
if (editingIndex === index) {
todohtml += `
<div class="edit-panel">
<div><button class="mark-btn"></button></div>
<div><input class="edit-name" value="${todo.name}"></div>


<div>
<select class="edit-cate">
<option value="no-category" ${todo.cate === "no-category" ? "selected" : ""}>no category</option>
<option value="Personal" ${todo.cate === "Personal" ? "selected" : ""}>Personal</option>
<option value="Work" ${todo.cate === "Work" ? "selected" : ""}>Work</option>
<option value="Study" ${todo.cate === "Study" ? "selected" : ""}>Study</option>
<option value="Tech" ${todo.cate === "Tech" ? "selected" : ""}>Tech</option>
<option value="Shopping" ${todo.cate === "Shopping" ? "selected" : ""}>Shopping</option>
</select>
</div>
<div>
<button class="save-button">Save</button>
</div>
<div>
<button class="red-button">Delete</button>
</div>
</div>
`;
} else {
todohtml += `
<div class ="task-content">
<div>
<button class="${todo.status === "completed" ? "marked-btn" : "mark-btn"}">
${todo.status === "completed" ? "✔" : ""}
</button>
</div>
<div>${todo.name}</div>
<div>${todo.cate}</div>
<div><button class="edit-button">Edit</button></div>
<div> <button class="red-button">Delete</button></div>
</div>
`;
}
});

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()
})
Loading