feat(admin): 后台迁移至 paper-* 主题变量对齐前台
将 /admin 路由下硬编码的 Tailwind gray + hex 配色统一迁移到 input.css 定义的 paper-* 主题变量系统,使后台视觉完全对齐前台: - 底色:bg-white → bg-paper-theme(米白,与前台一致) - 卡片/表格:bg-white dark:bg-[#2e2e33] → bg-paper-entry - 主操作按钮(写文章/保存/分页):bg-gray-900 黑 → bg-paper-accent 鼠尾草绿 - 文字/边框/hover:gray-* + dark:hex → text-paper-*/border-paper-* - 清理 trash 页散落的 #5c7a5e/#7da97f/#e8f0e8 等 hex,路由到变量 - 骨架占位统一复用 ADMIN_* 常量与 SkeletonBox 保留 green/amber/red 状态语义色(通过/待审/删除)与 toggle 白色滑块。 统一采用 bg-paper-* 工具类语法,与 header/post_card 主流写法一致。 dx check + clippy + 402 tests 全通过。
This commit is contained in:
parent
df85df3d2e
commit
519c0ae3a9
@ -79,7 +79,7 @@ pub fn AdminLayout() -> Element {
|
||||
div { class: "flex items-center gap-3",
|
||||
ThemeToggle {}
|
||||
button {
|
||||
class: "text-sm text-gray-600 dark:text-[#9b9c9d] hover:text-gray-900 dark:hover:text-[#dadadb] transition-colors",
|
||||
class: "text-sm text-paper-secondary hover:text-paper-primary transition-colors",
|
||||
onclick: move |_| {
|
||||
spawn(async move {
|
||||
let _ = logout().await;
|
||||
@ -103,9 +103,9 @@ pub fn AdminLayout() -> Element {
|
||||
|
||||
// Write 路由:页面固定高度,不滚动,由编辑器内部处理滚动
|
||||
let root_class = if is_write_route {
|
||||
"h-dvh flex flex-col overflow-hidden bg-white dark:bg-[#1d1e20]"
|
||||
"h-dvh flex flex-col overflow-hidden bg-paper-theme"
|
||||
} else {
|
||||
"min-h-screen flex flex-col bg-white dark:bg-[#1d1e20]"
|
||||
"min-h-screen flex flex-col bg-paper-theme"
|
||||
};
|
||||
|
||||
// 根据校验状态与用户状态渲染真实布局、跳转提示或骨架屏
|
||||
@ -125,7 +125,7 @@ pub fn AdminLayout() -> Element {
|
||||
rsx! {
|
||||
div { class: "{root_class}",
|
||||
div { class: "flex-1 flex items-center justify-center",
|
||||
p { class: "text-gray-600 dark:text-[#9b9c9d]", "未登录,正在跳转..." }
|
||||
p { class: "text-paper-secondary", "未登录,正在跳转..." }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ pub fn AdminDashboardSkeleton() -> Element {
|
||||
// 统计卡片骨架
|
||||
div { class: "grid grid-cols-1 md:grid-cols-3 gap-6",
|
||||
for _ in 0..3 {
|
||||
div { class: "rounded-xl bg-white dark:bg-[#2e2e33] border border-gray-200 dark:border-[#333] p-6 text-center space-y-3",
|
||||
div { class: "rounded-xl bg-paper-entry border border-paper-border p-6 text-center space-y-3",
|
||||
SkeletonBox { class: "h-9 w-16 mx-auto rounded" }
|
||||
SkeletonBox { class: "h-4 w-20 mx-auto rounded" }
|
||||
}
|
||||
@ -35,7 +35,7 @@ pub fn AdminDashboardSkeleton() -> Element {
|
||||
SkeletonBox { class: "h-6 w-24 rounded" }
|
||||
div { class: "space-y-0",
|
||||
for _ in 0..5 {
|
||||
div { class: "flex justify-between items-center py-3 border-b border-gray-100 dark:border-[#333]",
|
||||
div { class: "flex justify-between items-center py-3 border-b border-paper-border",
|
||||
SkeletonBox { class: "h-4 w-[45%] rounded" }
|
||||
SkeletonBox { class: "h-3 w-20 rounded" }
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
use crate::components::skeletons::atoms::SkeletonBox;
|
||||
use crate::components::ui::ADMIN_TABLE_CLASS;
|
||||
|
||||
/// 后台文章管理列表骨架屏组件。
|
||||
///
|
||||
@ -12,10 +13,10 @@ use crate::components::skeletons::atoms::SkeletonBox;
|
||||
#[component]
|
||||
pub fn PostsSkeleton() -> Element {
|
||||
rsx! {
|
||||
div { class: "bg-white dark:bg-[#2e2e33] rounded-xl border border-gray-200 dark:border-[#333] overflow-hidden",
|
||||
div { class: "{ADMIN_TABLE_CLASS}",
|
||||
table { class: "w-full text-sm",
|
||||
thead {
|
||||
tr { class: "border-b border-gray-200 dark:border-[#333]",
|
||||
tr { class: "border-b border-paper-border",
|
||||
th { class: "px-4 py-3", SkeletonBox { class: "h-3 w-10" } }
|
||||
th { class: "px-4 py-3 w-24", SkeletonBox { class: "h-3 w-10 mx-auto" } }
|
||||
th { class: "px-4 py-3 w-32", SkeletonBox { class: "h-3 w-10" } }
|
||||
@ -24,7 +25,7 @@ pub fn PostsSkeleton() -> Element {
|
||||
}
|
||||
tbody {
|
||||
for _ in 0..10 {
|
||||
tr { class: "border-b border-gray-100 dark:border-[#333] last:border-0",
|
||||
tr { class: "border-b border-paper-border last:border-0",
|
||||
td { class: "px-4 py-3", SkeletonBox { class: "h-4 w-1/3" } }
|
||||
td { class: "px-4 py-3", SkeletonBox { class: "h-5 w-14 mx-auto rounded" } }
|
||||
td { class: "px-4 py-3", SkeletonBox { class: "h-4 w-20" } }
|
||||
|
||||
@ -17,18 +17,18 @@ use crate::router::Route;
|
||||
|
||||
/// Admin 卡片容器:白底圆角描边,亮/暗双模式。用于 stat 卡片、面板等。
|
||||
pub const ADMIN_CARD_CLASS: &str =
|
||||
"bg-white dark:bg-[#2e2e33] rounded-xl border border-gray-200 dark:border-[#333]";
|
||||
"bg-paper-entry rounded-xl border border-paper-border";
|
||||
|
||||
/// Admin 表格容器:在卡片基础上加 `overflow-hidden`,圆角裁剪表格。
|
||||
pub const ADMIN_TABLE_CLASS: &str =
|
||||
"bg-white dark:bg-[#2e2e33] rounded-xl border border-gray-200 dark:border-[#333] overflow-hidden";
|
||||
"bg-paper-entry rounded-xl border border-paper-border overflow-hidden";
|
||||
|
||||
/// Admin 表格行 hover 态:底部分割线 + 悬停背景。
|
||||
pub const ADMIN_ROW_HOVER: &str =
|
||||
"border-b border-gray-100 dark:border-[#333] last:border-0 hover:bg-gray-50 dark:hover:bg-[#2a2a2a] transition-colors";
|
||||
"border-b border-paper-border last:border-0 hover:bg-paper-entry transition-colors";
|
||||
|
||||
/// 列表复选框统一样式(全选表头 + 行内)。
|
||||
pub const CHECKBOX_CLASS: &str = "rounded border-gray-300 dark:border-[#555]";
|
||||
pub const CHECKBOX_CLASS: &str = "rounded border-paper-border";
|
||||
|
||||
/// 状态徽章外层:小号圆角胶囊。
|
||||
pub const BADGE_BASE: &str =
|
||||
@ -56,7 +56,7 @@ pub const BTN_TEXT_AMBER: &str = "text-xs text-amber-600 hover:text-amber-800 da
|
||||
pub const BTN_TEXT_RED: &str =
|
||||
"text-xs text-red-500 hover:text-red-700 dark:hover:text-red-300 transition-colors cursor-pointer";
|
||||
/// 主题绿(鼠尾草)文字小按钮(行内恢复)。
|
||||
pub const BTN_TEXT_ACCENT: &str = "text-xs text-[#5c7a5e] hover:text-[#3d5a3f] dark:text-[#7da97f] dark:hover:text-[#9dc79f] transition-colors cursor-pointer";
|
||||
pub const BTN_TEXT_ACCENT: &str = "text-xs text-paper-accent hover:text-paper-primary transition-colors cursor-pointer";
|
||||
|
||||
// ===========================================================================
|
||||
// 组件
|
||||
@ -95,7 +95,7 @@ pub fn Pagination(
|
||||
let is_admin = variant == "admin";
|
||||
let (link_class, link_extra_next) = if is_admin {
|
||||
(
|
||||
"inline-flex items-center px-4 py-2 text-sm text-white bg-gray-900 dark:bg-[#dadadb] dark:text-gray-900 rounded-full hover:opacity-80 transition-opacity cursor-pointer",
|
||||
"inline-flex items-center px-4 py-2 text-sm text-paper-theme bg-paper-accent rounded-full hover:brightness-110 active:scale-[0.98] transition-all duration-200 cursor-pointer",
|
||||
"",
|
||||
)
|
||||
} else {
|
||||
@ -105,7 +105,7 @@ pub fn Pagination(
|
||||
)
|
||||
};
|
||||
let disabled_class =
|
||||
"inline-flex items-center px-4 py-2 text-sm text-gray-400 bg-gray-100 dark:bg-[#2a2a2a] rounded-full cursor-not-allowed";
|
||||
"inline-flex items-center px-4 py-2 text-sm text-paper-secondary bg-paper-tertiary rounded-full cursor-not-allowed";
|
||||
|
||||
// admin 首尾页渲染禁用态;frontend 首尾页直接不渲染。
|
||||
rsx! {
|
||||
@ -126,7 +126,7 @@ pub fn Pagination(
|
||||
|
||||
// admin 显示页码计数。
|
||||
if is_admin {
|
||||
span { class: "text-sm text-gray-500 dark:text-[#9b9c9d] self-center",
|
||||
span { class: "text-sm text-paper-secondary self-center",
|
||||
"{current_page} / {total_pages} 页 (共 {total} {unit})"
|
||||
}
|
||||
}
|
||||
@ -177,7 +177,7 @@ pub fn StatusBadge(color_class: &'static str, label: String) -> Element {
|
||||
pub fn EmptyState(message: &'static str, variant: &'static str) -> Element {
|
||||
let class = match variant {
|
||||
"error" => "text-center text-red-500 dark:text-red-400 py-20",
|
||||
_ => "text-center py-20 text-gray-500 dark:text-[#9b9c9d]",
|
||||
_ => "text-center py-20 text-paper-secondary",
|
||||
};
|
||||
rsx! {
|
||||
div { class: "{class}", "{message}" }
|
||||
|
||||
@ -14,10 +14,12 @@ use crate::api::comments::trash_comment;
|
||||
use crate::api::comments::{approve_comment, batch_update_comment_status, spam_comment};
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use crate::api::comments::{get_all_comments, AllCommentsResponse};
|
||||
use crate::components::skeletons::atoms::SkeletonBox;
|
||||
use crate::components::skeletons::delayed_skeleton::DelayedSkeleton;
|
||||
use crate::components::ui::{
|
||||
EmptyState, Pagination, StatusBadge, ADMIN_ROW_HOVER, ADMIN_TABLE_CLASS, BTN_TEXT_AMBER,
|
||||
BTN_TEXT_GREEN, BTN_TEXT_RED, BTN_SOLID_AMBER, BTN_SOLID_GREEN, BTN_SOLID_RED, CHECKBOX_CLASS,
|
||||
EmptyState, Pagination, StatusBadge, ADMIN_CARD_CLASS, ADMIN_ROW_HOVER, ADMIN_TABLE_CLASS,
|
||||
BTN_TEXT_AMBER, BTN_TEXT_GREEN, BTN_TEXT_RED, BTN_SOLID_AMBER, BTN_SOLID_GREEN, BTN_SOLID_RED,
|
||||
CHECKBOX_CLASS,
|
||||
};
|
||||
use crate::models::comment::{AdminComment, CommentStatus};
|
||||
use crate::router::Route;
|
||||
@ -122,17 +124,17 @@ pub fn AdminCommentsPage(page: i32) -> Element {
|
||||
|
||||
rsx! {
|
||||
div { class: "space-y-6",
|
||||
h1 { class: "text-2xl font-bold text-gray-900 dark:text-[#dadadb]",
|
||||
h1 { class: "text-2xl font-bold text-paper-primary",
|
||||
"评论管理"
|
||||
}
|
||||
|
||||
div { class: "flex gap-1 border-b border-gray-200 dark:border-[#333]",
|
||||
div { class: "flex gap-1 border-b border-paper-border",
|
||||
for (status, label) in [("", "全部"), ("pending", "待审核"), ("approved", "已通过"), ("spam", "垃圾箱")] {
|
||||
button {
|
||||
class: if active_filter() == status {
|
||||
"px-4 py-2 text-sm font-medium border-b-2 border-gray-900 dark:border-[#dadadb] text-gray-900 dark:text-[#dadadb]"
|
||||
"px-4 py-2 text-sm font-medium border-b-2 border-paper-accent text-paper-primary"
|
||||
} else {
|
||||
"px-4 py-2 text-sm font-medium text-gray-500 dark:text-[#9b9c9d] hover:text-gray-700 dark:hover:text-[#dadadb] transition-colors"
|
||||
"px-4 py-2 text-sm font-medium text-paper-secondary hover:text-paper-primary transition-colors"
|
||||
},
|
||||
onclick: move |_| active_filter.set(status.to_string()),
|
||||
"{label}"
|
||||
@ -142,8 +144,8 @@ pub fn AdminCommentsPage(page: i32) -> Element {
|
||||
|
||||
if !selected_ids().is_empty() {
|
||||
{ rsx! {
|
||||
div { class: "flex items-center gap-3 p-3 bg-gray-50 dark:bg-[#2a2a2a] rounded-lg",
|
||||
span { class: "text-sm text-gray-600 dark:text-[#9b9c9d]",
|
||||
div { class: "flex items-center gap-3 p-3 bg-paper-theme rounded-lg",
|
||||
span { class: "text-sm text-paper-secondary",
|
||||
"已选择 {selected_ids().len()} 条"
|
||||
}
|
||||
button {
|
||||
@ -203,13 +205,13 @@ pub fn AdminCommentsPage(page: i32) -> Element {
|
||||
} else if loading() && comments().is_empty() {
|
||||
rsx! {
|
||||
DelayedSkeleton {
|
||||
div { class: "bg-white dark:bg-[#2e2e33] rounded-xl border border-gray-200 dark:border-[#333] p-6 space-y-4",
|
||||
div { class: "{ADMIN_CARD_CLASS} p-6 space-y-4",
|
||||
for _ in 0..5 {
|
||||
div { class: "flex items-center gap-4",
|
||||
div { class: "h-4 w-4 bg-gray-200 dark:bg-[#2a2a2a] rounded" }
|
||||
div { class: "h-8 w-8 bg-gray-200 dark:bg-[#2a2a2a] rounded-full" }
|
||||
div { class: "h-4 w-32 bg-gray-200 dark:bg-[#2a2a2a] rounded" }
|
||||
div { class: "h-4 flex-1 bg-gray-200 dark:bg-[#2a2a2a] rounded" }
|
||||
SkeletonBox { class: "h-4 w-4 rounded" }
|
||||
SkeletonBox { class: "h-8 w-8 rounded-full" }
|
||||
SkeletonBox { class: "h-4 w-32 rounded" }
|
||||
SkeletonBox { class: "h-4 flex-1 rounded" }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -226,7 +228,7 @@ pub fn AdminCommentsPage(page: i32) -> Element {
|
||||
div { class: "overflow-x-auto",
|
||||
table { class: "w-full text-sm",
|
||||
thead {
|
||||
tr { class: "border-b border-gray-200 dark:border-[#333] text-left text-gray-500 dark:text-[#9b9c9d]",
|
||||
tr { class: "border-b border-paper-border text-left text-paper-secondary",
|
||||
th { class: "px-4 py-3 font-medium w-10",
|
||||
input {
|
||||
r#type: "checkbox",
|
||||
@ -372,23 +374,23 @@ fn CommentRow(
|
||||
alt: "{comment.author_name}",
|
||||
}
|
||||
div { class: "min-w-0",
|
||||
div { class: "text-sm font-medium text-gray-900 dark:text-[#dadadb] truncate",
|
||||
div { class: "text-sm font-medium text-paper-primary truncate",
|
||||
"{comment.author_name}"
|
||||
}
|
||||
div { class: "text-xs text-gray-400 dark:text-[#666] truncate",
|
||||
div { class: "text-xs text-paper-secondary truncate",
|
||||
"{comment.author_email}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
td { class: "px-4 py-3 max-w-xs",
|
||||
p { class: "text-sm text-gray-600 dark:text-[#9b9c9d] truncate",
|
||||
p { class: "text-sm text-paper-secondary truncate",
|
||||
"{preview}"
|
||||
}
|
||||
}
|
||||
td { class: "px-4 py-3",
|
||||
Link {
|
||||
class: "text-sm text-gray-700 dark:text-[#dadadb] hover:opacity-80 transition-opacity",
|
||||
class: "text-sm text-paper-primary hover:text-paper-accent transition-colors",
|
||||
to: Route::PostDetail { slug: comment.post_slug.clone() },
|
||||
"{comment.post_title}"
|
||||
}
|
||||
@ -405,7 +407,7 @@ fn CommentRow(
|
||||
label: status_label,
|
||||
}
|
||||
}
|
||||
td { class: "px-4 py-3 text-sm text-gray-500 dark:text-[#9b9c9d]",
|
||||
td { class: "px-4 py-3 text-sm text-paper-secondary",
|
||||
"{date_str}"
|
||||
}
|
||||
td { class: "px-4 py-3 text-right",
|
||||
|
||||
@ -13,6 +13,7 @@ use crate::api::posts::{get_post_stats, list_posts};
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use crate::api::posts::{PostListResponse, PostStatsResponse};
|
||||
use crate::components::ui::ADMIN_CARD_CLASS;
|
||||
use crate::components::skeletons::atoms::SkeletonBox;
|
||||
use crate::models::post::{PostListItem, PostStats};
|
||||
use crate::router::Route;
|
||||
|
||||
@ -70,9 +71,9 @@ pub fn Admin() -> Element {
|
||||
None => {
|
||||
rsx! {
|
||||
for _ in 0..3 {
|
||||
div { class: "rounded-xl bg-white dark:bg-[#2e2e33] border border-gray-200 dark:border-[#333] p-6 text-center space-y-3 animate-pulse",
|
||||
div { class: "h-9 w-16 mx-auto bg-gray-200 dark:bg-[#2a2a2a] rounded" }
|
||||
div { class: "h-4 w-20 mx-auto bg-gray-200 dark:bg-[#2a2a2a] rounded" }
|
||||
div { class: "{ADMIN_CARD_CLASS} p-6 text-center space-y-3 animate-pulse",
|
||||
SkeletonBox { class: "h-9 w-16 mx-auto rounded" }
|
||||
SkeletonBox { class: "h-4 w-20 mx-auto rounded" }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -81,7 +82,7 @@ pub fn Admin() -> Element {
|
||||
}
|
||||
|
||||
Link {
|
||||
class: "block rounded-xl bg-white dark:bg-[#2e2e33] border border-gray-200 dark:border-[#333] p-6 text-center hover:border-gray-300 dark:hover:border-[#555] transition-colors",
|
||||
class: "block {ADMIN_CARD_CLASS} p-6 text-center hover:border-paper-accent transition-colors",
|
||||
to: Route::AdminComments {},
|
||||
match pending_count() {
|
||||
Some(count) => {
|
||||
@ -89,15 +90,15 @@ pub fn Admin() -> Element {
|
||||
div { class: "text-3xl font-bold text-amber-600 dark:text-amber-400",
|
||||
"{count}"
|
||||
}
|
||||
div { class: "text-sm text-gray-500 dark:text-[#9b9c9d] mt-2",
|
||||
div { class: "text-sm text-paper-secondary mt-2",
|
||||
"待审核评论"
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
rsx! {
|
||||
div { class: "h-9 w-16 mx-auto bg-gray-200 dark:bg-[#2a2a2a] rounded animate-pulse" }
|
||||
div { class: "h-4 w-20 mx-auto bg-gray-200 dark:bg-[#2a2a2a] rounded mt-3 animate-pulse" }
|
||||
SkeletonBox { class: "h-9 w-16 mx-auto rounded" }
|
||||
SkeletonBox { class: "h-4 w-20 mx-auto rounded mt-3" }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -105,19 +106,19 @@ pub fn Admin() -> Element {
|
||||
|
||||
div { class: "grid grid-cols-1 md:grid-cols-2 gap-4",
|
||||
Link {
|
||||
class: "bg-gray-900 dark:bg-[#dadadb] text-white dark:text-gray-900 rounded-full px-6 py-3 text-center font-medium hover:opacity-80 transition-opacity cursor-pointer",
|
||||
class: "bg-paper-accent text-paper-theme rounded-full px-6 py-3 text-center font-medium hover:brightness-110 active:scale-[0.98] transition-all duration-200 cursor-pointer",
|
||||
to: Route::Write {},
|
||||
"写文章"
|
||||
}
|
||||
Link {
|
||||
class: "bg-gray-200 dark:bg-[#333] text-gray-700 dark:text-[#dadadb] rounded-full px-6 py-3 text-center font-medium hover:opacity-80 transition-opacity cursor-pointer",
|
||||
class: "bg-paper-tertiary text-paper-primary rounded-full px-6 py-3 text-center font-medium hover:opacity-80 transition-opacity cursor-pointer",
|
||||
to: Route::Posts {},
|
||||
"管理文章"
|
||||
}
|
||||
}
|
||||
|
||||
div { class: "mb-8",
|
||||
h2 { class: "text-xl font-bold text-gray-900 dark:text-[#dadadb] mb-4",
|
||||
h2 { class: "text-xl font-bold text-paper-primary mb-4",
|
||||
"最近文章"
|
||||
}
|
||||
match recent_posts() {
|
||||
@ -134,9 +135,9 @@ pub fn Admin() -> Element {
|
||||
rsx! {
|
||||
div { class: "space-y-4 animate-pulse",
|
||||
for _ in 0..5 {
|
||||
div { class: "flex justify-between items-center py-3 border-b border-gray-100 dark:border-[#333]",
|
||||
div { class: "h-4 w-[45%] bg-gray-200 dark:bg-[#2a2a2a] rounded" }
|
||||
div { class: "h-3 w-20 bg-gray-200 dark:bg-[#2a2a2a] rounded" }
|
||||
div { class: "flex justify-between items-center py-3 border-b border-paper-border",
|
||||
SkeletonBox { class: "h-4 w-[45%] rounded" }
|
||||
SkeletonBox { class: "h-3 w-20 rounded" }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -153,10 +154,10 @@ pub fn Admin() -> Element {
|
||||
fn StatCard(value: String, label: String) -> Element {
|
||||
rsx! {
|
||||
div { class: "{ADMIN_CARD_CLASS} p-6 text-center",
|
||||
div { class: "text-3xl font-bold text-gray-900 dark:text-[#dadadb]",
|
||||
div { class: "text-3xl font-bold text-paper-primary",
|
||||
"{value}"
|
||||
}
|
||||
div { class: "text-sm text-gray-500 dark:text-[#9b9c9d] mt-2",
|
||||
div { class: "text-sm text-paper-secondary mt-2",
|
||||
"{label}"
|
||||
}
|
||||
}
|
||||
@ -171,16 +172,16 @@ fn RecentPostItem(post: PostListItem) -> Element {
|
||||
let status_class = post.status_class();
|
||||
|
||||
rsx! {
|
||||
div { class: "flex justify-between items-center py-3 border-b border-gray-100 dark:border-[#333]",
|
||||
div { class: "flex justify-between items-center py-3 border-b border-paper-border",
|
||||
div { class: "flex items-center gap-3",
|
||||
span { class: "text-gray-700 dark:text-[#dadadb]",
|
||||
span { class: "text-paper-primary",
|
||||
"{post.title}"
|
||||
}
|
||||
span { class: "text-xs {status_class}",
|
||||
"{status_label}"
|
||||
}
|
||||
}
|
||||
span { class: "text-sm text-gray-400 dark:text-[#9b9c9d]",
|
||||
span { class: "text-sm text-paper-secondary",
|
||||
"{date_str}"
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,42 +101,42 @@ pub fn PostsPage(page: i32) -> Element {
|
||||
rsx! {
|
||||
div { class: "space-y-6",
|
||||
div { class: "flex items-center justify-between",
|
||||
h1 { class: "text-2xl font-bold text-gray-900 dark:text-[#dadadb]",
|
||||
h1 { class: "text-2xl font-bold text-paper-primary",
|
||||
"文章管理"
|
||||
}
|
||||
div { class: "flex items-center gap-3",
|
||||
div { class: "group relative",
|
||||
button {
|
||||
class: if rebuilding() {
|
||||
"px-4 py-2 rounded-full text-sm font-medium cursor-not-allowed text-gray-400 dark:text-[#666] border border-gray-300 dark:border-[#444]"
|
||||
"px-4 py-2 rounded-full text-sm font-medium cursor-not-allowed text-paper-secondary border border-paper-border"
|
||||
} else {
|
||||
"px-4 py-2 rounded-full text-sm font-medium cursor-pointer text-gray-700 dark:text-[#b0b0b1] border border-gray-300 dark:border-[#444] hover:border-gray-900 dark:hover:border-[#dadadb] hover:text-gray-900 dark:hover:text-[#dadadb] transition-all"
|
||||
"px-4 py-2 rounded-full text-sm font-medium cursor-pointer text-paper-primary border border-paper-border hover:border-paper-accent hover:text-paper-accent transition-all"
|
||||
},
|
||||
disabled: rebuilding(),
|
||||
onclick: move |_| do_rebuild(false),
|
||||
if rebuilding() { "重建中..." } else { "重建内容" }
|
||||
}
|
||||
div { class: "pointer-events-none absolute top-full left-1/2 -translate-x-1/2 mt-2 px-3 py-1.5 text-xs font-medium whitespace-nowrap rounded-lg opacity-0 group-hover:opacity-100 transition-opacity duration-200 bg-gray-900 dark:bg-[#dadadb] text-white dark:text-[#1a1a1a] shadow-lg z-50",
|
||||
div { class: "pointer-events-none absolute top-full left-1/2 -translate-x-1/2 mt-2 px-3 py-1.5 text-xs font-medium whitespace-nowrap rounded-lg opacity-0 group-hover:opacity-100 transition-opacity duration-200 bg-paper-primary text-paper-theme shadow-lg z-50",
|
||||
"重建 content_html 为空的文章渲染缓存"
|
||||
}
|
||||
}
|
||||
div { class: "group relative",
|
||||
button {
|
||||
class: if rebuilding() {
|
||||
"px-4 py-2 rounded-full text-sm font-medium cursor-not-allowed text-gray-400 dark:text-[#666] border border-gray-300 dark:border-[#444]"
|
||||
"px-4 py-2 rounded-full text-sm font-medium cursor-not-allowed text-paper-secondary border border-paper-border"
|
||||
} else {
|
||||
"px-4 py-2 rounded-full text-sm font-medium cursor-pointer text-gray-700 dark:text-[#b0b0b1] border border-gray-300 dark:border-[#444] hover:border-gray-900 dark:hover:border-[#dadadb] hover:text-gray-900 dark:hover:text-[#dadadb] transition-all"
|
||||
"px-4 py-2 rounded-full text-sm font-medium cursor-pointer text-paper-primary border border-paper-border hover:border-paper-accent hover:text-paper-accent transition-all"
|
||||
},
|
||||
disabled: rebuilding(),
|
||||
onclick: move |_| do_rebuild(true),
|
||||
if rebuilding() { "重建中..." } else { "重建全部" }
|
||||
}
|
||||
div { class: "pointer-events-none absolute top-full left-1/2 -translate-x-1/2 mt-2 px-3 py-1.5 text-xs font-medium whitespace-nowrap rounded-lg opacity-0 group-hover:opacity-100 transition-opacity duration-200 bg-gray-900 dark:bg-[#dadadb] text-white dark:text-[#1a1a1a] shadow-lg z-50",
|
||||
div { class: "pointer-events-none absolute top-full left-1/2 -translate-x-1/2 mt-2 px-3 py-1.5 text-xs font-medium whitespace-nowrap rounded-lg opacity-0 group-hover:opacity-100 transition-opacity duration-200 bg-paper-primary text-paper-theme shadow-lg z-50",
|
||||
"重建所有文章的渲染缓存(含已有内容)"
|
||||
}
|
||||
}
|
||||
Link {
|
||||
class: "px-4 py-2 bg-gray-900 dark:bg-[#dadadb] text-white dark:text-gray-900 rounded-full text-sm font-medium hover:opacity-80 transition-opacity cursor-pointer",
|
||||
class: "px-4 py-2 bg-paper-accent text-paper-theme rounded-full text-sm font-medium hover:brightness-110 active:scale-[0.98] transition-all duration-200 cursor-pointer",
|
||||
to: Route::Write {},
|
||||
"+ 写文章"
|
||||
}
|
||||
@ -144,7 +144,7 @@ pub fn PostsPage(page: i32) -> Element {
|
||||
}
|
||||
|
||||
if let Some(msg) = rebuild_result() {
|
||||
div { class: "text-sm text-gray-600 dark:text-[#9b9c9d] px-1",
|
||||
div { class: "text-sm text-paper-secondary px-1",
|
||||
"{msg}"
|
||||
}
|
||||
}
|
||||
@ -157,7 +157,7 @@ pub fn PostsPage(page: i32) -> Element {
|
||||
div { class: "{ADMIN_TABLE_CLASS}",
|
||||
table { class: "w-full text-sm",
|
||||
thead {
|
||||
tr { class: "border-b border-gray-200 dark:border-[#333] text-left text-gray-500 dark:text-[#9b9c9d]",
|
||||
tr { class: "border-b border-paper-border text-left text-paper-secondary",
|
||||
th { class: "px-4 py-3 font-medium", "标题" }
|
||||
th { class: "px-4 py-3 font-medium w-24 text-center", "状态" }
|
||||
th { class: "px-4 py-3 font-medium w-32", "日期" }
|
||||
@ -222,7 +222,7 @@ fn PostRow(post: PostListItem, deleting: bool, on_delete: EventHandler<i32>) ->
|
||||
tr { class: "{ADMIN_ROW_HOVER}",
|
||||
td { class: "px-4 py-3",
|
||||
Link {
|
||||
class: "text-gray-900 dark:text-[#dadadb] hover:opacity-80 transition-opacity",
|
||||
class: "text-paper-primary hover:text-paper-accent transition-colors cursor-pointer",
|
||||
to: Route::PostDetail { slug: post.slug.clone() },
|
||||
"{post.title}"
|
||||
}
|
||||
@ -233,19 +233,19 @@ fn PostRow(post: PostListItem, deleting: bool, on_delete: EventHandler<i32>) ->
|
||||
label: post.status_label().to_string(),
|
||||
}
|
||||
}
|
||||
td { class: "px-4 py-3 text-gray-500 dark:text-[#9b9c9d]",
|
||||
td { class: "px-4 py-3 text-paper-secondary",
|
||||
"{date_str}"
|
||||
}
|
||||
td { class: "px-4 py-3 text-right",
|
||||
div { class: "flex justify-end gap-3",
|
||||
Link {
|
||||
class: "text-xs text-gray-600 dark:text-[#9b9c9d] hover:text-gray-900 dark:hover:text-[#dadadb] transition-colors cursor-pointer",
|
||||
class: "text-xs text-paper-secondary hover:text-paper-primary transition-colors cursor-pointer",
|
||||
to: Route::WriteEdit { id: post.id },
|
||||
"编辑"
|
||||
}
|
||||
button {
|
||||
class: if deleting {
|
||||
"text-xs text-gray-400 cursor-not-allowed"
|
||||
"text-xs text-paper-secondary cursor-not-allowed"
|
||||
} else {
|
||||
BTN_TEXT_RED
|
||||
},
|
||||
|
||||
@ -18,10 +18,11 @@ use crate::api::posts::{
|
||||
use crate::api::posts::{list_deleted_posts, PostListResponse};
|
||||
#[allow(unused_imports)]
|
||||
use crate::api::settings::{get_trash_settings, update_trash_settings};
|
||||
use crate::components::skeletons::atoms::SkeletonBox;
|
||||
use crate::components::skeletons::delayed_skeleton::DelayedSkeleton;
|
||||
use crate::components::ui::{
|
||||
EmptyState, Pagination, StatusBadge, ADMIN_ROW_HOVER, ADMIN_TABLE_CLASS, BTN_SOLID_GREEN,
|
||||
BTN_SOLID_RED, BTN_TEXT_ACCENT, BTN_TEXT_RED, CHECKBOX_CLASS,
|
||||
EmptyState, Pagination, StatusBadge, ADMIN_CARD_CLASS, ADMIN_ROW_HOVER, ADMIN_TABLE_CLASS,
|
||||
BTN_SOLID_GREEN, BTN_SOLID_RED, BTN_TEXT_ACCENT, BTN_TEXT_RED, CHECKBOX_CLASS,
|
||||
};
|
||||
use crate::models::post::PostListItem;
|
||||
use crate::models::settings::TrashSettings;
|
||||
@ -124,27 +125,27 @@ pub fn TrashPage(page: i32) -> Element {
|
||||
div { class: "space-y-6",
|
||||
// 页面标题
|
||||
div { class: "flex items-center gap-3",
|
||||
h1 { class: "text-2xl font-bold text-gray-900 dark:text-[#dadadb]", "回收站" }
|
||||
span { class: "text-sm text-gray-500 dark:text-[#9b9c9d]",
|
||||
h1 { class: "text-2xl font-bold text-paper-primary", "回收站" }
|
||||
span { class: "text-sm text-paper-secondary",
|
||||
"共 {total()} 篇"
|
||||
}
|
||||
}
|
||||
|
||||
// 自动清理配置卡片:可折叠的设置面板,顶部始终显示当前状态摘要
|
||||
div {
|
||||
class: "rounded-xl border border-gray-200 dark:border-[#333] overflow-hidden bg-white dark:bg-[#2e2e33]",
|
||||
class: "rounded-xl border border-paper-border overflow-hidden bg-paper-entry",
|
||||
// 顶部可点击摘要条:状态指示灯 + 标题 + 展开箭头
|
||||
button {
|
||||
class: "w-full flex items-center gap-3 px-5 py-4 text-left cursor-pointer hover:bg-gray-50 dark:hover:bg-[#34343a] transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[#5c7a5e]/40 dark:focus-visible:ring-[#7da97f]/40",
|
||||
class: "w-full flex items-center gap-3 px-5 py-4 text-left cursor-pointer hover:bg-paper-theme focus:outline-none focus-visible:ring-2 focus-visible:ring-paper-accent/40",
|
||||
onclick: move |_| {
|
||||
settings_panel_open.set(!settings_panel_open());
|
||||
just_saved.set(false);
|
||||
},
|
||||
// 状态指示灯
|
||||
{let dot_class = if settings().auto_purge_enabled {
|
||||
"w-2 h-2 rounded-full bg-[#5c7a5e] dark:bg-[#7da97f] shadow-[0_0_0_3px_rgba(92,122,94,0.15)]"
|
||||
"w-2 h-2 rounded-full bg-paper-accent shadow-[0_0_0_3px_rgba(92,122,94,0.15)]"
|
||||
} else {
|
||||
"w-2 h-2 rounded-full bg-gray-300 dark:bg-[#666]"
|
||||
"w-2 h-2 rounded-full bg-paper-tertiary"
|
||||
};
|
||||
rsx! {
|
||||
div { class: "w-2 flex-shrink-0 flex items-center justify-center",
|
||||
@ -153,10 +154,10 @@ pub fn TrashPage(page: i32) -> Element {
|
||||
}}
|
||||
// 标题 + 当前状态描述
|
||||
div { class: "flex-1 min-w-0",
|
||||
div { class: "text-sm font-medium text-gray-900 dark:text-[#dadadb]",
|
||||
div { class: "text-sm font-medium text-paper-primary",
|
||||
"自动清理"
|
||||
}
|
||||
div { class: "text-xs text-gray-500 dark:text-[#9b9c9d] mt-0.5 truncate",
|
||||
div { class: "text-xs text-paper-secondary mt-0.5 truncate",
|
||||
if settings().auto_purge_enabled {
|
||||
"已开启 · 超过 {settings().retention_days} 天的文章将被自动删除"
|
||||
} else {
|
||||
@ -166,7 +167,7 @@ pub fn TrashPage(page: i32) -> Element {
|
||||
}
|
||||
// 展开箭头(旋转动画)
|
||||
svg {
|
||||
class: "w-4 h-4 text-gray-400 dark:text-[#9b9c9d] transition-transform duration-200 flex-shrink-0 {chevron_rotate}",
|
||||
class: "w-4 h-4 text-paper-secondary transition-transform duration-200 flex-shrink-0 {chevron_rotate}",
|
||||
view_box: "0 0 24 24",
|
||||
fill: "none",
|
||||
stroke: "currentColor",
|
||||
@ -177,15 +178,15 @@ pub fn TrashPage(page: i32) -> Element {
|
||||
|
||||
// 设置面板(可折叠)
|
||||
if settings_panel_open() {
|
||||
div { class: "border-t border-gray-100 dark:border-[#3a3a3e] p-5 space-y-6",
|
||||
div { class: "border-t border-paper-border p-5 space-y-6",
|
||||
// 开关行:启用自动清理
|
||||
div {
|
||||
class: "flex items-center justify-between gap-4",
|
||||
div { class: "min-w-0",
|
||||
div { class: "text-sm font-medium text-gray-900 dark:text-[#dadadb]",
|
||||
div { class: "text-sm font-medium text-paper-primary",
|
||||
"启用自动清理"
|
||||
}
|
||||
div { class: "text-xs text-gray-500 dark:text-[#9b9c9d] mt-1",
|
||||
div { class: "text-xs text-paper-secondary mt-1",
|
||||
"后台任务定期彻底删除超过保留期的文章"
|
||||
}
|
||||
}
|
||||
@ -194,9 +195,9 @@ pub fn TrashPage(page: i32) -> Element {
|
||||
role: "switch",
|
||||
aria_checked: "{settings_draft_enabled()}",
|
||||
class: if settings_draft_enabled() {
|
||||
"relative w-11 h-6 flex-shrink-0 rounded-full bg-[#5c7a5e] dark:bg-[#7da97f] cursor-pointer transition-colors duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-[#5c7a5e]/40 dark:focus-visible:ring-[#7da97f]/40"
|
||||
"relative w-11 h-6 flex-shrink-0 rounded-full bg-paper-accent cursor-pointer transition-colors duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-paper-accent/40"
|
||||
} else {
|
||||
"relative w-11 h-6 flex-shrink-0 rounded-full bg-gray-300 dark:bg-[#555] cursor-pointer transition-colors duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-[#5c7a5e]/40 dark:focus-visible:ring-[#7da97f]/40"
|
||||
"relative w-11 h-6 flex-shrink-0 rounded-full bg-paper-tertiary cursor-pointer transition-colors duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-paper-accent/40"
|
||||
},
|
||||
onclick: move |_| {
|
||||
settings_draft_enabled.set(!settings_draft_enabled());
|
||||
@ -216,19 +217,19 @@ pub fn TrashPage(page: i32) -> Element {
|
||||
// 保留天数行
|
||||
div { class: "space-y-3",
|
||||
div { class: "min-w-0",
|
||||
div { class: "text-sm font-medium text-gray-900 dark:text-[#dadadb]",
|
||||
div { class: "text-sm font-medium text-paper-primary",
|
||||
"保留天数"
|
||||
}
|
||||
div { class: "text-xs text-gray-500 dark:text-[#9b9c9d] mt-1",
|
||||
div { class: "text-xs text-paper-secondary mt-1",
|
||||
"文章删除后保留的时长,到期后自动彻底清除(1–365)"
|
||||
}
|
||||
}
|
||||
// 数字输入 + 步进按钮 + 单位后缀
|
||||
div { class: "flex items-center gap-3",
|
||||
div { class: "flex items-center rounded-lg border border-gray-300 dark:border-[#444] bg-white dark:bg-[#1d1e20] overflow-hidden",
|
||||
div { class: "flex items-center rounded-lg border border-paper-border bg-paper-entry overflow-hidden",
|
||||
// 减号
|
||||
button {
|
||||
class: "w-9 h-9 flex items-center justify-center text-sm text-gray-500 dark:text-[#9b9c9d] hover:text-gray-900 dark:hover:text-[#dadadb] hover:bg-gray-50 dark:hover:bg-[#2a2a2a] cursor-pointer transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[#5c7a5e]/40 dark:focus-visible:ring-[#7da97f]/40",
|
||||
class: "w-9 h-9 flex items-center justify-center text-sm text-paper-secondary hover:text-paper-primary hover:bg-paper-theme cursor-pointer transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-paper-accent/40",
|
||||
r#type: "button",
|
||||
aria_label: "减少保留天数",
|
||||
onclick: move |_| {
|
||||
@ -244,7 +245,7 @@ pub fn TrashPage(page: i32) -> Element {
|
||||
r#type: "number",
|
||||
min: "1",
|
||||
max: "365",
|
||||
class: "w-14 h-9 px-1 text-center text-sm tabular-nums text-gray-900 dark:text-[#dadadb] bg-transparent border-0 focus:outline-none [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none",
|
||||
class: "w-14 h-9 px-1 text-center text-sm tabular-nums text-paper-primary bg-transparent border-0 focus:outline-none [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none",
|
||||
value: "{settings_draft_days()}",
|
||||
oninput: move |e| {
|
||||
settings_draft_days.set(e.value());
|
||||
@ -253,7 +254,7 @@ pub fn TrashPage(page: i32) -> Element {
|
||||
}
|
||||
// 加号
|
||||
button {
|
||||
class: "w-9 h-9 flex items-center justify-center text-sm text-gray-500 dark:text-[#9b9c9d] hover:text-gray-900 dark:hover:text-[#dadadb] hover:bg-gray-50 dark:hover:bg-[#2a2a2a] cursor-pointer transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[#5c7a5e]/40 dark:focus-visible:ring-[#7da97f]/40",
|
||||
class: "w-9 h-9 flex items-center justify-center text-sm text-paper-secondary hover:text-paper-primary hover:bg-paper-theme cursor-pointer transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-paper-accent/40",
|
||||
r#type: "button",
|
||||
aria_label: "增加保留天数",
|
||||
onclick: move |_| {
|
||||
@ -265,7 +266,7 @@ pub fn TrashPage(page: i32) -> Element {
|
||||
"+"
|
||||
}
|
||||
}
|
||||
span { class: "text-xs text-gray-400 dark:text-[#666]", "天" }
|
||||
span { class: "text-xs text-paper-secondary", "天" }
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,14 +274,14 @@ pub fn TrashPage(page: i32) -> Element {
|
||||
div { class: "flex items-center justify-between gap-4 pt-1",
|
||||
// 草稿状态提示
|
||||
if just_saved() {
|
||||
span { class: "inline-flex items-center gap-1.5 text-xs text-[#5c7a5e] dark:text-[#7da97f]",
|
||||
span { class: "inline-flex items-center gap-1.5 text-xs text-paper-accent",
|
||||
svg { class: "w-3.5 h-3.5", view_box: "0 0 24 24", fill: "none", stroke: "currentColor", stroke_width: "2.5",
|
||||
path { stroke_linecap: "round", stroke_linejoin: "round", d: "M5 13l4 4L19 7" }
|
||||
}
|
||||
"已保存"
|
||||
}
|
||||
} else if dirty {
|
||||
span { class: "text-xs text-gray-400 dark:text-[#666]",
|
||||
span { class: "text-xs text-paper-secondary",
|
||||
"有未保存的更改"
|
||||
}
|
||||
} else {
|
||||
@ -289,11 +290,11 @@ pub fn TrashPage(page: i32) -> Element {
|
||||
// 保存按钮:启用主题色,禁用/保存中态灰化
|
||||
button {
|
||||
class: if saving_settings() {
|
||||
"inline-flex items-center gap-1.5 px-4 py-1.5 text-sm font-medium cursor-not-allowed text-gray-400 dark:text-[#666] bg-gray-100 dark:bg-[#2a2a2a] rounded-full"
|
||||
"inline-flex items-center gap-1.5 px-4 py-1.5 text-sm font-medium cursor-not-allowed text-paper-secondary bg-paper-tertiary rounded-full"
|
||||
} else if just_saved() {
|
||||
"inline-flex items-center gap-1.5 px-4 py-1.5 text-sm font-medium cursor-not-allowed text-gray-400 dark:text-[#666] bg-gray-100 dark:bg-[#2a2a2a] rounded-full"
|
||||
"inline-flex items-center gap-1.5 px-4 py-1.5 text-sm font-medium cursor-not-allowed text-paper-secondary bg-paper-tertiary rounded-full"
|
||||
} else {
|
||||
"inline-flex items-center gap-1.5 px-4 py-1.5 text-sm font-medium text-white bg-[#5c7a5e] dark:bg-[#7da97f] dark:text-[#1d1e20] rounded-full hover:brightness-110 active:scale-[0.98] transition-all cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-[#5c7a5e]/40 dark:focus-visible:ring-[#7da97f]/40"
|
||||
"inline-flex items-center gap-1.5 px-4 py-1.5 text-sm font-medium text-paper-theme bg-paper-accent rounded-full hover:brightness-110 active:scale-[0.98] transition-all cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-paper-accent/40"
|
||||
},
|
||||
disabled: saving_settings() || just_saved() || !dirty,
|
||||
onclick: move |_| {
|
||||
@ -317,8 +318,8 @@ pub fn TrashPage(page: i32) -> Element {
|
||||
|
||||
// 批量操作栏(选中时显示)
|
||||
if !selected_ids().is_empty() {
|
||||
div { class: "flex items-center gap-3 p-3 bg-gray-50 dark:bg-[#2a2a2a] rounded-lg",
|
||||
span { class: "text-sm text-gray-600 dark:text-[#9b9c9d]",
|
||||
div { class: "flex items-center gap-3 p-3 bg-paper-theme rounded-lg",
|
||||
span { class: "text-sm text-paper-secondary",
|
||||
"已选择 {selected_ids().len()} 条"
|
||||
}
|
||||
button {
|
||||
@ -363,9 +364,9 @@ pub fn TrashPage(page: i32) -> Element {
|
||||
} else if loading() && posts().is_empty() {
|
||||
rsx! {
|
||||
DelayedSkeleton {
|
||||
div { class: "bg-white dark:bg-[#2e2e33] rounded-xl border border-gray-200 dark:border-[#333] p-6 space-y-4",
|
||||
div { class: "{ADMIN_CARD_CLASS} p-6 space-y-4",
|
||||
for _ in 0..5 {
|
||||
div { class: "h-10 bg-gray-200 dark:bg-[#2a2a2a] rounded" }
|
||||
SkeletonBox { class: "h-10 rounded" }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -381,7 +382,7 @@ pub fn TrashPage(page: i32) -> Element {
|
||||
div { class: "overflow-x-auto",
|
||||
table { class: "w-full text-sm",
|
||||
thead {
|
||||
tr { class: "border-b border-gray-200 dark:border-[#333] text-left text-gray-500 dark:text-[#9b9c9d]",
|
||||
tr { class: "border-b border-paper-border text-left text-paper-secondary",
|
||||
th { class: "px-4 py-3 font-medium w-10",
|
||||
input {
|
||||
r#type: "checkbox",
|
||||
@ -535,9 +536,9 @@ fn TrashRow(
|
||||
let badge_class = if expired {
|
||||
"bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400"
|
||||
} else if remaining <= 7 {
|
||||
"bg-[#e8f0e8] text-[#5c7a5e] dark:bg-[#1e2e1e] dark:text-[#7da97f]"
|
||||
"bg-paper-accent-soft text-paper-accent"
|
||||
} else {
|
||||
"bg-gray-100 text-gray-600 dark:bg-[#333] dark:text-[#9b9c9d]"
|
||||
"bg-paper-tertiary text-paper-secondary"
|
||||
};
|
||||
let badge_text = if expired { "待清理".to_string() } else { format!("{remaining}天") };
|
||||
let deleted_str = post
|
||||
@ -556,7 +557,7 @@ fn TrashRow(
|
||||
}
|
||||
}
|
||||
td { class: "px-4 py-3",
|
||||
div { class: "text-sm font-medium text-gray-900 dark:text-[#dadadb] truncate max-w-xs",
|
||||
div { class: "text-sm font-medium text-paper-primary truncate max-w-xs",
|
||||
"{post.title}"
|
||||
}
|
||||
}
|
||||
@ -566,7 +567,7 @@ fn TrashRow(
|
||||
label: post.status_label().to_string(),
|
||||
}
|
||||
}
|
||||
td { class: "px-4 py-3 text-sm text-gray-500 dark:text-[#9b9c9d]",
|
||||
td { class: "px-4 py-3 text-sm text-paper-secondary",
|
||||
"{deleted_str}"
|
||||
}
|
||||
td { class: "px-4 py-3 text-center",
|
||||
|
||||
@ -423,7 +423,7 @@ fn write_editor(post_id: Option<i32>) -> Element {
|
||||
rsx! {
|
||||
div { class: "relative flex flex-col flex-1 min-h-0 overflow-hidden",
|
||||
if loading() {
|
||||
div { class: "absolute inset-0 z-10 bg-white dark:bg-[#1d1e20]",
|
||||
div { class: "absolute inset-0 z-10 bg-paper-theme",
|
||||
WriteSkeleton {}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user