diff --git a/assets/css/forum-style.css b/assets/css/forum-style.css
index 93328bf..a8f5e9f 100644
--- a/assets/css/forum-style.css
+++ b/assets/css/forum-style.css
@@ -416,14 +416,57 @@ a.wbf-btn--primary:hover {
align-items: center;
text-align: center;
}
+
+/* Banner */
+.wbf-profile-banner {
+ position: relative;
+ width: 100%;
+ height: 120px;
+ overflow: hidden;
+ background: linear-gradient(135deg, #0a1628 0%, #162040 50%, #0d1a30 100%);
+}
+.wbf-profile-banner__img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ display: block;
+}
+.wbf-profile-banner__placeholder {
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(135deg, #0a1628 0%, #162040 50%, #0d1a30 100%);
+}
+.wbf-banner-upload-btn {
+ position: absolute;
+ bottom: 8px;
+ right: 8px;
+ width: 32px;
+ height: 32px;
+ border-radius: 50%;
+ background: rgba(0,0,0,.55);
+ backdrop-filter: blur(6px);
+ color: #fff;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: background .2s, transform .15s;
+ font-size: .8rem;
+ border: 1px solid rgba(255,255,255,.15);
+}
+.wbf-banner-upload-btn:hover {
+ background: rgba(0,180,216,.5);
+ transform: scale(1.1);
+}
+
.wbf-profile-sidebar__avatar-wrap {
position: relative;
- padding: 2rem 0 1.25rem;
+ padding: 0 0 1.25rem;
+ margin-top: -45px;
width: 100%;
display: flex;
justify-content: center;
- background: linear-gradient(160deg, #0d1117, #161d2e);
- border-bottom: 1px solid rgba(0,180,216,.12);
+ z-index: 2;
}
.wbf-profile-sidebar__avatar {
width: 100px; height: 100px;
@@ -557,6 +600,235 @@ a.wbf-btn--primary:hover {
padding-top: 1rem;
border-top: 1px solid var(--c-border);
}
+/* ── Verbindungen / Connection Cards ────────────────────────────────────── */
+.wbf-connection-card {
+ display: grid;
+ grid-template-columns: 56px 1fr;
+ grid-template-rows: auto auto;
+ gap: 0 1.1rem;
+ padding: 1.4rem 1.25rem;
+ border-bottom: 1px solid var(--c-border);
+ transition: background .15s;
+}
+.wbf-connection-card:last-child { border-bottom: none; }
+.wbf-connection-card:hover { background: rgba(255,255,255,.025); }
+
+.wbf-connection-card__icon {
+ grid-column: 1;
+ grid-row: 1 / 3;
+ width: 48px;
+ height: 48px;
+ border-radius: 12px;
+ border: 1px solid transparent;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 1.35rem;
+ align-self: center;
+}
+
+/* Titelzeile — rechts oben */
+.wbf-connection-card__head {
+ grid-column: 2;
+ grid-row: 1;
+ display: flex;
+ align-items: center;
+ gap: .6rem;
+ margin-bottom: .5rem;
+}
+
+.wbf-connection-card__body {
+ flex: 1;
+ min-width: 0;
+}
+
+.wbf-connection-card__title {
+ font-weight: 700;
+ font-size: .92rem;
+ color: var(--c-text);
+ line-height: 1;
+}
+
+.wbf-connection-card__desc {
+ font-size: .82rem;
+ color: var(--c-muted);
+ line-height: 1.55;
+ margin-bottom: .85rem;
+}
+
+/* Content-Bereich — grid row 2, rechte Spalte */
+.wbf-connection-card__content {
+ grid-column: 2;
+ grid-row: 2;
+}
+
+/* Plugin-Output normalisieren */
+.wbf-connection-card__content p {
+ font-size: .8rem;
+ color: var(--c-muted);
+ line-height: 1.5;
+ margin: 0 0 .7rem;
+ font-weight: 400 !important;
+}
+.wbf-connection-card__content label {
+ display: block;
+ font-size: .75rem;
+ font-weight: 600;
+ color: var(--c-text-dim);
+ text-transform: uppercase;
+ letter-spacing: .04em;
+ margin-bottom: .35rem;
+}
+.wbf-connection-card__content .wbf-mc-row,
+.wbf-connection-card__content > form,
+.wbf-connection-card__content > div {
+ display: flex;
+ align-items: center;
+ gap: .55rem;
+ flex-wrap: wrap;
+}
+
+/* Input + Button auf einer Linie halten */
+.wbf-connect-row {
+ display: flex !important;
+ align-items: center !important;
+ gap: .55rem !important;
+ flex-wrap: nowrap !important;
+}
+.wbf-connect-row input[type="text"] {
+ flex: 1 1 0;
+ min-width: 0;
+ max-width: none !important;
+}
+.wbf-connect-row button,
+.wbf-connect-row .wbf-btn {
+ flex-shrink: 0;
+ white-space: nowrap;
+}
+
+/* Alle Verknüpfen-Buttons in Connection-Cards vereinheitlichen */
+.wbf-connection-card__content .wbf-btn,
+.wbf-connection-card__content button:not(.wbf-bb-spoiler__btn) {
+ padding: .5rem 1rem !important;
+ font-size: .83rem !important;
+ font-weight: 600 !important;
+ height: 2.25rem !important;
+ line-height: 1 !important;
+ display: inline-flex !important;
+ align-items: center !important;
+ gap: .4rem !important;
+ border-radius: var(--radius-sm) !important;
+ border: 1.5px solid transparent !important;
+ cursor: pointer !important;
+ font-family: inherit !important;
+ transition: var(--transition) !important;
+ white-space: nowrap !important;
+}
+/* Primär (Verknüpfen / Code senden) */
+.wbf-connection-card__content .wbf-btn--primary,
+.wbf-connection-card__content button.wbf-btn--primary {
+ background: var(--c-primary) !important;
+ color: #fff !important;
+ border-color: var(--c-primary) !important;
+ box-shadow: 0 0 10px rgba(0,180,216,.25) !important;
+}
+.wbf-connection-card__content .wbf-btn--primary:hover {
+ background: var(--c-primary-d) !important;
+ border-color: var(--c-primary-d) !important;
+}
+/* Ghost (Zurück / Trennen) */
+.wbf-connection-card__content .wbf-btn--ghost,
+.wbf-connection-card__content button.wbf-btn--ghost {
+ background: transparent !important;
+ color: var(--c-text-dim) !important;
+ border-color: var(--c-border-d) !important;
+}
+.wbf-connection-card__content .wbf-btn--ghost:hover {
+ border-color: var(--c-primary) !important;
+ color: var(--c-primary) !important;
+}
+/* MC-Plugin: dessen Button via content selector normalisieren */
+.wbf-connection-card__content input[type="submit"],
+.wbf-connection-card__content .mc-connect-btn {
+ padding: .5rem 1rem !important;
+ height: 2.25rem !important;
+ font-size: .83rem !important;
+ font-weight: 600 !important;
+ background: var(--c-primary) !important;
+ color: #fff !important;
+ border: 1.5px solid var(--c-primary) !important;
+ border-radius: var(--radius-sm) !important;
+ cursor: pointer !important;
+ font-family: inherit !important;
+ white-space: nowrap !important;
+ display: inline-flex !important;
+ align-items: center !important;
+}
+.wbf-connection-card__content input[type="text"] {
+ flex: 1;
+ min-width: 160px;
+ max-width: 280px;
+ padding: .45rem .75rem;
+ border: 1px solid var(--c-border);
+ border-radius: var(--radius-sm, 6px);
+ background: var(--c-bg);
+ color: var(--c-text);
+ font-size: .88rem;
+}
+.wbf-connection-card__content input[type="text"]:focus {
+ outline: none;
+ border-color: var(--c-primary);
+ box-shadow: 0 0 0 3px rgba(0,180,216,.15);
+}
+.wbf-connection-card__content button,
+.wbf-connection-card__content .wbf-btn {
+ white-space: nowrap;
+}
+
+/* Status-Badge in der Card (verbunden / nicht verbunden) */
+.wbf-connection-badge {
+ display: inline-flex;
+ align-items: center;
+ gap: .35rem;
+ font-size: .78rem;
+ font-weight: 600;
+ padding: .25rem .65rem;
+ border-radius: 20px;
+}
+.wbf-connection-badge--connected {
+ color: #16a34a;
+ background: rgba(22,163,74,.12);
+ border: 1px solid rgba(22,163,74,.25);
+}
+.wbf-connection-badge--disconnected {
+ color: var(--c-muted);
+ background: rgba(148,163,184,.08);
+ border: 1px solid var(--c-border);
+}
+
+/* Discord-spezifische Farben */
+.wbf-connection-card--discord .wbf-connection-card__icon {
+ background: rgba(88,101,242,.15);
+ border-color: rgba(88,101,242,.3);
+}
+.wbf-connection-card--discord .wbf-connection-card__icon i {
+ color: #5865f2;
+}
+
+/* Verbunden-Info */
+.wbf-discord-linked-name {
+ display: inline-flex;
+ align-items: center;
+ gap: .4rem;
+ font-weight: 700;
+ font-size: .92rem;
+ color: var(--c-text);
+ padding: .35rem .75rem;
+ background: rgba(88,101,242,.1);
+ border: 1px solid rgba(88,101,242,.25);
+ border-radius: 20px;
+}
+
.wbf-profile-edit-grid {
display: grid;
grid-template-columns: 1fr 1fr;
@@ -1816,10 +2088,15 @@ select.wbf-cf-input option { background: var(--c-surface2); color: var(--c-text)
text-align: left;
}
.wbf-profile-sidebar__avatar-wrap {
- padding: 1.25rem;
+ padding: 0 0 1rem;
+ margin-top: -45px;
width: auto;
border-bottom: none;
- border-right: 1px solid var(--c-border);
+ border-right: none;
+ }
+ .wbf-profile-banner {
+ height: 100px;
+ width: 100%;
}
.wbf-profile-sidebar__identity {
align-items: flex-start;
diff --git a/assets/js/forum-script.js b/assets/js/forum-script.js
index da4fdb0..f9ebd0a 100644
--- a/assets/js/forum-script.js
+++ b/assets/js/forum-script.js
@@ -3,6 +3,10 @@
/* ── Utilities ──────────────────────────────────────────────── */
function wbfPost(action, data, cb, errCb) {
+ if (typeof WBF === 'undefined' || !WBF.ajax_url || !WBF.nonce) {
+ if (errCb) errCb({message: 'Forum-Fehler: AJAX-Setup fehlt. Bitte Seite neu laden.'});
+ return;
+ }
data.action = action;
data.nonce = WBF.nonce;
$.post(WBF.ajax_url, data, function (res) {
@@ -52,12 +56,18 @@
/* ── Registrieren ───────────────────────────────────────────── */
$(document).on('click', '.wbf-reg-submit-btn', function () {
var $btn = $(this).prop('disabled', true).html('');
+ var $invite = $(this).closest('.wbf-auth-box').find('.wbf-field-invite-code');
+ var inviteVal = '';
+ if ($invite.length > 0) {
+ var raw = $invite.val();
+ if (typeof raw === 'string') inviteVal = raw.toUpperCase().trim();
+ }
wbfPost('wbf_register', {
username: $(this).closest('.wbf-auth-box').find('.wbf-field-reg-user').val(),
display_name: $(this).closest('.wbf-auth-box').find('.wbf-field-reg-name').val(),
email: $(this).closest('.wbf-auth-box').find('.wbf-field-reg-email').val(),
password: $(this).closest('.wbf-auth-box').find('.wbf-field-reg-pass').val(),
- invite_code: $(this).closest('.wbf-auth-box').find('.wbf-field-invite-code').val().toUpperCase().trim(),
+ invite_code: inviteVal,
rules_accepted: $(this).closest('.wbf-auth-box').find('.wbf-field-rules-accept').is(':checked') ? '1' : ''
}, function () {
location.reload();
@@ -609,6 +619,48 @@
});
});
+ // ── Banner-Upload ─────────────────────────────────────────────────────────
+ $(document).on('change', '#wbfBannerFile', function () {
+ var file = this.files[0];
+ if (!file) return;
+
+ // Sofort-Vorschau
+ var objectUrl = URL.createObjectURL(file);
+ var $wrap = $('#wbfProfileBannerWrap');
+ var $existing = $wrap.find('.wbf-profile-banner__img');
+
+ // Falls noch kein Banner-Bild existiert, eins einfügen
+ if ($existing.length === 0) {
+ $wrap.prepend('
');
+ } else {
+ $existing.attr('src', objectUrl).css('opacity', '.4');
+ }
+
+ var fd = new FormData();
+ fd.append('action', 'wbf_upload_banner');
+ fd.append('nonce', WBF.nonce);
+ fd.append('banner', file);
+
+ $.ajax({
+ url: WBF.ajax_url,
+ type: 'POST',
+ data: fd,
+ processData: false,
+ contentType: false,
+ success: function (res) {
+ var $img = $wrap.find('.wbf-profile-banner__img');
+ if (res.success) {
+ URL.revokeObjectURL(objectUrl);
+ $img.attr('src', res.data.banner_url + '?v=' + Date.now());
+ }
+ $img.css('opacity', '');
+ },
+ error: function () {
+ $wrap.find('.wbf-profile-banner__img').css('opacity', '');
+ }
+ });
+ });
+
/* ══════════════════════════════════════════════════════════
FEATURE: Ungelesene Beiträge
══════════════════════════════════════════════════════════ */
@@ -2163,4 +2215,132 @@
$bar.hide();
});
-}(jQuery));
\ No newline at end of file
+
+
+ // ── Discord-Integration (3-Schritt Verifikation) ─────────────────────────
+
+ var wbfDcStep = 1; // aktueller Schritt
+
+ function wbfDcMsg(text, color) {
+ var $m = $('#wbf-discord-msg');
+ $m.css('color', color || 'var(--c-muted)').html(text);
+ }
+
+ function wbfDcSetBadge(connected) {
+ var $badge = $('.wbf-connection-card--discord .wbf-connection-badge');
+ if (connected) {
+ $badge.removeClass('wbf-connection-badge--disconnected')
+ .addClass('wbf-connection-badge--connected')
+ .html(' Verbunden');
+ } else {
+ $badge.removeClass('wbf-connection-badge--connected')
+ .addClass('wbf-connection-badge--disconnected')
+ .html(' Nicht verbunden');
+ }
+ }
+
+ // Schritt 1 → Code senden
+ $(document).on('click', '#wbf-discord-send-code', function () {
+ var username = $('#wbf-discord-input').val().trim();
+ if (!username) { wbfDcMsg(' Bitte Benutzername eingeben.', '#f97316'); return; }
+ var $btn = $(this).prop('disabled', true).html(' Sende…');
+ wbfDcMsg('');
+ $.post(WBF.ajax_url, {
+ action: 'wbf_discord_send_code',
+ nonce: WBF.nonce,
+ discord_username: username,
+ }, function (res) {
+ $btn.prop('disabled', false).html(' Code senden');
+ if (res.success) {
+ wbfDcMsg(' ' + (res.data.message || 'Code gesendet!'), '#16a34a');
+ $('#wbf-dc-step1').slideUp(200, function () { $('#wbf-dc-step2').slideDown(200); });
+ $('#wbf-discord-code-input').val('').focus();
+ wbfDcStep = 2;
+ } else {
+ wbfDcMsg(' ' + ((res.data && res.data.message) || 'Fehler.'), '#dc2626');
+ }
+ }).fail(function () {
+ $btn.prop('disabled', false).html(' Code senden');
+ wbfDcMsg(' Netzwerkfehler.', '#dc2626');
+ });
+ });
+
+ // Schritt 2 → Code bestätigen
+ $(document).on('click', '#wbf-discord-verify', function () {
+ var code = $('#wbf-discord-code-input').val().trim().toUpperCase();
+ if (code.length < 4) { wbfDcMsg(' Bitte Code eingeben.', '#f97316'); return; }
+ var $btn = $(this).prop('disabled', true).html(' Prüfe…');
+ $.post(WBF.ajax_url, {
+ action: 'wbf_discord_verify_code',
+ nonce: WBF.nonce,
+ verify_code: code,
+ }, function (res) {
+ $btn.prop('disabled', false).html(' Bestätigen');
+ if (res.success) {
+ wbfDcMsg(' ' + (res.data.message || 'Verbunden!'), '#16a34a');
+ wbfDcSetBadge(true);
+ // UI auf "Verbunden"-Ansicht umschalten
+ var name = res.data.display_name || '';
+ $('#wbf-discord-form').slideUp(200);
+ // Verbunden-Info einfügen/aktualisieren
+ var $info = $('.wbf-discord-connected-info');
+ if ($info.length) {
+ $info.find('.wbf-discord-linked-name').html(' ' + $('').text(name).html());
+ } else {
+ // Frisch laden damit die PHP-Struktur stimmt
+ setTimeout(function(){ location.reload(); }, 1200);
+ }
+ } else {
+ wbfDcMsg(' ' + ((res.data && res.data.message) || 'Fehler.'), '#dc2626');
+ }
+ }).fail(function () {
+ $btn.prop('disabled', false).html(' Bestätigen');
+ wbfDcMsg(' Netzwerkfehler.', '#dc2626');
+ });
+ });
+
+ // Enter-Taste auf Code-Feld
+ $(document).on('keydown', '#wbf-discord-code-input', function (e) {
+ if (e.key === 'Enter') { e.preventDefault(); $('#wbf-discord-verify').trigger('click'); }
+ });
+
+ // Enter-Taste auf Username-Feld
+ $(document).on('keydown', '#wbf-discord-input', function (e) {
+ if (e.key === 'Enter') { e.preventDefault(); $('#wbf-discord-send-code').trigger('click'); }
+ });
+
+ // „Zurück" in Schritt 2
+ $(document).on('click', '#wbf-discord-code-back', function () {
+ $('#wbf-dc-step2').slideUp(200, function () { $('#wbf-dc-step1').slideDown(200); });
+ wbfDcMsg('');
+ wbfDcStep = 1;
+ });
+
+ // „Neu verknüpfen" bei bereits verbundenem Account
+ $(document).on('click', '#wbf-discord-relink', function () {
+ $('#wbf-discord-form').slideDown(200);
+ $('#wbf-discord-input').val('').focus();
+ });
+
+ // Verbindung trennen
+ $(document).on('click', '#wbf-discord-disconnect', function () {
+ if (!confirm('Discord-Verbindung wirklich trennen?')) return;
+ var $btn = $(this).prop('disabled', true);
+ $.post(WBF.ajax_url, {
+ action: 'wbf_save_discord',
+ nonce: WBF.nonce,
+ sub_action: 'disconnect',
+ }, function (res) {
+ $btn.prop('disabled', false);
+ if (res.success) {
+ wbfDcMsg(' ' + (res.data.message || 'Getrennt.'), '#16a34a');
+ wbfDcSetBadge(false);
+ setTimeout(function () { location.reload(); }, 900);
+ } else {
+ wbfDcMsg(' ' + ((res.data && res.data.message) || 'Fehler.'), '#dc2626');
+ }
+ });
+ });
+
+}(jQuery));
+// Overwrite last line — Discord handlers appended via patch:
\ No newline at end of file