feat: initial implementation of modern modular webshop (shop core)
This commit is contained in:
37
shop/lib/actions/orders.ts
Normal file
37
shop/lib/actions/orders.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
'use server'
|
||||
|
||||
import { createClient } from '@/lib/supabase/server'
|
||||
import { revalidatePath } from 'next/cache'
|
||||
import { Order } from '../types'
|
||||
|
||||
export async function submitOrder(orderData: {
|
||||
product_id: string;
|
||||
selected_modules: string[];
|
||||
total_amount: number;
|
||||
customer_details: any;
|
||||
}) {
|
||||
const supabase = await createClient()
|
||||
|
||||
const { data: { user } } = await supabase.auth.getUser()
|
||||
if (!user) throw new Error('Not authenticated')
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('orders')
|
||||
.insert([{
|
||||
user_id: user.id,
|
||||
total_amount: orderData.total_amount,
|
||||
items: {
|
||||
product_id: orderData.product_id,
|
||||
modules: orderData.selected_modules
|
||||
},
|
||||
billing_details: orderData.customer_details,
|
||||
status: 'pending'
|
||||
}])
|
||||
.select()
|
||||
.single()
|
||||
|
||||
if (error) throw error
|
||||
|
||||
revalidatePath('/admin/orders') // If there was an admin orders page
|
||||
return data
|
||||
}
|
||||
84
shop/lib/actions/products.ts
Normal file
84
shop/lib/actions/products.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
'use server'
|
||||
|
||||
import { createClient } from '@/lib/supabase/server'
|
||||
import { revalidatePath } from 'next/cache'
|
||||
import { Product, ProductModule } from '../types'
|
||||
|
||||
export async function getProducts() {
|
||||
const supabase = await createClient()
|
||||
const { data, error } = await supabase
|
||||
.from('products')
|
||||
.select('*, modules:product_modules(*)')
|
||||
.order('created_at', { ascending: false })
|
||||
|
||||
if (error) throw error
|
||||
return data as Product[]
|
||||
}
|
||||
|
||||
export async function createProduct(product: Omit<Product, 'id' | 'created_at' | 'updated_at'>, modules: Omit<ProductModule, 'id' | 'product_id' | 'created_at'>[]) {
|
||||
const supabase = await createClient()
|
||||
|
||||
// Start a transaction-like approach (Supabase doesn't have cross-table transactions easily in one call via JS client without RPC)
|
||||
const { data: newProduct, error: productError } = await supabase
|
||||
.from('products')
|
||||
.insert([product])
|
||||
.select()
|
||||
.single()
|
||||
|
||||
if (productError) throw productError
|
||||
|
||||
if (modules.length > 0) {
|
||||
const modulesWithId = modules.map(m => ({ ...m, product_id: newProduct.id }))
|
||||
const { error: modulesError } = await supabase
|
||||
.from('product_modules')
|
||||
.insert(modulesWithId)
|
||||
|
||||
if (modulesError) throw modulesError
|
||||
}
|
||||
|
||||
revalidatePath('/admin/products')
|
||||
revalidatePath('/order')
|
||||
return newProduct
|
||||
}
|
||||
|
||||
export async function updateProduct(id: string, product: Partial<Product>, modules: any[]) {
|
||||
const supabase = await createClient()
|
||||
|
||||
const { error: productError } = await supabase
|
||||
.from('products')
|
||||
.update(product)
|
||||
.eq('id', id)
|
||||
|
||||
if (productError) throw productError
|
||||
|
||||
// For modules, a simple approach is to delete and re-insert or use upsert if they have IDs
|
||||
// To keep it simple: Delete all modules and re-insert the current list
|
||||
await supabase.from('product_modules').delete().eq('product_id', id)
|
||||
|
||||
if (modules.length > 0) {
|
||||
const modulesWithId = modules.map(m => ({
|
||||
name: m.name,
|
||||
description: m.description,
|
||||
additional_price: m.additional_price,
|
||||
is_required: m.is_required,
|
||||
product_id: id
|
||||
}))
|
||||
const { error: modulesError } = await supabase
|
||||
.from('product_modules')
|
||||
.insert(modulesWithId)
|
||||
|
||||
if (modulesError) throw modulesError
|
||||
}
|
||||
|
||||
revalidatePath('/admin/products')
|
||||
revalidatePath('/order')
|
||||
}
|
||||
|
||||
export async function deleteProduct(id: string) {
|
||||
const supabase = await createClient()
|
||||
const { error } = await supabase.from('products').delete().eq('id', id)
|
||||
if (error) throw error
|
||||
|
||||
revalidatePath('/admin/products')
|
||||
revalidatePath('/order')
|
||||
}
|
||||
Reference in New Issue
Block a user