This commit is contained in:
Sir Blob
2025-01-25 01:19:36 -05:00
10 changed files with 7266 additions and 49 deletions

View File

@@ -0,0 +1,79 @@
import mongoose from 'mongoose';
import { User } from '../../../models/User';
import crypto from 'crypto';
import { NextResponse } from 'next/server';
const CLERK_WEBHOOK_SECRET = process.env.CLERK_WEBHOOK_SECRET;
async function connectDB() {
if (mongoose.connection.readyState >= 1) return;
await mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
}
export async function POST(req) {
if (req.method !== 'POST') {
return NextResponse.json(
{ message: 'Method Not Allowed' },
{ status: 405 }
);
}
try {
const webhookSignature = req.headers.get('clerk-signature');
const payload = JSON.stringify(await req.json());
const hmac = crypto.createHmac('sha256', CLERK_WEBHOOK_SECRET);
hmac.update(payload);
const computedSignature = hmac.digest('hex');
if (computedSignature !== webhookSignature) {
return NextResponse.json(
{ message: 'Invalid webhook signature' },
{ status: 400 }
);
}
await connectDB();
const { name, email } = await req.json();
if (!name || !email) {
return NextResponse.json(
{ message: 'Name and email are required' },
{ status: 400 }
);
}
let user = await User.findOne({ email });
if (user) {
return NextResponse.json(
{ message: 'User already exists' },
{ status: 400 }
);
}
user = new User({
name,
email,
role: 'patient',
medicalConditions: [],
medications: [],
});
await user.save();
return NextResponse.json(
{ message: 'User successfully created' },
{ status: 200 }
);
} catch (error) {
console.error(error);
return NextResponse.json(
{ message: 'Internal server error' },
{ status: 500 }
);
}
}

View File

@@ -1,49 +1,29 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import { Analytics } from "@vercel/analytics/react";
import { SpeedInsights } from "@vercel/speed-insights/next";
// import { ThemeProvider } from "@/components/theme-provider";
// import { NavigationMenuDemo } from "@/components/navbar";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
import {
ClerkProvider,
SignInButton,
SignedIn,
SignedOut,
UserButton
} from '@clerk/nextjs'
import './globals.css'
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{/* <ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
></ThemeProvider> */}
<Analytics />
<SpeedInsights />
{/* <NavigationMenuDemo /> */}
{children}
</body>
</html>
);
children,
}: {
children: React.ReactNode
}) {
return (
<ClerkProvider>
<html lang="en">
<body>
<SignedOut>
<SignInButton />
</SignedOut>
<SignedIn>
<UserButton />
</SignedIn>
{children}
</body>
</html>
</ClerkProvider>
)
}

33
src/app/lib/connectDB.js Normal file
View File

@@ -0,0 +1,33 @@
import mongoose from "mongoose";
const DATABASE_URL = process.env.MONGO_URI;
if (!DATABASE_URL) {
throw new Error("Please define the DATABASE_URL environment variable inside .env.local");
}
let cached = global.mongoose;
if (!cached) {
cached = global.mongoose = { conn: null, promise: null };
}
async function connectDB() {
if (cached.conn) {
return cached.conn;
}
if (!cached.promise) {
const opts = {
bufferCommands: false,
};
cached.promise = mongoose.connect(DATABASE_URL, opts).then((mongoose) => {
return mongoose;
});
}
cached.conn = await cached.promise;
return cached.conn;
}
export default connectDB;