irongit

Building a new website everyday to kickstart any new project I am recruited for.

compose and beginning auth for 8

huncholanehuncholaneauthored
parent d07c445commit 0fd40c79478dbd3e33d5a3f679d2e0a5cb5fddb8Browse files

18 files changed, +568 -113

+0-0.DS_Store

Binary file changed.

+2-0008_hygofitweb/.gitignore
@@ -1,3 +1,5 @@
1+data
2+
13 # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
24 .env
35
+2-0008_hygofitweb/app/api/auth/[...nextauth]/route.ts
@@ -0,0 +1,2 @@
1+import { handlers } from "@/auth"; // Referring to the auth.ts we just created
2+export const { GET, POST } = handlers;
+74-14008_hygofitweb/app/globals.css
@@ -3,25 +3,85 @@
33 @tailwind utilities;
44
55 :root {
6- --background: #ffffff;
7- --foreground: #171717;
6+ /* Primary Colors */
7+ --primary-color: #ff8200; /* Tennessee Orange */
8+ --primary-color-light: #ffa64d;
9+ --primary-color-dark: #cc6600;
10+
11+ /* Secondary Colors */
12+ --secondary-color: #58595b; /* Dark Gray */
13+ --secondary-color-light: #7a7b7d;
14+ --secondary-color-dark: #3a3b3c;
15+
16+ /* Accent Colors */
17+ --accent-color: #ffffff; /* White */
18+ --accent-color-light: #f2f2f2;
19+ --accent-color-dark: #cccccc;
20+
21+ /* Background Colors */
22+ --background-color: #ffffff; /* White */
23+ --background-color-light: #f8f9fa;
24+ --background-color-dark: #ecf0f1;
25+
26+ /* Text Colors */
27+ --text-color: #58595b; /* Dark Gray */
28+ --text-color-light: #7a7b7d;
29+ --text-color-dark: #3a3b3c;
30+
31+ /* Border Colors */
32+ --border-color: #dcdcdc;
33+ --border-color-light: #eaeaea;
34+ --border-color-dark: #bfbfbf;
35+}
36+
37+::-webkit-scrollbar {
38+ @apply w-2;
839 }
940
10-@media (prefers-color-scheme: dark) {
11- :root {
12- --background: #0a0a0a;
13- --foreground: #ededed;
14- }
41+::-webkit-scrollbar-thumb {
42+ @apply rounded bg-primary opacity-15;
1543 }
1644
1745 body {
18- color: var(--foreground);
19- background: var(--background);
20- font-family: Arial, Helvetica, sans-serif;
46+ @apply text-text bg-background;
47+}
48+
49+a {
50+ @apply text-primary;
51+}
52+
53+a:hover {
54+ @apply text-primary-dark;
55+}
56+
57+input {
58+ @apply border border-border p-2 rounded-sm;
59+}
60+
61+button {
62+ @apply bg-primary text-accent p-2 rounded-sm min-w-24;
63+}
64+
65+button:hover {
66+ @apply bg-primary-dark;
67+}
68+
69+h1 {
70+ @apply text-2xl font-bold text-text;
71+}
72+
73+h3 {
74+ @apply text-xl font-semibold text-text;
75+}
76+
77+:disabled {
78+ @apply cursor-not-allowed opacity-50;
79+}
80+
81+tr:nth-child(even) {
82+ @apply bg-background-light;
2183 }
2284
23-@layer utilities {
24- .text-balance {
25- text-wrap: balance;
26- }
85+tr:hover {
86+ @apply bg-accent-dark;
2787 }
+18-1008_hygofitweb/app/layout.tsx
@@ -1,6 +1,7 @@
11 import type { Metadata } from "next";
22 import localFont from "next/font/local";
33 import "./globals.css";
4+import { SignIn } from "@/components/auth/signin-button";
45
56 const geistSans = localFont({
67 src: "./fonts/GeistVF.woff",
@@ -23,12 +24,28 @@ export default function RootLayout({
2324 }: Readonly<{
2425 children: React.ReactNode;
2526 }>) {
27+ const thisYear = new Date().getFullYear();
2628 return (
2729 <html lang="en">
2830 <body
2931 className={`${geistSans.variable} ${geistMono.variable} antialiased`}
3032 >
31- {children}
33+ <div className="h-screen w-screen fixed border flex flex-col justify-between">
34+ <div className="flex h-20 justify-between px-4 w-full border-b">
35+ <div className="text-lg text-primary my-auto">HygoFit</div>
36+ <div className="my-auto">
37+ <SignIn />
38+ </div>
39+ </div>
40+ <div className="overflow-y-auto h-full flex flex-col justify-between">
41+ <div className="p-4">{children}</div>
42+ <footer className="min-h-16 h-16 w-full border-t flex items-center justify-center bg-gray-100">
43+ <p className="text-sm text-gray-600">
44+ © {thisYear} HygoFit. All rights reserved.
45+ </p>
46+ </footer>
47+ </div>
48+ </div>
3249 </body>
3350 </html>
3451 );
+2-96008_hygofitweb/app/page.tsx
@@ -1,101 +1,7 @@
1-import Image from "next/image";
2-
31 export default function Home() {
42 return (
5- <div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
6- <main className="flex flex-col gap-8 row-start-2 items-center sm:items-start">
7- <Image
8- className="dark:invert"
9- src="https://nextjs.org/icons/next.svg"
10- alt="Next.js logo"
11- width={180}
12- height={38}
13- priority
14- />
15- <ol className="list-inside list-decimal text-sm text-center sm:text-left font-[family-name:var(--font-geist-mono)]">
16- <li className="mb-2">
17- Get started by editing{" "}
18- <code className="bg-black/[.05] dark:bg-white/[.06] px-1 py-0.5 rounded font-semibold">
19- app/page.tsx
20- </code>
21- .
22- </li>
23- <li>Save and see your changes instantly.</li>
24- </ol>
25-
26- <div className="flex gap-4 items-center flex-col sm:flex-row">
27- <a
28- className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5"
29- href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
30- target="_blank"
31- rel="noopener noreferrer"
32- >
33- <Image
34- className="dark:invert"
35- src="https://nextjs.org/icons/vercel.svg"
36- alt="Vercel logomark"
37- width={20}
38- height={20}
39- />
40- Deploy now
41- </a>
42- <a
43- className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:min-w-44"
44- href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
45- target="_blank"
46- rel="noopener noreferrer"
47- >
48- Read our docs
49- </a>
50- </div>
51- </main>
52- <footer className="row-start-3 flex gap-6 flex-wrap items-center justify-center">
53- <a
54- className="flex items-center gap-2 hover:underline hover:underline-offset-4"
55- href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
56- target="_blank"
57- rel="noopener noreferrer"
58- >
59- <Image
60- aria-hidden
61- src="https://nextjs.org/icons/file.svg"
62- alt="File icon"
63- width={16}
64- height={16}
65- />
66- Learn
67- </a>
68- <a
69- className="flex items-center gap-2 hover:underline hover:underline-offset-4"
70- href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
71- target="_blank"
72- rel="noopener noreferrer"
73- >
74- <Image
75- aria-hidden
76- src="https://nextjs.org/icons/window.svg"
77- alt="Window icon"
78- width={16}
79- height={16}
80- />
81- Examples
82- </a>
83- <a
84- className="flex items-center gap-2 hover:underline hover:underline-offset-4"
85- href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
86- target="_blank"
87- rel="noopener noreferrer"
88- >
89- <Image
90- aria-hidden
91- src="https://nextjs.org/icons/globe.svg"
92- alt="Globe icon"
93- width={16}
94- height={16}
95- />
96- Go to nextjs.org →
97- </a>
98- </footer>
3+ <div>
4+ <div className="h-96">Content</div>
995 </div>
1006 );
1017 }
+9-0008_hygofitweb/auth.ts
@@ -0,0 +1,9 @@
1+import { prisma } from "@/prisma";
2+import { PrismaAdapter } from "@auth/prisma-adapter";
3+import NextAuth from "next-auth";
4+import Credentials from "next-auth/providers/credentials";
5+
6+export const { handlers, auth, signIn, signOut } = NextAuth({
7+ adapter: PrismaAdapter(prisma),
8+ providers: [],
9+});
+14-0008_hygofitweb/components/auth/signin-button.tsx
@@ -0,0 +1,14 @@
1+import { signIn } from "@/auth";
2+
3+export function SignIn() {
4+ return (
5+ <form
6+ action={async () => {
7+ "use server";
8+ await signIn();
9+ }}
10+ >
11+ <button type="submit">Sign in</button>
12+ </form>
13+ );
14+}
+6-0008_hygofitweb/middleware.ts
@@ -0,0 +1,6 @@
1+const deviceMiddleware = async (req: Request) => {
2+ const headers = new Headers(req.headers);
3+ const deviceId = headers.get("Device-ID");
4+};
5+
6+export default deviceMiddleware;
+232-0008_hygofitweb/package-lock.json
@@ -8,7 +8,10 @@
88 "name": "008_hygofitweb",
99 "version": "0.1.0",
1010 "dependencies": {
11+ "@auth/prisma-adapter": "^2.4.2",
12+ "@prisma/client": "^5.19.1",
1113 "next": "14.2.8",
14+ "next-auth": "^5.0.0-beta.20",
1215 "openai": "^4.58.1",
1316 "react": "^18",
1417 "react-dom": "^18",
@@ -21,6 +24,7 @@
2124 "eslint": "^8",
2225 "eslint-config-next": "14.2.8",
2326 "postcss": "^8",
27+ "prisma": "^5.19.1",
2428 "tailwindcss": "^3.4.1",
2529 "typescript": "^5"
2630 }
@@ -38,6 +42,89 @@
3842 "url": "https://github.com/sponsors/sindresorhus"
3943 }
4044 },
45+ "node_modules/@auth/core": {
46+ "version": "0.34.2",
47+ "resolved": "https://registry.npmjs.org/@auth/core/-/core-0.34.2.tgz",
48+ "integrity": "sha512-KywHKRgLiF3l7PLyL73fjLSIBe1YNcA6sMeew4yMP6cfCWGXZrkkXd32AjRi1hlJ9nvovUBGZHvbn+LijO6ZeQ==",
49+ "license": "ISC",
50+ "dependencies": {
51+ "@panva/hkdf": "^1.1.1",
52+ "@types/cookie": "0.6.0",
53+ "cookie": "0.6.0",
54+ "jose": "^5.1.3",
55+ "oauth4webapi": "^2.10.4",
56+ "preact": "10.11.3",
57+ "preact-render-to-string": "5.2.3"
58+ },
59+ "peerDependencies": {
60+ "@simplewebauthn/browser": "^9.0.1",
61+ "@simplewebauthn/server": "^9.0.2",
62+ "nodemailer": "^6.8.0"
63+ },
64+ "peerDependenciesMeta": {
65+ "@simplewebauthn/browser": {
66+ "optional": true
67+ },
68+ "@simplewebauthn/server": {
69+ "optional": true
70+ },
71+ "nodemailer": {
72+ "optional": true
73+ }
74+ }
75+ },
76+ "node_modules/@auth/core/node_modules/cookie": {
77+ "version": "0.6.0",
78+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
79+ "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
80+ "license": "MIT",
81+ "engines": {
82+ "node": ">= 0.6"
83+ }
84+ },
85+ "node_modules/@auth/core/node_modules/jose": {
86+ "version": "5.8.0",
87+ "resolved": "https://registry.npmjs.org/jose/-/jose-5.8.0.tgz",
88+ "integrity": "sha512-E7CqYpL/t7MMnfGnK/eg416OsFCVUrU/Y3Vwe7QjKhu/BkS1Ms455+2xsqZQVN57/U2MHMBvEb5SrmAZWAIntA==",
89+ "license": "MIT",
90+ "funding": {
91+ "url": "https://github.com/sponsors/panva"
92+ }
93+ },
94+ "node_modules/@auth/core/node_modules/preact": {
95+ "version": "10.11.3",
96+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz",
97+ "integrity": "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==",
98+ "license": "MIT",
99+ "funding": {
100+ "type": "opencollective",
101+ "url": "https://opencollective.com/preact"
102+ }
103+ },
104+ "node_modules/@auth/core/node_modules/preact-render-to-string": {
105+ "version": "5.2.3",
106+ "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz",
107+ "integrity": "sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==",
108+ "license": "MIT",
109+ "dependencies": {
110+ "pretty-format": "^3.8.0"
111+ },
112+ "peerDependencies": {
113+ "preact": ">=10"
114+ }
115+ },
116+ "node_modules/@auth/prisma-adapter": {
117+ "version": "2.4.2",
118+ "resolved": "https://registry.npmjs.org/@auth/prisma-adapter/-/prisma-adapter-2.4.2.tgz",
119+ "integrity": "sha512-QQwnGYfDiyTcAxMVhTrim+lLFFA3TKq3nIrbPtGZXlkiuNQ5t0rUg//Km7Wv21pD5bxhy4aRPlfq7TdFKk3XIw==",
120+ "license": "ISC",
121+ "dependencies": {
122+ "@auth/core": "0.34.2"
123+ },
124+ "peerDependencies": {
125+ "@prisma/client": ">=2.26.0 || >=3 || >=4 || >=5"
126+ }
127+ },
41128 "node_modules/@eslint-community/eslint-utils": {
42129 "version": "4.4.0",
43130 "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@@ -444,6 +531,15 @@
444531 "node": ">=12.4.0"
445532 }
446533 },
534+ "node_modules/@panva/hkdf": {
535+ "version": "1.2.1",
536+ "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.2.1.tgz",
537+ "integrity": "sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==",
538+ "license": "MIT",
539+ "funding": {
540+ "url": "https://github.com/sponsors/panva"
541+ }
542+ },
447543 "node_modules/@pkgjs/parseargs": {
448544 "version": "0.11.0",
449545 "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -455,6 +551,74 @@
455551 "node": ">=14"
456552 }
457553 },
554+ "node_modules/@prisma/client": {
555+ "version": "5.19.1",
556+ "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.19.1.tgz",
557+ "integrity": "sha512-x30GFguInsgt+4z5I4WbkZP2CGpotJMUXy+Gl/aaUjHn2o1DnLYNTA+q9XdYmAQZM8fIIkvUiA2NpgosM3fneg==",
558+ "hasInstallScript": true,
559+ "license": "Apache-2.0",
560+ "engines": {
561+ "node": ">=16.13"
562+ },
563+ "peerDependencies": {
564+ "prisma": "*"
565+ },
566+ "peerDependenciesMeta": {
567+ "prisma": {
568+ "optional": true
569+ }
570+ }
571+ },
572+ "node_modules/@prisma/debug": {
573+ "version": "5.19.1",
574+ "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.19.1.tgz",
575+ "integrity": "sha512-lAG6A6QnG2AskAukIEucYJZxxcSqKsMK74ZFVfCTOM/7UiyJQi48v6TQ47d6qKG3LbMslqOvnTX25dj/qvclGg==",
576+ "devOptional": true,
577+ "license": "Apache-2.0"
578+ },
579+ "node_modules/@prisma/engines": {
580+ "version": "5.19.1",
581+ "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.19.1.tgz",
582+ "integrity": "sha512-kR/PoxZDrfUmbbXqqb8SlBBgCjvGaJYMCOe189PEYzq9rKqitQ2fvT/VJ8PDSe8tTNxhc2KzsCfCAL+Iwm/7Cg==",
583+ "devOptional": true,
584+ "hasInstallScript": true,
585+ "license": "Apache-2.0",
586+ "dependencies": {
587+ "@prisma/debug": "5.19.1",
588+ "@prisma/engines-version": "5.19.1-2.69d742ee20b815d88e17e54db4a2a7a3b30324e3",
589+ "@prisma/fetch-engine": "5.19.1",
590+ "@prisma/get-platform": "5.19.1"
591+ }
592+ },
593+ "node_modules/@prisma/engines-version": {
594+ "version": "5.19.1-2.69d742ee20b815d88e17e54db4a2a7a3b30324e3",
595+ "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.19.1-2.69d742ee20b815d88e17e54db4a2a7a3b30324e3.tgz",
596+ "integrity": "sha512-xR6rt+z5LnNqTP5BBc+8+ySgf4WNMimOKXRn6xfNRDSpHvbOEmd7+qAOmzCrddEc4Cp8nFC0txU14dstjH7FXA==",
597+ "devOptional": true,
598+ "license": "Apache-2.0"
599+ },
600+ "node_modules/@prisma/fetch-engine": {
601+ "version": "5.19.1",
602+ "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.19.1.tgz",
603+ "integrity": "sha512-pCq74rtlOVJfn4pLmdJj+eI4P7w2dugOnnTXpRilP/6n5b2aZiA4ulJlE0ddCbTPkfHmOL9BfaRgA8o+1rfdHw==",
604+ "devOptional": true,
605+ "license": "Apache-2.0",
606+ "dependencies": {
607+ "@prisma/debug": "5.19.1",
608+ "@prisma/engines-version": "5.19.1-2.69d742ee20b815d88e17e54db4a2a7a3b30324e3",
609+ "@prisma/get-platform": "5.19.1"
610+ }
611+ },
612+ "node_modules/@prisma/get-platform": {
613+ "version": "5.19.1",
614+ "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.19.1.tgz",
615+ "integrity": "sha512-sCeoJ+7yt0UjnR+AXZL7vXlg5eNxaFOwC23h0KvW1YIXUoa7+W2ZcAUhoEQBmJTW4GrFqCuZ8YSP0mkDa4k3Zg==",
616+ "devOptional": true,
617+ "license": "Apache-2.0",
618+ "dependencies": {
619+ "@prisma/debug": "5.19.1"
620+ }
621+ },
458622 "node_modules/@rtsao/scc": {
459623 "version": "1.1.0",
460624 "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
@@ -485,6 +649,12 @@
485649 "tslib": "^2.4.0"
486650 }
487651 },
652+ "node_modules/@types/cookie": {
653+ "version": "0.6.0",
654+ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
655+ "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
656+ "license": "MIT"
657+ },
488658 "node_modules/@types/json-schema": {
489659 "version": "7.0.15",
490660 "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
@@ -3713,6 +3883,33 @@
37133883 }
37143884 }
37153885 },
3886+ "node_modules/next-auth": {
3887+ "version": "5.0.0-beta.20",
3888+ "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-5.0.0-beta.20.tgz",
3889+ "integrity": "sha512-+48SjV9k9AtUU3JbEIa4PXNjKIewfFjVGL7Xs2RKkuQ5QqegDNIQiIG8sLk6/qo7RTScQYIGKgeQ5IuQRtrTQg==",
3890+ "license": "ISC",
3891+ "dependencies": {
3892+ "@auth/core": "0.34.2"
3893+ },
3894+ "peerDependencies": {
3895+ "@simplewebauthn/browser": "^9.0.1",
3896+ "@simplewebauthn/server": "^9.0.2",
3897+ "next": "^14.0.0-0 || ^15.0.0-0",
3898+ "nodemailer": "^6.6.5",
3899+ "react": "^18.2.0 || ^19.0.0-0"
3900+ },
3901+ "peerDependenciesMeta": {
3902+ "@simplewebauthn/browser": {
3903+ "optional": true
3904+ },
3905+ "@simplewebauthn/server": {
3906+ "optional": true
3907+ },
3908+ "nodemailer": {
3909+ "optional": true
3910+ }
3911+ }
3912+ },
37163913 "node_modules/next/node_modules/postcss": {
37173914 "version": "8.4.31",
37183915 "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
@@ -3790,6 +3987,15 @@
37903987 "node": ">=0.10.0"
37913988 }
37923989 },
3990+ "node_modules/oauth4webapi": {
3991+ "version": "2.12.2",
3992+ "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-2.12.2.tgz",
3993+ "integrity": "sha512-mtwpQZ+NklZlonbXdyL+ffiOmTf2QDAGNUIJupImPeFPLqPRwEusIhCf7d5u9FgvXn2NtSGdKp2J/4I7VK7dSQ==",
3994+ "license": "MIT",
3995+ "funding": {
3996+ "url": "https://github.com/sponsors/panva"
3997+ }
3998+ },
37933999 "node_modules/object-assign": {
37944000 "version": "4.1.1",
37954001 "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -4337,6 +4543,32 @@
43374543 "node": ">= 0.8.0"
43384544 }
43394545 },
4546+ "node_modules/pretty-format": {
4547+ "version": "3.8.0",
4548+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz",
4549+ "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==",
4550+ "license": "MIT"
4551+ },
4552+ "node_modules/prisma": {
4553+ "version": "5.19.1",
4554+ "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.19.1.tgz",
4555+ "integrity": "sha512-c5K9MiDaa+VAAyh1OiYk76PXOme9s3E992D7kvvIOhCrNsBQfy2mP2QAQtX0WNj140IgG++12kwZpYB9iIydNQ==",
4556+ "devOptional": true,
4557+ "hasInstallScript": true,
4558+ "license": "Apache-2.0",
4559+ "dependencies": {
4560+ "@prisma/engines": "5.19.1"
4561+ },
4562+ "bin": {
4563+ "prisma": "build/index.js"
4564+ },
4565+ "engines": {
4566+ "node": ">=16.13"
4567+ },
4568+ "optionalDependencies": {
4569+ "fsevents": "2.3.3"
4570+ }
4571+ },
43404572 "node_modules/prop-types": {
43414573 "version": "15.8.1",
43424574 "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+4-0008_hygofitweb/package.json
@@ -9,7 +9,10 @@
99 "lint": "next lint"
1010 },
1111 "dependencies": {
12+ "@auth/prisma-adapter": "^2.4.2",
13+ "@prisma/client": "^5.19.1",
1214 "next": "14.2.8",
15+ "next-auth": "^5.0.0-beta.20",
1316 "openai": "^4.58.1",
1417 "react": "^18",
1518 "react-dom": "^18",
@@ -22,6 +25,7 @@
2225 "eslint": "^8",
2326 "eslint-config-next": "14.2.8",
2427 "postcss": "^8",
28+ "prisma": "^5.19.1",
2529 "tailwindcss": "^3.4.1",
2630 "typescript": "^5"
2731 }
+7-0008_hygofitweb/prisma.ts
@@ -0,0 +1,7 @@
1+import { PrismaClient } from "@prisma/client";
2+
3+const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
4+
5+export const prisma = globalForPrisma.prisma || new PrismaClient();
6+
7+if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
+81-0008_hygofitweb/prisma/migrations/20240910062014_nextauth/migration.sql
@@ -0,0 +1,81 @@
1+-- CreateTable
2+CREATE TABLE "User" (
3+ "id" TEXT NOT NULL,
4+ "name" TEXT,
5+ "email" TEXT NOT NULL,
6+ "emailVerified" TIMESTAMP(3),
7+ "image" TEXT,
8+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
9+ "updatedAt" TIMESTAMP(3) NOT NULL,
10+
11+ CONSTRAINT "User_pkey" PRIMARY KEY ("id")
12+);
13+
14+-- CreateTable
15+CREATE TABLE "Account" (
16+ "userId" TEXT NOT NULL,
17+ "type" TEXT NOT NULL,
18+ "provider" TEXT NOT NULL,
19+ "providerAccountId" TEXT NOT NULL,
20+ "refresh_token" TEXT,
21+ "access_token" TEXT,
22+ "expires_at" INTEGER,
23+ "token_type" TEXT,
24+ "scope" TEXT,
25+ "id_token" TEXT,
26+ "session_state" TEXT,
27+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
28+ "updatedAt" TIMESTAMP(3) NOT NULL,
29+
30+ CONSTRAINT "Account_pkey" PRIMARY KEY ("provider","providerAccountId")
31+);
32+
33+-- CreateTable
34+CREATE TABLE "Session" (
35+ "sessionToken" TEXT NOT NULL,
36+ "userId" TEXT NOT NULL,
37+ "expires" TIMESTAMP(3) NOT NULL,
38+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
39+ "updatedAt" TIMESTAMP(3) NOT NULL
40+);
41+
42+-- CreateTable
43+CREATE TABLE "VerificationToken" (
44+ "identifier" TEXT NOT NULL,
45+ "token" TEXT NOT NULL,
46+ "expires" TIMESTAMP(3) NOT NULL,
47+
48+ CONSTRAINT "VerificationToken_pkey" PRIMARY KEY ("identifier","token")
49+);
50+
51+-- CreateTable
52+CREATE TABLE "Authenticator" (
53+ "credentialID" TEXT NOT NULL,
54+ "userId" TEXT NOT NULL,
55+ "providerAccountId" TEXT NOT NULL,
56+ "credentialPublicKey" TEXT NOT NULL,
57+ "counter" INTEGER NOT NULL,
58+ "credentialDeviceType" TEXT NOT NULL,
59+ "credentialBackedUp" BOOLEAN NOT NULL,
60+ "transports" TEXT,
61+
62+ CONSTRAINT "Authenticator_pkey" PRIMARY KEY ("userId","credentialID")
63+);
64+
65+-- CreateIndex
66+CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
67+
68+-- CreateIndex
69+CREATE UNIQUE INDEX "Session_sessionToken_key" ON "Session"("sessionToken");
70+
71+-- CreateIndex
72+CREATE UNIQUE INDEX "Authenticator_credentialID_key" ON "Authenticator"("credentialID");
73+
74+-- AddForeignKey
75+ALTER TABLE "Account" ADD CONSTRAINT "Account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
76+
77+-- AddForeignKey
78+ALTER TABLE "Session" ADD CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
79+
80+-- AddForeignKey
81+ALTER TABLE "Authenticator" ADD CONSTRAINT "Authenticator_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
+3-0008_hygofitweb/prisma/migrations/migration_lock.toml
@@ -0,0 +1,3 @@
1+# Please do not edit this file manually
2+# It should be added in your version-control system (i.e. Git)
3+provider = "postgresql"
+82-0008_hygofitweb/prisma/schema.prisma
@@ -0,0 +1,82 @@
1+datasource db {
2+ provider = "postgresql"
3+ url = env("DATABASE_URL")
4+}
5+
6+generator client {
7+ provider = "prisma-client-js"
8+}
9+
10+model User {
11+ id String @id @default(cuid())
12+ name String?
13+ email String @unique
14+ emailVerified DateTime?
15+ image String?
16+ accounts Account[]
17+ sessions Session[]
18+ // Optional for WebAuthn support
19+ Authenticator Authenticator[]
20+
21+ createdAt DateTime @default(now())
22+ updatedAt DateTime @updatedAt
23+}
24+
25+model Account {
26+ userId String
27+ type String
28+ provider String
29+ providerAccountId String
30+ refresh_token String?
31+ access_token String?
32+ expires_at Int?
33+ token_type String?
34+ scope String?
35+ id_token String?
36+ session_state String?
37+
38+ createdAt DateTime @default(now())
39+ updatedAt DateTime @updatedAt
40+
41+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
42+
43+ @@id([provider, providerAccountId])
44+}
45+
46+model Session {
47+ sessionToken String @unique
48+ userId String
49+ expires DateTime
50+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
51+
52+ createdAt DateTime @default(now())
53+ updatedAt DateTime @updatedAt
54+}
55+
56+model VerificationToken {
57+ identifier String
58+ token String
59+ expires DateTime
60+
61+ @@id([identifier, token])
62+}
63+
64+// Optional for WebAuthn support
65+model Authenticator {
66+ credentialID String @unique
67+ userId String
68+ providerAccountId String
69+ credentialPublicKey String
70+ counter Int
71+ credentialDeviceType String
72+ credentialBackedUp Boolean
73+ transports String?
74+
75+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
76+
77+ @@id([userId, credentialID])
78+}
79+
80+model Device {
81+ id String @unique
82+}
+18-2008_hygofitweb/tailwind.config.ts
@@ -9,8 +9,24 @@ const config: Config = {
99 theme: {
1010 extend: {
1111 colors: {
12- background: "var(--background)",
13- foreground: "var(--foreground)",
12+ primary: "var(--primary-color)",
13+ "primary-light": "var(--primary-color-light)",
14+ "primary-dark": "var(--primary-color-dark)",
15+ secondary: "var(--secondary-color)",
16+ "secondary-light": "var(--secondary-color-light)",
17+ "secondary-dark": "var(--secondary-color-dark)",
18+ accent: "var(--accent-color)",
19+ "accent-light": "var(--accent-color-light)",
20+ "accent-dark": "var(--accent-color-dark)",
21+ background: "var(--background-color)",
22+ "background-light": "var(--background-color-light)",
23+ "background-dark": "var(--background-color-dark)",
24+ text: "var(--text-color)",
25+ "text-light": "var(--text-color-light)",
26+ "text-dark": "var(--text-color-dark)",
27+ border: "var(--border-color)",
28+ "border-light": "var(--border-color-light)",
29+ "border-dark": "var(--border-color-dark)",
1430 },
1531 },
1632 },
+8-0docker-compose.yml
@@ -0,0 +1,8 @@
1+services:
2+ db:
3+ image: postgres:latest
4+ restart: always
5+ environment:
6+ POSTGRES_PASSWORD: postgres
7+ ports:
8+ - "5556:5432"
+6-0package-lock.json
@@ -0,0 +1,6 @@
1+{
2+ "name": "dailywebsites",
3+ "lockfileVersion": 3,
4+ "requires": true,
5+ "packages": {}
6+}