feat:update form

This commit is contained in:
2026-07-28 00:02:34 +07:00 Unverified
parent 0e8c816276
commit fa35f00f38
25 changed files with 919 additions and 149 deletions
+25 -6
View File
@@ -7,7 +7,7 @@ import {
getFilteredSubmissions,
parseResultFilters,
} from "@/lib/admin-form-results";
import { formatStoredAnswer } from "@/lib/form-answer-values";
import { answerCellValue } from "@/lib/form-answer-values";
import { stripHtml } from "@/lib/utils";
function csvCell(value: unknown) {
@@ -25,6 +25,24 @@ function safeFilename(value: string) {
);
}
function safeAsciiFilename(value: string) {
return (
value
.normalize("NFKD")
.replace(/[^\x00-\x7F]/g, "")
.replace(/[^A-Za-z0-9]+/g, "-")
.replace(/^-|-$/g, "")
.slice(0, 60) || "form"
);
}
function csvContentDisposition(title: string, date: string) {
const unicodeFilename = `${safeFilename(title)}-responses-${date}.csv`;
const asciiFilename = `${safeAsciiFilename(title)}-responses-${date}.csv`;
return `attachment; filename="${asciiFilename}"; filename*=UTF-8''${encodeURIComponent(unicodeFilename)}`;
}
export async function GET(
request: Request,
{ params }: { params: Promise<{ id: string }> }
@@ -59,7 +77,7 @@ export async function GET(
const answerMap = new Map(
answerRows.map((answer) => [
`${answer.submissionId}:${answer.questionId}`,
answer.value,
{ value: answer.value, imageCdnId: answer.imageCdnId ?? null },
])
);
const header = [
@@ -83,9 +101,10 @@ export async function GET(
? submission.editHistory.length
: 0,
...questions.map((question) =>
formatStoredAnswer(
answerMap.get(`${submission.id}:${question.id}`) || "",
question.type
answerCellValue(
answerMap.get(`${submission.id}:${question.id}`)?.value || "",
question.type,
answerMap.get(`${submission.id}:${question.id}`)?.imageCdnId
)
),
]
@@ -98,7 +117,7 @@ export async function GET(
return new NextResponse(`\uFEFF${lines.join("\r\n")}`, {
headers: {
"Content-Type": "text/csv; charset=utf-8",
"Content-Disposition": `attachment; filename="${safeFilename(form.title)}-responses-${date}.csv"`,
"Content-Disposition": csvContentDisposition(form.title, date),
},
});
}