From 49dbc724c89509dde3af7f8be098b7f647106eb4 Mon Sep 17 00:00:00 2001 From: Bruno Bernardino Date: Sat, 6 Sep 2025 19:17:48 +0100 Subject: [PATCH] Fix creating and deleting calendars This fixes the creation and deletion of calendars to include a color and the proper chosen name. --- docker-compose.yml | 2 +- islands/calendar/Calendars.tsx | 10 ++++++++++ lib/models/calendar.ts | 8 ++++++-- lib/utils/calendar.ts | 6 +++++- lib/utils/calendar_test.ts | 3 ++- routes/api/calendar/add.tsx | 3 ++- routes/api/calendar/update.tsx | 4 ++-- routes/calendar.tsx | 4 ++-- 8 files changed, 30 insertions(+), 10 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 4f612e0..86fcc75 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,6 @@ services: website: - image: ghcr.io/bewcloud/bewcloud:v2.5.0 + image: ghcr.io/bewcloud/bewcloud:v2.5.1 restart: always ports: - 127.0.0.1:8000:8000 diff --git a/islands/calendar/Calendars.tsx b/islands/calendar/Calendars.tsx index 5a5b49e..b17e9df 100644 --- a/islands/calendar/Calendars.tsx +++ b/islands/calendar/Calendars.tsx @@ -37,6 +37,11 @@ export default function Calendars({ initialCalendars }: CalendarsProps) { method: 'POST', body: JSON.stringify(requestBody), }); + + if (!response.ok) { + throw new Error(`Failed to add calendar! ${response.statusText} ${await response.text()}`); + } + const result = await response.json() as AddResponseBody; if (!result.success) { @@ -65,6 +70,11 @@ export default function Calendars({ initialCalendars }: CalendarsProps) { method: 'POST', body: JSON.stringify(requestBody), }); + + if (!response.ok) { + throw new Error(`Failed to delete calendar! ${response.statusText} ${await response.text()}`); + } + const result = await response.json() as DeleteResponseBody; if (!result.success) { diff --git a/lib/models/calendar.ts b/lib/models/calendar.ts index 1f72f8e..a709dd5 100644 --- a/lib/models/calendar.ts +++ b/lib/models/calendar.ts @@ -120,6 +120,7 @@ export class CalendarModel { static async create( userId: string, name: string, + color: string, ): Promise { const calendarId = crypto.randomUUID(); const calendarUrl = `${calendarConfig.calDavUrl}/${userId}/${calendarId}/`; @@ -129,7 +130,8 @@ export class CalendarModel { await client.makeCalendar({ url: calendarUrl, props: { - displayName: name, + displayname: name, + calendarColor: color, }, }); } @@ -163,8 +165,10 @@ export class CalendarModel { static async delete( userId: string, - calendarUrl: string, + calendarId: string, ): Promise { + const calendarUrl = `${calendarConfig.calDavUrl}/${userId}/${calendarId}/`; + const client = await getClient(userId); await client.deleteObject({ diff --git a/lib/utils/calendar.ts b/lib/utils/calendar.ts index c819326..a81901a 100644 --- a/lib/utils/calendar.ts +++ b/lib/utils/calendar.ts @@ -21,6 +21,7 @@ export const CALENDAR_COLOR_OPTIONS = [ 'bg-fuchsia-700', 'bg-pink-800', 'bg-rose-700', + 'bg-gray-700', ] as const; const CALENDAR_COLOR_OPTIONS_HEX = [ @@ -44,9 +45,12 @@ const CALENDAR_COLOR_OPTIONS_HEX = [ '#9D21B1', '#9C174D', '#BC133D', + '#384354', ] as const; -export function getColorAsHex(calendarColor: string) { +export function getColorAsHex( + calendarColor: (typeof CALENDAR_COLOR_OPTIONS)[number], +): (typeof CALENDAR_COLOR_OPTIONS_HEX)[number] { const colorIndex = CALENDAR_COLOR_OPTIONS.findIndex((color) => color === calendarColor); return CALENDAR_COLOR_OPTIONS_HEX[colorIndex] || '#384354'; diff --git a/lib/utils/calendar_test.ts b/lib/utils/calendar_test.ts index 4d0cb05..a0008f5 100644 --- a/lib/utils/calendar_test.ts +++ b/lib/utils/calendar_test.ts @@ -3,6 +3,7 @@ import { assertMatch } from 'std/assert/assert_match.ts'; import { Calendar, CalendarEvent } from '/lib/models/calendar.ts'; import { + CALENDAR_COLOR_OPTIONS, convertRRuleToWords, generateVCalendar, generateVEvent, @@ -29,7 +30,7 @@ Deno.test('that getColorAsHex works', () => { ]; for (const test of tests) { - const output = getColorAsHex(test.input); + const output = getColorAsHex(test.input as typeof CALENDAR_COLOR_OPTIONS[number]); assertEquals(output, test.expected); } }); diff --git a/routes/api/calendar/add.tsx b/routes/api/calendar/add.tsx index af5ddea..6c3de8f 100644 --- a/routes/api/calendar/add.tsx +++ b/routes/api/calendar/add.tsx @@ -2,6 +2,7 @@ import { Handlers } from 'fresh/server.ts'; import { FreshContextState } from '/lib/types.ts'; import { Calendar, CalendarModel } from '/lib/models/calendar.ts'; +import { getColorAsHex } from '/lib/utils/calendar.ts'; interface Data {} @@ -23,7 +24,7 @@ export const handler: Handlers = { const requestBody = await request.clone().json() as RequestBody; if (requestBody.name) { - await CalendarModel.create(context.state.user.id, requestBody.name); + await CalendarModel.create(context.state.user.id, requestBody.name, getColorAsHex('bg-gray-700')); } const newCalendars = await CalendarModel.list(context.state.user.id); diff --git a/routes/api/calendar/update.tsx b/routes/api/calendar/update.tsx index 522f25f..b651e0c 100644 --- a/routes/api/calendar/update.tsx +++ b/routes/api/calendar/update.tsx @@ -3,7 +3,7 @@ import { Handlers } from 'fresh/server.ts'; import { FreshContextState } from '/lib/types.ts'; import { Calendar, CalendarModel } from '/lib/models/calendar.ts'; import { UserModel } from '/lib/models/user.ts'; -import { getColorAsHex } from '/lib/utils/calendar.ts'; +import { CALENDAR_COLOR_OPTIONS, getColorAsHex } from '/lib/utils/calendar.ts'; interface Data {} @@ -37,7 +37,7 @@ export const handler: Handlers = { calendar.displayName = requestBody.name; calendar.calendarColor = requestBody.color?.startsWith('#') ? requestBody.color - : getColorAsHex(requestBody.color || 'bg-gray-700'); + : getColorAsHex((requestBody.color || 'bg-gray-700') as typeof CALENDAR_COLOR_OPTIONS[number]); await CalendarModel.update(context.state.user.id, calendar.url, calendar.displayName, calendar.calendarColor); diff --git a/routes/calendar.tsx b/routes/calendar.tsx index 7c23f5a..0847317 100644 --- a/routes/calendar.tsx +++ b/routes/calendar.tsx @@ -4,7 +4,7 @@ import { FreshContextState } from '/lib/types.ts'; import { Calendar, CalendarEvent, CalendarEventModel, CalendarModel } from '/lib/models/calendar.ts'; import CalendarWrapper from '/islands/calendar/CalendarWrapper.tsx'; import { AppConfig } from '/lib/config.ts'; -import { getDateRangeForCalendarView } from '/lib/utils/calendar.ts'; +import { getColorAsHex, getDateRangeForCalendarView } from '/lib/utils/calendar.ts'; interface Data { userCalendars: Calendar[]; @@ -42,7 +42,7 @@ export const handler: Handlers = { // Create default calendar if none exists if (userCalendars.length === 0) { - await CalendarModel.create(userId, 'Calendar'); + await CalendarModel.create(userId, 'Calendar', getColorAsHex('bg-red-700')); userCalendars = await CalendarModel.list(userId); }