feat(03-02): add createClient, updateClient, deleteClient server actions
- 'use server' file with Zod validation (name min 1 char, valid email) - createClient: validate, insert, revalidatePath /portal/clients - updateClient: bind pattern (id, prevState, formData), revalidates client list + profile - deleteClient: auth check, delete by id, revalidatePath /portal/clients - Fixed Zod v4 .issues access (not .errors — v4 API change)
This commit is contained in:
83
teressa-copeland-homes/src/lib/actions/clients.ts
Normal file
83
teressa-copeland-homes/src/lib/actions/clients.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
"use server";
|
||||
|
||||
import { z } from "zod";
|
||||
import { db } from "@/lib/db";
|
||||
import { clients } from "@/lib/db/schema";
|
||||
import { auth } from "@/lib/auth";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
const clientSchema = z.object({
|
||||
name: z.string().min(1, "Name is required"),
|
||||
email: z.string().email("Valid email address required"),
|
||||
});
|
||||
|
||||
export async function createClient(
|
||||
_prevState: { error?: string; success?: boolean } | null,
|
||||
formData: FormData
|
||||
): Promise<{ error?: string; success?: boolean }> {
|
||||
const session = await auth();
|
||||
if (!session) {
|
||||
return { error: "Unauthorized" };
|
||||
}
|
||||
|
||||
const parsed = clientSchema.safeParse({
|
||||
name: formData.get("name"),
|
||||
email: formData.get("email"),
|
||||
});
|
||||
|
||||
if (!parsed.success) {
|
||||
return { error: parsed.error.issues[0].message };
|
||||
}
|
||||
|
||||
await db.insert(clients).values({
|
||||
name: parsed.data.name,
|
||||
email: parsed.data.email,
|
||||
});
|
||||
|
||||
revalidatePath("/portal/clients");
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
export async function updateClient(
|
||||
id: string,
|
||||
_prevState: { error?: string; success?: boolean } | null,
|
||||
formData: FormData
|
||||
): Promise<{ error?: string; success?: boolean }> {
|
||||
const session = await auth();
|
||||
if (!session) {
|
||||
return { error: "Unauthorized" };
|
||||
}
|
||||
|
||||
const parsed = clientSchema.safeParse({
|
||||
name: formData.get("name"),
|
||||
email: formData.get("email"),
|
||||
});
|
||||
|
||||
if (!parsed.success) {
|
||||
return { error: parsed.error.issues[0].message };
|
||||
}
|
||||
|
||||
await db
|
||||
.update(clients)
|
||||
.set({ name: parsed.data.name, email: parsed.data.email, updatedAt: new Date() })
|
||||
.where(eq(clients.id, id));
|
||||
|
||||
revalidatePath("/portal/clients");
|
||||
revalidatePath("/portal/clients/" + id);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
export async function deleteClient(
|
||||
id: string
|
||||
): Promise<{ error?: string; success?: boolean }> {
|
||||
const session = await auth();
|
||||
if (!session) {
|
||||
return { error: "Unauthorized" };
|
||||
}
|
||||
|
||||
await db.delete(clients).where(eq(clients.id, id));
|
||||
|
||||
revalidatePath("/portal/clients");
|
||||
return { success: true };
|
||||
}
|
||||
Reference in New Issue
Block a user