Add functions to commission form
This commit is contained in:
88
src/actions/commissions/submitCommissionRequest.ts
Normal file
88
src/actions/commissions/submitCommissionRequest.ts
Normal file
@ -0,0 +1,88 @@
|
||||
"use server";
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
/**
|
||||
* Server action
|
||||
* Forwards a multipart/form-data request (payload + files[])
|
||||
* from the public app to the admin app's public commissions endpoint.
|
||||
*
|
||||
* Server-only env required:
|
||||
* ADMIN_URL=https://admin.domain.com
|
||||
*/
|
||||
|
||||
const submitPayloadSchema = z.object({
|
||||
typeId: z.string().optional().nullable(),
|
||||
optionId: z.string().optional().nullable(),
|
||||
extraIds: z.array(z.string()).default([]),
|
||||
|
||||
customerName: z.string().min(1),
|
||||
customerEmail: z.string().email(),
|
||||
customerSocials: z.string().optional().nullable(),
|
||||
message: z.string().min(1),
|
||||
});
|
||||
|
||||
export type SubmitCommissionPayload = z.infer<typeof submitPayloadSchema>;
|
||||
|
||||
export async function submitCommissionRequest(input: {
|
||||
payload: SubmitCommissionPayload;
|
||||
files: File[];
|
||||
}) {
|
||||
const adminUrl = process.env.ADMIN_URL;
|
||||
if (!adminUrl) {
|
||||
throw new Error("ADMIN_URL is not set on the server");
|
||||
}
|
||||
|
||||
const payload = submitPayloadSchema.parse(input.payload);
|
||||
const files = input.files ?? [];
|
||||
|
||||
// Optional safety limits
|
||||
const MAX_FILES = 10;
|
||||
const MAX_BYTES_EACH = 10 * 1024 * 1024; // 10MB
|
||||
|
||||
if (files.length > MAX_FILES) {
|
||||
throw new Error("Too many files");
|
||||
}
|
||||
|
||||
for (const f of files) {
|
||||
if (f.size > MAX_BYTES_EACH) {
|
||||
throw new Error(`File too large: ${f.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
const fd = new FormData();
|
||||
fd.set("payload", JSON.stringify(payload));
|
||||
|
||||
for (const file of files) {
|
||||
fd.append("files", file, file.name);
|
||||
}
|
||||
|
||||
const res = await fetch(
|
||||
`${adminUrl.replace(/\/$/, "")}/api/v1/commissions`,
|
||||
{
|
||||
method: "POST",
|
||||
body: fd,
|
||||
cache: "no-store",
|
||||
}
|
||||
);
|
||||
|
||||
if (!res.ok) {
|
||||
const text = await res.text().catch(() => "");
|
||||
let parsed: any = null;
|
||||
try {
|
||||
parsed = text ? JSON.parse(text) : null;
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
|
||||
const message =
|
||||
parsed?.error ??
|
||||
parsed?.message ??
|
||||
(text ? text.slice(0, 300) : `Request failed (${res.status})`);
|
||||
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
// Expected response: { id: string; createdAt: string }
|
||||
return (await res.json()) as { id: string; createdAt: string };
|
||||
}
|
||||
Reference in New Issue
Block a user