diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index fda6f7c..72b9238 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -1,5 +1,12 @@
import { Navigate } from "react-router";
+import { useUserContext } from "./context/user-context";
export const App = () => {
+ const { isLoggedIn } = useUserContext();
+
+ if (isLoggedIn) {
+ return ;
+ }
+
return ;
};
diff --git a/frontend/src/components/ui/code.tsx b/frontend/src/components/ui/code.tsx
deleted file mode 100644
index a4bc8cb..0000000
--- a/frontend/src/components/ui/code.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { twMerge } from "tailwind-merge";
-
-interface CodeProps extends React.ComponentPropsWithoutRef<"code"> {
- children?: React.ReactNode;
- className?: string;
-}
-
-function Code({ children, className, ...props }: CodeProps) {
- return (
-
- {children}
-
- );
-}
-
-export { Code };
diff --git a/frontend/src/context/app-context.tsx b/frontend/src/context/app-context.tsx
index 347a06a..b8044f6 100644
--- a/frontend/src/context/app-context.tsx
+++ b/frontend/src/context/app-context.tsx
@@ -1,6 +1,6 @@
import { AppContextSchema } from "@/schemas/app-context-schema";
import { createContext, useContext } from "react";
-import { useQuery } from "@tanstack/react-query";
+import { useSuspenseQuery } from "@tanstack/react-query";
import axios from "axios";
const AppContext = createContext(null);
@@ -10,16 +10,12 @@ export const AppContextProvider = ({
}: {
children: React.ReactNode;
}) => {
- const { isPending, isError, data, error } = useQuery({
- queryKey: ["status"],
+ const { isFetching, data, error } = useSuspenseQuery({
+ queryKey: ["app"],
queryFn: () => axios.get("/api/app").then((res) => res.data),
});
- if (isPending) {
- return;
- }
-
- if (isError) {
+ if (error && !isFetching) {
throw error;
}
diff --git a/frontend/src/context/user-context.tsx b/frontend/src/context/user-context.tsx
new file mode 100644
index 0000000..84130d6
--- /dev/null
+++ b/frontend/src/context/user-context.tsx
@@ -0,0 +1,35 @@
+import { UserContextSchema } from "@/schemas/user-context-schema";
+import { createContext, useContext } from "react";
+import { useSuspenseQuery } from "@tanstack/react-query";
+import axios from "axios";
+
+const UserContext = createContext(null);
+
+export const UserContextProvider = ({
+ children,
+}: {
+ children: React.ReactNode;
+}) => {
+ const { isFetching, data, error } = useSuspenseQuery({
+ queryKey: ["user"],
+ queryFn: () => axios.get("/api/user").then((res) => res.data),
+ });
+
+ if (error && !isFetching) {
+ throw error;
+ }
+
+ return {children};
+};
+
+export const useUserContext = () => {
+ const context = useContext(UserContext);
+
+ if (!context) {
+ throw new Error(
+ "useUserContext must be used within an UserContextProvider",
+ );
+ }
+
+ return context;
+};
diff --git a/frontend/src/index.css b/frontend/src/index.css
index f4c1e9b..c80b837 100644
--- a/frontend/src/index.css
+++ b/frontend/src/index.css
@@ -118,3 +118,59 @@
@apply bg-background text-foreground;
}
}
+
+h1 {
+ @apply scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl;
+}
+
+h2 {
+ @apply scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight first:mt-0;
+}
+
+h3 {
+ @apply scroll-m-20 text-2xl font-semibold tracking-tight;
+}
+
+h4 {
+ @apply scroll-m-20 text-xl font-semibold tracking-tight;
+}
+
+p {
+ @apply leading-7 [&:not(:first-child)]:mt-6;
+}
+
+blockquote {
+ @apply mt-6 border-l-2 pl-6 italic;
+}
+
+tr {
+ @apply m-0 border-t p-0 even:bg-muted;
+}
+
+th {
+ @apply border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right;
+}
+
+ul {
+ @apply my-6 ml-6 list-disc [&>li]:mt-2;
+}
+
+code {
+ @apply relative rounded bg-muted px-[0.2rem] py-[0.1rem] font-mono text-sm font-semibold;
+}
+
+.lead {
+ @apply text-xl text-muted-foreground;
+}
+
+.large {
+ @apply text-lg font-semibold;
+}
+
+small {
+ @apply text-sm font-medium leading-none;
+}
+
+.muted {
+ @apply text-sm text-muted-foreground;
+}
diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx
index edf6c55..3d114db 100644
--- a/frontend/src/main.tsx
+++ b/frontend/src/main.tsx
@@ -14,6 +14,7 @@ import { LogoutPage } from "./pages/logout-page.tsx";
import { UnauthorizedPage } from "./pages/unauthorized-page.tsx";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { AppContextProvider } from "./context/app-context.tsx";
+import { UserContextProvider } from "./context/user-context.tsx";
const router = createBrowserRouter([
{
@@ -64,9 +65,11 @@ createRoot(document.getElementById("root")!).render(
-
-
-
+
+
+
+
+
,
diff --git a/frontend/src/pages/continue-page.tsx b/frontend/src/pages/continue-page.tsx
index 323bd5f..2baf89b 100644
--- a/frontend/src/pages/continue-page.tsx
+++ b/frontend/src/pages/continue-page.tsx
@@ -6,8 +6,8 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
-import { Code } from "@/components/ui/code";
import { useAppContext } from "@/context/app-context";
+import { useUserContext } from "@/context/user-context";
import { isValidUrl } from "@/lib/utils";
import { Trans, useTranslation } from "react-i18next";
import { Navigate, useNavigate } from "react-router";
@@ -16,11 +16,16 @@ export const ContinuePage = () => {
const params = new URLSearchParams(window.location.search);
const redirectURI = params.get("redirect_uri");
+ const { isLoggedIn } = useUserContext();
const { domain, disableContinue } = useAppContext();
const { t } = useTranslation();
const navigate = useNavigate();
+ if (!isLoggedIn) {
+ return ;
+ }
+
if (!redirectURI) {
return ;
}
@@ -37,7 +42,7 @@ export const ContinuePage = () => {
if (!url.hostname.includes(domain)) {
return (
-
+
{t("untrustedRedirectTitle")}
@@ -47,7 +52,7 @@ export const ContinuePage = () => {
i18nKey="untrustedRedirectSubtitle"
t={t}
components={{
- code: ,
+ code: ,
}}
values={{ domain }}
/>
@@ -70,7 +75,7 @@ export const ContinuePage = () => {
if (url.protocol === "http:" && window.location.protocol === "https:") {
return (
-
+
{t("continueInsecureRedirectTitle")}
@@ -80,7 +85,7 @@ export const ContinuePage = () => {
i18nKey="continueInsecureRedirectSubtitle"
t={t}
components={{
- code: ,
+ code: ,
}}
/>
diff --git a/frontend/src/pages/login-page.tsx b/frontend/src/pages/login-page.tsx
index 1278226..cb1b6c2 100644
--- a/frontend/src/pages/login-page.tsx
+++ b/frontend/src/pages/login-page.tsx
@@ -16,6 +16,8 @@ import { useTranslation } from "react-i18next";
export const LoginPage = () => {
const { configuredProviders, title } = useAppContext();
+
+ console.log("Configured providers:", configuredProviders);
const { t } = useTranslation();
const oauthConfigured =
diff --git a/frontend/src/pages/logout-page.tsx b/frontend/src/pages/logout-page.tsx
index 2e65e54..26229a1 100644
--- a/frontend/src/pages/logout-page.tsx
+++ b/frontend/src/pages/logout-page.tsx
@@ -6,18 +6,20 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
-import { Code } from "@/components/ui/code";
import { useAppContext } from "@/context/app-context";
+import { useUserContext } from "@/context/user-context";
import { capitalize } from "@/lib/utils";
import { Trans, useTranslation } from "react-i18next";
+import { Navigate } from "react-router";
export const LogoutPage = () => {
+ const { provider, username, email, isLoggedIn } = useUserContext();
const { genericName } = useAppContext();
const { t } = useTranslation();
- const provider = "google";
- const username = "username";
- const email = "smbd@example.com";
+ if (!isLoggedIn) {
+ return ;
+ }
return (
@@ -29,7 +31,7 @@ export const LogoutPage = () => {
i18nKey="logoutOauthSubtitle"
t={t}
components={{
- code: ,
+ code: ,
}}
values={{
username: email,
@@ -42,7 +44,7 @@ export const LogoutPage = () => {
i18nKey="logoutUsernameSubtitle"
t={t}
components={{
- code: ,
+ code: ,
}}
values={{
username: username,
diff --git a/frontend/src/pages/unauthorized-page.tsx b/frontend/src/pages/unauthorized-page.tsx
index fc4c484..22b4f32 100644
--- a/frontend/src/pages/unauthorized-page.tsx
+++ b/frontend/src/pages/unauthorized-page.tsx
@@ -6,7 +6,6 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
-import { Code } from "@/components/ui/code";
import { Trans, useTranslation } from "react-i18next";
import { Navigate, useNavigate } from "react-router";
@@ -42,7 +41,7 @@ export const UnauthorizedPage = () => {
i18nKey={i18nKey}
t={t}
components={{
- code: ,
+ code: ,
}}
values={{
username: username,