mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-30 02:23:47 +00:00
refactor: full codebase cleanup, dependency updates, and lint fixes
Phase 0: Remove ~920 lines of dead code (ThemeBentoPicker, PromoDiscountBadge, AdminLayout, SettingsSidebar, MovingGradient, EmptyState, miniapp API, unused types/functions/transitions/skeleton helpers). Fix API barrel file (add 20 missing exports). Phase 1: Add ErrorBoundary (app/page/widget levels), centralize constants, add axios timeout, fix staleTime:0 in React Query. Phase 2: Consolidate hexToHsl, extract email validation, fix duplicate code. Phase 3: Fix auth race condition (await checkAdminStatus), memoize useCurrency, add WebSocket message validation. Phase 4: Extract useBranding, useFeatureFlags, useScrollRestoration from AppShell. Phase 5: Remove all eslint-disable react-hooks/exhaustive-deps (14 total), simplify logger, remove deprecated hooks (useBackButton, useTelegramDnd, useTelegramWebApp). Dependencies: React 19, react-router 7, zustand 5, i18next 25, react-i18next 16, eslint-plugin-react-refresh 0.5. Remove unused @lottiefiles/dotlottie-react. Convert vite manualChunks to function-based approach for react-router v7 compat. Lint: Fix logger.ts no-unused-expressions, fix react-refresh/only-export-components in 6 Radix primitive files (const re-exports → direct re-exports), fix WebSocketProvider exhaustive-deps. Result: 0 errors, 0 warnings. Add CLAUDE.md to .gitignore.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useState, useEffect, useCallback, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
banSystemApi,
|
||||
@@ -206,6 +206,8 @@ export default function AdminBanSystem() {
|
||||
const [report, setReport] = useState<BanReportResponse | null>(null);
|
||||
const [health, setHealth] = useState<BanHealthResponse | null>(null);
|
||||
const [reportHours, setReportHours] = useState(24);
|
||||
const reportHoursRef = useRef(reportHours);
|
||||
reportHoursRef.current = reportHours;
|
||||
const [settingLoading, setSettingLoading] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
@@ -240,19 +242,7 @@ export default function AdminBanSystem() {
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [actionLoading, setActionLoading] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
loadStatus();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (status?.enabled && status?.configured) {
|
||||
loadTabData(activeTab);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [activeTab, status]);
|
||||
|
||||
const loadStatus = async () => {
|
||||
const loadStatus = useCallback(async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const data = await banSystemApi.getStatus();
|
||||
@@ -265,71 +255,84 @@ export default function AdminBanSystem() {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
}, [t]);
|
||||
|
||||
const loadTabData = async (tab: TabType) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
const loadTabData = useCallback(
|
||||
async (tab: TabType) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
switch (tab) {
|
||||
case 'dashboard': {
|
||||
const statsData = await banSystemApi.getStats();
|
||||
setStats(statsData);
|
||||
break;
|
||||
}
|
||||
case 'users': {
|
||||
const usersData = await banSystemApi.getUsers({ limit: 50 });
|
||||
setUsers(usersData);
|
||||
break;
|
||||
}
|
||||
case 'punishments': {
|
||||
const punishmentsData = await banSystemApi.getPunishments();
|
||||
setPunishments(punishmentsData);
|
||||
break;
|
||||
}
|
||||
case 'nodes': {
|
||||
const nodesData = await banSystemApi.getNodes();
|
||||
setNodes(nodesData);
|
||||
break;
|
||||
}
|
||||
case 'agents': {
|
||||
const agentsData = await banSystemApi.getAgents();
|
||||
setAgents(agentsData);
|
||||
break;
|
||||
}
|
||||
case 'violations': {
|
||||
const violationsData = await banSystemApi.getTrafficViolations();
|
||||
setViolations(violationsData);
|
||||
break;
|
||||
}
|
||||
case 'settings': {
|
||||
const settingsData = await banSystemApi.getSettings();
|
||||
setSettings(settingsData);
|
||||
break;
|
||||
}
|
||||
case 'traffic': {
|
||||
const trafficData = await banSystemApi.getTraffic();
|
||||
setTraffic(trafficData);
|
||||
break;
|
||||
}
|
||||
case 'reports': {
|
||||
const reportData = await banSystemApi.getReport(reportHours);
|
||||
setReport(reportData);
|
||||
break;
|
||||
}
|
||||
case 'health': {
|
||||
const healthData = await banSystemApi.getHealth();
|
||||
setHealth(healthData);
|
||||
break;
|
||||
switch (tab) {
|
||||
case 'dashboard': {
|
||||
const statsData = await banSystemApi.getStats();
|
||||
setStats(statsData);
|
||||
break;
|
||||
}
|
||||
case 'users': {
|
||||
const usersData = await banSystemApi.getUsers({ limit: 50 });
|
||||
setUsers(usersData);
|
||||
break;
|
||||
}
|
||||
case 'punishments': {
|
||||
const punishmentsData = await banSystemApi.getPunishments();
|
||||
setPunishments(punishmentsData);
|
||||
break;
|
||||
}
|
||||
case 'nodes': {
|
||||
const nodesData = await banSystemApi.getNodes();
|
||||
setNodes(nodesData);
|
||||
break;
|
||||
}
|
||||
case 'agents': {
|
||||
const agentsData = await banSystemApi.getAgents();
|
||||
setAgents(agentsData);
|
||||
break;
|
||||
}
|
||||
case 'violations': {
|
||||
const violationsData = await banSystemApi.getTrafficViolations();
|
||||
setViolations(violationsData);
|
||||
break;
|
||||
}
|
||||
case 'settings': {
|
||||
const settingsData = await banSystemApi.getSettings();
|
||||
setSettings(settingsData);
|
||||
break;
|
||||
}
|
||||
case 'traffic': {
|
||||
const trafficData = await banSystemApi.getTraffic();
|
||||
setTraffic(trafficData);
|
||||
break;
|
||||
}
|
||||
case 'reports': {
|
||||
const reportData = await banSystemApi.getReport(reportHoursRef.current);
|
||||
setReport(reportData);
|
||||
break;
|
||||
}
|
||||
case 'health': {
|
||||
const healthData = await banSystemApi.getHealth();
|
||||
setHealth(healthData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
setError(t('banSystem.loadError'));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
} catch {
|
||||
setError(t('banSystem.loadError'));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
},
|
||||
[t],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
loadStatus();
|
||||
}, [loadStatus]);
|
||||
|
||||
useEffect(() => {
|
||||
if (status?.enabled && status?.configured) {
|
||||
loadTabData(activeTab);
|
||||
}
|
||||
};
|
||||
}, [activeTab, status, loadTabData]);
|
||||
|
||||
const handleSearch = async () => {
|
||||
if (!searchQuery.trim()) {
|
||||
@@ -403,8 +406,7 @@ export default function AdminBanSystem() {
|
||||
if (activeTab === 'reports' && status?.enabled) {
|
||||
loadTabData('reports');
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [reportHours]);
|
||||
}, [reportHours, activeTab, status, loadTabData]);
|
||||
|
||||
const formatBytes = (bytes: number) => {
|
||||
if (bytes === 0) return '0 B';
|
||||
|
||||
Reference in New Issue
Block a user