Form implementation, api routes

This commit is contained in:
2024-09-26 16:04:57 -04:00
parent 66137ff7b4
commit 6584a48f27
23 changed files with 663 additions and 214 deletions

View File

@@ -0,0 +1,58 @@
import { NextResponse } from "next/server";
import { db } from "~/server/db";
import { informedConsentForms, contents } from "~/server/db/schema";
import { auth } from "@clerk/nextjs/server";
import { eq } from "drizzle-orm";
import fs from 'fs/promises';
import path from 'path';
export async function DELETE(
request: Request,
{ params }: { params: { id: string } }
) {
const { userId } = auth();
if (!userId) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const id = parseInt(params.id);
if (isNaN(id)) {
return NextResponse.json({ error: 'Invalid ID' }, { status: 400 });
}
try {
// First, get the content associated with this form
const [form] = await db
.select({
contentId: informedConsentForms.contentId,
location: contents.location,
})
.from(informedConsentForms)
.innerJoin(contents, eq(informedConsentForms.contentId, contents.id))
.where(eq(informedConsentForms.id, id));
if (!form) {
return NextResponse.json({ error: 'Form not found' }, { status: 404 });
}
// Delete the file from the file system
const fullPath = path.join(process.cwd(), form.location);
try {
await fs.access(fullPath);
await fs.unlink(fullPath);
} catch (error) {
console.warn(`File not found or couldn't be deleted: ${fullPath}`);
}
// Delete the form and content from the database
await db.transaction(async (tx) => {
await tx.delete(informedConsentForms).where(eq(informedConsentForms.id, id));
await tx.delete(contents).where(eq(contents.id, form.contentId));
});
return NextResponse.json({ message: "Form deleted successfully" });
} catch (error) {
console.error('Error deleting form:', error);
return NextResponse.json({ error: 'Failed to delete form' }, { status: 500 });
}
}

104
src/app/api/forms/route.ts Normal file
View File

@@ -0,0 +1,104 @@
import { NextResponse } from "next/server";
import { db } from "~/server/db";
import { contents, informedConsentForms, contentTypes } from "~/server/db/schema";
import { auth } from "@clerk/nextjs/server";
import { eq } from "drizzle-orm";
import { saveFile } from "~/lib/fileStorage";
import fs from 'fs/promises';
// Function to generate a random string
const generateRandomString = (length: number) => {
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
return result;
};
export async function GET(request: Request) {
const { userId } = auth();
if (!userId) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const forms = await db.select({
id: informedConsentForms.id,
title: contents.title,
location: contents.location,
previewLocation: contents.previewLocation,
studyId: informedConsentForms.studyId,
participantId: informedConsentForms.participantId,
contentId: informedConsentForms.contentId,
}).from(informedConsentForms)
.innerJoin(contents, eq(informedConsentForms.contentId, contents.id));
return NextResponse.json(forms);
}
export async function POST(request: Request) {
const { userId } = auth();
if (!userId) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const formData = await request.formData();
const file = formData.get('file') as File;
const title = formData.get('title') as string;
const studyId = formData.get('studyId') as string;
const participantId = formData.get('participantId') as string;
if (!file || !title || !studyId || !participantId) {
return NextResponse.json({ error: 'Missing required fields' }, { status: 400 });
}
try {
const [formContentType] = await db
.select()
.from(contentTypes)
.where(eq(contentTypes.name, "Informed Consent Form"));
const [previewContentType] = await db
.select()
.from(contentTypes)
.where(eq(contentTypes.name, "Preview Image"));
if (!formContentType || !previewContentType) {
return NextResponse.json({ error: 'Content type not found' }, { status: 500 });
}
// Generate a random filename with the same extension
const fileExtension = file.name.split('.').pop(); // Get the file extension
const randomFileName = `${generateRandomString(12)}.${fileExtension}`; // Generate random filename with 12 characters
const { pdfPath, previewPath } = await saveFile(file, `${formContentType.id}/${randomFileName}`, previewContentType.id);
const [content] = await db
.insert(contents)
.values({
contentTypeId: formContentType.id,
uploader: userId,
location: pdfPath,
previewLocation: previewPath,
title: title,
})
.returning();
if (!content) {
throw new Error("Content not found");
}
const [form] = await db
.insert(informedConsentForms)
.values({
studyId: parseInt(studyId),
participantId: parseInt(participantId),
contentId: content.id,
})
.returning();
return NextResponse.json(form);
} catch (error) {
console.error('Error uploading form:', error);
return NextResponse.json({ error: 'Failed to upload form' }, { status: 500 });
}
}