diff --git a/src/lib/dateFormatter.ts b/src/lib/dateFormatter.ts deleted file mode 100644 index a68d3b9..0000000 --- a/src/lib/dateFormatter.ts +++ /dev/null @@ -1,12 +0,0 @@ -export const formatDate = (dateString: string): string => { - const date = new Date(dateString); - const year = date.getFullYear(); - const month = String(date.getMonth() + 1).padStart(2, '0'); - const day = String(date.getDate()).padStart(2, '0'); - return `${year}/${month}/${day}`; -}; - -export const formatTime = (timeString: string): string => { - const [hours, minutes] = timeString.split(':'); - return `${hours}:${minutes}`; -}; diff --git a/src/lib/dateHelpers.ts b/src/lib/dateHelpers.ts new file mode 100644 index 0000000..d9536c5 --- /dev/null +++ b/src/lib/dateHelpers.ts @@ -0,0 +1,40 @@ +import type { Event } from './types'; + +export const formatDate = (dateString: string): string => { + const date = new Date(dateString); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}/${month}/${day}`; +}; + +export const formatTime = (timeString: string): string => { + const [hours, minutes] = timeString.split(':'); + return `${hours}:${minutes}`; +}; + +// Helper function to check if an event is within a time range +export const isEventInTimeRange = (event: Event, timeFilter: string): boolean => { + if (timeFilter === 'any') return true; + + const eventDate = new Date(`${event.date}T${event.time}`); + const now = new Date(); + + // Handle temporal status filters + if (timeFilter === 'upcoming') { + return eventDate >= now; + } + + if (timeFilter === 'past') { + return eventDate < now; + } + + // Handle time range filters + const ranges: Record = { + 'next-week': new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000), + 'next-month': new Date(new Date(now).setMonth(now.getMonth() + 1)) + }; + + const endDate = ranges[timeFilter]; + return endDate ? eventDate >= now && eventDate <= endDate : true; +}; diff --git a/src/routes/discover/+page.svelte b/src/routes/discover/+page.svelte index 66d4d2d..a2b2cd1 100644 --- a/src/routes/discover/+page.svelte +++ b/src/routes/discover/+page.svelte @@ -2,13 +2,17 @@ import type { Event, EventType } from '$lib/types'; import { goto } from '$app/navigation'; import type { PageData } from '../$types'; - import { formatTime, formatDate } from '$lib/dateFormatter'; + import { formatTime, formatDate, isEventInTimeRange } from '$lib/dateHelpers'; import Fuse from 'fuse.js'; let publicEvents: Event[] = []; let error = ''; let searchQuery = ''; let selectedEventType: EventType | 'all' = 'all'; + let selectedTimeFilter: 'any' | 'next-week' | 'next-month' = 'any'; + let selectedTemporalStatus: 'all' | 'upcoming' | 'past' = 'all'; + let selectedSortOrder: 'asc' | 'desc' = 'asc'; + let showFilters = false; let fuse: Fuse; export let data: PageData; @@ -26,7 +30,7 @@ includeMatches: true }); - // Filter events based on search query and event type using Fuse.js + // Filter events based on search query, event type, time filter, and temporal status $: filteredEvents = (() => { let events = publicEvents; @@ -35,15 +39,43 @@ events = events.filter((event) => event.type === selectedEventType); } + // Then filter by temporal status (past/upcoming/all) + if (selectedTemporalStatus !== 'all') { + events = events.filter((event) => isEventInTimeRange(event, selectedTemporalStatus)); + } + + // Then filter by time range + if (selectedTimeFilter !== 'any') { + events = events.filter((event) => isEventInTimeRange(event, selectedTimeFilter)); + } + // Then apply search query if (searchQuery.trim() !== '') { events = fuse.search(searchQuery).map((result) => result.item); - // Re-apply type filter after search + // Re-apply all filters after search if (selectedEventType !== 'all') { events = events.filter((event) => event.type === selectedEventType); } + if (selectedTemporalStatus !== 'all') { + events = events.filter((event) => isEventInTimeRange(event, selectedTemporalStatus)); + } + 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; })(); @@ -89,10 +121,10 @@ -
-
- -
+
+ +
+
{#if searchQuery} - - -
+ +
+ + + {#if showFilters} +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+ + +
+
+ {/if}
diff --git a/src/routes/event/+page.svelte b/src/routes/event/+page.svelte index 213f8c1..cd78948 100644 --- a/src/routes/event/+page.svelte +++ b/src/routes/event/+page.svelte @@ -1,7 +1,7 @@