| Server IP : 202.61.199.114 / Your IP : 216.73.217.139 Web Server : nginx/1.22.1 System : Linux de.arni-solutions.de 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64 User : web20 ( 1018) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /var/www/clients/client2/web30/web/assets/js/ |
Upload File : |
(function ($) {
'use strict';
const csrfToken = $('meta[name="csrf-token"]').attr('content') || '';
const basePath = $('meta[name="app-base-path"]').attr('content') || '';
const apiUrl = (path) => `${basePath}${path}`;
function debounce(fn, wait) {
let t;
return function () {
const ctx = this;
const args = arguments;
clearTimeout(t);
t = setTimeout(function () { fn.apply(ctx, args); }, wait);
};
}
function toast(message, type = 'success') {
const id = 't' + Date.now();
const html = `<div id="${id}" class="toast align-items-center text-bg-${type} border-0" role="alert"><div class="d-flex"><div class="toast-body">${message}</div><button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button></div></div>`;
$('#toastContainer').append(html);
const el = document.getElementById(id);
const bsToast = new bootstrap.Toast(el, { delay: 2500 });
bsToast.show();
}
function setLoading(id, isLoading) {
$(id).toggleClass('d-none', !isLoading);
}
function renderBookingsRows(rows) {
const tbody = $('#bookingsTable tbody');
tbody.empty();
rows.forEach((row) => {
tbody.append(`<tr>
<td>${row.id || ''}</td>
<td>${row.start_date || ''}<br><small>${row.end_date || ''}</small></td>
<td>${row.ship_name || ''}<br><small>${row.cruise_title || ''}</small></td>
<td>${(row.first_name || '')} ${(row.last_name || '')}</td>
<td><span class="plate">${row.car_license_plate || '-'}</span></td>
<td>${row.booking_number || ''}</td>
<td><span class="badge text-bg-light">${row.parking_type || ''}</span></td>
<td><span class="badge text-bg-secondary">${row.status || ''}</span></td>
<td>${row.invoice_total || ''}</td>
<td><a href="${apiUrl('/bookings/show')}?id=${row.id}" class="btn btn-sm btn-outline-primary">Details</a></td>
</tr>`);
});
}
function fetchBookings(page = 1) {
if (!$('#bookingsTable').length) return;
setLoading('#bookingLoading', true);
$.ajax({
url: apiUrl('/api/bookings/search'),
method: 'GET',
data: {
q: $('#bookingSearch').val(),
date: $('#filterDate').val(),
status: $('#filterStatus').val(),
parking_type: $('#filterParkingType').val(),
page: page
}
}).done(function (resp) {
renderBookingsRows(resp.data.rows || []);
$('#bookingCounter').text((resp.data.total || 0) + ' Ergebnisse');
}).fail(function () {
toast('Buchungen konnten nicht geladen werden', 'danger');
}).always(function () {
setLoading('#bookingLoading', false);
});
}
function checkinCard(row) {
return `<div class="col-12 col-lg-6">
<div class="card checkin-card h-100" data-id="${row.id}">
<div class="card-body">
<div class="d-flex justify-content-between align-items-start mb-2">
<div><h5 class="mb-1">${(row.first_name || '')} ${(row.last_name || '')}</h5><div class="plate-large">${row.car_license_plate || '-'}</div></div>
<span class="badge text-bg-secondary">${row.status || ''}</span>
</div>
<div class="small text-muted mb-2">${row.ship_name || ''} • ${row.cruise_title || ''} • ${row.start_date || ''} bis ${row.end_date || ''}</div>
<div class="d-flex flex-wrap gap-2 mb-2">
<span class="badge text-bg-light">${row.parking_type || '-'}</span>
<span class="badge text-bg-light">Gäste: ${row.guests_count || 0}</span>
<span class="badge text-bg-light">Tel: ${row.phone || '-'}</span>
</div>
<textarea class="form-control form-control-sm mb-2 note-field" rows="2" placeholder="Notiz">${row.note || ''}</textarea>
<div class="d-flex flex-wrap gap-2">
<button class="btn btn-success btn-sm js-checkin">Einchecken</button>
<button class="btn btn-warning btn-sm js-checkout">Auschecken</button>
<button class="btn btn-outline-secondary btn-sm js-status" data-status="reserved">Reserviert</button>
<button class="btn btn-outline-danger btn-sm js-status" data-status="cancelled">Storno</button>
<button class="btn btn-primary btn-sm js-save-note">Notiz speichern</button>
</div>
</div>
</div></div>`;
}
function loadCheckin() {
if (!$('#checkinCards').length) return;
setLoading('#checkinLoading', true);
$.get(apiUrl('/api/checkin/search'), { q: $('#checkinSearch').val() })
.done(function (resp) {
const rows = resp.data.rows || [];
$('#checkinCounter').text(rows.length + ' Treffer');
const html = rows.map(checkinCard).join('');
$('#checkinCards').html(html || '<div class="col-12"><div class="alert alert-light border">Keine Treffer</div></div>');
})
.fail(function () { toast('Checkin Suche fehlgeschlagen', 'danger'); })
.always(function () { setLoading('#checkinLoading', false); });
}
function postAction(url, data, cb) {
data._csrf_token = csrfToken;
$.ajax({ url: apiUrl(url), method: 'POST', data })
.done(function (resp) {
toast(resp.message || 'OK', 'success');
if (cb) cb(resp);
})
.fail(function (xhr) {
toast((xhr.responseJSON && xhr.responseJSON.message) || 'Fehler', 'danger');
});
}
$(document).on('input', '#bookingSearch', debounce(fetchBookings, 250));
$(document).on('change', '#filterDate,#filterStatus,#filterParkingType', fetchBookings);
$(document).on('click', '#bookingReload', function () { fetchBookings(1); });
$(document).on('input', '#checkinSearch', debounce(loadCheckin, 200));
$(document).on('click', '.js-checkin', function () {
const id = $(this).closest('.checkin-card').data('id');
postAction('/api/bookings/checkin', { id }, loadCheckin);
});
$(document).on('click', '.js-checkout', function () {
const id = $(this).closest('.checkin-card').data('id');
postAction('/api/bookings/checkout', { id }, loadCheckin);
});
$(document).on('click', '.js-status', function () {
const card = $(this).closest('.checkin-card');
postAction('/api/bookings/status', { id: card.data('id'), status: $(this).data('status') }, loadCheckin);
});
$(document).on('click', '.js-save-note', function () {
const card = $(this).closest('.checkin-card');
postAction('/api/bookings/note', { id: card.data('id'), note: card.find('.note-field').val() });
});
$(document).on('submit', '#bookingEditForm', function (e) {
e.preventDefault();
const data = $(this).serialize();
$.post(apiUrl('/api/bookings/update'), data)
.done(function (resp) { toast(resp.message || 'Gespeichert', 'success'); })
.fail(function () { toast('Speichern fehlgeschlagen', 'danger'); });
});
<<<<<<< HEAD
$(document).on('click', '.js-user-edit', function () {
const row = $(this).closest('tr');
$('#user_id').val(row.data('id'));
$('#user_name').val(row.data('name'));
$('#user_email').val(row.data('email'));
$('#user_role').val(row.data('role'));
$('#user_active').val(String(row.data('active')));
});
$(document).on('click', '#userFormReset', function () {
$('#userSaveForm')[0].reset();
$('#user_id').val('');
});
$(document).on('submit', '#userSaveForm', function (e) {
e.preventDefault();
const data = $(this).serialize();
$.post(apiUrl('/api/users/save'), data)
.done(function (resp) {
toast(resp.message || 'Benutzer gespeichert', 'success');
setTimeout(function () {
window.location.reload();
}, 350);
})
.fail(function (xhr) {
toast((xhr.responseJSON && xhr.responseJSON.message) || 'Benutzer konnte nicht gespeichert werden', 'danger');
});
});
=======
>>>>>>> origin/main
if ($('#bookingsTable').length) fetchBookings(1);
if ($('#checkinCards').length) loadCheckin();
})(jQuery);