优化仪表板页面,移除冗余组件,简化代码结构

This commit is contained in:
ryan
2026-03-14 16:17:43 +08:00
parent ee104f0ad8
commit 590e1d7a8a
11 changed files with 150 additions and 188 deletions
-5
View File
@@ -1,13 +1,8 @@
import { DashboardOverview } from '@/features/dashboard/components/dashboard-overview'; import { DashboardOverview } from '@/features/dashboard/components/dashboard-overview';
import { PageHeader } from '@/components/layout/page-header';
export default function DashboardPage() { export default function DashboardPage() {
return ( return (
<div className='space-y-6'> <div className='space-y-6'>
<PageHeader
title='ATSFlare 管理端'
description='集中展示系统核心数据概览,快速导航至各功能模块进行管理和配置。'
/>
<DashboardOverview /> <DashboardOverview />
</div> </div>
); );
@@ -235,7 +235,6 @@ export function DashboardOverview() {
return ( return (
<div className="space-y-6"> <div className="space-y-6">
<WorldStage <WorldStage
generatedAt={overview.generated_at}
summary={overview.summary} summary={overview.summary}
traffic={overview.traffic} traffic={overview.traffic}
capacity={overview.capacity} capacity={overview.capacity}
@@ -13,7 +13,6 @@ import type {
DistributionItem, DistributionItem,
} from '@/features/dashboard/types'; } from '@/features/dashboard/types';
import { cn } from '@/lib/utils/cn'; import { cn } from '@/lib/utils/cn';
import { formatDateTime } from '@/lib/utils/date';
type Tone = 'healthy' | 'warning' | 'danger'; type Tone = 'healthy' | 'warning' | 'danger';
@@ -157,14 +156,12 @@ function CountrySignal({
} }
export function WorldStage({ export function WorldStage({
generatedAt,
summary, summary,
traffic, traffic,
capacity, capacity,
nodes, nodes,
sourceCountries, sourceCountries,
}: { }: {
generatedAt: string;
summary: DashboardSummary; summary: DashboardSummary;
traffic: DashboardTraffic; traffic: DashboardTraffic;
capacity: DashboardCapacity; capacity: DashboardCapacity;
@@ -236,7 +233,6 @@ export function WorldStage({
)} )}
> >
<div className="flex flex-col gap-4 xl:flex-row xl:items-end xl:justify-between"> <div className="flex flex-col gap-4 xl:flex-row xl:items-end xl:justify-between">
<div className="space-y-2">
<p <p
className={cn( className={cn(
'text-[11px] tracking-[0.34em] uppercase', 'text-[11px] tracking-[0.34em] uppercase',
@@ -245,34 +241,6 @@ export function WorldStage({
> >
Global Stage Global Stage
</p> </p>
<h2
className={cn(
'text-2xl font-semibold',
isDark ? 'text-white' : 'text-slate-950',
)}
>
全球态势板
</h2>
<p
className={cn(
'max-w-3xl text-sm leading-6',
isDark ? 'text-slate-300' : 'text-slate-600',
)}
>
在同一视图汇总节点在线率、运行状态、资源负载与全球流量来源,
让首屏可以直接承担值守与研判入口。
</p>
</div>
<div
className={cn(
'rounded-full border px-4 py-2 text-sm backdrop-blur',
isDark
? 'border-white/10 bg-white/6 text-slate-200'
: 'border-slate-200/80 bg-white/80 text-slate-700',
)}
>
数据生成于 {formatDateTime(generatedAt)}
</div>
</div> </div>
</div> </div>
@@ -320,7 +320,7 @@ export function NodeDetailPage({ nodeId }: { nodeId: string }) {
const saveMutation = useMutation({ const saveMutation = useMutation({
mutationFn: async (payload: Parameters<typeof updateNode>[1]) => mutationFn: async (payload: Parameters<typeof updateNode>[1]) =>
updateNode(Number(nodeId), payload), updateNode(Number(nodeId), payload),
onSuccess: async (updatedNode) => { onSuccess: async () => {
setFeedback({ tone: 'success', message: '节点已更新。' }); setFeedback({ tone: 'success', message: '节点已更新。' });
setIsEditorOpen(false); setIsEditorOpen(false);
await queryClient.invalidateQueries({ queryKey: nodesQueryKey }); await queryClient.invalidateQueries({ queryKey: nodesQueryKey });
@@ -161,13 +161,6 @@ function isCacheLevelsValue(value: string) {
return /^\d{1,2}(?::\d{1,2}){0,2}$/.test(value.trim()); return /^\d{1,2}(?::\d{1,2}){0,2}$/.test(value.trim());
} }
function extractMainConfigLines(content: string, matcher: RegExp) {
return content
.split('\n')
.map((line) => line.trim())
.filter((line) => line && matcher.test(line));
}
export function PerformancePage() { export function PerformancePage() {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const {user} = useAuth(); const {user} = useAuth();
@@ -595,15 +588,6 @@ export function PerformancePage() {
); );
} }
const cachePreviewLines = extractMainConfigLines(
preview.main_config,
/proxy_cache_path|proxy_cache_key|proxy_cache_lock(?:_timeout)?|proxy_cache_use_stale/,
);
const gzipPreviewLines = extractMainConfigLines(
preview.main_config,
/gzip(?:_| )/,
);
return ( return (
<div className="space-y-6"> <div className="space-y-6">
<PageHeader <PageHeader
@@ -196,6 +196,7 @@ export function TlsCertificatesPage() {
</AppCard> </AppCard>
</div> </div>
{isImportOpen ? (
<CertificateImportModal <CertificateImportModal
isOpen={isImportOpen} isOpen={isImportOpen}
onClose={() => setIsImportOpen(false)} onClose={() => setIsImportOpen(false)}
@@ -206,7 +207,9 @@ export function TlsCertificatesPage() {
}); });
}} }}
/> />
) : null}
{isDetailOpen ? (
<CertificateDetailModal <CertificateDetailModal
certificateId={selectedCertificateId} certificateId={selectedCertificateId}
isOpen={isDetailOpen} isOpen={isDetailOpen}
@@ -226,7 +229,9 @@ export function TlsCertificatesPage() {
}} }}
deleting={deleteCertificateMutation.isPending} deleting={deleteCertificateMutation.isPending}
/> />
) : null}
{isEditorOpen ? (
<CertificateEditorModal <CertificateEditorModal
certificateId={selectedCertificateId} certificateId={selectedCertificateId}
isOpen={isEditorOpen} isOpen={isEditorOpen}
@@ -238,6 +243,7 @@ export function TlsCertificatesPage() {
}); });
}} }}
/> />
) : null}
</> </>
); );
} }
@@ -434,6 +434,7 @@ export function WebsiteDetailPage({websiteId}: { websiteId: string }) {
</AppCard> </AppCard>
</div> </div>
{isEditorOpen ? (
<WebsiteEditorModal <WebsiteEditorModal
isOpen={isEditorOpen} isOpen={isEditorOpen}
onClose={() => { onClose={() => {
@@ -450,7 +451,9 @@ export function WebsiteDetailPage({websiteId}: { websiteId: string }) {
setFeedback({tone: 'success', message: '网站已更新。'}); setFeedback({tone: 'success', message: '网站已更新。'});
}} }}
/> />
) : null}
{isCertificateImportOpen ? (
<CertificateImportModal <CertificateImportModal
isOpen={isCertificateImportOpen} isOpen={isCertificateImportOpen}
onClose={() => setIsCertificateImportOpen(false)} onClose={() => setIsCertificateImportOpen(false)}
@@ -463,7 +466,9 @@ export function WebsiteDetailPage({websiteId}: { websiteId: string }) {
setIsEditorOpen(true); setIsEditorOpen(true);
}} }}
/> />
) : null}
{isCertificateDetailOpen ? (
<CertificateDetailModal <CertificateDetailModal
certificateId={certificate?.id ?? null} certificateId={certificate?.id ?? null}
isOpen={isCertificateDetailOpen} isOpen={isCertificateDetailOpen}
@@ -478,7 +483,9 @@ export function WebsiteDetailPage({websiteId}: { websiteId: string }) {
}} }}
deleting={deleteCertificateMutation.isPending} deleting={deleteCertificateMutation.isPending}
/> />
) : null}
{isCertificateEditorOpen ? (
<CertificateEditorModal <CertificateEditorModal
certificateId={certificate?.id ?? null} certificateId={certificate?.id ?? null}
isOpen={isCertificateEditorOpen} isOpen={isCertificateEditorOpen}
@@ -490,6 +497,7 @@ export function WebsiteDetailPage({websiteId}: { websiteId: string }) {
}); });
}} }}
/> />
) : null}
</> </>
); );
} }
@@ -114,7 +114,7 @@ export function WebsiteEditorModal({
? toManagedDomainFormValues(initialDomain) ? toManagedDomainFormValues(initialDomain)
: defaultManagedDomainValues, : defaultManagedDomainValues,
); );
}, [form, initialDomain, isOpen]); }, [form, initialDomain, isOpen, saveMutation]);
useEffect(() => { useEffect(() => {
if (!isOpen || !preferredCertificateId) { if (!isOpen || !preferredCertificateId) {
@@ -28,7 +28,6 @@ import {
DangerButton, DangerButton,
PrimaryButton, PrimaryButton,
} from '@/features/shared/components/resource-primitives'; } from '@/features/shared/components/resource-primitives';
import { formatDateTime } from '@/lib/utils/date';
type FeedbackState = { type FeedbackState = {
tone: 'info' | 'success' | 'danger'; tone: 'info' | 'success' | 'danger';
@@ -205,6 +204,7 @@ export function WebsitesPage() {
</AppCard> </AppCard>
</div> </div>
{isWebsiteModalOpen ? (
<WebsiteEditorModal <WebsiteEditorModal
isOpen={isWebsiteModalOpen} isOpen={isWebsiteModalOpen}
onClose={() => { onClose={() => {
@@ -223,7 +223,9 @@ export function WebsitesPage() {
}); });
}} }}
/> />
) : null}
{isCertificateImportOpen ? (
<CertificateImportModal <CertificateImportModal
isOpen={isCertificateImportOpen} isOpen={isCertificateImportOpen}
onClose={() => setIsCertificateImportOpen(false)} onClose={() => setIsCertificateImportOpen(false)}
@@ -235,6 +237,7 @@ export function WebsitesPage() {
}); });
}} }}
/> />
) : null}
</> </>
); );
} }
@@ -2,7 +2,6 @@ import type {
ManagedDomainItem, ManagedDomainItem,
ManagedDomainMutationPayload, ManagedDomainMutationPayload,
} from '@/features/managed-domains/types'; } from '@/features/managed-domains/types';
import type { ProxyRouteItem } from '@/features/proxy-routes/types';
import type { import type {
TlsCertificateFileImportPayload, TlsCertificateFileImportPayload,
TlsCertificateItem, TlsCertificateItem,