mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
basic error screen
This commit is contained in:
1 parent
676601b06e
commit
2b955a281b
13 files changed
+143
-21
No files matched your search
@@ -223,8 +223,9 @@
|
||||
"postcss-nested": "^7.0.2",
|
||||
"postcss-preset-env": "^11.1.1",
|
||||
"quicklime": "^1.2.0",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react": "^19.2.6",
|
||||
"react-dom": "^19.2.6",
|
||||
"react-error-boundary": "^6.1.1",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-promise-suspense": "^0.3.4",
|
||||
"sharp": "^0.34.5",
|
||||
@@ -2502,6 +2503,8 @@
|
||||
|
||||
"react-dom": ["[email protected]", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
|
||||
|
||||
"react-error-boundary": ["[email protected]", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0" } }, "sha512-BrYwPOdXi5mqkk5lw+Uvt0ThHx32rCt3BkukS4X23A2AIWDPSGX6iaWTc0y9TU/mHDA/6qOSGel+B2ERkOvD1w=="],
|
||||
|
||||
"react-markdown": ["[email protected]", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "html-url-attributes": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "unified": "^11.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" }, "peerDependencies": { "@types/react": ">=18", "react": ">=18" } }, "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ=="],
|
||||
|
||||
"react-promise-suspense": ["[email protected]", "", { "dependencies": { "fast-deep-equal": "^2.0.1" } }, "sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ=="],
|
||||
@@ -3078,6 +3081,10 @@
|
||||
|
||||
"@blitzkit/website-ue/googleapis": ["[email protected]", "", { "dependencies": { "google-auth-library": "^10.2.0", "googleapis-common": "^8.0.0" } }, "sha512-xybFL2SmmUgIifgsbsRQYRdNrSAYwxWZDmkZTGjUIaRnX5jPqR8el/cEvo6rCqh7iaZx6MfEPS/lrDgZ0bymkg=="],
|
||||
|
||||
"@blitzkit/website-ue/react": ["[email protected]", "", {}, "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q=="],
|
||||
|
||||
"@blitzkit/website-ue/react-dom": ["[email protected]", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.6" } }, "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g=="],
|
||||
|
||||
"@blitzkit/website-ue/vite": ["[email protected]", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="],
|
||||
|
||||
"@discordjs/rest/@discordjs/collection": ["@discordjs/[email protected]", "", {}, "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg=="],
|
||||
@@ -3218,7 +3225,7 @@
|
||||
|
||||
"utif2/pako": ["[email protected]", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
|
||||
|
||||
"varuna/react": ["[email protected].5", "", {}, "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA=="],
|
||||
"varuna/react": ["[email protected].6", "", {}, "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q=="],
|
||||
|
||||
"vscode-json-languageservice/jsonc-parser": ["[email protected]", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="],
|
||||
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
{
|
||||
"error": {
|
||||
"heading": "BlitzKit ran into a critical error",
|
||||
"message": "Sorry about the inconvenience! You have a couple of options.",
|
||||
"view": "View error",
|
||||
"reload": "Reload",
|
||||
"support": "Support"
|
||||
},
|
||||
|
||||
"nations": {
|
||||
"0": "Unspecified",
|
||||
"1": "USSR",
|
||||
|
||||
@@ -45,8 +45,9 @@
|
||||
"postcss-nested": "^7.0.2",
|
||||
"postcss-preset-env": "^11.1.1",
|
||||
"quicklime": "^1.2.0",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react": "^19.2.6",
|
||||
"react-dom": "^19.2.6",
|
||||
"react-error-boundary": "^6.1.1",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-promise-suspense": "^0.3.4",
|
||||
"sharp": "^0.34.5",
|
||||
|
||||
@@ -40,14 +40,18 @@
|
||||
color: var(--accent-1);
|
||||
}
|
||||
|
||||
&[data-variant="ghost"] {
|
||||
&[data-variant="ghost"],
|
||||
&[data-variant="outline"] {
|
||||
background: none;
|
||||
color: var(--accent-11);
|
||||
color: var(--accent-12);
|
||||
}
|
||||
|
||||
&[data-variant="ghost"] {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&[data-variant="surface"] {
|
||||
&[data-variant="surface"],
|
||||
&[data-variant="outline"] {
|
||||
outline: var(--space-1) solid var(--accent-6);
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import styles from "./index.module.css";
|
||||
export interface ButtonProps extends ComponentProps<"button"> {
|
||||
color?: Color;
|
||||
radius?: `${1 | 2 | 3}` | "max";
|
||||
variant?: "solid" | "surface" | "soft" | "inverted" | "ghost";
|
||||
variant?: "solid" | "surface" | "soft" | "inverted" | "ghost" | "outline";
|
||||
size?: "regular";
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
---
|
||||
import { api } from "../api/dynamic";
|
||||
import { discordLink } from "../config/socials";
|
||||
import { Button } from "./Button";
|
||||
import { Heading } from "./Heading";
|
||||
import { Link } from "./Link";
|
||||
import { Text } from "./Text";
|
||||
|
||||
interface Props {
|
||||
locale: string;
|
||||
}
|
||||
|
||||
const { locale } = Astro.props;
|
||||
const strings = await api.strings(locale);
|
||||
---
|
||||
|
||||
<style>
|
||||
.error-display {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
gap: var(--space-4);
|
||||
padding: var(--space-4);
|
||||
box-sizing: border-box;
|
||||
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100dvw;
|
||||
height: 100dvh;
|
||||
|
||||
background-color: var(--gray-1);
|
||||
|
||||
body.error & {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.options {
|
||||
display: flex;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="error-display">
|
||||
<div class="info">
|
||||
<Heading size="2">{strings.error.heading}</Heading>
|
||||
<Text lowContrast>{strings.error.message}</Text>
|
||||
</div>
|
||||
|
||||
<div class="options">
|
||||
<Button variant="outline">{strings.error.view}</Button>
|
||||
|
||||
<Link href="" underline="never">
|
||||
<Button variant="outline">{strings.error.reload}</Button>
|
||||
</Link>
|
||||
|
||||
<Link href={discordLink} target="_blank" underline="never">
|
||||
<Button>{strings.error.support}</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,20 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { ErrorBoundary } from "react-error-boundary";
|
||||
|
||||
interface Props {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export function ErrorWrapper({ children }: Props) {
|
||||
return (
|
||||
<ErrorBoundary
|
||||
fallback={null}
|
||||
onError={() => {
|
||||
console.log("what?");
|
||||
document.body.classList.add("error");
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
import { DiscordLogoIcon, GitHubLogoIcon } from "@radix-ui/react-icons";
|
||||
import packageJson from "../../../../package.json";
|
||||
import { api } from "../api/dynamic";
|
||||
import { discordLink } from "../config/socials";
|
||||
import { BlitzKitIcon } from "../icons/BlitzKit";
|
||||
import { Code } from "./Code";
|
||||
import { Link } from "./Link";
|
||||
@@ -84,11 +85,7 @@ const strings = await api.strings(locale);
|
||||
</div>
|
||||
|
||||
<div class="links">
|
||||
<Link
|
||||
underline="hover"
|
||||
color="gray"
|
||||
href="https://discord.gg/nDt7AjGJQH"
|
||||
>
|
||||
<Link underline="hover" color="gray" href={discordLink}>
|
||||
<DiscordLogoIcon />
|
||||
{strings.companies.discord}
|
||||
</Link>
|
||||
|
||||
@@ -136,6 +136,10 @@ function EquipmentOption({
|
||||
state.protagonist.equipment[equipmentIndex] === optionIndex,
|
||||
);
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
throw "test error";
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
color={isSelected ? undefined : "gray"}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export const discordLink = "https://discord.gg/nDt7AjGJQH";
|
||||
@@ -1,19 +1,19 @@
|
||||
---
|
||||
import ErrorDisplay from "../components/ErrorDisplay.astro";
|
||||
import { api } from "../api/dynamic";
|
||||
import BaseMeta from "../components/BaseMeta.astro";
|
||||
import BaseStyles from "../components/BaseStyles.astro";
|
||||
import ColorAlias from "../components/ColorAlias.astro";
|
||||
import ColorScale from "../components/ColorScale.astro";
|
||||
import Footer from "../components/Footer.astro";
|
||||
import Navbar from "../components/Navbar.astro";
|
||||
import type { Color } from "../ui/color";
|
||||
|
||||
interface Props {
|
||||
locale: string;
|
||||
accent: Color;
|
||||
noNavbar?: boolean;
|
||||
}
|
||||
|
||||
const { accent, noNavbar, locale } = Astro.props;
|
||||
const { accent, locale } = Astro.props;
|
||||
---
|
||||
|
||||
<html lang={locale} class="dark">
|
||||
@@ -73,14 +73,14 @@ const { accent, noNavbar, locale } = Astro.props;
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{!noNavbar && <Navbar {locale} />}
|
||||
|
||||
<slot name="pre-app" />
|
||||
|
||||
<div class="app">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<ErrorDisplay {locale} />
|
||||
|
||||
<Footer {locale} />
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Fragment, useMemo } from "react";
|
||||
import { api } from "../../../../api/dynamic";
|
||||
import { ErrorWrapper } from "../../../../components/ErrorWrapper";
|
||||
import { TankopediaLoadout } from "../../../../components/TankopediaLoadout";
|
||||
import { useAwait } from "../../../../hooks/useAwait";
|
||||
import { useCharacteristicRenderer } from "../../../../hooks/useCharacteristicRenderer";
|
||||
@@ -14,7 +15,15 @@ interface PageProps {
|
||||
locale: string;
|
||||
}
|
||||
|
||||
export function Page({ id, locale }: PageProps) {
|
||||
export function Page(props: PageProps) {
|
||||
return (
|
||||
<ErrorWrapper>
|
||||
<Wrapper {...props} />
|
||||
</ErrorWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
function Wrapper({ id, locale }: PageProps) {
|
||||
const tank = useAwait(() => api.tank(id), `tank-${id}`);
|
||||
|
||||
Tankopedia.useInitialization(tank);
|
||||
|
||||
@@ -19,6 +19,5 @@ const { id, locale } = Astro.props;
|
||||
---
|
||||
|
||||
<BaseLayout {locale} accent="violet">
|
||||
|
||||
<Page {locale} {id} client:load />
|
||||
</BaseLayout>
|
||||
Reference in new issue
Block a user