mirror of
https://github.com/SrIzan10/YSWS-Catalog.git
synced 2026-05-01 11:15:09 +00:00
Add sorting options for programs by category, A-Z, deadline, and status
This commit is contained in:
@@ -29,6 +29,13 @@
|
||||
<button class="filter-btn" data-category="completed">Completed</button>
|
||||
</div>
|
||||
|
||||
<div class="sort-container">
|
||||
<button class="sort-btn active" data-sort="default">By Category</button>
|
||||
<button class="sort-btn" data-sort="alphabetical">A-Z</button>
|
||||
<button class="sort-btn" data-sort="deadline">By Deadline</button>
|
||||
<button class="sort-btn" data-sort="status">By Status</button>
|
||||
</div>
|
||||
|
||||
<div id="programs-container">
|
||||
</div>
|
||||
|
||||
|
||||
67
script.js
67
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 = `
|
||||
<h2 class="headline">${category.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase())}</h2>
|
||||
<div class="programs-grid">
|
||||
${programsList.map(program => createProgramCard(program)).join('')}
|
||||
</div>
|
||||
`;
|
||||
container.appendChild(section);
|
||||
}
|
||||
} else {
|
||||
const sortedPrograms = sortPrograms(programs, currentSort);
|
||||
const section = document.createElement('section');
|
||||
section.className = 'category-section';
|
||||
section.innerHTML = `
|
||||
<h2 class="headline">${category.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase())}</h2>
|
||||
<div class="programs-grid">
|
||||
${programsList.map(program => createProgramCard(program)).join('')}
|
||||
${sortedPrograms.map(program => createProgramCard(program)).join('')}
|
||||
</div>
|
||||
`;
|
||||
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) => {
|
||||
|
||||
37
styles.css
37
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user