diff --git a/.gitignore b/.gitignore index b622b6b..f7e5220 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,4 @@ yarn-error.log* *.tsbuildinfo next-env.d.ts -public/form-uploads \ No newline at end of file +public/form \ No newline at end of file diff --git a/app/actions/questions.ts b/app/actions/questions.ts index ac2072b..cfd4161 100644 --- a/app/actions/questions.ts +++ b/app/actions/questions.ts @@ -1,6 +1,8 @@ "use server"; import { db } from "@/db"; +import { unlink } from "fs/promises"; +import path from "path"; import { questions } from "@/db/schema"; import type { QuestionType } from "@/db/schema"; import { eq } from "drizzle-orm"; @@ -53,13 +55,40 @@ export async function updateQuestion( }> ) { await assertAdmin(); + if (data.imageUrl !== undefined) { + const q = await db.query.questions.findFirst({ + where: (q, { eq }) => eq(q.id, id), + }); + if (q?.imageUrl && q.imageUrl !== data.imageUrl) { + await deleteImageFile(q.imageUrl); + } + } await db.update(questions).set(data).where(eq(questions.id, id)); revalidatePath("/form"); revalidatePath("/form/admin"); } +async function deleteImageFile(imageUrl: string | null) { + if (!imageUrl) return; + try { + const filename = imageUrl.split("/").pop(); + if (filename) { + const filepath = path.join(process.cwd(), "public", "form", filename); + await unlink(filepath); + } + } catch (err) { + console.error("Failed to delete image file", err); + } +} + export async function deleteQuestion(id: string, formId: string) { await assertAdmin(); + const q = await db.query.questions.findFirst({ + where: (q, { eq }) => eq(q.id, id), + }); + if (q?.imageUrl) { + await deleteImageFile(q.imageUrl); + } await db.delete(questions).where(eq(questions.id, id)); revalidatePath("/form"); revalidatePath("/form/admin"); diff --git a/app/actions/upload.ts b/app/actions/upload.ts index 5877738..1e10b6e 100644 --- a/app/actions/upload.ts +++ b/app/actions/upload.ts @@ -22,11 +22,11 @@ export async function uploadImage(formData: FormData): Promise { const ext = file.name.split(".").pop() ?? "png"; const filename = `${crypto.randomUUID()}.${ext}`; - const uploadDir = path.join(process.cwd(), "public", "form-uploads"); + const uploadDir = path.join(process.cwd(), "public", "form"); await mkdir(uploadDir, { recursive: true }); const buffer = Buffer.from(await file.arrayBuffer()); await writeFile(path.join(uploadDir, filename), buffer); - return `/form-uploads/${filename}`; + return `/form/${filename}`; } diff --git a/app/form/admin/client.tsx b/app/form/admin/client.tsx index f2a1f15..3313ef7 100644 --- a/app/form/admin/client.tsx +++ b/app/form/admin/client.tsx @@ -297,20 +297,21 @@ export default function FormEditorClient({ form, initialQuestions }: FormEditorC
{q.imageUrl ? ( -
+
{q.label}
) : ( diff --git a/app/form/admin/result/[id]/client.tsx b/app/form/admin/result/[id]/client.tsx index 5e7c381..b02ddb5 100644 --- a/app/form/admin/result/[id]/client.tsx +++ b/app/form/admin/result/[id]/client.tsx @@ -159,10 +159,11 @@ export default function SubmissionDetailClient({ {q.imageUrl && (
{q.label}
)} diff --git a/app/form/admin/result/[id]/page.tsx b/app/form/admin/result/[id]/page.tsx index bed404d..5c98dee 100644 --- a/app/form/admin/result/[id]/page.tsx +++ b/app/form/admin/result/[id]/page.tsx @@ -36,6 +36,13 @@ export default async function SubmissionDetailPage({ params }: SubmissionDetailP for (const ans of answersList) { answersMap[ans.questionId] = ans.value; } + const submissionsList = await db.query.submissions.findMany({ + orderBy: (s, { desc }) => [desc(s.submittedAt)], + }); + + const currentIndex = submissionsList.findIndex((s) => s.id === id); + const prevId = currentIndex > 0 ? submissionsList[currentIndex - 1].id : null; + const nextId = currentIndex >= 0 && currentIndex < submissionsList.length - 1 ? submissionsList[currentIndex + 1].id : null; return (
@@ -48,7 +55,19 @@ export default async function SubmissionDetailPage({ params }: SubmissionDetailP

Response Detail

- +
+ {prevId && ( + + + + )} + {nextId && ( + + + + )} + +
)} {userName} @@ -207,20 +208,34 @@ export function FormFillerClient({ form, questions, initialAnswers = {} }: FormF
-
- {q.imageUrl && ( -
- {q.label} -
- )}
{q.type === "text" && ( diff --git a/public/form-uploads/49b49544-58bb-4aee-b301-80a6eecd8976.webp b/public/form-uploads/49b49544-58bb-4aee-b301-80a6eecd8976.webp deleted file mode 100644 index 44ea7ce..0000000 Binary files a/public/form-uploads/49b49544-58bb-4aee-b301-80a6eecd8976.webp and /dev/null differ