diff --git a/apps/web-tss/package.json b/apps/web-tss/package.json
index bc822444b..13c636d9e 100644
--- a/apps/web-tss/package.json
+++ b/apps/web-tss/package.json
@@ -13,6 +13,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
+ "posthog-js": "^1.259.0",
"@buster/server-shared": "workspace:*",
"@buster/typescript-config": "workspace:*",
"@faker-js/faker": "^9.9.0",
diff --git a/apps/web-tss/src/components/features/global/GlobalErrorCard.tsx b/apps/web-tss/src/components/features/global/GlobalErrorCard.tsx
new file mode 100644
index 000000000..71fcbd7b1
--- /dev/null
+++ b/apps/web-tss/src/components/features/global/GlobalErrorCard.tsx
@@ -0,0 +1,50 @@
+import { type ErrorRouteComponent, Link } from '@tanstack/react-router';
+import { usePostHog } from 'posthog-js/react';
+import { useEffect } from 'react';
+import { Button } from '@/components/ui/buttons';
+import { Card, CardContent, CardFooter } from '@/components/ui/card/CardBase';
+
+const ErrorCard = () => {
+ return (
+
+
+
+
+
Looks like we hit an unexpected error
+
+
+ {`Our team has been notified via Slack. We'll take a look at the issue ASAP and get back to you.`}
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export const GlobalErrorCard: ErrorRouteComponent = ({ error }) => {
+ const posthog = usePostHog();
+
+ useEffect(() => {
+ const isPosthogLoaded = posthog.__loaded;
+
+ if (isPosthogLoaded) {
+ posthog.captureException(error);
+ }
+
+ console.error(error);
+ }, [error]);
+
+ return ;
+};
diff --git a/apps/web-tss/src/components/features/global/NotFoundCard.tsx b/apps/web-tss/src/components/features/global/NotFoundCard.tsx
new file mode 100644
index 000000000..12d0e093c
--- /dev/null
+++ b/apps/web-tss/src/components/features/global/NotFoundCard.tsx
@@ -0,0 +1,13 @@
+import { Link, type NotFoundRouteComponent } from '@tanstack/react-router';
+
+export const NotFoundCard: NotFoundRouteComponent = () => {
+ return (
+
+
Page not found
+
The page you are looking for does not exist.
+
+ Go back home
+
+
+ );
+};
diff --git a/apps/web-tss/src/config/index.ts b/apps/web-tss/src/config/index.ts
deleted file mode 100644
index ed4b1e2f5..000000000
--- a/apps/web-tss/src/config/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './dev';
-export * from './languages';
diff --git a/apps/web-tss/src/data/demo-table-data.ts b/apps/web-tss/src/data/demo-table-data.ts
deleted file mode 100644
index ca77c2270..000000000
--- a/apps/web-tss/src/data/demo-table-data.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-export type Person = {
- id: number;
- firstName: string;
- lastName: string;
- age: number;
- visits: number;
- progress: number;
- status: 'relationship' | 'complicated' | 'single';
- subRows?: Person[];
-};
-
-const range = (len: number): number[] => {
- const arr: number[] = [];
- for (let i = 0; i < len; i += 1) arr.push(i);
- return arr;
-};
-
-const makePerson = (num: number): Person => {
- const statuses: Person['status'][] = ['relationship', 'complicated', 'single'];
- return {
- id: num,
- firstName: `First${num}`,
- lastName: `Last${num}`,
- age: (num % 40) + 1,
- visits: (num * 17) % 1_000,
- progress: (num * 7) % 100,
- status: statuses[num % statuses.length]
- };
-};
-
-export function makeData(...lens: number[]): Person[] {
- const makeDataLevel = (depth = 0): Person[] => {
- const len = lens[depth] ?? 0;
- return range(len).map((index): Person => {
- return {
- ...makePerson(index),
- subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined
- };
- });
- };
-
- return makeDataLevel();
-}
diff --git a/apps/web-tss/src/lib/language.ts b/apps/web-tss/src/lib/language.ts
index 26137edb1..954599b47 100644
--- a/apps/web-tss/src/lib/language.ts
+++ b/apps/web-tss/src/lib/language.ts
@@ -1,4 +1,4 @@
-import { SupportedLanguages } from '@/config';
+import { SupportedLanguages } from '@/config/languages';
export const ACCEPTED_LANGUAGES: SupportedLanguages[] = [...Object.values(SupportedLanguages)];
@@ -30,8 +30,8 @@ export const getUserAcceptedLanguage = (language: string): SupportedLanguages =>
export const embedLanguageOptions = [
{
label: 'English (en)',
- value: SupportedLanguages.EN
- }
+ value: SupportedLanguages.EN,
+ },
/* {
label: 'German (de)',
value: SupportedLanguages.DE
diff --git a/apps/web-tss/src/routes/__root.tsx b/apps/web-tss/src/routes/__root.tsx
index a31a3822e..0e409298d 100644
--- a/apps/web-tss/src/routes/__root.tsx
+++ b/apps/web-tss/src/routes/__root.tsx
@@ -1,4 +1,6 @@
import { createRootRouteWithContext, HeadContent, Link, Scripts } from '@tanstack/react-router';
+import { GlobalErrorCard } from '@/components/features/global/GlobalErrorCard';
+import { NotFoundCard } from '@/components/features/global/NotFoundCard';
import { AppProviders } from '@/context/AppProviders';
import { getSupabaseUser } from '../integrations/supabase/getSupabaseUserContext';
import { TanstackDevtools } from '../integrations/tanstack-dev-tools/tanstack-devtools';
@@ -21,8 +23,9 @@ export const Route = createRootRouteWithContext()({
],
links: [{ rel: 'stylesheet', href: appCss }],
}),
- notFoundComponent: NotFound,
+ notFoundComponent: NotFoundCard,
shellComponent: RootDocument,
+ errorComponent: GlobalErrorCard,
beforeLoad: async () => {
const supabaseConfig = await getSupabaseUser();
return supabaseConfig;
@@ -48,16 +51,3 @@ function RootDocument({ children }: { children: React.ReactNode }) {