100 lines
3.3 KiB
TypeScript
100 lines
3.3 KiB
TypeScript
"use server"
|
|
|
|
import { createClient } from "@/lib/supabase-server"
|
|
import { revalidatePath } from "next/cache"
|
|
|
|
interface ProductData {
|
|
name: string
|
|
category: string
|
|
description?: string
|
|
price: number
|
|
image_url?: string
|
|
is_active?: boolean
|
|
images?: string[]
|
|
product_code?: string
|
|
}
|
|
|
|
export async function createProduct(data: ProductData) {
|
|
const supabase = createClient()
|
|
|
|
try {
|
|
// 1. Create Product
|
|
const { data: product, error } = await supabase.from("products").insert({
|
|
name: data.name,
|
|
category: data.category,
|
|
description: data.description,
|
|
price: data.price,
|
|
image_url: data.image_url, // Main image (can be first of images)
|
|
is_active: data.is_active ?? true,
|
|
product_code: data.product_code
|
|
}).select().single()
|
|
|
|
if (error) throw error
|
|
|
|
// 2. Insert Images (if any)
|
|
if (data.images && data.images.length > 0) {
|
|
const imageInserts = data.images.map((url, index) => ({
|
|
product_id: product.id,
|
|
image_url: url,
|
|
display_order: index
|
|
}))
|
|
|
|
const { error: imgError } = await supabase.from("product_images").insert(imageInserts)
|
|
if (imgError) {
|
|
console.error("Error inserting images:", imgError)
|
|
// We don't throw here to avoid failing the whole product creation if just images fail
|
|
}
|
|
}
|
|
|
|
revalidatePath("/dashboard/products")
|
|
return { success: true }
|
|
} catch (error) {
|
|
return { success: false, error: (error as Error).message }
|
|
}
|
|
}
|
|
|
|
export async function updateProduct(id: number, data: ProductData) {
|
|
const supabase = createClient()
|
|
|
|
try {
|
|
// 1. Update Product
|
|
const { error } = await supabase.from("products").update({
|
|
name: data.name,
|
|
category: data.category,
|
|
description: data.description,
|
|
price: data.price,
|
|
image_url: data.image_url,
|
|
is_active: data.is_active,
|
|
product_code: data.product_code
|
|
}).eq("id", id)
|
|
|
|
if (error) throw error
|
|
|
|
// 2. Update Images
|
|
// Strategy: Delete all and re-insert is simplest for now.
|
|
// Or better: Differential update. For simplicity in MVP: Delete all for this product and re-insert *if* new images provided.
|
|
// Actually, if we want to keep existing ones, we need more complex logic.
|
|
// For now, let's assume the form sends the FULL list of current images.
|
|
if (data.images) {
|
|
// Delete old
|
|
await supabase.from("product_images").delete().eq("product_id", id)
|
|
|
|
// Insert new
|
|
if (data.images.length > 0) {
|
|
const imageInserts = data.images.map((url, index) => ({
|
|
product_id: id,
|
|
image_url: url,
|
|
display_order: index
|
|
}))
|
|
await supabase.from("product_images").insert(imageInserts)
|
|
}
|
|
}
|
|
|
|
revalidatePath("/dashboard/products")
|
|
revalidatePath(`/dashboard/products/${id}`)
|
|
return { success: true }
|
|
} catch (error) {
|
|
return { success: false, error: (error as Error).message }
|
|
}
|
|
}
|