From 16bd644783feef1563725be7c583384c3cfe8e66 Mon Sep 17 00:00:00 2001 From: xfy Date: Sat, 4 Jul 2026 22:49:25 +0800 Subject: [PATCH] =?UTF-8?q?fix(admin):=20=E4=BB=AA=E8=A1=A8=E7=9B=98?= =?UTF-8?q?=E7=A9=BA=E6=95=B0=E6=8D=AE=E6=97=B6=E6=98=BE=E7=A4=BA=E7=A9=BA?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E5=8D=A0=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 空库下 get_post_stats / list_posts 正常返回,但 list_posts 返回 Some([]) 时走有数据分支、循环 0 次,渲染出一个空表格容器,视觉 上仪表盘近期文章区域一片空白,没有空状态引导。 复用项目既有的 empty_state::EmptyState 约定(与 posts.rs / trash.rs / comments.rs 列表页一致):Some(posts) 且 posts.is_empty() 时渲染 暂无文章插画 + 写文章CTA。空状态放在 ADMIN_TABLE_CLASS 容器 之外,避免 overflow-hidden 裁掉插画的 py-20 内边距。 --- src/pages/admin/dashboard.rs | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/pages/admin/dashboard.rs b/src/pages/admin/dashboard.rs index bf5c9ec..a59341a 100644 --- a/src/pages/admin/dashboard.rs +++ b/src/pages/admin/dashboard.rs @@ -12,6 +12,7 @@ use crate::api::comments::get_pending_count; use crate::api::posts::{get_post_stats, list_posts}; #[cfg(target_arch = "wasm32")] use crate::api::posts::{PostListResponse, PostStatsResponse}; +use crate::components::empty_state::{EmptyState, EmptyStateAction}; use crate::components::skeletons::atoms::SkeletonBox; use crate::components::ui::{ADMIN_CARD_CLASS, ADMIN_TABLE_CLASS, BTN_SECONDARY}; use crate::models::post::{PostListItem, PostStats}; @@ -127,10 +128,24 @@ pub fn Admin() -> Element { div { class: "flex items-center justify-between mb-6", h2 { class: "text-xl font-bold text-[var(--color-paper-primary)] tracking-tight", "近期文章" } } - div { class: "{ADMIN_TABLE_CLASS}", - match recent_posts() { - Some(posts) => { - rsx! { + match recent_posts() { + // 空库 / 无文章:展示空状态占位(与 posts.rs 列表页一致)。 + // 放在 ADMIN_TABLE_CLASS 容器之外,避免 overflow-hidden 裁掉插画的 py-20 内边距。 + Some(posts) if posts.is_empty() => { + rsx! { + EmptyState { + title: "暂无文章", + description: "还没有创建任何文章,开始写下你的第一篇文字吧。", + action: Some(EmptyStateAction { + label: "写文章".to_string(), + to: Route::Write {}, + }), + } + } + } + Some(posts) => { + rsx! { + div { class: "{ADMIN_TABLE_CLASS}", div { class: "divide-y divide-paper-border", for post in posts.iter().take(5) { RecentPostItem { key: "{post.id}", post: post.clone() } @@ -138,8 +153,11 @@ pub fn Admin() -> Element { } } } - None => { - rsx! { + } + // 加载中:骨架屏。 + None => { + rsx! { + div { class: "{ADMIN_TABLE_CLASS}", div { class: "divide-y divide-paper-border animate-pulse", for _ in 0..5 { div { class: "flex justify-between items-center px-6 py-4",