@dialiq/calendar-component 1.1.1 → 1.1.3
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/dist/BookingDetailsModal.d.ts +3 -0
- package/dist/BookingDetailsModal.d.ts.map +1 -1
- package/dist/Calendar.d.ts.map +1 -1
- package/dist/api.d.ts +6 -3
- package/dist/api.d.ts.map +1 -1
- package/dist/components/CalendarHeader.d.ts +0 -1
- package/dist/components/CalendarHeader.d.ts.map +1 -1
- package/dist/components/TimeGrid.d.ts.map +1 -1
- package/dist/index.esm.js +74 -37
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +74 -37
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +48 -48
package/dist/index.js
CHANGED
|
@@ -7357,11 +7357,14 @@ const createBooking = (businessId, booking, apiBaseUrl) => __awaiter(void 0, voi
|
|
|
7357
7357
|
}
|
|
7358
7358
|
return response.json();
|
|
7359
7359
|
});
|
|
7360
|
-
const getResourceSchedule = (businessId, resourceId, startDate, endDate, apiBaseUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
7360
|
+
const getResourceSchedule = (businessId, resourceId, startDate, endDate, timezone, apiBaseUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
7361
7361
|
const baseUrl = apiBaseUrl || getBaseUrl();
|
|
7362
7362
|
const url = new URL(`${baseUrl}/businesses/${businessId}/schedules/${resourceId}`);
|
|
7363
7363
|
url.searchParams.append('start_date', startDate);
|
|
7364
7364
|
url.searchParams.append('end_date', endDate);
|
|
7365
|
+
if (timezone) {
|
|
7366
|
+
url.searchParams.append('timezone', timezone);
|
|
7367
|
+
}
|
|
7365
7368
|
const response = yield fetch(url.toString());
|
|
7366
7369
|
if (!response.ok) {
|
|
7367
7370
|
const error = yield response.json();
|
|
@@ -7369,11 +7372,14 @@ const getResourceSchedule = (businessId, resourceId, startDate, endDate, apiBase
|
|
|
7369
7372
|
}
|
|
7370
7373
|
return response.json();
|
|
7371
7374
|
});
|
|
7372
|
-
const getAllBookings = (businessId, startDate, endDate, apiBaseUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
7375
|
+
const getAllBookings = (businessId, startDate, endDate, timezone, apiBaseUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
7373
7376
|
const baseUrl = apiBaseUrl || getBaseUrl();
|
|
7374
7377
|
const url = new URL(`${baseUrl}/businesses/${businessId}/bookings`);
|
|
7375
7378
|
url.searchParams.append('start_date', startDate);
|
|
7376
7379
|
url.searchParams.append('end_date', endDate);
|
|
7380
|
+
if (timezone) {
|
|
7381
|
+
url.searchParams.append('timezone', timezone);
|
|
7382
|
+
}
|
|
7377
7383
|
const response = yield fetch(url.toString());
|
|
7378
7384
|
if (!response.ok) {
|
|
7379
7385
|
const error = yield response.json();
|
|
@@ -7381,15 +7387,30 @@ const getAllBookings = (businessId, startDate, endDate, apiBaseUrl) => __awaiter
|
|
|
7381
7387
|
}
|
|
7382
7388
|
return response.json();
|
|
7383
7389
|
});
|
|
7384
|
-
const getMeetingDetails = (businessId, meetingId, apiBaseUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
7390
|
+
const getMeetingDetails = (businessId, meetingId, timezone, apiBaseUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
7385
7391
|
const baseUrl = apiBaseUrl || getBaseUrl();
|
|
7386
|
-
const
|
|
7392
|
+
const url = new URL(`${baseUrl}/businesses/${businessId}/meetings/${meetingId}`);
|
|
7393
|
+
if (timezone) {
|
|
7394
|
+
url.searchParams.append('timezone', timezone);
|
|
7395
|
+
}
|
|
7396
|
+
const response = yield fetch(url.toString());
|
|
7387
7397
|
if (!response.ok) {
|
|
7388
7398
|
const error = yield response.json();
|
|
7389
7399
|
throw new Error(error.error || 'Failed to fetch meeting details');
|
|
7390
7400
|
}
|
|
7391
7401
|
return response.json();
|
|
7392
7402
|
});
|
|
7403
|
+
const deleteMeeting = (businessId, meetingId, apiBaseUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
7404
|
+
const baseUrl = apiBaseUrl || getBaseUrl();
|
|
7405
|
+
const response = yield fetch(`${baseUrl}/businesses/${businessId}/meetings/${meetingId}`, {
|
|
7406
|
+
method: 'DELETE',
|
|
7407
|
+
});
|
|
7408
|
+
if (!response.ok) {
|
|
7409
|
+
const error = yield response.json();
|
|
7410
|
+
throw new Error(error.error || 'Failed to delete meeting');
|
|
7411
|
+
}
|
|
7412
|
+
return response.json();
|
|
7413
|
+
});
|
|
7393
7414
|
|
|
7394
7415
|
function styleInject(css, ref) {
|
|
7395
7416
|
if ( ref === void 0 ) ref = {};
|
|
@@ -7437,7 +7458,7 @@ const CreateBookingModal = ({ businessId, apiBaseUrl, initialDate, participants:
|
|
|
7437
7458
|
const dayName = start.format('dddd');
|
|
7438
7459
|
const businessDay = businessHours[dayName];
|
|
7439
7460
|
if (!businessDay)
|
|
7440
|
-
return; // Assuming open if not defined, or closed? Usually open if not specified or handle as error.
|
|
7461
|
+
return; // Assuming open if not defined, or closed? Usually open if not specified or handle as error.
|
|
7441
7462
|
// Based on provided JSON, all days are present. If missing, maybe assume open.
|
|
7442
7463
|
if (businessDay.isClosed) {
|
|
7443
7464
|
throw new Error(`Business is closed on ${dayName}`);
|
|
@@ -7477,8 +7498,8 @@ const CreateBookingModal = ({ businessId, apiBaseUrl, initialDate, participants:
|
|
|
7477
7498
|
validateBusinessHours(startDateTime, endDateTime);
|
|
7478
7499
|
const booking = yield createBooking(businessId, {
|
|
7479
7500
|
participants: participantList,
|
|
7480
|
-
start: startDateTime.
|
|
7481
|
-
end: endDateTime.
|
|
7501
|
+
start: startDateTime.format(),
|
|
7502
|
+
end: endDateTime.format(),
|
|
7482
7503
|
metadata: {
|
|
7483
7504
|
title: title || 'Untitled Meeting',
|
|
7484
7505
|
description,
|
|
@@ -7531,20 +7552,48 @@ const CreateBookingModal = ({ businessId, apiBaseUrl, initialDate, participants:
|
|
|
7531
7552
|
React.createElement("button", { type: "submit", className: "modal-btn modal-btn-primary", disabled: loading }, loading ? 'Creating...' : 'Create Booking'))))));
|
|
7532
7553
|
};
|
|
7533
7554
|
|
|
7534
|
-
var css_248z$1 = "/* BookingDetailsModal - extends base modal styles from CreateBookingModal.css */\
|
|
7555
|
+
var css_248z$1 = "/* BookingDetailsModal - extends base modal styles from CreateBookingModal.css */\n\n.booking-details-modal {\n max-width: 500px;\n}\n\n.detail-section {\n padding: 12px 0;\n border-bottom: 1px solid #e9ecef;\n}\n\n.detail-section:last-child {\n border-bottom: none;\n}\n\n.detail-row {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 8px;\n}\n\n.detail-row:last-child {\n margin-bottom: 0;\n}\n\n.detail-row.full-width {\n flex-direction: column;\n}\n\n.detail-label {\n font-weight: 500;\n color: #6c757d;\n font-size: 14px;\n min-width: 100px;\n}\n\n.detail-label-muted {\n color: #adb5bd;\n font-size: 12px;\n}\n\n.detail-value {\n font-weight: 500;\n color: #212529;\n font-size: 14px;\n text-align: right;\n}\n\n.detail-value-muted {\n color: #adb5bd;\n font-size: 12px;\n font-family: monospace;\n}\n\n.detail-description {\n margin: 8px 0 0 0;\n color: #495057;\n font-size: 14px;\n line-height: 1.5;\n white-space: pre-wrap;\n}\n\n.participants-list {\n margin: 8px 0 0 0;\n padding-left: 20px;\n list-style-type: disc;\n}\n\n.participant-item {\n color: #495057;\n font-size: 14px;\n margin-bottom: 4px;\n}\n\n.modal-header-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.modal-delete-btn {\n background: none;\n border: none;\n color: #dc3545;\n cursor: pointer;\n padding: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n transition: background-color 0.2s;\n}\n\n.modal-delete-btn:hover:not(:disabled) {\n background: #f8d7da;\n}\n\n.modal-delete-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.delete-confirm-box {\n background: #fff3cd;\n border: 1px solid #ffc107;\n border-radius: 4px;\n padding: 16px;\n margin-bottom: 16px;\n}\n\n.delete-confirm-box p {\n margin: 0 0 12px 0;\n font-size: 14px;\n color: #856404;\n}\n\n.delete-confirm-actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n}\n\n.modal-btn-danger {\n background: #dc3545;\n color: #ffffff;\n}\n\n.modal-btn-danger:hover:not(:disabled) {\n background: #bb2d3b;\n}\n\n@media (max-width: 576px) {\n .booking-details-modal {\n max-width: 100%;\n }\n\n .detail-row {\n flex-direction: column;\n gap: 4px;\n }\n\n .detail-value {\n text-align: left;\n }\n}\n";
|
|
7535
7556
|
styleInject(css_248z$1);
|
|
7536
7557
|
|
|
7537
|
-
const BookingDetailsModal = ({ booking, timezone, onClose, }) => {
|
|
7538
|
-
var _a, _b, _c, _d, _e, _f, _g, _h
|
|
7558
|
+
const BookingDetailsModal = ({ booking, timezone, businessId, apiBaseUrl, onClose, onBookingDeleted, }) => {
|
|
7559
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
7560
|
+
const [showConfirm, setShowConfirm] = React.useState(false);
|
|
7561
|
+
const [deleting, setDeleting] = React.useState(false);
|
|
7562
|
+
const [error, setError] = React.useState(null);
|
|
7539
7563
|
const startMoment = moment$1(booking.start).tz(timezone);
|
|
7540
7564
|
const endMoment = moment$1(booking.end).tz(timezone);
|
|
7541
7565
|
const durationMinutes = endMoment.diff(startMoment, 'minutes');
|
|
7566
|
+
const handleDelete = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
7567
|
+
setDeleting(true);
|
|
7568
|
+
setError(null);
|
|
7569
|
+
try {
|
|
7570
|
+
yield deleteMeeting(businessId, booking.meeting_id, apiBaseUrl);
|
|
7571
|
+
onBookingDeleted();
|
|
7572
|
+
}
|
|
7573
|
+
catch (err) {
|
|
7574
|
+
setError(err instanceof Error ? err.message : 'Failed to delete meeting');
|
|
7575
|
+
setDeleting(false);
|
|
7576
|
+
}
|
|
7577
|
+
});
|
|
7542
7578
|
return (React.createElement("div", { className: "modal-overlay", onClick: onClose },
|
|
7543
7579
|
React.createElement("div", { className: "modal-content booking-details-modal", onClick: (e) => e.stopPropagation() },
|
|
7544
7580
|
React.createElement("div", { className: "modal-header" },
|
|
7545
7581
|
React.createElement("h3", null, ((_a = booking.metadata) === null || _a === void 0 ? void 0 : _a.title) || 'Untitled Booking'),
|
|
7546
|
-
React.createElement("
|
|
7582
|
+
React.createElement("div", { className: "modal-header-actions" },
|
|
7583
|
+
React.createElement("button", { className: "modal-delete-btn", onClick: () => setShowConfirm(true), title: "Delete meeting", disabled: deleting },
|
|
7584
|
+
React.createElement("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" },
|
|
7585
|
+
React.createElement("polyline", { points: "3 6 5 6 21 6" }),
|
|
7586
|
+
React.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }),
|
|
7587
|
+
React.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }),
|
|
7588
|
+
React.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" }))),
|
|
7589
|
+
React.createElement("button", { className: "modal-close-btn", onClick: onClose }, "\u00D7"))),
|
|
7547
7590
|
React.createElement("div", { className: "modal-body" },
|
|
7591
|
+
error && React.createElement("div", { className: "modal-error" }, error),
|
|
7592
|
+
showConfirm && (React.createElement("div", { className: "delete-confirm-box" },
|
|
7593
|
+
React.createElement("p", null, "Are you sure you want to delete this meeting?"),
|
|
7594
|
+
React.createElement("div", { className: "delete-confirm-actions" },
|
|
7595
|
+
React.createElement("button", { className: "modal-btn modal-btn-secondary", onClick: () => setShowConfirm(false), disabled: deleting }, "Cancel"),
|
|
7596
|
+
React.createElement("button", { className: "modal-btn modal-btn-danger", onClick: handleDelete, disabled: deleting }, deleting ? 'Deleting...' : 'Delete')))),
|
|
7548
7597
|
React.createElement("div", { className: "detail-section" },
|
|
7549
7598
|
React.createElement("div", { className: "detail-row" },
|
|
7550
7599
|
React.createElement("span", { className: "detail-label" }, "Date:"),
|
|
@@ -7571,14 +7620,6 @@ const BookingDetailsModal = ({ booking, timezone, onClose, }) => {
|
|
|
7571
7620
|
(booking.room || ((_g = booking.metadata) === null || _g === void 0 ? void 0 : _g.room)) && (React.createElement("div", { className: "detail-row" },
|
|
7572
7621
|
React.createElement("span", { className: "detail-label" }, "Room:"),
|
|
7573
7622
|
React.createElement("span", { className: "detail-value" }, booking.room || ((_h = booking.metadata) === null || _h === void 0 ? void 0 : _h.room)))))),
|
|
7574
|
-
booking.participants && booking.participants.length > 0 && (React.createElement("div", { className: "detail-section" },
|
|
7575
|
-
React.createElement("div", { className: "detail-row full-width" },
|
|
7576
|
-
React.createElement("span", { className: "detail-label" }, "Participants:"),
|
|
7577
|
-
React.createElement("ul", { className: "participants-list" }, booking.participants.map((participant, index) => (React.createElement("li", { key: index, className: "participant-item" }, participant))))))),
|
|
7578
|
-
((_j = booking.metadata) === null || _j === void 0 ? void 0 : _j.organizer) && (React.createElement("div", { className: "detail-section" },
|
|
7579
|
-
React.createElement("div", { className: "detail-row" },
|
|
7580
|
-
React.createElement("span", { className: "detail-label" }, "Organizer:"),
|
|
7581
|
-
React.createElement("span", { className: "detail-value" }, booking.metadata.organizer)))),
|
|
7582
7623
|
React.createElement("div", { className: "detail-section" },
|
|
7583
7624
|
React.createElement("div", { className: "detail-row" },
|
|
7584
7625
|
React.createElement("span", { className: "detail-label detail-label-muted" }, "Meeting ID:"),
|
|
@@ -7714,7 +7755,7 @@ const isMobile = () => {
|
|
|
7714
7755
|
return false;
|
|
7715
7756
|
};
|
|
7716
7757
|
|
|
7717
|
-
const CalendarHeader = ({ title, currentView, onViewChange, onNext, onPrevious, onToday,
|
|
7758
|
+
const CalendarHeader = ({ title, currentView, onViewChange, onNext, onPrevious, onToday, dateRangeText, }) => {
|
|
7718
7759
|
const mobile = isMobile();
|
|
7719
7760
|
return (React.createElement("div", { className: "calendar-header" },
|
|
7720
7761
|
React.createElement("div", { className: "calendar-title-section" },
|
|
@@ -7724,12 +7765,11 @@ const CalendarHeader = ({ title, currentView, onViewChange, onNext, onPrevious,
|
|
|
7724
7765
|
React.createElement("button", { className: `calendar-btn calendar-btn-view ${currentView === 'week' ? 'active' : ''}`, onClick: () => onViewChange('week'), disabled: mobile, style: mobile ? { display: 'none' } : {} }, "Week"),
|
|
7725
7766
|
React.createElement("button", { className: `calendar-btn calendar-btn-view ${currentView === 'workWeek' ? 'active' : ''}`, onClick: () => onViewChange('workWeek'), disabled: mobile, style: mobile ? { display: 'none' } : {} }, "Work Week"),
|
|
7726
7767
|
React.createElement("button", { className: `calendar-btn calendar-btn-view ${currentView === 'day' ? 'active' : ''}`, onClick: () => onViewChange('day') }, "Day")),
|
|
7727
|
-
React.createElement("
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
React.createElement("span", { className: "calendar-current-month" }, dateRangeText))));
|
|
7768
|
+
React.createElement("div", { className: "calendar-navigation" },
|
|
7769
|
+
React.createElement("button", { className: "calendar-btn", onClick: onPrevious }, "\u2039"),
|
|
7770
|
+
React.createElement("button", { className: "calendar-btn", onClick: onToday }, "Today"),
|
|
7771
|
+
React.createElement("button", { className: "calendar-btn", onClick: onNext }, "\u203A"),
|
|
7772
|
+
React.createElement("span", { className: "calendar-current-month" }, dateRangeText)))));
|
|
7733
7773
|
};
|
|
7734
7774
|
|
|
7735
7775
|
const TimeGrid = ({ currentDate, view, bookings, timezone, onBookingClick, onTimeSlotClick, businessHours, }) => {
|
|
@@ -7753,7 +7793,6 @@ const TimeGrid = ({ currentDate, view, bookings, timezone, onBookingClick, onTim
|
|
|
7753
7793
|
days.forEach(day => {
|
|
7754
7794
|
const dayName = day.format('dddd');
|
|
7755
7795
|
const dayHours = businessHours[dayName];
|
|
7756
|
-
console.log('Day:', dayName, 'Hours:', dayHours);
|
|
7757
7796
|
if (!(dayHours === null || dayHours === void 0 ? void 0 : dayHours.isClosed) && (dayHours === null || dayHours === void 0 ? void 0 : dayHours.openTime) && (dayHours === null || dayHours === void 0 ? void 0 : dayHours.closeTime)) {
|
|
7758
7797
|
const openTime = moment$1(dayHours.openTime, ['h:mm A', 'hh:mm A'], true);
|
|
7759
7798
|
const closeTime = moment$1(dayHours.closeTime, ['h:mm A', 'hh:mm A'], true);
|
|
@@ -7764,7 +7803,6 @@ const TimeGrid = ({ currentDate, view, bookings, timezone, onBookingClick, onTim
|
|
|
7764
7803
|
const openMinutes = openTime.hours() * 60 + openTime.minutes();
|
|
7765
7804
|
const closeMinutes = closeTime.hours() * 60 + closeTime.minutes();
|
|
7766
7805
|
const duration = closeMinutes - openMinutes;
|
|
7767
|
-
console.log(' Open:', dayHours.openTime, '->', openMinutes, '| Close:', dayHours.closeTime, '->', closeMinutes, '| Duration:', duration);
|
|
7768
7806
|
if (openMinutes < closeMinutes && duration > maxDuration) {
|
|
7769
7807
|
maxDuration = duration;
|
|
7770
7808
|
longestDayOpen = openMinutes;
|
|
@@ -7772,7 +7810,6 @@ const TimeGrid = ({ currentDate, view, bookings, timezone, onBookingClick, onTim
|
|
|
7772
7810
|
}
|
|
7773
7811
|
}
|
|
7774
7812
|
});
|
|
7775
|
-
console.log('Longest: open =', longestDayOpen, 'close =', longestDayClose);
|
|
7776
7813
|
if (maxDuration === 0) {
|
|
7777
7814
|
return {
|
|
7778
7815
|
displayStart: 0,
|
|
@@ -7978,7 +8015,7 @@ const MonthView = ({ currentDate, bookings, timezone, onBookingClick, onDateClic
|
|
|
7978
8015
|
React.createElement("div", { className: "calendar-body" }, rows)));
|
|
7979
8016
|
};
|
|
7980
8017
|
|
|
7981
|
-
var css_248z = ".calendar-container {\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n
|
|
8018
|
+
var css_248z = ".calendar-container {\r\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\r\n border: 1px solid #e0e0e0;\r\n border-radius: 8px;\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n /* Use 100% height of parent */\r\n max-height: 100vh;\r\n overflow: hidden;\r\n}\r\n\r\n/* Header */\r\n.calendar-header {\r\n padding: 16px;\r\n border-bottom: 1px solid #e0e0e0;\r\n background-color: #fff;\r\n}\r\n\r\n.calendar-title-section {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n margin-bottom: 16px;\r\n flex-wrap: wrap;\r\n gap: 10px;\r\n}\r\n\r\n.calendar-title {\r\n margin: 0;\r\n font-size: 1.5rem;\r\n color: #333;\r\n}\r\n\r\n.calendar-view-toggle {\r\n display: flex;\r\n background-color: #f5f5f5;\r\n border-radius: 6px;\r\n padding: 2px;\r\n}\r\n\r\n.calendar-btn {\r\n padding: 8px 16px;\r\n border: 1px solid #e0e0e0;\r\n background-color: #fff;\r\n cursor: pointer;\r\n border-radius: 4px;\r\n font-size: 14px;\r\n transition: all 0.2s;\r\n}\r\n\r\n.calendar-btn:hover {\r\n background-color: #f5f5f5;\r\n}\r\n\r\n.calendar-btn-view {\r\n border: none;\r\n background: transparent;\r\n border-radius: 4px;\r\n padding: 6px 12px;\r\n}\r\n\r\n.calendar-btn-view.active {\r\n background-color: #fff;\r\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\r\n font-weight: 600;\r\n}\r\n\r\n.calendar-btn-create {\r\n background-color: #0078d4;\r\n color: white;\r\n border: none;\r\n}\r\n\r\n.calendar-btn-create:hover {\r\n background-color: #106ebe;\r\n}\r\n\r\n.calendar-navigation {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n}\r\n\r\n.calendar-current-month {\r\n font-size: 1.1rem;\r\n font-weight: 600;\r\n margin-left: 16px;\r\n color: #333;\r\n}\r\n\r\n/* Content Area */\r\n.calendar-content {\r\n flex: 1;\r\n overflow: hidden;\r\n display: flex;\r\n flex-direction: column;\r\n}\r\n\r\n/* Month View */\r\n.month-view-container {\r\n flex: 1;\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n /* Prevent container scrolling, let body scroll */\r\n}\r\n\r\n.calendar-days-row {\r\n display: grid;\r\n grid-template-columns: repeat(7, 1fr);\r\n /* Ensure equal columns */\r\n border-bottom: 1px solid #e0e0e0;\r\n background-color: #f9f9f9;\r\n}\r\n\r\n.calendar-day-header {\r\n padding: 10px;\r\n text-align: center;\r\n font-weight: 600;\r\n color: #666;\r\n font-size: 0.9rem;\r\n overflow: hidden;\r\n /* Prevent overflow */\r\n text-overflow: ellipsis;\r\n}\r\n\r\n.calendar-body {\r\n display: flex;\r\n flex-direction: column;\r\n flex: 1;\r\n overflow-y: auto;\r\n /* Scrollable body */\r\n}\r\n\r\n.calendar-row {\r\n display: grid;\r\n grid-template-columns: repeat(7, 1fr);\r\n /* Ensure equal columns */\r\n flex: 1;\r\n min-height: 100px;\r\n /* Minimum row height */\r\n border-bottom: 1px solid #e0e0e0;\r\n}\r\n\r\n.calendar-cell {\r\n border-right: 1px solid #e0e0e0;\r\n padding: 8px;\r\n position: relative;\r\n cursor: pointer;\r\n transition: background-color 0.2s;\r\n overflow: hidden;\r\n /* Prevent cell expansion */\r\n min-width: 0;\r\n /* Allow shrinking below content size */\r\n}\r\n\r\n.calendar-cell:hover {\r\n background-color: #fcfcfc;\r\n}\r\n\r\n.calendar-cell-disabled {\r\n background-color: #f9f9f9;\r\n color: #999;\r\n}\r\n\r\n.calendar-cell-today {\r\n background-color: #e6f2ff;\r\n}\r\n\r\n.calendar-cell-closed {\r\n background-color: #f5f5f5;\r\n cursor: not-allowed;\r\n}\r\n\r\n.calendar-cell-header {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n margin-bottom: 4px;\r\n}\r\n\r\n.calendar-cell-number {\r\n font-weight: 600;\r\n font-size: 0.9rem;\r\n}\r\n\r\n.calendar-closed-label-small {\r\n font-size: 0.7rem;\r\n color: #d13438;\r\n background: #fde7e9;\r\n padding: 2px 4px;\r\n border-radius: 3px;\r\n}\r\n\r\n.calendar-cell-bookings {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n}\r\n\r\n.calendar-booking {\r\n background-color: #e1dfdd;\r\n /* Default neutral color */\r\n border-left: 3px solid #0078d4;\r\n padding: 4px 6px;\r\n border-radius: 2px;\r\n font-size: 0.8rem;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n cursor: pointer;\r\n position: relative;\r\n /* For tooltip positioning */\r\n}\r\n\r\n.calendar-booking:hover {\r\n background-color: #d0d0d0;\r\n}\r\n\r\n.calendar-booking-time {\r\n font-weight: 600;\r\n margin-right: 4px;\r\n}\r\n\r\n.calendar-booking-more {\r\n font-size: 0.8rem;\r\n color: #666;\r\n padding: 2px 4px;\r\n}\r\n\r\n/* Time Grid (Day/Week/WorkWeek) */\r\n.time-grid-container {\r\n display: flex;\r\n flex-direction: column;\r\n flex: 1;\r\n overflow: hidden;\r\n}\r\n\r\n.time-grid-header {\r\n display: flex;\r\n border-bottom: 1px solid #e0e0e0;\r\n padding-right: 17px;\r\n /* Adjust for scrollbar */\r\n}\r\n\r\n.time-column-header {\r\n width: 60px;\r\n /* Width of time labels column */\r\n flex-shrink: 0;\r\n border-right: 1px solid #e0e0e0;\r\n}\r\n\r\n.day-column-header {\r\n flex: 1;\r\n text-align: center;\r\n padding: 8px;\r\n border-right: 1px solid #e0e0e0;\r\n background-color: #f9f9f9;\r\n min-width: 0;\r\n /* Prevent expansion */\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n}\r\n\r\n.day-column-header.today {\r\n background-color: #e6f2ff;\r\n color: #0078d4;\r\n}\r\n\r\n.day-column-header.closed {\r\n background-color: #f0f0f0;\r\n color: #999;\r\n}\r\n\r\n.day-name {\r\n font-size: 0.8rem;\r\n text-transform: uppercase;\r\n color: #666;\r\n}\r\n\r\n.day-number {\r\n font-size: 1.2rem;\r\n font-weight: 600;\r\n}\r\n\r\n.time-grid-body {\r\n display: flex;\r\n flex: 1;\r\n overflow-y: auto;\r\n position: relative;\r\n}\r\n\r\n.time-labels-column {\r\n width: 60px;\r\n flex-shrink: 0;\r\n border-right: 1px solid #e0e0e0;\r\n background-color: #fff;\r\n}\r\n\r\n.time-label {\r\n height: 60px;\r\n /* 1 hour height */\r\n text-align: right;\r\n padding-right: 8px;\r\n font-size: 0.75rem;\r\n color: #666;\r\n justify-content: center;\r\n}\r\n\r\n.days-grid {\r\n flex: 1;\r\n display: flex;\r\n position: relative;\r\n /* 24 hours * 60px/hour = 1440px total height */\r\n height: 1440px;\r\n}\r\n\r\n.grid-lines {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n pointer-events: none;\r\n z-index: 0;\r\n}\r\n\r\n.grid-hour-row {\r\n height: 60px;\r\n border-bottom: 1px solid #e0e0e0;\r\n box-sizing: border-box;\r\n}\r\n\r\n.grid-hour-row:last-child {\r\n border-bottom: none;\r\n}\r\n\r\n.day-column {\r\n flex: 1;\r\n border-right: 1px solid #e0e0e0;\r\n position: relative;\r\n height: 100%;\r\n min-width: 0;\r\n /* Critical for flex containers to not expand based on content */\r\n}\r\n\r\n.day-column.closed-column {\r\n background-color: repeating-linear-gradient(45deg,\r\n #fbfbfb,\r\n #fbfbfb 10px,\r\n #f5f5f5 10px,\r\n #f5f5f5 20px);\r\n}\r\n\r\n.calendar-event {\r\n background-color: #e1dfdd;\r\n border-left: 4px solid #0078d4;\r\n border-radius: 3px;\r\n padding: 2px 4px;\r\n font-size: 0.75rem;\r\n overflow: hidden;\r\n cursor: pointer;\r\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\r\n z-index: 1;\r\n transition: transform 0.1s, z-index 0.1s;\r\n}\r\n\r\n.calendar-event:hover {\r\n z-index: 10;\r\n /* Bring to front on hover */\r\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);\r\n}\r\n\r\n.event-content {\r\n height: 100%;\r\n overflow: hidden;\r\n}\r\n\r\n.event-title {\r\n font-weight: 600;\r\n margin-bottom: 2px;\r\n}\r\n\r\n.event-time {\r\n font-size: 0.7rem;\r\n color: #555;\r\n}\r\n\r\n/* Tooltip Styles */\r\n.event-tooltip {\r\n display: none;\r\n position: absolute;\r\n left: 100%;\r\n top: 0;\r\n background: white;\r\n border: 1px solid #ccc;\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\r\n padding: 10px;\r\n border-radius: 4px;\r\n width: 200px;\r\n z-index: 100;\r\n pointer-events: none;\r\n}\r\n\r\n/* Show tooltip on hover */\r\n.calendar-booking:hover .event-tooltip,\r\n.calendar-event:hover .event-tooltip {\r\n display: block;\r\n}\r\n\r\n/* Adjust tooltip position if it goes offscreen (simple right-side check) */\r\n/* Note: A real production app would use a library like Popper.js */\r\n.day-column:last-child .event-tooltip,\r\n.day-column:nth-last-child(2) .event-tooltip {\r\n left: auto;\r\n right: 100%;\r\n}\r\n\r\n.tooltip-title {\r\n font-weight: bold;\r\n margin-bottom: 8px;\r\n border-bottom: 1px solid #eee;\r\n padding-bottom: 4px;\r\n}\r\n\r\n.tooltip-row {\r\n display: flex;\r\n justify-content: space-between;\r\n margin-bottom: 4px;\r\n font-size: 0.85rem;\r\n}\r\n\r\n.tooltip-label {\r\n color: #666;\r\n margin-right: 8px;\r\n}\r\n\r\n.tooltip-value {\r\n font-weight: 500;\r\n text-align: right;\r\n}\r\n\r\n/* Loading & Error */\r\n.calendar-loading,\r\n.calendar-error {\r\n padding: 20px;\r\n text-align: center;\r\n color: #666;\r\n}\r\n\r\n.calendar-error {\r\n color: #d13438;\r\n}\r\n\r\n/* Closed Block Styles */\r\n.calendar-closed-block {\r\n position: absolute;\r\n left: 0;\r\n right: 0;\r\n background-color: #f0f0f0;\r\n background-image: repeating-linear-gradient(45deg,\r\n #f0f0f0,\r\n #f0f0f0 10px,\r\n #e8e8e8 10px,\r\n #e8e8e8 20px);\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n z-index: 5;\r\n /* Below events but above grid lines */\r\n pointer-events: none;\r\n /* Allow clicks to pass through if needed, though we block clicks in JS */\r\n border-bottom: 1px solid #ddd;\r\n border-top: 1px solid #ddd;\r\n}\r\n\r\n.closed-block-label {\r\n background-color: rgba(255, 255, 255, 0.8);\r\n padding: 4px 8px;\r\n border-radius: 4px;\r\n font-size: 0.8rem;\r\n color: #888;\r\n font-weight: 500;\r\n}";
|
|
7982
8019
|
styleInject(css_248z);
|
|
7983
8020
|
|
|
7984
8021
|
const Calendar = ({ businessId, resourceId, title = 'Calendar', apiBaseUrl, defaultView = 'month', onBookingCreate, onBookingClick, participants = [], timezone = moment$1.tz.guess(), businessHours, }) => {
|
|
@@ -8033,10 +8070,10 @@ const Calendar = ({ businessId, resourceId, title = 'Calendar', apiBaseUrl, defa
|
|
|
8033
8070
|
}
|
|
8034
8071
|
let fetchedBookings;
|
|
8035
8072
|
if (resourceId) {
|
|
8036
|
-
fetchedBookings = yield getResourceSchedule(businessId, resourceId, startDate.toISOString(), endDate.toISOString(), apiBaseUrl);
|
|
8073
|
+
fetchedBookings = yield getResourceSchedule(businessId, resourceId, startDate.toISOString(), endDate.toISOString(), timezone, apiBaseUrl);
|
|
8037
8074
|
}
|
|
8038
8075
|
else {
|
|
8039
|
-
fetchedBookings = yield getAllBookings(businessId, startDate.toISOString(), endDate.toISOString(), apiBaseUrl);
|
|
8076
|
+
fetchedBookings = yield getAllBookings(businessId, startDate.toISOString(), endDate.toISOString(), timezone, apiBaseUrl);
|
|
8040
8077
|
}
|
|
8041
8078
|
setBookings(fetchedBookings);
|
|
8042
8079
|
}
|
|
@@ -8113,15 +8150,15 @@ const Calendar = ({ businessId, resourceId, title = 'Calendar', apiBaseUrl, defa
|
|
|
8113
8150
|
}
|
|
8114
8151
|
};
|
|
8115
8152
|
return (React.createElement("div", { className: "calendar-container" },
|
|
8116
|
-
React.createElement(CalendarHeader, { title: title, currentView: currentView, onViewChange: setCurrentView, onNext: handleNext, onPrevious: handlePrevious, onToday: handleToday,
|
|
8117
|
-
setSelectedDate(moment$1().tz(timezone).toDate());
|
|
8118
|
-
setShowCreateModal(true);
|
|
8119
|
-
}, dateRangeText: getHeaderDateFormat() }),
|
|
8153
|
+
React.createElement(CalendarHeader, { title: title, currentView: currentView, onViewChange: setCurrentView, onNext: handleNext, onPrevious: handlePrevious, onToday: handleToday, dateRangeText: getHeaderDateFormat() }),
|
|
8120
8154
|
error && React.createElement("div", { className: "calendar-error" }, error),
|
|
8121
8155
|
loading && React.createElement("div", { className: "calendar-loading" }, "Loading..."),
|
|
8122
8156
|
React.createElement("div", { className: "calendar-content" }, currentView === 'month' ? (React.createElement(MonthView, { currentDate: currentDate, bookings: bookings, timezone: timezone, onBookingClick: handleInternalBookingClick, onDateClick: handleDateClick, businessHours: businessHours })) : (React.createElement(TimeGrid, { currentDate: currentDate, view: currentView, bookings: bookings, timezone: timezone, onBookingClick: handleInternalBookingClick, onTimeSlotClick: handleDateClick, businessHours: businessHours }))),
|
|
8123
8157
|
showCreateModal && selectedDate && (React.createElement(CreateBookingModal, { businessId: businessId, apiBaseUrl: apiBaseUrl, initialDate: selectedDate, participants: participants, onClose: () => setShowCreateModal(false), onBookingCreated: handleBookingCreated, timezone: timezone, businessHours: businessHours })),
|
|
8124
|
-
selectedBooking && (React.createElement(BookingDetailsModal, { booking: selectedBooking, timezone: timezone, onClose: () => setSelectedBooking(null)
|
|
8158
|
+
selectedBooking && (React.createElement(BookingDetailsModal, { booking: selectedBooking, timezone: timezone, businessId: businessId, apiBaseUrl: apiBaseUrl, onClose: () => setSelectedBooking(null), onBookingDeleted: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
8159
|
+
setSelectedBooking(null);
|
|
8160
|
+
yield fetchBookings();
|
|
8161
|
+
}) }))));
|
|
8125
8162
|
};
|
|
8126
8163
|
|
|
8127
8164
|
exports.Calendar = Calendar;
|