feat: add confirmation dialogs for deleting variants in ProductForm and RawMaterialForm components to enhance user experience and prevent accidental deletions
This commit is contained in:
parent
897d9c62b7
commit
4753949338
@ -3,6 +3,7 @@ import { useForm } from '@inertiajs/vue3';
|
||||
import { Plus, Save } from '@lucide/vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import { toast } from 'vue-sonner';
|
||||
import ConfirmDialog from '@/components/ConfirmDialog.vue';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { useCan } from '@/composables/useCan';
|
||||
@ -12,6 +13,7 @@ import type { CategoryOption, ProductFormInitialData, ProductVariantFormItem } f
|
||||
import ProductInfoSection from './ProductInfoSection.vue';
|
||||
import ProductVariantSection from './ProductVariantSection.vue';
|
||||
|
||||
|
||||
const { hasRole } = useCan();
|
||||
const showPrices = !hasRole('admin-bahan-baku');
|
||||
|
||||
@ -33,7 +35,7 @@ function createClientId(): string {
|
||||
return `variant-${crypto.randomUUID()}`;
|
||||
}
|
||||
|
||||
const isUploading = computed(() =>
|
||||
const isUploading = computed(() =>
|
||||
variants.value.some((v) => v.media.pendingUploads > 0)
|
||||
);
|
||||
|
||||
@ -122,8 +124,8 @@ function copyPrices(variantPrices: Record<string, string>) {
|
||||
|
||||
function pastePrices(clientId: string) {
|
||||
if (!copiedPrices.value) {
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
setVariantField(clientId, 'prices', { ...copiedPrices.value });
|
||||
}
|
||||
@ -134,6 +136,23 @@ function applyToAllPrices(variantPrices: Record<string, string>) {
|
||||
});
|
||||
}
|
||||
|
||||
const showDeleteConfirm = ref(false);
|
||||
const variantToDelete = ref<string | null>(null);
|
||||
|
||||
function confirmRemoveVariant(clientId: string) {
|
||||
variantToDelete.value = clientId;
|
||||
showDeleteConfirm.value = true;
|
||||
}
|
||||
|
||||
function handleRemoveVariant() {
|
||||
if (variantToDelete.value) {
|
||||
removeVariant(variantToDelete.value);
|
||||
variantToDelete.value = null;
|
||||
}
|
||||
|
||||
showDeleteConfirm.value = false;
|
||||
}
|
||||
|
||||
const form = useForm({
|
||||
name: props.initialData?.name ?? '',
|
||||
description: props.initialData?.description ?? '',
|
||||
@ -205,27 +224,16 @@ function submit() {
|
||||
<CardTitle>Informasi Produk</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ProductInfoSection
|
||||
:form="form"
|
||||
:categories="categories"
|
||||
:category-error="categoryError"
|
||||
@update:name="form.name = $event"
|
||||
@update:description="form.description = $event"
|
||||
@toggle-category="toggleCategory"
|
||||
/>
|
||||
<ProductInfoSection :form="form" :categories="categories" :category-error="categoryError"
|
||||
@update:name="form.name = $event" @update:description="form.description = $event"
|
||||
@toggle-category="toggleCategory" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<ProductVariantSection
|
||||
v-for="(variant, index) in variants"
|
||||
:key="variant.client_id"
|
||||
:form="form"
|
||||
:variant="variant"
|
||||
:index="index"
|
||||
:can-remove="variants.length > 1"
|
||||
:has-copied-prices="!!copiedPrices"
|
||||
<ProductVariantSection v-for="(variant, index) in variants" :key="variant.client_id" :form="form"
|
||||
:variant="variant" :index="index" :can-remove="variants.length > 1" :has-copied-prices="!!copiedPrices"
|
||||
:variant-errors="(clientId, field) => variantErrors(form, clientId, field)"
|
||||
@remove="removeVariant(variant.client_id)"
|
||||
@remove="confirmRemoveVariant(variant.client_id)"
|
||||
@update:name="setVariantField(variant.client_id, 'name', $event)"
|
||||
@update:stock="setVariantField(variant.client_id, 'stock', $event)"
|
||||
@update:retail-stock="setVariantField(variant.client_id, 'retail_stock', $event)"
|
||||
@ -233,8 +241,7 @@ function submit() {
|
||||
@update:media="setVariantField(variant.client_id, 'media', $event)"
|
||||
@copy-prices="copyPrices(variant.prices as Record<string, string>)"
|
||||
@paste-prices="pastePrices(variant.client_id)"
|
||||
@apply-to-all-prices="applyToAllPrices(variant.prices as Record<string, string>)"
|
||||
/>
|
||||
@apply-to-all-prices="applyToAllPrices(variant.prices as Record<string, string>)" />
|
||||
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<Button type="button" variant="outline" @click="addVariant">
|
||||
@ -249,4 +256,8 @@ function submit() {
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<ConfirmDialog v-model:open="showDeleteConfirm" title="Hapus Varian?"
|
||||
description="Apakah Anda yakin ingin menghapus varian ini? Tindakan ini tidak dapat dibatalkan."
|
||||
confirm-label="Hapus" cancel-label="Batal" destructive @confirm="handleRemoveVariant" />
|
||||
</template>
|
||||
|
||||
@ -3,6 +3,7 @@ import { useForm } from '@inertiajs/vue3';
|
||||
import { Plus, Save } from '@lucide/vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import { toast } from 'vue-sonner';
|
||||
import ConfirmDialog from '@/components/ConfirmDialog.vue';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { FieldError } from '@/components/ui/field';
|
||||
import { useVariantList } from '@/composables/useVariantList';
|
||||
@ -89,6 +90,22 @@ const {
|
||||
|
||||
const useSamePrice = ref(prices.value.length <= 1 || allPricesHaveSameValue());
|
||||
|
||||
const showDeleteConfirm = ref(false);
|
||||
const priceToDelete = ref<string | null>(null);
|
||||
|
||||
function confirmRemovePrice(clientId: string) {
|
||||
priceToDelete.value = clientId;
|
||||
showDeleteConfirm.value = true;
|
||||
}
|
||||
|
||||
function handleRemovePrice() {
|
||||
if (priceToDelete.value) {
|
||||
removePrice(priceToDelete.value);
|
||||
priceToDelete.value = null;
|
||||
}
|
||||
showDeleteConfirm.value = false;
|
||||
}
|
||||
|
||||
const form = useForm({
|
||||
name: props.initialData?.name ?? '',
|
||||
unit: props.initialData?.unit ?? '',
|
||||
@ -196,7 +213,7 @@ function submit() {
|
||||
<RawMaterialVariantSection v-for="(price, index) in prices" :key="price.client_id" :form="form"
|
||||
:price="price" :index="index" :total-prices="prices.length" :use-same-price="useSamePrice"
|
||||
:price-errors="(clientId, field) => priceErrors(form, clientId, field)"
|
||||
@remove="removePrice(price.client_id)" @apply-price-to-all="applyPriceToAllVariants(price.client_id)"
|
||||
@remove="confirmRemovePrice(price.client_id)" @apply-price-to-all="applyPriceToAllVariants(price.client_id)"
|
||||
@update:variant="setPriceField(price.client_id, 'variant', $event)"
|
||||
@update:stock="setPriceField(price.client_id, 'stock', $event)"
|
||||
@update:price="setPriceValue(price.client_id, $event)" />
|
||||
@ -216,4 +233,14 @@ function submit() {
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<ConfirmDialog
|
||||
v-model:open="showDeleteConfirm"
|
||||
title="Hapus Varian?"
|
||||
description="Apakah Anda yakin ingin menghapus varian ini? Tindakan ini tidak dapat dibatalkan."
|
||||
confirm-label="Hapus"
|
||||
cancel-label="Batal"
|
||||
destructive
|
||||
@confirm="handleRemovePrice"
|
||||
/>
|
||||
</template>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user