diff --git a/src/app/routes/_authed/tournaments/$tournamentId.tsx b/src/app/routes/_authed/tournaments/$tournamentId.tsx
index 687b0ce..05cff52 100644
--- a/src/app/routes/_authed/tournaments/$tournamentId.tsx
+++ b/src/app/routes/_authed/tournaments/$tournamentId.tsx
@@ -17,7 +17,7 @@ export const Route = createFileRoute('/_authed/tournaments/$tournamentId')({
header: {
collapsed: true,
withBackButton: true,
- settingsLink: context.auth.roles?.includes("Admin") ? `/admin/tournaments/${params.tournamentId}` : undefined
+ settingsLink: context.auth.roles.includes("Admin") ? `/admin/tournaments/${params.tournamentId}` : undefined
},
refresh: {
toRefresh: tournamentQueries.details(params.tournamentId).queryKey,
diff --git a/src/components/DefaultCatchBoundary.tsx b/src/components/DefaultCatchBoundary.tsx
index f750e7b..eb0892c 100644
--- a/src/components/DefaultCatchBoundary.tsx
+++ b/src/components/DefaultCatchBoundary.tsx
@@ -1,53 +1,159 @@
import {
- ErrorComponent,
Link,
rootRouteId,
useMatch,
useRouter,
+ useNavigate,
} from '@tanstack/react-router'
import type { ErrorComponentProps } from '@tanstack/react-router'
+import {
+ Box,
+ Button,
+ Text,
+ Title,
+ Stack,
+ Group,
+ Alert,
+ Collapse,
+ Code,
+ ThemeIcon
+} from '@mantine/core'
+import { useDisclosure } from '@mantine/hooks'
+import { useEffect } from 'react'
+import toast from '@/lib/sonner'
+import { logger } from '@/lib/logger'
+import { ExclamationMarkIcon, XCircleIcon } from '@phosphor-icons/react'
export function DefaultCatchBoundary({ error }: ErrorComponentProps) {
const router = useRouter()
+ const navigate = useNavigate()
const isRoot = useMatch({
strict: false,
select: (state) => state.id === rootRouteId,
})
+ const [detailsOpened, { toggle: toggleDetails }] = useDisclosure(false)
- console.error('DefaultCatchBoundary Error:', error)
+ const errorMessage = error?.message || 'Unknown error'
+ const errorStack = error?.stack || 'No stack trace available'
+
+ useEffect(() => {
+ logger.error('DefaultCatchBoundary | ', error)
+
+ if (errorMessage.toLowerCase().includes('unauthenticated')) {
+ toast.error('You\'ve been logged out')
+ navigate({ to: '/login' })
+ return
+ }
+ }, [error, errorMessage, navigate])
+
+ if (errorMessage.toLowerCase().includes('unauthorized')) {
+ return (
+
+
+
+
+
+ Access Denied
+
+ You don't have permission to access this.
+
+
+
+
+
+
+
+ )
+ }
return (
-
-
-
-
- {isRoot ? (
-
{errorMessage}
+
+
+
+ {errorStack}
+
+
+
+
+
+
-
+ Try Again
+
+ {isRoot ? (
+
+ ) : (
+
+ )}
+
+
+
)
}
diff --git a/src/features/players/components/profile/index.tsx b/src/features/players/components/profile/index.tsx
index e7acc85..c58024e 100644
--- a/src/features/players/components/profile/index.tsx
+++ b/src/features/players/components/profile/index.tsx
@@ -1,4 +1,4 @@
-import { Box, Button, Text } from "@mantine/core";
+import { Box, Button, Text, Title } from "@mantine/core";
import Header from "./header";
import { testEvent } from "@/utils/test-event";
import { Player } from "@/features/players/types";
@@ -17,10 +17,12 @@ const Profile = ({ player }: ProfileProps) => {
},
{
label: "Teams",
- content: Panel 2 content
+ content: <>
+
+ >
},
{
- label: "Stats",
+ label: "Tournaments",
content: Panel 3 content
}
];
@@ -28,13 +30,7 @@ const Profile = ({ player }: ProfileProps) => {
return <>
- {
- console.log(`Switched to ${tab.label} tab`);
- }}
- />
+
>;
};
diff --git a/src/features/players/server.ts b/src/features/players/server.ts
index 3c92255..0356aae 100644
--- a/src/features/players/server.ts
+++ b/src/features/players/server.ts
@@ -1,13 +1,16 @@
-import { setUserMetadata, superTokensFunctionMiddleware } from "@/utils/supertokens";
+import { setUserMetadata, superTokensFunctionMiddleware, verifySuperTokensSession } from "@/utils/supertokens";
import { createServerFn } from "@tanstack/react-start";
import { playerInputSchema, playerUpdateSchema } from "@/features/players/types";
import { pbAdmin } from "@/lib/pocketbase/client";
import { z } from "zod";
import { logger } from ".";
+import { getWebRequest } from "@tanstack/react-start/server";
export const fetchMe = createServerFn()
- .middleware([superTokensFunctionMiddleware])
- .handler(async ({ context }) => {
+ .handler(async ({ response }) => {
+ const request = getWebRequest();
+ const { context } = await verifySuperTokensSession(request, response);
+
if (!context || !context.userAuthId) return { user: undefined, roles: [], metadata: {} };
try {
diff --git a/src/lib/pocketbase/services/tournaments.ts b/src/lib/pocketbase/services/tournaments.ts
index f368b23..879f2bf 100644
--- a/src/lib/pocketbase/services/tournaments.ts
+++ b/src/lib/pocketbase/services/tournaments.ts
@@ -28,7 +28,6 @@ export function createTournamentsService(pb: PocketBase) {
sort: "-created",
});
- console.log(result);
return result.map(transformTournament);
},
async createTournament(data: TournamentInput): Promise {
diff --git a/src/utils/supertokens.ts b/src/utils/supertokens.ts
index f0cbcd1..c5e9d99 100644
--- a/src/utils/supertokens.ts
+++ b/src/utils/supertokens.ts
@@ -10,7 +10,7 @@ import { refreshSession } from "supertokens-node/recipe/session";
const logger = new Logger('Middleware');
-const verifySuperTokensSession = async (request: Request, response?: ServerFnResponseType) => {
+export const verifySuperTokensSession = async (request: Request, response?: ServerFnResponseType) => {
const session = await getSessionForStart(request, { sessionRequired: false });
if (session?.needsRefresh && response) {
@@ -44,9 +44,10 @@ const verifySuperTokensSession = async (request: Request, response?: ServerFnRes
export const superTokensRequestMiddleware = createMiddleware({ type: 'request' })
.server(async ({ next, request }) => {
const session = await verifySuperTokensSession(request);
-
+
if (!session.context.userAuthId) {
logger.error('Unauthenticated user in API call.', session.context)
+ throw new Error("Unauthenticated");
}
const context = {
@@ -65,6 +66,7 @@ export const superTokensFunctionMiddleware = createMiddleware({ type: 'function'
if (!session.context.userAuthId) {
logger.error('Unauthenticated user in server function.', session.context)
+ throw new Error("Unauthenticated");
}
const context = {