Implement calendar module

This commit is contained in:
ginnoir
2026-05-06 03:10:28 -05:00
parent 8cc2ef0732
commit 744c1119a9
18 changed files with 1414 additions and 32 deletions
+87
View File
@@ -0,0 +1,87 @@
import type { ModuleManifest } from "../_core/module";
import { z } from "zod";
import { listCalendars, searchCalendars, searchEvents } from "./server/queries";
const calendarIdsSchema = z.union([z.literal("all"), z.array(z.string().uuid())]);
const manifest: ModuleManifest = {
id: "calendar",
name: "Calendar",
nav: { href: "/calendar", label: "Calendar", icon: "calendar" },
entities: [
{
type: "calendar.calendar",
label: { singular: "Calendar", plural: "Calendars" },
share: { canShare: true, defaultCapabilities: ["read"] },
search: { search: searchCalendars },
resolveUrl: (id) => `/calendar?id=${id}`,
},
{
type: "calendar.event",
label: { singular: "Event", plural: "Events" },
share: { canShare: true, defaultCapabilities: ["read"] },
reminder: { canRemind: true },
search: { search: searchEvents },
resolveUrl: (id) => `/calendar/events/${id}`,
},
],
dashboardWidgets: [
{
id: "calendar.upcoming",
title: "Upcoming events",
description: "Events from selected calendars over the next few days.",
category: "Calendar",
defaultSize: { w: 4, h: 3 },
minSize: { w: 3, h: 2 },
defaultPriority: 10,
configSchema: z.object({
calendarIds: calendarIdsSchema,
days: z.number().int().min(1).max(30),
}),
defaultConfig: { calendarIds: "all", days: 3 },
resolveConfigOptions: async () => ({
calendars: (await listCalendars()).map((calendar) => ({
id: calendar.id,
name: calendar.name,
visibility: calendar.visibility,
})),
}),
render: () => <div className="text-sm text-muted-foreground">Upcoming events</div>,
},
{
id: "calendar.month",
title: "Month calendar",
description: "A compact month view for selected calendars.",
category: "Calendar",
defaultSize: { w: 6, h: 5 },
minSize: { w: 4, h: 4 },
defaultPriority: 20,
configSchema: z.object({ calendarIds: calendarIdsSchema }),
defaultConfig: { calendarIds: "all" },
resolveConfigOptions: async () => ({
calendars: (await listCalendars()).map((calendar) => ({
id: calendar.id,
name: calendar.name,
visibility: calendar.visibility,
})),
}),
render: () => <div className="text-sm text-muted-foreground">Month calendar</div>,
},
],
quickAdds: [
{
id: "calendar.new-event",
label: "New event",
icon: "calendar-plus",
action: () => undefined,
},
{
id: "calendar.new-calendar",
label: "New calendar",
icon: "calendar-days",
action: () => undefined,
},
],
};
export default manifest;