@imola-solutions/calendar
v0.4.0
Published
Reusable calendar & event management module. Built on FullCalendar with MUI dialogs. Consumers inject events + CRUD callbacks or use the built-in in-memory provider.
Readme
@imola-solutions/calendar
Calendar + events module built on FullCalendar with MUI dialogs. Drag-to-reschedule, click-to-edit, quick create dialog. Ships with an in-memory CalendarProvider for prototyping; wrap your own provider to persist events to your backend.
Install
npm install @imola-solutions/calendar @imola-solutions/uiPeer deps (already in most React + MUI stacks):
react>=18,react-dom>=18@mui/material>=5,@mui/x-date-pickers>=6@fullcalendar/react>=6 + plugins (daygrid, timegrid, timeline, list, interaction)react-hook-form>=7,@hookform/resolvers>=3,zod>=3@phosphor-icons/react>=2,dayjs>=1
Minimal usage (in-memory)
import { CalendarProvider, CalendarView } from "@imola-solutions/calendar";
const initialEvents = [
{ id: "1", title: "Kickoff", start: new Date(), end: new Date(Date.now() + 3600000) },
];
export function Page() {
return (
<CalendarProvider events={initialEvents}>
<CalendarView view="dayGridMonth" onViewChange={(v) => console.log("switched to", v)} />
</CalendarProvider>
);
}With server persistence
Pass onCreate/onUpdate/onDelete callbacks to CalendarProvider and forward them to your API:
<CalendarProvider
events={eventsFromServer}
onCreate={(event) => api.post("/events", event)}
onUpdate={(id, event) => api.put(`/events/${id}`, event)}
onDelete={(id) => api.delete(`/events/${id}`)}
>
<CalendarView />
</CalendarProvider>Compliance & audit
CalendarProvider accepts an onAudit prop. Every create/update/delete
(and every AI call) emits a structured event:
<CalendarProvider
events={events}
onCreate={...}
onAudit={(event) => {
// event: { action, targetId, timestamp, metadata?, success }
// actions: event.create | event.update | event.delete | ai.*
myAuditLogger.record({ ...event, product: "bopc", surface: "calendar" });
}}
>
<CalendarView />
</CalendarProvider>Audit callback errors are caught so a logger outage never breaks the calendar.
AI extensions
Pass aiExtensions to unlock optional AI capabilities. Each extension is
independent; check ai.available to conditionally render UI.
<CalendarProvider
events={events}
aiExtensions={{
suggestTitle: async (description) => callLLM(`Title for: ${description}`),
detectConflicts: async (candidate, existing) => {
return existing.filter((e) => overlaps(candidate, e));
},
parseNaturalLanguage: async (prompt) => {
// "Team standup tomorrow 9am" → { title, start, end }
return callLLM(`Parse this into an event JSON: ${prompt}`);
},
}}
>
{/* Then inside your UI: */}
<MyCreateForm />
</CalendarProvider>
// From inside a consumer:
function MyCreateForm() {
const { ai, createEvent } = React.useContext(CalendarContext);
if (!ai.available.suggestTitle) return <ManualForm />;
const handleAssist = async (description) => {
const title = await ai.suggestTitle(description);
setForm((f) => ({ ...f, title }));
};
// ...
}Unconfigured AI methods throw a helpful error (fail loud, not silent).
Exports
CalendarProvider— in-memory context with optional CRUD callbacks + audit + AI hooksCalendarContext— bring your own provider by publishing the same shapeCalendarView— full calendar UI (grid, toolbar, create/edit dialog)CalendarToolbar— standalone toolbar (view switcher + New event button)EventDialog— standalone dialog for create/edit/deleteEventContent— custom event renderer used by FullCalendaruseDialog— small open/close helper hook
