178 lines
5.0 KiB
TypeScript
178 lines
5.0 KiB
TypeScript
'use server';
|
|
|
|
import { revalidatePath } from 'next/cache';
|
|
import { API_BASE } from '../../lib/api';
|
|
|
|
export async function createProduct(formData: FormData) {
|
|
const name = String(formData.get('name') || '').trim();
|
|
|
|
const res = await fetch(`${API_BASE}/api/products`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({ name }),
|
|
cache: 'no-store',
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
throw new Error(`Kunde inte skapa produkt: ${text}`);
|
|
}
|
|
|
|
revalidatePath('/inventory');
|
|
}
|
|
|
|
export async function createInventoryItem(formData: FormData) {
|
|
const productId = Number(formData.get('productId'));
|
|
const quantity = Number(formData.get('quantity'));
|
|
const unit = String(formData.get('unit') || '').trim();
|
|
const location = String(formData.get('location') || '').trim();
|
|
const opened = formData.get('opened') === 'on';
|
|
const suitableFor = String(formData.get('suitableFor') || '').trim();
|
|
const bestBeforeDateRaw = String(formData.get('bestBeforeDate') || '').trim();
|
|
const brand = String(formData.get('brand') || '').trim();
|
|
|
|
const payload: Record<string, unknown> = {
|
|
productId,
|
|
quantity,
|
|
unit,
|
|
};
|
|
|
|
if (location) payload.location = location;
|
|
payload.opened = opened;
|
|
if (brand) payload.brand = brand;
|
|
if (suitableFor) payload.suitableFor = suitableFor;
|
|
if (bestBeforeDateRaw) payload.bestBeforeDate = bestBeforeDateRaw;
|
|
|
|
const res = await fetch(`${API_BASE}/api/inventory`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(payload),
|
|
cache: 'no-store',
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
throw new Error(`Kunde inte skapa inventory-rad: ${text}`);
|
|
}
|
|
|
|
revalidatePath('/inventory');
|
|
}
|
|
|
|
export async function updateInventoryItem(formData: FormData) {
|
|
const id = Number(formData.get('id'));
|
|
const quantityRaw = String(formData.get('quantity') || '').trim();
|
|
const unit = String(formData.get('unit') || '').trim();
|
|
const location = String(formData.get('location') || '').trim();
|
|
const brand = String(formData.get('brand') || '').trim();
|
|
const suitableFor = String(formData.get('suitableFor') || '').trim();
|
|
const comment = String(formData.get('comment') || '').trim();
|
|
const bestBeforeDateRaw = String(formData.get('bestBeforeDate') || '').trim();
|
|
const opened = formData.get('opened') === 'on';
|
|
|
|
const payload: Record<string, unknown> = {
|
|
opened,
|
|
};
|
|
|
|
if (quantityRaw) payload.quantity = Number(quantityRaw);
|
|
if (unit) payload.unit = unit;
|
|
payload.location = location;
|
|
payload.brand = brand;
|
|
payload.suitableFor = suitableFor;
|
|
payload.comment = comment;
|
|
payload.bestBeforeDate = bestBeforeDateRaw || null;
|
|
|
|
const res = await fetch(`${API_BASE}/api/inventory/${id}`, {
|
|
method: 'PATCH',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(payload),
|
|
cache: 'no-store',
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
throw new Error(`Kunde inte uppdatera inventory-rad: ${text}`);
|
|
}
|
|
|
|
revalidatePath('/inventory');
|
|
}
|
|
|
|
export async function updateCanonicalName(formData: FormData) {
|
|
const id = Number(formData.get('id'));
|
|
const canonicalName = String(formData.get('canonicalName') || '').trim();
|
|
|
|
const res = await fetch(`${API_BASE}/api/products/${id}/canonical-name`, {
|
|
method: 'PATCH',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({ canonicalName }),
|
|
cache: 'no-store',
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
throw new Error(`Kunde inte uppdatera canonicalName: ${text}`);
|
|
}
|
|
|
|
revalidatePath('/admin/products');
|
|
}
|
|
|
|
export async function mergeProducts(formData: FormData) {
|
|
const sourceProductId = Number(formData.get('sourceProductId'));
|
|
const targetProductId = Number(formData.get('targetProductId'));
|
|
|
|
const res = await fetch(`${API_BASE}/api/products/merge`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
sourceProductId,
|
|
targetProductId,
|
|
}),
|
|
cache: 'no-store',
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
throw new Error(`Kunde inte slå ihop produkter: ${text}`);
|
|
}
|
|
|
|
revalidatePath('/admin/products');
|
|
}
|
|
|
|
export async function consumeInventoryItem(formData: FormData) {
|
|
const id = Number(formData.get('id'));
|
|
const amountUsed = Number(formData.get('amountUsed'));
|
|
const comment = String(formData.get('comment') || '').trim();
|
|
|
|
const payload: Record<string, unknown> = {
|
|
amountUsed,
|
|
};
|
|
|
|
if (comment) {
|
|
payload.comment = comment;
|
|
}
|
|
|
|
const res = await fetch(`${API_BASE}/api/inventory/${id}/consume`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(payload),
|
|
cache: 'no-store',
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
throw new Error(`Kunde inte förbruka inventory-rad: ${text}`);
|
|
}
|
|
|
|
revalidatePath('/inventory');
|
|
} |