diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index c4cc2a6..59465d8 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -6,112 +6,18 @@ import { useMemo, useState } from "react";
import { EventScale, EventStatus } from "@/types/event";
import { Switch } from "@headlessui/react";
import { sendTrack } from "@/utils/track";
-
-enum DurationType {
- Passed = "passed", //already done.
- Now = "now", // in the duration of event.
- Soon = "soon", // in the same month of event start date.
- Next = "next", // not start yet but plan in this year.
- NextYear = "nextYear", // in the next year
-}
+import { DurationType } from "@/types/list";
+import { filteringEvents, groupByCustomDurationEvent } from "@/utils/event";
export default function Home(props: { events: Event[] }) {
const [selectedFilter, setFilter] = useState({
onlyAvailable: false,
eventScale: ["All"],
});
- const filteredEvents = props.events.filter((event) => {
- const now = Date.now();
- const endTime = event.endDate
- ? new Date(new Date(event.endDate).setHours(23, 59, 59, 999)).getTime()
- : null;
- if (selectedFilter.onlyAvailable) {
- if (event.status === EventStatus.EventCancelled) {
- return false;
- }
- if (endTime && now > endTime) {
- return false;
- }
- }
-
- if (
- selectedFilter.eventScale[0] !== "All" &&
- !selectedFilter.eventScale.includes(event.scale)
- ) {
- return false;
- }
- return true;
- });
- const groupByCustomDurationEvent = useMemo(() => {
- const currentMonth = new Date().getUTCMonth() + 1;
- const now = Date.now();
-
- const durationObject: { [x in DurationType]: Event[] } = {
- now: [],
- soon: [],
- next: [],
- nextYear: [],
- passed: [],
- };
-
- filteredEvents.forEach((event) => {
- const startTime = event.startDate
- ? new Date(new Date(event.startDate).setHours(0, 0, 0, 0)).getTime()
- : null;
- const endTime = event.endDate
- ? new Date(new Date(event.endDate).setHours(23, 59, 59, 999)).getTime()
- : null;
-
- // if a event end date is next year, then count it in next year not in current year.
- const isNextYear =
- event.startDate && event.endDate
- ? new Date(event.startDate).getUTCFullYear() >
- new Date().getUTCFullYear() ||
- new Date(event.endDate).getUTCFullYear() >
- new Date().getUTCFullYear()
- : false;
-
- const startMonth = event.startDate
- ? new Date(event.startDate).getUTCMonth() + 1 + (isNextYear ? 12 : 0)
- : null;
- const endMonth = event.endDate
- ? new Date(event.endDate).getUTCMonth() + 1 + (isNextYear ? 12 : 0)
- : null;
-
- if (
- startTime === null ||
- endTime === null ||
- startMonth === null ||
- endMonth === null
- ) {
- return durationObject.next.push(event);
- }
- //Passed events
- if (now > endTime) {
- return durationObject.passed.push(event);
- }
-
- if (startMonth <= currentMonth) {
- //Now events
- if (now > startTime && now < endTime) {
- return durationObject.now.push(event);
- } else {
- //Soon events
- return durationObject.soon.push(event);
- }
- }
-
- //Next events
- if (startMonth > currentMonth) {
- if (startMonth > 12) {
- return durationObject.nextYear.push(event);
- }
- return durationObject.next.push(event);
- }
- });
- return durationObject;
- }, [filteredEvents]);
+ const filteredEvents = filteringEvents(props.events, selectedFilter);
+ const groupByCustomDurationEvents =
+ groupByCustomDurationEvent(filteredEvents);
return (
<>
@@ -131,12 +37,12 @@ export default function Home(props: { events: Event[] }) {
)}
- {Object.keys(groupByCustomDurationEvent).map((type) =>
- groupByCustomDurationEvent[type as DurationType].length ? (
+ {Object.keys(groupByCustomDurationEvents).map((type) =>
+ groupByCustomDurationEvents[type as DurationType].length ? (
) : null
)}
diff --git a/src/types/list.ts b/src/types/list.ts
new file mode 100644
index 0000000..b67bb70
--- /dev/null
+++ b/src/types/list.ts
@@ -0,0 +1,14 @@
+import { EventScale } from "./event";
+
+export enum DurationType {
+ Passed = "passed", //already done.
+ Now = "now", // in the duration of event.
+ Soon = "soon", // in the same month of event start date.
+ Next = "next", // not start yet but plan in this year.
+ NextYear = "nextYear", // in the next year
+}
+
+export type SelectedFilterType = {
+ onlyAvailable: boolean;
+ eventScale: (typeof EventScale)[keyof typeof EventScale][];
+};
diff --git a/src/utils/event.ts b/src/utils/event.ts
index 355d494..bf28104 100644
--- a/src/utils/event.ts
+++ b/src/utils/event.ts
@@ -1,5 +1,15 @@
+import { EventStatus } from "@/types/event";
+import { DurationType, SelectedFilterType } from "@/types/list";
import { Event } from "@/xata/xata";
import groupBy from "lodash-es/groupBy";
+import {
+ isBefore,
+ isAfter,
+ endOfDay,
+ startOfDay,
+ endOfToday,
+ startOfToday,
+} from "date-fns";
export function sortByStartDateDesc(data: Event[]) {
const groupByStartDate = groupBy(data, (e) =>
@@ -21,3 +31,106 @@ export function sortByStartDateDesc(data: Event[]) {
return years.map((year) => ({ year, events: groupByStartDate[year] }));
}
+
+export function filteringEvents(
+ events: Event[],
+ selectedFilter: SelectedFilterType
+) {
+ return events.filter((event) => {
+ const now = Date.now();
+ const endTime = event.endDate
+ ? new Date(new Date(event.endDate).setHours(23, 59, 59, 999)).getTime()
+ : null;
+ if (selectedFilter.onlyAvailable) {
+ // for now, if event is cancelled, the data willn't include it at all.
+ // if (event.status === EventStatus.EventCancelled) {
+ // return false;
+ // }
+ if (endTime && now > endTime) {
+ return false;
+ }
+ }
+
+ if (
+ selectedFilter.eventScale[0] !== "All" &&
+ !selectedFilter.eventScale.includes(event.scale)
+ ) {
+ return false;
+ }
+ return true;
+ });
+}
+
+function isDateBelongNextYear(testDate: string) {
+ return new Date(testDate).getUTCFullYear() > new Date().getUTCFullYear();
+}
+
+function getDateMonth(testDate: string) {
+ const isNextYear = isDateBelongNextYear(testDate);
+ const dateBelongMonth = new Date(testDate).getUTCMonth() + 1;
+ return isNextYear ? dateBelongMonth + 12 : dateBelongMonth;
+}
+
+export function groupByCustomDurationEvent(events: Event[]) {
+ const currentMonth = new Date().getUTCMonth() + 1;
+ const now = Date.now();
+
+ const durationObject: { [x in DurationType]: Event[] } = {
+ now: [],
+ soon: [],
+ next: [],
+ nextYear: [],
+ passed: [],
+ };
+
+ events.forEach((event) => {
+ const startTime = event.startDate
+ ? new Date(new Date(event.startDate).setHours(0, 0, 0, 0)).getTime()
+ : null;
+ const endTime = event.endDate
+ ? new Date(new Date(event.endDate).setHours(23, 59, 59, 999)).getTime()
+ : null;
+
+ const startMonth = event.startDate
+ ? getDateMonth(event.startDate.toString())
+ : null;
+ const endMonth = event.endDate
+ ? getDateMonth(event.endDate.toString())
+ : null;
+
+ //next events
+ if (
+ startTime === null ||
+ endTime === null ||
+ startMonth === null ||
+ endMonth === null
+ ) {
+ return durationObject.next.push(event);
+ }
+
+ //Passed events
+ if (isAfter(now, endTime)) {
+ return durationObject.passed.push(event);
+ }
+
+ //Now events
+ if (isAfter(now, startTime) && isBefore(now, endTime)) {
+ return durationObject.now.push(event);
+ }
+
+ //Soon events
+ if (startMonth === currentMonth && isBefore(now, startTime)) {
+ return durationObject.soon.push(event);
+ }
+
+ //Next events
+ if (startMonth > currentMonth) {
+ if (startMonth > 12) {
+ return durationObject.nextYear.push(event);
+ }
+ return durationObject.next.push(event);
+ }
+ });
+
+ return durationObject;
+}