203 lines
4.6 KiB
Vue
203 lines
4.6 KiB
Vue
<template>
|
|
<UModal v-model="isOpen">
|
|
<UCard>
|
|
<template #header>
|
|
<div class="flex items-center justify-between">
|
|
<h3 class="text-lg font-semibold">Edit Item</h3>
|
|
<UButton
|
|
icon="i-heroicons-x-mark"
|
|
color="gray"
|
|
variant="ghost"
|
|
@click="close"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<form @submit.prevent="handleSubmit" class="space-y-4">
|
|
<!-- Item Name -->
|
|
<UFormGroup label="Item Name" required>
|
|
<UInput
|
|
v-model="form.name"
|
|
placeholder="Item name"
|
|
size="lg"
|
|
/>
|
|
</UFormGroup>
|
|
|
|
<!-- Quantity & Unit -->
|
|
<div class="grid grid-cols-2 gap-3">
|
|
<UFormGroup label="Quantity" required>
|
|
<UInput
|
|
v-model.number="form.quantity"
|
|
type="number"
|
|
min="0.01"
|
|
step="0.01"
|
|
size="lg"
|
|
/>
|
|
</UFormGroup>
|
|
|
|
<UFormGroup label="Unit" required>
|
|
<USelect
|
|
v-model="form.unit_id"
|
|
:options="unitOptions"
|
|
option-attribute="label"
|
|
value-attribute="value"
|
|
size="lg"
|
|
/>
|
|
</UFormGroup>
|
|
</div>
|
|
|
|
<!-- Expiry Date -->
|
|
<UFormGroup label="Expiry Date" hint="Optional">
|
|
<UInput
|
|
v-model="form.expiry_date"
|
|
type="date"
|
|
size="lg"
|
|
/>
|
|
</UFormGroup>
|
|
|
|
<!-- Low Stock Threshold -->
|
|
<UFormGroup
|
|
label="Low Stock Alert"
|
|
hint="Optional - Alert when quantity falls below this"
|
|
>
|
|
<UInput
|
|
v-model.number="form.low_stock_threshold"
|
|
type="number"
|
|
min="0"
|
|
step="0.1"
|
|
placeholder="e.g. 2"
|
|
size="lg"
|
|
/>
|
|
</UFormGroup>
|
|
|
|
<!-- Notes -->
|
|
<UFormGroup label="Notes" hint="Optional">
|
|
<UTextarea
|
|
v-model="form.notes"
|
|
placeholder="Any additional notes..."
|
|
:rows="2"
|
|
/>
|
|
</UFormGroup>
|
|
|
|
<!-- Submit -->
|
|
<div class="flex gap-2 pt-2">
|
|
<UButton
|
|
type="submit"
|
|
color="primary"
|
|
size="lg"
|
|
class="flex-1"
|
|
:loading="submitting"
|
|
:disabled="!isValid"
|
|
>
|
|
Save Changes
|
|
</UButton>
|
|
<UButton
|
|
color="gray"
|
|
size="lg"
|
|
variant="soft"
|
|
@click="close"
|
|
>
|
|
Cancel
|
|
</UButton>
|
|
</div>
|
|
</form>
|
|
</UCard>
|
|
</UModal>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
const { updateInventoryItem } = useInventory()
|
|
const { getUnits } = useUnits()
|
|
|
|
const props = defineProps<{
|
|
item: any | null
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
close: []
|
|
updated: [item: any]
|
|
}>()
|
|
|
|
const isOpen = ref(false)
|
|
const submitting = ref(false)
|
|
const units = ref<any[]>([])
|
|
|
|
const form = reactive({
|
|
name: '',
|
|
quantity: 1,
|
|
unit_id: '',
|
|
expiry_date: '',
|
|
low_stock_threshold: null as number | null,
|
|
notes: ''
|
|
})
|
|
|
|
// Load units
|
|
onMounted(async () => {
|
|
const { data } = await getUnits()
|
|
units.value = data || []
|
|
})
|
|
|
|
// Unit options for select
|
|
const unitOptions = computed(() => {
|
|
return units.value.map(unit => ({
|
|
label: `${unit.name} (${unit.abbreviation})`,
|
|
value: unit.id
|
|
}))
|
|
})
|
|
|
|
// Watch for item changes (open modal)
|
|
watch(() => props.item, (newItem) => {
|
|
if (newItem) {
|
|
form.name = newItem.name
|
|
form.quantity = Number(newItem.quantity)
|
|
form.unit_id = newItem.unit_id
|
|
form.expiry_date = newItem.expiry_date || ''
|
|
form.low_stock_threshold = newItem.low_stock_threshold || null
|
|
form.notes = newItem.notes || ''
|
|
isOpen.value = true
|
|
}
|
|
}, { immediate: true })
|
|
|
|
// Watch modal close
|
|
watch(isOpen, (val) => {
|
|
if (!val) {
|
|
emit('close')
|
|
}
|
|
})
|
|
|
|
// Validation
|
|
const isValid = computed(() => {
|
|
return form.name.trim().length > 0 && form.quantity > 0 && form.unit_id
|
|
})
|
|
|
|
const close = () => {
|
|
isOpen.value = false
|
|
}
|
|
|
|
// Submit
|
|
const handleSubmit = async () => {
|
|
if (!isValid.value || !props.item) return
|
|
|
|
submitting.value = true
|
|
|
|
const { data, error } = await updateInventoryItem(props.item.id, {
|
|
name: form.name.trim(),
|
|
quantity: form.quantity,
|
|
unit_id: form.unit_id,
|
|
expiry_date: form.expiry_date || null,
|
|
low_stock_threshold: form.low_stock_threshold,
|
|
notes: form.notes.trim() || null
|
|
})
|
|
|
|
if (error) {
|
|
alert('Failed to update item: ' + error.message)
|
|
submitting.value = false
|
|
return
|
|
}
|
|
|
|
emit('updated', data)
|
|
submitting.value = false
|
|
close()
|
|
}
|
|
</script>
|