| 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/seaside.pacim.de/web/ |
Upload File : |
<?php
/**
* umfrage.php – Öffentlicher Kundenzufriedenheits-Fragebogen.
* Zuordnung pro Buchung über signierten Link: /umfrage.php?b=<booking_id>&h=pacim_sign('survey:'.id)
* Speichert nach pacim_survey; Auswertung im CRM unter /zufriedenheit/.
* Review-Gate: gute Gesamtbewertung -> Bitte um Google-Bewertung (CTA), sonst internes Danke/Feedback.
*
* Google-Bewertungslink: PLACE_ID unten eintragen (search.google.com/local/writereview).
*/
require_once( __DIR__ . '/includes/config.inc.php' );
require_once( __DIR__ . '/includes/survey.php' );
@ini_set( 'display_errors', '0' );
error_reporting( 0 );
while ( ob_get_level() > 0 ) ob_end_clean();
$LOGO = 'https://seaside.pacim.de/assets/images/seaside-logo-white.png'; // Bewertungsziel: pacim_google_review_url()
$bid = (int) ( $_GET['b'] ?? $_POST['b'] ?? 0 );
$h = trim( (string) ( $_GET['h'] ?? $_POST['h'] ?? '' ) );
$action = (string) ( $_POST['action'] ?? '' );
$linkOk = pacim_survey_verify( $bid, $h );
$db = new MysqliDb( MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB );
$db->rawQuery( "SET NAMES utf8mb4" );
// Allgemeiner (buchungsunabhängiger) Bewertungsmodus: ohne Hash, Zuordnung per Session-Cookie.
$general = ( trim( (string) ( $_GET['g'] ?? $_POST['g'] ?? '' ) ) !== '' );
$svSession = (string) ( $_COOKIE['pas_svsession'] ?? '' );
if ( $general && ! preg_match( '/^[a-f0-9]{32}$/', $svSession ) ) {
$svSession = bin2hex( random_bytes( 16 ) );
@setcookie( 'pas_svsession', $svSession, time() + 31536000, '/' );
}
/* ------------------------------------------------- Speichern (AJAX POST) */
if ( $action === 'save' ) {
header( 'Content-Type: application/json; charset=utf-8' );
// ---- Allgemeine Bewertung (Session-basiert, mit Schiff/Stellplatz) ----
if ( $general ) {
pacim_survey_general_ensure( $db );
$clampG = function ( $v ) { $v = (int) $v; return ( $v >= 1 && $v <= 5 ) ? $v : null; };
$overall = $clampG( $_POST['overall'] ?? 0 );
if ( $overall === null ) { echo json_encode( array( 'ok' => false, 'error' => 'overall' ) ); exit(); }
$ship = mb_substr( trim( (string) ( $_POST['ship'] ?? '' ) ), 0, 120 );
$park = in_array( (string) ( $_POST['park'] ?? '' ), array( 'halle', 'aussen' ), true ) ? (string) $_POST['park'] : '';
if ( $ship === '' || $park === '' ) { echo json_encode( array( 'ok' => false, 'error' => 'meta' ) ); exit(); }
$rec = ( isset( $_POST['recommend'] ) && $_POST['recommend'] !== '' ) ? ( (int) $_POST['recommend'] ? 1 : 0 ) : null;
$aspects = array();
foreach ( pacim_survey_aspects( $db ) as $ak => $alabel ) { $v = $clampG( $_POST[ $ak ] ?? 0 ); if ( $v !== null ) $aspects[ $ak ] = $v; }
$db->insert( 'pacim_survey_general', array(
'sg_session' => $svSession ?: 'unknown',
'sg_ship' => $ship, 'sg_park' => $park,
'sg_overall' => $overall, 'sg_recommend' => $rec,
'sg_aspects' => json_encode( $aspects, JSON_UNESCAPED_UNICODE ),
'sg_comment' => mb_substr( trim( (string) ( $_POST['comment'] ?? '' ) ), 0, 600 ),
'sg_ip' => substr( (string) ( $_SERVER['REMOTE_ADDR'] ?? '' ), 0, 45 ),
'sg_ua' => substr( (string) ( $_SERVER['HTTP_USER_AGENT'] ?? '' ), 0, 255 ),
'sg_created' => date( 'Y-m-d H:i:s' ),
) );
echo json_encode( array( 'ok' => true ) );
exit();
}
if ( ! $linkOk ) { echo json_encode( array( 'ok' => false, 'error' => 'link' ) ); exit(); }
$bk = $db->rawQueryOne( "SELECT booking_customer FROM pacim_booking WHERE booking_id = ?", array( $bid ) );
if ( ! $bk ) { echo json_encode( array( 'ok' => false, 'error' => 'notfound' ) ); exit(); }
pacim_survey_ensure( $db );
$clamp = function ( $v ) { $v = (int) $v; return ( $v >= 1 && $v <= 5 ) ? $v : null; };
$overall = $clamp( $_POST['overall'] ?? 0 );
if ( $overall === null ) { echo json_encode( array( 'ok' => false, 'error' => 'overall' ) ); exit(); }
$rec = ( isset( $_POST['recommend'] ) && $_POST['recommend'] !== '' ) ? ( (int) $_POST['recommend'] ? 1 : 0 ) : null;
$data = array(
'survey_booking' => $bid,
'survey_customer' => ( (int) $bk['booking_customer'] ) ?: null,
'survey_overall' => $overall,
'survey_recommend' => $rec,
'survey_comment' => mb_substr( trim( (string) ( $_POST['comment'] ?? '' ) ), 0, 600 ),
'survey_ip' => substr( (string) ( $_SERVER['REMOTE_ADDR'] ?? '' ), 0, 45 ),
'survey_ua' => substr( (string) ( $_SERVER['HTTP_USER_AGENT'] ?? '' ), 0, 255 ),
);
// Aspekte dynamisch: eingebaute -> eigene Spalte survey_a_<key>, custom -> pacim_survey_answers.
$customAnswers = array();
foreach ( pacim_survey_aspects( $db ) as $ak => $alabel ) {
$val = $clamp( $_POST[ $ak ] ?? 0 );
$col = pacim_survey_aspect_column( $ak );
if ( $col !== null ) $data[ $col ] = $val;
else $customAnswers[ $ak ] = $val;
}
$existing = $db->rawQueryOne( "SELECT survey_id FROM pacim_survey WHERE survey_booking = ?", array( $bid ) );
if ( $existing ) {
$surveyId = (int) $existing['survey_id'];
$data['survey_updated'] = date( 'Y-m-d H:i:s' );
$data['survey_seen'] = 0; // aktualisierte Bewertung wieder als „neu" markieren
$db->where( 'survey_id', $surveyId );
$db->update( 'pacim_survey', $data );
} else {
$data['survey_created'] = date( 'Y-m-d H:i:s' );
$surveyId = (int) $db->insert( 'pacim_survey', $data );
}
// Custom-Aspekt-Bewertungen upserten (nur wenn eine survey_id vorliegt).
if ( $surveyId > 0 ) {
foreach ( $customAnswers as $ak => $val ) {
$db->rawQuery(
"INSERT INTO pacim_survey_answers (ans_survey, ans_key, ans_rating) VALUES (?,?,?)
ON DUPLICATE KEY UPDATE ans_rating = VALUES(ans_rating)",
array( $surveyId, $ak, $val )
);
}
}
echo json_encode( array( 'ok' => true ) );
exit();
}
/* ------------------------------------------------- Ungültiger/fehlender Link -> Hinweis */
header( 'Content-Type: text/html; charset=utf-8' );
$shipOptions = array();
$singleShip = null; // steht nur genau ein Schiff zur Auswahl -> keine Abfrage, als Hidden-Wert
if ( $general ) {
/* Allgemeine Umfrage: kein Buchungsbezug, generische Personalisierung + Schiff-Auswahl. */
pacim_survey_general_ensure( $db );
$booking = null;
$firstName = '';
$ship = '';
$trip = '';
$hasSurvey = false;
$reviewLink = pacim_google_review_url();
$custId = 0;
$shipOptions = pacim_survey_ships( $db );
if ( count( $shipOptions ) === 1 ) $singleShip = reset( $shipOptions );
} else {
$booking = $linkOk
? $db->rawQueryOne(
"SELECT b.booking_no, b.booking_event, b.booking_begin, b.booking_end, b.booking_customer,
c.customer_firstname, c.customer_lastname
FROM pacim_booking b
LEFT JOIN pacim_customer c ON c.customer_id = b.booking_customer
WHERE b.booking_id = ?", array( $bid ) )
: null;
if ( ! $linkOk || ! $booking ) {
?><!DOCTYPE html><html lang="de"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"><meta name="robots" content="noindex">
<title>Link ungültig · Parken am Schiff</title>
<style>body{margin:0;min-height:100vh;display:flex;align-items:center;justify-content:center;background:#eef3f8;
font-family:-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;color:#1e2633;padding:24px;text-align:center}
.box{background:#fff;border-radius:18px;box-shadow:0 24px 60px rgba(11,70,119,.16);padding:34px 30px;max-width:440px}
h1{font-size:20px;margin:0 0 8px}p{color:#7e8896;margin:0;font-size:14.5px}</style></head><body>
<div class="box"><div style="font-size:46px;margin-bottom:6px">🔗</div>
<h1>Dieser Bewertungslink ist ungültig</h1>
<p>Der Link ist unvollständig oder abgelaufen. Bitte verwenden Sie den Link direkt aus unserer E-Mail.</p></div>
</body></html><?php
exit();
}
/* ------------------------------------------------- Personalisierung */
$firstName = trim( (string) $booking['customer_firstname'] );
$ship = trim( (string) $booking['booking_event'] );
$bgTs = strtotime( (string) $booking['booking_begin'] );
$enTs = strtotime( (string) $booking['booking_end'] );
$trip = '';
if ( $bgTs && $enTs ) $trip = date( 'd.m.', $bgTs ) . '–' . date( 'd.m.Y', $enTs );
$hasSurvey = (bool) $db->rawQueryOne( "SELECT survey_id FROM pacim_survey WHERE survey_booking = ?", array( $bid ) );
// „Bei Google bewerten"-Ziel: pro Kunde signierter /bewertung/-Redirect (sonst direkt Google).
$custId = (int) $booking['booking_customer'];
$reviewLink = $custId > 0 ? pacim_review_link( $custId ) : pacim_google_review_url();
}
$e = function ( $s ) { return htmlspecialchars( (string) $s, ENT_QUOTES, 'UTF-8' ); };
?><!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="robots" content="noindex">
<title>Ihre Meinung zählt · Parken am Schiff</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
:root{
--pas-blue:#0b4677; --pas-blue2:#1a6bb0; --pas-ink:#1e2633; --pas-muted:#7e8896;
--pas-line:#e6eef4; --pas-star:#ffb400; --pas-bg:#eef3f8; --pas-radius:18px;
}
*{box-sizing:border-box}
body{margin:0;background:linear-gradient(160deg,#eef3f8 0%,#e3edf6 100%);min-height:100vh;
font-family:'Poppins',-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;color:var(--pas-ink);
display:flex;align-items:center;justify-content:center;padding:24px 14px;}
.pas-card{width:100%;max-width:560px;background:#fff;border-radius:var(--pas-radius);
box-shadow:0 24px 60px rgba(11,70,119,.16);overflow:hidden}
.pas-head{background:linear-gradient(135deg,var(--pas-blue),var(--pas-blue2));color:#fff;padding:26px 26px 22px;text-align:center}
.pas-head img{height:46px;width:auto;margin-bottom:12px}
.pas-head h1{font-size:20px;font-weight:600;margin:0 0 4px}
.pas-head p{margin:0;opacity:.9;font-size:14px}
.pas-trip{display:inline-block;margin-top:12px;background:rgba(255,255,255,.15);border-radius:999px;padding:5px 14px;font-size:12.5px}
.pas-progress{height:5px;background:rgba(255,255,255,.25);border-radius:99px;margin:16px auto 0;max-width:280px;overflow:hidden}
.pas-progress span{display:block;height:100%;background:#fff;border-radius:99px;width:33%;transition:width .35s ease}
.pas-step-count{font-size:12px;opacity:.85;margin-top:8px;letter-spacing:.3px}
.pas-body{padding:26px}
.pas-note{background:#fff7e6;border:1px solid #ffe1a8;color:#8a6400;border-radius:12px;padding:11px 14px;font-size:13px;margin-bottom:18px}
.pas-step{display:none;animation:pasIn .3s ease}
.pas-step.active{display:block}
@keyframes pasIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.pas-q{font-size:17px;font-weight:600;margin:0 0 4px}
.pas-q-sub{color:var(--pas-muted);font-size:13.5px;margin:0 0 18px}
.pas-ship-fixed{background:var(--pas-soft,#f3f5f9);border-radius:10px;padding:11px 14px;font-size:15px}
.pas-ship-fixed .pas-q-sub{margin:0;display:inline}
/* Sterne */
.pas-stars{display:flex;gap:8px;justify-content:center;margin:8px 0 4px}
.pas-stars.lg{gap:12px}
.pas-star{font-size:34px;line-height:1;color:#d7e1ea;cursor:pointer;transition:transform .1s,color .15s;user-select:none}
.pas-stars.lg .pas-star{font-size:46px}
.pas-star:hover{transform:scale(1.12)}
.pas-star.on{color:var(--pas-star)}
.pas-stars-label{text-align:center;color:var(--pas-muted);font-size:13px;min-height:18px;margin-bottom:6px}
/* Aspekt-Zeilen */
.pas-aspect{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 0;border-bottom:1px solid var(--pas-line)}
.pas-aspect:last-child{border-bottom:0}
.pas-aspect .lab{font-size:14.5px;font-weight:500}
.pas-aspect .pas-stars{margin:0;gap:5px}
.pas-aspect .pas-star{font-size:24px}
/* Empfehlung */
.pas-choice{display:flex;gap:10px;flex-wrap:wrap}
.pas-chip{flex:1 1 0;min-width:120px;border:1.5px solid var(--pas-line);border-radius:12px;padding:14px;text-align:center;
cursor:pointer;font-weight:600;transition:.15s;background:#fff}
.pas-chip:hover{border-color:var(--pas-blue2)}
.pas-chip.sel{border-color:var(--pas-blue);background:#eef5fb;color:var(--pas-blue)}
.pas-chip small{display:block;font-weight:400;color:var(--pas-muted);font-size:12px;margin-top:2px}
textarea.form-control{border-radius:12px;border-color:var(--pas-line);resize:vertical}
textarea.form-control:focus{border-color:var(--pas-blue2);box-shadow:0 0 0 .2rem rgba(26,107,176,.15)}
/* Buttons */
.pas-actions{display:flex;gap:10px;margin-top:24px}
.btn-pas{background:var(--pas-blue);border:0;color:#fff;border-radius:12px;padding:13px 20px;font-weight:600;flex:1;transition:.15s}
.btn-pas:hover{background:var(--pas-blue2);color:#fff}
.btn-pas:disabled{opacity:.5}
.btn-pas-ghost{background:transparent;border:1.5px solid var(--pas-line);color:var(--pas-ink);border-radius:12px;padding:13px 18px;font-weight:600}
.btn-pas-ghost:hover{border-color:var(--pas-blue2);color:var(--pas-blue)}
/* PRIMÄRE Aktion: Google-Bewertung – bewusst auffällig (Ziel der Seite) */
.btn-google{background:linear-gradient(135deg,#1a73e8,#1567d3);border:0;color:#fff;border-radius:14px;padding:17px 22px;font-weight:800;font-size:17px;
display:inline-flex;align-items:center;justify-content:center;gap:12px;width:100%;text-decoration:none;transition:filter .15s,transform .1s,box-shadow .15s;
box-shadow:0 10px 26px rgba(26,115,232,.38);}
.btn-google:hover{color:#fff;filter:brightness(1.05);box-shadow:0 14px 32px rgba(26,115,232,.5);}
.btn-google:active{transform:scale(.99);}
.btn-google .g-chip{width:30px;height:30px;border-radius:50%;background:#fff;display:inline-flex;align-items:center;justify-content:center;flex:none;box-shadow:0 2px 6px rgba(0,0,0,.15);}
.btn-google .g-chip svg{width:19px;height:19px;}
/* SEKUNDÄRE Aktion: Social-Kanäle – dezent, damit der Google-Button dominiert */
.pas-social-lbl{font-size:12px;color:var(--pas-muted);font-weight:700;text-transform:uppercase;letter-spacing:.05em;margin:30px 0 10px;}
.pas-social{display:flex;gap:11px;}
.pas-soc{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:8px;border-radius:12px;padding:12px 10px;font-weight:700;font-size:14.5px;text-decoration:none;border:1.5px solid transparent;transition:.15s;}
.pas-soc svg{width:19px;height:19px;flex:none;}
.pas-soc:active{transform:scale(.98);}
.pas-fb{background:#eef4fe;color:#1877f2;border-color:#cfe0fb;}
.pas-fb:hover{background:#e2edfd;color:#1877f2;}
.pas-ig{background:#fdeef6;color:#c1358a;border-color:#f4cfe3;}
.pas-ig:hover{background:#fbe3f0;color:#c1358a;}
/* Ergebnis */
.pas-result{display:none;padding:34px 26px;text-align:center}
.pas-result.active{display:block;animation:pasIn .35s ease}
.pas-emoji{font-size:54px;line-height:1;margin-bottom:8px}
.pas-result h2{font-size:21px;font-weight:600;margin:0 0 8px}
.pas-result p{color:var(--pas-muted);font-size:14.5px;margin:0 auto 20px;max-width:420px}
.pas-foot{text-align:center;color:var(--pas-muted);font-size:11.5px;padding:0 26px 22px}
.pas-foot a{color:var(--pas-muted)}
.pas-req{color:#d23}
</style>
</head>
<body>
<div class="pas-card">
<div class="pas-head">
<img src="<?php echo $e( $LOGO ); ?>" alt="SeaSide Travel Parking" onerror="this.style.display='none'">
<h1><?php echo $firstName !== '' ? 'Hallo ' . $e( $firstName ) . ', Ihre Meinung zählt' : 'Ihre Meinung zählt'; ?></h1>
<p>2 Minuten – wir möchten unseren Service für Sie verbessern.</p>
<?php if ( $ship !== '' || $trip !== '' ) { ?>
<div class="pas-trip">🚢 <?php echo $e( trim( $ship . ( $trip !== '' ? ' · ' . $trip : '' ), ' ·' ) ); ?></div>
<?php } ?>
<div class="pas-progress" id="pasBar"><span></span></div>
<div class="pas-step-count" id="pasCount">Schritt 1 von 3</div>
</div>
<form id="pasForm" class="pas-body" novalidate>
<?php if ( $hasSurvey ) { ?>
<div class="pas-note">Sie haben zu dieser Reise bereits eine Bewertung abgegeben – vielen Dank! Sie können sie hier gerne aktualisieren.</div>
<?php } ?>
<?php if ( $general ) { ?>
<!-- Schritt 0: Angaben zur Reise (nur allgemeiner Link) -->
<div class="pas-step active" data-step="meta" data-requires="meta">
<p class="pas-q">Zu welcher Reise möchten Sie uns bewerten?</p>
<?php if ( $singleShip !== null ) { ?>
<p class="pas-q-sub">Bitte kurz den Stellplatz wählen.</p>
<input type="hidden" id="pasShip" value="<?php echo $e( $singleShip ); ?>">
<div class="pas-ship-fixed mb-3"><span class="pas-q-sub">Schiff:</span> <strong><?php echo $e( $singleShip ); ?></strong></div>
<?php } else { ?>
<p class="pas-q-sub">Bitte kurz Schiff und Stellplatz wählen.</p>
<label class="pas-q-sub d-block mb-1">Schiff <span class="pas-req">*</span></label>
<select class="form-select mb-3" id="pasShip">
<option value="">Bitte wählen …</option>
<?php foreach ( $shipOptions as $sh ) { echo '<option value="' . $e( $sh ) . '">' . $e( $sh ) . '</option>'; } ?>
</select>
<?php } ?>
<label class="pas-q-sub d-block mb-1">Stellplatz <span class="pas-req">*</span></label>
<div class="pas-choice" data-field="park">
<div class="pas-chip" data-v="halle">🏠 Halle</div>
<div class="pas-chip" data-v="aussen">🅿️ Außen</div>
</div>
<div class="pas-actions">
<button type="button" class="btn-pas" data-next disabled>Weiter</button>
</div>
</div>
<?php } ?>
<!-- Schritt 1: Gesamtzufriedenheit -->
<div class="pas-step<?php echo $general ? '' : ' active'; ?>" data-step="1" data-requires="overall">
<p class="pas-q">Wie zufrieden waren Sie insgesamt mit Parken am Schiff? <span class="pas-req">*</span></p>
<p class="pas-q-sub">Von der Buchung bis zur Rückgabe Ihres Fahrzeugs.</p>
<div class="pas-stars lg" data-rating="overall">
<span class="pas-star" data-v="1">★</span><span class="pas-star" data-v="2">★</span><span class="pas-star" data-v="3">★</span><span class="pas-star" data-v="4">★</span><span class="pas-star" data-v="5">★</span>
</div>
<div class="pas-stars-label" data-label="overall"></div>
<div class="pas-actions">
<button type="button" class="btn-pas" data-next disabled>Weiter</button>
</div>
</div>
<!-- Schritt 2: Detail-Aspekte -->
<div class="pas-step" data-step="2">
<p class="pas-q">Wie bewerten Sie diese Punkte?</p>
<p class="pas-q-sub">Tippen Sie pro Zeile auf die Sterne.</p>
<?php foreach ( pacim_survey_aspects( $db ) as $ak => $alabel ): ?>
<div class="pas-aspect"><span class="lab"><?php echo htmlspecialchars( $alabel, ENT_QUOTES, 'UTF-8' ); ?></span>
<div class="pas-stars" data-rating="<?php echo htmlspecialchars( $ak, ENT_QUOTES, 'UTF-8' ); ?>"><span class="pas-star" data-v="1">★</span><span class="pas-star" data-v="2">★</span><span class="pas-star" data-v="3">★</span><span class="pas-star" data-v="4">★</span><span class="pas-star" data-v="5">★</span></div></div>
<?php endforeach; ?>
<div class="pas-actions">
<button type="button" class="btn-pas-ghost" data-prev>Zurück</button>
<button type="button" class="btn-pas" data-next>Weiter</button>
</div>
</div>
<!-- Schritt 3: Empfehlung + Kommentar -->
<div class="pas-step" data-step="3" data-requires="recommend">
<p class="pas-q">Würden Sie uns weiterempfehlen? <span class="pas-req">*</span></p>
<p class="pas-q-sub">Ihre Empfehlung hilft anderen Reisenden.</p>
<div class="pas-choice" data-field="recommend">
<div class="pas-chip" data-v="1">👍 Ja, gerne<small>Würde wieder buchen</small></div>
<div class="pas-chip" data-v="0">🤔 Eher nicht<small>Da geht noch was</small></div>
</div>
<div class="mt-3">
<label class="pas-q-sub d-block mb-1" for="pasComment">Möchten Sie uns noch etwas mitteilen? <span class="text-muted">(optional)</span></label>
<textarea class="form-control" id="pasComment" rows="3" maxlength="600" placeholder="Lob, Anregung oder Kritik …"></textarea>
</div>
<div class="pas-actions">
<button type="button" class="btn-pas-ghost" data-prev>Zurück</button>
<button type="submit" class="btn-pas" id="pasSubmit">Absenden</button>
</div>
</div>
</form>
<!-- Ergebnis: gut bewertet -> Google-CTA -->
<div class="pas-result" id="pasGood">
<div class="pas-emoji">🙏</div>
<h2>Vielen Dank für Ihre Bewertung!</h2>
<p>Es freut uns sehr, dass Sie zufrieden waren. Wenn Sie uns unterstützen möchten: Eine kurze Google-Bewertung hilft uns enorm und ist in 30 Sekunden erledigt.</p>
<a class="btn-google" id="pasGoogle" href="#" target="_blank" rel="noopener">
<span class="g-chip"><svg viewBox="0 0 48 48"><path fill="#FFC107" d="M43.6 20.5H42V20H24v8h11.3C33.7 32.4 29.2 35 24 35c-6.6 0-12-5.4-12-12s5.4-12 12-12c3.1 0 5.9 1.2 8 3.1l5.7-5.7C34.5 5 29.5 3 24 3 12.4 3 3 12.4 3 24s9.4 21 21 21 21-9.4 21-21c0-1.2-.1-2.3-.4-3.5z"/><path fill="#FF3D00" d="M6.3 14.7l6.6 4.8C14.7 16 19 13 24 13c3.1 0 5.9 1.2 8 3.1l5.7-5.7C34.5 7 29.8 5 24 5 16 5 9.1 9.5 6.3 14.7z"/><path fill="#4CAF50" d="M24 45c5.2 0 9.9-2 13.4-5.2l-6.2-5.2C29.2 36 26.7 37 24 37c-5.2 0-9.6-2.6-11.3-7l-6.5 5C9.1 40.5 16 45 24 45z"/><path fill="#1976D2" d="M43.6 20.5H42V20H24v8h11.3c-.8 2.4-2.4 4.4-4.5 5.6l6.2 5.2C40.9 36.5 45 31 45 24c0-1.2-.1-2.3-.4-3.5z"/></svg></span>
Jetzt bei Google bewerten
</a>
<div class="pas-social-lbl">Folgen Sie uns</div>
<div class="pas-social">
<a class="pas-soc pas-fb" href="https://www.facebook.com/ParkenWarnemuendeKreuzfahrt/" target="_blank" rel="noopener">
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M22 12a10 10 0 1 0-11.56 9.88v-6.99H7.9V12h2.54V9.8c0-2.5 1.49-3.89 3.77-3.89 1.09 0 2.24.2 2.24.2v2.46h-1.26c-1.24 0-1.63.77-1.63 1.56V12h2.78l-.44 2.89h-2.34v6.99A10 10 0 0 0 22 12z"/></svg>
Facebook
</a>
<a class="pas-soc pas-ig" href="https://www.instagram.com/seaside.parking/" target="_blank" rel="noopener">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17.5" cy="6.5" r="1.1" fill="currentColor" stroke="none"/></svg>
Instagram
</a>
</div>
</div>
<!-- Ergebnis: Verbesserungspotenzial -> internes Danke -->
<div class="pas-result" id="pasImprove">
<div class="pas-emoji">💙</div>
<h2>Danke für Ihr ehrliches Feedback!</h2>
<p>Es tut uns leid, dass nicht alles rund lief. Ihr Feedback geht direkt an unser Team – wir nehmen es ernst und arbeiten daran, beim nächsten Mal zu überzeugen.</p>
<p class="text-muted" style="font-size:13px">Bei einem konkreten Anliegen erreichen Sie uns unter <a href="mailto:info@parken-am-schiff.de">info@parken-am-schiff.de</a>.</p>
<div><button type="button" class="btn-pas-ghost" onclick="window.close()">Schließen</button></div>
</div>
<div class="pas-foot">
SeaSide Travel GmbH & Co. Immobilien KG · Parken am Schiff · Warnemünde<br>
Ihre Angaben werden vertraulich behandelt.
</div>
</div>
<script>
(function(){
var REVIEW_LINK = <?php echo json_encode( $reviewLink ); ?>;
var SURVEY_B = <?php echo json_encode( (string) $bid ); ?>;
var SURVEY_H = <?php echo json_encode( $h ); ?>;
var GENERAL = <?php echo $general ? 'true' : 'false'; ?>;
var data = { overall:0, recommend:null, comment:'', ship:'', park:'' };
// Aspekt-Keys dynamisch aus dem DOM (inkl. verwaltbarer/neuer Bereiche in Schritt 2)
document.querySelectorAll('.pas-step[data-step="2"] .pas-stars[data-rating]').forEach(function(b){ data[b.dataset.rating] = 0; });
var LABELS = ['', 'Sehr unzufrieden', 'Unzufrieden', 'Geht so', 'Zufrieden', 'Begeistert'];
var steps = Array.prototype.slice.call(document.querySelectorAll('.pas-step'));
var cur = 0;
function paint(group){
document.querySelectorAll('.pas-stars[data-rating="'+group+'"] .pas-star').forEach(function(s){
s.classList.toggle('on', parseInt(s.dataset.v,10) <= data[group]);
});
var lab = document.querySelector('[data-label="'+group+'"]');
if (lab) lab.textContent = data[group] ? LABELS[data[group]] : '';
}
// Sterne
document.querySelectorAll('.pas-stars').forEach(function(box){
var group = box.dataset.rating;
box.querySelectorAll('.pas-star').forEach(function(star){
star.addEventListener('click', function(){ data[group] = parseInt(star.dataset.v,10); paint(group); refreshNav(); });
star.addEventListener('mouseenter', function(){
var v = parseInt(star.dataset.v,10);
box.querySelectorAll('.pas-star').forEach(function(s){ s.classList.toggle('on', parseInt(s.dataset.v,10) <= v); });
});
});
box.addEventListener('mouseleave', function(){ paint(group); });
});
// Auswahl-Chips (Empfehlung sowie Stellplatz im allgemeinen Modus)
document.querySelectorAll('.pas-choice').forEach(function(choice){
var field = choice.dataset.field;
choice.querySelectorAll('.pas-chip').forEach(function(chip){
chip.addEventListener('click', function(){
choice.querySelectorAll('.pas-chip').forEach(function(c){ c.classList.remove('sel'); });
chip.classList.add('sel');
if (field === 'recommend') data.recommend = parseInt(chip.dataset.v, 10);
else if (field) data[field] = chip.dataset.v;
refreshNav();
});
});
});
// Schiff-Auswahl (allgemeiner Modus)
var shipSel = document.getElementById('pasShip');
// Bei nur einem Schiff ist #pasShip ein Hidden-Feld mit vorbelegtem Wert -> direkt übernehmen;
// bei mehreren ein Auswahlfeld (Startwert leer), das per change aktualisiert wird.
if (shipSel) { data.ship = shipSel.value; shipSel.addEventListener('change', function(){ data.ship = shipSel.value; refreshNav(); }); }
function showStep(i){
cur = i;
steps.forEach(function(s,idx){ s.classList.toggle('active', idx===i); });
document.querySelector('#pasBar span').style.width = Math.round(((i+1)/steps.length)*100)+'%';
document.getElementById('pasCount').textContent = 'Schritt '+(i+1)+' von '+steps.length;
refreshNav();
document.querySelector('.pas-card').scrollIntoView({behavior:'smooth', block:'start'});
}
function refreshNav(){
var s = steps[cur];
var req = s.getAttribute('data-requires');
var ok = true;
if (req === 'meta') ok = !!(data.ship && data.park); // Schiff/Stellplatz
else if (req === 'overall') ok = data.overall > 0; // Gesamtbewertung Pflicht
else if (req === 'recommend') ok = data.recommend !== null; // Empfehlung Pflicht
var nextBtn = s.querySelector('[data-next]'); if (nextBtn) nextBtn.disabled = !ok;
var submit = s.querySelector('[type="submit"]'); if (submit) submit.disabled = !ok;
}
document.querySelectorAll('[data-next]').forEach(function(b){ b.addEventListener('click', function(){ if(cur<steps.length-1) showStep(cur+1); }); });
document.querySelectorAll('[data-prev]').forEach(function(b){ b.addEventListener('click', function(){ if(cur>0) showStep(cur-1); }); });
function showResult(){
document.getElementById('pasForm').style.display='none';
var sc = document.querySelector('.pas-step-count'); if (sc) sc.style.display='none';
document.querySelector('#pasBar span').style.width='100%';
var good = (data.overall>=4 && data.recommend===1);
if (good){
document.getElementById('pasGoogle').href = REVIEW_LINK;
document.getElementById('pasGood').classList.add('active');
} else {
document.getElementById('pasImprove').classList.add('active');
}
}
document.getElementById('pasForm').addEventListener('submit', function(e){
e.preventDefault();
if (data.recommend===null || data.overall===0) return;
if (GENERAL && (!data.ship || !data.park)) return;
data.comment = document.getElementById('pasComment').value.trim();
var submit = document.getElementById('pasSubmit');
if (submit){ submit.disabled = true; submit.textContent = 'Wird gesendet …'; }
var body = new URLSearchParams();
body.append('action','save');
if (GENERAL){ body.append('g','1'); body.append('ship',data.ship); body.append('park',data.park); }
else { body.append('b',SURVEY_B); body.append('h',SURVEY_H); }
body.append('overall', data.overall);
body.append('recommend', (data.recommend===null?'':data.recommend));
body.append('comment', data.comment);
Object.keys(data).forEach(function(k){ // alle Aspekt-Bewertungen (dynamisch)
if (['overall','recommend','comment','ship','park'].indexOf(k)!==-1) return;
body.append(k, data[k]);
});
fetch('umfrage.php', { method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded;charset=UTF-8'}, body:body.toString() })
.then(function(r){ return r.json(); })
.then(function(res){ showResult(); })
.catch(function(){ showResult(); }); // Kunde soll nie im Fehler hängen bleiben
});
showStep(0);
})();
</script>
</body>
</html>