New source found from dndbeyond.com

This commit is contained in:
2026-07-08 01:00:09 -07:00
parent 9a983a6d7b
commit dcefa0d2f2
2865 changed files with 222467 additions and 49053 deletions
+58 -14
View File
@@ -1,10 +1,10 @@
import clsx from "clsx";
import { FC, HTMLAttributes } from "react";
import { useMatch } from "react-router-dom";
import { createPortal } from "react-dom";
import { useMatch, useSearchParams } from "react-router-dom";
import { NavigationMenu } from "@dndbeyond/navigation-menu";
import { Footer } from "@dndbeyond/ttui/components/Footer";
import { MegaMenu } from "@dndbeyond/ttui/components/MegaMenu";
import { Sitebar } from "@dndbeyond/ttui/components/Sitebar";
import config from "~/config";
import useUser from "~/hooks/useUser";
@@ -13,9 +13,40 @@ import styles from "./styles.module.css";
const BASE_PATHNAME = config.basePathname;
const NOTIFICATIONS_CACHE_KEY = "dndbNotificationsCache";
const seedNotificationsCache = () => {
try {
const existing = localStorage.getItem(NOTIFICATIONS_CACHE_KEY);
const parsed = existing ? JSON.parse(existing) : null;
const isValid =
parsed &&
typeof parsed.expiresAtMs === "number" &&
Date.now() < parsed.expiresAtMs;
if (!isValid) {
localStorage.setItem(
NOTIFICATIONS_CACHE_KEY,
JSON.stringify({
expiresAtMs: Date.now() + 60 * 60 * 1000,
counts: {
unreadNotifications: null,
unreadMessages: null,
unreadReports: null,
unreadAppeals: null,
},
})
);
}
} catch {
// localStorage unavailable
}
};
interface LayoutProps extends HTMLAttributes<HTMLDivElement> {}
export const Layout: FC<LayoutProps> = ({ children, ...props }) => {
const [searchParams] = useSearchParams();
const isVttView = searchParams.get("view") === "vtt";
const isDev = process.env.NODE_ENV === "development";
const user = useUser();
const matchSheet = useMatch(`${BASE_PATHNAME}/:characterId/`);
@@ -23,20 +54,33 @@ export const Layout: FC<LayoutProps> = ({ children, ...props }) => {
// Don't show the navigation in production
if (!isDev) return <>{children}</>;
// Seed the notifications cache so NavigationMenu skips the JWT fetch in local
// dev, where the auth service is not proxied.
seedNotificationsCache();
const navigationUser =
user && user.avatarUrl
? {
displayName: user.displayName,
avatarUrl: user.avatarUrl,
subscriptionTier: user.subscriptionTier as "Master",
roles: user.roles,
}
: undefined;
return (
<div {...props}>
{/* TODO: fetch navItems */}
<div className={styles.siteStyles}>
<Sitebar user={user as any} navItems={[]} />
{/* TODO: fetch sources */}
<MegaMenu enablePartyWizard={true} sources={[]} />
</div>
{!isVttView &&
createPortal(
<NavigationMenu user={navigationUser} />,
document.getElementById("header-wrapper")!
)}
<div className={clsx(["container", styles.devContainer])}>{children}</div>
{!matchSheet && (
<div className={styles.siteStyles}>
<Footer />
</div>
)}
{!isVttView &&
(!matchSheet ||
matchSheet.pathname === "/characters/builder" ||
matchSheet.pathname === "/characters/premade") &&
createPortal(<Footer />, document.getElementById("footer-wrapper")!)}
</div>
);
};