mirror of
https://github.com/polaroi8d/cactoide.git
synced 2026-03-22 14:15:28 +00:00
Compare commits
2 Commits
fix/remove
...
0.0.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6020a78302 | ||
|
|
f8b122ed45 |
@@ -9,6 +9,8 @@
|
|||||||
let error = '';
|
let error = '';
|
||||||
let searchQuery = '';
|
let searchQuery = '';
|
||||||
let selectedEventType: EventType | 'all' = 'all';
|
let selectedEventType: EventType | 'all' = 'all';
|
||||||
|
let selectedTimeFilter: 'any' | 'next-week' | 'next-month' = 'any';
|
||||||
|
let selectedSortOrder: 'asc' | 'desc' = 'asc';
|
||||||
let fuse: Fuse<Event>;
|
let fuse: Fuse<Event>;
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
@@ -26,7 +28,29 @@
|
|||||||
includeMatches: true
|
includeMatches: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// Filter events based on search query and event type using Fuse.js
|
// Helper function to check if an event is within a time range
|
||||||
|
function isEventInTimeRange(event: Event, timeFilter: string): boolean {
|
||||||
|
if (timeFilter === 'any') return true;
|
||||||
|
|
||||||
|
const eventDate = new Date(`${event.date}T${event.time}`);
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
if (timeFilter === 'next-week') {
|
||||||
|
const nextWeek = new Date(now);
|
||||||
|
nextWeek.setDate(now.getDate() + 7);
|
||||||
|
return eventDate >= now && eventDate <= nextWeek;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeFilter === 'next-month') {
|
||||||
|
const nextMonth = new Date(now);
|
||||||
|
nextMonth.setMonth(now.getMonth() + 1);
|
||||||
|
return eventDate >= now && eventDate <= nextMonth;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter events based on search query, event type, and time filter using Fuse.js
|
||||||
$: filteredEvents = (() => {
|
$: filteredEvents = (() => {
|
||||||
let events = publicEvents;
|
let events = publicEvents;
|
||||||
|
|
||||||
@@ -35,14 +59,34 @@
|
|||||||
events = events.filter((event) => event.type === selectedEventType);
|
events = events.filter((event) => event.type === selectedEventType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Then filter by time range
|
||||||
|
if (selectedTimeFilter !== 'any') {
|
||||||
|
events = events.filter((event) => isEventInTimeRange(event, selectedTimeFilter));
|
||||||
|
}
|
||||||
|
|
||||||
// Then apply search query
|
// Then apply search query
|
||||||
if (searchQuery.trim() !== '') {
|
if (searchQuery.trim() !== '') {
|
||||||
events = fuse.search(searchQuery).map((result) => result.item);
|
events = fuse.search(searchQuery).map((result) => result.item);
|
||||||
// Re-apply type filter after search
|
// Re-apply type and time filters after search
|
||||||
if (selectedEventType !== 'all') {
|
if (selectedEventType !== 'all') {
|
||||||
events = events.filter((event) => event.type === selectedEventType);
|
events = events.filter((event) => event.type === selectedEventType);
|
||||||
}
|
}
|
||||||
|
if (selectedTimeFilter !== 'any') {
|
||||||
|
events = events.filter((event) => isEventInTimeRange(event, selectedTimeFilter));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort events by date and time
|
||||||
|
events = events.sort((a, b) => {
|
||||||
|
const dateA = new Date(`${a.date}T${a.time}`);
|
||||||
|
const dateB = new Date(`${b.date}T${b.time}`);
|
||||||
|
|
||||||
|
if (selectedSortOrder === 'asc') {
|
||||||
|
return dateA.getTime() - dateB.getTime();
|
||||||
|
} else {
|
||||||
|
return dateB.getTime() - dateA.getTime();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return events;
|
return events;
|
||||||
})();
|
})();
|
||||||
@@ -89,10 +133,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Search and Filter Section -->
|
<!-- Search and Filter Section -->
|
||||||
<div class="mb-8">
|
<div class="mb-8 max-h-screen">
|
||||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-center">
|
|
||||||
<!-- Search Bar -->
|
<!-- Search Bar -->
|
||||||
<div class="relative mx-auto max-w-md sm:mx-0">
|
<div class="relative mx-auto w-full md:w-2/3">
|
||||||
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
||||||
<svg
|
<svg
|
||||||
class="h-5 w-5 text-slate-400"
|
class="h-5 w-5 text-slate-400"
|
||||||
@@ -118,6 +161,7 @@
|
|||||||
<button
|
<button
|
||||||
on:click={() => (searchQuery = '')}
|
on:click={() => (searchQuery = '')}
|
||||||
class="absolute inset-y-0 right-0 flex items-center pr-3 text-slate-400 hover:text-slate-300"
|
class="absolute inset-y-0 right-0 flex items-center pr-3 text-slate-400 hover:text-slate-300"
|
||||||
|
aria-label="Search input"
|
||||||
>
|
>
|
||||||
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path
|
<path
|
||||||
@@ -131,35 +175,47 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Time Filter and Sort Controls -->
|
||||||
|
<div class="mx-auto mt-4 flex flex-col items-center gap-4 sm:flex-row sm:justify-center">
|
||||||
<!-- Event Type Filter -->
|
<!-- Event Type Filter -->
|
||||||
<div class="flex items-center justify-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<button
|
<label for="event-type-filter" class="text-sm font-medium text-slate-400">Type:</label
|
||||||
on:click={() => (selectedEventType = 'all')}
|
|
||||||
class="rounded-sm border px-3 py-2 text-sm font-medium transition-colors {selectedEventType ===
|
|
||||||
'all'
|
|
||||||
? 'border-violet-500 bg-violet-500/20 text-violet-400'
|
|
||||||
: 'border-slate-600 text-slate-400 hover:border-slate-500 hover:text-slate-300'}"
|
|
||||||
>
|
>
|
||||||
All
|
<select
|
||||||
</button>
|
id="event-type-filter"
|
||||||
<button
|
bind:value={selectedEventType}
|
||||||
on:click={() => (selectedEventType = 'limited')}
|
class="rounded-lg border border-slate-600 bg-slate-800 px-3 py-2 text-sm text-white focus:border-violet-500 focus:ring-2 focus:ring-violet-500/20 focus:outline-none"
|
||||||
class="rounded-sm border px-3 py-2 text-sm font-medium transition-colors {selectedEventType ===
|
|
||||||
'limited'
|
|
||||||
? 'border-amber-600 bg-amber-600/20 text-amber-600'
|
|
||||||
: 'border-slate-600 text-slate-400 hover:border-slate-500 hover:text-slate-300'}"
|
|
||||||
>
|
>
|
||||||
Limited
|
<option value="all">All</option>
|
||||||
</button>
|
<option value="limited">Limited</option>
|
||||||
<button
|
<option value="unlimited">Unlimited</option>
|
||||||
on:click={() => (selectedEventType = 'unlimited')}
|
</select>
|
||||||
class="rounded-sm border px-3 py-2 text-sm font-medium transition-colors {selectedEventType ===
|
</div>
|
||||||
'unlimited'
|
<!-- Time Filter Dropdown -->
|
||||||
? 'border-teal-500 bg-teal-500/20 text-teal-500'
|
<div class="flex items-center gap-2">
|
||||||
: 'border-slate-600 text-slate-400 hover:border-slate-500 hover:text-slate-300'}"
|
<label for="time-filter" class="text-sm font-medium text-slate-400">Time:</label>
|
||||||
|
<select
|
||||||
|
id="time-filter"
|
||||||
|
bind:value={selectedTimeFilter}
|
||||||
|
class="rounded-lg border border-slate-600 bg-slate-800 px-3 py-2 text-sm text-white focus:border-violet-500 focus:ring-2 focus:ring-violet-500/20 focus:outline-none"
|
||||||
>
|
>
|
||||||
Unlimited
|
<option value="any">Any time</option>
|
||||||
</button>
|
<option value="next-week">Next week</option>
|
||||||
|
<option value="next-month">Next month</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sort Order Dropdown -->
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<label for="sort-order" class="text-sm font-medium text-slate-400">Sort:</label>
|
||||||
|
<select
|
||||||
|
id="sort-order"
|
||||||
|
bind:value={selectedSortOrder}
|
||||||
|
class="rounded-lg border border-slate-600 bg-slate-800 px-3 py-2 text-sm text-white focus:border-violet-500 focus:ring-2 focus:ring-violet-500/20 focus:outline-none"
|
||||||
|
>
|
||||||
|
<option value="asc">Earliest first</option>
|
||||||
|
<option value="desc">Latest first</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user