diff --git a/package-lock.json b/package-lock.json
index 0e838a9..ea65d21 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
"version": "0.1.0",
"dependencies": {
"@base-ui/react": "^1.1.0",
+ "@next-auth/prisma-adapter": "^1.0.7",
"@prisma/adapter-pg": "^7.3.0",
"@prisma/client": "^7.3.0",
"@radix-ui/react-label": "^2.1.8",
@@ -116,9 +117,9 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.0.tgz",
- "integrity": "sha512-vSH118/wwM/pLR38g/Sgk05sNtro6TlTJKuiMXDaZqPUfjTFcudpCOt00IhOfj+1BFAX+UFAlzCU+6WXr3GLFQ==",
+ "version": "7.29.1",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz",
+ "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1703,15 +1704,25 @@
}
},
"node_modules/@neondatabase/serverless/node_modules/@types/node": {
- "version": "22.19.7",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.7.tgz",
- "integrity": "sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw==",
+ "version": "22.19.9",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.9.tgz",
+ "integrity": "sha512-PD03/U8g1F9T9MI+1OBisaIARhSzeidsUjQaf51fOxrfjeiKN9bLVO06lHuHYjxdnqLWJijJHfqXPSJri2EM2A==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
}
},
+ "node_modules/@next-auth/prisma-adapter": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@next-auth/prisma-adapter/-/prisma-adapter-1.0.7.tgz",
+ "integrity": "sha512-Cdko4KfcmKjsyHFrWwZ//lfLUbcLqlyFqjd/nYE2m3aZ7tjMNUjpks47iw7NTCnXf+5UWz5Ypyt1dSs1EP5QJw==",
+ "license": "ISC",
+ "peerDependencies": {
+ "@prisma/client": ">=2.26.0 || >=3",
+ "next-auth": "^4"
+ }
+ },
"node_modules/@next/env": {
"version": "16.1.6",
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.1.6.tgz",
@@ -5625,9 +5636,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
- "version": "20.19.30",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz",
- "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==",
+ "version": "20.19.32",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.32.tgz",
+ "integrity": "sha512-Ez8QE4DMfhjjTsES9K2dwfV258qBui7qxUsoaixZDiTzbde4U12e1pXGNu/ECsUIOi5/zoCxAQxIhQnaUQ2VvA==",
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
@@ -5646,9 +5657,9 @@
}
},
"node_modules/@types/react": {
- "version": "19.2.10",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.10.tgz",
- "integrity": "sha512-WPigyYuGhgZ/cTPRXB2EwUw+XvsRA3GqHlsP4qteqrnnjDrApbS7MxcGr/hke5iUoeB7E/gQtrs9I37zAJ0Vjw==",
+ "version": "19.2.13",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.13.tgz",
+ "integrity": "sha512-KkiJeU6VbYbUOp5ITMIc7kBfqlYkKA5KhEHVrGMmUUMt7NeaZg65ojdPk+FtNrBAOXNVM5QM72jnADjM+XVRAQ==",
"devOptional": true,
"license": "MIT",
"dependencies": {
@@ -5886,9 +5897,9 @@
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
- "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
"dev": true,
"license": "ISC",
"bin": {
@@ -6711,9 +6722,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001766",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz",
- "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==",
+ "version": "1.0.30001769",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz",
+ "integrity": "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==",
"funding": [
{
"type": "opencollective",
@@ -6843,9 +6854,9 @@
"license": "MIT"
},
"node_modules/confbox": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz",
- "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==",
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz",
+ "integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==",
"devOptional": true,
"license": "MIT"
},
@@ -7225,9 +7236,9 @@
}
},
"node_modules/dotenv": {
- "version": "17.2.3",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz",
- "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==",
+ "version": "17.2.4",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.4.tgz",
+ "integrity": "sha512-mudtfb4zRB4bVvdj0xRo+e6duH1csJRM8IukBqfTRvHotn9+LBXB8ynAidP9zHqoRC/fsllXgk4kCKlR21fIhw==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
@@ -7263,9 +7274,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.5.283",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.283.tgz",
- "integrity": "sha512-3vifjt1HgrGW/h76UEeny+adYApveS9dH2h3p57JYzBSXJIKUJAvtmIytDKjcSCt9xHfrNCFJ7gts6vkhuq++w==",
+ "version": "1.5.286",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz",
+ "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==",
"dev": true,
"license": "ISC"
},
@@ -7287,14 +7298,14 @@
}
},
"node_modules/enhanced-resolve": {
- "version": "5.18.4",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz",
- "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==",
+ "version": "5.19.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz",
+ "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==",
"dev": true,
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.4",
- "tapable": "^2.2.0"
+ "tapable": "^2.3.0"
},
"engines": {
"node": ">=10.13.0"
@@ -8170,12 +8181,12 @@
}
},
"node_modules/framer-motion": {
- "version": "12.31.0",
- "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.31.0.tgz",
- "integrity": "sha512-Tnd0FU05zGRFI3JJmBegXonF1rfuzYeuXd1QSdQ99Ysnppk0yWBWSW2wUsqzRpS5nv0zPNx+y0wtDj4kf0q5RQ==",
+ "version": "12.33.0",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.33.0.tgz",
+ "integrity": "sha512-ca8d+rRPcDP5iIF+MoT3WNc0KHJMjIyFAbtVLvM9eA7joGSpeqDfiNH/kCs1t4CHi04njYvWyj0jS4QlEK/rJQ==",
"license": "MIT",
"dependencies": {
- "motion-dom": "^12.30.1",
+ "motion-dom": "^12.33.0",
"motion-utils": "^12.29.2",
"tslib": "^2.4.0"
},
@@ -8355,9 +8366,9 @@
}
},
"node_modules/get-tsconfig": {
- "version": "4.13.1",
- "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.1.tgz",
- "integrity": "sha512-EoY1N2xCn44xU6750Sx7OjOIT59FkmstNc3X6y5xpz7D5cBtZRe/3pSlTkDJgqsOk3WwZPkWfonhhUJfttQo3w==",
+ "version": "4.13.6",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz",
+ "integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==",
"license": "MIT",
"dependencies": {
"resolve-pkg-maps": "^1.0.0"
@@ -8758,9 +8769,9 @@
}
},
"node_modules/is-bun-module/node_modules/semver": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
- "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
"dev": true,
"license": "ISC",
"bin": {
@@ -9608,9 +9619,9 @@
}
},
"node_modules/lru.min": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.3.tgz",
- "integrity": "sha512-Lkk/vx6ak3rYkRR0Nhu4lFUT2VDnQSxBe8Hbl7f36358p6ow8Bnvr8lrLt98H8J1aGxfhbX4Fs5tYg2+FTwr5Q==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.4.tgz",
+ "integrity": "sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA==",
"devOptional": true,
"license": "MIT",
"engines": {
@@ -9706,9 +9717,9 @@
}
},
"node_modules/motion-dom": {
- "version": "12.30.1",
- "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.30.1.tgz",
- "integrity": "sha512-QXB+iFJRzZTqL+Am4a1CRoHdH+0Nq12wLdqQQZZsfHlp9AMt6PA098L/61oVZsDA+Ep3QSGudzpViyRrhYhGcQ==",
+ "version": "12.33.0",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.33.0.tgz",
+ "integrity": "sha512-XRPebVypsl0UM+7v0Hr8o9UAj0S2djsQWRdHBd5iVouVpMrQqAI0C/rDAT3QaYnXnHuC5hMcwDHCboNeyYjPoQ==",
"license": "MIT",
"dependencies": {
"motion-utils": "^12.29.2"
@@ -9930,9 +9941,9 @@
"license": "MIT"
},
"node_modules/nypm": {
- "version": "0.6.4",
- "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.4.tgz",
- "integrity": "sha512-1TvCKjZyyklN+JJj2TS3P4uSQEInrM/HkkuSXsEzm1ApPgBffOn8gFguNnZf07r/1X6vlryfIqMUkJKQMzlZiw==",
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.5.tgz",
+ "integrity": "sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ==",
"devOptional": true,
"license": "MIT",
"dependencies": {
@@ -10568,6 +10579,13 @@
"react-is": "^16.13.1"
}
},
+ "node_modules/prop-types/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/proper-lockfile": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz",
@@ -10832,10 +10850,11 @@
}
},
"node_modules/react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
- "license": "MIT"
+ "version": "19.2.4",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.4.tgz",
+ "integrity": "sha512-W+EWGn2v0ApPKgKKCy/7s7WHXkboGcsrXE+2joLyVxkbyVQfO3MUEaUQDHoSmb8TFFrSKYa9mw64WZHNHSDzYA==",
+ "license": "MIT",
+ "peer": true
},
"node_modules/react-redux": {
"version": "9.2.0",
@@ -11319,9 +11338,9 @@
}
},
"node_modules/sharp/node_modules/semver": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
- "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
"license": "ISC",
"optional": true,
"bin": {
diff --git a/package.json b/package.json
index 075c36e..6bd68cb 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,7 @@
},
"dependencies": {
"@base-ui/react": "^1.1.0",
+ "@next-auth/prisma-adapter": "^1.0.7",
"@prisma/adapter-pg": "^7.3.0",
"@prisma/client": "^7.3.0",
"@radix-ui/react-label": "^2.1.8",
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 8fb2352..50b0f62 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -18,17 +18,57 @@ enum Sentiment {
neutral
}
-model User {
- id Int @id @default(autoincrement())
- email String @unique
- name String?
- gender UserGender?
- productReference String?
- password String
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
+model Account {
+ id Int @id @default(autoincrement())
+ userId Int
+ type String
+ provider String
+ providerAccountId String
+ refresh_token String?
+ access_token String?
+ expires_at Int?
+ token_type String?
+ scope String?
+ id_token String?
+ session_state String?
- analysis Analysis[]
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
+
+ @@unique([provider, providerAccountId])
+}
+
+model Session {
+ id Int @id @default(autoincrement())
+ sessionToken String @unique
+ userId Int
+ expires DateTime
+
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
+}
+
+model VerificationToken {
+ identifier String
+ token String @unique
+ expires DateTime
+
+ @@unique([identifier, token])
+}
+
+
+model User {
+ id Int @id @default(autoincrement())
+ name String?
+ email String? @unique
+ emailVerified DateTime?
+ image String?
+ gender UserGender?
+ productReference String?
+ password String?
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ accounts Account[]
+ sessions Session[]
+ analysis Analysis[]
}
model Analysis {
diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts
index 06596ea..2b72140 100644
--- a/src/app/api/auth/[...nextauth]/route.ts
+++ b/src/app/api/auth/[...nextauth]/route.ts
@@ -1,15 +1,22 @@
import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";
+import { PrismaAdapter } from "@next-auth/prisma-adapter";
+import prisma from "@/lib/prisma";
+
+export const runtime = "nodejs";
export const authOptions = {
+ secret: process.env.NEXTAUTH_SECRET,
+ adapter: PrismaAdapter(prisma),
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
}),
],
+ debug: true,
+ session: { strategy: "database" as const },
};
const handler = NextAuth(authOptions);
-
export { handler as GET, handler as POST };
diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx
index 3afcfbd..d81920a 100644
--- a/src/app/dashboard/page.tsx
+++ b/src/app/dashboard/page.tsx
@@ -1,9 +1,10 @@
import { redirect } from "next/navigation";
import { getServerSession } from "next-auth";
import DashboardClient from "@/src/components/dashboards/DashboardClient";
+import { authOptions } from "../api/auth/[...nextauth]/route";
export default async function DashboardPage() {
- const session = await getServerSession();
+ const session = await getServerSession(authOptions);
if (!session) {
redirect("/");
diff --git a/src/components/auth/LoginForm.tsx b/src/components/auth/LoginForm.tsx
index fd2da21..bd8a6a9 100644
--- a/src/components/auth/LoginForm.tsx
+++ b/src/components/auth/LoginForm.tsx
@@ -42,7 +42,7 @@ export function LoginForm({
diff --git a/src/components/dashboards/Header.tsx b/src/components/dashboards/Header.tsx
index 88d67bd..4e4e51c 100644
--- a/src/components/dashboards/Header.tsx
+++ b/src/components/dashboards/Header.tsx
@@ -4,6 +4,7 @@ import {
Database,
Laptop,
LogOut,
+ Smile,
User,
UserCircle,
} from "lucide-react";
@@ -18,11 +19,11 @@ import {
DropdownMenuTrigger,
} from "../ui/dropdown-menu";
import { signOut, useSession } from "next-auth/react";
-import { redirect } from "next/navigation";
export function Header() {
const [isRefreshing, setIsRefreshing] = useState(false);
const [open, setOpen] = useState(false);
+ const session = useSession();
const handleRefresh = () => {
setIsRefreshing(true);
@@ -57,11 +58,12 @@ export function Header() {