From 9e0188c9ef1d40095a8391f1730687cbe66e3ff8 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Wed, 8 Jul 2026 00:21:54 +0700 Subject: [PATCH] feat: add functionality for setting cart item quantity and improve cart detail dialog with empty state handling --- .../orders/form/OrderPosCartDetailDialog.vue | 73 +++++++++++++++++-- .../admin/manage/orders/form/OrderPosForm.vue | 18 ++++- .../manage/orders/form/useOrderPosCart.ts | 26 +++++++ 3 files changed, 111 insertions(+), 6 deletions(-) diff --git a/resources/js/pages/admin/manage/orders/form/OrderPosCartDetailDialog.vue b/resources/js/pages/admin/manage/orders/form/OrderPosCartDetailDialog.vue index 56e9c82..018b249 100644 --- a/resources/js/pages/admin/manage/orders/form/OrderPosCartDetailDialog.vue +++ b/resources/js/pages/admin/manage/orders/form/OrderPosCartDetailDialog.vue @@ -5,6 +5,12 @@ import { DialogHeader, DialogTitle, } from '@/components/ui/dialog'; +import { + Empty, + EmptyDescription, + EmptyHeader, + EmptyTitle, +} from '@/components/ui/empty'; import { formatRupiah } from '@/lib/rupiah'; import type { OrderCartItem } from '@/types/order'; @@ -15,18 +21,40 @@ defineProps<{ totalAmount: number; }>(); +const emit = defineEmits<{ + remove: [index: number]; + 'adjust-quantity': [index: number, delta: number]; + 'set-quantity': [index: number, value: string]; +}>(); + const open = defineModel('open', { required: true }); + +function onQtyInput(index: number, event: Event) { + emit('set-quantity', index, (event.target as HTMLInputElement).value); +} diff --git a/resources/js/pages/admin/manage/orders/form/useOrderPosCart.ts b/resources/js/pages/admin/manage/orders/form/useOrderPosCart.ts index fdca245..2804ee6 100644 --- a/resources/js/pages/admin/manage/orders/form/useOrderPosCart.ts +++ b/resources/js/pages/admin/manage/orders/form/useOrderPosCart.ts @@ -287,6 +287,31 @@ export function useOrderPosCart(options: { } } + async function setCartItemQuantity(index: number, value: string) { + const item = cart.value[index]; + const nextQty = Number.parseFloat(value.replace(',', '.')); + + if (Number.isNaN(nextQty) || nextQty < 0) { + return; + } + + if (nextQty < 1) { + await removeFromCart(index); + + return; + } + + item.quantity = String(nextQty); + + if (toValue(options.isCreateMode)) { + try { + await syncDraftItem(item.product_variant_id, nextQty, item.stock_quality); + } catch (error) { + toast.error(error instanceof Error ? error.message : 'Gagal memperbarui jumlah item.'); + } + } + } + return { search, selectedStockQuality, @@ -303,6 +328,7 @@ export function useOrderPosCart(options: { removeFromCart, adjustQuantity, syncCartItemQuantity, + setCartItemQuantity, decreaseVariantQty, }; }