mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-08-25 20:50:14 -05:00
Fix 404 page crashing
This commit is contained in:
@@ -27,15 +27,24 @@ export function Catcher() {
|
||||
)}
|
||||
</Main>
|
||||
);
|
||||
case 404:
|
||||
return (
|
||||
<Main>
|
||||
<h2>Error {caught.status} - Page not found</h2>
|
||||
<GetHelp />
|
||||
</Main>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<Main>
|
||||
<h2>Error {caught.status}</h2>
|
||||
{caught.data ? (
|
||||
<code>{JSON.stringify(caught.data, null, 2)}</code>
|
||||
) : null}
|
||||
<GetHelp />
|
||||
</Main>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Main>
|
||||
<h2>Error {caught.status}</h2>
|
||||
{caught.data ? <code>{JSON.stringify(caught.data, null, 2)}</code> : null}
|
||||
<GetHelp />
|
||||
</Main>
|
||||
);
|
||||
}
|
||||
|
||||
function GetHelp() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Link, useLoaderData } from "@remix-run/react";
|
||||
import { Link } from "@remix-run/react";
|
||||
import type { RootLoaderData } from "~/root";
|
||||
import { discordFullName } from "~/utils/strings";
|
||||
import {
|
||||
@@ -16,9 +16,11 @@ import { PatreonIcon } from "../icons/Patreon";
|
||||
import { TwitterIcon } from "../icons/Twitter";
|
||||
import { Image } from "../Image";
|
||||
|
||||
export function Footer() {
|
||||
const data = useLoaderData<RootLoaderData>();
|
||||
|
||||
export function Footer({
|
||||
patrons = [],
|
||||
}: {
|
||||
patrons?: RootLoaderData["patrons"];
|
||||
}) {
|
||||
return (
|
||||
<footer className="layout__footer">
|
||||
<div className="layout__footer__link-list">
|
||||
@@ -71,7 +73,7 @@ export function Footer() {
|
||||
<PatreonIcon className="layout__footer__social-icon patreon" />
|
||||
</a>
|
||||
</div>
|
||||
{data.patrons.length > 0 ? (
|
||||
{patrons.length > 0 ? (
|
||||
<div>
|
||||
<h4 className="layout__footer__patron-title">
|
||||
Thanks to the patrons for the support
|
||||
@@ -83,7 +85,7 @@ export function Footer() {
|
||||
/>
|
||||
</h4>
|
||||
<ul className="layout__footer__patron-list">
|
||||
{data.patrons.map((patron) => (
|
||||
{patrons.map((patron) => (
|
||||
<li key={patron.id}>
|
||||
<Link to={userPage(patron.discordId)}>
|
||||
{discordFullName(patron)}
|
||||
|
||||
@@ -6,11 +6,14 @@ import navItems from "./nav-items.json";
|
||||
import { useLocation } from "@remix-run/react";
|
||||
import { Image } from "../Image";
|
||||
import { Footer } from "./Footer";
|
||||
import type { RootLoaderData } from "~/root";
|
||||
|
||||
export const Layout = React.memo(function Layout({
|
||||
children,
|
||||
patrons,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
patrons?: RootLoaderData["patrons"];
|
||||
}) {
|
||||
const location = useLocation();
|
||||
const [menuOpen, setMenuOpen] = React.useState(false);
|
||||
@@ -46,7 +49,7 @@ export const Layout = React.memo(function Layout({
|
||||
</header>
|
||||
<Menu expanded={menuOpen} closeMenu={() => setMenuOpen(false)} />
|
||||
{children}
|
||||
<Footer />
|
||||
<Footer patrons={patrons} />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
29
app/root.tsx
29
app/root.tsx
@@ -1,10 +1,9 @@
|
||||
import type {
|
||||
LinksFunction,
|
||||
LoaderFunction,
|
||||
MetaFunction,
|
||||
import {
|
||||
json,
|
||||
type LinksFunction,
|
||||
type LoaderFunction,
|
||||
type MetaFunction,
|
||||
} from "@remix-run/node";
|
||||
import { json } from "@remix-run/node";
|
||||
import type { ShouldReloadFunction } from "@remix-run/react";
|
||||
import {
|
||||
Links,
|
||||
LiveReload,
|
||||
@@ -12,6 +11,8 @@ import {
|
||||
Outlet,
|
||||
Scripts,
|
||||
ScrollRestoration,
|
||||
useLoaderData,
|
||||
type ShouldReloadFunction,
|
||||
} from "@remix-run/react";
|
||||
import * as React from "react";
|
||||
import commonStyles from "~/styles/common.css";
|
||||
@@ -66,7 +67,13 @@ export const loader: LoaderFunction = async ({ request }) => {
|
||||
});
|
||||
};
|
||||
|
||||
function Document({ children }: { children: React.ReactNode }) {
|
||||
function Document({
|
||||
children,
|
||||
patrons,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
patrons?: RootLoaderData["patrons"];
|
||||
}) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<head>
|
||||
@@ -76,7 +83,7 @@ function Document({ children }: { children: React.ReactNode }) {
|
||||
</head>
|
||||
<body>
|
||||
<React.StrictMode>
|
||||
<Layout>{children}</Layout>
|
||||
<Layout patrons={patrons}>{children}</Layout>
|
||||
</React.StrictMode>
|
||||
<ScrollRestoration />
|
||||
<Scripts />
|
||||
@@ -87,8 +94,12 @@ function Document({ children }: { children: React.ReactNode }) {
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
// prop drilling patrons instead of using useLoaderData in the Footer directly because
|
||||
// useLoaderData can't be used in CatchBoundary and Footer is rendered in it as well
|
||||
const data = useLoaderData<RootLoaderData>();
|
||||
|
||||
return (
|
||||
<Document>
|
||||
<Document patrons={data.patrons}>
|
||||
<Outlet />
|
||||
</Document>
|
||||
);
|
||||
|
||||
8
cypress/e2e/misc.cy.ts
Normal file
8
cypress/e2e/misc.cy.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export {};
|
||||
|
||||
describe("404 page", () => {
|
||||
it("should say 404 if accessing URL that doesn't exist", () => {
|
||||
cy.visit("/plus/idonotexist", { failOnStatusCode: false });
|
||||
cy.contains("404");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user