mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 21:41:57 +00:00
refactor(FE-Storyless): remove UpdateMovementPayload type and related schema, streamline MovementForm handling
This commit is contained in:
@@ -133,8 +133,6 @@ export const MovementFormSchema = Yup.object({
|
||||
.required('Pengiriman wajib diisi!'),
|
||||
});
|
||||
|
||||
export const UpdateMovementFormSchema = MovementFormSchema;
|
||||
|
||||
export type MovementFormValues = Yup.InferType<typeof MovementFormSchema>;
|
||||
|
||||
export const getMovementFormInitialValues = (
|
||||
|
||||
@@ -13,19 +13,19 @@ import {
|
||||
CreateMovementPayload,
|
||||
Movement,
|
||||
} from '@/types/api/inventory/movement';
|
||||
import { isResponseSuccess } from '@/lib/api-helper';
|
||||
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import {
|
||||
MovementFormSchema,
|
||||
MovementFormValues,
|
||||
UpdateMovementFormSchema,
|
||||
getMovementFormInitialValues,
|
||||
ProductSchema,
|
||||
DeliverySchema,
|
||||
} from '@/components/pages/inventory/movement/form/MovementForm.schema';
|
||||
import { useMovementFormHandlers } from './useMovementFormHandlers';
|
||||
import { SupplierApi, WarehouseApi } from '@/services/api/master-data';
|
||||
import { ProductWarehouseApi } from '@/services/api/inventory';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import { MovementApi } from '@/services/api/inventory';
|
||||
import FileInput from '@/components/input/FileInput';
|
||||
import CheckboxInput from '@/components/input/CheckboxInput';
|
||||
import Badge from '@/components/Badge';
|
||||
@@ -36,8 +36,10 @@ interface MovementFormProps {
|
||||
}
|
||||
|
||||
const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
const router = useRouter();
|
||||
|
||||
// ===== STATE MANAGEMENT =====
|
||||
const [, setMovementFormErrorMessage] = useState('');
|
||||
const [movementFormErrorMessage, setMovementFormErrorMessage] = useState('');
|
||||
const [
|
||||
productWarehouseSelectInputValue,
|
||||
setProductWarehouseSelectInputValue,
|
||||
@@ -49,11 +51,26 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
const [supplierSelectInputValue, setSupplierSelectInputValue] = useState('');
|
||||
|
||||
// ===== FORM HANDLERS =====
|
||||
const {
|
||||
movementFormErrorMessage,
|
||||
createMovementHandler,
|
||||
updateMovementHandler,
|
||||
} = useMovementFormHandlers(initialValues?.id);
|
||||
const createMovementHandler = useCallback(
|
||||
async (payload: CreateMovementPayload, documents: File[] = []) => {
|
||||
const formData = new FormData();
|
||||
formData.append('data', JSON.stringify(payload));
|
||||
documents.forEach((file, index) => {
|
||||
formData.append(`documents[${index}]`, file);
|
||||
});
|
||||
|
||||
const res = await MovementApi.create(
|
||||
formData as unknown as CreateMovementPayload
|
||||
);
|
||||
if (isResponseError(res)) {
|
||||
setMovementFormErrorMessage(res.message);
|
||||
return;
|
||||
}
|
||||
toast.success(res?.message as string);
|
||||
router.push('/inventory/movement');
|
||||
},
|
||||
[router]
|
||||
);
|
||||
|
||||
// ===== INTERFACES =====
|
||||
interface WarehouseOptionType extends OptionType {
|
||||
@@ -139,8 +156,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
|
||||
const formik = useFormik<MovementFormValues>({
|
||||
initialValues: formikInitialValues,
|
||||
validationSchema:
|
||||
type === 'edit' ? UpdateMovementFormSchema : MovementFormSchema,
|
||||
validationSchema: MovementFormSchema,
|
||||
validateOnChange: true,
|
||||
validateOnBlur: true,
|
||||
validateOnMount: false,
|
||||
@@ -148,7 +164,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
onSubmit: async (values) => {
|
||||
setMovementFormErrorMessage('');
|
||||
const documents: File[] = [];
|
||||
const deliveriesPayload = values.deliveries.map((d, idx) => {
|
||||
const deliveriesPayload = values.deliveries.map((d) => {
|
||||
let documentIndex = 0;
|
||||
|
||||
if (d.document && d.document instanceof File) {
|
||||
@@ -187,13 +203,6 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
case 'add':
|
||||
await createMovementHandler(payload, documents);
|
||||
break;
|
||||
case 'edit':
|
||||
await updateMovementHandler(
|
||||
initialValues?.id as number,
|
||||
payload,
|
||||
documents
|
||||
);
|
||||
break;
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -1591,49 +1600,9 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
|
||||
{/* Action buttons */}
|
||||
<div className='flex flex-row justify-between gap-2 flex-wrap'>
|
||||
{type !== 'add' && (
|
||||
<div className='flex flex-row justify-start gap-2'>
|
||||
<Button
|
||||
type='button'
|
||||
color='error'
|
||||
onClick={() => console.log('Delete clicked')}
|
||||
className='px-4'
|
||||
>
|
||||
<Icon
|
||||
icon='material-symbols:delete-outline-rounded'
|
||||
width={24}
|
||||
height={24}
|
||||
className='justify-start text-sm'
|
||||
/>
|
||||
Delete
|
||||
</Button>
|
||||
|
||||
{type !== 'edit' && (
|
||||
<Button
|
||||
type='button'
|
||||
color='warning'
|
||||
href={`/inventory/movement/detail/edit/?movementId=${initialValues?.id}`}
|
||||
className='px-4'
|
||||
>
|
||||
<Icon
|
||||
icon='material-symbols:edit-outline'
|
||||
width={24}
|
||||
height={24}
|
||||
className='justify-start text-sm'
|
||||
/>
|
||||
Edit
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{type !== 'detail' && (
|
||||
<div className='flex flex-row justify-end gap-2 w-full'>
|
||||
<Button
|
||||
type='reset'
|
||||
color='warning'
|
||||
className='px-4'
|
||||
>
|
||||
<Button type='reset' color='warning' className='px-4'>
|
||||
Reset
|
||||
</Button>
|
||||
|
||||
@@ -1642,7 +1611,12 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
color='primary'
|
||||
className='px-4'
|
||||
isLoading={formik.isSubmitting}
|
||||
disabled={hasInvalidQty || hasExceededStock || !formik.isValid || formik.isSubmitting}
|
||||
disabled={
|
||||
hasInvalidQty ||
|
||||
hasExceededStock ||
|
||||
!formik.isValid ||
|
||||
formik.isSubmitting
|
||||
}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import { useModal } from '@/components/Modal';
|
||||
import { MovementApi } from '@/services/api/inventory';
|
||||
import {
|
||||
CreateMovementPayload,
|
||||
UpdateMovementPayload,
|
||||
} from '@/types/api/inventory/movement';
|
||||
import { isResponseError } from '@/lib/api-helper';
|
||||
|
||||
export const useMovementFormHandlers = (initialValuesId?: number) => {
|
||||
const router = useRouter();
|
||||
const deleteModal = useModal();
|
||||
const [movementFormErrorMessage, setMovementFormErrorMessage] = useState('');
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
|
||||
const createMovementHandler = useCallback(
|
||||
async (payload: CreateMovementPayload, documents: File[] = []) => {
|
||||
const formData = new FormData();
|
||||
formData.append('data', JSON.stringify(payload));
|
||||
documents.forEach((file, index) => {
|
||||
formData.append(`documents[${index}]`, file);
|
||||
});
|
||||
|
||||
const res = await MovementApi.create(
|
||||
formData as unknown as CreateMovementPayload
|
||||
);
|
||||
if (isResponseError(res)) {
|
||||
setMovementFormErrorMessage(res.message);
|
||||
return;
|
||||
}
|
||||
toast.success(res?.message as string);
|
||||
router.push('/inventory/movement');
|
||||
},
|
||||
[router]
|
||||
);
|
||||
|
||||
const updateMovementHandler = useCallback(
|
||||
async (
|
||||
movementId: number,
|
||||
payload: UpdateMovementPayload,
|
||||
documents: File[] = []
|
||||
) => {
|
||||
let finalPayload: UpdateMovementPayload | FormData;
|
||||
|
||||
if (documents.length > 0) {
|
||||
const formData = new FormData();
|
||||
formData.append('data', JSON.stringify(payload));
|
||||
documents.forEach((file, index) => {
|
||||
formData.append(`documents[${index}]`, file);
|
||||
});
|
||||
|
||||
finalPayload = formData as unknown as UpdateMovementPayload;
|
||||
} else {
|
||||
finalPayload = payload;
|
||||
}
|
||||
|
||||
const res = await MovementApi.update(movementId, finalPayload);
|
||||
if (res?.status === 'error') {
|
||||
setMovementFormErrorMessage(res.message);
|
||||
return;
|
||||
}
|
||||
toast.success(res?.message as string);
|
||||
router.refresh();
|
||||
router.push('/inventory/movement');
|
||||
},
|
||||
[router]
|
||||
);
|
||||
|
||||
const deleteMovementClickHandler = useCallback(() => {
|
||||
deleteModal.openModal();
|
||||
}, [deleteModal]);
|
||||
|
||||
const confirmationModalDeleteClickHandler = useCallback(async () => {
|
||||
if (!initialValuesId) return;
|
||||
|
||||
setIsDeleteLoading(true);
|
||||
await MovementApi.delete(initialValuesId);
|
||||
deleteModal.closeModal();
|
||||
toast.success('Successfully delete Movement!');
|
||||
setIsDeleteLoading(false);
|
||||
router.push('/inventory/movement');
|
||||
}, [deleteModal, initialValuesId, router]);
|
||||
|
||||
return {
|
||||
deleteModal,
|
||||
movementFormErrorMessage,
|
||||
isDeleteLoading,
|
||||
createMovementHandler,
|
||||
updateMovementHandler,
|
||||
deleteMovementClickHandler,
|
||||
confirmationModalDeleteClickHandler,
|
||||
};
|
||||
};
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
import {
|
||||
CreateMovementPayload,
|
||||
Movement,
|
||||
UpdateMovementPayload,
|
||||
} from '@/types/api/inventory/movement';
|
||||
import {
|
||||
CreateInventoryAdjustmentPayload,
|
||||
@@ -23,7 +22,7 @@ export const ProductWarehouseApi = new BaseApiService<
|
||||
export const MovementApi = new BaseApiService<
|
||||
Movement,
|
||||
CreateMovementPayload,
|
||||
UpdateMovementPayload
|
||||
unknown
|
||||
>('/inventory/transfers');
|
||||
|
||||
export const inventoryAdjustmentApi = new BaseApiService<
|
||||
|
||||
-2
@@ -71,5 +71,3 @@ export type CreateMovementPayload = {
|
||||
}[];
|
||||
}[];
|
||||
};
|
||||
|
||||
export type UpdateMovementPayload = CreateMovementPayload;
|
||||
|
||||
Reference in New Issue
Block a user