"use server"; import { redirect } from "next/navigation"; import { createClient } from "@/lib/supabase/server"; import { verifySession } from "@/lib/dal"; import { NeedFormSchema, type NeedFormState } from "@/lib/validations/needs"; const MAX_IMAGES = 5; const MAX_IMAGE_SIZE = 5 * 1024 * 1024; // 5 Mo export async function createNeed( _state: NeedFormState, formData: FormData ): Promise { const user = await verifySession(); const validatedFields = NeedFormSchema.safeParse({ title: formData.get("title"), description: formData.get("description"), categoryId: formData.get("categoryId"), city: formData.get("city"), region: formData.get("region") || undefined, budgetMin: formData.get("budgetMin") || undefined, budgetMax: formData.get("budgetMax") || undefined, }); if (!validatedFields.success) { return { errors: validatedFields.error.flatten().fieldErrors }; } const { title, description, categoryId, city, region, budgetMin, budgetMax } = validatedFields.data; const parsedBudgetMin = budgetMin ? Number(budgetMin) : null; const parsedBudgetMax = budgetMax ? Number(budgetMax) : null; if ( (budgetMin && Number.isNaN(parsedBudgetMin)) || (budgetMax && Number.isNaN(parsedBudgetMax)) ) { return { message: "Budget invalide." }; } if ( parsedBudgetMin !== null && parsedBudgetMax !== null && parsedBudgetMin > parsedBudgetMax ) { return { message: "Le budget minimum doit être inférieur au maximum." }; } const images = formData .getAll("images") .filter((entry): entry is File => entry instanceof File && entry.size > 0); if (images.length > MAX_IMAGES) { return { message: `${MAX_IMAGES} images maximum.` }; } if (images.some((file) => file.size > MAX_IMAGE_SIZE)) { return { message: "Chaque image doit faire moins de 5 Mo." }; } const supabase = await createClient(); const { data: need, error } = await supabase .from("needs") .insert({ author_id: user.id, category_id: categoryId, title, description, city, region: region || null, budget_min: parsedBudgetMin, budget_max: parsedBudgetMax, }) .select("id") .single(); if (error || !need) { return { message: "Une erreur est survenue lors de la création du besoin." }; } for (const [index, file] of images.entries()) { const path = `${user.id}/${need.id}/${index}-${file.name}`; const { error: uploadError } = await supabase.storage .from("need-images") .upload(path, file); if (!uploadError) { await supabase .from("need_images") .insert({ need_id: need.id, storage_path: path, position: index }); } } redirect(`/needs/${need.id}`); }