Create RouteError page

This commit is contained in:
Mathias Wagner
2026-01-20 00:06:51 +01:00
parent a734323f38
commit 452c430bdd
3 changed files with 116 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faExclamationTriangle} from "@fortawesome/free-solid-svg-icons";
import {useNavigate, useRouteError, isRouteErrorResponse} from "react-router-dom";
import {useTranslation} from "react-i18next";
import "./styles.sass";
export const RouteError = () => {
const error = useRouteError();
const navigate = useNavigate();
const {t} = useTranslation();
const is404 = isRouteErrorResponse(error) && error.status === 404;
return (
<div className="route-error-page">
<div className="route-error-content">
<div className="route-error-icon">
<FontAwesomeIcon icon={faExclamationTriangle} size="4x"/>
</div>
<h1 className="route-error-title">
{is404 ? "404" : t("route_error.title")}
</h1>
<h2 className="route-error-subtitle">
{is404 ? t("not_found.title") : t("route_error.subtitle")}
</h2>
<p className="route-error-description">
{is404 ? t("not_found.description") : t("route_error.description")}
</p>
{!is404 && error?.message && (
<pre className="route-error-details">{error.message}</pre>
)}
<div className="route-error-actions">
<button className="dialog-btn" onClick={() => navigate("/")}>
{t("not_found.back_home")}
</button>
{!is404 && (
<button className="dialog-btn dialog-secondary" onClick={() => window.location.reload()}>
{t("route_error.reload")}
</button>
)}
</div>
</div>
</div>
);
};

View File

@@ -0,0 +1 @@
export {RouteError as default} from "./RouteError";

View File

@@ -0,0 +1,70 @@
@use "@/common/styles/_colors" as *
@use "@/common/contexts/Dialog/styles"
.route-error-page
display: flex
flex-direction: column
justify-content: center
align-items: center
min-height: calc(100vh - 5rem)
padding: 2rem
text-align: center
color: $white
.route-error-content
display: flex
flex-direction: column
align-items: center
gap: 1rem
max-width: 500px
.route-error-icon
width: 100px
height: 100px
border-radius: 50%
background: $dark-gray
display: flex
align-items: center
justify-content: center
margin-bottom: 1rem
svg
color: $red
.route-error-title
font-size: 3rem
font-weight: 700
margin: 0
color: $white
line-height: 1
.route-error-subtitle
font-size: 1.5rem
font-weight: 600
margin: 0
color: $white
.route-error-description
font-size: 1rem
color: $subtext
margin: 0.5rem 0 1rem 0
line-height: 1.5
.route-error-details
background: $darker-gray
border: 1px solid $light-gray
border-radius: 0.5rem
padding: 1rem
font-size: 0.875rem
color: $red
max-width: 100%
overflow-x: auto
margin: 0.5rem 0 1rem 0
white-space: pre-wrap
word-break: break-word
.route-error-actions
display: flex
gap: 1rem
flex-wrap: wrap
justify-content: center