feat: Added current opening times to each study space on the main page. In the expanded card, you can view the opening times for the full week. Improved ui

Co-Authored-By: Tadios Temesgen <tt2022@ic.ac.uk>
This commit is contained in:
Caspar Jojo Asaam
2025-06-12 15:40:20 +01:00
parent afe7b3078d
commit 30f44b0ac6

View File

@@ -10,6 +10,8 @@
let selectedTags = $state<string[]>([]);
let tagFilter = $state("");
let openingFilter = $state("");
let closingFilter = $state("");
let tagFilterElem = $state<HTMLInputElement>();
function categorySelected(category: string[]) {
@@ -32,19 +34,60 @@
})
);
let filteredStudySpaces = $derived(
selectedTags.length === 0
? studySpaces
: studySpaces.filter((space) => {
const allTags = [
...(space.tags || []),
space.volume,
space.wifi,
space.power
].filter(Boolean);
// Convert "HH:MM" or "HH:MM:SS" to minutes since midnight
function toMinutes(timeStr: string): number {
const [h, m] = timeStr.slice(0, 5).split(":").map(Number);
return h * 60 + m;
}
return selectedTags.every((tag) => allTags.includes(tag));
})
// Combine tag and time filtering
let filteredStudySpaces = $derived(
studySpaces
// tag filtering
.filter((space) => {
if (selectedTags.length === 0) return true;
const allTags = [
...(space.tags || []),
space.volume,
space.wifi,
space.power
].filter(Boolean);
return selectedTags.every((tag) => allTags.includes(tag));
})
// opening time filter
.filter((space) => {
if (!openingFilter) return true;
const entry = space.study_space_hours?.find(
(h) => h.day_of_week === new Date().getDay()
);
if (!entry) return false;
if (entry.is_24_7) return true;
const openMin = toMinutes(entry.opens_at);
let closeMin = toMinutes(entry.closes_at);
// Treat midnight as end of day and handle overnight spans
if (closeMin === 0) closeMin = 24 * 60;
if (closeMin <= openMin) closeMin += 24 * 60;
const filterMin = toMinutes(openingFilter);
// Include spaces open at the filter time
return filterMin >= openMin && filterMin < closeMin;
})
// closing time filter
.filter((space) => {
if (!closingFilter) return true;
const entry = space.study_space_hours?.find(
(h) => h.day_of_week === new Date().getDay()
);
if (!entry) return false;
if (entry.is_24_7) return true;
const openMin = toMinutes(entry.opens_at);
let closeMin = toMinutes(entry.closes_at);
if (closeMin === 0) closeMin = 24 * 60;
if (closeMin <= openMin) closeMin += 24 * 60;
const filterMin =
toMinutes(closingFilter) === 0 ? 24 * 60 : toMinutes(closingFilter);
// Include spaces still open at the filter time
return filterMin > openMin && filterMin <= closeMin;
})
);
let dropdownVisible = $state(false);
@@ -73,6 +116,16 @@
<main>
<a href="/space/reports" class="checkReports">Check Reports</a>
<div class="time-filter-container">
<label>
Open from:
<input type="time" bind:value={openingFilter} />
</label>
<label>
Open until:
<input type="time" bind:value={closingFilter} />
</label>
</div>
<div class="tag-filter-container">
<form>
<div class="tagDisplay">
@@ -162,7 +215,29 @@
grid-column: 1 / -1;
display: flex;
justify-content: center;
margin-bottom: 1rem;
margin-bottom: 0.5rem;
}
.time-filter-container {
grid-column: 1 / -1;
display: flex;
gap: 1rem;
justify-content: center;
margin-bottom: 0.5rem;
}
.time-filter-container label {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 1rem;
color: #eaffeb;
}
.time-filter-container input[type="time"] {
background: none;
border: 2px solid #eaffeb;
border-radius: 0.5rem;
padding: 0.25rem 0.5rem;
color: #eaffeb;
}
form {