@hectorbliss/denik-calendar 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,7 +24,6 @@ function App() {
24
24
  <Calendar
25
25
  events={events}
26
26
  onEventMove={(eventId, newStart) => {
27
- // Handle event move
28
27
  setEvents(prev =>
29
28
  prev.map(e => (e.id === eventId ? { ...e, start: newStart } : e))
30
29
  );
@@ -43,84 +42,175 @@ function App() {
43
42
  }
44
43
  ```
45
44
 
46
- ## Headless Hook
45
+ ## Resource Mode (Day View)
47
46
 
48
- Use the calendar logic without the UI:
47
+ Display resources (courts, rooms, employees) as columns instead of weekdays:
49
48
 
50
49
  ```tsx
51
- import { useCalendarEvents } from "@hectorbliss/denik-calendar";
50
+ import { Calendar, useCalendarControls } from "@hectorbliss/denik-calendar";
51
+
52
+ const courts = [
53
+ { id: "court-1", name: "Cancha 1", icon: <PadelIcon /> },
54
+ { id: "court-2", name: "Cancha 2", icon: <PadelIcon /> },
55
+ { id: "court-3", name: "Cancha 3", icon: <TennisIcon /> },
56
+ { id: "court-4", name: "Cancha 4", icon: <TennisIcon /> },
57
+ ];
58
+
59
+ // Events with resourceId
60
+ const events = [
61
+ { id: "1", start: new Date(), duration: 90, title: "Match", resourceId: "court-1" },
62
+ { id: "2", start: new Date(), duration: 60, title: "Training", resourceId: "court-2" },
63
+ ];
64
+
65
+ function CourtSchedule() {
66
+ return (
67
+ <Calendar
68
+ events={events}
69
+ date={selectedDay}
70
+ resources={courts}
71
+ />
72
+ );
73
+ }
74
+ ```
75
+
76
+ ## Navigation Controls
52
77
 
53
- function MyCustomCalendar({ events }) {
54
- const {
55
- canMove,
56
- hasOverlap,
57
- findConflicts,
58
- getEventsForDay,
59
- getEventsForWeek,
60
- findAvailableSlots
61
- } = useCalendarEvents(events);
62
-
63
- const handleDrop = (eventId, newStart) => {
64
- if (canMove(eventId, newStart)) {
65
- updateEvent(eventId, newStart);
66
- } else {
67
- toast.error("Time slot occupied");
68
- }
69
- };
70
-
71
- // Get available 60-min slots for today (8am-6pm)
72
- const slots = findAvailableSlots(new Date(), 60);
78
+ Use the headless hook for complete control:
79
+
80
+ ```tsx
81
+ import { Calendar, useCalendarControls, CalendarControls } from "@hectorbliss/denik-calendar";
82
+
83
+ function App() {
84
+ const controls = useCalendarControls();
85
+
86
+ return (
87
+ <>
88
+ {/* Pre-built controls */}
89
+ <CalendarControls controls={controls} />
90
+
91
+ {/* Or build your own */}
92
+ <div>
93
+ <button onClick={controls.goToToday}>HOY</button>
94
+ <button onClick={controls.goToPrev}>←</button>
95
+ <button onClick={controls.goToNext}>→</button>
96
+ <span>{controls.label}</span>
97
+ <button onClick={controls.toggleView}>
98
+ {controls.view === "week" ? "DÍA" : "SEMANA"}
99
+ </button>
100
+ </div>
101
+
102
+ <Calendar
103
+ date={controls.date}
104
+ events={events}
105
+ resources={controls.view === "day" ? courts : undefined}
106
+ />
107
+ </>
108
+ );
73
109
  }
74
110
  ```
75
111
 
112
+ ## Visual Overlaps
113
+
114
+ Events at the same time are displayed side-by-side automatically.
115
+
116
+ ## Headless Hooks
117
+
118
+ ### useCalendarEvents
119
+
120
+ ```tsx
121
+ import { useCalendarEvents } from "@hectorbliss/denik-calendar";
122
+
123
+ const {
124
+ canMove, // Check if event can move to new time
125
+ hasOverlap, // Check if time slot has conflicts
126
+ findConflicts, // Get all conflicting events
127
+ getEventsForDay, // Filter events by day
128
+ getEventsForWeek, // Filter events by week
129
+ findAvailableSlots // Get available time slots
130
+ } = useCalendarEvents(events);
131
+ ```
132
+
133
+ ### useCalendarControls
134
+
135
+ ```tsx
136
+ import { useCalendarControls } from "@hectorbliss/denik-calendar";
137
+
138
+ const {
139
+ date, // Current date
140
+ view, // "week" | "day"
141
+ week, // Array of 7 dates (Mon-Sun)
142
+ label, // Formatted date label
143
+ isToday, // Boolean
144
+ goToToday, // Navigate to today
145
+ goToPrev, // Navigate back (7 days or 1 day)
146
+ goToNext, // Navigate forward
147
+ toggleView, // Switch between week/day
148
+ setDate, // Set specific date
149
+ setView, // Set specific view
150
+ } = useCalendarControls({ locale: "es-MX" });
151
+ ```
152
+
76
153
  ## Props
77
154
 
78
155
  ### Calendar
79
156
 
80
157
  | Prop | Type | Description |
81
158
  |------|------|-------------|
82
- | `events` | `CalendarEvent[]` | Array of events to display |
83
- | `date` | `Date` | Current week to display (default: today) |
84
- | `onEventMove` | `(eventId, newStart) => void` | Called when event is dragged |
85
- | `onAddBlock` | `(start) => void` | Called when creating a block |
86
- | `onRemoveBlock` | `(eventId) => void` | Called when removing a block |
87
- | `onEventClick` | `(event) => void` | Called when clicking an event |
88
- | `onNewEvent` | `(start) => void` | Called when clicking empty slot |
89
- | `config` | `CalendarConfig` | Configuration options |
90
-
91
- ### CalendarEvent
159
+ | `events` | `CalendarEvent[]` | Array of events |
160
+ | `date` | `Date` | Current date (default: today) |
161
+ | `resources` | `Resource[]` | Resources for day view mode |
162
+ | `onEventMove` | `(eventId, newStart) => void` | Drag handler |
163
+ | `onAddBlock` | `(start) => void` | Block creation |
164
+ | `onRemoveBlock` | `(eventId) => void` | Block removal |
165
+ | `onEventClick` | `(event) => void` | Click handler |
166
+ | `onNewEvent` | `(start) => void` | Empty slot click |
167
+ | `config` | `CalendarConfig` | Configuration |
168
+
169
+ ### Types
92
170
 
93
171
  ```typescript
94
172
  interface CalendarEvent {
95
173
  id: string;
96
174
  start: Date;
97
- duration: number; // minutes
175
+ duration: number; // minutes
98
176
  title?: string;
99
177
  type?: "BLOCK" | "EVENT";
178
+ resourceId?: string; // For resource mode
100
179
  service?: { name: string };
101
180
  }
102
- ```
103
181
 
104
- ### CalendarConfig
182
+ interface Resource {
183
+ id: string;
184
+ name: string;
185
+ icon?: ReactNode;
186
+ }
105
187
 
106
- ```typescript
107
188
  interface CalendarConfig {
108
- locale?: string; // default: "es-MX"
109
- icons?: {
110
- trash?: ReactNode;
111
- edit?: ReactNode;
112
- close?: ReactNode;
113
- };
189
+ locale?: string;
190
+ icons?: { trash?, edit?, close? };
191
+ renderColumnHeader?: (props: ColumnHeaderProps) => ReactNode;
192
+ }
193
+
194
+ interface ColumnHeaderProps {
195
+ date: Date;
196
+ index: number;
197
+ isToday: boolean;
198
+ locale: string;
199
+ resource?: Resource;
114
200
  }
115
201
  ```
116
202
 
117
203
  ## Features
118
204
 
119
- - Drag & drop events between time slots
120
- - Automatic overlap detection
205
+ - Drag & drop events
206
+ - Visual overlap rendering
207
+ - Resource/day view mode
208
+ - Week view mode
209
+ - Navigation controls (hook + component)
121
210
  - Block time slots
122
- - Week navigation
123
211
  - Auto-scroll to current hour
212
+ - Custom column headers
213
+ - Horizontal scroll for many resources
124
214
  - Customizable icons
125
215
  - Locale support
126
216
  - TypeScript support