Refactor CashTransactionFormModal and EmployeeAdvanceFormModal to utilize useFormDialog for improved form handling. Replace MediaImageUpload with ImageUploadField for photo uploads, enhancing user experience. Update form data handling to accommodate new photo upload logic and streamline code.
This commit is contained in:
parent
10e188807d
commit
e871da4c5f
@ -1,9 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { useForm } from '@inertiajs/vue3';
|
||||
import { Save } from '@lucide/vue';
|
||||
import { computed, watch } from 'vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import { toast } from 'vue-sonner';
|
||||
import MediaImageUpload from '@/components/media/MediaImageUpload.vue';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
Dialog,
|
||||
@ -19,12 +18,13 @@ import {
|
||||
FieldLabel,
|
||||
FieldSet,
|
||||
} from '@/components/ui/field';
|
||||
import ImageUploadField from '@/components/ui/image-upload-field/ImageUploadField.vue';
|
||||
import { RupiahInput } from '@/components/ui/rupiah-input';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import { useFormDialog } from '@/composables/useFormDialog';
|
||||
import { formErrors } from '@/lib/form';
|
||||
import { parseRupiah } from '@/lib/rupiah';
|
||||
import type { CashTransactionListItem } from '@/types/cash';
|
||||
import { appendRootPhotosToFormData, createMediaUploadState } from '@/types/media';
|
||||
|
||||
const open = defineModel<boolean>('open', { default: false });
|
||||
|
||||
@ -34,15 +34,21 @@ const props = defineProps<{
|
||||
|
||||
const isEditing = computed(() => props.transaction != null);
|
||||
|
||||
const existingPhotoId = ref<number | null>(null);
|
||||
|
||||
const currentPhotoUrl = computed(() => props.transaction?.photos?.[0]?.url ?? null);
|
||||
|
||||
|
||||
const form = useForm({
|
||||
amount: '',
|
||||
description: '',
|
||||
media: createMediaUploadState(),
|
||||
photo: null as File | null,
|
||||
});
|
||||
|
||||
function resetForm() {
|
||||
form.reset();
|
||||
form.media = createMediaUploadState();
|
||||
form.photo = null;
|
||||
existingPhotoId.value = null;
|
||||
form.clearErrors();
|
||||
}
|
||||
|
||||
@ -55,22 +61,14 @@ function populateForm(transaction: CashTransactionListItem | null | undefined) {
|
||||
|
||||
form.amount = String(transaction.amount);
|
||||
form.description = transaction.description;
|
||||
form.media = createMediaUploadState(transaction.photos ?? []);
|
||||
existingPhotoId.value = transaction.photos?.[0]?.id ?? null;
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.transaction,
|
||||
(transaction) => {
|
||||
populateForm(transaction);
|
||||
},
|
||||
);
|
||||
|
||||
watch(open, (isOpen) => {
|
||||
if (isOpen) {
|
||||
populateForm(props.transaction);
|
||||
} else {
|
||||
resetForm();
|
||||
}
|
||||
useFormDialog({
|
||||
open,
|
||||
source: () => props.transaction,
|
||||
populate: populateForm,
|
||||
reset: resetForm,
|
||||
});
|
||||
|
||||
function buildFormData(forUpdate: boolean): FormData {
|
||||
@ -82,12 +80,21 @@ function buildFormData(forUpdate: boolean): FormData {
|
||||
|
||||
formData.append('amount', parseRupiah(form.amount));
|
||||
formData.append('description', form.description);
|
||||
appendRootPhotosToFormData(formData, form.media);
|
||||
|
||||
if (form.photo) {
|
||||
formData.append('photos[]', form.photo);
|
||||
|
||||
if (existingPhotoId.value) {
|
||||
formData.append('remove_media_ids[]', String(existingPhotoId.value));
|
||||
}
|
||||
}
|
||||
|
||||
return formData;
|
||||
}
|
||||
|
||||
function submit() {
|
||||
const payload = buildFormData(isEditing.value);
|
||||
|
||||
const options = {
|
||||
forceFormData: true,
|
||||
preserveScroll: true,
|
||||
@ -101,13 +108,13 @@ function submit() {
|
||||
},
|
||||
};
|
||||
|
||||
const payload = buildFormData(isEditing.value);
|
||||
|
||||
if (isEditing.value && props.transaction) {
|
||||
form.transform(() => payload).post(`/admin/finance/cash/transactions/${props.transaction.id}`, options);
|
||||
} else {
|
||||
form.transform(() => payload).post('/admin/finance/cash/deposit', options);
|
||||
form.transform(() => payload).put(`/admin/finance/cash/transactions/${props.transaction.id}`, options);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
form.transform(() => payload).post('/admin/finance/cash/deposit', options);
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -132,8 +139,8 @@ function submit() {
|
||||
placeholder="Contoh: Setoran kas harian" rows="3" />
|
||||
<FieldError :errors="formErrors(form, 'description')" />
|
||||
</Field>
|
||||
<MediaImageUpload id="cash-photos" v-model="form.media" label="Foto Bukti" required
|
||||
:errors="formErrors(form, 'photos')" />
|
||||
<ImageUploadField id="cash-photos" v-model="form.photo" label="Foto Bukti" required
|
||||
:current-url="currentPhotoUrl" :errors="formErrors(form, 'photos')" />
|
||||
</FieldSet>
|
||||
</FieldGroup>
|
||||
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { useForm } from '@inertiajs/vue3';
|
||||
import { Save } from '@lucide/vue';
|
||||
import { computed, watch } from 'vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import { toast } from 'vue-sonner';
|
||||
import MediaImageUpload from '@/components/media/MediaImageUpload.vue';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { DatePicker } from '@/components/ui/date-picker';
|
||||
import {
|
||||
@ -20,12 +19,13 @@ import {
|
||||
FieldLabel,
|
||||
FieldSet,
|
||||
} from '@/components/ui/field';
|
||||
import ImageUploadField from '@/components/ui/image-upload-field/ImageUploadField.vue';
|
||||
import { RupiahInput } from '@/components/ui/rupiah-input';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import { useFormDialog } from '@/composables/useFormDialog';
|
||||
import { formErrors } from '@/lib/form';
|
||||
import { parseRupiah } from '@/lib/rupiah';
|
||||
import type { EmployeeAdvanceListItem } from '@/types/employee-advance';
|
||||
import { appendRootPhotosToFormData, createMediaUploadState } from '@/types/media';
|
||||
|
||||
const open = defineModel<boolean>('open', { default: false });
|
||||
|
||||
@ -35,16 +35,21 @@ const props = defineProps<{
|
||||
|
||||
const isEditing = computed(() => props.employeeAdvance != null);
|
||||
|
||||
const existingPhotoId = ref<number | null>(null);
|
||||
|
||||
const currentPhotoUrl = computed(() => props.employeeAdvance?.photos?.[0]?.url ?? null);
|
||||
|
||||
const form = useForm({
|
||||
amount: '',
|
||||
description: '',
|
||||
due_date: '',
|
||||
media: createMediaUploadState(),
|
||||
photo: null as File | null,
|
||||
});
|
||||
|
||||
function resetForm() {
|
||||
form.reset();
|
||||
form.media = createMediaUploadState();
|
||||
form.photo = null;
|
||||
existingPhotoId.value = null;
|
||||
form.clearErrors();
|
||||
}
|
||||
|
||||
@ -58,22 +63,14 @@ function populateForm(employeeAdvance: EmployeeAdvanceListItem | null | undefine
|
||||
form.amount = String(employeeAdvance.amount);
|
||||
form.description = employeeAdvance.description;
|
||||
form.due_date = employeeAdvance.due_date_input;
|
||||
form.media = createMediaUploadState(employeeAdvance.photos ?? []);
|
||||
existingPhotoId.value = employeeAdvance.photos?.[0]?.id ?? null;
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.employeeAdvance,
|
||||
(employeeAdvance) => {
|
||||
populateForm(employeeAdvance);
|
||||
},
|
||||
);
|
||||
|
||||
watch(open, (isOpen) => {
|
||||
if (isOpen) {
|
||||
populateForm(props.employeeAdvance);
|
||||
} else {
|
||||
resetForm();
|
||||
}
|
||||
useFormDialog({
|
||||
open,
|
||||
source: () => props.employeeAdvance,
|
||||
populate: populateForm,
|
||||
reset: resetForm,
|
||||
});
|
||||
|
||||
function buildFormData(forUpdate: boolean): FormData {
|
||||
@ -86,12 +83,21 @@ function buildFormData(forUpdate: boolean): FormData {
|
||||
formData.append('amount', parseRupiah(form.amount));
|
||||
formData.append('description', form.description);
|
||||
formData.append('due_date', form.due_date);
|
||||
appendRootPhotosToFormData(formData, form.media);
|
||||
|
||||
if (form.photo) {
|
||||
formData.append('photos[]', form.photo);
|
||||
|
||||
if (existingPhotoId.value) {
|
||||
formData.append('remove_media_ids[]', String(existingPhotoId.value));
|
||||
}
|
||||
}
|
||||
|
||||
return formData;
|
||||
}
|
||||
|
||||
function submit() {
|
||||
const payload = buildFormData(isEditing.value);
|
||||
|
||||
const options = {
|
||||
forceFormData: true,
|
||||
preserveScroll: true,
|
||||
@ -103,13 +109,13 @@ function submit() {
|
||||
},
|
||||
};
|
||||
|
||||
const payload = buildFormData(isEditing.value);
|
||||
|
||||
if (isEditing.value && props.employeeAdvance) {
|
||||
form.transform(() => payload).post(`/admin/finance/employee-advances/${props.employeeAdvance.id}`, options);
|
||||
} else {
|
||||
form.transform(() => payload).post('/admin/finance/employee-advances', options);
|
||||
form.transform(() => payload).put(`/admin/finance/employee-advances/${props.employeeAdvance.id}`, options);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
form.transform(() => payload).post('/admin/finance/employee-advances', options);
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -139,8 +145,8 @@ function submit() {
|
||||
<DatePicker id="employee-advance-due-date" v-model="form.due_date" />
|
||||
<FieldError :errors="formErrors(form, 'due_date')" />
|
||||
</Field>
|
||||
<MediaImageUpload id="employee-advance-photos" v-model="form.media" label="Foto Bukti" required
|
||||
:errors="formErrors(form, 'photos')" />
|
||||
<ImageUploadField id="employee-advance-photos" v-model="form.photo" label="Foto Bukti" required
|
||||
:current-url="currentPhotoUrl" :errors="formErrors(form, 'photos')" />
|
||||
</FieldSet>
|
||||
</FieldGroup>
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user