{"_id":"@abhay-dev/shift-operations-calendar","name":"@abhay-dev/shift-operations-calendar","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@abhay-dev/shift-operations-calendar","version":"1.0.0","type":"module","main":"dist/operations-calendar.umd.cjs","module":"dist/operations-calendar.js","types":"dist/index.d.ts","description":"A React-based operations calendar for managing site schedules and shifts.","author":{"name":"Ctrl Room"},"license":"MIT","keywords":["react","calendar","operations","scheduling","shifts"],"publishConfig":{"access":"public"},"scripts":{"dev":"vite","build":"tsc && vite build","preview":"vite preview"},"peerDependencies":{"react":"^18.0.0","react-dom":"^18.0.0","lucide-react":">=0.200.0"},"dependencies":{"@radix-ui/react-avatar":"^1.1.2","@radix-ui/react-select":"^2.1.4","@radix-ui/react-slot":"^1.1.1","class-variance-authority":"^0.7.1","clsx":"^2.1.1","tailwind-merge":"^2.6.0"},"devDependencies":{"@types/node":"^20.0.0","@types/react":"^18.0.0","@types/react-dom":"^18.0.0","@vitejs/plugin-react":"^4.0.0","autoprefixer":"^10.4.0","postcss":"^8.4.0","tailwindcss":"^3.4.0","typescript":"^5.0.0","vite":"^5.0.0","vite-plugin-dts":"^3.0.0"},"_id":"@abhay-dev/shift-operations-calendar@1.0.0","_nodeVersion":"22.19.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-b4v/9CAixhvEpMXpZKTB4rmZWH0v7887GPtMo/Rpm0VbpYitxb4vQmlK4sQx0K+knMpuweUDjC3m1JBVbmPpow==","shasum":"1e11091e2a9ac86b6e0cad0564a9727a5d306557","tarball":"https://registry.npmjs.org/@abhay-dev/shift-operations-calendar/-/shift-operations-calendar-1.0.0.tgz","fileCount":14,"unpackedSize":392195,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD7hQn+koDYAZwHcBW1TEcJ4iHcHPPPzwFSi4Yw+cm4DgIhAOsDTBlHGFRf7wlqwYfeT8S92yHA1OYzOzUT10ieeGRB"}]},"_npmUser":{"name":"abhaykrishnan","email":"abhaykrishnan210@gmail.com"},"directories":{},"maintainers":[{"name":"abhaykrishnan","email":"abhaykrishnan210@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/shift-operations-calendar_1.0.0_1769597303108_0.710982385986553"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-28T10:48:23.045Z","1.0.0":"2026-01-28T10:48:23.243Z","modified":"2026-01-28T10:48:23.409Z"},"maintainers":[{"name":"abhaykrishnan","email":"abhaykrishnan210@gmail.com"}],"description":"A React-based operations calendar for managing site schedules and shifts.","keywords":["react","calendar","operations","scheduling","shifts"],"author":{"name":"Ctrl Room"},"license":"MIT","readme":"# @abhay-dev/operations-calendar\r\n\r\nA modern, responsive React-based operations calendar for managing site schedules and shifts.\r\n\r\n## Features\r\n\r\n- **Weekly View**: Navigate through weeks to view site-specific schedules.\r\n- **Shift Status**: Color-coded visualization for published and unpublished shifts.\r\n- **Site Filtering**: Easily filter shifts by site.\r\n- **Interactive**: Click handlers for shifts and empty date cells.\r\n- **Responsive**: Horizontal scrolling for small screens.\r\n- **Customizable**: Built with Tailwind CSS and Radix UI.\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install @abhay-dev/operations-calendar\r\n```\r\n\r\nMake sure you have the following peer dependencies installed:\r\n\r\n```bash\r\nnpm install react react-dom lucide-react\r\n```\r\n\r\n## Usage\r\n\r\nHere is an example of how to use the `OperationsCalendar` component in your React application:\r\n\r\n```tsx\r\nimport {\r\n  OperationsCalendar,\r\n  SiteSchedule,\r\n} from \"@ctrl-room/operations-calendar\";\r\n\r\nconst sampleSites: SiteSchedule[] = [\r\n  {\r\n    siteId: \"1\",\r\n    siteName: \"Main Office\",\r\n    location: \"New York, NY\",\r\n    schedules: {\r\n      \"2026-01-26\": [\r\n        {\r\n          id: \"s1\",\r\n          shiftCode: \"MORNING\",\r\n          startTime: \"08:00\",\r\n          endTime: \"16:00\",\r\n          startDate: \"2026-01-26\",\r\n          endDate: \"2026-01-26\",\r\n          assignedCount: 5,\r\n          requiredCount: 8,\r\n          status: \"published\",\r\n        },\r\n      ],\r\n    },\r\n  },\r\n];\r\n\r\nfunction MyCalendar() {\r\n  return (\r\n    <OperationsCalendar\r\n      sites={sampleSites}\r\n      startDate={new Date()}\r\n      onShiftClick={(shift, date, site) => console.log(\"Shift clicked:\", shift)}\r\n      onDateCellClick={(date, site) =>\r\n        console.log(\"Cell clicked:\", date, site.siteName)\r\n      }\r\n    />\r\n  );\r\n}\r\n```\r\n\r\n### Tailwind CSS Integration\r\n\r\nSince this library uses Tailwind CSS, ensure your `tailwind.config.js` includes the library's components to apply the styles correctly:\r\n\r\n```javascript\r\nmodule.exports = {\r\n  content: [\r\n    // ... your project files\r\n    \"./node_modules/@ctrl-room/operations-calendar/dist/operations-calendar.js\",\r\n  ],\r\n  // ...\r\n};\r\n```\r\n\r\n## Props\r\n\r\n| Prop              | Type                                     | Description                                                      |\r\n| :---------------- | :--------------------------------------- | :--------------------------------------------------------------- |\r\n| `sites`           | `SiteSchedule[]`                         | List of sites and their respective schedules.                    |\r\n| `startDate`       | `Date` (optional)                        | The date to start the calendar's weekly view. Defaults to `now`. |\r\n| `onSiteChange`    | `(siteId: string) => void` (optional)    | Callback when the site filter changes.                           |\r\n| `onShiftClick`    | `(shift, date, site) => void` (optional) | Callback when a shift badge is clicked.                          |\r\n| `onDateCellClick` | `(date, site) => void` (optional)        | Callback when an empty date cell is clicked.                     |\r\n\r\n## Handling Interactions\r\n\r\nThe `OperationsCalendar` provides callback props to handle user interactions. This is ideal for opening modals, sidebars, or navigating to detailed shift pages.\r\n\r\n### Example: Opening a Modal on Shift Click\r\n\r\nTo 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:\r\n\r\n```tsx\r\nimport { useState } from \"react\";\r\nimport { OperationsCalendar } from \"@ctrl-room/operations-calendar\";\r\n\r\nfunction App() {\r\n  const [isModalOpen, setIsModalOpen] = useState(false);\r\n  const [selectedShift, setSelectedShift] = useState(null);\r\n\r\n  const handleShiftClick = (shift, date, site) => {\r\n    setSelectedShift({ shift, date, site });\r\n    setIsModalOpen(true);\r\n  };\r\n\r\n  return (\r\n    <>\r\n      <OperationsCalendar sites={sites} onShiftClick={handleShiftClick} />\r\n\r\n      {isModalOpen && (\r\n        <div className=\"modal\">\r\n          <h3>Shift Details</h3>\r\n          <p>Site: {selectedShift.site.siteName}</p>\r\n          <p>Shift: {selectedShift.shift.shiftCode}</p>\r\n          <button onClick={() => setIsModalOpen(false)}>Close</button>\r\n        </div>\r\n      )}\r\n    </>\r\n  );\r\n}\r\n```\r\n\r\n### Handling Multiple Actions (Example)\r\n\r\nYou can use the interaction callbacks to offer multiple choices, such as viewing vs editing:\r\n\r\n```tsx\r\nconst handleShiftClick = (shift, date, site) => {\r\n  if (shift.status === \"unpublished\") {\r\n    // Show 'Publish' or 'Edit' options\r\n    openEditModal(shift);\r\n  } else {\r\n    // Show read-only details\r\n    showShiftDetails(shift);\r\n  }\r\n};\r\n```\r\n\r\n### Example: Creating a Shift on Empty Cell Click\r\n\r\nUse `onDateCellClick` to let users add new shifts to the schedule:\r\n\r\n```tsx\r\nconst handleDateCellClick = (date, site) => {\r\n  // Open a 'New Shift' form with pre-filled date and site\r\n  setNewShiftDefaults({ date, siteId: site.siteId });\r\n  setIsCreateModalOpen(true);\r\n};\r\n\r\nreturn (\r\n  <OperationsCalendar\r\n    onDateCellClick={handleDateCellClick}\r\n    // ... other props\r\n  />\r\n);\r\n```\r\n\r\n## License\r\n\r\nMIT © [Ctrl Room](https://github.com/ctrl-room)\r\n","readmeFilename":"README.md","_rev":"1-f539cc51d2bfa311dbd7142d8d65e80b"}