diff --git a/assets/css/forum-style.css b/assets/css/forum-style.css index a8f5e9f..5e1090a 100644 --- a/assets/css/forum-style.css +++ b/assets/css/forum-style.css @@ -1,3 +1,68 @@ +/* Shop Orders (Profil) */ +.wbf-shop-orders-list { + margin-top: 1.2rem; +} +.wbf-shop-orders-table { + width: 100%; + border-collapse: collapse; + background: var(--c-surface); + border-radius: var(--radius-sm); + overflow: hidden; + box-shadow: var(--shadow-sm); + font-size: .97em; +} +.wbf-shop-orders-table th, .wbf-shop-orders-table td { + padding: .65em 1em; + border-bottom: 1px solid var(--c-border); +} +.wbf-shop-orders-table th { + background: var(--c-surface2); + color: var(--c-text-dim); + font-weight: 600; + font-size: .93em; + text-transform: uppercase; + letter-spacing: .04em; +} +.wbf-shop-orders-table tr:last-child td { border-bottom: none; } +.wbf-shop-order-row { + cursor: pointer; + transition: background .15s; +} +.wbf-shop-order-row:hover { + background: var(--c-primary-l); +} +.wbf-shop-order-details-inner { + background: var(--c-bg2); + border-radius: var(--radius-sm); + padding: 1em 1.2em; + margin: .2em 0 .5em 0; + box-shadow: 0 2px 8px rgba(0,0,0,.08); + color: var(--c-text); + font-size: .98em; +} +.wbf-shop-order-cancelled td, .wbf-shop-order-cancelled .wbf-shop-order-details-inner { + color: var(--c-danger); + text-decoration: line-through; + opacity: .7; +} +.wbf-shop-order-details { + background: var(--c-surface2); + transition: display .2s; +} +.wbf-shop-order-toggle { + background: var(--c-surface2); + border: 1px solid var(--c-border); + color: var(--c-muted); + border-radius: 6px; + padding: 2px 10px; + font-size: 1em; + cursor: pointer; + transition: background .15s, color .15s; +} +.wbf-shop-order-toggle:hover { + background: var(--c-primary-l); + color: var(--c-primary); +} /* ═══════════════════════════════════════════════════════════ WP Business Forum — Minecraft Modern Dark Theme ═══════════════════════════════════════════════════════════ */ @@ -3994,4 +4059,230 @@ select.wbf-cf-input option { background: var(--c-surface2); color: var(--c-text) .wbf-prof__header-card-inner { padding: 1.1rem; } .wbf-prof__stat-cards { flex-direction: column; } .wbf-prof__badges { grid-template-columns: repeat(3,1fr); } +} +/* ═══════════════════════════════════════════════════════════════════════════ + 2FA — Zwei-Faktor-Authentifizierung + ═══════════════════════════════════════════════════════════════════════════ */ + +/* Badge im Profil-Card-Header */ +.wbf-2fa-badge { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: .72rem; + font-weight: 600; + padding: 2px 8px; + border-radius: 20px; + margin-left: auto; + letter-spacing: .02em; +} +.wbf-2fa-badge--on { + background: rgba(34,197,94,.15); + color: #16a34a; + border: 1px solid rgba(34,197,94,.3); +} +.wbf-2fa-badge--off { + background: rgba(156,163,175,.12); + color: var(--c-muted); + border: 1px solid rgba(156,163,175,.2); +} + +/* QR-Code Container */ +/* QR-Code — QRCode.js erzeugt img UND canvas; img ausblenden, nur canvas zeigen */ +#wbf2faQr { + display: inline-block; + padding: 12px; + background: #fff; + border-radius: 8px; + line-height: 0; + box-shadow: 0 1px 6px rgba(0,0,0,.15); + align-self: flex-start; + flex-shrink: 0; +} +/* Das leere Duplikat-img von QRCode.js komplett verstecken */ +#wbf2faQr img { + display: none !important; +} +/* Nur das canvas anzeigen — exakte quadratische Größe erzwingen */ +#wbf2faQr canvas { + display: block !important; + width: 200px !important; + height: 200px !important; +} + +/* Secret-Code (manuelle Eingabe) */ +#wbf2faSecret { + display: inline-block; + font-family: 'Courier New', monospace; + font-size: .9rem; + letter-spacing: .12em; + background: var(--c-bg-2, rgba(255,255,255,.05)); + border: 1px solid rgba(255,255,255,.1); + padding: 5px 12px; + border-radius: 6px; + user-select: all; + cursor: text; + word-break: break-all; +} + +/* 2FA-Login-Step (im Auth-Modal) */ +.wbf-2fa-login-step { + animation: wbfFadeIn .2s ease; +} +.wbf-2fa-login-step input { + width: 100%; + box-sizing: border-box; + font-family: monospace; + text-align: center; + font-size: 1.4rem; + letter-spacing: .3em; + padding: 10px 14px; + border: 1px solid rgba(234,179,8,.4); + border-radius: 7px; + background: var(--c-bg, #1e2535); + color: var(--c-text, #e2e8f0); + transition: border-color .15s; +} +.wbf-2fa-login-step input:focus { + outline: none; + border-color: #eab308; + box-shadow: 0 0 0 2px rgba(234,179,8,.2); +} + +/* Verify-Code-Input im Profil */ +#wbf2faVerifyCode { + font-family: monospace; + letter-spacing: .25em; + font-size: 1.3rem; + text-align: center; + transition: border-color .15s; +} +#wbf2faVerifyCode:focus { + border-color: var(--c-primary) !important; + box-shadow: 0 0 0 2px rgba(var(--c-primary-rgb, 99,102,241), .2); +} + +/* Schritt-3-Erfolgs-Animation */ +#wbf2faStep3 { + animation: wbfFadeIn .3s ease; +} + +@keyframes wbfFadeIn { + from { opacity: 0; transform: translateY(6px); } + to { opacity: 1; transform: translateY(0); } +} + +/* ── 2FA Login Modal ─────────────────────────────────────────────────────── */ +.wbf-2fa-modal-overlay { + position: fixed; + inset: 0; + z-index: 99999; + display: flex; + align-items: center; + justify-content: center; + background: rgba(0, 0, 0, 0); + backdrop-filter: blur(0px); + transition: background .25s ease, backdrop-filter .25s ease; + padding: 16px; +} +.wbf-2fa-modal-overlay.wbf-2fa-modal--visible { + background: rgba(0, 0, 0, .65); + backdrop-filter: blur(4px); +} +.wbf-2fa-modal-box { + background: var(--c-bg-2, #1e2535); + border: 1px solid rgba(234,179,8,.35); + border-radius: 14px; + padding: 28px 28px 24px; + width: 100%; + max-width: 380px; + box-shadow: 0 24px 60px rgba(0,0,0,.5), 0 0 0 1px rgba(234,179,8,.1); + transform: translateY(20px) scale(.97); + opacity: 0; + transition: transform .25s cubic-bezier(.34,1.3,.64,1), opacity .2s ease; +} +.wbf-2fa-modal--visible .wbf-2fa-modal-box { + transform: translateY(0) scale(1); + opacity: 1; +} + +/* Modal Header */ +.wbf-2fa-modal-header { + display: flex; + align-items: flex-start; + gap: 12px; + margin-bottom: 20px; +} +.wbf-2fa-modal-icon { + font-size: 1.8rem; + line-height: 1; + flex-shrink: 0; +} +.wbf-2fa-modal-title { + display: block; + font-size: 1rem; + font-weight: 700; + color: var(--c-text, #e2e8f0); + margin-bottom: 3px; +} +.wbf-2fa-modal-sub { + margin: 0; + font-size: .82rem; + color: var(--c-muted, #94a3b8); + line-height: 1.4; +} + +/* Code-Eingabe im Modal */ +.wbf-2fa-modal-box .wbf-2fa-code-input { + display: block; + width: 100%; + box-sizing: border-box; + padding: 12px 16px; + font-size: 1.6rem; + letter-spacing: .35em; + text-align: center; + font-family: 'Courier New', monospace; + font-weight: 600; + background: var(--c-bg, #141928); + color: var(--c-text, #e2e8f0); + border: 2px solid rgba(234,179,8,.3); + border-radius: 10px; + outline: none; + transition: border-color .15s, box-shadow .15s; + margin-bottom: 16px; +} +.wbf-2fa-modal-box .wbf-2fa-code-input:focus { + border-color: #eab308; + box-shadow: 0 0 0 3px rgba(234,179,8,.2); +} +.wbf-2fa-modal-box .wbf-2fa-code-input::placeholder { + color: rgba(148,163,184,.35); + letter-spacing: .25em; +} + +/* Buttons im Modal */ +.wbf-2fa-modal-actions { + display: flex; + gap: 10px; +} +.wbf-2fa-modal-actions .wbf-btn--primary { + flex: 1; +} +.wbf-2fa-modal-actions .wbf-2fa-cancel-btn { + font-size: .83rem; + padding: 7px 14px; + opacity: .65; + transition: opacity .15s; +} +.wbf-2fa-modal-actions .wbf-2fa-cancel-btn:hover { + opacity: 1; +} + +/* Fehlermeldung */ +.wbf-2fa-modal-box .wbf-2fa-msg { + display: block; + min-height: 1.2em; + margin-top: 10px; + font-size: .82rem; + text-align: center; } \ No newline at end of file diff --git a/assets/js/forum-script.js b/assets/js/forum-script.js index f9ebd0a..a43b597 100644 --- a/assets/js/forum-script.js +++ b/assets/js/forum-script.js @@ -536,6 +536,13 @@ wbfPost('wbf_update_profile', data, function (d) { showMsg($msg, d.message, true); $btn.prop('disabled', false); + // Bio und Signatur sofort aktualisieren (ohne Reload) + if (typeof data.bio !== 'undefined') { + $('.wbf-profile-sidebar__bio-text').text(data.bio); + } + if (typeof data.signature !== 'undefined') { + $('.wbf-profile-sidebar__sig').text(data.signature); + } }, function (d) { showMsg($msg, d.message || 'Fehler', false); $btn.prop('disabled', false); @@ -1394,12 +1401,16 @@ '' ].join('')).appendTo('body'); + var wbfLogoutFired = false; // Guard gegen doppelten Logout-Call + function wbfDoLogout() { + if (wbfLogoutFired) return; // doppelten Aufruf verhindern + wbfLogoutFired = true; clearTimeout(wbfIdleTimer); clearTimeout(wbfWarnTimer); clearInterval(wbfCountTimer); $wbfToast.hide(); - wbfPost('wbf_logout', {}, function () { + wbfPost('wbf_logout', { nonce: WBF.nonce }, function () { location.reload(); }); } @@ -1409,23 +1420,23 @@ var secs = 30; $('#wbfIdleCountdown').text(secs); $wbfToast.fadeIn(200); + // Countdown-Interval läuft bis 0 und ruft dann wbfDoLogout() auf — + // kein zusätzlicher setTimeout(wbfDoLogout) nötig (war die Ursache des Doppel-Logouts) wbfCountTimer = setInterval(function () { secs--; - $('#wbfIdleCountdown').text(secs); + $('#wbfIdleCountdown').text(Math.max(0, secs)); if (secs <= 0) { clearInterval(wbfCountTimer); wbfDoLogout(); } }, 1000); - // Auto-logout after warning period - wbfIdleTimer = setTimeout(wbfDoLogout, wbfWarnMs); } function wbfResetIdleTimer() { if (wbfWarning) return; // Nutzer hat aktiv Warnung bestätigt — nicht resetten clearTimeout(wbfIdleTimer); clearTimeout(wbfWarnTimer); - // Warn 30 sec before timeout + // Warnung 30 Sek. vor Ablauf zeigen wbfWarnTimer = setTimeout(wbfShowWarning, wbfIdleMs - wbfWarnMs); } @@ -1435,6 +1446,7 @@ clearInterval(wbfCountTimer); $wbfToast.fadeOut(200); wbfWarning = false; + wbfLogoutFired = false; // Guard zurücksetzen wbfResetIdleTimer(); });