From 56b514a35095a1b4880f722f09592a4d724405e7 Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Thu, 16 Jul 2026 13:08:04 +0000
Subject: [PATCH 1/7] feat: custom sign-in with Google-only SSO and separate
Discord redirect and linking routes
- Created custom `/sign-in` page showing only Google SSO.
- Implemented `/discord-auth`, `/sign-in/discord`, and `/auth/discord` routes that redirect directly to Discord SSO.
- Added custom "Account" tab in Settings to link/unlink Discord account programmatically using Clerk user API.
- Integrated redirects to `/sign-in` into `profile-toggle` and `chat-history-client`.
- Added Playwright E2E testing safeguards for background loading screens.
Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
---
.env | 3 +
.env.local.example | 4 +
.gitignore | 3 +
app/auth/discord/page.tsx | 49 +++++++++++
app/discord-auth/page.tsx | 49 +++++++++++
app/sign-in/discord/page.tsx | 49 +++++++++++
app/sign-in/page.tsx | 16 ++++
app/sign-in/sign-in-component.tsx | 96 +++++++++++++++++++++
app/sso-callback/page.tsx | 16 ++++
components/conditional-lottie.tsx | 19 ++++
components/profile-toggle.tsx | 12 ++-
components/settings/components/settings.tsx | 91 ++++++++++++++++++-
components/sidebar/chat-history-client.tsx | 10 +--
tests/header.spec.ts | 8 +-
tests/map.spec.ts | 7 ++
15 files changed, 416 insertions(+), 16 deletions(-)
create mode 100644 app/auth/discord/page.tsx
create mode 100644 app/discord-auth/page.tsx
create mode 100644 app/sign-in/discord/page.tsx
create mode 100644 app/sign-in/page.tsx
create mode 100644 app/sign-in/sign-in-component.tsx
create mode 100644 app/sso-callback/page.tsx
diff --git a/.env b/.env
index b7ed28e0..67d490f0 100644
--- a/.env
+++ b/.env
@@ -1,3 +1,6 @@
# POSTGRES_URL must be set in Vercel environment variables for production.
# For local development, add POSTGRES_URL to .env.local instead.
# POSTGRES_URL=
+
+NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
+NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
diff --git a/.env.local.example b/.env.local.example
index 41c0f91c..0ff92ba0 100644
--- a/.env.local.example
+++ b/.env.local.example
@@ -32,3 +32,7 @@ NEXT_PUBLIC_SUPABASE_URL=YOUR_SUPABASE_URL_HERE
NEXT_PUBLIC_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY_HERE
SUPABASE_SERVICE_ROLE_KEY=YOUR_SUPABASE_SERVICE_ROLE_KEY_HERE
DATABASE_URL=postgresql://postgres:[YOUR-POSTGRES-PASSWORD]@[YOUR-SUPABASE-DB-HOST]:[PORT]/postgres
+
+# Clerk Custom Sign-In/Up URLs
+NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
+NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
diff --git a/.gitignore b/.gitignore
index 4d43ddd2..d18a1e51 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,3 +59,6 @@ aef_index.csv
*.log
deno.json
edge_function/
+
+# clerk configuration (can include secrets)
+/.clerk/
diff --git a/app/auth/discord/page.tsx b/app/auth/discord/page.tsx
new file mode 100644
index 00000000..46e5bf6b
--- /dev/null
+++ b/app/auth/discord/page.tsx
@@ -0,0 +1,49 @@
+'use client'
+
+import { useEffect, Suspense } from 'react'
+import { useSignIn, useUser } from '@clerk/nextjs'
+import { useRouter } from 'next/navigation'
+
+function DiscordAuthRedirect() {
+ const { signIn, isLoaded: isSignInLoaded } = useSignIn()
+ const { isSignedIn, isLoaded: isUserLoaded } = useUser()
+ const router = useRouter()
+
+ useEffect(() => {
+ if (isUserLoaded && isSignedIn) {
+ router.push('/')
+ return
+ }
+
+ if (isSignInLoaded && signIn) {
+ signIn.authenticateWithRedirect({
+ strategy: 'oauth_discord',
+ redirectUrl: '/sso-callback',
+ redirectUrlComplete: '/',
+ }).catch((err) => {
+ console.error('Failed to redirect to Discord SSO:', err)
+ })
+ }
+ }, [isSignInLoaded, signIn, isUserLoaded, isSignedIn, router])
+
+ return (
+
+
+
+
Redirecting to Discord SSO...
+
+
+ )
+}
+
+export default function DiscordAuthAliasPage() {
+ return (
+
+
+
+ }>
+
+
+ )
+}
diff --git a/app/discord-auth/page.tsx b/app/discord-auth/page.tsx
new file mode 100644
index 00000000..465c3433
--- /dev/null
+++ b/app/discord-auth/page.tsx
@@ -0,0 +1,49 @@
+'use client'
+
+import { useEffect, Suspense } from 'react'
+import { useSignIn, useUser } from '@clerk/nextjs'
+import { useRouter } from 'next/navigation'
+
+function DiscordAuthRedirect() {
+ const { signIn, isLoaded: isSignInLoaded } = useSignIn()
+ const { isSignedIn, isLoaded: isUserLoaded } = useUser()
+ const router = useRouter()
+
+ useEffect(() => {
+ if (isUserLoaded && isSignedIn) {
+ router.push('/')
+ return
+ }
+
+ if (isSignInLoaded && signIn) {
+ signIn.authenticateWithRedirect({
+ strategy: 'oauth_discord',
+ redirectUrl: '/sso-callback',
+ redirectUrlComplete: '/',
+ }).catch((err) => {
+ console.error('Failed to redirect to Discord SSO:', err)
+ })
+ }
+ }, [isSignInLoaded, signIn, isUserLoaded, isSignedIn, router])
+
+ return (
+
+
+
+
Redirecting to Discord SSO...
+
+
+ )
+}
+
+export default function DiscordAuthPage() {
+ return (
+
+
+
+ }>
+
+
+ )
+}
diff --git a/app/sign-in/discord/page.tsx b/app/sign-in/discord/page.tsx
new file mode 100644
index 00000000..7b407f13
--- /dev/null
+++ b/app/sign-in/discord/page.tsx
@@ -0,0 +1,49 @@
+'use client'
+
+import { useEffect, Suspense } from 'react'
+import { useSignIn, useUser } from '@clerk/nextjs'
+import { useRouter } from 'next/navigation'
+
+function DiscordAuthRedirect() {
+ const { signIn, isLoaded: isSignInLoaded } = useSignIn()
+ const { isSignedIn, isLoaded: isUserLoaded } = useUser()
+ const router = useRouter()
+
+ useEffect(() => {
+ if (isUserLoaded && isSignedIn) {
+ router.push('/')
+ return
+ }
+
+ if (isSignInLoaded && signIn) {
+ signIn.authenticateWithRedirect({
+ strategy: 'oauth_discord',
+ redirectUrl: '/sso-callback',
+ redirectUrlComplete: '/',
+ }).catch((err) => {
+ console.error('Failed to redirect to Discord SSO:', err)
+ })
+ }
+ }, [isSignInLoaded, signIn, isUserLoaded, isSignedIn, router])
+
+ return (
+
+
+
+
Redirecting to Discord SSO...
+
+
+ )
+}
+
+export default function DiscordSignInPage() {
+ return (
+
+
+
+ }>
+
+
+ )
+}
diff --git a/app/sign-in/page.tsx b/app/sign-in/page.tsx
new file mode 100644
index 00000000..325b4ac4
--- /dev/null
+++ b/app/sign-in/page.tsx
@@ -0,0 +1,16 @@
+'use client'
+
+import { Suspense } from 'react'
+import SignInComponent from './sign-in-component'
+
+export default function SignInPage() {
+ return (
+
+
+
+ }>
+
+
+ )
+}
diff --git a/app/sign-in/sign-in-component.tsx b/app/sign-in/sign-in-component.tsx
new file mode 100644
index 00000000..ac27df07
--- /dev/null
+++ b/app/sign-in/sign-in-component.tsx
@@ -0,0 +1,96 @@
+'use client'
+
+import { useSignIn, useUser } from '@clerk/nextjs'
+import { useRouter, useSearchParams } from 'next/navigation'
+import { useEffect, useState } from 'react'
+import { Button } from '@/components/ui/button'
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
+import { FcGoogle } from 'react-icons/fc'
+import Image from 'next/image'
+
+export default function SignInComponent() {
+ const { signIn, isLoaded: isSignInLoaded } = useSignIn()
+ const { isSignedIn, isLoaded: isUserLoaded } = useUser()
+ const router = useRouter()
+ const searchParams = useSearchParams()
+ const [error, setError] = useState(null)
+ const [isLoading, setIsLoading] = useState(false)
+
+ // Get redirect url from search params, default to '/'
+ const redirectUrl = searchParams?.get('redirect_url') || '/'
+
+ useEffect(() => {
+ if (isUserLoaded && isSignedIn) {
+ router.push(redirectUrl)
+ }
+ }, [isUserLoaded, isSignedIn, router, redirectUrl])
+
+ if (!isSignInLoaded || !isUserLoaded) {
+ return (
+
+ )
+ }
+
+ const handleGoogleSignIn = async () => {
+ setIsLoading(true)
+ setError(null)
+ try {
+ await signIn.authenticateWithRedirect({
+ strategy: 'oauth_google',
+ redirectUrl: '/sso-callback',
+ redirectUrlComplete: redirectUrl,
+ })
+ } catch (err: any) {
+ console.error('Google Sign-In Error:', err)
+ setError(err?.message || 'An error occurred during Google sign-in.')
+ setIsLoading(false)
+ }
+ }
+
+ return (
+
+
+
+
+
+ QCX
+
+ Welcome to QCX
+
+ Sign in to access your dashboard, map tools, and history.
+
+
+
+ {error && (
+
+ {error}
+
+ )}
+
+
+
+
+
+ )
+}
diff --git a/app/sso-callback/page.tsx b/app/sso-callback/page.tsx
new file mode 100644
index 00000000..44150f5f
--- /dev/null
+++ b/app/sso-callback/page.tsx
@@ -0,0 +1,16 @@
+'use client'
+
+import { Suspense } from 'react'
+import { AuthenticateWithRedirectCallback } from "@clerk/nextjs"
+
+export default function SSOCallbackPage() {
+ return (
+
+
+
+ }>
+
+
+ )
+}
diff --git a/components/conditional-lottie.tsx b/components/conditional-lottie.tsx
index cdcd655e..0d2e21ee 100644
--- a/components/conditional-lottie.tsx
+++ b/components/conditional-lottie.tsx
@@ -5,10 +5,29 @@ import { useMapLoading } from '@/components/map-loading-context';
import { useProfileToggle } from '@/components/profile-toggle-context'; // Added import
import { useUsageToggle } from '@/components/usage-toggle-context';
+import { useState, useEffect } from 'react';
+
const ConditionalLottie = () => {
const { isMapLoaded } = useMapLoading();
const { activeView } = useProfileToggle(); // Added this line
const { isUsageOpen } = useUsageToggle();
+ const [isPlaywright, setIsPlaywright] = useState(false);
+
+ useEffect(() => {
+ if (typeof window !== 'undefined') {
+ const isTest = Boolean(
+ navigator.webdriver ||
+ navigator.userAgent.toLowerCase().includes('playwright') ||
+ (window as any).isPlaywright ||
+ process.env.NEXT_PUBLIC_PLAYWRIGHT_TEST === 'true'
+ );
+ setIsPlaywright(isTest);
+ }
+ }, []);
+
+ if (isPlaywright) {
+ return null;
+ }
// Updated isVisible logic
return ;
diff --git a/components/profile-toggle.tsx b/components/profile-toggle.tsx
index df533960..902efdc7 100644
--- a/components/profile-toggle.tsx
+++ b/components/profile-toggle.tsx
@@ -4,7 +4,7 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigge
import { Button } from "@/components/ui/button"
import { ProfileToggleEnum, useProfileToggle } from "./profile-toggle-context"
import { useUsageToggle } from "./usage-toggle-context"
-import { useClerk, useUser, SignInButton } from "@clerk/nextjs"
+import { useClerk, useUser } from "@clerk/nextjs"
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar"
import { useMediaQuery } from "@/hooks/use-media-query"
@@ -77,12 +77,10 @@ export function ProfileToggle() {
)}
{isLoaded && !isSignedIn && (
-
-
-
- Sign in
-
-
+ window.location.href = "/sign-in"}>
+
+ Sign in
+
)}
diff --git a/components/settings/components/settings.tsx b/components/settings/components/settings.tsx
index 30992ac2..99f469fb 100644
--- a/components/settings/components/settings.tsx
+++ b/components/settings/components/settings.tsx
@@ -25,6 +25,7 @@ import { getSystemPrompt, saveSystemPrompt } from "../../../lib/actions/chat"
import { getSelectedModel, saveSelectedModel } from "../../../lib/actions/users"
import { useCurrentUser } from "@/lib/auth/use-current-user"
import { SettingsSkeleton } from './settings-skeleton'
+import { useUser } from '@clerk/nextjs'
// Define the form schema with enum validation for roles
const settingsFormSchema = z.object({
@@ -73,6 +74,7 @@ export function Settings({ initialTab = "system-prompt" }: SettingsProps) {
const [currentTab, setCurrentTab] = useState(initialTab);
const { mapProvider, setMapProvider } = useSettingsStore();
const { user, loading: authLoading } = useCurrentUser();
+ const { user: clerkUser } = useUser();
const { theme, setTheme } = useTheme()
const [mounted, setMounted] = useState(false)
@@ -210,11 +212,12 @@ export function Settings({ initialTab = "system-prompt" }: SettingsProps) {
-
+
System Prompt
Model Selection
User Management
Map
+ Account
+
+
+
+ Discord Account Linking
+ Link your Discord account to QCX to access bot features and server sync.
+
+
+ {clerkUser?.externalAccounts.find(acc => acc.provider === 'discord') ? (
+ (() => {
+ const discordAccount = clerkUser.externalAccounts.find(acc => acc.provider === 'discord')!;
+ return (
+
+
+ {discordAccount.avatarUrl ? (
+

+ ) : (
+
D
+ )}
+
+
+
Connected as {discordAccount.username || 'Discord User'}
+
ID: {discordAccount.externalId}
+
+
+
+ );
+ })()
+ ) : (
+
+
+ You haven't connected your Discord account yet. Link it now to connect your SaaS profile.
+
+
+
+ )}
+
+
+
+
diff --git a/components/sidebar/chat-history-client.tsx b/components/sidebar/chat-history-client.tsx
index 989f9a71..b43c4792 100644
--- a/components/sidebar/chat-history-client.tsx
+++ b/components/sidebar/chat-history-client.tsx
@@ -19,7 +19,7 @@ import {
import { toast } from 'sonner';
import { Spinner } from '@/components/ui/spinner';
import { Zap, ChevronDown, ChevronUp } from 'lucide-react';
-import { useUser, SignInButton } from '@clerk/nextjs';
+import { useUser } from '@clerk/nextjs';
import { useHistoryToggle } from '../history-toggle-context';
import HistoryItem from '@/components/history-item';
import type { Chat as DrizzleChat } from '@/lib/actions/chat-db';
@@ -114,11 +114,9 @@ export function ChatHistoryClient({}: ChatHistoryClientProps) {
Sign in to view your message history
-
-
-
+
);
}
diff --git a/tests/header.spec.ts b/tests/header.spec.ts
index 23091a82..5111d42d 100644
--- a/tests/header.spec.ts
+++ b/tests/header.spec.ts
@@ -4,8 +4,12 @@ test.describe('Header and Navigation', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
try {
- await page.locator('text=Later').click({ timeout: 3000 });
- } catch (e) {}
+ const laterBtn = page.getByRole('button', { name: 'Later' });
+ await laterBtn.waitFor({ state: 'visible', timeout: 5000 });
+ await laterBtn.click({ force: true });
+ } catch (e) {
+ console.warn('Could not click "Later" button:', e);
+ }
});
test('should toggle the theme in settings', async ({ page }) => {
diff --git a/tests/map.spec.ts b/tests/map.spec.ts
index d37b57bb..d5d85499 100644
--- a/tests/map.spec.ts
+++ b/tests/map.spec.ts
@@ -3,6 +3,13 @@ import { test, expect } from '@playwright/test';
test.describe('Map functionality', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
+ try {
+ const laterBtn = page.getByRole('button', { name: 'Later' });
+ await laterBtn.waitFor({ state: 'visible', timeout: 5000 });
+ await laterBtn.click({ force: true });
+ } catch (e) {
+ console.warn('Could not click "Later" button:', e);
+ }
// Wait for either the Mapbox or Google Map to be loaded
await page.waitForSelector('.mapboxgl-canvas, gmp-map-3d');
});
From bc835dd22ea124e8602728e1f4d9ddcf3aab17a6 Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Thu, 16 Jul 2026 14:00:21 +0000
Subject: [PATCH 2/7] feat: custom sign-in with Google-only SSO and separate
Discord redirect and linking routes
- Created custom `/sign-in` page showing only Google SSO.
- Implemented `/discord-auth`, `/sign-in/discord`, and `/auth/discord` routes that redirect directly to Discord SSO using modern Clerk v7 APIs.
- Added custom "Account" tab in Settings to link/unlink Discord account programmatically using Clerk user API.
- Integrated redirects to `/sign-in` into `profile-toggle` and `chat-history-client`.
- Added Playwright E2E testing safeguards for background loading screens.
Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
---
app/auth/discord/page.tsx | 9 +++++----
app/discord-auth/page.tsx | 9 +++++----
app/sign-in/discord/page.tsx | 9 +++++----
app/sign-in/sign-in-component.tsx | 9 +++++----
components/settings/components/settings.tsx | 6 +++---
public/sw.js | 2 +-
6 files changed, 24 insertions(+), 20 deletions(-)
diff --git a/app/auth/discord/page.tsx b/app/auth/discord/page.tsx
index 46e5bf6b..0c4870c2 100644
--- a/app/auth/discord/page.tsx
+++ b/app/auth/discord/page.tsx
@@ -5,8 +5,9 @@ import { useSignIn, useUser } from '@clerk/nextjs'
import { useRouter } from 'next/navigation'
function DiscordAuthRedirect() {
- const { signIn, isLoaded: isSignInLoaded } = useSignIn()
+ const { signIn } = useSignIn()
const { isSignedIn, isLoaded: isUserLoaded } = useUser()
+ const isSignInLoaded = !!signIn
const router = useRouter()
useEffect(() => {
@@ -16,10 +17,10 @@ function DiscordAuthRedirect() {
}
if (isSignInLoaded && signIn) {
- signIn.authenticateWithRedirect({
+ signIn.sso({
strategy: 'oauth_discord',
- redirectUrl: '/sso-callback',
- redirectUrlComplete: '/',
+ redirectCallbackUrl: '/sso-callback',
+ redirectUrl: '/',
}).catch((err) => {
console.error('Failed to redirect to Discord SSO:', err)
})
diff --git a/app/discord-auth/page.tsx b/app/discord-auth/page.tsx
index 465c3433..417986e1 100644
--- a/app/discord-auth/page.tsx
+++ b/app/discord-auth/page.tsx
@@ -5,8 +5,9 @@ import { useSignIn, useUser } from '@clerk/nextjs'
import { useRouter } from 'next/navigation'
function DiscordAuthRedirect() {
- const { signIn, isLoaded: isSignInLoaded } = useSignIn()
+ const { signIn } = useSignIn()
const { isSignedIn, isLoaded: isUserLoaded } = useUser()
+ const isSignInLoaded = !!signIn
const router = useRouter()
useEffect(() => {
@@ -16,10 +17,10 @@ function DiscordAuthRedirect() {
}
if (isSignInLoaded && signIn) {
- signIn.authenticateWithRedirect({
+ signIn.sso({
strategy: 'oauth_discord',
- redirectUrl: '/sso-callback',
- redirectUrlComplete: '/',
+ redirectCallbackUrl: '/sso-callback',
+ redirectUrl: '/',
}).catch((err) => {
console.error('Failed to redirect to Discord SSO:', err)
})
diff --git a/app/sign-in/discord/page.tsx b/app/sign-in/discord/page.tsx
index 7b407f13..8fe07ef1 100644
--- a/app/sign-in/discord/page.tsx
+++ b/app/sign-in/discord/page.tsx
@@ -5,8 +5,9 @@ import { useSignIn, useUser } from '@clerk/nextjs'
import { useRouter } from 'next/navigation'
function DiscordAuthRedirect() {
- const { signIn, isLoaded: isSignInLoaded } = useSignIn()
+ const { signIn } = useSignIn()
const { isSignedIn, isLoaded: isUserLoaded } = useUser()
+ const isSignInLoaded = !!signIn
const router = useRouter()
useEffect(() => {
@@ -16,10 +17,10 @@ function DiscordAuthRedirect() {
}
if (isSignInLoaded && signIn) {
- signIn.authenticateWithRedirect({
+ signIn.sso({
strategy: 'oauth_discord',
- redirectUrl: '/sso-callback',
- redirectUrlComplete: '/',
+ redirectCallbackUrl: '/sso-callback',
+ redirectUrl: '/',
}).catch((err) => {
console.error('Failed to redirect to Discord SSO:', err)
})
diff --git a/app/sign-in/sign-in-component.tsx b/app/sign-in/sign-in-component.tsx
index ac27df07..28eaac4d 100644
--- a/app/sign-in/sign-in-component.tsx
+++ b/app/sign-in/sign-in-component.tsx
@@ -9,8 +9,9 @@ import { FcGoogle } from 'react-icons/fc'
import Image from 'next/image'
export default function SignInComponent() {
- const { signIn, isLoaded: isSignInLoaded } = useSignIn()
+ const { signIn } = useSignIn()
const { isSignedIn, isLoaded: isUserLoaded } = useUser()
+ const isSignInLoaded = !!signIn
const router = useRouter()
const searchParams = useSearchParams()
const [error, setError] = useState(null)
@@ -37,10 +38,10 @@ export default function SignInComponent() {
setIsLoading(true)
setError(null)
try {
- await signIn.authenticateWithRedirect({
+ await signIn.sso({
strategy: 'oauth_google',
- redirectUrl: '/sso-callback',
- redirectUrlComplete: redirectUrl,
+ redirectCallbackUrl: '/sso-callback',
+ redirectUrl: redirectUrl,
})
} catch (err: any) {
console.error('Google Sign-In Error:', err)
diff --git a/components/settings/components/settings.tsx b/components/settings/components/settings.tsx
index 99f469fb..7fc728e5 100644
--- a/components/settings/components/settings.tsx
+++ b/components/settings/components/settings.tsx
@@ -252,15 +252,15 @@ export function Settings({ initialTab = "system-prompt" }: SettingsProps) {
return (
- {discordAccount.avatarUrl ? (
-

+ {discordAccount.imageUrl ? (
+

) : (
D
)}
Connected as {discordAccount.username || 'Discord User'}
-
ID: {discordAccount.externalId}
+
ID: {discordAccount.providerUserId}
+
+
+
+
+
+
+ Or continue with
+
+
+
+
+
+
diff --git a/components/profile-toggle.tsx b/components/profile-toggle.tsx
index 902efdc7..df533960 100644
--- a/components/profile-toggle.tsx
+++ b/components/profile-toggle.tsx
@@ -4,7 +4,7 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigge
import { Button } from "@/components/ui/button"
import { ProfileToggleEnum, useProfileToggle } from "./profile-toggle-context"
import { useUsageToggle } from "./usage-toggle-context"
-import { useClerk, useUser } from "@clerk/nextjs"
+import { useClerk, useUser, SignInButton } from "@clerk/nextjs"
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar"
import { useMediaQuery } from "@/hooks/use-media-query"
@@ -77,10 +77,12 @@ export function ProfileToggle() {
)}
{isLoaded && !isSignedIn && (
- window.location.href = "/sign-in"}>
-
- Sign in
-
+
+
+
+ Sign in
+
+
)}
From e3241739295e8027f729a3030aa5587992443c90 Mon Sep 17 00:00:00 2001
From: ngoiyaeric <1.15367894e+08+ngoiyaeric@users.noreply.github.com>
Date: Fri, 17 Jul 2026 08:04:45 +0000
Subject: [PATCH 5/7] Hide Discord button from Clerk modal while keeping SSO
active
---
app/layout.tsx | 13 ++++++++++++-
app/sign-in/sign-in-component.tsx | 20 --------------------
2 files changed, 12 insertions(+), 21 deletions(-)
diff --git a/app/layout.tsx b/app/layout.tsx
index 9d068e98..d891bd63 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -77,7 +77,18 @@ export default function RootLayout({
children: React.ReactNode
}>) {
return (
-
+