diff --git a/app/globals.css b/app/globals.css
index 6c8538e..a5f8ac4 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -1,300 +1,300 @@
@import "tailwindcss";
:root {
- --background: #0a0a1a;
- --foreground: #e2e8f0;
- --card-bg: rgba(15, 15, 40, 0.7);
- --card-border: rgba(99, 102, 241, 0.12);
- --card-border-hover: rgba(99, 102, 241, 0.25);
- --accent-primary: #818cf8;
- --accent-secondary: #a78bfa;
- --accent-glow: rgba(129, 140, 248, 0.15);
+ --background: #0a0a1a;
+ --foreground: #e2e8f0;
+ --card-bg: rgba(15, 15, 40, 0.7);
+ --card-border: rgba(99, 102, 241, 0.12);
+ --card-border-hover: rgba(99, 102, 241, 0.25);
+ --accent-primary: #818cf8;
+ --accent-secondary: #a78bfa;
+ --accent-glow: rgba(129, 140, 248, 0.15);
}
@theme inline {
- --color-background: var(--background);
- --color-foreground: var(--foreground);
- --font-sans: var(--font-geist-sans);
- --font-mono: var(--font-geist-mono);
+ --color-background: var(--background);
+ --color-foreground: var(--foreground);
+ --font-sans: var(--font-geist-sans);
+ --font-mono: var(--font-geist-mono);
}
* {
- scrollbar-width: thin;
- scrollbar-color: rgba(99, 102, 241, 0.3) transparent;
+ scrollbar-width: thin;
+ scrollbar-color: rgba(99, 102, 241, 0.3) transparent;
}
body {
- background: var(--background);
- color: var(--foreground);
- font-family: var(--font-sans), Arial, Helvetica, sans-serif;
- transition:
- background-color 0.3s ease,
- color 0.3s ease;
- scroll-behavior: smooth;
+ background: var(--background);
+ color: var(--foreground);
+ font-family: var(--font-sans), Arial, Helvetica, sans-serif;
+ transition:
+ background-color 0.3s ease,
+ color 0.3s ease;
+ scroll-behavior: smooth;
}
/* Glassmorphic card base */
.glass-card {
- background: var(--card-bg);
- backdrop-filter: blur(24px);
- -webkit-backdrop-filter: blur(24px);
- border: 1px solid var(--card-border);
- border-radius: 1rem;
- transition:
- border-color 0.3s ease,
- box-shadow 0.3s ease;
+ background: var(--card-bg);
+ backdrop-filter: blur(24px);
+ -webkit-backdrop-filter: blur(24px);
+ border: 1px solid var(--card-border);
+ border-radius: 1rem;
+ transition:
+ border-color 0.3s ease,
+ box-shadow 0.3s ease;
}
.glass-card:hover {
- border-color: var(--card-border-hover);
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
+ border-color: var(--card-border-hover);
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
}
/* Gradient text utility */
.gradient-text {
- background: linear-gradient(135deg, #818cf8 0%, #a78bfa 50%, #c084fc 100%);
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- background-clip: text;
+ background: linear-gradient(135deg, #818cf8 0%, #a78bfa 50%, #c084fc 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
}
/* Subtle grid background */
.grid-bg {
- background-image:
- linear-gradient(rgba(99, 102, 241, 0.03) 1px, transparent 1px),
- linear-gradient(90deg, rgba(99, 102, 241, 0.03) 1px, transparent 1px);
- background-size: 40px 40px;
+ background-image:
+ linear-gradient(rgba(99, 102, 241, 0.03) 1px, transparent 1px),
+ linear-gradient(90deg, rgba(99, 102, 241, 0.03) 1px, transparent 1px);
+ background-size: 40px 40px;
}
/* Glow orb */
.glow-orb {
- position: absolute;
- border-radius: 50%;
- filter: blur(120px);
- pointer-events: none;
- z-index: 0;
+ position: absolute;
+ border-radius: 50%;
+ filter: blur(120px);
+ pointer-events: none;
+ z-index: 0;
}
/* Button styles */
.btn-primary {
- background: linear-gradient(135deg, #6366f1, #8b5cf6);
- color: white;
- font-weight: 600;
- border-radius: 0.75rem;
- padding: 0.75rem 2rem;
- transition: all 0.3s ease;
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
+ background: linear-gradient(135deg, #6366f1, #8b5cf6);
+ color: white;
+ font-weight: 600;
+ border-radius: 0.75rem;
+ padding: 0.75rem 2rem;
+ transition: all 0.3s ease;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}
.btn-primary:hover {
- transform: translateY(-1px);
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
+ transform: translateY(-1px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.btn-secondary {
- background: rgba(255, 255, 255, 0.04);
- color: white;
- font-weight: 600;
- border-radius: 0.75rem;
- padding: 0.75rem 2rem;
- border: 1px solid rgba(255, 255, 255, 0.1);
- transition: all 0.3s ease;
+ background: rgba(255, 255, 255, 0.04);
+ color: white;
+ font-weight: 600;
+ border-radius: 0.75rem;
+ padding: 0.75rem 2rem;
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ transition: all 0.3s ease;
}
.btn-secondary:hover {
- background: rgba(255, 255, 255, 0.08);
- border-color: rgba(255, 255, 255, 0.2);
+ background: rgba(255, 255, 255, 0.08);
+ border-color: rgba(255, 255, 255, 0.2);
}
/* Input styles */
.input-field {
- width: 100%;
- padding: 0.75rem 1rem;
- background: rgba(10, 10, 30, 0.6);
- border: 1px solid rgba(99, 102, 241, 0.15);
- border-radius: 0.75rem;
- color: #e2e8f0;
- outline: none;
- transition: all 0.3s ease;
+ width: 100%;
+ padding: 0.75rem 1rem;
+ background: rgba(10, 10, 30, 0.6);
+ border: 1px solid rgba(99, 102, 241, 0.15);
+ border-radius: 0.75rem;
+ color: #e2e8f0;
+ outline: none;
+ transition: all 0.3s ease;
}
.input-field:focus {
- border-color: #6366f1;
- box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);
+ border-color: #6366f1;
+ box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);
}
.input-field::placeholder {
- color: #4b5563;
+ color: #4b5563;
}
/* Stat card */
.stat-card {
- background: rgba(15, 15, 40, 0.5);
- border: 1px solid rgba(99, 102, 241, 0.08);
- border-radius: 0.75rem;
- padding: 1.25rem;
- transition: all 0.3s ease;
+ background: rgba(15, 15, 40, 0.5);
+ border: 1px solid rgba(99, 102, 241, 0.08);
+ border-radius: 0.75rem;
+ padding: 1.25rem;
+ transition: all 0.3s ease;
}
.stat-card:hover {
- border-color: rgba(99, 102, 241, 0.2);
- background: rgba(15, 15, 40, 0.7);
+ border-color: rgba(99, 102, 241, 0.2);
+ background: rgba(15, 15, 40, 0.7);
}
@media (min-width: 376px) {
- .flex-row-321 {
- flex-direction: row;
- }
+ .flex-row-321 {
+ flex-direction: row;
+ }
}
@media (max-width: 375px) {
- .flex-row-321 {
- flex-direction: column;
- }
+ .flex-row-321 {
+ flex-direction: column;
+ }
}
@keyframes shimmer-bg {
- 0% {
- background-position: 0% 50%;
- }
- 100% {
- background-position: 200% 50%;
- }
+ 0% {
+ background-position: 0% 50%;
+ }
+ 100% {
+ background-position: 200% 50%;
+ }
}
@keyframes pulse-glow {
- 0%,
- 100% {
- box-shadow: 0 0 15px rgba(255, 0, 102, 0.6);
- }
- 50% {
- box-shadow: 0 0 25px rgba(255, 0, 102, 1);
- }
+ 0%,
+ 100% {
+ box-shadow: 0 0 15px rgba(255, 0, 102, 0.6);
+ }
+ 50% {
+ box-shadow: 0 0 25px rgba(255, 0, 102, 1);
+ }
}
@keyframes glow-pulse {
- 0% {
- box-shadow: 0 0 5px rgba(217, 70, 239, 0.4);
- }
- 100% {
- box-shadow: 0 0 15px rgba(217, 70, 239, 0.8);
- }
+ 0% {
+ box-shadow: 0 0 5px rgba(217, 70, 239, 0.4);
+ }
+ 100% {
+ box-shadow: 0 0 15px rgba(217, 70, 239, 0.8);
+ }
}
.badge-base {
- padding: 0.125rem 0.375rem;
- border-radius: 0.25rem;
- font-size: 0.5rem;
- font-weight: 800;
- text-transform: uppercase;
- letter-spacing: 0.1em;
- display: inline-flex;
- align-items: center;
- gap: 0.25rem;
- line-height: normal;
+ padding: 0.125rem 0.375rem;
+ border-radius: 0.25rem;
+ font-size: 0.5rem;
+ font-weight: 800;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ display: inline-flex;
+ align-items: center;
+ gap: 0.25rem;
+ line-height: normal;
}
.badge-impossible {
- background: linear-gradient(
- 90deg,
- rgba(255, 0, 102, 0.15) 0%,
- rgba(255, 51, 153, 0.8) 50%,
- rgba(255, 0, 102, 0.15) 100%
- );
- background-size: 200% auto;
- animation:
- pulse-glow 1.5s infinite,
- shimmer-bg 1.5s linear infinite;
+ background: linear-gradient(
+ 90deg,
+ rgba(255, 0, 102, 0.15) 0%,
+ rgba(255, 51, 153, 0.8) 50%,
+ rgba(255, 0, 102, 0.15) 100%
+ );
+ background-size: 200% auto;
+ animation:
+ pulse-glow 1.5s infinite,
+ shimmer-bg 1.5s linear infinite;
- border: 1px solid rgba(255, 0, 102, 0.8);
- color: #ff99cc;
- box-shadow: 0 0 15px rgba(255, 0, 102, 0.6);
+ border: 1px solid rgba(255, 0, 102, 0.8);
+ color: #ff99cc;
+ box-shadow: 0 0 15px rgba(255, 0, 102, 0.6);
}
.badge-god {
- background: linear-gradient(
- 90deg,
- rgba(217, 70, 239, 0.15) 0%,
- rgba(232, 121, 249, 0.6) 50%,
- rgba(217, 70, 239, 0.15) 100%
- );
- background-size: 200% auto;
- animation:
- shimmer-bg 2s linear infinite,
- glow-pulse 2s alternate infinite;
+ background: linear-gradient(
+ 90deg,
+ rgba(217, 70, 239, 0.15) 0%,
+ rgba(232, 121, 249, 0.6) 50%,
+ rgba(217, 70, 239, 0.15) 100%
+ );
+ background-size: 200% auto;
+ animation:
+ shimmer-bg 2s linear infinite,
+ glow-pulse 2s alternate infinite;
- border: 1px solid rgba(217, 70, 239, 0.6);
- color: #f0abfc;
- box-shadow: 0 0 10px rgba(217, 70, 239, 0.4);
+ border: 1px solid rgba(217, 70, 239, 0.6);
+ color: #f0abfc;
+ box-shadow: 0 0 10px rgba(217, 70, 239, 0.4);
}
.badge-starlight {
- background: linear-gradient(
- 90deg,
- rgba(56, 189, 248, 0.15) 0%,
- rgba(125, 211, 252, 0.6) 50%,
- rgba(56, 189, 248, 0.15) 100%
- );
- background-size: 200% auto;
- animation: shimmer-bg 2.5s linear infinite;
+ background: linear-gradient(
+ 90deg,
+ rgba(56, 189, 248, 0.15) 0%,
+ rgba(125, 211, 252, 0.6) 50%,
+ rgba(56, 189, 248, 0.15) 100%
+ );
+ background-size: 200% auto;
+ animation: shimmer-bg 2.5s linear infinite;
- border: 1px solid rgba(56, 189, 248, 0.5);
- color: #bae6fd;
- box-shadow: 0 0 10px rgba(56, 189, 248, 0.3);
+ border: 1px solid rgba(56, 189, 248, 0.5);
+ color: #bae6fd;
+ box-shadow: 0 0 10px rgba(56, 189, 248, 0.3);
}
.badge-elite {
- background: linear-gradient(
- 90deg,
- rgba(239, 68, 68, 0.15) 0%,
- rgba(248, 113, 113, 0.6) 50%,
- rgba(239, 68, 68, 0.15) 100%
- );
- background-size: 200% auto;
- animation: shimmer-bg 3s linear infinite;
+ background: linear-gradient(
+ 90deg,
+ rgba(239, 68, 68, 0.15) 0%,
+ rgba(248, 113, 113, 0.6) 50%,
+ rgba(239, 68, 68, 0.15) 100%
+ );
+ background-size: 200% auto;
+ animation: shimmer-bg 3s linear infinite;
- border: 1px solid rgba(239, 68, 68, 0.5);
- color: #fca5a5;
- box-shadow: 0 0 10px rgba(239, 68, 68, 0.3);
+ border: 1px solid rgba(239, 68, 68, 0.5);
+ color: #fca5a5;
+ box-shadow: 0 0 10px rgba(239, 68, 68, 0.3);
}
.badge-pro {
- background: linear-gradient(
- 90deg,
- rgba(234, 179, 8, 0.15) 0%,
- rgba(253, 224, 71, 0.5) 50%,
- rgba(234, 179, 8, 0.15) 100%
- );
- background-size: 200% auto;
- animation: shimmer-bg 4s linear infinite;
+ background: linear-gradient(
+ 90deg,
+ rgba(234, 179, 8, 0.15) 0%,
+ rgba(253, 224, 71, 0.5) 50%,
+ rgba(234, 179, 8, 0.15) 100%
+ );
+ background-size: 200% auto;
+ animation: shimmer-bg 4s linear infinite;
- border: 1px solid rgba(234, 179, 8, 0.5);
- color: #fef08a;
- box-shadow: 0 0 10px rgba(234, 179, 8, 0.2);
+ border: 1px solid rgba(234, 179, 8, 0.5);
+ color: #fef08a;
+ box-shadow: 0 0 10px rgba(234, 179, 8, 0.2);
}
.badge-master {
- background: rgba(99, 102, 241, 0.15);
- border: 1px solid rgba(99, 102, 241, 0.4);
- color: #a5b4fc;
+ background: rgba(99, 102, 241, 0.15);
+ border: 1px solid rgba(99, 102, 241, 0.4);
+ color: #a5b4fc;
}
.badge-hustler {
- background: rgba(59, 130, 246, 0.15);
- border: 1px solid rgba(59, 130, 246, 0.4);
- color: #93c5fd;
+ background: rgba(59, 130, 246, 0.15);
+ border: 1px solid rgba(59, 130, 246, 0.4);
+ color: #93c5fd;
}
.badge-novice {
- background: linear-gradient(
- 90deg,
- rgba(16, 185, 129, 0.1) 0%,
- rgba(52, 211, 153, 0.3) 50%,
- rgba(16, 185, 129, 0.1) 100%
- );
- background-size: 200% auto;
- animation: shimmer-bg 5s linear infinite;
+ background: linear-gradient(
+ 90deg,
+ rgba(16, 185, 129, 0.1) 0%,
+ rgba(52, 211, 153, 0.3) 50%,
+ rgba(16, 185, 129, 0.1) 100%
+ );
+ background-size: 200% auto;
+ animation: shimmer-bg 5s linear infinite;
- border: 1px solid rgba(16, 185, 129, 0.4);
- color: #6ee7b7;
+ border: 1px solid rgba(16, 185, 129, 0.4);
+ color: #6ee7b7;
}
.badge-newbie {
- background: rgba(107, 114, 128, 0.15);
- border: 1px solid rgba(107, 114, 128, 0.4);
- color: #d1d5db;
+ background: rgba(107, 114, 128, 0.15);
+ border: 1px solid rgba(107, 114, 128, 0.4);
+ color: #d1d5db;
}
.badge-none {
- background: rgba(55, 65, 81, 0.15);
- border: 1px dashed rgba(55, 65, 81, 0.4);
- color: #9ca3af;
+ background: rgba(55, 65, 81, 0.15);
+ border: 1px dashed rgba(55, 65, 81, 0.4);
+ color: #9ca3af;
}
diff --git a/app/hooks/useBadWords.ts b/app/hooks/useBadWords.ts
index db357f9..b379a65 100644
--- a/app/hooks/useBadWords.ts
+++ b/app/hooks/useBadWords.ts
@@ -74,4 +74,4 @@ export function useBadWords() {
return {
badWords,
};
-}
\ No newline at end of file
+}
diff --git a/app/internal-server-error.tsx b/app/internal-server-error.tsx
index 263db55..5e201b6 100644
--- a/app/internal-server-error.tsx
+++ b/app/internal-server-error.tsx
@@ -7,11 +7,13 @@ export default function InternalServerError() {
Internal Server Error
- Oops! Something went wrong on our end. Please try refreshing the page or come back later.
+ Oops! Something went wrong on our end. Please try refreshing the page
+ or come back later.
- Tip: Theres nothing you can do about this, but we’re already on it. Thanks for your patience!
+ Tip: Theres nothing you can do about this, but we’re already on it.
+ Thanks for your patience!
diff --git a/app/lib/auth.ts b/app/lib/auth.ts
new file mode 100644
index 0000000..14fe584
--- /dev/null
+++ b/app/lib/auth.ts
@@ -0,0 +1,123 @@
+import NextAuth from "next-auth";
+import { PrismaAdapter } from "@auth/prisma-adapter";
+import Credentials from "next-auth/providers/credentials";
+import Google from "next-auth/providers/google";
+import GitHub from "next-auth/providers/github";
+import MicrosoftEntraID from "next-auth/providers/microsoft-entra-id";
+import bcrypt from "bcryptjs";
+import { prisma } from "./prisma";
+
+export const { handlers, auth, signIn, signOut } = NextAuth({
+ adapter: PrismaAdapter(prisma),
+ session: { strategy: "jwt" },
+ providers: [
+ Credentials({
+ credentials: {
+ email: { type: "email" },
+ password: { type: "password" },
+ },
+ async authorize(credentials) {
+ if (!credentials?.email || !credentials?.password) return null;
+
+ const user = await prisma.user.findUnique({
+ where: { email: credentials.email as string },
+ });
+
+ if (!user?.password) return null;
+
+ const valid = await bcrypt.compare(
+ credentials.password as string,
+ user.password,
+ );
+
+ if (!valid) return null;
+
+ return {
+ id: user.id,
+ email: user.email,
+ name: user.name,
+ role: user.role,
+ };
+ },
+ }),
+ Google,
+ GitHub,
+ MicrosoftEntraID,
+ ],
+ callbacks: {
+ async jwt({ token, user }) {
+ if (user?.id) {
+ token.id = user.id;
+ }
+
+ if (typeof user?.role === "string") {
+ token.role = user.role;
+ }
+
+ if (token.sub && typeof token.role !== "string") {
+ const dbUser = await prisma.user.findUnique({
+ where: { id: token.sub },
+ select: { role: true },
+ });
+ token.role = dbUser?.role ?? "user";
+ }
+
+ return token;
+ },
+ async session({ session, token }) {
+ if (token.sub) {
+ session.user.id = token.sub;
+ }
+ session.user.role =
+ typeof token.role === "string" ? token.role : "user";
+ return session;
+ },
+ async signIn({ user, account }) {
+ if (!user.id) return true;
+
+ await prisma.userStats.upsert({
+ where: { userId: user.id },
+ create: { userId: user.id },
+ update: {},
+ });
+
+ await prisma.userProjects.upsert({
+ where: { userId: user.id },
+ create: { userId: user.id },
+ update: {},
+ });
+
+ const globalConversationId = process.env.GLOBAL_CONVERSATION_ID;
+ if (globalConversationId && user.email) {
+ await prisma.conversation.upsert({
+ where: { id: globalConversationId },
+ create: { id: globalConversationId, type: "GLOBAL" },
+ update: {},
+ });
+
+ await prisma.conversationParticipant.upsert({
+ where: {
+ conversationId_userId: {
+ conversationId: globalConversationId,
+ userId: user.id,
+ },
+ },
+ create: {
+ conversationId: globalConversationId,
+ userId: user.id,
+ email: user.email,
+ type: "global",
+ },
+ update: {},
+ });
+ }
+
+ void account;
+ return true;
+ },
+ },
+ pages: {
+ signIn: "/login",
+ error: "/login",
+ },
+});
diff --git a/app/lib/auth/user.ts b/app/lib/auth/user.ts
new file mode 100644
index 0000000..d4c4d44
--- /dev/null
+++ b/app/lib/auth/user.ts
@@ -0,0 +1,22 @@
+import { cache } from "react";
+import { auth } from "@/app/lib/auth";
+import { prisma } from "@/app/lib/prisma";
+
+export const getCurrentUser = cache(async () => {
+ const session = await auth();
+ if (!session?.user?.id) return { user: null };
+
+ const user = await prisma.user.findUnique({
+ where: { id: session.user.id },
+ select: {
+ id: true,
+ email: true,
+ name: true,
+ image: true,
+ role: true,
+ wakatimeApiKey: true,
+ },
+ });
+
+ return { user };
+});
diff --git a/app/lib/emitter.ts b/app/lib/emitter.ts
new file mode 100644
index 0000000..0d304fe
--- /dev/null
+++ b/app/lib/emitter.ts
@@ -0,0 +1,8 @@
+import { EventEmitter } from "events";
+
+const globalForEmitter = globalThis as unknown as { emitter: EventEmitter };
+
+export const emitter = globalForEmitter.emitter ?? new EventEmitter();
+emitter.setMaxListeners(100);
+
+if (process.env.NODE_ENV !== "production") globalForEmitter.emitter = emitter;
diff --git a/app/lib/prisma.ts b/app/lib/prisma.ts
new file mode 100644
index 0000000..1bee0b9
--- /dev/null
+++ b/app/lib/prisma.ts
@@ -0,0 +1,7 @@
+import { PrismaClient } from "@prisma/client";
+
+const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
+
+export const prisma = globalForPrisma.prisma ?? new PrismaClient();
+
+if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
diff --git a/app/lib/proxy/auth.ts b/app/lib/proxy/auth.ts
index 36713eb..27205a5 100644
--- a/app/lib/proxy/auth.ts
+++ b/app/lib/proxy/auth.ts
@@ -1,59 +1,14 @@
import { NextResponse, type NextRequest } from "next/server";
-import { createServerClient } from "@supabase/ssr";
+import { auth } from "@/app/lib/auth";
export default async function Auth(req: NextRequest) {
- const response = NextResponse.next({
- request: { headers: req.headers },
- });
-
- const supabase = createServerClient(
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
- {
- cookies: {
- get(name) {
- return req.cookies.get(name)?.value;
- },
- set(name, value, options) {
- response.cookies.set({ name, value, ...options });
- },
- remove(name, options) {
- response.cookies.set({ name, value: "", ...options });
- },
- },
- },
- );
-
- const code = req.nextUrl.searchParams.get("code");
- if (code) {
- const { error } = await supabase.auth.exchangeCodeForSession(code);
- if (error) {
- console.error("Supabase code exchange failed:", error.message);
- } else {
- const redirectUrl = req.nextUrl.clone();
- redirectUrl.searchParams.delete("code");
-
- const redirectResponse = NextResponse.redirect(redirectUrl);
- response.cookies.getAll().forEach((cookie) => {
- redirectResponse.cookies.set(cookie);
- });
-
- return redirectResponse;
- }
- }
-
- const {
- data: { session },
- } = await supabase.auth.getSession();
-
+ const session = await auth();
const { pathname } = req.nextUrl;
- // Define protected routes that require authentication
const protectedRoutes = ["/d", "/api/wakatime/sync"];
- const isProtectedRoute = protectedRoutes.some((route) => {
- const regex = new RegExp(`^${route}(/.*)?$`);
- return regex.test(pathname);
- });
+ const isProtectedRoute = protectedRoutes.some((route) =>
+ new RegExp(`^${route}(/.*)?$`).test(pathname),
+ );
if (isProtectedRoute && !session) {
console.log("User is not authenticated, redirecting to login.");
@@ -71,5 +26,5 @@ export default async function Auth(req: NextRequest) {
return NextResponse.redirect(new URL("/", req.url));
}
- return response;
+ return null;
}
diff --git a/app/lib/supabase/client.ts b/app/lib/supabase/client.ts
deleted file mode 100644
index 058d56d..0000000
--- a/app/lib/supabase/client.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { createBrowserClient } from "@supabase/ssr";
-import type { Database } from "@/app/supabase-types";
-
-export function createClient() {
- return createBrowserClient