update
This commit is contained in:
@@ -86,15 +86,30 @@
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.yacht-calendar-all .fc-event-title,
|
||||
.yacht-calendar-all .fc-daygrid-event-dot,
|
||||
.yacht-calendar-all .fc-event-time {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Pasek eventu zawsze wyższy żeby był czytelny bez tekstu */
|
||||
/* Custom kontener tytułu (renderowany przez eventContent w JS). */
|
||||
.yacht-calendar-all .yc-event-title {
|
||||
padding: 1px 6px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.35);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
/* Pasek eventu wyższy + gap między dziennymi segmentami (rezerwacja wielonocna
|
||||
= N osobnych pasków zamiast jednej belki — patrz REST split per-day). */
|
||||
.yacht-calendar-all .fc-daygrid-event {
|
||||
min-height: 18px;
|
||||
margin: 1px 2px !important;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* Half-day visual: gradient wpisywany przez calendar-all.js (eventDidMount), który
|
||||
@@ -106,6 +121,11 @@
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.yacht-calendar-all .yc-event-title {
|
||||
font-size: 10px;
|
||||
padding: 1px 4px;
|
||||
}
|
||||
|
||||
.yacht-calendar-all .fc-toolbar.fc-header-toolbar {
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
|
||||
@@ -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