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

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 { PageHeader } from '@/components/layout/page-header';
export default function DashboardPage() {
return (
<div className='space-y-6'>
<PageHeader
title='ATSFlare 管理端'
description='集中展示系统核心数据概览,快速导航至各功能模块进行管理和配置。'
/>
<DashboardOverview />
</div>
);
+4 -4
View File
@@ -20,8 +20,8 @@ interface RootLayoutProps {
children: ReactNode;
}
export default function RootLayout({ children }: RootLayoutProps) {
return (
export default function RootLayout({ children }: RootLayoutProps) {
return (
<html lang='zh-CN' suppressHydrationWarning>
<body>
<Script id='theme-init' strategy='beforeInteractive'>
@@ -30,5 +30,5 @@ export default function RootLayout({ children }: RootLayoutProps) {
<AppProviders>{children}</AppProviders>
</body>
</html>
);
}
);
}
@@ -235,7 +235,6 @@ export function DashboardOverview() {
return (
<div className="space-y-6">
<WorldStage
generatedAt={overview.generated_at}
summary={overview.summary}
traffic={overview.traffic}
capacity={overview.capacity}
@@ -13,7 +13,6 @@ import type {
DistributionItem,
} from '@/features/dashboard/types';
import { cn } from '@/lib/utils/cn';
import { formatDateTime } from '@/lib/utils/date';
type Tone = 'healthy' | 'warning' | 'danger';
@@ -157,14 +156,12 @@ function CountrySignal({
}
export function WorldStage({
generatedAt,
summary,
traffic,
capacity,
nodes,
sourceCountries,
}: {
generatedAt: string;
summary: DashboardSummary;
traffic: DashboardTraffic;
capacity: DashboardCapacity;
@@ -236,43 +233,14 @@ export function WorldStage({
)}
>
<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(
'text-[11px] tracking-[0.34em] uppercase',
isDark ? 'text-sky-200/80' : 'text-sky-700/80',
'text-[11px] tracking-[0.34em] uppercase',
isDark ? 'text-sky-200/80' : 'text-sky-700/80',
)}
>
Global Stage
</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>
Global Stage
</p>
</div>
</div>
@@ -320,7 +320,7 @@ export function NodeDetailPage({ nodeId }: { nodeId: string }) {
const saveMutation = useMutation({
mutationFn: async (payload: Parameters<typeof updateNode>[1]) =>
updateNode(Number(nodeId), payload),
onSuccess: async (updatedNode) => {
onSuccess: async () => {
setFeedback({ tone: 'success', message: '节点已更新。' });
setIsEditorOpen(false);
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());
}
function extractMainConfigLines(content: string, matcher: RegExp) {
return content
.split('\n')
.map((line) => line.trim())
.filter((line) => line && matcher.test(line));
}
export function PerformancePage() {
const queryClient = useQueryClient();
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 (
<div className="space-y-6">
<PageHeader
@@ -196,48 +196,54 @@ export function TlsCertificatesPage() {
</AppCard>
</div>
<CertificateImportModal
isOpen={isImportOpen}
onClose={() => setIsImportOpen(false)}
onImported={(certificate) => {
setFeedback({
tone: 'success',
message: `证书 ${certificate.name} 已导入。`,
});
}}
/>
{isImportOpen ? (
<CertificateImportModal
isOpen={isImportOpen}
onClose={() => setIsImportOpen(false)}
onImported={(certificate) => {
setFeedback({
tone: 'success',
message: `证书 ${certificate.name} 已导入。`,
});
}}
/>
) : null}
<CertificateDetailModal
certificateId={selectedCertificateId}
isOpen={isDetailOpen}
onClose={() => setIsDetailOpen(false)}
onEdit={() => {
setIsDetailOpen(false);
setIsEditorOpen(true);
}}
onDelete={() => {
const certificate = certificates.find(
(item) => item.id === selectedCertificateId,
);
if (certificate) {
{isDetailOpen ? (
<CertificateDetailModal
certificateId={selectedCertificateId}
isOpen={isDetailOpen}
onClose={() => setIsDetailOpen(false)}
onEdit={() => {
setIsDetailOpen(false);
handleDeleteCertificate(certificate);
}
}}
deleting={deleteCertificateMutation.isPending}
/>
setIsEditorOpen(true);
}}
onDelete={() => {
const certificate = certificates.find(
(item) => item.id === selectedCertificateId,
);
if (certificate) {
setIsDetailOpen(false);
handleDeleteCertificate(certificate);
}
}}
deleting={deleteCertificateMutation.isPending}
/>
) : null}
<CertificateEditorModal
certificateId={selectedCertificateId}
isOpen={isEditorOpen}
onClose={() => setIsEditorOpen(false)}
onSaved={(certificate) => {
setFeedback({
tone: 'success',
message: `证书 ${certificate.name} 已更新。`,
});
}}
/>
{isEditorOpen ? (
<CertificateEditorModal
certificateId={selectedCertificateId}
isOpen={isEditorOpen}
onClose={() => setIsEditorOpen(false)}
onSaved={(certificate) => {
setFeedback({
tone: 'success',
message: `证书 ${certificate.name} 已更新。`,
});
}}
/>
) : null}
</>
);
}
@@ -434,62 +434,70 @@ export function WebsiteDetailPage({websiteId}: { websiteId: string }) {
</AppCard>
</div>
<WebsiteEditorModal
isOpen={isEditorOpen}
onClose={() => {
setIsEditorOpen(false);
setPreferredCertificateId(null);
}}
initialDomain={website}
certificates={certificates}
certificatesLoading={certificatesQuery.isLoading}
preferredCertificateId={preferredCertificateId}
onRequestImportCertificate={() => setIsCertificateImportOpen(true)}
onSaved={() => {
setPreferredCertificateId(null);
setFeedback({tone: 'success', message: '网站已更新。'});
}}
/>
{isEditorOpen ? (
<WebsiteEditorModal
isOpen={isEditorOpen}
onClose={() => {
setIsEditorOpen(false);
setPreferredCertificateId(null);
}}
initialDomain={website}
certificates={certificates}
certificatesLoading={certificatesQuery.isLoading}
preferredCertificateId={preferredCertificateId}
onRequestImportCertificate={() => setIsCertificateImportOpen(true)}
onSaved={() => {
setPreferredCertificateId(null);
setFeedback({tone: 'success', message: '网站已更新。'});
}}
/>
) : null}
<CertificateImportModal
isOpen={isCertificateImportOpen}
onClose={() => setIsCertificateImportOpen(false)}
onImported={(importedCertificate) => {
setPreferredCertificateId(importedCertificate.id);
setFeedback({
tone: 'success',
message: `证书 ${importedCertificate.name} 已导入,可在编辑网站时直接应用。`,
});
setIsEditorOpen(true);
}}
/>
{isCertificateImportOpen ? (
<CertificateImportModal
isOpen={isCertificateImportOpen}
onClose={() => setIsCertificateImportOpen(false)}
onImported={(importedCertificate) => {
setPreferredCertificateId(importedCertificate.id);
setFeedback({
tone: 'success',
message: `证书 ${importedCertificate.name} 已导入,可在编辑网站时直接应用。`,
});
setIsEditorOpen(true);
}}
/>
) : null}
<CertificateDetailModal
certificateId={certificate?.id ?? null}
isOpen={isCertificateDetailOpen}
onClose={() => setIsCertificateDetailOpen(false)}
onEdit={() => {
setIsCertificateDetailOpen(false);
setIsCertificateEditorOpen(true);
}}
onDelete={() => {
setIsCertificateDetailOpen(false);
handleDeleteCertificate();
}}
deleting={deleteCertificateMutation.isPending}
/>
{isCertificateDetailOpen ? (
<CertificateDetailModal
certificateId={certificate?.id ?? null}
isOpen={isCertificateDetailOpen}
onClose={() => setIsCertificateDetailOpen(false)}
onEdit={() => {
setIsCertificateDetailOpen(false);
setIsCertificateEditorOpen(true);
}}
onDelete={() => {
setIsCertificateDetailOpen(false);
handleDeleteCertificate();
}}
deleting={deleteCertificateMutation.isPending}
/>
) : null}
<CertificateEditorModal
certificateId={certificate?.id ?? null}
isOpen={isCertificateEditorOpen}
onClose={() => setIsCertificateEditorOpen(false)}
onSaved={(updatedCertificate) => {
setFeedback({
tone: 'success',
message: `证书 ${updatedCertificate.name} 已更新。`,
});
}}
/>
{isCertificateEditorOpen ? (
<CertificateEditorModal
certificateId={certificate?.id ?? null}
isOpen={isCertificateEditorOpen}
onClose={() => setIsCertificateEditorOpen(false)}
onSaved={(updatedCertificate) => {
setFeedback({
tone: 'success',
message: `证书 ${updatedCertificate.name} 已更新。`,
});
}}
/>
) : null}
</>
);
}
@@ -114,7 +114,7 @@ export function WebsiteEditorModal({
? toManagedDomainFormValues(initialDomain)
: defaultManagedDomainValues,
);
}, [form, initialDomain, isOpen]);
}, [form, initialDomain, isOpen, saveMutation]);
useEffect(() => {
if (!isOpen || !preferredCertificateId) {
@@ -28,7 +28,6 @@ import {
DangerButton,
PrimaryButton,
} from '@/features/shared/components/resource-primitives';
import { formatDateTime } from '@/lib/utils/date';
type FeedbackState = {
tone: 'info' | 'success' | 'danger';
@@ -205,36 +204,40 @@ export function WebsitesPage() {
</AppCard>
</div>
<WebsiteEditorModal
isOpen={isWebsiteModalOpen}
onClose={() => {
setIsWebsiteModalOpen(false);
setPreferredCertificateId(null);
}}
certificates={certificates}
certificatesLoading={certificatesQuery.isLoading}
preferredCertificateId={preferredCertificateId}
onRequestImportCertificate={() => setIsCertificateImportOpen(true)}
onSaved={(_, mode) => {
setPreferredCertificateId(null);
setFeedback({
tone: 'success',
message: mode === 'create' ? '网站已创建。' : '网站已更新。',
});
}}
/>
{isWebsiteModalOpen ? (
<WebsiteEditorModal
isOpen={isWebsiteModalOpen}
onClose={() => {
setIsWebsiteModalOpen(false);
setPreferredCertificateId(null);
}}
certificates={certificates}
certificatesLoading={certificatesQuery.isLoading}
preferredCertificateId={preferredCertificateId}
onRequestImportCertificate={() => setIsCertificateImportOpen(true)}
onSaved={(_, mode) => {
setPreferredCertificateId(null);
setFeedback({
tone: 'success',
message: mode === 'create' ? '网站已创建。' : '网站已更新。',
});
}}
/>
) : null}
<CertificateImportModal
isOpen={isCertificateImportOpen}
onClose={() => setIsCertificateImportOpen(false)}
onImported={(certificate) => {
setPreferredCertificateId(certificate.id);
setFeedback({
tone: 'success',
message: `证书 ${certificate.name} 已导入,可直接用于当前网站。`,
});
}}
/>
{isCertificateImportOpen ? (
<CertificateImportModal
isOpen={isCertificateImportOpen}
onClose={() => setIsCertificateImportOpen(false)}
onImported={(certificate) => {
setPreferredCertificateId(certificate.id);
setFeedback({
tone: 'success',
message: `证书 ${certificate.name} 已导入,可直接用于当前网站。`,
});
}}
/>
) : null}
</>
);
}
@@ -2,7 +2,6 @@ import type {
ManagedDomainItem,
ManagedDomainMutationPayload,
} from '@/features/managed-domains/types';
import type { ProxyRouteItem } from '@/features/proxy-routes/types';
import type {
TlsCertificateFileImportPayload,
TlsCertificateItem,