mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-12 02:06:37 +08:00
migrate frontend
This commit is contained in:
+1
-1
@@ -194,7 +194,7 @@ export default function AboutPage() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="flex flex-wrap gap-3 text-sm">
|
<div className="flex flex-wrap gap-3 text-sm">
|
||||||
<Link href="/openflare" className="text-primary transition hover:opacity-80">
|
<Link href="/" className="text-primary transition hover:opacity-80">
|
||||||
返回总览
|
返回总览
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
@@ -28,7 +28,7 @@ import {ErrorInline} from "@/components/layout/error"
|
|||||||
import {LoadingStateWithBorder} from "@/components/layout/loading"
|
import {LoadingStateWithBorder} from "@/components/layout/loading"
|
||||||
import type {DatabaseCleanupTarget} from "@/lib/services/openflare"
|
import type {DatabaseCleanupTarget} from "@/lib/services/openflare"
|
||||||
import {NodeService, OptionService, StatusService, UpdateService, UptimeKumaService,} from "@/lib/services/openflare"
|
import {NodeService, OptionService, StatusService, UpdateService, UptimeKumaService,} from "@/lib/services/openflare"
|
||||||
import {VersionUpgradeDialog} from "@/app/(main)/openflare/components/version-upgrade-dialog"
|
import {VersionUpgradeDialog} from "@/app/(main)/components/version-upgrade-dialog"
|
||||||
import {openflareLatestReleaseQueryKey, openflarePublicStatusQueryKey,} from "@/lib/hooks/use-openflare-server-upgrade"
|
import {openflareLatestReleaseQueryKey, openflarePublicStatusQueryKey,} from "@/lib/hooks/use-openflare-server-upgrade"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -364,7 +364,7 @@ export function OpenFlareOpsSettings() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
<Button variant="outline" size="sm" asChild>
|
<Button variant="outline" size="sm" asChild>
|
||||||
<Link href="/openflare/nodes">
|
<Link href="/nodes">
|
||||||
<ExternalLink className="size-3.5 mr-1" />
|
<ExternalLink className="size-3.5 mr-1" />
|
||||||
节点管理
|
节点管理
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
+1
-1
@@ -151,7 +151,7 @@ export function ApplyLogsPageClient() {
|
|||||||
刷新
|
刷新
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="outline" size="sm" asChild>
|
<Button variant="outline" size="sm" asChild>
|
||||||
<Link href="/openflare/nodes">返回节点</Link>
|
<Link href="/nodes">返回节点</Link>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
+2
-2
@@ -47,7 +47,7 @@ export function NodeHealthTable({ nodes }: { nodes: DashboardNodeHealth[] }) {
|
|||||||
</CardDescription>
|
</CardDescription>
|
||||||
</div>
|
</div>
|
||||||
<Button variant="outline" size="sm" className="h-8 text-xs" asChild>
|
<Button variant="outline" size="sm" className="h-8 text-xs" asChild>
|
||||||
<Link href="/openflare/nodes">进入节点页</Link>
|
<Link href="/nodes">进入节点页</Link>
|
||||||
</Button>
|
</Button>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
@@ -117,7 +117,7 @@ export function NodeHealthTable({ nodes }: { nodes: DashboardNodeHealth[] }) {
|
|||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="py-3 text-right">
|
<TableCell className="py-3 text-right">
|
||||||
<Button variant="ghost" size="sm" className="h-8 text-xs" asChild>
|
<Button variant="ghost" size="sm" className="h-8 text-xs" asChild>
|
||||||
<Link href={`/openflare/nodes/detail?id=${node.id}`}>详情</Link>
|
<Link href={`/nodes/detail?id=${node.id}`}>详情</Link>
|
||||||
</Button>
|
</Button>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
+1
-1
@@ -16,7 +16,7 @@ import {Tabs, TabsContent, TabsList, TabsTrigger} from '@/components/ui/tabs';
|
|||||||
import {useOpenFlareServerUpgrade} from '@/lib/hooks/use-openflare-server-upgrade';
|
import {useOpenFlareServerUpgrade} from '@/lib/hooks/use-openflare-server-upgrade';
|
||||||
import type {LatestReleaseInfo, ReleaseChannel} from '@/lib/services/openflare';
|
import type {LatestReleaseInfo, ReleaseChannel} from '@/lib/services/openflare';
|
||||||
import {formatDateTime} from '@/lib/utils';
|
import {formatDateTime} from '@/lib/utils';
|
||||||
import {formatRelativeTime} from '@/app/(main)/openflare/nodes/components/node-utils';
|
import {formatRelativeTime} from '@/app/(main)/nodes/components/node-utils';
|
||||||
|
|
||||||
import {UpgradeLogPanel} from './upgrade-log-panel';
|
import {UpgradeLogPanel} from './upgrade-log-panel';
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import {redirect} from "next/navigation"
|
import {redirect} from "next/navigation"
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
redirect("/openflare")
|
redirect("/")
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -109,7 +109,7 @@ export function EdgeNodeDetail({ node }: { node: NodeItem }) {
|
|||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
toast.success('节点已删除');
|
toast.success('节点已删除');
|
||||||
await queryClient.invalidateQueries({ queryKey: nodesQueryKey });
|
await queryClient.invalidateQueries({ queryKey: nodesQueryKey });
|
||||||
router.push('/openflare/nodes');
|
router.push('/nodes');
|
||||||
},
|
},
|
||||||
onError: (error) => toast.error(getErrorMessage(error)),
|
onError: (error) => toast.error(getErrorMessage(error)),
|
||||||
});
|
});
|
||||||
@@ -133,7 +133,7 @@ export function EdgeNodeDetail({ node }: { node: NodeItem }) {
|
|||||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Button variant="ghost" size="sm" className="h-8 px-2" asChild>
|
<Button variant="ghost" size="sm" className="h-8 px-2" asChild>
|
||||||
<Link href="/openflare/nodes">
|
<Link href="/nodes">
|
||||||
<ArrowLeft className="size-4" />
|
<ArrowLeft className="size-4" />
|
||||||
</Link>
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -295,7 +295,7 @@ export function EdgeNodeDetail({ node }: { node: NodeItem }) {
|
|||||||
<CardDescription>来自 observability 接口的最近上报</CardDescription>
|
<CardDescription>来自 observability 接口的最近上报</CardDescription>
|
||||||
</div>
|
</div>
|
||||||
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
||||||
<Link href={`/openflare/apply-logs?node_id=${encodeURIComponent(node.node_id)}`}>
|
<Link href={`/apply-logs?node_id=${encodeURIComponent(node.node_id)}`}>
|
||||||
<FileText className="size-3.5 mr-1" />
|
<FileText className="size-3.5 mr-1" />
|
||||||
应用记录
|
应用记录
|
||||||
</Link>
|
</Link>
|
||||||
+4
-4
@@ -8,10 +8,10 @@ import {cn} from '@/lib/utils';
|
|||||||
export type NodeFilter = 'all' | 'edge' | 'relay' | 'tunnel';
|
export type NodeFilter = 'all' | 'edge' | 'relay' | 'tunnel';
|
||||||
|
|
||||||
const filters: Array<{ key: NodeFilter; label: string; href: string }> = [
|
const filters: Array<{ key: NodeFilter; label: string; href: string }> = [
|
||||||
{ key: 'all', label: '全部节点', href: '/openflare/nodes' },
|
{ key: 'all', label: '全部节点', href: '/nodes' },
|
||||||
{ key: 'edge', label: 'Edge', href: '/openflare/nodes?filter=edge' },
|
{ key: 'edge', label: 'Edge', href: '/nodes?filter=edge' },
|
||||||
{ key: 'relay', label: 'Relay', href: '/openflare/nodes?filter=relay' },
|
{ key: 'relay', label: 'Relay', href: '/nodes?filter=relay' },
|
||||||
{ key: 'tunnel', label: 'Tunnel', href: '/openflare/nodes?filter=tunnel' },
|
{ key: 'tunnel', label: 'Tunnel', href: '/nodes?filter=tunnel' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export function getNodeFilter(searchParams: URLSearchParams): NodeFilter {
|
export function getNodeFilter(searchParams: URLSearchParams): NodeFilter {
|
||||||
+1
-1
@@ -119,7 +119,7 @@ export function NodesTable({
|
|||||||
<TableCell className="py-3">
|
<TableCell className="py-3">
|
||||||
<div className="flex flex-wrap justify-end gap-1">
|
<div className="flex flex-wrap justify-end gap-1">
|
||||||
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
||||||
<Link href={`/openflare/nodes/detail?id=${node.id}`}>详情</Link>
|
<Link href={`/nodes/detail?id=${node.id}`}>详情</Link>
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
+3
-3
@@ -122,7 +122,7 @@ export function RelayNodeDetail({ node }: { node: NodeItem }) {
|
|||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
toast.success('中继节点已删除');
|
toast.success('中继节点已删除');
|
||||||
await queryClient.invalidateQueries({ queryKey: nodesQueryKey });
|
await queryClient.invalidateQueries({ queryKey: nodesQueryKey });
|
||||||
router.push('/openflare/nodes');
|
router.push('/nodes');
|
||||||
},
|
},
|
||||||
onError: (error) => toast.error(getErrorMessage(error)),
|
onError: (error) => toast.error(getErrorMessage(error)),
|
||||||
});
|
});
|
||||||
@@ -144,7 +144,7 @@ export function RelayNodeDetail({ node }: { node: NodeItem }) {
|
|||||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Button variant="ghost" size="sm" className="h-8 px-2" asChild>
|
<Button variant="ghost" size="sm" className="h-8 px-2" asChild>
|
||||||
<Link href="/openflare/nodes">
|
<Link href="/nodes">
|
||||||
<ArrowLeft className="size-4" />
|
<ArrowLeft className="size-4" />
|
||||||
</Link>
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -295,7 +295,7 @@ export function RelayNodeDetail({ node }: { node: NodeItem }) {
|
|||||||
<CardDescription>控制 frps 内置 Web 管理界面是否启用</CardDescription>
|
<CardDescription>控制 frps 内置 Web 管理界面是否启用</CardDescription>
|
||||||
</div>
|
</div>
|
||||||
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
||||||
<Link href={`/openflare/apply-logs?node_id=${encodeURIComponent(node.node_id)}`}>
|
<Link href={`/apply-logs?node_id=${encodeURIComponent(node.node_id)}`}>
|
||||||
<FileText className="size-3.5 mr-1" />
|
<FileText className="size-3.5 mr-1" />
|
||||||
应用记录
|
应用记录
|
||||||
</Link>
|
</Link>
|
||||||
+3
-3
@@ -97,7 +97,7 @@ export function TunnelNodeDetail({ node }: { node: NodeItem }) {
|
|||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
toast.success('隧道节点已删除');
|
toast.success('隧道节点已删除');
|
||||||
await queryClient.invalidateQueries({ queryKey: nodesQueryKey });
|
await queryClient.invalidateQueries({ queryKey: nodesQueryKey });
|
||||||
router.push('/openflare/nodes');
|
router.push('/nodes');
|
||||||
},
|
},
|
||||||
onError: (error) => toast.error(getErrorMessage(error)),
|
onError: (error) => toast.error(getErrorMessage(error)),
|
||||||
});
|
});
|
||||||
@@ -114,7 +114,7 @@ export function TunnelNodeDetail({ node }: { node: NodeItem }) {
|
|||||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Button variant="ghost" size="sm" className="h-8 px-2" asChild>
|
<Button variant="ghost" size="sm" className="h-8 px-2" asChild>
|
||||||
<Link href="/openflare/nodes">
|
<Link href="/nodes">
|
||||||
<ArrowLeft className="size-4" />
|
<ArrowLeft className="size-4" />
|
||||||
</Link>
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -265,7 +265,7 @@ export function TunnelNodeDetail({ node }: { node: NodeItem }) {
|
|||||||
<CardDescription>配置追平与应用结果</CardDescription>
|
<CardDescription>配置追平与应用结果</CardDescription>
|
||||||
</div>
|
</div>
|
||||||
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
||||||
<Link href={`/openflare/apply-logs?node_id=${encodeURIComponent(node.node_id)}`}>
|
<Link href={`/apply-logs?node_id=${encodeURIComponent(node.node_id)}`}>
|
||||||
<FileText className="size-3.5 mr-1" />
|
<FileText className="size-3.5 mr-1" />
|
||||||
应用记录
|
应用记录
|
||||||
</Link>
|
</Link>
|
||||||
+1
-1
@@ -71,7 +71,7 @@ export function NodeDetailPageClient() {
|
|||||||
return (
|
return (
|
||||||
<div className="py-6 px-1 space-y-4">
|
<div className="py-6 px-1 space-y-4">
|
||||||
<Button variant="ghost" size="sm" className="h-8 px-2" asChild>
|
<Button variant="ghost" size="sm" className="h-8 px-2" asChild>
|
||||||
<Link href="/openflare/nodes">
|
<Link href="/nodes">
|
||||||
<ArrowLeft className="size-4 mr-1" />
|
<ArrowLeft className="size-4 mr-1" />
|
||||||
返回节点列表
|
返回节点列表
|
||||||
</Link>
|
</Link>
|
||||||
+1
-1
@@ -109,7 +109,7 @@ export function NodesPageClient() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
||||||
<Link href="/openflare/apply-logs">应用记录</Link>
|
<Link href="/apply-logs">应用记录</Link>
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="secondary" size="sm" className="h-7 text-xs" onClick={handleCreate}>
|
<Button variant="secondary" size="sm" className="h-7 text-xs" onClick={handleCreate}>
|
||||||
<Plus className="size-3.5 mr-1" />
|
<Plus className="size-3.5 mr-1" />
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
export default function OpenFlareLayout({
|
|
||||||
children,
|
|
||||||
}: {
|
|
||||||
children: React.ReactNode;
|
|
||||||
}) {
|
|
||||||
return children;
|
|
||||||
}
|
|
||||||
+3
-3
@@ -49,7 +49,7 @@ export function OriginDetailPageClient() {
|
|||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
toast.success("源站已删除")
|
toast.success("源站已删除")
|
||||||
await queryClient.invalidateQueries({ queryKey: ["openflare", "origins"] })
|
await queryClient.invalidateQueries({ queryKey: ["openflare", "origins"] })
|
||||||
window.location.href = "/openflare/origins"
|
window.location.href = "/origins"
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
toast.error(error instanceof Error ? error.message : "删除失败")
|
toast.error(error instanceof Error ? error.message : "删除失败")
|
||||||
@@ -93,7 +93,7 @@ export function OriginDetailPageClient() {
|
|||||||
return (
|
return (
|
||||||
<div className="py-6 px-1 space-y-4">
|
<div className="py-6 px-1 space-y-4">
|
||||||
<Button variant="ghost" size="sm" asChild>
|
<Button variant="ghost" size="sm" asChild>
|
||||||
<Link href="/openflare/origins">
|
<Link href="/origins">
|
||||||
<ArrowLeft className="size-4 mr-1" />
|
<ArrowLeft className="size-4 mr-1" />
|
||||||
返回列表
|
返回列表
|
||||||
</Link>
|
</Link>
|
||||||
@@ -108,7 +108,7 @@ export function OriginDetailPageClient() {
|
|||||||
<div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
|
<div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Button variant="ghost" size="sm" className="h-8 px-2 -ml-2" asChild>
|
<Button variant="ghost" size="sm" className="h-8 px-2 -ml-2" asChild>
|
||||||
<Link href="/openflare/origins">
|
<Link href="/origins">
|
||||||
<ArrowLeft className="size-4 mr-1" />
|
<ArrowLeft className="size-4 mr-1" />
|
||||||
返回列表
|
返回列表
|
||||||
</Link>
|
</Link>
|
||||||
+1
-1
@@ -141,7 +141,7 @@ export default function OriginsPage() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
<Button variant="outline" size="sm" asChild>
|
<Button variant="outline" size="sm" asChild>
|
||||||
<Link href={`/openflare/origins/detail?id=${origin.id}`}>
|
<Link href={`/origins/detail?id=${origin.id}`}>
|
||||||
详情
|
详情
|
||||||
</Link>
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
+1
-1
@@ -14,7 +14,7 @@ interface ProjectListItemProps {
|
|||||||
export function ProjectListItem({ project }: ProjectListItemProps) {
|
export function ProjectListItem({ project }: ProjectListItemProps) {
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
href={`/openflare/pages/detail?id=${project.id}`}
|
href={`/pages/detail?id=${project.id}`}
|
||||||
className="group block rounded-lg border border-dashed bg-background p-4 transition hover:bg-muted/20"
|
className="group block rounded-lg border border-dashed bg-background p-4 transition hover:bg-muted/20"
|
||||||
>
|
>
|
||||||
<div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
|
<div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
|
||||||
+3
-3
@@ -157,7 +157,7 @@ export function PagesDetailPageClient() {
|
|||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
toast.success("项目已删除")
|
toast.success("项目已删除")
|
||||||
await queryClient.invalidateQueries({ queryKey: projectsQueryKey })
|
await queryClient.invalidateQueries({ queryKey: projectsQueryKey })
|
||||||
window.location.href = "/openflare/pages"
|
window.location.href = "/pages"
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
toast.error(error instanceof Error ? error.message : "删除失败")
|
toast.error(error instanceof Error ? error.message : "删除失败")
|
||||||
@@ -202,7 +202,7 @@ export function PagesDetailPageClient() {
|
|||||||
return (
|
return (
|
||||||
<div className="py-6 px-1 space-y-4">
|
<div className="py-6 px-1 space-y-4">
|
||||||
<Button variant="ghost" size="sm" asChild>
|
<Button variant="ghost" size="sm" asChild>
|
||||||
<Link href="/openflare/pages">
|
<Link href="/pages">
|
||||||
<ArrowLeft className="size-4 mr-1" />
|
<ArrowLeft className="size-4 mr-1" />
|
||||||
返回列表
|
返回列表
|
||||||
</Link>
|
</Link>
|
||||||
@@ -217,7 +217,7 @@ export function PagesDetailPageClient() {
|
|||||||
<div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
|
<div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Button variant="ghost" size="sm" className="h-8 px-2 -ml-2" asChild>
|
<Button variant="ghost" size="sm" className="h-8 px-2 -ml-2" asChild>
|
||||||
<Link href="/openflare/pages">
|
<Link href="/pages">
|
||||||
<ArrowLeft className="size-4 mr-1" />
|
<ArrowLeft className="size-4 mr-1" />
|
||||||
返回列表
|
返回列表
|
||||||
</Link>
|
</Link>
|
||||||
+1
-1
@@ -147,7 +147,7 @@ export default function PerformancePage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Button variant="outline" size="sm" asChild>
|
<Button variant="outline" size="sm" asChild>
|
||||||
<Link href="/openflare/config-versions">
|
<Link href="/config-versions">
|
||||||
<ExternalLink className="size-3.5 mr-1" />
|
<ExternalLink className="size-3.5 mr-1" />
|
||||||
查看配置预览
|
查看配置预览
|
||||||
</Link>
|
</Link>
|
||||||
+2
-2
@@ -24,8 +24,8 @@ import {
|
|||||||
} from '@/components/ui/select';
|
} from '@/components/ui/select';
|
||||||
import type {ProxyRouteItem, ProxyRoutePoWConfig} from '@/lib/services/openflare';
|
import type {ProxyRouteItem, ProxyRoutePoWConfig} from '@/lib/services/openflare';
|
||||||
|
|
||||||
import {defaultPowConfig} from '@/app/(main)/openflare/waf/components/helpers';
|
import {defaultPowConfig} from '@/app/(main)/waf/components/helpers';
|
||||||
import {PowConfigPanel} from '@/app/(main)/openflare/waf/components/pow-config-panel';
|
import {PowConfigPanel} from '@/app/(main)/waf/components/pow-config-panel';
|
||||||
|
|
||||||
import {proxyRouteFormIds} from '../helpers';
|
import {proxyRouteFormIds} from '../helpers';
|
||||||
import {useRouteSectionSave} from '../hooks/use-route-section-save';
|
import {useRouteSectionSave} from '../hooks/use-route-section-save';
|
||||||
+2
-2
@@ -16,7 +16,7 @@ import {
|
|||||||
} from '@/components/ui/alert-dialog';
|
} from '@/components/ui/alert-dialog';
|
||||||
import {Badge} from '@/components/ui/badge';
|
import {Badge} from '@/components/ui/badge';
|
||||||
import {Button} from '@/components/ui/button';
|
import {Button} from '@/components/ui/button';
|
||||||
import {DiffDialog} from '@/app/(main)/openflare/config-versions/components/diff-dialog';
|
import {DiffDialog} from '@/app/(main)/config-versions/components/diff-dialog';
|
||||||
import type {ConfigDiffResult, ProxyRouteConfigSection, ProxyRouteItem} from '@/lib/services/openflare';
|
import type {ConfigDiffResult, ProxyRouteConfigSection, ProxyRouteItem} from '@/lib/services/openflare';
|
||||||
import {ConfigVersionService} from '@/lib/services/openflare';
|
import {ConfigVersionService} from '@/lib/services/openflare';
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ export function RouteHeader({ route, activeSection, saving = false }: RouteHeade
|
|||||||
<>
|
<>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<Button variant="ghost" size="sm" className="h-8 gap-1.5 px-0 text-xs" asChild>
|
<Button variant="ghost" size="sm" className="h-8 gap-1.5 px-0 text-xs" asChild>
|
||||||
<Link href="/openflare/proxy-routes">
|
<Link href="/proxy-routes">
|
||||||
<ArrowLeft className="size-3.5" />
|
<ArrowLeft className="size-3.5" />
|
||||||
返回规则列表
|
返回规则列表
|
||||||
</Link>
|
</Link>
|
||||||
+1
-1
@@ -35,7 +35,7 @@ export function ProxyRouteDetailPageClient() {
|
|||||||
(section: ProxyRouteConfigSection) => {
|
(section: ProxyRouteConfigSection) => {
|
||||||
const params = new URLSearchParams(searchParams.toString());
|
const params = new URLSearchParams(searchParams.toString());
|
||||||
params.set('section', section);
|
params.set('section', section);
|
||||||
router.replace(`/openflare/proxy-routes/detail?${params.toString()}`);
|
router.replace(`/proxy-routes/detail?${params.toString()}`);
|
||||||
},
|
},
|
||||||
[router, searchParams],
|
[router, searchParams],
|
||||||
);
|
);
|
||||||
+2
-2
@@ -184,7 +184,7 @@ export function ProxyRoutesPageClient() {
|
|||||||
<TableCell className="text-right">
|
<TableCell className="text-right">
|
||||||
<div className="flex justify-end gap-2">
|
<div className="flex justify-end gap-2">
|
||||||
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
||||||
<Link href={`/openflare/proxy-routes/detail?id=${route.id}`}>
|
<Link href={`/proxy-routes/detail?id=${route.id}`}>
|
||||||
配置
|
配置
|
||||||
</Link>
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -212,7 +212,7 @@ export function ProxyRoutesPageClient() {
|
|||||||
onCreated={(route) => {
|
onCreated={(route) => {
|
||||||
toast.success('网站已创建');
|
toast.success('网站已创建');
|
||||||
void fetchRoutes();
|
void fetchRoutes();
|
||||||
router.push(`/openflare/proxy-routes/detail?id=${route.id}§ion=domains`);
|
router.push(`/proxy-routes/detail?id=${route.id}§ion=domains`);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
+1
-1
@@ -158,7 +158,7 @@ export default function WafIPGroupsPage() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
||||||
<Link href="/openflare/waf">
|
<Link href="/waf">
|
||||||
<ArrowLeft className="size-3.5 mr-1" />
|
<ArrowLeft className="size-3.5 mr-1" />
|
||||||
返回 WAF
|
返回 WAF
|
||||||
</Link>
|
</Link>
|
||||||
+1
-1
@@ -140,7 +140,7 @@ export default function WafPage() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
||||||
<Link href="/openflare/waf/ip-groups">
|
<Link href="/waf/ip-groups">
|
||||||
<Network className="size-3.5 mr-1" />
|
<Network className="size-3.5 mr-1" />
|
||||||
IP 组
|
IP 组
|
||||||
</Link>
|
</Link>
|
||||||
+2
-2
@@ -96,10 +96,10 @@ export default function CertificatesPage() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
||||||
<Link href="/openflare/websites">返回网站</Link>
|
<Link href="/websites">返回网站</Link>
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
||||||
<Link href="/openflare/websites/dns-accounts">DNS 账号</Link>
|
<Link href="/websites/dns-accounts">DNS 账号</Link>
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
+4
-4
@@ -26,7 +26,7 @@ import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow,} from '@/
|
|||||||
import type {TlsCertificateItem} from '@/lib/services/openflare';
|
import type {TlsCertificateItem} from '@/lib/services/openflare';
|
||||||
import {ProxyRouteService, TlsCertificateService, WebsiteService,} from '@/lib/services/openflare';
|
import {ProxyRouteService, TlsCertificateService, WebsiteService,} from '@/lib/services/openflare';
|
||||||
import {formatDateTime} from '@/lib/utils';
|
import {formatDateTime} from '@/lib/utils';
|
||||||
import {getUpstreamSummary} from '@/app/(main)/openflare/proxy-routes/components/helpers';
|
import {getUpstreamSummary} from '@/app/(main)/proxy-routes/components/helpers';
|
||||||
|
|
||||||
import {CertificateApplyDialog} from '../components/certificate-apply-dialog';
|
import {CertificateApplyDialog} from '../components/certificate-apply-dialog';
|
||||||
import {CertificateDetailDialog} from '../components/certificate-detail-dialog';
|
import {CertificateDetailDialog} from '../components/certificate-detail-dialog';
|
||||||
@@ -105,7 +105,7 @@ export function WebsiteDetailPageClient() {
|
|||||||
mutationFn: (id: number) => WebsiteService.delete(id),
|
mutationFn: (id: number) => WebsiteService.delete(id),
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
await queryClient.invalidateQueries({queryKey: domainsQueryKey});
|
await queryClient.invalidateQueries({queryKey: domainsQueryKey});
|
||||||
router.push('/openflare/websites');
|
router.push('/websites');
|
||||||
},
|
},
|
||||||
onError: (error) => toast.error(getErrorMessage(error)),
|
onError: (error) => toast.error(getErrorMessage(error)),
|
||||||
});
|
});
|
||||||
@@ -162,7 +162,7 @@ export function WebsiteDetailPageClient() {
|
|||||||
return (
|
return (
|
||||||
<div className="py-6 px-1 space-y-4">
|
<div className="py-6 px-1 space-y-4">
|
||||||
<Button variant="ghost" size="sm" className="h-8 px-2" asChild>
|
<Button variant="ghost" size="sm" className="h-8 px-2" asChild>
|
||||||
<Link href="/openflare/websites">
|
<Link href="/websites">
|
||||||
<ArrowLeft className="size-4 mr-1" />
|
<ArrowLeft className="size-4 mr-1" />
|
||||||
返回网站列表
|
返回网站列表
|
||||||
</Link>
|
</Link>
|
||||||
@@ -191,7 +191,7 @@ export function WebsiteDetailPageClient() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
||||||
<Link href="/openflare/websites">
|
<Link href="/websites">
|
||||||
<ArrowLeft className="size-3.5 mr-1" />
|
<ArrowLeft className="size-3.5 mr-1" />
|
||||||
返回
|
返回
|
||||||
</Link>
|
</Link>
|
||||||
+2
-2
@@ -64,10 +64,10 @@ export default function DnsAccountsPage() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
||||||
<Link href="/openflare/websites">返回网站</Link>
|
<Link href="/websites">返回网站</Link>
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
||||||
<Link href="/openflare/websites/certificates">证书</Link>
|
<Link href="/websites/certificates">证书</Link>
|
||||||
</Button>
|
</Button>
|
||||||
<Button size="sm" className="h-7 text-xs" onClick={() => setCreateOpen(true)}>
|
<Button size="sm" className="h-7 text-xs" onClick={() => setCreateOpen(true)}>
|
||||||
<Plus className="size-3.5 mr-1" />
|
<Plus className="size-3.5 mr-1" />
|
||||||
+3
-3
@@ -78,10 +78,10 @@ export default function WebsitesPage() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
||||||
<Link href="/openflare/websites/certificates">证书列表</Link>
|
<Link href="/websites/certificates">证书列表</Link>
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
||||||
<Link href="/openflare/websites/dns-accounts">DNS 账号</Link>
|
<Link href="/websites/dns-accounts">DNS 账号</Link>
|
||||||
</Button>
|
</Button>
|
||||||
<Button size="sm" className="h-7 text-xs" onClick={() => setEditorOpen(true)}>
|
<Button size="sm" className="h-7 text-xs" onClick={() => setEditorOpen(true)}>
|
||||||
<Plus className="size-3.5 mr-1" />
|
<Plus className="size-3.5 mr-1" />
|
||||||
@@ -146,7 +146,7 @@ export default function WebsitesPage() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex shrink-0 gap-1">
|
<div className="flex shrink-0 gap-1">
|
||||||
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
<Button variant="outline" size="sm" className="h-7 text-xs" asChild>
|
||||||
<Link href={`/openflare/websites/detail?id=${domain.id}`}>
|
<Link href={`/websites/detail?id=${domain.id}`}>
|
||||||
详情
|
详情
|
||||||
</Link>
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { HeroSection } from "@/components/home/hero-section";
|
|
||||||
import { DeveloperSection } from "@/components/home/developer-section";
|
|
||||||
import { FooterSection } from "@/components/home/footer-section";
|
|
||||||
|
|
||||||
export default function HomePage() {
|
|
||||||
return (
|
|
||||||
<div className="relative w-full min-h-screen bg-transparent text-foreground font-sans overflow-x-hidden selection:bg-primary selection:text-primary-foreground z-10">
|
|
||||||
<HeroSection />
|
|
||||||
<DeveloperSection />
|
|
||||||
<FooterSection />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -42,7 +42,7 @@ export function LoginPage() {
|
|||||||
const resolveRedirectTarget = useCallback(() => {
|
const resolveRedirectTarget = useCallback(() => {
|
||||||
const callbackUrl = searchParams.get('callbackUrl')
|
const callbackUrl = searchParams.get('callbackUrl')
|
||||||
const storedRedirect = sessionStorage.getItem('redirect_after_login')
|
const storedRedirect = sessionStorage.getItem('redirect_after_login')
|
||||||
const target = callbackUrl || storedRedirect || '/home'
|
const target = callbackUrl || storedRedirect || '/'
|
||||||
|
|
||||||
if (storedRedirect) {
|
if (storedRedirect) {
|
||||||
sessionStorage.removeItem('redirect_after_login')
|
sessionStorage.removeItem('redirect_after_login')
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ function getRedirectTarget(searchParams: ReturnType<typeof useSearchParams>) {
|
|||||||
typeof window === "undefined"
|
typeof window === "undefined"
|
||||||
? null
|
? null
|
||||||
: sessionStorage.getItem("redirect_after_login")
|
: sessionStorage.getItem("redirect_after_login")
|
||||||
return safeRedirectTarget(callbackUrl || storedRedirect || "/home")
|
return safeRedirectTarget(callbackUrl || storedRedirect || "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user