Skip to content

Commit

Permalink
un-component EventList so the diff is cleaner
Browse files Browse the repository at this point in the history
  • Loading branch information
SheepTester committed Sep 29, 2024
1 parent 50a8dbb commit 5119178
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 156 deletions.
149 changes: 0 additions & 149 deletions src/components/events/EventList/index.tsx

This file was deleted.

1 change: 0 additions & 1 deletion src/components/events/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ export { default as EventCard } from './EventCard';
export { default as EventCarousel } from './EventCarousel';
export { default as EventDisplay } from './EventDisplay';
export { DEFAULT_FILTER_STATE, default as EventFilter } from './EventFilter';
export { default as EventList } from './EventList';
export { default as EventModal } from './EventModal';
135 changes: 129 additions & 6 deletions src/pages/events.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,66 @@
import { DEFAULT_FILTER_STATE, EventList } from '@/components/events';
import { LoginAppeal, PaginationControls, Typography } from '@/components/common';
import { DEFAULT_FILTER_STATE, EventDisplay, EventFilter } from '@/components/events';
import { config } from '@/lib';
import { EventAPI, UserAPI } from '@/lib/api';
import { getCurrentUser } from '@/lib/hoc/withAccessType';
import useQueryState from '@/lib/hooks/useQueryState';
import { CookieService } from '@/lib/services';
import type { PublicAttendance, PublicEvent } from '@/lib/types/apiResponses';
import { FilterEventOptions } from '@/lib/types/client';
import {
FilterEventOptions,
isValidAttendanceFilter,
isValidCommunityFilter,
isValidDateFilter,
} from '@/lib/types/client';
import { CookieType } from '@/lib/types/enums';
import { formatSearch, getDateRange, getYears } from '@/lib/utils';
import styles from '@/styles/pages/events.module.scss';
import { GetServerSideProps } from 'next';
import { useMemo, useState } from 'react';

interface FilterOptions {
search: string;
communityFilter: string;
dateFilter: string | number;
attendanceFilter: string;
}

const filterEvent = (
event: PublicEvent,
attendances: PublicAttendance[],
{ search, communityFilter, dateFilter, attendanceFilter }: FilterOptions
): boolean => {
// Filter search query
if (search !== '' && !formatSearch(event.title).includes(formatSearch(search))) {
return false;
}
// Filter by community
if (communityFilter !== 'all' && event.committee.toLowerCase() !== communityFilter) {
return false;
}
// Filter by date
const { from, to } = getDateRange(dateFilter);
if (from !== undefined && new Date(event.start) < new Date(from * 1000)) {
return false;
}
if (to !== undefined && new Date(event.end) > new Date(to * 1000)) {
return false;
}
// Filter by attendance
if (attendanceFilter === 'any') {
return true;
}
const attended = attendances.some(a => a.event.uuid === event.uuid);
if (attendanceFilter === 'attended' && !attended) {
return false;
}
if (attendanceFilter === 'not-attended' && attended) {
return false;
}
return true;
};

const ROWS_PER_PAGE = 25;

interface EventsPageProps {
events: PublicEvent[];
Expand All @@ -16,14 +70,83 @@ interface EventsPageProps {
}

const EventsPage = ({ events, attendances, initialFilters, loggedOut }: EventsPageProps) => {
const [page, setPage] = useState(0);
const years = useMemo(getYears, []);

const validDate = (value: string): boolean => {
return isValidDateFilter(value) || years.some(o => o.value === value);
};

const [states, setStates] = useQueryState({
pathName: config.eventsRoute,
initialFilters,
queryStates: {
community: {
defaultValue: DEFAULT_FILTER_STATE.community,
valid: isValidCommunityFilter,
},
date: {
defaultValue: DEFAULT_FILTER_STATE.date,
valid: validDate,
},
attendance: {
defaultValue: DEFAULT_FILTER_STATE.attendance,
valid: isValidAttendanceFilter,
},
search: {
defaultValue: DEFAULT_FILTER_STATE.search,
// Any string is a valid search, so just return true.
valid: () => true,
},
},
});

const communityFilter = states.community?.value || DEFAULT_FILTER_STATE.community;
const dateFilter = states.date?.value || DEFAULT_FILTER_STATE.date;
const attendanceFilter = states.attendance?.value || DEFAULT_FILTER_STATE.attendance;
const search = states.search?.value || DEFAULT_FILTER_STATE.search;

const filteredEvents = events.filter(e =>
filterEvent(e, attendances, { search, communityFilter, dateFilter, attendanceFilter })
);

filteredEvents.sort((a, b) => {
if (dateFilter === 'upcoming') {
// For upcoming events, sort from soonest to latest
return new Date(a.start).getTime() - new Date(b.start).getTime();
}
// For all other events, sort from most recent to least recent
return new Date(b.start).getTime() - new Date(a.start).getTime();
});

const displayedEvents = filteredEvents.slice(page * ROWS_PER_PAGE, (page + 1) * ROWS_PER_PAGE);

return (
<div className={styles.page}>
<EventList
events={events}
attendances={attendances}
initialFilters={initialFilters}
<Typography variant="headline/heavy/small">Events</Typography>
{loggedOut ? (
<LoginAppeal>
Create an account to check into events, give feedback, earn points, and join a community
of thousands.
</LoginAppeal>
) : null}
<EventFilter
filters={{ search, communityFilter, dateFilter, attendanceFilter }}
onFilter={(param, value) => {
setStates(param, value);
setPage(0);
}}
loggedOut={loggedOut}
/>
<EventDisplay events={displayedEvents} attendances={attendances} />

{filteredEvents.length > 0 ? (
<PaginationControls
page={page}
onPage={page => setPage(page)}
pages={Math.ceil(filteredEvents.length / ROWS_PER_PAGE)}
/>
) : null}
</div>
);
};
Expand Down

0 comments on commit 5119178

Please sign in to comment.