From deff20532f982942cccc3e4bf5b7bb28dad37dba Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 21 Jul 2026 17:53:34 +0800 Subject: [PATCH] fix(ui): nav CTA icon alignment and always show UC VIP menu --- .../src/schema/sections/users/features.js | 4 +- .../css/frontend/nav/header-menu-buttons.css | 116 ++++++++++++++++-- inc/helpers/aksrt-header-menu-buttons.php | 86 ++++++++++--- inc/helpers/aksrt-header-userbox.php | 12 +- src/AKSRT/Admin/Schema/SchemaUsers.php | 2 +- src/AKSRT/Content/VipServiceModal.php | 2 +- src/AKSRT/Settings/UserRuntime.php | 26 +++- src/AKSRT/User/Center.php | 87 ++++++------- 8 files changed, 257 insertions(+), 78 deletions(-) diff --git a/assets/admin/src/schema/sections/users/features.js b/assets/admin/src/schema/sections/users/features.js index a4efb658..719b9593 100644 --- a/assets/admin/src/schema/sections/users/features.js +++ b/assets/admin/src/schema/sections/users/features.js @@ -4,7 +4,7 @@ export const featuresSchema = { icon: 'fas fa-user-cog', description: '配置用户中心和个人主页的功能模块。', defaults: { - user_center_tabs: 'profile,posts,comments,credits,favorites', + user_center_tabs: 'profile,posts,comments,favorites,vip,credits', user_avatar_upload: true, user_cover_upload: true, user_social_links: true, @@ -25,7 +25,7 @@ export const featuresSchema = { title: '用户中心', icon: 'fas fa-user-shield', fields: [ - { key: 'user_center_tabs', label: '用户中心 Tab', type: 'input', default: 'profile,posts,comments,credits,favorites', help: '逗号分隔' }, + { key: 'user_center_tabs', label: '用户中心 Tab', type: 'input', default: 'profile,posts,comments,favorites,vip,credits', help: '逗号分隔。vip=我的会员(会员功能开启时也会自动注入)' }, { key: 'user_avatar_upload', label: '头像上传', type: 'switch', default: true }, { key: 'user_cover_upload', label: '封面上传', type: 'switch', default: true }, { key: 'user_social_links', label: '社交链接', type: 'switch', default: true }, diff --git a/assets/css/frontend/nav/header-menu-buttons.css b/assets/css/frontend/nav/header-menu-buttons.css index 39cc6f15..f68badaf 100644 --- a/assets/css/frontend/nav/header-menu-buttons.css +++ b/assets/css/frontend/nav/header-menu-buttons.css @@ -8,44 +8,97 @@ display: flex; align-items: center; gap: 8px; + flex-wrap: nowrap; + min-width: 0; } .navbar-but-cluster .navbar-but, .navbar-but-cluster .navbar-vip { display: inline-flex; align-items: center; + min-width: 0; } +/* CTA button base: flex icon + text, never stack or clip glyphs */ +.navbar-but-cluster .navbar-cta, .navbar-but-cluster .btn-primary, .navbar-but-cluster .but.btn-primary, .navbar-but-cluster .navbar-newposts.but, .navbar-but-cluster a.but { - display: inline-flex; + display: inline-flex !important; align-items: center; + justify-content: center; gap: 6px; padding: 6px 14px; - border-radius: 20px; + border-radius: var(--navbar-cta-radius, 20px); background: var(--color-primary, #2f6df6); color: #fff; text-decoration: none; border: 0; font-size: 13px; - line-height: 1.4; + line-height: 1.2; + white-space: nowrap; + box-sizing: border-box; + vertical-align: middle; +} + +.navbar-but-cluster .navbar-cta > i, +.navbar-but-cluster a.but > i, +.navbar-but-cluster .btn-primary > i { + display: inline-flex; + align-items: center; + justify-content: center; + width: 1em; + height: 1em; + margin: 0 !important; /* kill mr3/ml10 utility drift on icons */ + flex: 0 0 auto; + line-height: 1; + font-size: 1em; +} + +.navbar-but-cluster .navbar-cta-text, +.navbar-but-cluster .navbar-cta > span:not(.badge) { + display: inline-block; + line-height: 1.2; white-space: nowrap; } -.navbar-but-cluster .payvip-icon.but { +.navbar-but-cluster .payvip-icon.but, +.navbar-but-cluster a.payvip-icon { background: linear-gradient(90deg, #ff6b6b, #f04494); color: #fff; padding: 6px 12px; - border-radius: 20px; + border-radius: var(--navbar-cta-radius, 20px); text-decoration: none; font-size: 13px; } +.navbar-but-cluster .ml10 { + margin-left: 0; /* spacing handled by cluster gap */ +} + +.navbar-but-cluster .theme-toggle-desktop, +.navbar-but-cluster .toggle-theme { + display: inline-flex; + align-items: center; + justify-content: center; + width: 34px; + height: 34px; + padding: 0; + border-radius: 999px; + flex: 0 0 auto; +} + +.navbar-but-cluster .theme-toggle-desktop > i, +.navbar-but-cluster .toggle-theme > i { + margin: 0 !important; + line-height: 1; +} + .newadd-btns.hover-show { position: relative; - display: inline-block; + display: inline-flex; + align-items: center; } .newadd-btns .drop-newadd, @@ -54,7 +107,7 @@ position: absolute; top: calc(100% + 6px); right: 0; - min-width: 140px; + min-width: 148px; background: var(--main-bg-color, #fff); border-radius: 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); @@ -78,11 +131,43 @@ white-space: nowrap; } +.newadd-btns__item > i { + width: 1em; + margin: 0; + text-align: center; + flex: 0 0 auto; +} + .newadd-btns__item:hover { background: var(--surface-2, rgba(0, 0, 0, 0.04)); color: var(--focus-color, var(--color-primary)); } +/* Header VIP hover cards */ +.navbar-vip.hover-show { + position: relative; +} + +.navbar-vip .sub-vip-card { + display: none; + position: absolute; + top: calc(100% + 8px); + right: 0; + z-index: 60; + width: min(420px, 90vw); + padding: 10px; + border-radius: 12px; + background: var(--main-bg-color, #fff); + box-shadow: 0 12px 36px rgba(0, 0, 0, 0.16); + gap: 10px; + flex-wrap: wrap; +} + +.navbar-vip.hover-show:hover .sub-vip-card, +.navbar-vip.hover-show:focus-within .sub-vip-card { + display: flex; +} + /* float commerce */ .float-btn-shop-cart { position: relative; @@ -112,3 +197,20 @@ .float-btn.pay-vip { color: #f5a623; } + +@media (max-width: 768px) { + .navbar-but-cluster .navbar-cta-text { + /* keep text on tablet; hide only on very narrow if needed */ + } +} + +@media (max-width: 520px) { + .navbar-but-cluster { + gap: 6px; + } + .navbar-but-cluster .navbar-cta, + .navbar-but-cluster a.but { + padding: 6px 10px; + font-size: 12px; + } +} diff --git a/inc/helpers/aksrt-header-menu-buttons.php b/inc/helpers/aksrt-header-menu-buttons.php index 67d50542..9c5ecf13 100644 --- a/inc/helpers/aksrt-header-menu-buttons.php +++ b/inc/helpers/aksrt-header-menu-buttons.php @@ -65,7 +65,8 @@ if (!function_exists('aksrt_get_new_add_actions')) : 'type' => 'post', 'url' => $url, 'label' => __('写文章', 'aksrt'), - 'icon' => 'fa fa-file-text-o', + // FA5 free solid names (avoid FA4 aliases like file-text-o). + 'icon' => 'fas fa-file-alt', ]; } elseif ($type === 'topic') { $url = function_exists('aksrt_get_forum_compose_url') ? aksrt_get_forum_compose_url() : ''; @@ -76,25 +77,21 @@ if (!function_exists('aksrt_get_new_add_actions')) : 'type' => 'topic', 'url' => $url, 'label' => __('发帖', 'aksrt'), - 'icon' => 'fa fa-comments-o', + 'icon' => 'fas fa-comments', ]; } elseif ($type === 'product') { - // Prefer front product edit page when registered. $url = ''; if (function_exists('aksrt_get_product_edit_url')) { $url = (string) aksrt_get_product_edit_url(); } if ($url === '') { - // Fallback: product-edit page template lookup is optional. - $url = home_url('/?page_id=0'); - // Use admin product CPT if available. $url = admin_url('post-new.php?post_type=aksrt_product'); } $out[] = [ 'type' => 'product', 'url' => $url, 'label' => __('发布商品', 'aksrt'), - 'icon' => 'fa fa-shopping-bag', + 'icon' => 'fas fa-shopping-bag', ]; } } @@ -102,6 +99,49 @@ if (!function_exists('aksrt_get_new_add_actions')) : } endif; +if (!function_exists('aksrt_normalize_header_cta_label')) : + /** + * Normalize CTA label HTML: map FA4 classes and keep a single leading icon. + */ + function aksrt_normalize_header_cta_label(string $label, string $fallback_icon = 'fas fa-pen'): string { + $label = trim($label); + if ($label === '') { + return ' ' . esc_html__('发布', 'aksrt'); + } + + // Common FA4 → FA5 renames used in admin defaults. + $replacements = [ + 'fa-file-text-o' => 'fa-file-alt', + 'fa-file-text' => 'fa-file-alt', + 'fa-pencil-square-o' => 'fa-edit', + 'fa-pencil' => 'fa-pen', + 'fa-comments-o' => 'fa-comments', + 'fa-clock-o' => 'fa-clock', + 'fa-calendar-check-o'=> 'fa-calendar-check', + 'fa-diamond' => 'fa-gem', + ]; + $label = strtr($label, $replacements); + + // Ensure icon uses fas (FA5 solid) when only bare "fa " is present. + $label = preg_replace('/\bclass=(["\'])fa\s+/', 'class=$1fas ', $label) ?? $label; + $label = preg_replace('/