fix(admin): UX improvements — silent fetch failures, empty states, batch loading guards, dashboard refresh
- Replace console.error-only catches with message.error user-facing notifications
across Bills, Classes, ClassroomRentals, ClassroomSchedule, Classrooms, Deposits,
Expenses, OperationLogs, Permissions, Roles, RoomVisual, Rooms, Students,
Tenants, Users
- Add Empty component via Table locale prop on list pages: Bills, Classes,
ClassroomRentals, Classrooms, Deposits, Expenses (room+personal), Occupancies,
Rooms, Students, Tenants, Roles
- Add batchLoading state to batch delete/update operations: Bills (batchDelete,
batchUpdateStatus), Expenses (batchDeleteRoom, batchDeletePersonal),
Occupancies (batchCheckOut, batchDelete), Rooms (batchDelete),
Students (batchDelete)
- Add refreshLoading indicator to Dashboard header when re-fetching data
- Consistent error pattern: catch (e: unknown) { const err = e as { message?: string }; message.error(...); }
This commit is contained in:
@@ -83,13 +83,19 @@ const DashboardPage: React.FC = () => {
|
||||
const [roomRanking, setRoomRanking] = useState<Array<{ roomNumber: string; total: string }>>([]);
|
||||
const [classroomUtil, setClassroomUtil] = useState<ClassroomUtilStats | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [refreshLoading, setRefreshLoading] = useState(false);
|
||||
const [period, setPeriod] = useState<[string, string]>([
|
||||
dayjs().startOf('month').format('YYYY-MM-DD'),
|
||||
dayjs().endOf('month').format('YYYY-MM-DD'),
|
||||
]);
|
||||
|
||||
const fetchData = useCallback(async () => {
|
||||
setLoading(true);
|
||||
const isRefresh = stats !== null;
|
||||
if (isRefresh) {
|
||||
setRefreshLoading(true);
|
||||
} else {
|
||||
setLoading(true);
|
||||
}
|
||||
try {
|
||||
const [s, rr, cr, g] = await Promise.all([
|
||||
api.get<DashboardStats>('/dashboard/stats'),
|
||||
@@ -114,7 +120,8 @@ const DashboardPage: React.FC = () => {
|
||||
message.error('数据加载失败,请稍后重试');
|
||||
}
|
||||
setLoading(false);
|
||||
}, [period]);
|
||||
setRefreshLoading(false);
|
||||
}, [period, stats]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
@@ -321,7 +328,7 @@ const DashboardPage: React.FC = () => {
|
||||
gap: 12,
|
||||
}}
|
||||
>
|
||||
<h2 style={{ margin: 0 }}>数据面板</h2>
|
||||
<h2 style={{ margin: 0 }}>数据面板{refreshLoading && <Spin size="small" style={{ marginLeft: 12 }} />}</h2>
|
||||
<RangePicker
|
||||
aria-label="选择日期范围"
|
||||
value={[dayjs(period[0]), dayjs(period[1])]}
|
||||
|
||||
Reference in New Issue
Block a user