@abhay-dev/shift-operations-calendar
v1.0.0
Published
A React-based operations calendar for managing site schedules and shifts.
Maintainers
Readme
@abhay-dev/operations-calendar
A modern, responsive React-based operations calendar for managing site schedules and shifts.
Features
- Weekly View: Navigate through weeks to view site-specific schedules.
- Shift Status: Color-coded visualization for published and unpublished shifts.
- Site Filtering: Easily filter shifts by site.
- Interactive: Click handlers for shifts and empty date cells.
- Responsive: Horizontal scrolling for small screens.
- Customizable: Built with Tailwind CSS and Radix UI.
Installation
npm install @abhay-dev/operations-calendarMake sure you have the following peer dependencies installed:
npm install react react-dom lucide-reactUsage
Here is an example of how to use the OperationsCalendar component in your React application:
import {
OperationsCalendar,
SiteSchedule,
} from "@ctrl-room/operations-calendar";
const sampleSites: SiteSchedule[] = [
{
siteId: "1",
siteName: "Main Office",
location: "New York, NY",
schedules: {
"2026-01-26": [
{
id: "s1",
shiftCode: "MORNING",
startTime: "08:00",
endTime: "16:00",
startDate: "2026-01-26",
endDate: "2026-01-26",
assignedCount: 5,
requiredCount: 8,
status: "published",
},
],
},
},
];
function MyCalendar() {
return (
<OperationsCalendar
sites={sampleSites}
startDate={new Date()}
onShiftClick={(shift, date, site) => console.log("Shift clicked:", shift)}
onDateCellClick={(date, site) =>
console.log("Cell clicked:", date, site.siteName)
}
/>
);
}Tailwind CSS Integration
Since this library uses Tailwind CSS, ensure your tailwind.config.js includes the library's components to apply the styles correctly:
module.exports = {
content: [
// ... your project files
"./node_modules/@ctrl-room/operations-calendar/dist/operations-calendar.js",
],
// ...
};Props
| Prop | Type | Description |
| :---------------- | :--------------------------------------- | :--------------------------------------------------------------- |
| sites | SiteSchedule[] | List of sites and their respective schedules. |
| startDate | Date (optional) | The date to start the calendar's weekly view. Defaults to now. |
| onSiteChange | (siteId: string) => void (optional) | Callback when the site filter changes. |
| onShiftClick | (shift, date, site) => void (optional) | Callback when a shift badge is clicked. |
| onDateCellClick | (date, site) => void (optional) | Callback when an empty date cell is clicked. |
Handling Interactions
The OperationsCalendar provides callback props to handle user interactions. This is ideal for opening modals, sidebars, or navigating to detailed shift pages.
Example: Opening a Modal on Shift Click
To open a modal when a user clicks a shift, you can manage the modal's visibility and the "active" shift in your component's state:
import { useState } from "react";
import { OperationsCalendar } from "@ctrl-room/operations-calendar";
function App() {
const [isModalOpen, setIsModalOpen] = useState(false);
const [selectedShift, setSelectedShift] = useState(null);
const handleShiftClick = (shift, date, site) => {
setSelectedShift({ shift, date, site });
setIsModalOpen(true);
};
return (
<>
<OperationsCalendar sites={sites} onShiftClick={handleShiftClick} />
{isModalOpen && (
<div className="modal">
<h3>Shift Details</h3>
<p>Site: {selectedShift.site.siteName}</p>
<p>Shift: {selectedShift.shift.shiftCode}</p>
<button onClick={() => setIsModalOpen(false)}>Close</button>
</div>
)}
</>
);
}Handling Multiple Actions (Example)
You can use the interaction callbacks to offer multiple choices, such as viewing vs editing:
const handleShiftClick = (shift, date, site) => {
if (shift.status === "unpublished") {
// Show 'Publish' or 'Edit' options
openEditModal(shift);
} else {
// Show read-only details
showShiftDetails(shift);
}
};Example: Creating a Shift on Empty Cell Click
Use onDateCellClick to let users add new shifts to the schedule:
const handleDateCellClick = (date, site) => {
// Open a 'New Shift' form with pre-filled date and site
setNewShiftDefaults({ date, siteId: site.siteId });
setIsCreateModalOpen(true);
};
return (
<OperationsCalendar
onDateCellClick={handleDateCellClick}
// ... other props
/>
);License
MIT © Ctrl Room
