Implement Phase 2 improvements

This commit is contained in:
gpt-engineer-app[bot]
2025-10-15 12:09:23 +00:00
parent cdd6b0bbd5
commit c3533d0a82
5 changed files with 381 additions and 33 deletions

View File

@@ -121,15 +121,15 @@ export const ReportsQueue = forwardRef<ReportsQueueRef>((props, ref) => {
const [totalCount, setTotalCount] = useState(0);
const totalPages = Math.ceil(totalCount / pageSize);
// Sort state
// Sort state with error handling
const [sortConfig, setSortConfig] = useState<ReportSortConfig>(() => {
const saved = localStorage.getItem('reportsQueue_sortConfig');
if (saved) {
try {
try {
const saved = localStorage.getItem('reportsQueue_sortConfig');
if (saved) {
return JSON.parse(saved);
} catch {
return { field: 'created_at', direction: 'asc' as ReportSortDirection };
}
} catch (error) {
console.warn('Failed to load sort config from localStorage:', error);
}
return { field: 'created_at', direction: 'asc' as ReportSortDirection };
});
@@ -149,9 +149,13 @@ export const ReportsQueue = forwardRef<ReportsQueueRef>((props, ref) => {
refresh: () => fetchReports(false) // Manual refresh shows loading
}), []);
// Persist sort configuration
// Persist sort configuration with error handling
useEffect(() => {
localStorage.setItem('reportsQueue_sortConfig', JSON.stringify(sortConfig));
try {
localStorage.setItem('reportsQueue_sortConfig', JSON.stringify(sortConfig));
} catch (error) {
console.warn('Failed to save sort config to localStorage:', error);
}
}, [sortConfig]);
const fetchReports = async (silent = false) => {

View File

@@ -8,10 +8,7 @@ import { useAdminSettings } from '@/hooks/useAdminSettings';
import { useModerationStats } from '@/hooks/useModerationStats';
export default function AdminReports() {
const { user, loading: authLoading } = useAuth();
const { isModerator, loading: roleLoading } = useUserRole();
const { needsEnrollment, loading: mfaLoading } = useRequireMFA();
const navigate = useNavigate();
const { isLoading, isAuthorized, needsMFA } = useAdminGuard();
const reportsQueueRef = useRef<ReportsQueueRef>(null);
const {
@@ -22,8 +19,8 @@ export default function AdminReports() {
const refreshMode = getAdminPanelRefreshMode();
const pollInterval = getAdminPanelPollInterval();
const { refresh: refreshStats, lastUpdated } = useModerationStats({
enabled: !!user && !authLoading && !roleLoading && isModerator(),
const { lastUpdated, refresh: refreshStats } = useModerationStats({
enabled: isAuthorized,
pollingEnabled: refreshMode === 'auto',
pollingInterval: pollInterval,
});
@@ -33,21 +30,7 @@ export default function AdminReports() {
refreshStats();
}, [refreshStats]);
useEffect(() => {
if (!authLoading && !roleLoading) {
if (!user) {
navigate('/auth');
return;
}
if (!isModerator()) {
navigate('/');
return;
}
}
}, [user, authLoading, roleLoading, navigate, isModerator]);
if (authLoading || roleLoading || mfaLoading) {
if (isLoading) {
return (
<AdminLayout
onRefresh={handleRefresh}

View File

@@ -1,7 +1,5 @@
import { useEffect, Component, ReactNode } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '@/hooks/useAuth';
import { useUserRole } from '@/hooks/useUserRole';
import { Component, ReactNode } from 'react';
import { useAdminGuard } from '@/hooks/useAdminGuard';
import { AdminLayout } from '@/components/layout/AdminLayout';
import { SystemActivityLog } from '@/components/admin/SystemActivityLog';
import { Skeleton } from '@/components/ui/skeleton';