fix(admin): 后台列表切换保留当前内容,去掉加载占位

用户档案、用户列表、内容筛选与公告页等数据到达后再换视图,避免滚动条闪动。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-17 00:57:54 +08:00
parent a0a9aeed66
commit 442af625f6
7 changed files with 213 additions and 100 deletions

View File

@@ -1,6 +1,6 @@
"use client";
import { useCallback, useEffect, useState } from "react";
import { useCallback, useState } from "react";
import {
Plus,
Pencil,
@@ -51,32 +51,30 @@ const EMPTY_FORM: FormState = {
published: true,
};
export default function AnnouncementAdmin() {
const [list, setList] = useState<Announcement[]>([]);
const [loading, setLoading] = useState(true);
const [loadError, setLoadError] = useState("");
export default function AnnouncementAdmin({
initial,
initError,
}: {
initial: Announcement[];
initError: string;
}) {
const [list, setList] = useState(initial);
const [loadError, setLoadError] = useState(initError);
const [form, setForm] = useState<FormState | null>(null);
const [saving, setSaving] = useState(false);
const [deletingId, setDeletingId] = useState<number | null>(null);
const [deleteTarget, setDeleteTarget] = useState<Announcement | null>(null);
const load = useCallback(async () => {
setLoading(true);
try {
const res = await apiAdminListAnnouncements();
setList(res.announcements);
setLoadError("");
} catch (e) {
setLoadError(e instanceof Error ? e.message : "加载公告失败");
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
load();
}, [load]);
const startCreate = () => setForm({ ...EMPTY_FORM });
const startEdit = (a: Announcement) =>
setForm({
@@ -263,11 +261,7 @@ export default function AnnouncementAdmin() {
<span className="meta text-[12px] tabular-nums">共 {list.length} 条</span>
</div>
{loading ? (
<div className="flex items-center justify-center gap-2 py-16 meta text-[13px]">
<Loader2 size={16} className="animate-spin" /> 加载中…
</div>
) : loadError ? (
{loadError ? (
<p className="alert-error m-4">{loadError}</p>
) : list.length === 0 ? (
<AdminEmpty