feat(frontend): replicate reference header user box 1:1
顶导航点击小人弹出的用户信息浮层,从 AKSRT 定制结构改为与参考主题 zib_header_user_box() 逐行同构:头像链接包裹、钱包双瓷砖、会员条、签到、消息图标、统计徽章行全部改用参考主题遗留类,渲染交回 main.css(.sub-user-box 242px、.avatar-img 38px、.msg-news-icon、badge.top、.payvip-icon 深色渐变加 gem 水印、.vip-expdate-tag、.muted-box)。 头像改走 aksrt_get_avatar_box(用户ID, avatar-img, true, false),得到参考的 a 链接包裹 avatar-img 结构。消息图标改参考标记 msg-news-icon abs-right 加 toggle-radius msg-icon,未读徽章用 badge.top,avatar_dropdown 位置门控契约保留。管理端行在「后台管理」前插入「支付中心」,跳 admin.php?page=aksrt_pay,即参考主题「商城中心」槽位,图标 fa-credit-card。 钱包重写为参考双瓷砖:余额在前(c-blue-2 加 fa-money-bill-wave)、积分在后(c-yellow 加 fa-coins),分别按充值开关与积分总开关门控,两块皆关则不渲染,并保留 data-aksrt-wallet-value 与 data-aksrt-points-value 两个 JS 刷新钩子。会员条去掉 AKSRT 自创的 vipbg-v2 level-N 金色背景,改参考的 payvip-icon 加 badg jb-yellow vip-expdate-tag,到期文案按参考语义分为已过期、永久会员、裸日期三种。签到入口由 button 改为 a.but block c-yellow,并去掉随之失效的 compact 形参,data-signin 挂载与 wp_footer 验证码不变。统计行删掉文章徽章(本站不做帖子),图标由 SVG sprite 换 FA5+ 的 fa-comment-dots、fa-thumbs-up、fa-fire。 会员等级图标契约不动:aksrt_get_vip_icon 与 User\Level::get_badge_html 的调用与参数保持原样。 顺带清死代码:aksrt_header_user_badges_row 原本取到函数后直接返回空串,现在真正输出统计行;删掉 header-userbox.css 里整套 bespoke 规则与 vip-modal.css 的 vipbg-v2 死规则。 显式偏差:统计行链接保持扁平用户主页 URL(AKSRT 用户主页是干净 URL 加 JS tab,没有 query tab 路由);签到入口沿用积分签到总开关门控,不新增管理端可配置项。 public.css 与 public.min.css 用 tools/build-public-assets.mjs 重建:该 bundle 打包了 header-userbox.css 且作为依赖先于单模块入队,旧的 width 260px 会压过新源码、把卡片钉在 260px 而不是参考的 242px。 验证:node --test tests/**/*.test.cjs 573 项全通过;六个改动 PHP 文件 php -l 无语法错误;卡片用到的 FA5 token 逐个核对 5.15.4 全部命中。未做真实视觉效果验收。
This commit is contained in:
@@ -167,14 +167,58 @@ test('guest account member VIP and publish contracts share reference header DOM'
|
||||
assert.match(header, /navbar-form navbar-right navbar-but/);
|
||||
assert.match(header, /pay-vip/);
|
||||
assert.match(scripts, /\$enqueue_module\('header-userbox'\)/);
|
||||
assert.match(userboxCss, /\.aksrt-header-userbox \.user-info > \.avatar/);
|
||||
assert.match(userboxCss, /\.aksrt-header-wallet/);
|
||||
assert.match(userboxCss, /\.aksrt-header-checkin/);
|
||||
assert.match(userboxCss, /\.aksrt-header-payvip__cta/);
|
||||
assert.match(userboxCss, /\.header-user-href > a[\s\S]*?max-height: none/);
|
||||
assert.match(userboxCss, /body\.dark-theme \.aksrt-header-checkin/);
|
||||
assert.doesNotMatch(userboxCss, /user-dropdown|nav-user|html\.dark|theme-dark/);
|
||||
assert.doesNotMatch(userboxCss, /--(?:main|muted|key)-|@import/);
|
||||
// Account rows render through the shared legacy classes; the module keeps only
|
||||
// the shell anchoring, the account href geometry and the top-nav bell badge.
|
||||
assert.match(userboxCss, /\.aksrt-nav-notification \.aksrt-notification-badge/);
|
||||
assert.doesNotMatch(userboxCss, /aksrt-header-wallet|aksrt-header-checkin|aksrt-header-payvip|\.aksrt-header-userbox \.aksrt-notification-badge/);
|
||||
assert.doesNotMatch(userboxCss, /width:\s*260px/);
|
||||
});
|
||||
|
||||
test('the account popover rows match the reference user box structure', () => {
|
||||
const identity = read('inc/helpers/aksrt-identity.php');
|
||||
const legacyMainCss = read('assets/css/main.css');
|
||||
|
||||
// Stats row is wired with the reference wrapper and drops the posts chip.
|
||||
assert.match(header, /aksrt_header_user_badges_row\(\$user_id\)/);
|
||||
assert.match(header, /class="em09 author-tag mb10 mt6 flex jc"/);
|
||||
assert.doesNotMatch(identity, /tag-posts/);
|
||||
assert.match(identity, /fa fas fa-comment-dots/);
|
||||
assert.match(identity, /fa fas fa-thumbs-up/);
|
||||
assert.match(identity, /fa fas fa-fire/);
|
||||
assert.doesNotMatch(identity, /aksrt_renderer_svg_icon/);
|
||||
|
||||
// Admin row exposes the AKSRT payment center at the reference mall slot.
|
||||
assert.match(header, /admin\.php\?page=aksrt_pay/);
|
||||
assert.match(header, /支付中心/);
|
||||
|
||||
// Wallet tiles: balance first, muted-box geometry, FA5 icons.
|
||||
assert.match(header, /class="flex ab jsb col-ml6"/);
|
||||
assert.match(header, /muted-box padding-6 flex1 radius4/);
|
||||
assert.match(header, /font-bold c-blue-2/);
|
||||
assert.match(header, /font-bold c-yellow/);
|
||||
assert.match(header, /fa fas fa-money-bill-wave/);
|
||||
assert.match(header, /fa fas fa-coins/);
|
||||
|
||||
// Message icon uses the reference markup.
|
||||
assert.match(header, /msg-news-icon abs-right/);
|
||||
assert.match(header, /toggle-radius msg-icon/);
|
||||
assert.match(header, /<badge class="top">/);
|
||||
|
||||
// VIP bar and CTA use the reference payvip geometry.
|
||||
assert.match(header, /radius4 payvip-icon btn-block text-center/);
|
||||
assert.match(header, /vip-expdate-tag/);
|
||||
assert.match(header, /pay-vip but radius4 payvip-icon btn-block/);
|
||||
assert.doesNotMatch(header, /vipbg-v2/);
|
||||
|
||||
// Check-in entry is an anchor with the reference button classes.
|
||||
assert.match(header, /but block c-yellow/);
|
||||
assert.match(header, /data-signin-done-label[\s\S]{0,120}?今日已签到/);
|
||||
|
||||
// Card geometry falls back to the reference .sub-user-box width.
|
||||
assert.match(legacyMainCss, /\.sub-user-box\s*\{\s*width:\s*242px;/s);
|
||||
});
|
||||
|
||||
test('the only menu metadata and Walker contract is the legacy runtime', () => {
|
||||
|
||||
Reference in New Issue
Block a user