fix: admin布局间隙主题适配 + 默认模型移至/v1/messages badge内

- AdminLayout添加主题背景色包裹,消除tab与内容间的未适配间隙
- 缩小nav底部margin (mb-4 → mb-1)
- SubscriptionPlanCard默认模型从独立区块移到/v1/messages badge后面
This commit is contained in:
erio
2026-03-14 04:42:39 +08:00
parent 4ce3484179
commit ef4241b82f
2 changed files with 35 additions and 43 deletions

View File

@@ -11,7 +11,7 @@ const NAV_ITEMS = [
{ path: '/admin/subscriptions', label: { zh: '订阅管理', en: 'Subscriptions' } }, { path: '/admin/subscriptions', label: { zh: '订阅管理', en: 'Subscriptions' } },
]; ];
function AdminNav() { function AdminLayoutInner({ children }: { children: React.ReactNode }) {
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const pathname = usePathname(); const pathname = usePathname();
const token = searchParams.get('token') || ''; const token = searchParams.get('token') || '';
@@ -35,39 +35,43 @@ function AdminNav() {
}; };
return ( return (
<nav <div className={['min-h-screen', isDark ? 'bg-slate-950' : 'bg-slate-100'].join(' ')}>
className={[ <div className="px-2 pt-2 sm:px-3 sm:pt-3">
'mb-4 flex flex-wrap gap-1 rounded-xl border p-1', <nav
isDark ? 'border-slate-700 bg-slate-800/70' : 'border-slate-200 bg-slate-100/90',
].join(' ')}
>
{NAV_ITEMS.map((item) => (
<a
key={item.path}
href={buildUrl(item.path)}
className={[ className={[
'rounded-lg px-3 py-1.5 text-xs font-medium transition-colors', 'mb-1 flex flex-wrap gap-1 rounded-xl border p-1',
isActive(item.path) isDark ? 'border-slate-700 bg-slate-800/70' : 'border-slate-200 bg-slate-100/90',
? isDark
? 'bg-indigo-500/30 text-indigo-100 ring-1 ring-indigo-300/35'
: 'bg-white text-slate-900 ring-1 ring-slate-300 shadow-sm'
: isDark
? 'text-slate-400 hover:text-slate-200 hover:bg-slate-700/50'
: 'text-slate-500 hover:text-slate-700 hover:bg-slate-200/70',
].join(' ')} ].join(' ')}
> >
{item.label[locale]} {NAV_ITEMS.map((item) => (
</a> <a
))} key={item.path}
</nav> href={buildUrl(item.path)}
className={[
'rounded-lg px-3 py-1.5 text-xs font-medium transition-colors',
isActive(item.path)
? isDark
? 'bg-indigo-500/30 text-indigo-100 ring-1 ring-indigo-300/35'
: 'bg-white text-slate-900 ring-1 ring-slate-300 shadow-sm'
: isDark
? 'text-slate-400 hover:text-slate-200 hover:bg-slate-700/50'
: 'text-slate-500 hover:text-slate-700 hover:bg-slate-200/70',
].join(' ')}
>
{item.label[locale]}
</a>
))}
</nav>
</div>
{children}
</div>
); );
} }
export default function AdminLayout({ children }: { children: React.ReactNode }) { export default function AdminLayout({ children }: { children: React.ReactNode }) {
return ( return (
<Suspense> <Suspense>
<AdminNav /> <AdminLayoutInner>{children}</AdminLayoutInner>
{children}
</Suspense> </Suspense>
); );
} }

View File

@@ -73,11 +73,16 @@ export default function SubscriptionPlanCard({ plan, onSubscribe, isDark, locale
{isOpenAI && plan.allowMessagesDispatch && ( {isOpenAI && plan.allowMessagesDispatch && (
<span <span
className={[ className={[
'rounded-full px-2 py-0.5 text-xs font-medium', 'inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium',
isDark ? 'bg-green-500/20 text-green-300' : 'bg-green-100 text-green-700', isDark ? 'bg-green-500/20 text-green-300' : 'bg-green-100 text-green-700',
].join(' ')} ].join(' ')}
> >
/v1/messages /v1/messages
{plan.defaultMappedModel && (
<span className={['font-mono', isDark ? 'text-green-400' : 'text-green-800'].join(' ')}>
{plan.defaultMappedModel}
</span>
)}
</span> </span>
)} )}
</div> </div>
@@ -149,23 +154,6 @@ export default function SubscriptionPlanCard({ plan, onSubscribe, isDark, locale
</div> </div>
)} )}
{/* OpenAI specific: default model */}
{isOpenAI && plan.defaultMappedModel && (
<div
className={[
'mb-4 flex items-center justify-between rounded-lg border px-3 py-2 text-sm',
isDark ? 'border-green-500/30 bg-green-500/10' : 'border-green-200 bg-green-50/50',
].join(' ')}
>
<span className={isDark ? 'text-slate-400' : 'text-slate-500'}>
{pickLocaleText(locale, '默认模型', 'Default Model')}
</span>
<span className={['text-xs font-mono', isDark ? 'text-slate-300' : 'text-slate-700'].join(' ')}>
{plan.defaultMappedModel}
</span>
</div>
)}
{/* Features */} {/* Features */}
{plan.features.length > 0 && ( {plan.features.length > 0 && (
<div className="mb-5"> <div className="mb-5">