From ea4392063f084210a80689b17441a18f19d2b26e Mon Sep 17 00:00:00 2001 From: Arjun Komath Date: Thu, 16 Jan 2025 19:29:25 +1100 Subject: [PATCH] Fix events in today --- app/(dashboard)/[tenant]/settings/page.tsx | 8 +- app/(dashboard)/[tenant]/today/page.tsx | 112 ++++++++++++++++----- components/project/events/events-list.tsx | 20 +--- lib/utils/useEvents.ts | 18 ++++ 4 files changed, 112 insertions(+), 46 deletions(-) create mode 100644 lib/utils/useEvents.ts diff --git a/app/(dashboard)/[tenant]/settings/page.tsx b/app/(dashboard)/[tenant]/settings/page.tsx index 5d6131c..d9cb5ab 100644 --- a/app/(dashboard)/[tenant]/settings/page.tsx +++ b/app/(dashboard)/[tenant]/settings/page.tsx @@ -66,7 +66,7 @@ export default async function Settings() { Profile ({userInfo.username}) -
+

Name

@@ -79,10 +79,10 @@ export default async function Settings() { />
-
-
+
+

Email address -

+

; +}) { const db = await database(); const timezone = await getTimezone(); - const today = toTimeZone(Date(), timezone); + const today = toTimeZone(new Date(), "UTC"); + const startOfDay = toStartOfDay(today); + const endOfDay = toEndOfDay(today); const [tasks, events] = await Promise.all([ db.query.task.findMany({ - where: (task, { and, isNotNull, lte, ne }) => - and( - lte(task.dueDate, toEndOfDay(today)), - ne(task.status, "done"), - isNotNull(task.dueDate), - ), + where: and( + lte(task.dueDate, toEndOfDay(today)), + ne(task.status, "done"), + isNotNull(task.dueDate), + ), orderBy: [asc(task.position)], columns: { name: true, @@ -38,12 +58,14 @@ export default async function Today() { with: { taskList: { columns: { + id: true, status: true, name: true, }, with: { project: { columns: { + id: true, name: true, }, }, @@ -52,8 +74,28 @@ export default async function Today() { }, }), db.query.calendarEvent.findMany({ - where: and(lte(calendarEvent.start, today)), - orderBy: [asc(calendarEvent.start)], + where: and( + or( + between(calendarEvent.start, startOfDay, endOfDay), + between(calendarEvent.end, startOfDay, endOfDay), + and( + lt(calendarEvent.start, startOfDay), + gt(calendarEvent.end, endOfDay), + ), + isNotNull(calendarEvent.repeatRule), + eq(calendarEvent.start, startOfDay), + eq(calendarEvent.end, endOfDay), + ), + ), + orderBy: [desc(calendarEvent.start), asc(calendarEvent.allDay)], + with: { + project: { + columns: { + id: true, + name: true, + }, + }, + }, }), ]); @@ -65,7 +107,13 @@ export default async function Today() { .filter((t) => t.taskList.status !== "archived") .filter((t) => t.dueDate! < new Date()); - const summary = ` You've got ${dueToday.length > 0 ? dueToday.length : "no"} tasks due today, ${overDue.length > 0 ? overDue.length : "no"} overdue tasks and ${events.length > 0 ? events.length : "no"} events today.`; + const filteredEvents = events.filter((event) => + filterByRepeatRule(event, today), + ); + + const summary = ` You've got ${dueToday.length > 0 ? dueToday.length : "no"} task(s) due today, ${overDue.length > 0 ? overDue.length : "no"} overdue task(s) and ${events.length > 0 ? events.length : "no"} event(s) today.`; + + const { tenant } = await props.params; return ( <> @@ -77,14 +125,18 @@ export default async function Today() {

- {events.length ? ( + {filteredEvents.length ? (

Events

{events.map((event) => ( -
+

{event.name}

{event.description}

-
+ ))} ) : null} @@ -121,7 +173,7 @@ export default async function Today() { Overdue

- {overDue.map((task) => TaskItem(task))} + {overDue.map((task) => TaskItem(tenant, task))} ) : null} @@ -131,7 +183,7 @@ export default async function Today() { Due Today

- {dueToday.map((task) => TaskItem(task))} + {dueToday.map((task) => TaskItem(tenant, task))} ) : null} @@ -139,17 +191,29 @@ export default async function Today() { ); } -function TaskItem(task: { - name: string; - id: number; - taskList: { name: string; status: string; project: { name: string } }; -}) { +function TaskItem( + tenant: string, + task: { + name: string; + id: number; + taskList: { + id: number; + name: string; + status: string; + project: { id: number; name: string }; + }; + }, +) { return ( -
+

{task.taskList.project.name} - {task.taskList.name}

{task.name}

-
+ ); } diff --git a/components/project/events/events-list.tsx b/components/project/events/events-list.tsx index a0f89f8..c56c96d 100644 --- a/components/project/events/events-list.tsx +++ b/components/project/events/events-list.tsx @@ -12,29 +12,13 @@ import { } from "@/components/ui/dropdown-menu"; import type { EventWithInvites } from "@/drizzle/types"; import { cn } from "@/lib/utils"; -import { - toDateStringWithDay, - toDateTimeString, - toEndOfDay, - toStartOfDay, -} from "@/lib/utils/date"; +import { toDateStringWithDay, toDateTimeString } from "@/lib/utils/date"; +import { filterByRepeatRule } from "@/lib/utils/useEvents"; import { CircleEllipsisIcon } from "lucide-react"; import Link from "next/link"; import { rrulestr } from "rrule"; import { Assignee } from "../shared/assigee"; -const filterByRepeatRule = (event: EventWithInvites, date: Date) => { - if (event.repeatRule) { - const rrule = rrulestr(event.repeatRule); - const start = toStartOfDay(date); - const end = toEndOfDay(date); - - return rrule.between(start, end, true).length > 0; - } - - return true; -}; - export default function EventsList({ date, projectId, diff --git a/lib/utils/useEvents.ts b/lib/utils/useEvents.ts new file mode 100644 index 0000000..618aeb7 --- /dev/null +++ b/lib/utils/useEvents.ts @@ -0,0 +1,18 @@ +import type { CalendarEvent, EventWithInvites } from "@/drizzle/types"; +import { rrulestr } from "rrule"; +import { toEndOfDay, toStartOfDay } from "./date"; + +export const filterByRepeatRule = ( + event: CalendarEvent | EventWithInvites, + date: Date, +) => { + if (event.repeatRule) { + const rrule = rrulestr(event.repeatRule); + const start = toStartOfDay(date); + const end = toEndOfDay(date); + + return rrule.between(start, end, true).length > 0; + } + + return true; +};