feat: error page

This commit is contained in:
hamster1963 2024-12-20 09:19:31 +08:00
parent 3633664345
commit 13915634c5
3 changed files with 68 additions and 40 deletions

View File

@ -3,6 +3,7 @@ import React, { useEffect, useState } from "react"
import { useTranslation } from "react-i18next"
import { Route, BrowserRouter as Router, Routes } from "react-router-dom"
import ErrorBoundary from "./components/ErrorBoundary"
import Footer from "./components/Footer"
import Header from "./components/Header"
import { InjectContext } from "./lib/inject"
@ -56,37 +57,39 @@ const App: React.FC = () => {
return (
<Router basename={import.meta.env.BASE_URL}>
{/* 固定定位的背景层 */}
{customBackgroundImage && (
<ErrorBoundary>
{/* 固定定位的背景层 */}
{customBackgroundImage && (
<div
className={cn("fixed inset-0 z-0 bg-cover min-h-lvh bg-no-repeat bg-center", {
"hidden sm:block": customMobileBackgroundImage,
})}
style={{ backgroundImage: `url(${customBackgroundImage})` }}
/>
)}
{customMobileBackgroundImage && (
<div
className={cn("fixed inset-0 z-0 bg-cover min-h-lvh bg-no-repeat bg-center sm:hidden")}
style={{ backgroundImage: `url(${customMobileBackgroundImage})` }}
/>
)}
<div
className={cn("fixed inset-0 z-0 bg-cover min-h-lvh bg-no-repeat bg-center", {
"hidden sm:block": customMobileBackgroundImage,
className={cn("flex min-h-screen w-full flex-col", {
"bg-background": !customBackgroundImage,
})}
style={{ backgroundImage: `url(${customBackgroundImage})` }}
/>
)}
{customMobileBackgroundImage && (
<div
className={cn("fixed inset-0 z-0 bg-cover min-h-lvh bg-no-repeat bg-center sm:hidden")}
style={{ backgroundImage: `url(${customMobileBackgroundImage})` }}
/>
)}
<div
className={cn("flex min-h-screen w-full flex-col", {
"bg-background": !customBackgroundImage,
})}
>
<main className="flex z-20 min-h-[calc(100vh-calc(var(--spacing)*16))] flex-1 flex-col gap-4 p-4 md:p-10 md:pt-8">
<Header />
<Routes>
<Route path="/" element={<Server />} />
<Route path="/server/:id" element={<ServerDetail />} />
<Route path="/error" element={<ErrorPage />} />
<Route path="*" element={<NotFound />} />
</Routes>
<Footer />
</main>
</div>
>
<main className="flex z-20 min-h-[calc(100vh-calc(var(--spacing)*16))] flex-1 flex-col gap-4 p-4 md:p-10 md:pt-8">
<Header />
<Routes>
<Route path="/" element={<Server />} />
<Route path="/server/:id" element={<ServerDetail />} />
<Route path="/error" element={<ErrorPage />} />
<Route path="*" element={<NotFound />} />
</Routes>
<Footer />
</main>
</div>
</ErrorBoundary>
</Router>
)
}

View File

@ -0,0 +1,36 @@
import React from "react"
import ErrorPage from "../pages/ErrorPage"
interface Props {
children: React.ReactNode
}
interface State {
hasError: boolean
error?: Error
}
class ErrorBoundary extends React.Component<Props, State> {
constructor(props: Props) {
super(props)
this.state = { hasError: false }
}
static getDerivedStateFromError(error: Error): State {
return {
hasError: true,
error,
}
}
render() {
if (this.state.hasError) {
return <ErrorPage code={500} message={this.state.error?.message || "应用程序发生错误"} />
}
return this.props.children
}
}
export default ErrorBoundary

View File

@ -1,6 +1,4 @@
import { Button } from "@/components/ui/button"
import { useTranslation } from "react-i18next"
import { useNavigate } from "react-router-dom"
interface ErrorPageProps {
code?: string | number
@ -8,7 +6,6 @@ interface ErrorPageProps {
}
export default function ErrorPage({ code = "500", message }: ErrorPageProps) {
const navigate = useNavigate()
const { t } = useTranslation()
return (
@ -16,14 +13,6 @@ export default function ErrorPage({ code = "500", message }: ErrorPageProps) {
<div className="flex flex-col items-center gap-2">
<h1 className="text-4xl font-semibold">{code}</h1>
<p className="text-xl text-muted-foreground">{message || t("error.somethingWentWrong")}</p>
<div className="flex gap-2">
<Button onClick={() => window.location.reload()} variant="outline">
{t("error.tryAgain")}
</Button>
<Button onClick={() => navigate("/")} className="mt-2">
{t("error.backToHome")}
</Button>
</div>
</div>
</div>
)