update
This commit is contained in:
@@ -21,6 +21,14 @@
|
||||
return date.getFullYear() + '-' + pad(date.getMonth() + 1) + '-' + pad(date.getDate());
|
||||
}
|
||||
|
||||
function firstOfMonth(d) {
|
||||
return new Date(d.getFullYear(), d.getMonth(), 1);
|
||||
}
|
||||
|
||||
function nextMonthFirst(d) {
|
||||
return new Date(d.getFullYear(), d.getMonth() + 1, 1);
|
||||
}
|
||||
|
||||
function initCalendar(wrapper) {
|
||||
var $wrapper = $(wrapper);
|
||||
var $cal = $wrapper.find('.yacht-calendar-all');
|
||||
@@ -32,6 +40,31 @@
|
||||
var heightPx = parseInt($wrapper.data('height'), 10);
|
||||
if (!heightPx || heightPx < 200) heightPx = 650;
|
||||
|
||||
// Bounds: pobierz max_booking_date żeby ograniczyć validRange w FullCalendar.
|
||||
// Endpoint `/availability/bounds` jest siostrzany do `/availability/all`.
|
||||
var boundsUrl = restUrl.replace(/\/availability\/all.*$/, '/availability/bounds');
|
||||
|
||||
$.getJSON(boundsUrl)
|
||||
.done(function (data) {
|
||||
buildCalendar($wrapper, $cal, restUrl, heightPx, data && data.max_booking_date ? data.max_booking_date : null);
|
||||
})
|
||||
.fail(function () {
|
||||
// Graceful degradation — kalendarz bez validRange.
|
||||
buildCalendar($wrapper, $cal, restUrl, heightPx, null);
|
||||
});
|
||||
}
|
||||
|
||||
function buildCalendar($wrapper, $cal, restUrl, heightPx, maxBookingDate) {
|
||||
var today = new Date();
|
||||
var rangeStart = firstOfMonth(today);
|
||||
var rangeEnd;
|
||||
if (maxBookingDate) {
|
||||
var maxDate = new Date(maxBookingDate + 'T00:00:00');
|
||||
rangeEnd = maxDate >= today ? nextMonthFirst(maxDate) : nextMonthFirst(today);
|
||||
} else {
|
||||
rangeEnd = nextMonthFirst(today);
|
||||
}
|
||||
|
||||
var calendar = new window.FullCalendar.Calendar($cal.get(0), {
|
||||
initialView: 'dayGridMonth',
|
||||
locale: 'pl',
|
||||
@@ -41,6 +74,7 @@
|
||||
center: 'title',
|
||||
right: ''
|
||||
},
|
||||
validRange: { start: rangeStart, end: rangeEnd },
|
||||
height: heightPx,
|
||||
displayEventTime: false,
|
||||
eventDisplay: 'block',
|
||||
@@ -63,6 +97,10 @@
|
||||
var color = info.event.backgroundColor || '#3498db';
|
||||
info.el.style.setProperty('--yc-event-color', color);
|
||||
|
||||
// Native tooltip na hover — tytuł + data dnia.
|
||||
var dayStr = info.event.startStr ? info.event.startStr.slice(0, 10) : '';
|
||||
info.el.setAttribute('title', info.event.title + (dayStr ? ' (' + dayStr + ')' : ''));
|
||||
|
||||
// Half-day visual: gradient z half-cell transparent na pierwszym/ostatnim dniu.
|
||||
// Liczone po renderze (wymaga znajomości szerokości komórki dnia w siatce).
|
||||
// Przekładamy na requestAnimationFrame żeby DOM był ułożony.
|
||||
@@ -70,9 +108,11 @@
|
||||
applyHalfDayGradient(info);
|
||||
});
|
||||
},
|
||||
eventContent: function () {
|
||||
// Pasek koloru bez treści — privacy: nie pokazujemy nazwisk klientów ani nazw jachtów.
|
||||
return { html: '' };
|
||||
eventContent: function (arg) {
|
||||
// Tytuł renderowany przez .text() → automatyczny escaping (XSS safe).
|
||||
var title = arg.event.title || '';
|
||||
var $el = $('<div class="yc-event-title"></div>').text(title);
|
||||
return { domNodes: [$el.get(0)] };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -169,8 +209,11 @@
|
||||
if (halfPct > 49) halfPct = 49;
|
||||
|
||||
var color = el.style.getPropertyValue('--yc-event-color') || '#3498db';
|
||||
var startTrans = info.isStart;
|
||||
var endTrans = info.isEnd;
|
||||
// Server emituje 1 event per doba — info.isStart/isEnd byłyby zawsze true.
|
||||
// Flagi half-day pochodzą z extendedProps (server wie czy to pierwszy/ostatni dzień rezerwacji).
|
||||
var props = info.event.extendedProps || {};
|
||||
var startTrans = !!props.is_first;
|
||||
var endTrans = !!props.is_last_night;
|
||||
|
||||
// Build gradient.
|
||||
var stops;
|
||||
|
||||
Reference in New Issue
Block a user