From 64a678890ec53cc72c17b83ececc42e26028090f Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Fri, 3 Jul 2026 14:28:43 +0700 Subject: [PATCH] feat: enhance form validation in Cutting module by adding error handling and displaying field-specific error messages in CuttingPosForm and related components --- .../manage/cuttings/form/CuttingPosForm.vue | 75 +++++++------------ .../form/CuttingPosMaterialSummaryItems.vue | 8 +- .../form/CuttingPosResultSummaryItems.vue | 18 ++++- .../cuttings/form/CuttingPosSummaryPanel.vue | 2 + 4 files changed, 51 insertions(+), 52 deletions(-) diff --git a/resources/js/pages/admin/manage/cuttings/form/CuttingPosForm.vue b/resources/js/pages/admin/manage/cuttings/form/CuttingPosForm.vue index 4f0a869..4e95952 100644 --- a/resources/js/pages/admin/manage/cuttings/form/CuttingPosForm.vue +++ b/resources/js/pages/admin/manage/cuttings/form/CuttingPosForm.vue @@ -9,14 +9,14 @@ import type { CuttingRawMaterialCatalogItem, CuttingResultCartItem, } from '@/types/cutting'; -import type { CategoryOption } from '@/types/product'; -import type { EnumOption } from '@/types/raw-material'; -import type { MediaItem } from '@/types/media'; import { appendRootPhotosToFormData, createMediaUploadState, } from '@/types/media'; +import type { MediaItem } from '@/types/media'; import type { MediaUploadState } from '@/types/media'; +import type { CategoryOption } from '@/types/product'; +import type { EnumOption } from '@/types/raw-material'; import CuttingPosCartDetailDialog from './CuttingPosCartDetailDialog.vue'; import CuttingPosMaterialCatalogPanel from './CuttingPosMaterialCatalogPanel.vue'; import CuttingPosResultCatalogPanel from './CuttingPosResultCatalogPanel.vue'; @@ -108,6 +108,7 @@ const { function populateForm() { if (!props.initialData) { imageState.value = createMediaUploadState(); + return; } @@ -191,6 +192,14 @@ function submit() { onError: (errors: Record) => { if (errors.system) { toast.error(errors.system); + } else { + const firstError = Object.values(errors)[0]; + + if (firstError) { + toast.error(firstError); + } else { + toast.error('Perbaiki kesalahan pada form.'); + } } }, }); @@ -224,53 +233,25 @@ function onProductCreated(product: CuttingProductCatalogItem) { diff --git a/resources/js/pages/admin/manage/cuttings/form/CuttingPosMaterialSummaryItems.vue b/resources/js/pages/admin/manage/cuttings/form/CuttingPosMaterialSummaryItems.vue index 41f5845..2257533 100644 --- a/resources/js/pages/admin/manage/cuttings/form/CuttingPosMaterialSummaryItems.vue +++ b/resources/js/pages/admin/manage/cuttings/form/CuttingPosMaterialSummaryItems.vue @@ -4,11 +4,15 @@ import { DecimalInput } from '@/components/form/decimal-input'; import { Button } from '@/components/ui/button'; import { Field, + FieldError, FieldLabel, } from '@/components/ui/field'; +import { formErrors } from '@/lib/form'; +import type { FormWithErrors } from '@/lib/form'; import type { CuttingMaterialCartItem } from '@/types/cutting'; defineProps<{ + form: FormWithErrors; materialCart: CuttingMaterialCartItem[]; }>(); @@ -55,15 +59,17 @@ const emit = defineEmits<{ - + Pemakaian ({{ item.unit_abbreviation }}) + diff --git a/resources/js/pages/admin/manage/cuttings/form/CuttingPosResultSummaryItems.vue b/resources/js/pages/admin/manage/cuttings/form/CuttingPosResultSummaryItems.vue index 59076e2..afff01f 100644 --- a/resources/js/pages/admin/manage/cuttings/form/CuttingPosResultSummaryItems.vue +++ b/resources/js/pages/admin/manage/cuttings/form/CuttingPosResultSummaryItems.vue @@ -5,11 +5,15 @@ import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Field, + FieldError, FieldLabel, } from '@/components/ui/field'; +import { formErrors } from '@/lib/form'; +import type { FormWithErrors } from '@/lib/form'; import type { CuttingResultCartItem } from '@/types/cutting'; defineProps<{ + form: FormWithErrors; resultCart: CuttingResultCartItem[]; totalResultPieces: number; isCreateMode: boolean; @@ -54,19 +58,25 @@ const emit = defineEmits<{
- + Hasil + - + Sample + - + Diluar Sample - + +
diff --git a/resources/js/pages/admin/manage/cuttings/form/CuttingPosSummaryPanel.vue b/resources/js/pages/admin/manage/cuttings/form/CuttingPosSummaryPanel.vue index b3ec2ab..7f3c7ae 100644 --- a/resources/js/pages/admin/manage/cuttings/form/CuttingPosSummaryPanel.vue +++ b/resources/js/pages/admin/manage/cuttings/form/CuttingPosSummaryPanel.vue @@ -106,6 +106,7 @@ const imageState = defineModel('imageState', { /> ('imageState', {