fix(FE) resolve merge conflict

This commit is contained in:
randy-ar
2025-10-21 10:19:03 +07:00
31 changed files with 2742 additions and 33 deletions
+18 -8
View File
@@ -4,9 +4,11 @@ import { BaseApiResponse } from '@/types/api/api-general';
export class BaseApiService<T, CreatePayloadGeneric, UpdatePayloadGeneric> {
basePath: string;
header?: Record<string, string>;
constructor(basePath: string) {
constructor(basePath: string, header?: Record<string, string>) {
this.basePath = basePath;
this.header = header;
}
async getAllFetcher(endpoint: string): Promise<BaseApiResponse<T[]>> {
@@ -23,42 +25,52 @@ export class BaseApiService<T, CreatePayloadGeneric, UpdatePayloadGeneric> {
if (axios.isAxiosError<BaseApiResponse<T>>(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<BaseApiResponse<T>>(this.basePath, {
method: 'POST',
body: payload,
headers,
});
return createRes;
} catch (error: unknown) {
if (axios.isAxiosError<BaseApiResponse<T>>(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<BaseApiResponse<T>>(updatePath, {
method: 'PATCH',
body: payload,
headers,
});
return updateRes;
} catch (error: unknown) {
if (axios.isAxiosError<BaseApiResponse<T>>(error)) {
return error.response?.data;
}
return undefined;
}
}
@@ -69,13 +81,11 @@ export class BaseApiService<T, CreatePayloadGeneric, UpdatePayloadGeneric> {
const deleteRes = await httpClient<BaseApiResponse>(deletePath, {
method: 'DELETE',
});
return deleteRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse>(error)) {
return error.response?.data;
}
return undefined;
}
}
+30 -8
View File
@@ -1,11 +1,33 @@
import {
InventoryAdjustment,
CreateInventoryAdjustmentPayload,
} from '@/types/api/inventory/adjustment';
import { BaseApiService } from '@/services/api/base';
import {
CreateProductWarehousePayload,
ProductWarehouse,
UpdateProductWarehousePayload,
} from '@/types/api/inventory/product-warehouse';
import {
CreateMovementPayload,
Movement,
UpdateMovementPayload,
} from '@/types/api/inventory/movement';
import {
CreateInventoryAdjustmentPayload,
InventoryAdjustment,
} from '@/types/api/inventory/adjustment';
export const ProductWarehouseApi = new BaseApiService<
ProductWarehouse,
CreateProductWarehousePayload,
UpdateProductWarehousePayload
>('/inventory/product-warehouses');
export const MovementApi = new BaseApiService<
Movement,
CreateMovementPayload,
UpdateMovementPayload
>('/inventory/transfers');
export const inventoryAdjustmentApi = new BaseApiService<
InventoryAdjustment,
CreateInventoryAdjustmentPayload,
unknown
>('/inventory/adjustments');
InventoryAdjustment,
CreateInventoryAdjustmentPayload,
unknown
>('/inventory/adjustments');
+23 -2
View File
@@ -6,22 +6,43 @@ type AuthStore = {
isLoadingUser?: boolean;
setUser: (newUserData?: UserWithRoles) => void;
setIsLoadingUser: (isLoading?: boolean) => void;
permissionCheck: (permissionName: string) => boolean;
};
const useAuthStore = create<AuthStore>()((set) => ({
const useAuthStore = create<AuthStore>()((set, get) => ({
user: undefined,
isLoadingUser: false,
setUser: (newUserData) => set({ user: newUserData }),
setIsLoadingUser: (isLoading) => set({ isLoadingUser: Boolean(isLoading) }),
permissionCheck: (name) => {
const { user, isLoadingUser } = get();
if (!isLoadingUser && user) {
const isAllowed = user.roles.some((role) => {
const isPermissionNameAllowed = role.permissions.some(
(permission) => permission.name === name
);
return isPermissionNameAllowed;
});
return isAllowed;
}
return false;
},
}));
export const useAuth = () => {
const { user, setUser, isLoadingUser, setIsLoadingUser } = useAuthStore();
const { user, setUser, isLoadingUser, setIsLoadingUser, permissionCheck } =
useAuthStore();
return {
user,
setUser,
isLoadingUser,
setIsLoadingUser,
permissionCheck,
};
};
+4 -1
View File
@@ -14,6 +14,9 @@ export async function httpClient<T, B = unknown>(
(!opts.auth && opts.auth !== 'none' && opts.auth !== 'bearer');
const isBearerAuth = opts.auth === 'bearer' && !!opts.token;
const isFormData =
typeof FormData !== 'undefined' && opts.body instanceof FormData;
const config: AxiosRequestConfig = {
url: path,
method: opts.method ?? 'GET',
@@ -22,7 +25,7 @@ export async function httpClient<T, B = unknown>(
timeout: opts.timeoutMs ?? 10_000,
withCredentials: isCookieAuth && !isBearerAuth,
headers: {
'Content-Type': 'application/json',
...(isFormData ? {} : { 'Content-Type': 'application/json' }),
...(opts.headers ?? {}),
...(isBearerAuth && !isCookieAuth
? { Authorization: `Bearer ${opts.token}` }