Update from Git Manager GUI

This commit is contained in:
2026-03-29 22:25:43 +02:00
parent 689fd0c77b
commit 8c2955a2cf
2 changed files with 464 additions and 7 deletions

View File

@@ -416,14 +416,57 @@ a.wbf-btn--primary:hover {
align-items: center; align-items: center;
text-align: 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 { .wbf-profile-sidebar__avatar-wrap {
position: relative; position: relative;
padding: 2rem 0 1.25rem; padding: 0 0 1.25rem;
margin-top: -45px;
width: 100%; width: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
background: linear-gradient(160deg, #0d1117, #161d2e); z-index: 2;
border-bottom: 1px solid rgba(0,180,216,.12);
} }
.wbf-profile-sidebar__avatar { .wbf-profile-sidebar__avatar {
width: 100px; height: 100px; width: 100px; height: 100px;
@@ -557,6 +600,235 @@ a.wbf-btn--primary:hover {
padding-top: 1rem; padding-top: 1rem;
border-top: 1px solid var(--c-border); 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 { .wbf-profile-edit-grid {
display: grid; display: grid;
grid-template-columns: 1fr 1fr; 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; text-align: left;
} }
.wbf-profile-sidebar__avatar-wrap { .wbf-profile-sidebar__avatar-wrap {
padding: 1.25rem; padding: 0 0 1rem;
margin-top: -45px;
width: auto; width: auto;
border-bottom: none; border-bottom: none;
border-right: 1px solid var(--c-border); border-right: none;
}
.wbf-profile-banner {
height: 100px;
width: 100%;
} }
.wbf-profile-sidebar__identity { .wbf-profile-sidebar__identity {
align-items: flex-start; align-items: flex-start;

View File

@@ -3,6 +3,10 @@
/* ── Utilities ──────────────────────────────────────────────── */ /* ── Utilities ──────────────────────────────────────────────── */
function wbfPost(action, data, cb, errCb) { 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.action = action;
data.nonce = WBF.nonce; data.nonce = WBF.nonce;
$.post(WBF.ajax_url, data, function (res) { $.post(WBF.ajax_url, data, function (res) {
@@ -52,12 +56,18 @@
/* ── Registrieren ───────────────────────────────────────────── */ /* ── Registrieren ───────────────────────────────────────────── */
$(document).on('click', '.wbf-reg-submit-btn', function () { $(document).on('click', '.wbf-reg-submit-btn', function () {
var $btn = $(this).prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i>'); var $btn = $(this).prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i>');
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', { wbfPost('wbf_register', {
username: $(this).closest('.wbf-auth-box').find('.wbf-field-reg-user').val(), 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(), 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(), email: $(this).closest('.wbf-auth-box').find('.wbf-field-reg-email').val(),
password: $(this).closest('.wbf-auth-box').find('.wbf-field-reg-pass').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' : '' rules_accepted: $(this).closest('.wbf-auth-box').find('.wbf-field-rules-accept').is(':checked') ? '1' : ''
}, function () { }, function () {
location.reload(); 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('<img src="' + objectUrl + '" alt="" id="wbfProfileBanner" class="wbf-profile-banner__img" style="opacity:.4">');
} 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 FEATURE: Ungelesene Beiträge
══════════════════════════════════════════════════════════ */ ══════════════════════════════════════════════════════════ */
@@ -2163,4 +2215,132 @@
$bar.hide(); $bar.hide();
}); });
// ── 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('<i class="fas fa-check-circle"></i> Verbunden');
} else {
$badge.removeClass('wbf-connection-badge--connected')
.addClass('wbf-connection-badge--disconnected')
.html('<i class="fas fa-circle-xmark"></i> Nicht verbunden');
}
}
// Schritt 1 → Code senden
$(document).on('click', '#wbf-discord-send-code', function () {
var username = $('#wbf-discord-input').val().trim();
if (!username) { wbfDcMsg('<i class="fas fa-triangle-exclamation"></i> Bitte Benutzername eingeben.', '#f97316'); return; }
var $btn = $(this).prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Sende…');
wbfDcMsg('');
$.post(WBF.ajax_url, {
action: 'wbf_discord_send_code',
nonce: WBF.nonce,
discord_username: username,
}, function (res) {
$btn.prop('disabled', false).html('<i class="fab fa-discord"></i> Code senden');
if (res.success) {
wbfDcMsg('<i class="fas fa-check" style="color:#16a34a"></i> ' + (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('<i class="fas fa-circle-xmark"></i> ' + ((res.data && res.data.message) || 'Fehler.'), '#dc2626');
}
}).fail(function () {
$btn.prop('disabled', false).html('<i class="fab fa-discord"></i> Code senden');
wbfDcMsg('<i class="fas fa-circle-xmark"></i> 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('<i class="fas fa-triangle-exclamation"></i> Bitte Code eingeben.', '#f97316'); return; }
var $btn = $(this).prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Prüfe…');
$.post(WBF.ajax_url, {
action: 'wbf_discord_verify_code',
nonce: WBF.nonce,
verify_code: code,
}, function (res) {
$btn.prop('disabled', false).html('<i class="fas fa-check"></i> Bestätigen');
if (res.success) {
wbfDcMsg('<i class="fas fa-check-circle"></i> ' + (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('<i class="fab fa-discord" style="color:#5865f2"></i> ' + $('<span>').text(name).html());
} else {
// Frisch laden damit die PHP-Struktur stimmt
setTimeout(function(){ location.reload(); }, 1200);
}
} else {
wbfDcMsg('<i class="fas fa-circle-xmark"></i> ' + ((res.data && res.data.message) || 'Fehler.'), '#dc2626');
}
}).fail(function () {
$btn.prop('disabled', false).html('<i class="fas fa-check"></i> Bestätigen');
wbfDcMsg('<i class="fas fa-circle-xmark"></i> 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('<i class="fas fa-check"></i> ' + (res.data.message || 'Getrennt.'), '#16a34a');
wbfDcSetBadge(false);
setTimeout(function () { location.reload(); }, 900);
} else {
wbfDcMsg('<i class="fas fa-circle-xmark"></i> ' + ((res.data && res.data.message) || 'Fehler.'), '#dc2626');
}
});
});
}(jQuery)); }(jQuery));
// Overwrite last line — Discord handlers appended via patch: