Skip to content

Commit

Permalink
Add user timezone handling to calendar events
Browse files Browse the repository at this point in the history
  • Loading branch information
arjunkomath committed Jan 9, 2025
1 parent 097fbfd commit 405f139
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 9 deletions.
50 changes: 41 additions & 9 deletions app/(api)/api/calendar/[ownerId]/[projectId]/route.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,39 @@
import { calendarEvent, project, task, taskList } from "@/drizzle/schema";
import { getUser } from "@/lib/ops/auth";
import { getDatabaseForOwner } from "@/lib/utils/useDatabase";
import { getVtimezoneComponent } from "@touch4it/ical-timezones";
import dayjs from "dayjs";
import tz from "dayjs/plugin/timezone";
import utc from "dayjs/plugin/utc";
import { and, desc, eq, lte } from "drizzle-orm";
import ical, { ICalCalendarMethod } from "ical-generator";
import type { NextRequest } from "next/server";

dayjs.extend(utc);
dayjs.extend(tz);

export const revalidate = 0;
export const dynamic = "force-dynamic";

export async function GET(
_: Request,
props: { params: Promise<{ projectId: string; ownerId: string }> },
request: NextRequest,
props: {
params: Promise<{ projectId: string; ownerId: string }>;
},
) {
const params = await props.params;
const searchParams = request.nextUrl.searchParams;
const { projectId, ownerId } = params;

let timezone: string | null = null;
const userId = searchParams.get("userId");
if (userId) {
const user = await getUser(userId);
if (user.customData?.timezone) {
timezone = user.customData.timezone;
}
}

const db = await getDatabaseForOwner(ownerId);

const projectDetails = await db.query.project
Expand Down Expand Up @@ -47,21 +67,29 @@ export async function GET(
const calendar = ical({
name: projectDetails.name,
method: ICalCalendarMethod.PUBLISH,
timezone: { name: "Australia/Sydney", generator: getVtimezoneComponent },
timezone: timezone
? { name: timezone, generator: getVtimezoneComponent }
: null,
});

for (const event of events) {
calendar.createEvent({
id: event.id,
start: event.start,
end: event.end ?? null,
start: timezone
? dayjs.utc(event.start).tz(timezone).format("YYYY-MM-DDTHH:mm:ssZ")
: event.start,
end: event.end
? timezone
? dayjs.utc(event.end).tz(timezone).format("YYYY-MM-DDTHH:mm:ssZ")
: event.end
: null,
summary: event.name,
description: event.description,
allDay: event.allDay,
created: event.createdAt,
lastModified: event.updatedAt,
repeating: event.repeatRule,
timezone: "Australia/Sydney",
timezone,
});
}

Expand All @@ -76,14 +104,18 @@ export async function GET(

calendar.createEvent({
id: task.id,
start: task.dueDate,
end: task.dueDate,
start: timezone
? dayjs.utc(task.dueDate).tz(timezone).format("YYYY-MM-DDTHH:mm:ssZ")
: task.dueDate,
end: timezone
? dayjs.utc(task.dueDate).tz(timezone).format("YYYY-MM-DDTHH:mm:ssZ")
: task.dueDate,
summary: `[${tasklist.name}] ${task.name}`,
description: task.description,
allDay: true,
created: task.createdAt,
lastModified: task.updatedAt,
timezone: "Australia/Sydney",
timezone,
});
}
}
Expand Down
24 changes: 24 additions & 0 deletions lib/ops/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,30 @@ export const fetchAccessToken = async () => {
}).toString(),
});
};

export const getUser = async (userId: string) => {
const { access_token } = await fetchAccessToken().then((res) => res.json());
if (!access_token) {
throw new Error("Access token not found");
}

const { endpoint } = logtoConfig;
const response = await fetch(`${endpoint}api/users/${userId}`, {
method: "GET",
headers: {
Authorization: `Bearer ${access_token}`,
"Content-Type": "application/json",
},
});

if (!response.ok) {
console.error("Failed to fetch user", response.status);
throw new Error("Failed to fetch user");
}

return await response.json();
};

export const updateUser = async (
userId: string,
data: {
Expand Down

0 comments on commit 405f139

Please sign in to comment.