diff --git a/src/components/pages/inventory/movement/form/MovementForm.tsx b/src/components/pages/inventory/movement/form/MovementForm.tsx
index cd81b8a0..89546442 100644
--- a/src/components/pages/inventory/movement/form/MovementForm.tsx
+++ b/src/components/pages/inventory/movement/form/MovementForm.tsx
@@ -31,6 +31,8 @@ import {
WarehouseApi,
} from '@/services/api/master-data';
import { toast } from 'react-hot-toast';
+import FileInput from '@/components/input/FileInput';
+import { containsFile } from '@/lib/form-data';
interface MovementFormProps {
type?: 'add' | 'edit' | 'detail';
@@ -62,6 +64,11 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
validationSchema:
type === 'edit' ? UpdateMovementFormSchema : MovementFormSchema,
onSubmit: async (values) => {
+ console.log(
+ 'Dokumen:',
+ values.ekspedisi?.map((e) => e.dokumen)
+ );
+
setMovementFormErrorMessage('');
const payload: CreateMovementPayload = {
alasan_transfer: values.alasan_transfer,
@@ -88,6 +95,9 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
})),
};
+ console.log('containsFile:', containsFile(payload));
+ console.log('payload:', payload);
+
switch (type) {
case 'add':
await createMovementHandler(payload);
@@ -810,9 +820,8 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
/>
- {
const file = e.target.files?.[0];
diff --git a/src/components/pages/inventory/movement/form/useMovementFormHandlers.ts b/src/components/pages/inventory/movement/form/useMovementFormHandlers.ts
index f6531bf4..0b6b0962 100644
--- a/src/components/pages/inventory/movement/form/useMovementFormHandlers.ts
+++ b/src/components/pages/inventory/movement/form/useMovementFormHandlers.ts
@@ -8,6 +8,7 @@ import {
UpdateMovementPayload,
} from '@/types/api/inventory/movement';
import { isResponseError } from '@/lib/api-helper';
+import { containsFile, toFormData } from '@/lib/form-data';
export const useMovementFormHandlers = (initialValuesId?: number) => {
const router = useRouter();
@@ -17,7 +18,11 @@ export const useMovementFormHandlers = (initialValuesId?: number) => {
const createMovementHandler = useCallback(
async (payload: CreateMovementPayload) => {
- const res = await MovementApi.create(payload);
+ const finalPayload = containsFile(payload)
+ ? (toFormData(payload) as unknown as CreateMovementPayload)
+ : payload;
+
+ const res = await MovementApi.create(finalPayload);
if (isResponseError(res)) {
setMovementFormErrorMessage(res.message);
return;
@@ -30,7 +35,11 @@ export const useMovementFormHandlers = (initialValuesId?: number) => {
const updateMovementHandler = useCallback(
async (movementId: number, payload: UpdateMovementPayload) => {
- const res = await MovementApi.update(movementId, payload);
+ const finalPayload = containsFile(payload)
+ ? (toFormData(payload) as unknown as UpdateMovementPayload)
+ : payload;
+
+ const res = await MovementApi.update(movementId, finalPayload);
if (res?.status === 'error') {
setMovementFormErrorMessage(res.message);
return;
diff --git a/src/lib/form-data.ts b/src/lib/form-data.ts
new file mode 100644
index 00000000..d94e0724
--- /dev/null
+++ b/src/lib/form-data.ts
@@ -0,0 +1,45 @@
+export function toFormData(
+ value: unknown,
+ form = new FormData(),
+ parentKey?: string
+) {
+ if (value === undefined || value === null) {
+ if (parentKey) form.append(parentKey, '');
+ return form;
+ }
+
+ if (value instanceof File) {
+ if (!parentKey) throw new Error('File must have a key');
+ form.append(parentKey, value);
+ return form;
+ }
+
+ if (Array.isArray(value)) {
+ value.forEach((v, i) => {
+ const key = parentKey ? `${parentKey}[${i}]` : `${i}`;
+ toFormData(v, form, key);
+ });
+ return form;
+ }
+
+ if (typeof value === 'object') {
+ Object.entries(value as Record).forEach(([k, v]) => {
+ const key = parentKey ? `${parentKey}[${k}]` : k;
+ toFormData(v, form, key);
+ });
+ return form;
+ }
+
+ if (parentKey) form.append(parentKey, String(value));
+ return form;
+}
+
+export function containsFile(obj: unknown): boolean {
+ if (!obj) return false;
+ if (obj instanceof File) return true;
+ if (Array.isArray(obj)) return obj.some(containsFile);
+ if (typeof obj === 'object') {
+ return Object.values(obj as Record).some(containsFile);
+ }
+ return false;
+}
diff --git a/src/services/api/base.ts b/src/services/api/base.ts
index d1ac4729..c4dd826e 100644
--- a/src/services/api/base.ts
+++ b/src/services/api/base.ts
@@ -4,9 +4,11 @@ import { BaseApiResponse } from '@/types/api/api-general';
export class BaseApiService {
basePath: string;
+ header?: Record;
- constructor(basePath: string) {
+ constructor(basePath: string, header?: Record) {
this.basePath = basePath;
+ this.header = header;
}
async getAllFetcher(endpoint: string): Promise> {
@@ -23,42 +25,52 @@ export class BaseApiService {
if (axios.isAxiosError>(error)) {
return error.response?.data;
}
-
return undefined;
}
}
async create(payload: CreatePayloadGeneric) {
+ const isFormData =
+ typeof FormData !== 'undefined' && payload instanceof FormData;
try {
+ const headers = isFormData
+ ? { ...(this.header ?? {}) }
+ : { 'Content-Type': 'application/json', ...(this.header ?? {}) };
+
const createRes = await httpClient>(this.basePath, {
method: 'POST',
body: payload,
+ headers,
});
-
return createRes;
} catch (error: unknown) {
if (axios.isAxiosError>(error)) {
return error.response?.data;
}
-
return undefined;
}
}
async update(id: number, payload: UpdatePayloadGeneric) {
+ const isFormData =
+ typeof FormData !== 'undefined' && payload instanceof FormData;
try {
const updatePath = `${this.basePath}/${id}`;
+
+ const headers = isFormData
+ ? { ...(this.header ?? {}) }
+ : { 'Content-Type': 'application/json', ...(this.header ?? {}) };
+
const updateRes = await httpClient>(updatePath, {
method: 'PATCH',
body: payload,
+ headers,
});
-
return updateRes;
} catch (error: unknown) {
if (axios.isAxiosError>(error)) {
return error.response?.data;
}
-
return undefined;
}
}
@@ -69,13 +81,11 @@ export class BaseApiService {
const deleteRes = await httpClient(deletePath, {
method: 'DELETE',
});
-
return deleteRes;
} catch (error) {
if (axios.isAxiosError(error)) {
return error.response?.data;
}
-
return undefined;
}
}
|