fix: edit table and migrations

This commit is contained in:
2026-04-17 13:56:26 +02:00
59 changed files with 8918 additions and 88 deletions

View File

@@ -0,0 +1,120 @@
<template>
<div class="card-section space-y-4">
<div v-if="store.loading" class="flex justify-center py-10">
<UIcon name="svg-spinners:ring-resize" class="text-3xl text-primary" />
</div>
<div v-else-if="store.variants.length === 0" class="flex flex-col items-center gap-3 py-10 text-gray-400">
<UIcon name="i-lucide-layers" class="text-4xl" />
<p class="text-sm text-center">
{{ isEditMode ? 'No variants found for this product.' : 'Save the product first, then variants will appear here.' }}
</p>
</div>
<template v-else>
<p class="text-sm text-gray-400">
Each variant is a combination of attributes (e.g. Color: Red / Size: M).
Edit price offset, stock and other details per variant independently.
</p>
<div v-for="variant in store.variants" :key="variant.id_product_attribute"
class="border border-(--border-light) dark:border-(--border-dark) rounded-xl p-4 space-y-4">
<!-- Variant header -->
<div class="flex items-center justify-between flex-wrap gap-2">
<div class="flex items-center gap-2">
<span class="font-semibold text-black dark:text-white text-sm">
{{ variant.attribute_label || `Variant #${variant.id_product_attribute}` }}
</span>
<UBadge v-if="variant.default_on" color="success" variant="subtle" size="sm">
Default
</UBadge>
</div>
<UButton size="sm" color="info"
:loading="!!store.variantSaving[variant.id_product_attribute!]"
@click="handleSaveVariant(variant)">
Save variant
</UButton>
</div>
<UAlert v-if="store.variantErrors[variant.id_product_attribute!]" color="error"
variant="subtle" :title="store.variantErrors[variant.id_product_attribute!]" />
<!-- Variant fields -->
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
<UFormField label="Reference">
<UInput v-model="variant.reference" placeholder="REF-001-A" class="w-full" />
</UFormField>
<UFormField label="EAN-13">
<UInput v-model="variant.ean13" placeholder="4006381333931" :maxlength="13"
class="w-full" />
</UFormField>
<UFormField label="Price offset">
<UInputNumber v-model="variant.price" :step="0.01"
:format-options="{ minimumFractionDigits: 2 }" class="w-full" />
</UFormField>
<UFormField label="Wholesale price">
<UInputNumber v-model="variant.wholesale_price" :min="0" :step="0.01"
:format-options="{ minimumFractionDigits: 2 }" class="w-full" />
</UFormField>
<UFormField label="Stock quantity">
<UInputNumber v-model="variant.quantity" :min="0" class="w-full" />
</UFormField>
<UFormField label="Min. quantity">
<UInputNumber v-model="variant.minimal_quantity" :min="1" class="w-full" />
</UFormField>
<UFormField label="Weight offset (kg)">
<UInputNumber v-model="variant.weight" :step="0.001" class="w-full" />
</UFormField>
<UFormField label="">
<div class="flex items-center gap-2 pt-6">
<USwitch v-model="variant.default_on" color="success"
@update:model-value="onSetDefault(variant)" />
<span class="text-sm text-black dark:text-white">Set as default</span>
</div>
</UFormField>
</div>
</div>
</template>
</div>
</template>
<script setup lang="ts">
import { useAddProductStore } from '@/stores/admin/addProduct'
import type { ProductVariantForm } from '@/types/product'
const props = defineProps<{ isEditMode: boolean }>()
const store = useAddProductStore()
async function handleSaveVariant(variant: ProductVariantForm) {
if (!variant.id_product_attribute) return
await store.saveVariant(variant.id_product_attribute, {
reference: variant.reference,
ean13: variant.ean13,
price: variant.price,
wholesale_price: variant.wholesale_price,
quantity: variant.quantity,
minimal_quantity: variant.minimal_quantity,
weight: variant.weight,
default_on: variant.default_on,
})
}
function onSetDefault(selected: ProductVariantForm) {
if (!selected.default_on) return
store.variants.forEach(v => {
if (v.id_product_attribute !== selected.id_product_attribute) v.default_on = false
})
}
</script>