refactor(admin-web): unify page headers with shared title card
Introduce .page-title-card style and migrate Images, Knowledge, KolDashboard, KolManage, KolProfile views to the shared header layout. Add subtitle copy for KOL dashboard and manage views. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -352,22 +352,13 @@ async function confirmDeleteImage(image: ImageAssetItem) {
|
||||
|
||||
<template>
|
||||
<div class="images-page">
|
||||
<div class="images-page__hero">
|
||||
<h2>{{ t("images.title") }}</h2>
|
||||
<p>{{ t("images.description") }}</p>
|
||||
</div>
|
||||
|
||||
<div class="images-main-card">
|
||||
<div class="images-toolbar">
|
||||
<div class="images-toolbar__left">
|
||||
<a-input-search
|
||||
v-model:value="searchKeyword"
|
||||
:placeholder="t('images.searchPlaceholder')"
|
||||
style="width: 300px"
|
||||
allow-clear
|
||||
/>
|
||||
<section class="page-title-card">
|
||||
<div class="page-title-card__header">
|
||||
<div class="page-title-card__copy">
|
||||
<h2>{{ t("images.title") }}</h2>
|
||||
<p>{{ t("images.description") }}</p>
|
||||
</div>
|
||||
<div class="images-toolbar__right">
|
||||
<div class="page-title-card__actions">
|
||||
<a-button type="primary" :disabled="imageUploadBusy" @click="triggerUpload">
|
||||
<template #icon><UploadOutlined /></template>
|
||||
{{ t("images.uploadBtn") }}
|
||||
@@ -383,6 +374,19 @@ async function confirmDeleteImage(image: ImageAssetItem) {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="images-main-card">
|
||||
<div class="images-toolbar">
|
||||
<div class="images-toolbar__left">
|
||||
<a-input-search
|
||||
v-model:value="searchKeyword"
|
||||
:placeholder="t('images.searchPlaceholder')"
|
||||
style="width: 300px"
|
||||
allow-clear
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="images-layout-inner">
|
||||
<aside class="images-sidebar">
|
||||
@@ -579,19 +583,6 @@ async function confirmDeleteImage(image: ImageAssetItem) {
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.images-page__hero h2 {
|
||||
margin: 0;
|
||||
color: #111827;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.images-page__hero p {
|
||||
margin: 0;
|
||||
color: #6b7280;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.images-main-card {
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
|
||||
@@ -505,21 +505,24 @@ function closeItemDetail(): void {
|
||||
|
||||
<template>
|
||||
<div class="knowledge-page">
|
||||
<div class="knowledge-page__hero">
|
||||
<h2>知识库</h2>
|
||||
<p>
|
||||
通过上传文档,网站认证及任何与您的产品相关的包装及品牌故事内容;对各种格式的数据和资料信息来进行归纳,并结合生成文章
|
||||
</p>
|
||||
</div>
|
||||
<section class="page-title-card">
|
||||
<div class="page-title-card__header">
|
||||
<div class="page-title-card__copy">
|
||||
<h2>知识库</h2>
|
||||
<p>
|
||||
通过上传文档,网站认证及任何与您的产品相关的包装及品牌故事内容;对各种格式的数据和资料信息来进行归纳,并结合生成文章
|
||||
</p>
|
||||
</div>
|
||||
<div class="page-title-card__actions">
|
||||
<a-button type="primary" class="knowledge-add-btn" @click="openItemModal('document')">
|
||||
<template #icon><PlusOutlined /></template>
|
||||
添加知识
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="knowledge-main-card">
|
||||
<div class="knowledge-toolbar">
|
||||
<a-button type="primary" class="knowledge-add-btn" @click="openItemModal('document')">
|
||||
<template #icon><PlusOutlined /></template>
|
||||
添加知识
|
||||
</a-button>
|
||||
</div>
|
||||
|
||||
<div class="knowledge-layout-inner">
|
||||
<aside class="knowledge-sidebar">
|
||||
<div class="knowledge-sidebar__header">
|
||||
@@ -736,25 +739,6 @@ function closeItemDetail(): void {
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.knowledge-page__hero {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.knowledge-page__hero h2 {
|
||||
margin: 0;
|
||||
color: #111827;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.knowledge-page__hero p {
|
||||
margin: 0;
|
||||
color: #6b7280;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.knowledge-main-card {
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
@@ -765,10 +749,6 @@ function closeItemDetail(): void {
|
||||
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.03);
|
||||
}
|
||||
|
||||
.knowledge-toolbar {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.knowledge-add-btn {
|
||||
width: 120px;
|
||||
border-radius: 6px;
|
||||
|
||||
@@ -208,16 +208,20 @@ function refresh() {
|
||||
|
||||
<template>
|
||||
<div class="kol-dashboard-view">
|
||||
<div class="page-header">
|
||||
<div class="header-info">
|
||||
<h2 class="page-title">{{ t("kol.dashboard.title") }}</h2>
|
||||
<p class="page-desc">实时查看订阅情况与生成数据统计</p>
|
||||
<section class="page-title-card">
|
||||
<div class="page-title-card__header">
|
||||
<div class="page-title-card__copy">
|
||||
<h2>{{ t("kol.dashboard.title") }}</h2>
|
||||
<p>{{ t("kol.dashboard.subtitle") }}</p>
|
||||
</div>
|
||||
<div class="page-title-card__actions">
|
||||
<a-button @click="refresh">
|
||||
<template #icon><ReloadOutlined /></template>
|
||||
刷新
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<a-button @click="refresh">
|
||||
<template #icon><ReloadOutlined /></template>
|
||||
刷新
|
||||
</a-button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Stats Row -->
|
||||
<div class="stats-row">
|
||||
@@ -366,23 +370,6 @@ function refresh() {
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.page-title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
margin: 0 0 4px 0;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
.page-desc {
|
||||
font-size: 14px;
|
||||
color: #8c8c8c;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Stats Row */
|
||||
.stats-row {
|
||||
display: grid;
|
||||
|
||||
@@ -224,6 +224,15 @@ function packageStatusLabel(status: string) {
|
||||
|
||||
<template>
|
||||
<div class="kol-manage-view">
|
||||
<section v-if="!editingPromptId" class="page-title-card">
|
||||
<div class="page-title-card__header">
|
||||
<div class="page-title-card__copy">
|
||||
<h2>{{ t("kol.manage.title") }}</h2>
|
||||
<p>{{ t("kol.manage.subtitle") }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div v-if="editingPromptId" class="manage-content manage-content--editor">
|
||||
<div class="fullscreen-editor">
|
||||
<KolPromptEditor :prompt-id="editingPromptId" @back="handleCloseEditor" />
|
||||
@@ -401,6 +410,7 @@ function packageStatusLabel(status: string) {
|
||||
.kol-manage-view {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
height: calc(100vh - 120px);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,14 @@ const profileQuery = useQuery({
|
||||
|
||||
<template>
|
||||
<div class="kol-profile-view">
|
||||
<header class="page-header">
|
||||
<h2 class="page-title">{{ t("kol.profile.title") }}</h2>
|
||||
<p class="page-subtitle">{{ t("kol.profile.subtitle") }}</p>
|
||||
</header>
|
||||
<section class="page-title-card">
|
||||
<div class="page-title-card__header">
|
||||
<div class="page-title-card__copy">
|
||||
<h2>{{ t("kol.profile.title") }}</h2>
|
||||
<p>{{ t("kol.profile.subtitle") }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<a-skeleton v-if="profileQuery.isPending.value" active avatar :paragraph="{ rows: 3 }" />
|
||||
<a-alert
|
||||
@@ -41,20 +45,4 @@ const profileQuery = useQuery({
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
.page-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
.page-title {
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
.page-subtitle {
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
color: #8c8c8c;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user