Skip to content

Commit

Permalink
Merge branch 'main' into PennyWalker-patch-3
Browse files Browse the repository at this point in the history
  • Loading branch information
Calinator444 committed Nov 27, 2024
2 parents d9c7987 + 5989a3a commit 0a322ab
Show file tree
Hide file tree
Showing 39 changed files with 320 additions and 88 deletions.
11 changes: 11 additions & 0 deletions app/articles/[filename]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import { TODAY } from "hooks/useFetchEvents";
import { useSEO } from "hooks/useSeo";
import { Metadata } from "next";
import ArticlePage, { ArticleData, ArticlePageProps } from ".";

export const dynamicParams = false;

type Articles = Awaited<ReturnType<typeof client.queries.articlesConnection>>;

const getData = async (
filename: string
): Promise<{
Expand All @@ -22,6 +27,12 @@ const getData = async (
};
};

export async function generateStaticParams(): Promise<{ filename: string }[]> {
const articles: Articles = await client.queries.articlesConnection();
return articles.data.articlesConnection.edges.map((edge) => {
return { filename: edge.node._sys.filename };
});
}
export async function generateMetadata({
params,
}: {
Expand Down
33 changes: 33 additions & 0 deletions app/components/global-error-handler.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"use client";
import { useAppInsightsContext } from "@microsoft/applicationinsights-react-js";
import React, { useEffect } from "react";
function GlobalErrorHandler({ error, children }) {
const appInsights = useAppInsightsContext();
useEffect(() => {
if (!appInsights) {
// eslint-disable-next-line no-console
console.error("AppInsights not initialized");
}

try {
appInsights.trackException({
exception: error,
properties: {
Request: `GET /${window?.location?.pathname || "unknown"}`,
Type: "ErrorBoundary",
ErrorInfo: error.stack || error.message,
},
});
// eslint-disable-next-line no-console
console.log("error", error);
// eslint-disable-next-line no-console
console.log("appInsights client", appInsights);
} catch (e) {
// eslint-disable-next-line no-console
console.error("Error in tracking exception", e.message);
}
}, [appInsights, error]);
return <>{children}</>;
}

export default GlobalErrorHandler;
17 changes: 17 additions & 0 deletions app/components/page-layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Footer } from "@/components/layout/footer/footer";

type PageLayoutProps = {
children: React.ReactNode;
megaMenu: React.ReactNode;
};
const PageLayout = ({ children, megaMenu }: PageLayoutProps) => {
return (
<div className="flex min-h-screen flex-col">
<header className="no-print">{megaMenu}</header>
<main className="grow bg-white">{children}</main>
<Footer />
</div>
);
};

export default PageLayout;
17 changes: 17 additions & 0 deletions app/error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"use client";
import { ErrorPage } from "@/components/util/error-page";
import GlobalErrorHandler from "./components/global-error-handler";
export const Error = ({
error,
}: {
error: Error & { digest?: string };
reset: () => void;
}) => {
return (
<GlobalErrorHandler error={error}>
<ErrorPage details={error.message} />
</GlobalErrorHandler>
);
};

export default Error;
80 changes: 80 additions & 0 deletions app/global-error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"use client";
import { MegaMenuWrapper } from "@/components/server/MegaMenuWrapper";
import { ErrorPage } from "@/components/util/error-page";
import { ReactPlugin } from "@microsoft/applicationinsights-react-js";
import { ApplicationInsights } from "@microsoft/applicationinsights-web";
import { Inter } from "next/font/google";
import { useEffect } from "react";
import "styles.css";
import menu from "../content/megamenu/menu.json";
import { MenuWrapper } from "./components/MenuWrapper";
import PageLayout from "./components/page-layout";

// Error boundaries must be Client Components

const inter = Inter({
variable: "--inter-font",
subsets: ["latin"],
display: "swap",
weight: ["400", "600", "700"],
});

export default function GlobalError({ error }: { error: Error }) {
useEffect(() => {
const reactPlugin = new ReactPlugin();
const appInsights = new ApplicationInsights({
config: {
connectionString: process.env.NEXT_PUBLIC_APP_INSIGHT_CONNECTION_STRING,
extensions: [reactPlugin],
autoExceptionInstrumented: true,
autoTrackPageVisitTime: true,
enableRequestHeaderTracking: true,
enableResponseHeaderTracking: true,
enableAjaxErrorStatusText: true,
distributedTracingMode: 0,
loggingLevelTelemetry: 1,
loggingLevelConsole: 1,
extensionConfig: {
[reactPlugin.identifier]: {},
},
disablePageUnloadEvents: ["unload"],
},
});

if (appInsights.config.connectionString) {
appInsights.loadAppInsights();
appInsights.trackException({
exception: error,
properties: {
Request: `GET /${window?.location?.pathname || "unknown"}`,
Type: "ErrorBoundary",
ErrorInfo: error.stack || error.message,
},
});
} else {
// eslint-disable-next-line no-console
console.error(
"Failed to log root layout exception to Application Insights!"
);
}
}, [error]);

const errorDetails = error.stack || error.message;
return (
<html lang="en" className={inter.className}>
<body>
<PageLayout megaMenu={MegaMenu()}>
<ErrorPage details={errorDetails}></ErrorPage>
</PageLayout>
</body>
</html>
);
}

const MegaMenu = () => {
return (
<MenuWrapper>
<MegaMenuWrapper menuBarItems={menu.menuGroups} />
</MenuWrapper>
);
};
64 changes: 38 additions & 26 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import { Footer } from "@/components/layout/footer/footer";
import { MegaMenuWrapper } from "@/components/server/MegaMenuWrapper";
import dynamic from "next/dynamic";
import "styles.css";

import { AppInsightsProvider } from "@/context/app-insight-client";
import { EventInfoStatic } from "@/services/server/events";
import { GoogleTagManager } from "@next/third-parties/google";
Expand All @@ -13,14 +9,17 @@ import relativeTime from "dayjs/plugin/relativeTime";
import timezone from "dayjs/plugin/timezone";
import utc from "dayjs/plugin/utc";
import { Metadata, Viewport } from "next";
import dynamic from "next/dynamic";
import { Inter } from "next/font/google";
import "styles.css";
import client from "../tina/__generated__/client";
import { MenuWrapper } from "./components/MenuWrapper";
import PageLayout from "./components/page-layout";
import { WebVitals } from "./components/web-vitals";
import { LiveStream } from "./live-steam-banner/live-stream";
import { DEFAULT } from "./meta-data/default";
import { QueryProvider } from "./providers/query-provider";
import { getMegamenu } from "./utils/get-mega-menu";
import { getMegamenu, MegaMenuProps } from "./utils/get-mega-menu";

dayjs.extend(relativeTime);
dayjs.extend(timezone);
Expand Down Expand Up @@ -73,31 +72,44 @@ export default async function RootLayout({
<QueryProvider>
{/* <Theme> */}
{/* Ensures next/font CSS variable is accessible for all components */}
<div className="flex min-h-screen flex-col">
<header className="no-print">
{liveStreamData ? (
<LiveStream event={liveStreamData}>
<MegaMenuWrapper menu={menuData.data.megamenu.menuGroups} />
</LiveStream>
) : (
<MenuWrapper>
<MegaMenuWrapper menu={menuData.data.megamenu.menuGroups} />
</MenuWrapper>
)}
</header>
<main className="grow bg-white">
<AppInsightsProvider>
<WebVitals />
{children}
</AppInsightsProvider>
</main>
<Footer />
</div>
{/* </Theme> */}
<PageLayout
megaMenu={MegaMenu({
menuData: menuData,
liveStreamData: liveStreamData,
})}
>
<AppInsightsProvider>
<WebVitals />
{children}
</AppInsightsProvider>
{/* </Theme> */}
</PageLayout>
<GoogleTagManager gtmId={process.env.NEXT_PUBLIC_GOOGLE_GTM_ID} />
<ChatBaseBot />
</QueryProvider>
</body>
</html>
);
}

const MegaMenu = ({
liveStreamData,
menuData,
}: {
liveStreamData: EventInfoStatic;
menuData: MegaMenuProps;
}) => {
return (
<>
{liveStreamData ? (
<LiveStream event={liveStreamData}>
<MegaMenuWrapper menu={menuData.data.megamenu.menuGroups} />
</LiveStream>
) : (
<MenuWrapper>
<MegaMenuWrapper menu={menuData.data.megamenu.menuGroups} />
</MenuWrapper>
)}
</>
);
};
1 change: 1 addition & 0 deletions app/utils/get-mega-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export const getMegamenu = cache(async () => {

return data;
});
export type MegaMenuProps = Awaited<ReturnType<typeof client.queries.megamenu>>;
57 changes: 30 additions & 27 deletions components/util/error-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import { BiChevronRight } from "react-icons/bi";
import { FaXmark } from "react-icons/fa6";
import { LiveStreamData } from "../layout/layout";

type ErrorPageProps = {
//TODO: consolidate all of the error components into one https://github.com/SSWConsulting/SSW.Website/issues/3350

export type ErrorPageProps = {
code?: string;
title?: string;
tipText?: React.ReactNode;
Expand All @@ -25,13 +27,13 @@ export const ErrorPage = (props: ErrorPageProps) => {
className={classNames(
"w-full",
"select-none",
"bg-[url('/images/404/broken-chain.png')] bg-center bg-no-repeat md:bg-bottom"
"bg-errorPage bg-center bg-no-repeat md:bg-bottom"
)}
>
<div className="flex min-h-screen-4/5 flex-col md:flex-row">
<div className="px-7 pt-7">
<div className="flex min-h-screen-4/5 flex-col md:flex-row md:gap-7 lg:gap-14">
<div className="md:pt-7">
<p className="text-center">
<span className="font-sans text-9xl font-extrabold leading-none text-sswRed">
<span className="font-sans text-8xl font-extrabold leading-none text-sswRed sm:text-9xl">
{props.code || "Error"}
</span>
</p>
Expand Down Expand Up @@ -82,7 +84,7 @@ type ErrorTextProps = {

export const ErrorText = (props: ErrorTextProps) => {
return (
<div className="py-12">
<div className="overflow-x-hidden py-4 md:py-12">
{props.exitButtonCallback && (
<div className="flex justify-end">
<button
Expand All @@ -94,16 +96,15 @@ export const ErrorText = (props: ErrorTextProps) => {
</div>
)}
<span
className="font-sans text-3xl font-extralight text-gray-650 md:text-5xl"
className="font-sans font-extralight text-gray-650"
style={{ wordBreak: "break-word" }}
>
<h1 className="mt-0 pb-1 pt-0 text-5xl">
<h1 className="mt-0 pb-1 pt-0 text-3xl sm:text-5xl">
{props.title || "We're sorry, something has gone wrong here."}
</h1>
{props.tipText || (
<div>
<h1 className="pb-1 pt-0 text-4xl"></h1>
<p className="pt-4 text-xl">
<p className="pt-4">
For help, please submit a bug report issue on our GitHub at{" "}
<a href="https://github.com/SSWConsulting/SSW.Website/issues/new/choose">
github.com/SSWConsulting/SSW.Website
Expand All @@ -115,23 +116,25 @@ export const ErrorText = (props: ErrorTextProps) => {
)}
</span>
{props.details && (
<Disclosure>
{({ open }) => (
<>
<Disclosure.Button>
<div className="flex flex-row items-center font-extralight text-gray-650">
See details{" "}
<BiChevronRight className={open ? "rotate-90" : ""} />
</div>
</Disclosure.Button>
<Disclosure.Panel>
<pre>
<code>{props.details}</code>
</pre>
</Disclosure.Panel>
</>
)}
</Disclosure>
<div className="min-h-40">
<Disclosure>
{({ open }) => (
<>
<Disclosure.Button className={"mt-5"}>
<div className="flex flex-row items-center font-extralight text-gray-650">
See details{" "}
<BiChevronRight className={open ? "rotate-90" : ""} />
</div>
</Disclosure.Button>
<Disclosure.Panel className={"overflow-x-auto"}>
<pre>
<code>{props.details}</code>
</pre>
</Disclosure.Panel>
</>
)}
</Disclosure>
</div>
)}
</div>
);
Expand Down
Loading

0 comments on commit 0a322ab

Please sign in to comment.