288 lines
12 KiB
JavaScript
288 lines
12 KiB
JavaScript
document.addEventListener('DOMContentLoaded', function () {
|
|
var calendarEl = document.getElementById('on-admin-calendar');
|
|
if (!calendarEl) return;
|
|
|
|
// Modal Logic
|
|
var modal = document.getElementById('onAdminModal');
|
|
var closeBtn = document.getElementById('onAdminCloseModal');
|
|
var contentDiv = document.getElementById('onBookingDetailsContent');
|
|
var currentPostId = null;
|
|
|
|
function openModal() {
|
|
if (modal) modal.classList.add('is-open');
|
|
}
|
|
function closeModal() {
|
|
if (modal) modal.classList.remove('is-open');
|
|
currentPostId = null;
|
|
}
|
|
|
|
if (closeBtn) {
|
|
closeBtn.addEventListener('click', closeModal);
|
|
}
|
|
if (modal) {
|
|
modal.addEventListener('click', function (e) {
|
|
if (e.target === modal) closeModal();
|
|
});
|
|
}
|
|
|
|
// Helper: Format Date for Inputs
|
|
function formatDateISO(date) {
|
|
var d = new Date(date),
|
|
month = '' + (d.getMonth() + 1),
|
|
day = '' + d.getDate(),
|
|
year = d.getFullYear();
|
|
|
|
if (month.length < 2) month = '0' + month;
|
|
if (day.length < 2) day = '0' + day;
|
|
|
|
return [year, month, day].join('-');
|
|
}
|
|
|
|
var calendar = new FullCalendar.Calendar(calendarEl, {
|
|
initialView: 'dayGridMonth',
|
|
locale: 'de',
|
|
height: window.innerHeight - 120, // Dynamic height: Viewport - WP Admin items
|
|
windowResize: function (view) {
|
|
calendar.setOption('height', window.innerHeight - 120);
|
|
},
|
|
editable: true, // Enable Drag & Drop
|
|
droppable: false,
|
|
headerToolbar: {
|
|
left: 'prev,next today',
|
|
center: 'title',
|
|
right: 'dayGridMonth,timeGridWeek,timeGridDay'
|
|
},
|
|
events: {
|
|
url: ajaxurl,
|
|
method: 'POST',
|
|
extraParams: {
|
|
action: 'on_get_admin_bookings',
|
|
nonce: onBookingAdmin.nonce
|
|
}
|
|
},
|
|
eventDrop: function (info) {
|
|
// Handle Drag & Drop
|
|
if (!confirm("Möchtest du den Termin '" + info.event.title + "' wirklich verschieben auf " + info.event.start.toLocaleDateString() + "?")) {
|
|
info.revert();
|
|
return;
|
|
}
|
|
|
|
var newDate = formatDateISO(info.event.start);
|
|
var newTime = info.event.start.toTimeString().substring(0, 5); // HH:MM
|
|
|
|
// If dragged in month view, time might be messed up or set to 00:00.
|
|
// Ideally we keep original time if we don't have time view info?
|
|
// FullCalendar standard: strip time if dayGrid.
|
|
// Let's try to preserve time if possible or default to start time?
|
|
// Getting original time from oldEvent?
|
|
if (info.view.type === 'dayGridMonth' && info.event.allDay) {
|
|
// It might strip time. Let's assume we want to keep original time?
|
|
// But we don't have it easily if it became allDay.
|
|
// Actually, on backend we just updated the DATE.
|
|
// Let's check what we send.
|
|
// For now, let's just send the date and keep existing time if we pass empty time string?
|
|
// But if we drag to a timeSlot in week view, we definitely want the time.
|
|
if (!info.event.startStr.includes('T')) {
|
|
// It's a date string only
|
|
newTime = ''; // Backend should preserve old time if this is empty
|
|
}
|
|
}
|
|
|
|
jQuery.ajax({
|
|
url: ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'on_update_booking_date',
|
|
nonce: onBookingAdmin.nonce,
|
|
post_id: info.event.id,
|
|
new_date: newDate,
|
|
new_time: newTime
|
|
},
|
|
success: function (response) {
|
|
if (!response.success) {
|
|
alert('Fehler: ' + response.data.message);
|
|
info.revert();
|
|
}
|
|
},
|
|
error: function () {
|
|
alert('Verbindungsfehler.');
|
|
info.revert();
|
|
}
|
|
});
|
|
},
|
|
eventClick: function (info) {
|
|
info.jsEvent.preventDefault();
|
|
|
|
var postId = info.event.id;
|
|
if (postId) {
|
|
currentPostId = postId;
|
|
openModal();
|
|
contentDiv.innerHTML = '<div style="text-align:center; padding: 20px;">Lade Details...</div>';
|
|
|
|
// Fetch Details
|
|
jQuery.ajax({
|
|
url: ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'on_get_booking_details',
|
|
nonce: onBookingAdmin.nonce,
|
|
post_id: postId
|
|
},
|
|
success: function (response) {
|
|
if (response.success) {
|
|
var data = response.data;
|
|
|
|
var html = '<div>' + data.content + '</div>';
|
|
|
|
// Actions Area
|
|
html += '<div style="margin-top: 30px; padding-top: 20px; border-top: 1px solid #444; display: flex; gap: 10px; flex-wrap: wrap;">';
|
|
|
|
// Delete Button
|
|
html += '<button id="onBtnDelete" style="background:#d93025; color:#fff; border:none; padding:8px 15px; cursor:pointer; font-weight:bold;">Löschen</button>';
|
|
|
|
// Reschedule Toggle
|
|
html += '<button id="onBtnReschedule" style="background:#0061ff; color:#fff; border:none; padding:8px 15px; cursor:pointer; font-weight:bold;">Verschieben</button>';
|
|
|
|
html += '</div>';
|
|
|
|
// Reschedule Form (Hidden)
|
|
html += '<div id="onRescheduleForm" style="display:none; margin-top: 15px; background: rgba(255,255,255,0.05); padding: 15px; border: 1px solid #444;">';
|
|
html += '<h4 style="margin-top:0; color:#fff;">Neuer Termin</h4>';
|
|
html += '<label style="display:block; margin-bottom:5px;">Datum: <input type="date" id="onNewDate" value="' + (data.date || '') + '" style="width:100%; padding:8px;"></label>';
|
|
html += '<label style="display:block; margin-bottom:10px;">Zeit: <input type="time" id="onNewTime" value="' + (data.time || '') + '" style="width:100%; padding:8px;"></label>';
|
|
html += '<button id="onBtnSaveReschedule" style="background:#008000; color:#fff; border:none; padding:8px 15px; cursor:pointer; margin-right:5px;">Speichern</button>';
|
|
html += '<button id="onBtnCancelReschedule" style="background:#666; color:#fff; border:none; padding:8px 15px; cursor:pointer;">Abbrechen</button>';
|
|
html += '</div>';
|
|
|
|
contentDiv.innerHTML = html;
|
|
|
|
// Bind Events (jQuery Delegation for robustness when content is replaced)
|
|
// We can use direct clicks here since we just replaced HTML, but consistent jQuery is cleaner.
|
|
|
|
$('#onBtnDelete').off('click').on('click', function () {
|
|
if (confirm('Möchtest du diese Buchung wirklich unwiderruflich löschen?')) {
|
|
deleteBooking(currentPostId);
|
|
}
|
|
});
|
|
|
|
$('#onBtnReschedule').off('click').on('click', function () {
|
|
$('#onRescheduleForm').show();
|
|
$(this).hide();
|
|
});
|
|
|
|
$('#onBtnCancelReschedule').off('click').on('click', function () {
|
|
$('#onRescheduleForm').hide();
|
|
$('#onBtnReschedule').show();
|
|
});
|
|
|
|
$('#onBtnSaveReschedule').off('click').on('click', function () {
|
|
var nd = $('#onNewDate').val();
|
|
var nt = $('#onNewTime').val();
|
|
updateBooking(currentPostId, nd, nt);
|
|
});
|
|
|
|
// Save Notes Handler
|
|
$('#onSaveNotesBtnCalendar').off('click').on('click', function () {
|
|
var btn = $(this);
|
|
var notes = $('#onAdminNotesCalendar').val();
|
|
var msg = $('#onSaveNotesMsgCalendar');
|
|
|
|
btn.prop('disabled', true);
|
|
msg.text('Speichere...').css('color', '#333');
|
|
|
|
jQuery.ajax({
|
|
url: ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'on_update_booking_notes',
|
|
post_id: currentPostId,
|
|
notes: notes,
|
|
nonce: onBookingAdmin.nonce
|
|
},
|
|
success: function (response) {
|
|
if (response.success) {
|
|
msg.text('Gespeichert!').css('color', 'green');
|
|
} else {
|
|
msg.text('Fehler.').css('color', 'red');
|
|
}
|
|
},
|
|
error: function () {
|
|
msg.text('Fehler.').css('color', 'red');
|
|
},
|
|
complete: function () {
|
|
setTimeout(function () {
|
|
btn.prop('disabled', false);
|
|
msg.text('');
|
|
}, 2000);
|
|
}
|
|
});
|
|
});
|
|
|
|
} else {
|
|
contentDiv.innerHTML = 'Fehler: ' + (response.data.message || 'Unbekannt');
|
|
}
|
|
},
|
|
error: function () {
|
|
contentDiv.innerHTML = 'Verbindungsfehler.';
|
|
}
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
calendar.render();
|
|
|
|
// AJAX Actions
|
|
function deleteBooking(id) {
|
|
contentDiv.innerHTML = 'Lösche...';
|
|
jQuery.ajax({
|
|
url: ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'on_delete_booking',
|
|
nonce: onBookingAdmin.nonce,
|
|
post_id: id
|
|
},
|
|
success: function (res) {
|
|
if (res.success) {
|
|
closeModal();
|
|
calendar.refetchEvents(); // Refresh calendar
|
|
} else {
|
|
alert('Fehler: ' + res.data.message);
|
|
openModal(); // Re-open or keep open?
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function updateBooking(id, date, time) {
|
|
if (!date || !time) {
|
|
alert('Bitte Datum und Zeit wählen.');
|
|
return;
|
|
}
|
|
var saveBtn = document.getElementById('onBtnSaveReschedule');
|
|
saveBtn.innerText = 'Speichere...';
|
|
|
|
jQuery.ajax({
|
|
url: ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'on_update_booking_date',
|
|
nonce: onBookingAdmin.nonce,
|
|
post_id: id,
|
|
new_date: date,
|
|
new_time: time
|
|
},
|
|
success: function (res) {
|
|
if (res.success) {
|
|
closeModal();
|
|
calendar.refetchEvents();
|
|
} else {
|
|
alert('Fehler: ' + res.data.message);
|
|
saveBtn.innerText = 'Speichern';
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|