diff --git a/assets/css/routes/user-center/level.css b/assets/css/routes/user-center/level.css index ec8ee259..8effad9a 100644 --- a/assets/css/routes/user-center/level.css +++ b/assets/css/routes/user-center/level.css @@ -1,95 +1,383 @@ -/* User level — dedicated center panel. - * Base level icon sizing lives in assets/css/frontend/base.css (1.1em, inline). - * This file keeps only the UC-level-specific hero/road overrides + admin column. */ +/* User level panel — zibll-aligned single-path layout. */ .aksrt-user-level-icon--admin { height: 22px; } -.uc-level-page { display: grid; gap: 16px; } -.uc-level-page .aksrt-panel { - margin: 0; - padding: 18px; - border: 1px solid var(--color-line-soft, rgba(0,0,0,.06)); - border-radius: var(--main-radius, 10px); - background: var(--main-bg-color, var(--surface-1, #fff)); - box-shadow: 0 0 10px var(--main-shadow, rgba(116,116,116,.08)); +/* The level page owns its cards; do not wrap it in the generic dashboard card. */ +.uc-content #panel-level.dashboard-panel { + padding: 0; + border: 0; + border-radius: 0; + background: transparent; + box-shadow: none; } -.uc-level-hero { + +.aksrt-level-page { + color: var(--color-ink, #4e5358); +} + +.aksrt-level-page .row { + margin-right: -10px; + margin-left: -10px; +} + +.aksrt-level-page .row > [class*="col-"] { + padding-right: 10px; + padding-left: 10px; +} + +.aksrt-level-page__summary { + margin-bottom: 20px; +} + +.aksrt-level-card { position: relative; + min-height: 176px; + margin-bottom: 0; + padding: 15px; overflow: hidden; - background: linear-gradient(135deg, rgba(124,58,237,.12), rgba(236,72,153,.10)) !important; + border: 0; + border-radius: var(--main-radius, 8px); + box-shadow: 0 0 10px var(--main-shadow, rgba(116, 116, 116, .08)); } -.uc-level-hero::after { - content: ''; - position: absolute; - width: 220px; - height: 220px; - right: -80px; - top: -100px; - border-radius: 50%; - background: rgba(255,255,255,.2); + +.aksrt-level-card .colorful-make { pointer-events: none; } -.uc-level-hero__identity { display: flex; align-items: center; gap: 14px; position: relative; z-index: 1; } -.uc-level-hero__identity p { margin: 0 0 3px; color: var(--muted-2-color, #8b9198); font-size: 12px; } -.uc-level-hero__identity h2 { margin: 0; font-size: 22px; } -.uc-level-hero__icon { - display: grid; - place-items: center; - width: 62px; - height: 62px; - border-radius: 16px; - background: rgba(255,255,255,.62); - box-shadow: inset 0 0 0 1px rgba(255,255,255,.55); + +.aksrt-level-card__summary-inner, +.aksrt-level-card__growth-inner { + position: relative; + z-index: 1; + display: flex; + flex-direction: column; + justify-content: space-between; + min-height: 146px; } -.uc-level-hero__icon .aksrt-user-level-icon { max-width: 48px; height: 42px; } -.uc-level-hero__stats { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 10px; margin: 20px 0 16px; position: relative; z-index: 1; } -.uc-level-hero__stats > div { padding: 12px; border-radius: 10px; background: rgba(255,255,255,.46); } -.uc-level-hero__stats strong, .uc-level-hero__stats span { display: block; } -.uc-level-hero__stats strong { font-size: 18px; } -.uc-level-hero__stats span { margin-top: 3px; font-size: 11px; color: var(--muted-2-color, #747b83); } -.uc-level-hero__progress { position: relative; z-index: 1; } -.uc-level-hero__progress-meta { display: flex; justify-content: space-between; margin-bottom: 7px; font-size: 12px; font-weight: 700; } -.uc-level-progress { height: 9px; overflow: hidden; border-radius: 999px; background: rgba(127,127,127,.18); } -.uc-level-progress > span { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, #7c3aed, #ec4899); } -.uc-level-section__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; } -.uc-level-section__head h3 { margin: 0; font-size: 16px; } -.uc-level-section__head span { color: var(--muted-2-color, #8b9198); font-size: 11px; } -.uc-level-road { display: grid; grid-template-columns: repeat(auto-fit, minmax(92px, 1fr)); gap: 10px; } -.uc-level-road__item { position: relative; display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 14px 8px; border: 1px solid var(--color-line-soft, rgba(0,0,0,.06)); border-radius: 10px; opacity: .58; text-align: center; } -.uc-level-road__item.is-done { opacity: .78; } -.uc-level-road__item.is-current { opacity: 1; border-color: #8b5cf6; box-shadow: 0 0 0 2px rgba(139,92,246,.12); } -.uc-level-road__item.is-current::after { content: '当前'; position: absolute; top: 6px; right: 6px; padding: 1px 5px; border-radius: 999px; background: #8b5cf6; color: #fff; font-size: 9px; } -.uc-level-road__icon { display: grid; place-items: center; height: 40px; } -.uc-level-road__icon img { max-width: 52px; max-height: 38px; object-fit: contain; } -.uc-level-road__icon span { font-weight: 800; color: #7c3aed; } -.uc-level-road__item strong { font-size: 12px; } -.uc-level-road__item small { color: var(--muted-2-color, #8b9198); font-size: 10px; } +.aksrt-level-card--summary { + --this-color: #866127; + --this-bg: linear-gradient(25deg, #eabe7b 10%, #f5e3c7 70%, #edc788 100%); + color: var(--this-color); +} -.uc-level-methods { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 10px; } -.uc-level-methods__item { display: grid; grid-template-columns: 34px 1fr auto; align-items: center; gap: 10px; padding: 11px; border: 1px solid var(--color-line-soft, rgba(0,0,0,.06)); border-radius: 9px; } -.uc-level-methods__item > span { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 9px; background: rgba(245,158,11,.12); color: #d97706; } -.uc-level-methods__item strong, .uc-level-methods__item small { display: block; } -.uc-level-methods__item strong { font-size: 12px; } -.uc-level-methods__item small { margin-top: 2px; color: var(--muted-2-color, #8b9198); font-size: 10px; } -.uc-level-methods__item b { color: #7c3aed; } -.uc-level-ledger__row time + small { display: block; margin-top: 2px; color: var(--muted-2-color, #8b9198); font-size: 10px; } +.aksrt-level-card--growth { + --this-color: #888; + --this-bg: rgba(136, 136, 136, .1); + color: var(--this-color); +} -.uc-level-history-grid { display: grid; grid-template-columns: minmax(0,1.35fr) minmax(240px,.65fr); gap: 16px; } -.uc-level-ledger, .uc-level-dates { display: grid; } -.uc-level-ledger__row { display: grid; grid-template-columns: 36px 1fr auto; align-items: center; gap: 10px; padding: 11px 0; border-bottom: 1px solid var(--color-line-soft, rgba(0,0,0,.05)); } -.uc-level-ledger__row:last-child, .uc-level-dates > div:last-child { border-bottom: 0; } -.uc-level-ledger__icon { display: grid; place-items: center; width: 34px; height: 34px; border-radius: 9px; background: rgba(124,58,237,.10); color: #7c3aed; } -.uc-level-ledger__row strong, .uc-level-ledger__row time { display: block; } -.uc-level-ledger__row strong { font-size: 13px; } -.uc-level-ledger__row time { margin-top: 2px; color: var(--muted-2-color, #8b9198); font-size: 10px; } -.uc-level-ledger__row b { color: #16a34a; font-size: 13px; } -.uc-level-dates > div { display: flex; justify-content: space-between; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--color-line-soft, rgba(0,0,0,.05)); font-size: 12px; } -.uc-level-dates span { color: #16a34a; font-weight: 700; } -.uc-level-empty { margin: 0; padding: 24px 0; color: var(--muted-2-color, #8b9198); text-align: center; } +.aksrt-level-card__identity, +.aksrt-level-card__current, +.aksrt-level-card__growth-head { + display: flex; + align-items: center; +} + +.aksrt-level-card__identity { + gap: 6px; + font-weight: 700; +} + +.aksrt-level-card__avatar { + display: inline-flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + margin-top: -4px; + overflow: hidden; + border-radius: 50%; + background: rgba(255, 255, 255, .45); +} + +.aksrt-level-card__avatar img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; +} + +.aksrt-level-card__current { + justify-content: flex-end; + gap: 8px; + margin-top: -27px; + font-size: 14px; + font-weight: 700; +} + +.aksrt-level-card__badge { + display: inline-block; + width: auto; + max-width: 72px; + height: 26px; + object-fit: contain; +} + +.aksrt-level-card__badge-text { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 34px; + height: 26px; + padding: 0 6px; + border-radius: 4px; + background: rgba(255, 255, 255, .38); + font-size: 12px; + font-weight: 700; +} + +.aksrt-level-card__progress-copy { + margin-top: auto; +} + +.aksrt-level-card__progress-copy .flex { + gap: 10px; +} + +.aksrt-level-card__progress-copy strong { + font-size: 12px; +} + +.aksrt-level-card__progress-copy span { + font-size: 11px; + opacity: .8; + text-align: right; +} + +.aksrt-level-progress { + height: 3px; + overflow: hidden; + margin: 0; + border-radius: 4px; + background: rgba(155, 107, 78, .28); +} + +.aksrt-level-progress > span { + display: block; + height: 100%; + border-radius: inherit; + background: #9b6b4e; +} + +.aksrt-level-card__growth-head { + justify-content: space-between; + gap: 12px; + min-height: 28px; + line-height: 1.35; +} + +.aksrt-level-card__growth-head > div { + min-width: 0; +} + +.aksrt-level-card__growth-head strong, +.aksrt-level-card__growth-head a { + display: inline-flex; + align-items: center; +} + +.aksrt-level-card__growth-head strong { + margin-right: 12px; + color: inherit; + font-weight: 700; +} + +.aksrt-level-card__growth-head strong i { + margin-right: 6px; + font-size: 12px; +} + +.aksrt-level-card__growth-head a { + font-size: 11px; + text-decoration: none; + opacity: .8; +} + +.aksrt-level-card__growth-head > a { + flex: 0 0 auto; + white-space: nowrap; +} + +.aksrt-level-growth { + width: 100%; + min-height: 96px; + margin-top: 4px; + overflow: hidden; +} + +.aksrt-level-growth .swiper-wrapper { + align-items: flex-end; + min-height: 96px; +} + +.aksrt-level-growth .pillar-item { + display: flex; + flex: 0 0 34px; + flex-direction: column; + align-items: center; + justify-content: flex-end; + min-height: 96px; + color: inherit; + opacity: .9; + text-align: center; + transition: opacity .2s ease; +} + +.aksrt-level-growth .pillar-item.is-future { + opacity: .5; +} + +.aksrt-level-growth .pillar-item .value { + min-height: 15px; + font-size: 9px; + line-height: 15px; + white-space: nowrap; +} + +.aksrt-level-growth .pillar-item .pillar { + width: 6px; + min-height: 2px; + margin: 0 auto 3px; + border-radius: 6px; + background: linear-gradient(#707479, #bfc5cc); +} + +.aksrt-level-growth .pillar-item.active { + color: #b97030; + font-weight: 700; +} + +.aksrt-level-growth .pillar-item.active .pillar { + background: linear-gradient(#c1764a, #e8c48e); +} + +.aksrt-level-growth .level-name { + display: flex; + align-items: center; + justify-content: center; + height: 22px; +} + +.aksrt-level-growth .level-name img { + display: block; + width: auto; + max-width: 32px; + height: 18px; + object-fit: contain; +} + +.aksrt-level-growth .level-name span { + font-size: 9px; + font-weight: 700; +} + +.aksrt-level-experience { + clear: both; + margin-bottom: 20px; + padding: 15px; + border: 0; + border-radius: var(--main-radius, 8px); + background: var(--main-bg-color, var(--surface-1, #fff)); + box-shadow: 0 0 10px var(--main-shadow, rgba(116, 116, 116, .08)); +} + +.aksrt-level-experience .box-body { + padding: 15px; +} + +.aksrt-level-tabs { + display: flex; + align-items: center; + gap: 6px; + flex-wrap: wrap; +} + +.aksrt-level-tabs .but { + text-decoration: none; +} + +.aksrt-level-tabs .but.is-active { + color: var(--focus-color, #f04494); +} + +.aksrt-level-experience .tab-content { + min-height: 80px; +} + +.aksrt-level-experience .tab-pane[hidden] { + display: none !important; +} + +.aksrt-level-list-row, +.aksrt-level-date-row { + border-color: var(--main-border-color, rgba(0, 0, 0, .06)); +} + +.aksrt-level-list-row .focus-color, +.aksrt-level-date-row .focus-color { + white-space: nowrap; +} + +.aksrt-level-empty { + margin: 0; + padding: 24px 0; + color: var(--muted-2-color, #999); + text-align: center; +} + +@media (max-width: 991px) { + .aksrt-level-card--summary, + .aksrt-level-card--growth { + margin-bottom: 20px; + } + + .aksrt-level-page__summary { + margin-bottom: 0; + } +} @media (max-width: 767px) { - .uc-level-hero__stats { grid-template-columns: 1fr; } - .uc-level-history-grid { grid-template-columns: 1fr; } - .uc-level-methods { grid-template-columns: 1fr; } - .uc-level-road { grid-template-columns: repeat(2, minmax(0,1fr)); } + .aksrt-level-page .row { + margin-right: 0; + margin-left: 0; + } + + .aksrt-level-page .row > [class*="col-"] { + padding-right: 0; + padding-left: 0; + } + + .aksrt-level-card { + min-height: 176px; + } + + .aksrt-level-card__growth-head { + align-items: flex-start; + flex-direction: column; + gap: 4px; + } + + .aksrt-level-card__growth-head > a { + align-self: flex-end; + } + + .aksrt-level-growth { + min-height: 92px; + } + + .aksrt-level-growth .swiper-wrapper, + .aksrt-level-growth .pillar-item { + min-height: 92px; + } + + .aksrt-level-experience { + padding: 10px; + } + + .aksrt-level-experience .box-body { + padding: 10px 5px; + } + + .aksrt-level-list-row .flex { + align-items: flex-start; + } } diff --git a/assets/js/routes/user-center.js b/assets/js/routes/user-center.js index 693afa4d..9827a1b2 100644 --- a/assets/js/routes/user-center.js +++ b/assets/js/routes/user-center.js @@ -107,12 +107,11 @@ var allowedParams = []; if (name === 'creator') allowedParams = ['income_page']; if (name === 'revenue') allowedParams = ['reward_tab', 'commission_page', 'user_page']; - if (name === 'posts') allowedParams = ['post_status', 'posts_page']; - if (name === 'follow') allowedParams = ['follow_list', 'follow_page']; - if (name === 'credits') allowedParams = ['asset', 'page']; - allowedParams.forEach(function(key) { - if (params.get(key)) url += (url.indexOf('?') === -1 ? '?' : '&') + key + '=' + encodeURIComponent(params.get(key)); - }); + if (name === 'posts') allowedParams = ['post_status', 'posts_page']; + if (name === 'follow') allowedParams = ['follow_list', 'follow_page']; + allowedParams.forEach(function(key) { + if (params.get(key)) url += (url.indexOf('?') === -1 ? '?' : '&') + key + '=' + encodeURIComponent(params.get(key)); + }); } target._aksrtPanelRequest = fetch(url, { credentials: 'same-origin', @@ -135,9 +134,31 @@ return target._aksrtPanelRequest; } - /* Revenue tabs are injected with the panel HTML. Handle them in the - * capture phase so they never fall through to a browser navigation. */ - function loadRevenueTab(queryParams) { + /* Level tabs are nested inside the active panel and must not enter the + * main user-center navigation handler. */ + function activateLevelTab(link) { + var page = link.closest('.aksrt-level-page'); + var paneId = link.getAttribute('data-aksrt-level-tab') || ''; + if (!page || !paneId) return false; + var pane = Array.prototype.find.call(page.querySelectorAll('.aksrt-level-experience .tab-pane'), function(item) { + return item.id === paneId; + }); + if (!pane) return false; + page.querySelectorAll('[data-aksrt-level-tab]').forEach(function(tab) { + var active = tab.getAttribute('data-aksrt-level-tab') === paneId; + tab.classList.toggle('is-active', active); + if (tab.getAttribute('role') === 'tab') tab.setAttribute('aria-selected', active ? 'true' : 'false'); + }); + page.querySelectorAll('.aksrt-level-experience .tab-pane').forEach(function(item) { + var active = item === pane; + item.classList.toggle('active', active); + item.classList.toggle('in', active); + item.hidden = !active; + }); + return true; + } + + function loadRevenueTab(queryParams) { var target = document.getElementById('panel-revenue'); var restUrl = (window.aksrtData && (window.aksrtData.restUrl || window.aksrtData.apiUrl)) || cfg.restUrl || ''; if (!target || !restUrl) return Promise.reject(new Error('revenue-panel-unavailable')); @@ -201,8 +222,14 @@ // Delegate every internal user-center link. This also covers markup injected // after a REST panel refresh, so panel navigation never falls back to a full load. - document.addEventListener('click', function(e) { - var withdrawOpen = e.target && e.target.closest ? e.target.closest('[data-aksrt-withdraw-open]') : null; + document.addEventListener('click', function(e) { + var levelTab = e.target && e.target.closest ? e.target.closest('[data-aksrt-level-tab]') : null; + if (levelTab && activateLevelTab(levelTab)) { + e.preventDefault(); + e.stopPropagation(); + return; + } + var withdrawOpen = e.target && e.target.closest ? e.target.closest('[data-aksrt-withdraw-open]') : null; if (withdrawOpen) { var withdrawModal = document.querySelector('[data-aksrt-withdraw-modal]'); if (withdrawModal) { diff --git a/inc/helpers/user-center-renderers/profile-level.php b/inc/helpers/user-center-renderers/profile-level.php index c0945911..c820f278 100644 --- a/inc/helpers/user-center-renderers/profile-level.php +++ b/inc/helpers/user-center-renderers/profile-level.php @@ -1,6 +1,6 @@ '; +} else { + $badge_html = 'LV' . esc_html((string) $current_level) . ''; +} + +$avatar_html = function_exists('aksrt_get_avatar_html') + ? aksrt_get_avatar_html($user_id, 48, ['class' => 'avatar-mini']) + : get_avatar($user_id, 48); + +$next_need = max(0, (int) ($progress['next_need'] ?? 0)); +$integral = max(0, (int) ($progress['integral'] ?? 0)); +$remaining = max(0, (int) ($progress['remaining'] ?? 0)); +$percentage = max(0, min(100, (int) ($progress['progress'] ?? 0))); ?> -