243 lines
7.3 KiB
PHP
243 lines
7.3 KiB
PHP
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/flatpickr/dist/l10n/pl.js"></script>
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
|
|
|
|
<div id="tickets-calendar-admin">
|
|
<div class="container">
|
|
<div class="tickets-orders">
|
|
<h1>Kalendarz</h1>
|
|
|
|
<div class="calendar-controls">
|
|
<div class="mb-3">
|
|
<label for="ticket_group" class="form-label"><strong>Rodzaj biletu</strong></label>
|
|
<select id="ticket_group" class="form-select">
|
|
<?php foreach ($this->calendar_groups as $groupKey => $groupData) : ?>
|
|
<option value="<?= htmlspecialchars($groupKey, ENT_QUOTES, 'UTF-8'); ?>">
|
|
<?= htmlspecialchars($groupData['label'], ENT_QUOTES, 'UTF-8'); ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
|
|
<input type="hidden" id="calendar_csrf_token" value="<?= htmlspecialchars($this->csrf_token, ENT_QUOTES, 'UTF-8'); ?>">
|
|
|
|
<div id="admin-flatpickr"></div>
|
|
|
|
<div class="calendar-buttons mt-3">
|
|
<button type="button" class="btn btn-outline-success" id="enable-month">Odblokuj cały miesiąc</button>
|
|
<button type="button" class="btn btn-outline-danger" id="disable-month">Zablokuj cały miesiąc</button>
|
|
<button type="button" class="btn btn-primary" id="save-calendar">Zapisz</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script type="text/javascript">
|
|
$(function() {
|
|
const storageKeys = {
|
|
selectedGroup: 'admin_calendar_selected_group',
|
|
visibleMonth: 'admin_calendar_visible_month'
|
|
};
|
|
let enabledDatesSet = new Set();
|
|
|
|
const calendarInstance = flatpickr("#admin-flatpickr", {
|
|
inline: true,
|
|
mode: "multiple",
|
|
dateFormat: "Y-m-d",
|
|
disableMobile: true,
|
|
locale: "pl",
|
|
onMonthChange: function() {
|
|
persistVisibleMonth();
|
|
},
|
|
onYearChange: function() {
|
|
persistVisibleMonth();
|
|
},
|
|
onChange: function(selectedDates, dateStr, instance) {
|
|
syncSetWithPicker(instance);
|
|
}
|
|
});
|
|
|
|
function formatDateToYmd(dateObject) {
|
|
const year = dateObject.getFullYear();
|
|
const month = String(dateObject.getMonth() + 1).padStart(2, "0");
|
|
const day = String(dateObject.getDate()).padStart(2, "0");
|
|
return year + "-" + month + "-" + day;
|
|
}
|
|
|
|
function syncSetWithPicker(instance) {
|
|
enabledDatesSet = new Set(instance.selectedDates.map(function(dateObject) {
|
|
return formatDateToYmd(dateObject);
|
|
}));
|
|
}
|
|
|
|
function renderCurrentSetToPicker() {
|
|
const currentViewDate = new Date(calendarInstance.currentYear, calendarInstance.currentMonth, 1);
|
|
calendarInstance.setDate(Array.from(enabledDatesSet), false, "Y-m-d");
|
|
calendarInstance.jumpToDate(currentViewDate, false);
|
|
}
|
|
|
|
function persistSelectedGroup() {
|
|
try {
|
|
localStorage.setItem(storageKeys.selectedGroup, getCurrentGroup());
|
|
} catch (error) {}
|
|
}
|
|
|
|
function restoreSelectedGroup() {
|
|
try {
|
|
const savedGroup = localStorage.getItem(storageKeys.selectedGroup);
|
|
if (!savedGroup) {
|
|
return;
|
|
}
|
|
|
|
if ($('#ticket_group option[value="' + savedGroup + '"]').length > 0) {
|
|
$('#ticket_group').val(savedGroup);
|
|
}
|
|
} catch (error) {}
|
|
}
|
|
|
|
function persistVisibleMonth() {
|
|
try {
|
|
const month = String(calendarInstance.currentMonth + 1).padStart(2, "0");
|
|
const year = String(calendarInstance.currentYear);
|
|
localStorage.setItem(storageKeys.visibleMonth, year + "-" + month);
|
|
} catch (error) {}
|
|
}
|
|
|
|
function restoreVisibleMonth() {
|
|
try {
|
|
const savedMonth = localStorage.getItem(storageKeys.visibleMonth);
|
|
if (!savedMonth || !/^\d{4}-\d{2}$/.test(savedMonth)) {
|
|
return;
|
|
}
|
|
|
|
calendarInstance.jumpToDate(savedMonth + "-01", false);
|
|
} catch (error) {}
|
|
}
|
|
|
|
function getCurrentGroup() {
|
|
return $('#ticket_group').val();
|
|
}
|
|
|
|
function handleError(message) {
|
|
if ($.alert) {
|
|
$.alert(message);
|
|
} else {
|
|
alert(message);
|
|
}
|
|
}
|
|
|
|
function parseServerResponse(rawResponse) {
|
|
if (rawResponse && typeof rawResponse === 'object') {
|
|
return rawResponse;
|
|
}
|
|
|
|
try {
|
|
return JSON.parse(rawResponse);
|
|
} catch (error) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function fetchDatesForGroup() {
|
|
$.ajax({
|
|
type: 'POST',
|
|
cache: false,
|
|
url: '/apanel/calendar_dates/',
|
|
dataType: 'json',
|
|
data: {
|
|
ticket_group: getCurrentGroup()
|
|
},
|
|
success: function(rawResponse) {
|
|
const response = parseServerResponse(rawResponse);
|
|
if (!response) {
|
|
handleError('Nie udalo sie odczytac odpowiedzi serwera.');
|
|
return;
|
|
}
|
|
if (response.status !== 'ok') {
|
|
handleError(response.message || 'Nie udało się pobrać danych kalendarza.');
|
|
return;
|
|
}
|
|
|
|
enabledDatesSet = new Set(response.enabled_dates || []);
|
|
renderCurrentSetToPicker();
|
|
},
|
|
error: function() {
|
|
handleError('Błąd połączenia podczas pobierania kalendarza.');
|
|
}
|
|
});
|
|
}
|
|
|
|
function updateWholeMonth(enableMonth) {
|
|
const year = calendarInstance.currentYear;
|
|
const monthIndex = calendarInstance.currentMonth;
|
|
const daysInMonth = new Date(year, monthIndex + 1, 0).getDate();
|
|
|
|
for (let day = 1; day <= daysInMonth; day++) {
|
|
const dateObject = new Date(year, monthIndex, day);
|
|
const dateString = formatDateToYmd(dateObject);
|
|
if (enableMonth) {
|
|
enabledDatesSet.add(dateString);
|
|
} else {
|
|
enabledDatesSet.delete(dateString);
|
|
}
|
|
}
|
|
|
|
renderCurrentSetToPicker();
|
|
}
|
|
|
|
function saveCalendar() {
|
|
$.ajax({
|
|
type: 'POST',
|
|
cache: false,
|
|
url: '/apanel/calendar_save/',
|
|
dataType: 'json',
|
|
data: {
|
|
ticket_group: getCurrentGroup(),
|
|
dates: Array.from(enabledDatesSet),
|
|
csrf_token: $('#calendar_csrf_token').val()
|
|
},
|
|
success: function(rawResponse) {
|
|
const response = parseServerResponse(rawResponse);
|
|
if (!response) {
|
|
handleError('Nie udalo sie odczytac odpowiedzi serwera.');
|
|
return;
|
|
}
|
|
if (response.status !== 'ok') {
|
|
handleError(response.message || 'Nie udało się zapisać kalendarza.');
|
|
return;
|
|
}
|
|
|
|
if ($.alert) {
|
|
$.alert('Kalendarz został zapisany.');
|
|
}
|
|
},
|
|
error: function() {
|
|
handleError('Błąd połączenia podczas zapisu kalendarza.');
|
|
}
|
|
});
|
|
}
|
|
|
|
$('body').on('change', '#ticket_group', function() {
|
|
persistSelectedGroup();
|
|
fetchDatesForGroup();
|
|
});
|
|
|
|
$('body').on('click', '#enable-month', function() {
|
|
updateWholeMonth(true);
|
|
});
|
|
|
|
$('body').on('click', '#disable-month', function() {
|
|
updateWholeMonth(false);
|
|
});
|
|
|
|
$('body').on('click', '#save-calendar', function() {
|
|
saveCalendar();
|
|
});
|
|
|
|
restoreSelectedGroup();
|
|
restoreVisibleMonth();
|
|
fetchDatesForGroup();
|
|
});
|
|
</script>
|