refactor: enhance component structure in various forms by introducing computed properties and improving template syntax for better readability and maintainability
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (8.3) (push) Waiting to run
tests / ci (8.4) (push) Waiting to run
tests / ci (8.5) (push) Waiting to run

This commit is contained in:
Yoga Pangestu 2026-07-02 22:41:18 +07:00
parent b78d512197
commit 4eea267756
6 changed files with 33 additions and 69 deletions

View File

@ -1,13 +1,7 @@
<script setup lang="ts">
import { Plus, Save } from '@lucide/vue';
import { ref } from 'vue';
import { computed, ref } from 'vue';
import { toast } from 'vue-sonner';
import { apiFetch } from '@/lib/api';
import { useVariantList } from '@/composables/useVariantList';
import { appendMediaToFormData, createMediaUploadState } from '@/types/media';
import { formErrors } from '@/lib/form';
import { parseRupiah } from '@/lib/rupiah';
import type { EnumOption, RawMaterialPriceFormItem } from '@/types/raw-material';
import { Button } from '@/components/ui/button';
import {
Dialog,
@ -16,10 +10,16 @@ import {
DialogTitle,
} from '@/components/ui/dialog';
import { FieldError } from '@/components/ui/field';
import { useVariantList } from '@/composables/useVariantList';
import { apiFetch } from '@/lib/api';
import { formErrors } from '@/lib/form';
import { parseRupiah } from '@/lib/rupiah';
import RawMaterialInfoSection from '@/pages/admin/master/raw-materials/form/RawMaterialInfoSection.vue';
import RawMaterialSharedPriceSection from '@/pages/admin/master/raw-materials/form/RawMaterialSharedPriceSection.vue';
import RawMaterialVariantSection from '@/pages/admin/master/raw-materials/form/RawMaterialVariantSection.vue';
import type { CuttingRawMaterialCatalogItem } from '@/types/cutting';
import { appendMediaToFormData, createMediaUploadState } from '@/types/media';
import type { EnumOption, RawMaterialPriceFormItem } from '@/types/raw-material';
const props = defineProps<{
units: EnumOption[];
@ -34,7 +34,7 @@ const emit = defineEmits<{
const loading = ref(false);
const selectPortalTarget = ref<HTMLElement>();
const isUploading = computed(() =>
const isUploading = computed(() =>
prices.value.some((p) => p.media.pendingUploads > 0)
);
@ -190,31 +190,20 @@ async function submit() {
<div class="scrollbar-thin flex-1 overflow-y-auto pr-1">
<form id="quick-create-raw-material-form" @submit.prevent="submit" class="space-y-6">
<RawMaterialInfoSection :form="form" :units="units" method="post" :select-portal-target="selectPortalTarget" />
<RawMaterialInfoSection :form="form" :units="units" method="post"
:select-portal-target="selectPortalTarget" />
<RawMaterialSharedPriceSection
:form="form"
:prices="prices"
:use-same-price="useSamePrice"
@toggle-use-same-price="toggleUseSamePrice"
@set-shared-price="setSharedPrice"
/>
<RawMaterialSharedPriceSection :form="form" :prices="prices" :use-same-price="useSamePrice"
@toggle-use-same-price="toggleUseSamePrice" @set-shared-price="setSharedPrice" />
<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"
<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)"
@update:variant="setPriceField(price.client_id, 'variant', $event)"
@update:stock="setPriceField(price.client_id, 'stock', $event)"
@update:price="setPriceValue(price.client_id, $event)"
/>
@update:price="setPriceValue(price.client_id, $event)" />
<FieldError :errors="formErrors(form, 'prices')" />
</form>

View File

@ -1,5 +1,6 @@
<script setup lang="ts">
import { Save } from '@lucide/vue';
import { computed } from 'vue';
import { RupiahInput } from '@/components/form/rupiah-input';
import MediaDropzone from '@/components/media/MediaDropzone.vue';
import { Button } from '@/components/ui/button';
@ -71,11 +72,8 @@ const isUploading = computed(() => photoState.value.pendingUploads > 0);
<Field v-if="canComplete">
<div class="flex items-center gap-3">
<Switch
id="status-completed"
:model-value="form.status === OrderStatus.COMPLETED"
@update:model-value="form.status = $event ? OrderStatus.COMPLETED : OrderStatus.PENDING"
/>
<Switch id="status-completed" :model-value="form.status === OrderStatus.COMPLETED"
@update:model-value="form.status = $event ? OrderStatus.COMPLETED : OrderStatus.PENDING" />
<Label for="status-completed" class="cursor-pointer text-sm">
Pesanan selesai
</Label>
@ -92,15 +90,8 @@ const isUploading = computed(() => photoState.value.pendingUploads > 0);
<FieldError :errors="formErrors(form, 'notes')" />
</Field>
<MediaDropzone
v-if="showPhotoInput"
id="order-photos"
v-model="photoState"
label="Bukti Transaksi"
:max-files="1"
required
:errors="formErrors(form, 'photos')"
/>
<MediaDropzone v-if="showPhotoInput" id="order-photos" v-model="photoState" label="Bukti Transaksi" :max-files="1"
required :errors="formErrors(form, 'photos')" />
<Field v-if="isCreateMode && canCreate">
<div class="flex items-center gap-3">
@ -112,16 +103,12 @@ const isUploading = computed(() => photoState.value.pendingUploads > 0);
<div v-if="printAfterSave" class="mt-2 flex items-center gap-2 pl-1">
<span class="text-xs text-muted-foreground">Ukuran kertas:</span>
<div class="flex gap-1.5">
<button
v-for="size in ([PaperSize.MM_58, PaperSize.MM_80] as const)"
:key="size"
type="button"
<button v-for="size in ([PaperSize.MM_58, PaperSize.MM_80] as const)" :key="size" type="button"
class="inline-flex h-7 cursor-pointer items-center rounded-md border px-2.5 text-xs font-medium transition-colors"
:class="selectedPaperSize === size
? 'border-primary bg-primary/5 text-primary'
: 'border-input bg-background text-foreground hover:bg-accent hover:text-accent-foreground'"
@click="selectedPaperSize = size"
>
@click="selectedPaperSize = size">
{{ size }}
</button>
</div>

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, watch } from 'vue';
import { computed, ref, watch } from 'vue';
import { toast } from 'vue-sonner';
import { DecimalInput } from '@/components/form/decimal-input';
import { RupiahInput } from '@/components/form/rupiah-input';

View File

@ -1,4 +1,5 @@
<script setup lang="ts">
import { computed } from 'vue';
import { Save } from '@lucide/vue';
import { RupiahInput } from '@/components/form/rupiah-input';
import MediaDropzone from '@/components/media/MediaDropzone.vue';

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import { useForm } from '@inertiajs/vue3';
import { Plus, Save } from '@lucide/vue';
import { ref } from 'vue';
import { computed, ref } from 'vue';
import { toast } from 'vue-sonner';
import { Button } from '@/components/ui/button';
import { FieldError } from '@/components/ui/field';
@ -46,7 +46,7 @@ function createClientId(): string {
return `price-${crypto.randomUUID()}`;
}
const isUploading = computed(() =>
const isUploading = computed(() =>
prices.value.some((p) => p.media.pendingUploads > 0)
);
@ -190,29 +190,16 @@ function submit() {
<div class="grid gap-6">
<RawMaterialInfoSection :form="form" :units="units" :method="method" />
<RawMaterialSharedPriceSection
:form="form"
:prices="prices"
:use-same-price="useSamePrice"
@toggle-use-same-price="toggleUseSamePrice"
@set-shared-price="setSharedPrice"
/>
<RawMaterialSharedPriceSection :form="form" :prices="prices" :use-same-price="useSamePrice"
@toggle-use-same-price="toggleUseSamePrice" @set-shared-price="setSharedPrice" />
<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"
<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="removePrice(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)"
/>
@update:price="setPriceValue(price.client_id, $event)" />
<FieldError :errors="formErrors(form, 'prices')" />

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import { router } from '@inertiajs/vue3';
import { Save } from '@lucide/vue';
import { ref } from 'vue';
import { computed, ref } from 'vue';
import { toast } from 'vue-sonner';
import MediaDropzone from '@/components/media/MediaDropzone.vue';
import { Button } from '@/components/ui/button';