Files
on-motorrad-buchungs-plugin/includes/class-on-booking-admin.php

809 lines
38 KiB
PHP

<?php
if (!defined('ABSPATH')) {
exit;
}
class ON_Booking_Admin
{
private $calendar_page_hook;
public function __construct()
{
add_action('admin_menu', array($this, 'add_admin_menu'));
add_action('admin_init', array($this, 'register_settings'));
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_assets'));
}
public function enqueue_admin_assets($hook)
{
if ($hook === $this->calendar_page_hook) {
// FullCalendar CDN
wp_enqueue_script('on-fullcalendar', 'https://cdn.jsdelivr.net/npm/fullcalendar@6.1.10/index.global.min.js', array(), '6.1.10', true);
// Admin Calendar JS
wp_enqueue_script('on-admin-calendar-js', ON_BOOKING_URL . 'assets/js/admin-calendar.js', array('on-fullcalendar'), ON_BOOKING_VERSION, true);
wp_localize_script('on-admin-calendar-js', 'onBookingAdmin', array(
'nonce' => wp_create_nonce('on_booking_nonce')
));
}
// Kanban JS
if (isset($_GET['page']) && $_GET['page'] === 'on-booking-kanban') {
// Enqueue WordPress editor for rich text notes
wp_enqueue_editor();
wp_enqueue_script('on-admin-kanban-js', ON_BOOKING_URL . 'assets/js/admin-kanban.js', array('jquery', 'jquery-ui-draggable', 'jquery-ui-droppable'), time(), true);
wp_localize_script('on-admin-kanban-js', 'onBookingKanban', array(
'nonce' => wp_create_nonce('on_booking_nonce')
));
}
wp_enqueue_style('on-booking-admin-style', ON_BOOKING_URL . 'assets/css/admin-style.css', array(), ON_BOOKING_VERSION);
}
public function add_admin_menu()
{
// Top Level Menu for Calendar
$this->calendar_page_hook = add_menu_page(
'Werkstatt Buchungen',
'Buchungen',
'manage_options',
'on-booking-calendar',
array($this, 'render_calendar_page'),
'dashicons-calendar-alt',
26
);
// Submenu for Calendar (to rename the first item if desired, but usually WP handles 'Buchungen' > 'Buchungen')
// Actually, let's keep it simple: Top level is Calendar.
// Settings Submenu
add_submenu_page(
'on-booking-calendar', // Parent slug
'Buchungs-Einstellungen',
'Einstellungen',
'manage_options',
'on-booking-settings',
array($this, 'render_settings_page')
);
// Services Submenu
add_submenu_page(
'on-booking-calendar',
'Services verwalten',
'Services',
'manage_options',
'on-booking-services',
array($this, 'render_services_page')
);
// Status Board Submenu
add_submenu_page(
'on-booking-calendar',
'Status Board',
'Status Board',
'manage_options',
'on-booking-kanban',
array($this, 'render_kanban_page')
);
}
public function register_settings()
{
// General Settings Group: on_booking_general
register_setting('on_booking_general', 'on_booking_days_blocked');
register_setting('on_booking_general', 'on_booking_time_start');
register_setting('on_booking_general', 'on_booking_time_end');
register_setting('on_booking_general', 'on_booking_time_interval');
register_setting('on_booking_general', 'on_booking_theme_mode');
register_setting('on_booking_general', 'on_booking_show_duration');
register_setting('on_booking_general', 'on_booking_simple_mode');
// SMTP Settings Group: on_booking_smtp
register_setting('on_booking_smtp', 'on_booking_mail_method'); // smtp, wp_mail
register_setting('on_booking_smtp', 'on_booking_smtp_host');
register_setting('on_booking_smtp', 'on_booking_smtp_port'); // Default 587
register_setting('on_booking_smtp', 'on_booking_smtp_user');
register_setting('on_booking_smtp', 'on_booking_smtp_pass');
register_setting('on_booking_smtp', 'on_booking_smtp_auth_type'); // auto, login, plain, cram-md5
register_setting('on_booking_smtp', 'on_booking_smtp_enc'); // none, ssl, tls
register_setting('on_booking_smtp', 'on_booking_from_email');
register_setting('on_booking_smtp', 'on_booking_from_name');
// Email Template Settings Group: on_booking_email
register_setting('on_booking_email', 'on_booking_enable_emails'); // New: Enable/Disable
register_setting('on_booking_email', 'on_booking_email_subject');
register_setting('on_booking_email', 'on_booking_email_body');
// Admin Notification
register_setting('on_booking_email', 'on_booking_enable_admin_notify');
register_setting('on_booking_email', 'on_booking_admin_notify_email');
}
public function render_settings_page()
{
$active_tab = isset($_GET['tab']) ? $_GET['tab'] : 'general';
$prio_group = 'on_booking_general'; // Default
if ($active_tab == 'smtp') {
$prio_group = 'on_booking_smtp';
} else if ($active_tab == 'email') {
$prio_group = 'on_booking_email';
}
?>
<div class="wrap">
<h1>Buchungs-Einstellungen</h1>
<h2 class="nav-tab-wrapper">
<a href="?page=on-booking-settings&tab=general"
class="nav-tab <?php echo $active_tab == 'general' ? 'nav-tab-active' : ''; ?>">Allgemein</a>
<a href="?page=on-booking-settings&tab=smtp"
class="nav-tab <?php echo $active_tab == 'smtp' ? 'nav-tab-active' : ''; ?>">SMTP Einstellungen</a>
<a href="?page=on-booking-settings&tab=email"
class="nav-tab <?php echo $active_tab == 'email' ? 'nav-tab-active' : ''; ?>">E-Mail Vorlage</a>
</h2>
<form method="post" action="options.php">
<?php
// Output nonces and hidden fields for the specific group
settings_fields($prio_group);
if ($active_tab == 'general') {
$this->render_general_settings();
} else if ($active_tab == 'smtp') {
$this->render_smtp_settings();
} else if ($active_tab == 'email') {
$this->render_email_template_settings();
}
?>
<?php submit_button(); ?>
</form>
</div>
<?php
}
private function render_general_settings()
{
?>
<table class="form-table">
<tr valign="top">
<th scope="row">Geschlossene Tage</th>
<td>
<?php
$blocked_days = get_option('on_booking_days_blocked', array());
if (!is_array($blocked_days))
$blocked_days = array();
// Hidden input to ensure array is reset if all unchecked
echo '<input type="hidden" name="on_booking_days_blocked" value="">';
$days = array('Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag');
foreach ($days as $index => $day) {
$checked = in_array($index, $blocked_days) ? 'checked' : '';
echo '<label><input type="checkbox" name="on_booking_days_blocked[]" value="' . $index . '" ' . $checked . '> ' . $day . '</label><br>';
}
?>
<p class="description">Wähle die Tage, an denen die Werkstatt geschlossen ist.</p>
</td>
</tr>
<tr valign="top">
<th scope="row">Buchungszeiten</th>
<td>
<label>Startzeit: <input type="time" name="on_booking_time_start"
value="<?php echo esc_attr(get_option('on_booking_time_start', '08:00')); ?>"></label><br>
<label>Endzeit: <input type="time" name="on_booking_time_end"
value="<?php echo esc_attr(get_option('on_booking_time_end', '17:00')); ?>"></label><br>
<label>Intervall (Min): <input type="number" name="on_booking_time_interval"
value="<?php echo esc_attr(get_option('on_booking_time_interval', '60')); ?>" min="15"
step="15"></label>
</td>
</tr>
<tr valign="top">
<th scope="row">Anzeigeoptionen</th>
<td>
<label>
<input type="hidden" name="on_booking_show_duration" value="0">
<input type="checkbox" name="on_booking_show_duration" value="1" <?php checked(1, get_option('on_booking_show_duration', 0)); ?>>
Service-Dauer im Frontend anzeigen
</label>
<p class="description">Wenn aktiviert, wird die Dauer (z.B. "30 min") im Dropdown neben dem Service-Namen
angezeigt.</p>
</td>
</tr>
<tr valign="top">
<th scope="row">Design Modus</th>
<td>
<?php $theme_mode = get_option('on_booking_theme_mode', 'auto'); ?>
<select name="on_booking_theme_mode">
<option value="auto" <?php selected($theme_mode, 'auto'); ?>>Automatisch (Browser)</option>
<option value="light" <?php selected($theme_mode, 'light'); ?>>Hell (Light Mode)</option>
<option value="dark" <?php selected($theme_mode, 'dark'); ?>>Dunkel (Dark Mode)</option>
</select>
<p class="description">Wähle das Erscheinungsbild des Kalenders im Backend.</p>
</td>
</tr>
<tr valign="top">
<th scope="row">Buchungsmodus</th>
<td>
<label>
<input type="hidden" name="on_booking_simple_mode" value="0">
<input type="checkbox" name="on_booking_simple_mode" value="1" <?php checked(1, get_option('on_booking_simple_mode', 0)); ?>>
Einfacher Modus (ohne Service-/Termin-Auswahl)
</label>
<p class="description">Wenn aktiviert, sieht der Kunde im Frontend nur ein Kontaktformular mit einem
Freitextfeld für Wünsche &ndash; ohne Service-, Kalender- oder Uhrzeitauswahl.</p>
</td>
</tr>
</table>
<?php
}
private function render_smtp_settings()
{
?>
<table class="form-table">
<tr valign="top">
<th scope="row">Absender Name</th>
<td><input type="text" name="on_booking_from_name"
value="<?php echo esc_attr(get_option('on_booking_from_name', get_bloginfo('name'))); ?>"
class="regular-text"></td>
</tr>
<tr valign="top">
<th scope="row">Absender E-Mail</th>
<td><input type="email" name="on_booking_from_email"
value="<?php echo esc_attr(get_option('on_booking_from_email', get_bloginfo('admin_email'))); ?>"
class="regular-text"></td>
</tr>
<tr valign="top">
<th scope="row">Versandmethode</th>
<td>
<?php $method = get_option('on_booking_mail_method', 'smtp'); ?>
<label><input type="radio" name="on_booking_mail_method" value="smtp" <?php checked($method, 'smtp'); ?>>
SMTP (Empfohlen)</label><br>
<label><input type="radio" name="on_booking_mail_method" value="wp_mail" <?php checked($method, 'wp_mail'); ?>> PHP Mail (Standard / WP Default)</label>
<p class="description">Wähle "PHP Mail", wenn SMTP Probleme macht (kann im Spam landen).</p>
</td>
</tr>
<tr valign="top">
<th scope="row">SMTP Host</th>
<td><input type="text" name="on_booking_smtp_host"
value="<?php echo esc_attr(get_option('on_booking_smtp_host', '')); ?>" class="regular-text"
placeholder="smtp.example.com"></td>
</tr>
<tr valign="top">
<th scope="row">SMTP Port</th>
<td><input type="number" name="on_booking_smtp_port"
value="<?php echo esc_attr(get_option('on_booking_smtp_port', '587')); ?>" class="small-text"></td>
</tr>
<tr valign="top">
<th scope="row">SMTP Benutzer</th>
<td><input type="text" name="on_booking_smtp_user"
value="<?php echo esc_attr(get_option('on_booking_smtp_user', '')); ?>" class="regular-text"></td>
</tr>
<tr valign="top">
<th scope="row">SMTP Passwort</th>
<td><input type="password" name="on_booking_smtp_pass"
value="<?php echo esc_attr(get_option('on_booking_smtp_pass', '')); ?>" class="regular-text"></td>
</tr>
<tr valign="top">
<th scope="row">Authentifizierung</th>
<td>
<?php $auth_type = get_option('on_booking_smtp_auth_type', 'auto'); ?>
<select name="on_booking_smtp_auth_type">
<option value="auto" <?php selected($auth_type, 'auto'); ?>>Automatisch (Empfohlen)</option>
<option value="LOGIN" <?php selected($auth_type, 'LOGIN'); ?>>LOGIN</option>
<option value="PLAIN" <?php selected($auth_type, 'PLAIN'); ?>>PLAIN</option>
<option value="CRAM-MD5" <?php selected($auth_type, 'CRAM-MD5'); ?>>CRAM-MD5</option>
</select>
<p class="description">Falls 'Automatisch' fehlschlägt, versuche PLAIN oder LOGIN.</p>
</td>
</tr>
<tr valign="top">
<th scope="row">Verschlüsselung</th>
<td>
<?php $enc = get_option('on_booking_smtp_enc', 'tls'); ?>
<label><input type="radio" name="on_booking_smtp_enc" value="none" <?php checked($enc, 'none'); ?>>
Keine</label><br>
<label><input type="radio" name="on_booking_smtp_enc" value="ssl" <?php checked($enc, 'ssl'); ?>>
SSL</label><br>
<label><input type="radio" name="on_booking_smtp_enc" value="tls" <?php checked($enc, 'tls'); ?>>
TLS</label><br>
<label><input type="radio" name="on_booking_smtp_enc" value="starttls" <?php checked($enc, 'starttls'); ?>>
STARTTLS</label>
</td>
</tr>
</table>
<hr>
<h3>SMTP testen</h3>
<div style="display: flex; gap: 10px; align-items: center; margin-bottom: 10px;">
<input type="email" id="onTestEmailInput" class="regular-text" placeholder="Deine E-Mail Adresse"
value="<?php echo esc_attr(wp_get_current_user()->user_email); ?>">
<button type="button" class="button button-secondary" id="onSendTestEmail">Test-Email senden</button>
</div>
<textarea id="onTestEmailLog" rows="10" cols="80" style="width: 100%; font-family: monospace; background: #f0f0f1;"
readonly placeholder="Log Ausgabe..."></textarea>
<script>
jQuery(document).ready(function ($) {
function logMessage(msg) {
const log = $('#onTestEmailLog');
const time = new Date().toLocaleTimeString();
log.val('[' + time + '] ' + msg + '\n' + log.val());
}
$('#onSendTestEmail').on('click', function () {
const btn = $(this);
const email = $('#onTestEmailInput').val();
if (!email) {
alert('Bitte E-Mail eingeben');
return;
}
btn.prop('disabled', true).text('Sende...');
logMessage('Starte Test für: ' + email + '...');
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'on_send_test_email',
test_email: email,
nonce: '<?php echo wp_create_nonce('on_booking_nonce'); ?>'
},
success: function (response) {
if (response.success) {
logMessage('ERFOLG: ' + response.data.message);
} else {
logMessage('FEHLER: ' + response.data.message);
}
},
error: function (xhr, status, error) {
logMessage('AJAX FEHLER: ' + error);
if (xhr.responseText) {
logMessage('Response: ' + xhr.responseText);
}
logMessage('Status: ' + xhr.status + ' ' + xhr.statusText);
},
complete: function () {
btn.prop('disabled', false).text('Test-Email senden');
}
});
});
});
</script>
<?php
}
private function render_email_template_settings()
{
$default_subject = 'Buchungsbestätigung: {service} am {date}';
$default_body = '<h3>Hallo {name},</h3><p>vielen Dank für deine Buchung bei uns. Hier sind deine Details:</p>' .
'<div style="background: #1f1f1f; color: #fff; padding: 15px; border-left: 4px solid #0061ff; margin: 20px 0;">' .
'<p><strong>Service:</strong> {service}</p>' .
'<p><strong>Datum:</strong> {date}</p>' .
'<p><strong>Uhrzeit:</strong> {time}</p>' .
'<p><strong>Auftragsnummer:</strong> <span style="font-family: monospace; font-size: 1.2em; color: #0061ff;">{tracking_id}</span></p>' .
'</div>' .
'<p>Du kannst den Status deiner Buchung jederzeit auf unserer Webseite mit deiner Auftragsnummer abfragen.</p>' .
'<p>Mit freundlichen Grüßen,<br>Dein Werkstatt-Team</p>';
$subject = get_option('on_booking_email_subject', $default_subject);
$body = get_option('on_booking_email_body', $default_body);
?>
<div style="max-width: 800px;">
<p>Hier kannst du die E-Mail anpassen, die nach einer erfolgreichen Buchung an den Kunden gesendet wird.</p>
<table class="form-table">
<tr valign="top"> <!-- New Enable Toggle -->
<th scope="row">E-Mail Benachrichtigung</th>
<td>
<label>
<input type="hidden" name="on_booking_enable_emails" value="0">
<input type="checkbox" name="on_booking_enable_emails" value="1" <?php checked(1, get_option('on_booking_enable_emails', 0)); ?>>
E-Mail Bestätigungen aktivieren
</label>
<p class="description">Wenn aktiviert, werden Bestätigungs-E-Mails an Kunden gesendet.</p>
</td>
</tr>
<tr valign="top">
<th scope="row">Betreff</th>
<td><input type="text" name="on_booking_email_subject" value="<?php echo esc_attr($subject); ?>"
class="large-text"></td>
</tr>
<tr valign="top">
<th scope="row">Inhalt</th>
<td>
<?php
wp_editor($body, 'on_booking_email_body', array(
'media_buttons' => false,
'textarea_rows' => 15,
'teeny' => true
));
?>
<p class="description">
<strong>Verfügbare Platzhalter:</strong><br>
<code>{name}</code> - Name des Kunden<br>
<code>{date}</code> - Datum des Termins<br>
<code>{time}</code> - Uhrzeit des Termins<br>
<code>{service}</code> - gebuchter Service<br>
<code>{tracking_id}</code> - Auftragsnummer für Statusabfrage
</p>
</td>
</tr>
</table>
<h3 style="margin-top: 30px; padding-top: 15px; border-top: 1px solid #ccc;">Werkstatt-Benachrichtigung</h3>
<p>Erhalte bei jeder neuen Buchung eine E-Mail mit allen Details &ndash; als Alternative zum Kalender.</p>
<table class="form-table">
<tr valign="top">
<th scope="row">Werkstatt-Mail aktivieren</th>
<td>
<label>
<input type="hidden" name="on_booking_enable_admin_notify" value="0">
<input type="checkbox" name="on_booking_enable_admin_notify" value="1" <?php checked(1, get_option('on_booking_enable_admin_notify', 0)); ?>>
Bei jeder Buchung eine Kopie an die Werkstatt senden
</label>
</td>
</tr>
<tr valign="top">
<th scope="row">Empf&auml;nger E-Mail</th>
<td>
<input type="email" name="on_booking_admin_notify_email"
value="<?php echo esc_attr(get_option('on_booking_admin_notify_email', '')); ?>"
class="regular-text" placeholder="werkstatt@beispiel.de">
<p class="description">An diese Adresse wird bei jeder neuen Buchung eine Benachrichtigung gesendet.</p>
</td>
</tr>
</table>
<p>
<button type="button" class="button" id="on-reset-email-template">Standard-Vorlage wiederherstellen</button>
</p>
<script>
jQuery(document).ready(function ($) {
$('#on-reset-email-template').on('click', function () {
if (!confirm('Möchtest du wirklich die Standard-Vorlage wiederherstellen? Alle Änderungen gehen verloren.')) {
return;
}
var defaultSubject = <?php echo json_encode($default_subject); ?>;
var defaultBody = <?php echo json_encode($default_body); ?>;
// Set Subject
$('input[name="on_booking_email_subject"]').val(defaultSubject);
// Set Body (TinyMCE or Textarea)
if (typeof tinymce !== 'undefined' && tinymce.get('on_booking_email_body')) {
tinymce.get('on_booking_email_body').setContent(defaultBody);
} else {
$('#on_booking_email_body').val(defaultBody);
}
});
});
</script>
</div>
<?php
}
public function render_calendar_page()
{
$theme_mode = get_option('on_booking_theme_mode', 'auto');
$theme_class = 'on-theme-' . $theme_mode;
?>
<div class="wrap">
<h1>Buchungskalender</h1>
<div id="on-admin-calendar" class="<?php echo esc_attr($theme_class); ?>"></div>
</div>
<!-- Admin Detail Modal -->
<div id="onAdminModal" class="on-modal-overlay <?php echo esc_attr($theme_class); ?>" style="z-index: 10000;">
<div class="on-modal-content" style="max-width: 600px;">
<button class="on-close-btn" id="onAdminCloseModal">&times;</button>
<div id="onAdminModalBody">
<h3>Buchungs <span>Details</span></h3>
<div id="onBookingDetailsContent">Lade...</div>
</div>
</div>
</div>
<?php
}
public function render_kanban_page()
{
$theme_mode = get_option('on_booking_theme_mode', 'auto');
$theme_class = 'on-theme-' . $theme_mode;
// Reuse Modal HTML
?>
<div id="onAdminModal" class="on-modal-overlay <?php echo esc_attr($theme_class); ?>" style="z-index: 10000;">
<div class="on-modal-content" style="max-width: 600px;">
<button class="on-close-btn" id="onAdminCloseModal">&times;</button>
<div id="onAdminModalBody">
<h3>Buchungs <span>Details</span></h3>
<div id="onBookingDetailsContent">Lade...</div>
</div>
</div>
</div>
<?php
// Fetch all bookings
$posts = get_posts(array(
'post_type' => 'on_booking',
'numberposts' => -1,
'post_status' => array('publish', 'pending', 'future', 'private')
));
$columns = array(
'waiting' => array('title' => 'Warten', 'items' => array()),
'in_progress' => array('title' => 'In Bearbeitung', 'items' => array()),
'done' => array('title' => 'Abholbereit', 'items' => array())
);
foreach ($posts as $p) {
$status = get_post_meta($p->ID, 'on_booking_status', true);
if (!$status)
$status = 'waiting';
if (!array_key_exists($status, $columns))
$status = 'waiting';
$date = get_post_meta($p->ID, 'on_booking_date', true);
$time = get_post_meta($p->ID, 'on_booking_time', true);
$columns[$status]['items'][] = array(
'id' => $p->ID,
'title' => $p->post_title,
'date' => $date,
'time' => $time
);
}
?>
<div class="wrap <?php echo esc_attr($theme_class); ?>">
<h1>Status Board</h1>
<div class="on-kanban-board">
<?php foreach ($columns as $key => $col): ?>
<div class="on-kanban-column" data-status="<?php echo esc_attr($key); ?>">
<div class="on-kanban-header"><?php echo esc_html($col['title']); ?> <span
class="count"><?php echo count($col['items']); ?></span></div>
<div class="on-kanban-items">
<?php foreach ($col['items'] as $item): ?>
<div class="on-kanban-card" data-id="<?php echo esc_attr($item['id']); ?>"
data-status="<?php echo esc_attr($key); ?>">
<div class="card-title"><?php echo esc_html($item['title']); ?> <span
class="dashicons dashicons-edit on-edit-icon" title="Notiz/Details bearbeiten"
style="float:right; color:#888; cursor:pointer;"></span></div>
<div class="card-meta"><?php echo esc_html($item['date'] . ' ' . $item['time']); ?></div>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<?php
}
public function render_services_page()
{
$theme_mode = get_option('on_booking_theme_mode', 'auto');
$theme_class = 'on-theme-' . $theme_mode;
$services = ON_Service_Manager::get_all_services();
?>
<div class="wrap <?php echo esc_attr($theme_class); ?>">
<h1>Services verwalten</h1>
<div style="background: var(--on-bg); padding: 20px; border-radius: 4px; margin-bottom: 20px;">
<h2>Neuen Service hinzufügen</h2>
<form id="onAddServiceForm" style="display: flex; gap: 15px; align-items: end;">
<div>
<label style="display: block; margin-bottom: 5px; font-weight: bold;">Service Name</label>
<input type="text" id="onServiceName" required style="padding: 8px; width: 250px;">
</div>
<div>
<label style="display: block; margin-bottom: 5px; font-weight: bold;">Dauer (Minuten)</label>
<select id="onServiceDuration" style="padding: 8px;">
<option value="30">30 min</option>
<option value="60">60 min</option>
<option value="90">90 min</option>
<option value="120">120 min</option>
<option value="150">150 min</option>
<option value="180">180 min</option>
</select>
</div>
<button type="submit" class="button button-primary">Service hinzufügen</button>
<span id="onAddServiceMsg" style="margin-left: 10px; font-weight: bold;"></span>
</form>
</div>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th style="width: 50%;">Service Name</th>
<th style="width: 20%;">Dauer</th>
<th style="width: 15%;">Status</th>
<th style="width: 15%;">Aktionen</th>
</tr>
</thead>
<tbody id="onServicesTableBody">
<?php foreach ($services as $service): ?>
<tr data-service-id="<?php echo esc_attr($service['id']); ?>">
<td>
<span class="service-name-display"><?php echo esc_html($service['name']); ?></span>
<input type="text" class="service-name-edit" value="<?php echo esc_attr($service['name']); ?>"
style="display:none; width: 100%;">
</td>
<td>
<span class="service-duration-display"><?php echo esc_html($service['duration']); ?> min</span>
<select class="service-duration-edit" style="display:none;">
<option value="30" <?php selected($service['duration'], 30); ?>>30 min</option>
<option value="60" <?php selected($service['duration'], 60); ?>>60 min</option>
<option value="90" <?php selected($service['duration'], 90); ?>>90 min</option>
<option value="120" <?php selected($service['duration'], 120); ?>>120 min</option>
<option value="150" <?php selected($service['duration'], 150); ?>>150 min</option>
<option value="180" <?php selected($service['duration'], 180); ?>>180 min</option>
</select>
</td>
<td>
<span class="service-status-badge"
style="padding: 4px 8px; border-radius: 3px; font-size: 0.85em; <?php echo $service['active'] ? 'background: #46b450; color: white;' : 'background: #dc3232; color: white;'; ?>">
<?php echo $service['active'] ? 'Aktiv' : 'Inaktiv'; ?>
</span>
</td>
<td>
<button class="button button-small on-edit-service-btn">Bearbeiten</button>
<button class="button button-small on-save-service-btn" style="display:none;">Speichern</button>
<button class="button button-small on-cancel-edit-btn" style="display:none;">Abbrechen</button>
<button class="button button-small on-toggle-status-btn" style="margin-left: 5px;">
<?php echo $service['active'] ? 'Deaktivieren' : 'Aktivieren'; ?>
</button>
<button class="button button-small on-delete-service-btn"
style="margin-left: 5px; color: #a00;">Löschen</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<script>
jQuery(document).ready(function ($) {
// Add new service
$('#onAddServiceForm').on('submit', function (e) {
e.preventDefault();
const name = $('#onServiceName').val().trim();
const duration = $('#onServiceDuration').val();
const msg = $('#onAddServiceMsg');
if (!name) {
msg.text('Bitte Namen eingeben').css('color', 'red');
return;
}
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'on_create_service',
name: name,
duration: duration,
nonce: '<?php echo wp_create_nonce('on_booking_nonce'); ?>'
},
success: function (response) {
if (response.success) {
msg.text('✓ Service hinzugefügt').css('color', 'green');
setTimeout(() => location.reload(), 1000);
} else {
msg.text('Fehler: ' + response.data.message).css('color', 'red');
}
}
});
});
// Edit service
$('.on-edit-service-btn').on('click', function () {
const row = $(this).closest('tr');
row.find('.service-name-display, .service-duration-display').hide();
row.find('.service-name-edit, .service-duration-edit').show();
row.find('.on-edit-service-btn').hide();
row.find('.on-save-service-btn, .on-cancel-edit-btn').show();
});
// Cancel edit
$('.on-cancel-edit-btn').on('click', function () {
const row = $(this).closest('tr');
row.find('.service-name-display, .service-duration-display').show();
row.find('.service-name-edit, .service-duration-edit').hide();
row.find('.on-edit-service-btn').show();
row.find('.on-save-service-btn, .on-cancel-edit-btn').hide();
});
// Save service
$('.on-save-service-btn').on('click', function () {
const row = $(this).closest('tr');
const serviceId = row.data('service-id');
const name = row.find('.service-name-edit').val().trim();
const duration = row.find('.service-duration-edit').val();
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'on_update_service',
service_id: serviceId,
name: name,
duration: duration,
nonce: '<?php echo wp_create_nonce('on_booking_nonce'); ?>'
},
success: function (response) {
if (response.success) {
location.reload();
} else {
alert('Fehler: ' + response.data.message);
}
}
});
});
// Toggle status
$('.on-toggle-status-btn').on('click', function () {
const row = $(this).closest('tr');
const serviceId = row.data('service-id');
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'on_toggle_service_status',
service_id: serviceId,
nonce: '<?php echo wp_create_nonce('on_booking_nonce'); ?>'
},
success: function (response) {
if (response.success) {
location.reload();
} else {
alert('Fehler: ' + response.data.message);
}
}
});
});
// Delete service
$('.on-delete-service-btn').on('click', function () {
if (!confirm('Service wirklich löschen?')) return;
const row = $(this).closest('tr');
const serviceId = row.data('service-id');
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'on_delete_service',
service_id: serviceId,
nonce: '<?php echo wp_create_nonce('on_booking_nonce'); ?>'
},
success: function (response) {
if (response.success) {
row.fadeOut(300, function () { $(this).remove(); });
} else {
alert('Fehler: ' + response.data.message);
}
}
});
});
});
</script>
<?php
}
}