From 0cc29b1659f981d29a67a125ba2fb1a07d203e52 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82?= <81538700+PawiX25@users.noreply.github.com>
Date: Fri, 13 Dec 2024 01:40:51 +0000
Subject: [PATCH] Add sorting options for programs by category, A-Z, deadline,
and status
---
index.html | 7 ++++++
script.js | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++---
styles.css | 37 ++++++++++++++++++++++++++++++
3 files changed, 108 insertions(+), 3 deletions(-)
diff --git a/index.html b/index.html
index 13ee2fd..6cf7d2a 100644
--- a/index.html
+++ b/index.html
@@ -29,6 +29,13 @@
+
+
+
+
+
+
+
diff --git a/script.js b/script.js
index bc35f39..5511efe 100644
--- a/script.js
+++ b/script.js
@@ -192,24 +192,79 @@ function countActivePrograms() {
return count;
}
+let currentSort = 'default';
+
+function sortPrograms(programs, sortType) {
+ const flattened = Object.entries(programs).flatMap(([category, progs]) =>
+ progs.map(p => ({...p, category}))
+ );
+
+ switch(sortType) {
+ case 'alphabetical':
+ return flattened.sort((a, b) => a.name.localeCompare(b.name));
+ case 'deadline':
+ return flattened.sort((a, b) => {
+ if (!a.deadline) return 1;
+ if (!b.deadline) return -1;
+ return new Date(a.deadline) - new Date(b.deadline);
+ });
+ case 'status':
+ const statusOrder = { active: 0, upcoming: 1, completed: 2 };
+ return flattened.sort((a, b) => statusOrder[a.status] - statusOrder[b.status]);
+ default:
+ return flattened;
+ }
+}
+
function renderPrograms() {
const container = document.getElementById('programs-container');
+ container.innerHTML = '';
const activeCount = countActivePrograms();
document.getElementById('active-count').textContent = activeCount;
- for (const [category, programsList] of Object.entries(programs)) {
+ if (currentSort === 'default') {
+ for (const [category, programsList] of Object.entries(programs)) {
+ const section = document.createElement('section');
+ section.className = 'category-section';
+ section.innerHTML = `
+ ${category.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase())}
+
+ ${programsList.map(program => createProgramCard(program)).join('')}
+
+ `;
+ container.appendChild(section);
+ }
+ } else {
+ const sortedPrograms = sortPrograms(programs, currentSort);
const section = document.createElement('section');
section.className = 'category-section';
section.innerHTML = `
- ${category.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase())}
- ${programsList.map(program => createProgramCard(program)).join('')}
+ ${sortedPrograms.map(program => createProgramCard(program)).join('')}
`;
container.appendChild(section);
}
}
+function updateSort(sortType) {
+ currentSort = sortType;
+ const buttons = document.querySelectorAll('.sort-btn');
+ buttons.forEach(btn => {
+ btn.classList.toggle('active', btn.dataset.sort === sortType);
+ });
+ renderPrograms();
+
+ const activeFilter = document.querySelector('.filter-btn.active');
+ if (activeFilter) {
+ filterPrograms(activeFilter.dataset.category);
+ }
+ const searchInput = document.getElementById('program-search');
+ if (searchInput.value) {
+ searchPrograms(searchInput.value);
+ }
+}
+
function filterPrograms(category) {
const sections = document.querySelectorAll('.category-section');
const buttons = document.querySelectorAll('.filter-btn');
@@ -326,6 +381,12 @@ document.addEventListener('DOMContentLoaded', () => {
document.getElementById('theme-toggle').addEventListener('click', toggleTheme);
setInterval(updateDeadlines, 60000);
+
+ document.querySelectorAll('.sort-btn').forEach(button => {
+ button.addEventListener('click', () => {
+ updateSort(button.dataset.sort);
+ });
+ });
});
document.addEventListener('click', (e) => {
diff --git a/styles.css b/styles.css
index 3f43352..659ebba 100644
--- a/styles.css
+++ b/styles.css
@@ -1019,4 +1019,41 @@ body.modal-open {
.program-position:hover {
opacity: 1;
+}
+
+.sort-container {
+ display: flex;
+ gap: var(--spacing-2);
+ flex-wrap: wrap;
+ margin-bottom: var(--spacing-4);
+}
+
+.sort-btn {
+ background: var(--elevated);
+ color: var(--text);
+ border: 1px solid var(--border);
+ box-shadow: none;
+ transition: all 0.3s ease;
+ font-size: var(--font-1);
+ padding: var(--spacing-1) var(--spacing-2);
+}
+
+.sort-btn.active {
+ background: var(--primary);
+ color: var(--white);
+ border-color: var(--primary);
+}
+
+.sort-btn:hover {
+ transform: none;
+ box-shadow: none;
+ background: var(--smoke);
+}
+
+@media screen and (max-width: 48em) {
+ .filter-container,
+ .sort-container {
+ justify-content: center;
+ margin: var(--spacing-2) 0;
+ }
}
\ No newline at end of file