From e12a9a82fa9bcc992bcabed2d84d62ae12ddf4e7 Mon Sep 17 00:00:00 2001 From: Jonas Braathen Date: Sun, 12 May 2024 01:40:59 +0200 Subject: [PATCH] add some date handling --- web/package-lock.json | 19 ++++++++++++++++ web/package.json | 2 ++ web/src/components/events/EventContainer.tsx | 22 ++++++++++++------ web/src/components/events/EventItem.tsx | 17 +++++++++++--- web/src/lib/date.ts | 24 ++++++++++++++++++++ web/src/lib/event.ts | 2 ++ 6 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 web/src/lib/date.ts diff --git a/web/package-lock.json b/web/package-lock.json index 3877602..414a69e 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -12,6 +12,8 @@ "@graphql-codegen/client-preset": "^4.2.5", "@parcel/watcher": "^2.4.1", "@urql/next": "^1.1.1", + "date-fns": "^3.6.0", + "date-fns-tz": "^3.1.3", "graphql": "^16.8.1", "next": "14.2.3", "react": "^18", @@ -3922,6 +3924,23 @@ "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.2.2.tgz", "integrity": "sha512-8YnDaaf7N3k/q5HnTJVuzSyLETjoZjVmHc4AeKAzOvKHEFQKcn64OKBfzHYtE9zGjctNM7V9I0MfnUVLpi7M5g==" }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, + "node_modules/date-fns-tz": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-3.1.3.tgz", + "integrity": "sha512-ZfbMu+nbzW0mEzC8VZrLiSWvUIaI3aRHeq33mTe7Y38UctKukgqPR4nTDwcwS4d64Gf8GghnVsroBuMY3eiTeA==", + "peerDependencies": { + "date-fns": "^3.0.0" + } + }, "node_modules/debounce": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", diff --git a/web/package.json b/web/package.json index 1dd4a4d..14984c9 100644 --- a/web/package.json +++ b/web/package.json @@ -14,6 +14,8 @@ "@graphql-codegen/client-preset": "^4.2.5", "@parcel/watcher": "^2.4.1", "@urql/next": "^1.1.1", + "date-fns": "^3.6.0", + "date-fns-tz": "^3.1.3", "graphql": "^16.8.1", "next": "14.2.3", "react": "^18", diff --git a/web/src/components/events/EventContainer.tsx b/web/src/components/events/EventContainer.tsx index 355299b..2130bed 100644 --- a/web/src/components/events/EventContainer.tsx +++ b/web/src/components/events/EventContainer.tsx @@ -1,16 +1,21 @@ "use client"; -import styles from "./eventContainer.module.scss"; +import { useState } from "react"; import { EventItem } from "./EventItem"; import { EventFilter } from "./EventFilter"; -import { EventFragment } from "@/gql/graphql"; -import { getSingularEvents } from "@/lib/event"; -import { useState } from "react"; +import { EventFragment, getSingularEvents } from "@/lib/event"; +import { + toLocalTime, + formatDate, + commonDateFormat, + isTodayOrFuture, +} from "@/lib/date"; +import styles from "./eventContainer.module.scss"; type EventContainerMode = "list" | "calendar"; export const EventContainer = ({ events }: { events: EventFragment[] }) => { - const [mode, setMode] = useState("list"); + const [mode, setMode] = useState("calendar"); return (
@@ -38,10 +43,13 @@ const EventList = ({ events }: { events: EventFragment[] }) => { }; const EventCalendar = ({ events }: { events: EventFragment[] }) => { - const singularEvents = getSingularEvents(events); + const singularEvents = getSingularEvents(events).filter((x) => + x.occurrence?.start && isTodayOrFuture(x.occurrence.start) + ); + return (
    - {events.map((event) => ( + {singularEvents.map((event) => ( ))}
diff --git a/web/src/components/events/EventItem.tsx b/web/src/components/events/EventItem.tsx index e740c7f..6254ea1 100644 --- a/web/src/components/events/EventItem.tsx +++ b/web/src/components/events/EventItem.tsx @@ -1,9 +1,16 @@ -import { SingularEvent } from "@/app/arrangementer/page"; +"use client"; + import styles from "./eventItem.module.scss"; import Link from "next/link"; import Image from "../general/Image"; +import { SingularEvent, EventFragment } from "@/lib/event"; +import { toLocalTime, formatDate, commonDateFormat } from "@/lib/date"; -export const EventItem = ({ event }: { event: SingularEvent }) => { +export const EventItem = ({ + event, +}: { + event: SingularEvent | EventFragment; +}) => { return (
  • @@ -19,7 +26,11 @@ export const EventItem = ({ event }: { event: SingularEvent }) => {

    {event.title}

    - {event.occurrence &&

    {event.occurrence.start}

    } + {event.occurrence?.start && ( +

    + {formatDate(event.occurrence?.start, commonDateFormat)} +

    + )}
    Mer om arrangementet {event.title} diff --git a/web/src/lib/date.ts b/web/src/lib/date.ts new file mode 100644 index 0000000..046fcb2 --- /dev/null +++ b/web/src/lib/date.ts @@ -0,0 +1,24 @@ +import { isToday, isAfter, parseISO } from "date-fns"; +import { toZonedTime, format } from "date-fns-tz"; + +const timeZone = "Europe/Oslo"; + +export const commonDateFormat = "dd.MM.yyyy 'kl.' HH:mm"; + +export function toLocalTime(date: Date | string | number) { + return toZonedTime(date, timeZone); +} + +export function formatDate(date: Date | string | number, formatStr: string) { + return format(toLocalTime(date), formatStr, { timeZone }); +} + +export function isTodayOrFuture( + date: Date | string | number, + timeZone = "UTC" +) { + const now = new Date(); + const zonedNow = toZonedTime(now, timeZone); + const zonedDate = toLocalTime(date); + return isToday(zonedDate) || isAfter(zonedDate, zonedNow); +} diff --git a/web/src/lib/event.ts b/web/src/lib/event.ts index c698696..22fa680 100644 --- a/web/src/lib/event.ts +++ b/web/src/lib/event.ts @@ -1,6 +1,8 @@ import { graphql } from "@/gql"; import { EventFragment, EventOccurrence } from "@/gql/graphql"; +export type { EventFragment } from "@/gql/graphql" + const EventFragmentDefinition = graphql(` fragment Event on EventPage { __typename