ignore folder
This commit is contained in:
59
services/api.ts
Normal file
59
services/api.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import axios from "axios";
|
||||
import { useAuthStore } from "@/store/authStore";
|
||||
import { useTenantStore } from "@/store/tenantStore";
|
||||
import { useLocaleStore } from "@/store/uiStore";
|
||||
import { useApiStore } from "@/store/uiStore";
|
||||
|
||||
export const apiClient = axios.create({
|
||||
baseURL: process.env.NEXT_PUBLIC_API_BASE_URL || "http://localhost:9191",
|
||||
timeout: 25000
|
||||
});
|
||||
|
||||
apiClient.interceptors.request.use((config) => {
|
||||
const auth = useAuthStore.getState();
|
||||
const tenantId = useTenantStore.getState().tenantId || auth.tenantId;
|
||||
const locale = useLocaleStore.getState().locale;
|
||||
|
||||
if (auth.accessToken) {
|
||||
config.headers.Authorization = `${auth.tokenType ?? "Bearer"} ${auth.accessToken}`;
|
||||
}
|
||||
if (tenantId) {
|
||||
config.headers["X-Tenant-Id"] = tenantId;
|
||||
}
|
||||
if (locale) {
|
||||
config.headers["Accept-Language"] = locale === "id" ? "id-ID" : "en-US";
|
||||
}
|
||||
|
||||
return config;
|
||||
});
|
||||
|
||||
apiClient.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
const status = error?.response?.status;
|
||||
const message = error?.response?.data?.message || error.message;
|
||||
const ui = useApiStore.getState();
|
||||
if (status === 401) {
|
||||
ui.addToast(message || "Unauthorized", "error");
|
||||
useAuthStore.getState().clearAuth();
|
||||
if (typeof window !== "undefined") {
|
||||
window.location.href = "/(auth)/login";
|
||||
}
|
||||
}
|
||||
|
||||
if (status === 403) {
|
||||
ui.addToast(message || "Forbidden", "error");
|
||||
}
|
||||
|
||||
return Promise.reject(new Error(message ?? "Request failed"));
|
||||
}
|
||||
);
|
||||
|
||||
export async function unwrap<T>(promise: ReturnType<typeof apiClient.request>): Promise<T> {
|
||||
const response = await promise;
|
||||
const payload = response.data;
|
||||
if (payload && typeof payload.success === "boolean" && payload.success === false) {
|
||||
throw new Error(payload.message ?? "Business error");
|
||||
}
|
||||
return payload.data as T;
|
||||
}
|
||||
10
services/audit.ts
Normal file
10
services/audit.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { ApiResponse, AuditItem } from "@/types/api";
|
||||
import { apiClient } from "./api";
|
||||
|
||||
export async function getAudit(limit = 50): Promise<AuditItem[]> {
|
||||
const response = await apiClient.get<ApiResponse<AuditItem[]>>("/api/audit", {
|
||||
params: { limit }
|
||||
});
|
||||
if (!response.data.success) throw new Error(response.data.message);
|
||||
return response.data.data;
|
||||
}
|
||||
41
services/auth.ts
Normal file
41
services/auth.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { ApiResponse, LoginRequest, LoginResponseData, UserProfile, TenantContextResponse } from "@/types/api";
|
||||
import { apiClient, unwrap } from "./api";
|
||||
|
||||
export async function login(request: LoginRequest, tenantId: string): Promise<LoginResponseData> {
|
||||
const response = await apiClient.post<ApiResponse<LoginResponseData>>(
|
||||
"/api/auth/login",
|
||||
request,
|
||||
{
|
||||
headers: { "X-Tenant-Id": tenantId }
|
||||
}
|
||||
);
|
||||
const payload = response.data;
|
||||
if (!payload.success) {
|
||||
throw new Error(payload.message);
|
||||
}
|
||||
return payload.data;
|
||||
}
|
||||
|
||||
export async function refreshToken(refreshToken: string) {
|
||||
const response = await apiClient.post<ApiResponse<LoginResponseData>>("/api/auth/refresh", {
|
||||
refreshToken
|
||||
});
|
||||
const payload = response.data;
|
||||
if (!payload.success) throw new Error(payload.message);
|
||||
return payload.data;
|
||||
}
|
||||
|
||||
export async function logout() {
|
||||
await unwrap<null>(apiClient.post<ApiResponse<null>>("/api/auth/logout"));
|
||||
}
|
||||
|
||||
export async function getCurrentUser(): Promise<ApiResponse<UserProfile>> {
|
||||
const response = await apiClient.get<ApiResponse<UserProfile>>("/api/users/me");
|
||||
return response.data;
|
||||
}
|
||||
|
||||
export async function getTenantContext(): Promise<TenantContextResponse> {
|
||||
const response = await apiClient.get<ApiResponse<TenantContextResponse>>("/api/tenant/context");
|
||||
if (!response.data.success) throw new Error(response.data.message);
|
||||
return response.data.data;
|
||||
}
|
||||
15
services/modules.ts
Normal file
15
services/modules.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { ApiResponse, ModuleItem, ToggleModuleRequest } from "@/types/api";
|
||||
import { apiClient } from "./api";
|
||||
|
||||
export async function getModules(): Promise<ModuleItem[]> {
|
||||
const response = await apiClient.get<ApiResponse<ModuleItem[]>>("/api/modules");
|
||||
if (!response.data.success) throw new Error(response.data.message);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
export async function toggleModule(code: string, payload: ToggleModuleRequest): Promise<ModuleItem> {
|
||||
const response = await apiClient.post<ApiResponse<ModuleItem>>(`/api/modules/${code}/toggle`, payload);
|
||||
const data = response.data;
|
||||
if (!data.success) throw new Error(data.message);
|
||||
return data.data;
|
||||
}
|
||||
24
services/roles.ts
Normal file
24
services/roles.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { ApiResponse, RoleCreateRequest, UpdateRolePermissionRequest, WorkflowRequestItem } from "@/types/api";
|
||||
import { apiClient } from "./api";
|
||||
|
||||
export async function createRoleRequest(payload: RoleCreateRequest): Promise<WorkflowRequestItem> {
|
||||
const response = await apiClient.post<ApiResponse<WorkflowRequestItem>>(
|
||||
"/api/roles/management/requests/create",
|
||||
payload
|
||||
);
|
||||
const data = response.data;
|
||||
if (!data.success) throw new Error(data.message);
|
||||
return data.data;
|
||||
}
|
||||
|
||||
export async function updateRolePermissionRequest(
|
||||
payload: UpdateRolePermissionRequest
|
||||
): Promise<WorkflowRequestItem> {
|
||||
const response = await apiClient.post<ApiResponse<WorkflowRequestItem>>(
|
||||
"/api/roles/management/requests/update-permissions",
|
||||
payload
|
||||
);
|
||||
const data = response.data;
|
||||
if (!data.success) throw new Error(data.message);
|
||||
return data.data;
|
||||
}
|
||||
8
services/tenant.ts
Normal file
8
services/tenant.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { ApiResponse, TenantContextResponse } from "@/types/api";
|
||||
import { apiClient } from "./api";
|
||||
|
||||
export async function getTenantContext(): Promise<TenantContextResponse> {
|
||||
const response = await apiClient.get<ApiResponse<TenantContextResponse>>("/api/tenant/context");
|
||||
if (!response.data.success) throw new Error(response.data.message);
|
||||
return response.data.data;
|
||||
}
|
||||
22
services/users.ts
Normal file
22
services/users.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { ApiResponse, UpdateUserRolesRequest, UserCreateRequest, WorkflowRequestItem, WorkflowCreateRequest } from "@/types/api";
|
||||
import { apiClient, unwrap } from "./api";
|
||||
|
||||
export async function createUserRequest(payload: UserCreateRequest): Promise<WorkflowRequestItem> {
|
||||
const response = await apiClient.post<ApiResponse<WorkflowRequestItem>>(
|
||||
"/api/users/management/requests/create",
|
||||
payload
|
||||
);
|
||||
const data = response.data;
|
||||
if (!data.success) throw new Error(data.message);
|
||||
return data.data;
|
||||
}
|
||||
|
||||
export async function updateUserRolesRequest(payload: UpdateUserRolesRequest): Promise<WorkflowRequestItem> {
|
||||
const response = await apiClient.post<ApiResponse<WorkflowRequestItem>>(
|
||||
"/api/users/management/requests/update-roles",
|
||||
payload
|
||||
);
|
||||
const data = response.data;
|
||||
if (!data.success) throw new Error(data.message);
|
||||
return data.data;
|
||||
}
|
||||
43
services/workflow.ts
Normal file
43
services/workflow.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import {
|
||||
ApiResponse,
|
||||
WorkflowActionPayload,
|
||||
WorkflowCreateRequest,
|
||||
WorkflowFilters,
|
||||
WorkflowRequestItem
|
||||
} from "@/types/api";
|
||||
import { apiClient } from "./api";
|
||||
|
||||
export async function getWorkflowRequests(filters: WorkflowFilters = {}): Promise<WorkflowRequestItem[]> {
|
||||
const response = await apiClient.get<ApiResponse<WorkflowRequestItem[]>>("/api/workflow/requests", {
|
||||
params: filters
|
||||
});
|
||||
if (!response.data.success) throw new Error(response.data.message);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
export async function createWorkflowRequest(payload: WorkflowCreateRequest): Promise<WorkflowRequestItem> {
|
||||
const response = await apiClient.post<ApiResponse<WorkflowRequestItem>>("/api/workflow/request", payload);
|
||||
const data = response.data;
|
||||
if (!data.success) throw new Error(data.message);
|
||||
return data.data;
|
||||
}
|
||||
|
||||
export async function approveWorkflowRequest(id: string, payload: WorkflowActionPayload): Promise<WorkflowRequestItem> {
|
||||
const response = await apiClient.post<ApiResponse<WorkflowRequestItem>>(
|
||||
`/api/workflow/${id}/approve`,
|
||||
payload
|
||||
);
|
||||
const data = response.data;
|
||||
if (!data.success) throw new Error(data.message);
|
||||
return data.data;
|
||||
}
|
||||
|
||||
export async function rejectWorkflowRequest(id: string, payload: WorkflowActionPayload): Promise<WorkflowRequestItem> {
|
||||
const response = await apiClient.post<ApiResponse<WorkflowRequestItem>>(
|
||||
`/api/workflow/${id}/reject`,
|
||||
payload
|
||||
);
|
||||
const data = response.data;
|
||||
if (!data.success) throw new Error(data.message);
|
||||
return data.data;
|
||||
}
|
||||
Reference in New Issue
Block a user