diff --git a/assets/css/forum-style.css b/assets/css/forum-style.css index 0afb406..93328bf 100644 --- a/assets/css/forum-style.css +++ b/assets/css/forum-style.css @@ -3115,4 +3115,606 @@ select.wbf-cf-input option { background: var(--c-surface2); color: var(--c-text) .wbf-profile-lastseen i { font-size: .68rem; opacity: .7; +} +/* ════════════════════════════════════════════════════════════════════ + PROFIL v3 — Sidebar-Links Layout (wbf-prof) + ════════════════════════════════════════════════════════════════════ */ + +.wbf-prof { + display: grid; + grid-template-columns: 260px 1fr; + gap: 1.5rem; + align-items: start; + margin-bottom: 2rem; +} + +/* ── SIDEBAR ─────────────────────────────────────────────────────── */ +.wbf-prof__sidebar { + background: var(--c-surface); + border: 1px solid var(--c-border); + border-radius: var(--radius); + padding: 1.75rem 1.25rem 1.5rem; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + gap: .75rem; + position: sticky; + top: 80px; +} + +/* Avatar */ +.wbf-prof__av-wrap { + position: relative; + width: 110px; + height: 110px; + margin-bottom: .25rem; +} +.wbf-prof__av-ring { + position: absolute; + inset: -4px; + border-radius: 50%; + background: conic-gradient(from 0deg, var(--c-primary), #6366f1, var(--c-primary)); + opacity: .6; + animation: wbf-spin 8s linear infinite; +} +@keyframes wbf-spin { to { transform: rotate(360deg); } } +.wbf-prof__av { + position: relative; + width: 110px; + height: 110px; + border-radius: 50%; + border: 3px solid var(--c-surface); + object-fit: cover; + display: block; + background: var(--c-bg2); + box-shadow: 0 0 28px rgba(0,180,216,.25); +} +.wbf-prof__av-online { + position: absolute; + bottom: 5px; right: 5px; + width: 16px; height: 16px; + border-radius: 50%; + background: #22c55e; + border: 3px solid var(--c-surface); + box-shadow: 0 0 8px rgba(34,197,94,.7); +} +.wbf-prof__av-camera { + position: absolute; + inset: 0; + border-radius: 50%; + background: rgba(0,0,0,.6); + display: flex; + align-items: center; + justify-content: center; + color: #fff; + font-size: 1.1rem; + cursor: pointer; + opacity: 0; + transition: opacity .18s; +} +.wbf-prof__av-wrap:hover .wbf-prof__av-camera { opacity: 1; } + +/* Identity */ +.wbf-prof__sb-name { + font-size: 1.1rem; + font-weight: 800; + color: var(--c-text); + letter-spacing: -.01em; +} +.wbf-prof__sb-role { margin-top: -.15rem; } +.wbf-prof__sb-status { + font-size: .75rem; + color: var(--c-muted); + display: flex; + align-items: center; + gap: .35rem; + justify-content: center; +} +.wbf-prof__sb-status--online { color: #22c55e; font-weight: 600; } +.wbf-prof__dot { + width: 7px; height: 7px; + border-radius: 50%; + background: #22c55e; + box-shadow: 0 0 6px rgba(34,197,94,.8); + animation: wbf-pulse 2s infinite; +} + +/* Stats grid */ +.wbf-prof__sb-stats { + display: grid; + grid-template-columns: repeat(3,1fr); + gap: .5rem; + width: 100%; + margin: .25rem 0; + border-top: 1px solid var(--c-border); + border-bottom: 1px solid var(--c-border); + padding: .9rem 0; +} +.wbf-prof__sb-stat { + display: flex; + flex-direction: column; + align-items: center; + gap: .2rem; +} +.wbf-prof__sb-stat span { + font-size: 1.15rem; + font-weight: 700; + color: var(--c-text); + line-height: 1; +} +.wbf-prof__sb-stat em { + font-style: normal; + font-size: .65rem; + color: var(--c-muted); + text-transform: uppercase; + letter-spacing: .06em; +} + +/* Level progress */ +.wbf-prof__sb-level { + width: 100%; + display: flex; + flex-direction: column; + gap: .35rem; +} +.wbf-prof__sb-level-labels { + display: flex; + justify-content: space-between; + font-size: .75rem; + font-weight: 600; +} +.wbf-prof__sb-level-xp { + color: var(--c-muted); + font-weight: 400; +} +.wbf-prof__sb-level-bar { + height: 6px; + background: rgba(255,255,255,.07); + border-radius: 6px; + overflow: hidden; +} +.wbf-prof__sb-level-bar > div { + height: 100%; + border-radius: 6px; + transition: width .6s ease; +} +.wbf-prof__sb-level-next { + font-size: .72rem; + color: var(--c-muted); + text-align: center; +} + +/* Meta */ +.wbf-prof__sb-meta { + display: flex; + align-items: center; + gap: .45rem; + font-size: .78rem; + color: var(--c-muted); +} +.wbf-prof__sb-meta i { color: var(--c-primary); } + +/* Sidebar custom field blocks */ +.wbf-prof__sb-block { + width: 100%; + border-top: 1px solid var(--c-border); + padding-top: .85rem; + display: flex; + flex-direction: column; + gap: .5rem; + text-align: left; +} +.wbf-prof__sb-block-title { + font-size: .65rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: .09em; + color: var(--c-primary); + margin-bottom: .15rem; +} +.wbf-prof__sb-field { display: flex; flex-direction: column; gap: .1rem; } +.wbf-prof__sb-field-lbl { + font-size: .72rem; + color: var(--c-muted); + font-weight: 600; +} +.wbf-prof__sb-field-lbl i { margin-right: .25rem; } +.wbf-prof__sb-field-val { + font-size: .82rem; + color: var(--c-text-dim); + word-break: break-all; +} +.wbf-prof__sb-field-val--link { + color: var(--c-primary); + text-decoration: none; +} +.wbf-prof__sb-field-val--link:hover { text-decoration: underline; } + +/* ── MAIN ────────────────────────────────────────────────────────── */ +.wbf-prof__main { + display: flex; + flex-direction: column; + gap: 0; + min-width: 0; +} + +/* Header card */ +.wbf-prof__header-card { + position: relative; + border-radius: var(--radius) var(--radius) 0 0; + overflow: hidden; + border: 1px solid var(--c-border); + border-bottom: none; +} +.wbf-prof__header-card-bg { + position: absolute; inset: 0; + background: linear-gradient(135deg, #0a1628 0%, #0d1f3c 50%, #061218 100%); +} +.wbf-prof__header-card-bg::after { + content: ''; + position: absolute; inset: 0; + background: radial-gradient(ellipse 70% 120% at 85% 50%, rgba(0,180,216,.2) 0%, transparent 65%); +} +.wbf-prof__header-card-inner { + position: relative; + display: flex; + align-items: center; + justify-content: space-between; + gap: 1rem; + padding: 1.5rem 1.75rem; + flex-wrap: wrap; +} +.wbf-prof__header-name { + font-size: 1.5rem; + font-weight: 800; + color: #fff; + margin: 0 0 .35rem; + letter-spacing: -.02em; +} +.wbf-prof__header-sub { + display: flex; + align-items: center; + gap: .6rem; + margin-bottom: .5rem; + flex-wrap: wrap; +} +.wbf-prof__header-online { + display: inline-flex; + align-items: center; + gap: .35rem; + font-size: .72rem; + font-weight: 700; + color: #22c55e; + background: rgba(34,197,94,.12); + border: 1px solid rgba(34,197,94,.25); + border-radius: 20px; + padding: .15rem .65rem; +} +.wbf-prof__header-online span { + width: 6px; height: 6px; + border-radius: 50%; + background: #22c55e; + box-shadow: 0 0 5px rgba(34,197,94,.8); + animation: wbf-pulse 2s infinite; +} +.wbf-prof__header-bio { + font-size: .85rem; + color: rgba(255,255,255,.6); + margin: 0; + max-width: 420px; +} +.wbf-prof__header-btns { + display: flex; + gap: .6rem; + flex-wrap: wrap; + flex-shrink: 0; +} + +/* Tabs */ +.wbf-prof__tabs { + display: flex; + background: var(--c-surface); + border: 1px solid var(--c-border); + border-top: none; + padding: 0 .75rem; + overflow-x: auto; + scrollbar-width: none; +} +.wbf-prof__tabs::-webkit-scrollbar { display: none; } +.wbf-prof__tab { + display: inline-flex; + align-items: center; + gap: .4rem; + padding: .85rem 1rem; + font-size: .82rem; + font-weight: 600; + color: var(--c-muted); + text-decoration: none; + border-bottom: 2px solid transparent; + margin-bottom: -1px; + white-space: nowrap; + transition: color .15s, border-color .15s; +} +.wbf-prof__tab:hover { color: var(--c-text); } +.wbf-prof__tab.active { color: var(--c-primary); border-bottom-color: var(--c-primary); } +.wbf-prof__tab i { font-size: .8rem; } + +/* Tab body */ +.wbf-prof__tab-body { + background: var(--c-bg); + border: 1px solid var(--c-border); + border-top: none; + border-radius: 0 0 var(--radius) var(--radius); + padding: 1.5rem; + display: flex; + flex-direction: column; + gap: 1.5rem; +} + +/* Section headers */ +.wbf-prof__section-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: .75rem; +} +.wbf-prof__section-header > span { + font-size: .82rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: .07em; + color: var(--c-text-dim); + display: flex; + align-items: center; + gap: .45rem; +} +.wbf-prof__section-header > span i { color: var(--c-primary); } +.wbf-prof__section-more { + font-size: .75rem; + color: var(--c-primary); + text-decoration: none; + display: flex; + align-items: center; + gap: .3rem; + opacity: .8; + transition: opacity .15s; +} +.wbf-prof__section-more:hover { opacity: 1; } + +/* Post cards */ +.wbf-prof__posts { + display: flex; + flex-direction: column; + gap: .6rem; +} +.wbf-prof__post-card { + display: block; + background: var(--c-surface); + border: 1px solid var(--c-border); + border-radius: var(--radius-sm); + text-decoration: none; + transition: border-color .15s, transform .12s; + overflow: hidden; +} +.wbf-prof__post-card:hover { + border-color: rgba(0,180,216,.4); + transform: translateX(3px); +} +.wbf-prof__post-card-inner { + display: flex; + align-items: flex-start; + gap: .9rem; + padding: .9rem 1.1rem; +} +.wbf-prof__post-card-icon { flex-shrink: 0; } +.wbf-prof__post-card-type-icon { + width: 36px; height: 36px; + border-radius: 8px; + display: flex; align-items: center; justify-content: center; + font-size: .85rem; +} +.wbf-prof__post-card-type-icon--thread { background: rgba(0,180,216,.15); color: var(--c-primary); } +.wbf-prof__post-card-type-icon--reply { background: rgba(99,102,241,.15); color: #818cf8; } +.wbf-prof__post-card-body { flex: 1; min-width: 0; } +.wbf-prof__post-card-title { + font-size: .88rem; + font-weight: 600; + color: var(--c-text); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin-bottom: .2rem; +} +.wbf-prof__post-card-preview { + font-size: .78rem; + color: var(--c-muted); + line-height: 1.4; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; + margin-bottom: .35rem; +} +.wbf-prof__post-card-meta { + display: flex; + gap: .75rem; + font-size: .72rem; + color: var(--c-muted); + flex-wrap: wrap; + align-items: center; +} +.wbf-prof__post-card-meta i { margin-right: .2rem; } +.wbf-prof__post-card-type { font-weight: 600; } +.wbf-prof__post-card-type--thread { color: var(--c-primary); } +.wbf-prof__post-card-type--reply { color: #818cf8; } +.wbf-prof__post-card-time { + font-size: .72rem; + color: var(--c-muted); + white-space: nowrap; + flex-shrink: 0; + display: flex; + align-items: center; + gap: .4rem; + margin-top: .2rem; +} + +/* Overview 2-col grid */ +.wbf-prof__overview-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1.5rem; + align-items: start; +} + +/* Stat cards */ +.wbf-prof__stat-cards { + display: flex; + flex-direction: column; + gap: .65rem; +} +.wbf-prof__stat-card { + background: var(--c-surface); + border: 1px solid var(--c-border); + border-radius: var(--radius-sm); + padding: .9rem 1rem; + position: relative; + overflow: hidden; +} +.wbf-prof__stat-card::before { + content: ''; + position: absolute; + left: 0; top: 0; bottom: 0; + width: 3px; +} +.wbf-prof__stat-card--blue::before { background: var(--c-primary); } +.wbf-prof__stat-card--pink::before { background: #ec4899; } +.wbf-prof__stat-card--gold::before { background: #fbbf24; } +.wbf-prof__stat-card-icon { + font-size: 1rem; + margin-bottom: .3rem; +} +.wbf-prof__stat-card--blue .wbf-prof__stat-card-icon { color: var(--c-primary); } +.wbf-prof__stat-card--pink .wbf-prof__stat-card-icon { color: #ec4899; } +.wbf-prof__stat-card--gold .wbf-prof__stat-card-icon { color: #fbbf24; } +.wbf-prof__stat-card-val { + font-size: 1.4rem; + font-weight: 800; + color: var(--c-text); + line-height: 1.1; +} +.wbf-prof__stat-card-lbl { + font-size: .72rem; + color: var(--c-muted); + margin-top: .15rem; +} +.wbf-prof__stat-card-sub { + font-size: .7rem; + color: var(--c-muted); + margin-top: .3rem; +} +.wbf-prof__stat-card-bar { + height: 3px; + background: rgba(255,255,255,.07); + border-radius: 3px; + margin-top: .6rem; + overflow: hidden; +} +.wbf-prof__stat-card--blue .wbf-prof__stat-card-bar > div { background: var(--c-primary); height: 100%; border-radius: 3px; } +.wbf-prof__stat-card--pink .wbf-prof__stat-card-bar > div { background: #ec4899; height: 100%; border-radius: 3px; } + +/* Badges */ +.wbf-prof__badges { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(90px, 1fr)); + gap: .65rem; +} +.wbf-prof__badge { + background: var(--c-surface); + border: 1px solid var(--c-border); + border-radius: var(--radius-sm); + padding: .75rem .5rem; + text-align: center; + opacity: .45; + transition: opacity .15s; +} +.wbf-prof__badge--active { opacity: 1; } +.wbf-prof__badge-icon { + width: 40px; height: 40px; + border-radius: 50%; + display: flex; align-items: center; justify-content: center; + font-size: 1rem; + margin: 0 auto .5rem; +} +.wbf-prof__badge-name { + font-size: .72rem; + font-weight: 700; + color: var(--c-text); +} +.wbf-prof__badge-sub { + font-size: .62rem; + color: var(--c-muted); + margin-top: .1rem; +} + +/* Activity list */ +.wbf-prof__activity-list { + display: flex; + flex-direction: column; + gap: 0; +} +.wbf-prof__activity-item { + display: flex; + gap: .75rem; + align-items: flex-start; + padding: .75rem 0; + border-bottom: 1px solid rgba(255,255,255,.04); +} +.wbf-prof__activity-item:last-child { border-bottom: none; } +.wbf-prof__activity-av { flex-shrink: 0; } +.wbf-prof__activity-body { flex: 1; min-width: 0; } +.wbf-prof__activity-title { + display: block; + font-size: .82rem; + font-weight: 600; + color: var(--c-text); + text-decoration: none; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin-bottom: .2rem; +} +.wbf-prof__activity-title:hover { color: var(--c-primary); } +.wbf-prof__activity-meta { + font-size: .7rem; + color: var(--c-muted); +} +.wbf-prof__activity-meta i { margin-right: .2rem; } +.wbf-prof__activity-time { + font-size: .7rem; + color: var(--c-muted); + white-space: nowrap; + flex-shrink: 0; +} + +/* Settings grid */ +.wbf-prof__settings-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1.25rem; + align-items: start; +} + +/* Mobile */ +@media (max-width: 900px) { + .wbf-prof { grid-template-columns: 1fr; } + .wbf-prof__sidebar { position: static; } + .wbf-prof__overview-grid, + .wbf-prof__settings-grid { grid-template-columns: 1fr; } +} +@media (max-width: 600px) { + .wbf-prof__tab-body { padding: 1rem; } + .wbf-prof__header-card-inner { padding: 1.1rem; } + .wbf-prof__stat-cards { flex-direction: column; } + .wbf-prof__badges { grid-template-columns: repeat(3,1fr); } } \ No newline at end of file diff --git a/assets/js/forum-script.js b/assets/js/forum-script.js index 64e6cac..da4fdb0 100644 --- a/assets/js/forum-script.js +++ b/assets/js/forum-script.js @@ -510,17 +510,16 @@ }); }); - /* ── Profil speichern ───────────────────────────────────────── */ - $(document).on('click', '#wbfSaveProfile, #wbfSaveProfileCf', function () { + /* ── Profil speichern (alles auf einmal) ───────────────────── */ + $(document).on('click', '#wbfSaveProfile', function () { var $btn = $(this).prop('disabled', true); - var $msg = $(this).siblings('.wbf-msg').length ? $(this).siblings('.wbf-msg') : $('#wbfProfileMsg'); + var $msg = $('#wbfProfileMsg'); var data = { display_name: $('#wbfEditName').val(), bio: $('#wbfEditBio').val(), - signature: $('#wbfEditSignature').val(), - new_password: $('#wbfNewPassword').val() + signature: $('#wbfEditSignature').val() }; - // Benutzerdefinierte Profilfelder einsammeln + // Alle benutzerdefinierten Felder (alle Kategorien) einsammeln $('.wbf-cf-input').each(function () { data[$(this).data('field')] = $(this).val(); }); @@ -533,6 +532,40 @@ }); }); + /* ── Passwort ändern ────────────────────────────────────────── */ + $(document).on('click', '#wbfSavePassword', function () { + var $btn = $(this).prop('disabled', true); + var $msg = $('#wbfPasswordMsg'); + var cur = $('#wbfCurrentPassword').val(); + var pw1 = $('#wbfNewPassword').val(); + var pw2 = $('#wbfNewPassword2').val(); + + if (!cur) { + showMsg($msg, 'Bitte aktuelles Passwort eingeben.', false); + return $btn.prop('disabled', false); + } + if (pw1.length < 6) { + showMsg($msg, 'Neues Passwort mindestens 6 Zeichen.', false); + return $btn.prop('disabled', false); + } + if (pw1 !== pw2) { + showMsg($msg, 'Die Passwörter stimmen nicht überein.', false); + return $btn.prop('disabled', false); + } + + wbfPost('wbf_update_profile', { + current_password: cur, + new_password: pw1 + }, function (d) { + showMsg($msg, d.message, true); + $('#wbfCurrentPassword, #wbfNewPassword, #wbfNewPassword2').val(''); + $btn.prop('disabled', false); + }, function (d) { + showMsg($msg, d.message || 'Fehler', false); + $btn.prop('disabled', false); + }); + }); + /* ── Signatur Zeichenzähler ─────────────────────────────────── */ $(document).on('input', '#wbfEditSignature', function () { $('#wbfSigCount').text($(this).val().length); @@ -542,10 +575,16 @@ $(document).on('change', '#wbfAvatarFile', function () { var file = this.files[0]; if (!file) return; + + // Sofort-Vorschau — synchron, kein Callback, kein Warten + var objectUrl = URL.createObjectURL(file); + $('#wbfProfileAvatar').attr('src', objectUrl).css('opacity', '.6'); + var fd = new FormData(); fd.append('action', 'wbf_upload_avatar'); fd.append('nonce', WBF.nonce); fd.append('avatar', file); + $.ajax({ url: WBF.ajax_url, type: 'POST', @@ -553,9 +592,19 @@ processData: false, contentType: false, success: function (res) { + $('#wbfProfileAvatar').css('opacity', '1'); if (res.success) { - $('.wbf-profile-page__avatar').attr('src', res.data.avatar_url); + // Object-URL freigeben, endgültige Server-URL setzen + URL.revokeObjectURL(objectUrl); + var finalUrl = res.data.avatar_url + '?v=' + Date.now(); + $('#wbfProfileAvatar').attr('src', finalUrl); + // Topbar-Avatar ebenfalls aktualisieren + $('.wbf-topbar__user img').attr('src', finalUrl); + $('.wbf-profile-widget__avatar img').attr('src', finalUrl); } + }, + error: function () { + $('#wbfProfileAvatar').css('opacity', '1'); } }); }); @@ -1091,7 +1140,7 @@ var html = ''; d.notifications.forEach(function (n) { var isUnread = n.is_read == 0; - var avatar = n.actor_avatar || ''; + var avatar = $('').attr('src', n.actor_avatar || '').attr('alt', '').attr('class', 'wbf-dm-inbox-item__avatar')[0].outerHTML; var base = WBF.forum_url || window.location.href.split('?')[0]; var sep = base.indexOf('?') !== -1 ? '&' : '?'; var actor = '' + $('').text(n.actor_name).html() + ''; @@ -1118,7 +1167,7 @@ } html += '' + - '
' + + '
' + avatar + '
' + '
' + '
' + text + (sub ? '
' + $('').text(sub).html() + '' : '') + @@ -1218,7 +1267,7 @@ var delBtn = ''; var html = '
'; if (!isMine) { - html += ''; + html += $('').attr('src', m.sender_avatar || '').attr('class', 'wbf-dm-inbox-item__avatar')[0].outerHTML; } html += '
' + $('').text(m.content).html().replace(/\n/g,'
') @@ -1452,7 +1501,7 @@ var html = ''; d.users.forEach(function(u) { html += '
' - + '' + + $('').attr('src', u.avatar_url || '').attr('width', '22').attr('height', '22').css({'border-radius':'50%','flex-shrink':'0'})[0].outerHTML + '' + $('').text(u.display_name).html() + '' + '@' + $('').text(u.username).html() + '' + '
'; @@ -1500,7 +1549,7 @@ var delBtn = ''; if (!isMine) { html += '
' - + '' + + $('').attr('src', m.sender_avatar || '').attr('class', 'wbf-dm-msg__avatar')[0].outerHTML + '
' + $('').text(m.content).html().replace(/\n/g,'
') + '
' + time + delBtn + '
'; @@ -1524,7 +1573,7 @@ var href = window.location.pathname + '?forum_dm=inbox&with=' + conv.partner_id; var unread = parseInt(conv.unread_cnt) > 0; html += '
' - + '' + + $('').attr('src', conv.partner_avatar || '').attr('class', 'wbf-dm-inbox-item__avatar')[0].outerHTML + '
' + '' + $('').text(conv.partner_name).html() + '' + (unread ? '' + conv.unread_cnt + '' : '') @@ -1550,7 +1599,7 @@ var backUrl = window.location.pathname + '?forum_dm=inbox'; $('#wbfDmHeader').html( '' - + '' + + $('').attr('src', p.avatar_url || '').attr('class', 'wbf-dm-inbox-item__avatar')[0].outerHTML + '' + $('').text(p.display_name).html() + '' + '@' + $('').text(p.username).html() + '' ); @@ -1634,7 +1683,7 @@ var html = ''; d.users.forEach(function(u) { html += '
' - + '' + + $('').attr('src', u.avatar_url || '').attr('width', '22').attr('height', '22').css({'border-radius':'50%','flex-shrink':'0'})[0].outerHTML + $('').text(u.display_name).html() + '@' + $('').text(u.username).html() + '' + '
';