fix(admin): 仪表盘空数据时显示空状态占位
空库下 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 内边距。
This commit is contained in:
parent
383e6f6b43
commit
16bd644783
@ -12,6 +12,7 @@ use crate::api::comments::get_pending_count;
|
|||||||
use crate::api::posts::{get_post_stats, list_posts};
|
use crate::api::posts::{get_post_stats, list_posts};
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
use crate::api::posts::{PostListResponse, PostStatsResponse};
|
use crate::api::posts::{PostListResponse, PostStatsResponse};
|
||||||
|
use crate::components::empty_state::{EmptyState, EmptyStateAction};
|
||||||
use crate::components::skeletons::atoms::SkeletonBox;
|
use crate::components::skeletons::atoms::SkeletonBox;
|
||||||
use crate::components::ui::{ADMIN_CARD_CLASS, ADMIN_TABLE_CLASS, BTN_SECONDARY};
|
use crate::components::ui::{ADMIN_CARD_CLASS, ADMIN_TABLE_CLASS, BTN_SECONDARY};
|
||||||
use crate::models::post::{PostListItem, PostStats};
|
use crate::models::post::{PostListItem, PostStats};
|
||||||
@ -127,10 +128,24 @@ pub fn Admin() -> Element {
|
|||||||
div { class: "flex items-center justify-between mb-6",
|
div { class: "flex items-center justify-between mb-6",
|
||||||
h2 { class: "text-xl font-bold text-[var(--color-paper-primary)] tracking-tight", "近期文章" }
|
h2 { class: "text-xl font-bold text-[var(--color-paper-primary)] tracking-tight", "近期文章" }
|
||||||
}
|
}
|
||||||
div { class: "{ADMIN_TABLE_CLASS}",
|
|
||||||
match recent_posts() {
|
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) => {
|
Some(posts) => {
|
||||||
rsx! {
|
rsx! {
|
||||||
|
div { class: "{ADMIN_TABLE_CLASS}",
|
||||||
div { class: "divide-y divide-paper-border",
|
div { class: "divide-y divide-paper-border",
|
||||||
for post in posts.iter().take(5) {
|
for post in posts.iter().take(5) {
|
||||||
RecentPostItem { key: "{post.id}", post: post.clone() }
|
RecentPostItem { key: "{post.id}", post: post.clone() }
|
||||||
@ -138,8 +153,11 @@ pub fn Admin() -> Element {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// 加载中:骨架屏。
|
||||||
None => {
|
None => {
|
||||||
rsx! {
|
rsx! {
|
||||||
|
div { class: "{ADMIN_TABLE_CLASS}",
|
||||||
div { class: "divide-y divide-paper-border animate-pulse",
|
div { class: "divide-y divide-paper-border animate-pulse",
|
||||||
for _ in 0..5 {
|
for _ in 0..5 {
|
||||||
div { class: "flex justify-between items-center px-6 py-4",
|
div { class: "flex justify-between items-center px-6 py-4",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user