From ae6e53bb9c40d73e77a1e0d813791378f6cfca10 Mon Sep 17 00:00:00 2001 From: Martin Alexander Kaminski Date: Mon, 19 Oct 2026 18:56:40 +0200 Subject: [PATCH 01/11] build: add simple icons react package to frontend --- frontend/package.json | 1 + frontend/pnpm-lock.yaml | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/frontend/package.json b/frontend/package.json index 07db717..3f41fe0 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -22,6 +22,7 @@ "@apollo/client": "^4.3.1", "@base-ui/react": "^1.8.0", "@fontsource-variable/inter": "^5.3.0", + "@icons-pack/react-simple-icons": "^13.15.1", "@react-router/node": "^8.4.0", "@react-router/serve": "^8.4.0", "@tailwindcss/vite": "^4.3.3", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 3c76004..2be6852 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -17,6 +17,9 @@ importers: '@fontsource-variable/inter': specifier: ^5.3.0 version: 5.3.0 + '@icons-pack/react-simple-icons': + specifier: ^13.15.1 + version: 13.15.1(react@19.3.0) '@react-router/node': specifier: ^8.4.0 version: 8.4.0(react-router@8.4.0(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(typescript@6.0.3) @@ -895,6 +898,11 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} + '@icons-pack/react-simple-icons@13.15.1': + resolution: {integrity: sha512-S35E7vJlJzMeoqjwwI7ZmQUJ2W+2KspnB6bc49KdoDGwp5mCgAy9L3sscfWMewQSMgBdPU8KWWwpSGq5DJyAFw==} + peerDependencies: + react: ^16.13 || ^17 || ^18 || ^19 + '@inquirer/ansi@2.0.9': resolution: {integrity: sha512-0Ywt3S8tqM6TWUcsRlBFQ1x+X3/o8kktX0ZiKAnByYb9GFDknnOhse1PVtfiD2BXPI8ar+BWx9PV9R0lQIcygw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -4990,6 +4998,10 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} + '@icons-pack/react-simple-icons@13.15.1(react@19.3.0)': + dependencies: + react: 19.3.0 + '@inquirer/ansi@2.0.9': {} '@inquirer/checkbox@5.2.6(@types/node@24.19.1)': From 1dc44e36fde7f2fe38f0570632a805a052e58c89 Mon Sep 17 00:00:00 2001 From: Martin Alexander Kaminski Date: Mon, 19 Oct 2026 18:58:57 +0200 Subject: [PATCH 02/11] feat: add GitHub OAuth --- backend/.env.example | 3 +++ backend/src/auth/index.ts | 6 ++++++ frontend/.env.example | 1 + frontend/app/routes/login.tsx | 13 +++++++++++++ frontend/app/routes/signup.tsx | 13 +++++++++++++ 5 files changed, 36 insertions(+) create mode 100644 frontend/.env.example diff --git a/backend/.env.example b/backend/.env.example index 2330c3e..42af71c 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -5,3 +5,6 @@ FRONTEND_URL=http://localhost:5173 # Add a random string here # In order to generate one, you may use this command: openssl rand -base64 32 BETTER_AUTH_SECRET= + +GITHUB_CLIENT_ID= +GITHUB_CLIENT_SECRET= diff --git a/backend/src/auth/index.ts b/backend/src/auth/index.ts index d7b263c..971bd2f 100644 --- a/backend/src/auth/index.ts +++ b/backend/src/auth/index.ts @@ -11,5 +11,11 @@ export const auth = betterAuth({ emailAndPassword: { enabled: true, }, + socialProviders: { + github: { + clientId: process.env.GITHUB_CLIENT_ID ?? "", + clientSecret: process.env.GITHUB_CLIENT_SECRET ?? "", + }, + }, trustedOrigins: [process.env.FRONTEND_URL ?? "http://localhost:5173"], }); diff --git a/frontend/.env.example b/frontend/.env.example new file mode 100644 index 0000000..dd4f002 --- /dev/null +++ b/frontend/.env.example @@ -0,0 +1 @@ +VITE_APP_URL=http://localhost:5173 diff --git a/frontend/app/routes/login.tsx b/frontend/app/routes/login.tsx index 147ca44..6dfec2a 100644 --- a/frontend/app/routes/login.tsx +++ b/frontend/app/routes/login.tsx @@ -21,6 +21,7 @@ import { import { Input } from "~/components/ui/Input"; import { Spinner } from "~/components/ui/Spinner"; import { toast } from "~/components/ui/Toast"; +import { SiGithub } from "@icons-pack/react-simple-icons"; const formSchema = z.object({ email: z.email("Enter a valid email address."), @@ -149,6 +150,18 @@ export default function LoginPage() { )} +

Don't have an account?{" "} diff --git a/frontend/app/routes/signup.tsx b/frontend/app/routes/signup.tsx index 3103002..92b5734 100644 --- a/frontend/app/routes/signup.tsx +++ b/frontend/app/routes/signup.tsx @@ -22,6 +22,7 @@ import { import { Input } from "~/components/ui/Input"; import { Spinner } from "~/components/ui/Spinner"; import { toast } from "~/components/ui/Toast"; +import { SiGithub } from "@icons-pack/react-simple-icons"; // Matches better-auth's default minPasswordLength. const MIN_PASSWORD_LENGTH = 8; @@ -230,6 +231,18 @@ export default function SignupPage() { )} +

Already have an account?{" "} From df9eb273ca50573720a608ed7312480723c68566 Mon Sep 17 00:00:00 2001 From: Martin Alexander Kaminski Date: Mon, 19 Oct 2026 18:59:19 +0200 Subject: [PATCH 03/11] feat: give all buttons cursor-pointer --- frontend/app/components/ui/Button.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/app/components/ui/Button.tsx b/frontend/app/components/ui/Button.tsx index 4212cbb..1dd6b2e 100644 --- a/frontend/app/components/ui/Button.tsx +++ b/frontend/app/components/ui/Button.tsx @@ -3,7 +3,7 @@ import { cva, type VariantProps } from "class-variance-authority"; import { cn } from "cn"; const buttonVariants = cva( - "group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", + "group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none cursor-pointer focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", { variants: { variant: { From 39ef62ac7a5e4d161a6cfef6474df8f448528bf7 Mon Sep 17 00:00:00 2001 From: Martin Alexander Kaminski Date: Mon, 19 Oct 2026 19:38:20 +0200 Subject: [PATCH 04/11] feat: add Collapsible component from shadcn --- frontend/app/components/ui/Collapsible.tsx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 frontend/app/components/ui/Collapsible.tsx diff --git a/frontend/app/components/ui/Collapsible.tsx b/frontend/app/components/ui/Collapsible.tsx new file mode 100644 index 0000000..4b242f7 --- /dev/null +++ b/frontend/app/components/ui/Collapsible.tsx @@ -0,0 +1,19 @@ +import { Collapsible as CollapsiblePrimitive } from "@base-ui/react/collapsible" + +function Collapsible({ ...props }: CollapsiblePrimitive.Root.Props) { + return +} + +function CollapsibleTrigger({ ...props }: CollapsiblePrimitive.Trigger.Props) { + return ( + + ) +} + +function CollapsibleContent({ ...props }: CollapsiblePrimitive.Panel.Props) { + return ( + + ) +} + +export { Collapsible, CollapsibleTrigger, CollapsibleContent } From 7fbd1d998545a93cf27e5d1bf29eaba1f09a31cb Mon Sep 17 00:00:00 2001 From: Martin Alexander Kaminski Date: Mon, 19 Oct 2026 19:39:16 +0200 Subject: [PATCH 05/11] feat: add sign in with Discord --- backend/.env.example | 3 +++ backend/src/auth/index.ts | 4 ++++ frontend/app/routes/login.tsx | 40 +++++++++++++++++++++++++++++++++- frontend/app/routes/signup.tsx | 40 +++++++++++++++++++++++++++++++++- 4 files changed, 85 insertions(+), 2 deletions(-) diff --git a/backend/.env.example b/backend/.env.example index 42af71c..9600c13 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -8,3 +8,6 @@ BETTER_AUTH_SECRET= GITHUB_CLIENT_ID= GITHUB_CLIENT_SECRET= + +DISCORD_CLIENT_ID= +DISCORD_CLIENT_SECRET= diff --git a/backend/src/auth/index.ts b/backend/src/auth/index.ts index 971bd2f..3b59217 100644 --- a/backend/src/auth/index.ts +++ b/backend/src/auth/index.ts @@ -16,6 +16,10 @@ export const auth = betterAuth({ clientId: process.env.GITHUB_CLIENT_ID ?? "", clientSecret: process.env.GITHUB_CLIENT_SECRET ?? "", }, + discord: { + clientId: process.env.DISCORD_CLIENT_ID ?? "", + clientSecret: process.env.DISCORD_CLIENT_SECRET ?? "", + }, }, trustedOrigins: [process.env.FRONTEND_URL ?? "http://localhost:5173"], }); diff --git a/frontend/app/routes/login.tsx b/frontend/app/routes/login.tsx index 6dfec2a..0134c6b 100644 --- a/frontend/app/routes/login.tsx +++ b/frontend/app/routes/login.tsx @@ -21,7 +21,13 @@ import { import { Input } from "~/components/ui/Input"; import { Spinner } from "~/components/ui/Spinner"; import { toast } from "~/components/ui/Toast"; -import { SiGithub } from "@icons-pack/react-simple-icons"; +import { SiDiscord, SiGithub } from "@icons-pack/react-simple-icons"; +import { + Collapsible, + CollapsibleContent, + CollapsibleTrigger, +} from "~/components/ui/collapsible"; +import { ChevronDown, ChevronUp } from "lucide-react"; const formSchema = z.object({ email: z.email("Enter a valid email address."), @@ -35,6 +41,7 @@ export function meta() { export default function LoginPage() { const navigate = useNavigate(); const [serverError, setServerError] = useState(null); + const [collapsibleOpen, setCollapsibleOpen] = useState(false); const form = useForm({ defaultValues: { @@ -162,6 +169,37 @@ export default function LoginPage() { Log in with GitHub + setCollapsibleOpen(value)} + > +

+ More options + + + +
+ + + +

Don't have an account?{" "} diff --git a/frontend/app/routes/signup.tsx b/frontend/app/routes/signup.tsx index 92b5734..4870b09 100644 --- a/frontend/app/routes/signup.tsx +++ b/frontend/app/routes/signup.tsx @@ -22,7 +22,13 @@ import { import { Input } from "~/components/ui/Input"; import { Spinner } from "~/components/ui/Spinner"; import { toast } from "~/components/ui/Toast"; -import { SiGithub } from "@icons-pack/react-simple-icons"; +import { SiDiscord, SiGithub } from "@icons-pack/react-simple-icons"; +import { + Collapsible, + CollapsibleContent, + CollapsibleTrigger, +} from "~/components/ui/collapsible"; +import { ChevronDown, ChevronUp } from "lucide-react"; // Matches better-auth's default minPasswordLength. const MIN_PASSWORD_LENGTH = 8; @@ -46,6 +52,7 @@ export function meta() { export default function SignupPage() { const navigate = useNavigate(); const [serverError, setServerError] = useState(null); + const [collapsibleOpen, setCollapsibleOpen] = useState(false); const form = useForm({ defaultValues: { @@ -243,6 +250,37 @@ export default function SignupPage() { Sign up with GitHub + setCollapsibleOpen(value)} + > +

+ More options + + + +
+ + + +

Already have an account?{" "} From e77d3143ce32a028d6a6263f89064f1999ae292d Mon Sep 17 00:00:00 2001 From: Martin Alexander Kaminski Date: Mon, 19 Oct 2026 20:02:27 +0200 Subject: [PATCH 06/11] feat: move additional OAuths to own component --- .../components/SocialLogIns/SocialLogIns.tsx | 50 +++++++++++++++++++ frontend/app/routes/login.tsx | 42 ++-------------- frontend/app/routes/signup.tsx | 42 ++-------------- 3 files changed, 56 insertions(+), 78 deletions(-) create mode 100644 frontend/app/components/SocialLogIns/SocialLogIns.tsx diff --git a/frontend/app/components/SocialLogIns/SocialLogIns.tsx b/frontend/app/components/SocialLogIns/SocialLogIns.tsx new file mode 100644 index 0000000..c975fde --- /dev/null +++ b/frontend/app/components/SocialLogIns/SocialLogIns.tsx @@ -0,0 +1,50 @@ +import { + Collapsible, + CollapsibleContent, + CollapsibleTrigger, +} from "~/components/ui/Collapsible"; +import { ChevronDown, ChevronUp } from "lucide-react"; +import { SiDiscord } from "@icons-pack/react-simple-icons"; +import { Button } from "~/components/ui/Button"; +import { useState } from "react"; +import { authClient } from "~/api/auth"; + +function SocialLogIns({ logInType }: { logInType: "login" | "signup" }) { + const [collapsibleOpen, setCollapsibleOpen] = useState(false); + + return ( + setCollapsibleOpen(value)} + > +

+ More options + + + +
+ + + + + ); +} + +export { SocialLogIns }; diff --git a/frontend/app/routes/login.tsx b/frontend/app/routes/login.tsx index 0134c6b..9c1435f 100644 --- a/frontend/app/routes/login.tsx +++ b/frontend/app/routes/login.tsx @@ -21,13 +21,8 @@ import { import { Input } from "~/components/ui/Input"; import { Spinner } from "~/components/ui/Spinner"; import { toast } from "~/components/ui/Toast"; -import { SiDiscord, SiGithub } from "@icons-pack/react-simple-icons"; -import { - Collapsible, - CollapsibleContent, - CollapsibleTrigger, -} from "~/components/ui/collapsible"; -import { ChevronDown, ChevronUp } from "lucide-react"; +import { SiGithub } from "@icons-pack/react-simple-icons"; +import { SocialLogIns } from "~/components/SocialLogIns/SocialLogIns"; const formSchema = z.object({ email: z.email("Enter a valid email address."), @@ -41,7 +36,6 @@ export function meta() { export default function LoginPage() { const navigate = useNavigate(); const [serverError, setServerError] = useState(null); - const [collapsibleOpen, setCollapsibleOpen] = useState(false); const form = useForm({ defaultValues: { @@ -169,37 +163,7 @@ export default function LoginPage() { Log in with GitHub - setCollapsibleOpen(value)} - > -
- More options - - - -
- - - -
+

Don't have an account?{" "} diff --git a/frontend/app/routes/signup.tsx b/frontend/app/routes/signup.tsx index 4870b09..6665c33 100644 --- a/frontend/app/routes/signup.tsx +++ b/frontend/app/routes/signup.tsx @@ -22,13 +22,8 @@ import { import { Input } from "~/components/ui/Input"; import { Spinner } from "~/components/ui/Spinner"; import { toast } from "~/components/ui/Toast"; -import { SiDiscord, SiGithub } from "@icons-pack/react-simple-icons"; -import { - Collapsible, - CollapsibleContent, - CollapsibleTrigger, -} from "~/components/ui/collapsible"; -import { ChevronDown, ChevronUp } from "lucide-react"; +import { SiGithub } from "@icons-pack/react-simple-icons"; +import { SocialLogIns } from "~/components/SocialLogIns/SocialLogIns"; // Matches better-auth's default minPasswordLength. const MIN_PASSWORD_LENGTH = 8; @@ -52,7 +47,6 @@ export function meta() { export default function SignupPage() { const navigate = useNavigate(); const [serverError, setServerError] = useState(null); - const [collapsibleOpen, setCollapsibleOpen] = useState(false); const form = useForm({ defaultValues: { @@ -250,37 +244,7 @@ export default function SignupPage() { Sign up with GitHub - setCollapsibleOpen(value)} - > -

- More options - - - -
- - - - +

Already have an account?{" "} From aa0a6a6e85d918a0315e0f435713917285eb3d28 Mon Sep 17 00:00:00 2001 From: Martin Alexander Kaminski Date: Wed, 21 Oct 2026 14:55:47 +0200 Subject: [PATCH 07/11] docs: add instructions on social OAuth using GitHub and Discord --- backend/README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/backend/README.md b/backend/README.md index 6dbaaed..215b391 100644 --- a/backend/README.md +++ b/backend/README.md @@ -48,7 +48,21 @@ brew install postgresql@18 ### Setting the environment variables -Copy the [.env.example](./.env.example) and replace the `DATABASE_URL` if needed. +Start by copying the [.env.example](./.env.example) to `.env`: + +```sh +cd backend +cp .env.example .env +``` + +Proceed to do the following: + +- Check whether the `DATABASE_URL` needs to be updated for the deployment +- Make sure the URLs for the frontend and backend are correct +- Create and insert the GitHub client ID and client secret: + - This can be done by creating an OAuth application in [GitHub's Developer settings -> OAuth Apps](https://github.com/settings/developers) +- Create and insert the Discord client ID and client secret: + - This can be done by creating an application in [Discord's Developer Portal](https://discord.com/developers/applications) ### Downloading the book dataset From 5faea8f20264aca08e4d43418382837336ffca63 Mon Sep 17 00:00:00 2001 From: Martin Alexander Kaminski Date: Thu, 22 Oct 2026 15:59:37 +0200 Subject: [PATCH 08/11] docs: add info about app URL env variable --- frontend/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/frontend/README.md b/frontend/README.md index 068e082..78a3ea6 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -21,6 +21,16 @@ cd frontend pnpm i # or: pnpm install ``` +Set up environment variables: + +``` +cd frontend +cp .env.example .env +``` + +Make sure `VITE_APP_URL` matches the frontend URL. +We need this URL to use as the callback URL for Social OAuth logins - otherwise we will be redirected to the backend at port `3001`, which is not what we want. + Run the application: ```sh From 7bd11de7d8f22f32dd3f38cb9476dce6372d9a77 Mon Sep 17 00:00:00 2001 From: Martin Alexander Kaminski Date: Thu, 22 Oct 2026 16:00:24 +0200 Subject: [PATCH 09/11] refactor: move Discord login out of Collapsible --- .../components/SocialLogIns/SocialLogIns.tsx | 50 ------------------- frontend/app/components/ui/Collapsible.tsx | 19 ------- frontend/app/routes/login.tsx | 16 ++++-- frontend/app/routes/signup.tsx | 16 ++++-- 4 files changed, 26 insertions(+), 75 deletions(-) delete mode 100644 frontend/app/components/SocialLogIns/SocialLogIns.tsx delete mode 100644 frontend/app/components/ui/Collapsible.tsx diff --git a/frontend/app/components/SocialLogIns/SocialLogIns.tsx b/frontend/app/components/SocialLogIns/SocialLogIns.tsx deleted file mode 100644 index c975fde..0000000 --- a/frontend/app/components/SocialLogIns/SocialLogIns.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { - Collapsible, - CollapsibleContent, - CollapsibleTrigger, -} from "~/components/ui/Collapsible"; -import { ChevronDown, ChevronUp } from "lucide-react"; -import { SiDiscord } from "@icons-pack/react-simple-icons"; -import { Button } from "~/components/ui/Button"; -import { useState } from "react"; -import { authClient } from "~/api/auth"; - -function SocialLogIns({ logInType }: { logInType: "login" | "signup" }) { - const [collapsibleOpen, setCollapsibleOpen] = useState(false); - - return ( - setCollapsibleOpen(value)} - > -

- More options - - - -
- - - - - ); -} - -export { SocialLogIns }; diff --git a/frontend/app/components/ui/Collapsible.tsx b/frontend/app/components/ui/Collapsible.tsx deleted file mode 100644 index 4b242f7..0000000 --- a/frontend/app/components/ui/Collapsible.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { Collapsible as CollapsiblePrimitive } from "@base-ui/react/collapsible" - -function Collapsible({ ...props }: CollapsiblePrimitive.Root.Props) { - return -} - -function CollapsibleTrigger({ ...props }: CollapsiblePrimitive.Trigger.Props) { - return ( - - ) -} - -function CollapsibleContent({ ...props }: CollapsiblePrimitive.Panel.Props) { - return ( - - ) -} - -export { Collapsible, CollapsibleTrigger, CollapsibleContent } diff --git a/frontend/app/routes/login.tsx b/frontend/app/routes/login.tsx index 9c1435f..13a31dd 100644 --- a/frontend/app/routes/login.tsx +++ b/frontend/app/routes/login.tsx @@ -21,8 +21,7 @@ import { import { Input } from "~/components/ui/Input"; import { Spinner } from "~/components/ui/Spinner"; import { toast } from "~/components/ui/Toast"; -import { SiGithub } from "@icons-pack/react-simple-icons"; -import { SocialLogIns } from "~/components/SocialLogIns/SocialLogIns"; +import { SiDiscord, SiGithub } from "@icons-pack/react-simple-icons"; const formSchema = z.object({ email: z.email("Enter a valid email address."), @@ -163,7 +162,18 @@ export default function LoginPage() { Log in with GitHub - +

Don't have an account?{" "} diff --git a/frontend/app/routes/signup.tsx b/frontend/app/routes/signup.tsx index 6665c33..337a531 100644 --- a/frontend/app/routes/signup.tsx +++ b/frontend/app/routes/signup.tsx @@ -22,8 +22,7 @@ import { import { Input } from "~/components/ui/Input"; import { Spinner } from "~/components/ui/Spinner"; import { toast } from "~/components/ui/Toast"; -import { SiGithub } from "@icons-pack/react-simple-icons"; -import { SocialLogIns } from "~/components/SocialLogIns/SocialLogIns"; +import { SiDiscord, SiGithub } from "@icons-pack/react-simple-icons"; // Matches better-auth's default minPasswordLength. const MIN_PASSWORD_LENGTH = 8; @@ -244,7 +243,18 @@ export default function SignupPage() { Sign up with GitHub - +

Already have an account?{" "} From 7482d9307eb945b80e6bc36d930370d471cf5475 Mon Sep 17 00:00:00 2001 From: Martin Alexander Kaminski Date: Thu, 22 Oct 2026 16:02:03 +0200 Subject: [PATCH 10/11] fix: redirect user if already logged in --- frontend/app/routes/login.tsx | 7 ++++++- frontend/app/routes/signup.tsx | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/frontend/app/routes/login.tsx b/frontend/app/routes/login.tsx index 13a31dd..efc8f49 100644 --- a/frontend/app/routes/login.tsx +++ b/frontend/app/routes/login.tsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import { Link, useNavigate } from "react-router"; +import { Link, Navigate, useNavigate } from "react-router"; import { useForm } from "@tanstack/react-form"; import { z } from "zod"; import { authClient } from "~/api/auth"; @@ -35,6 +35,7 @@ export function meta() { export default function LoginPage() { const navigate = useNavigate(); const [serverError, setServerError] = useState(null); + const { data: session } = authClient.useSession(); const form = useForm({ defaultValues: { @@ -62,6 +63,10 @@ export default function LoginPage() { }, }); + if (session) { + return ; + } + return (

diff --git a/frontend/app/routes/signup.tsx b/frontend/app/routes/signup.tsx index 337a531..1b1e80d 100644 --- a/frontend/app/routes/signup.tsx +++ b/frontend/app/routes/signup.tsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import { Link, useNavigate } from "react-router"; +import { Link, Navigate, useNavigate } from "react-router"; import { useForm } from "@tanstack/react-form"; import { z } from "zod"; import { authClient } from "~/api/auth"; @@ -46,6 +46,7 @@ export function meta() { export default function SignupPage() { const navigate = useNavigate(); const [serverError, setServerError] = useState(null); + const { data: session } = authClient.useSession(); const form = useForm({ defaultValues: { @@ -81,6 +82,10 @@ export default function SignupPage() { }, }); + if (session) { + return ; + } + return (
From 1f5f82f4c50a51384ed8de8e7ef6a961b9287927 Mon Sep 17 00:00:00 2001 From: Martin Alexander Kaminski Date: Thu, 22 Oct 2026 16:05:56 +0200 Subject: [PATCH 11/11] fix: build callback URL with client-side data as fallback --- frontend/app/routes/login.tsx | 4 ++-- frontend/app/routes/signup.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/app/routes/login.tsx b/frontend/app/routes/login.tsx index efc8f49..1b0c20e 100644 --- a/frontend/app/routes/login.tsx +++ b/frontend/app/routes/login.tsx @@ -159,7 +159,7 @@ export default function LoginPage() { onClick={() => void authClient.signIn.social({ provider: "github", - callbackURL: `${import.meta.env.VITE_APP_URL}/project2/`, + callbackURL: `${import.meta.env.VITE_APP_URL ?? window.location.origin}${import.meta.env.BASE_URL}`, }) } variant="outline" @@ -171,7 +171,7 @@ export default function LoginPage() { onClick={() => void authClient.signIn.social({ provider: "discord", - callbackURL: `${import.meta.env.VITE_APP_URL}/project2/`, + callbackURL: `${import.meta.env.VITE_APP_URL ?? window.location.origin}${import.meta.env.BASE_URL}`, }) } variant="outline" diff --git a/frontend/app/routes/signup.tsx b/frontend/app/routes/signup.tsx index 1b1e80d..f09d00b 100644 --- a/frontend/app/routes/signup.tsx +++ b/frontend/app/routes/signup.tsx @@ -240,7 +240,7 @@ export default function SignupPage() { onClick={() => void authClient.signIn.social({ provider: "github", - callbackURL: `${import.meta.env.VITE_APP_URL}/project2/`, + callbackURL: `${import.meta.env.VITE_APP_URL ?? window.location.origin}${import.meta.env.BASE_URL}`, }) } variant="outline" @@ -252,7 +252,7 @@ export default function SignupPage() { onClick={() => void authClient.signIn.social({ provider: "discord", - callbackURL: `${import.meta.env.VITE_APP_URL}/project2/`, + callbackURL: `${import.meta.env.VITE_APP_URL ?? window.location.origin}${import.meta.env.BASE_URL}`, }) } variant="outline"