f77051a3fc
- /admin page: Server Component fetching all clients with payment badges - ClientRow component with Acconto/Saldo status badges and secret link - /admin/clients/new: form wired to createClient Server Action - createClient action: Zod validation, inserts client + 2 payment stubs (Acconto 50%, Saldo 50%) - Token auto-generated server-side via nanoid $defaultFn - Redirects to /admin/clients/[id] after creation; revalidates /admin
59 lines
1.7 KiB
TypeScript
59 lines
1.7 KiB
TypeScript
"use server";
|
|
|
|
import { redirect } from "next/navigation";
|
|
import { revalidatePath } from "next/cache";
|
|
import { z } from "zod";
|
|
import { db } from "@/db";
|
|
import { clients, payments } from "@/db/schema";
|
|
|
|
const createClientSchema = z.object({
|
|
name: z.string().min(1, "Nome richiesto"),
|
|
brand_name: z.string().min(1, "Nome brand richiesto"),
|
|
brief: z.string().min(1, "Brief richiesto"),
|
|
});
|
|
|
|
export async function createClient(formData: FormData) {
|
|
const raw = {
|
|
name: formData.get("name") as string,
|
|
brand_name: formData.get("brand_name") as string,
|
|
brief: formData.get("brief") as string,
|
|
};
|
|
|
|
const parsed = createClientSchema.safeParse(raw);
|
|
if (!parsed.success) {
|
|
// In v1 return errors as thrown string — form displays validation inline
|
|
throw new Error(
|
|
parsed.error.issues.map((i) => i.message).join(", ")
|
|
);
|
|
}
|
|
|
|
// Insert client — token and id are auto-generated by $defaultFn(() => nanoid())
|
|
const [newClient] = await db
|
|
.insert(clients)
|
|
.values({
|
|
name: parsed.data.name,
|
|
brand_name: parsed.data.brand_name,
|
|
brief: parsed.data.brief,
|
|
})
|
|
.returning({ id: clients.id, token: clients.token });
|
|
|
|
// Always create two payment stubs per client — Acconto 50% and Saldo 50%
|
|
// Amounts default to 0 until admin sets accepted_total; admin updates separately
|
|
await db.insert(payments).values([
|
|
{
|
|
client_id: newClient.id,
|
|
label: "Acconto 50%",
|
|
amount: "0",
|
|
status: "da_saldare",
|
|
},
|
|
{
|
|
client_id: newClient.id,
|
|
label: "Saldo 50%",
|
|
amount: "0",
|
|
status: "da_saldare",
|
|
},
|
|
]);
|
|
|
|
revalidatePath("/admin");
|
|
redirect(`/admin/clients/${newClient.id}`);
|
|
} |