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))); ?> -
-
-
-
- -
-
-

-

-
-
-
-
-
0 ? '/' . esc_html((string) $day_max) : ''; ?>
-
-
-
-
- EXP - -
-
-
-
- -
-

-
- -
-
- - alt="">LV +
+
+
+
+ +
+
+
+ +
+
+ + +
+
+ +
/
+ +
/
+ +
- - EXP
- +
-
- -
-

-
- $default_value) : - if ($key === 'day_max') continue; - $value = in_array($key, ['checkin', 'shop_gift'], true) ? 0 : ($key === 'referral' ? (int) $default_value : \AKSRT\User\Level::task_points($key)); - if ($value <= 0 && !in_array($key, ['checkin', 'shop_gift'], true)) continue; - ?> -
- -
- 0 ? '+' . esc_html((string) $value) : esc_html__('动态', 'aksrt'); ?> +
+
+ +
+ +
+
+ $current_level ? ' is-future' : ''); + ?> +
+
+
+
+ alt="" title="" decoding="async">LV +
+
+ +
+
- +
-
+
-
-
-

- -
- +
+
+ + +
+
+
+ $default_value) : + if ($key === 'day_max') { + continue; + } + $value = in_array($key, ['checkin', 'shop_gift'], true) ? 0 : ($key === 'referral' ? (int) $default_value : \AKSRT\User\Level::task_points($key)); + if ($value <= 0 && !in_array($key, ['checkin', 'shop_gift'], true)) { + continue; + } ?> -
- -
- + +
+
+
+ 0 ? '+' . esc_html((string) $value) : esc_html__('动态', 'aksrt'); ?> +
- -

- -
- -
-

- -
- $value) : ?> -
+ EXP
- + - -

- -
-
+ + + + diff --git a/tests/widget-system/user-level-contract.test.cjs b/tests/widget-system/user-level-contract.test.cjs new file mode 100644 index 00000000..381ae36c --- /dev/null +++ b/tests/widget-system/user-level-contract.test.cjs @@ -0,0 +1,102 @@ +const assert = require('node:assert/strict'); +const fs = require('node:fs'); +const path = require('node:path'); +const test = require('node:test'); + +const root = path.resolve(__dirname, '..', '..'); +const read = (file) => fs.readFileSync(path.join(root, file), 'utf8'); + +test('user level renderer keeps the canonical panel mapping and reference layout', () => { + const context = read('inc/helpers/aksrt-user-center.php'); + const renderer = read('inc/helpers/user-center-renderers/profile-level.php'); + const panel = read('templates/parts/user-center/panel.php'); + + assert.match(context, /'level'\s*=>\s*'level'/); + assert.match(context, /profile-' \. \$renderer \. '\.php/); + assert.match(renderer, /class="aksrt-level-page"/); + assert.match(renderer, /class="row aksrt-level-page__summary"/); + assert.match(renderer, /class="col-md-5"/); + assert.match(renderer, /class="col-md-7"/); + assert.match(renderer, /colorful-bg jb-vip1 aksrt-level-card/); + assert.match(renderer, /colorful-bg c-gray aksrt-level-card/); + assert.match(renderer, /class="zib-widget aksrt-level-experience"/); + assert.match(renderer, /id="tab_integral_get"/); + assert.match(renderer, /id="tab_integral_my"/); + assert.match(renderer, /id="tab_integral_date"/); + assert.match(renderer, /data-aksrt-level-tab="tab_integral_date"/); + assert.match(renderer, /Level::get_progress/); + assert.match(renderer, /Level::get_details/); + assert.match(renderer, /Level::get_date_details/); + assert.match(panel, /class="dashboard-panel/); + assert.match(panel, /role="tabpanel"/); +}); + +test('user level renderer covers states, limits, and safe icon fallbacks', () => { + const renderer = read('inc/helpers/user-center-renderers/profile-level.php'); + + assert.match(renderer, /array_slice\(\\AKSRT\\User\\Level::get_details\(\$user_id\), 0, 50\)/); + assert.match(renderer, /array_slice\(\\AKSRT\\User\\Level::get_date_details\(\$user_id\), 0, 30, true\)/); + assert.match(renderer, /!empty\(\$progress\['is_max'\]\)/); + assert.match(renderer, /get_level_icon_url\(\$level\)/); + assert.match(renderer, /if \(\$icon !== ''\)/); + assert.match(renderer, /暂无经验值获取明细/); + assert.match(renderer, /最多显示近50条记录/); + assert.match(renderer, /最多显示近30条记录/); + assert.match(renderer, /esc_html\(\$labels\[\$key\] \?\? \$key\)/); + assert.match(renderer, /role="progressbar"/); + assert.match(renderer, /aria-valuenow=/); +}); + +test('user level renderer no longer carries the retired multi-card markup', () => { + const renderer = read('inc/helpers/user-center-renderers/profile-level.php'); + const css = read('assets/css/routes/user-center/level.css'); + + for (const selector of [ + 'uc-level-hero', + 'uc-level-road', + 'uc-level-methods', + 'uc-level-history-grid', + 'uc-level-ledger', + 'uc-level-dates', + ]) { + assert.doesNotMatch(renderer, new RegExp(selector)); + assert.doesNotMatch(css, new RegExp(`\\.${selector}(?:\\b|__)`)); + } +}); + +test('user level styles remove the generic panel card and retain reference visual primitives', () => { + const css = read('assets/css/routes/user-center/level.css'); + + assert.match(css, /\.uc-content #panel-level\.dashboard-panel\s*\{[\s\S]*?padding:\s*0;[\s\S]*?background:\s*transparent;[\s\S]*?box-shadow:\s*none;/); + assert.match(css, /\.aksrt-level-card--summary\s*\{[\s\S]*?--this-bg:\s*linear-gradient\(25deg/); + assert.match(css, /\.aksrt-level-card--growth\s*\{[\s\S]*?--this-bg:\s*rgba\(136, 136, 136, \.1\)/); + assert.match(css, /\.aksrt-level-progress\s*\{[\s\S]*?height:\s*3px/); + assert.match(css, /\.aksrt-level-growth \.pillar-item \.pillar\s*\{[\s\S]*?width:\s*6px/); + assert.match(css, /\.aksrt-level-growth \.pillar-item\.active \.pillar/); + assert.match(css, /@media \(max-width: 767px\)/); +}); + +test('user center handles level-internal tabs before main navigation and has no dead credits branch', () => { + const scripts = read('assets/js/routes/user-center.js'); + const levelHandler = scripts.indexOf('function activateLevelTab'); + const clickHandler = scripts.indexOf("document.addEventListener('click', function(e)"); + const withdrawHandler = scripts.indexOf('var withdrawOpen', clickHandler); + + assert.ok(levelHandler >= 0); + assert.ok(clickHandler >= 0); + assert.ok(levelHandler < clickHandler); + assert.ok(scripts.indexOf("closest('[data-aksrt-level-tab]')", clickHandler) > clickHandler); + assert.ok(scripts.indexOf('e.stopPropagation();', clickHandler) < withdrawHandler); + assert.doesNotMatch(scripts, /if \(name === 'credits'\) allowedParams/); + assert.match(scripts, /item\.hidden = !active/); + assert.match(scripts, /aria-selected/); +}); + +test('user center loads level styles as a versioned leaf', () => { + const scripts = read('src/Core/ScriptsPart1b.php'); + + assert.match(scripts, /'user-center\/level'/); + assert.match(scripts, /filemtime\(\$part_path\)/); + assert.doesNotMatch(scripts, /assets\/css\/routes\/user-center\.css/); + assert.doesNotMatch(scripts, /assets\/css\/routes\/profile\.css/); +});