ERP-node/frontend/hooks/admin/useComponents.ts

229 lines
6.8 KiB
TypeScript

"use client";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { apiClient } from "@/lib/api/client";
// 컴포넌트 표준 타입 정의
export interface ComponentStandard {
component_code: string;
component_name: string;
component_name_eng?: string;
description?: string;
category: string;
icon_name?: string;
default_size?: { width: number; height: number };
component_config: any;
preview_image?: string;
sort_order?: number;
is_active?: string;
is_public?: string;
company_code: string;
created_date?: string;
created_by?: string;
updated_date?: string;
updated_by?: string;
}
export interface ComponentQueryParams {
category?: string;
active?: string;
is_public?: string;
search?: string;
sort?: string;
order?: "asc" | "desc";
limit?: number;
offset?: number;
}
export interface ComponentListResponse {
components: ComponentStandard[];
total: number;
limit?: number;
offset?: number;
}
export interface ApiResponse<T> {
success: boolean;
data: T;
message: string;
}
// API 함수들
const componentApi = {
// 컴포넌트 목록 조회
getComponents: async (params: ComponentQueryParams = {}): Promise<ComponentListResponse> => {
const searchParams = new URLSearchParams();
Object.entries(params).forEach(([key, value]) => {
if (value !== undefined && value !== "") {
searchParams.append(key, value.toString());
}
});
const response = await apiClient.get<ApiResponse<ComponentListResponse>>(
`/admin/component-standards?${searchParams.toString()}`,
);
return response.data.data;
},
// 컴포넌트 상세 조회
getComponent: async (component_code: string): Promise<ComponentStandard> => {
const response = await apiClient.get<ApiResponse<ComponentStandard>>(
`/admin/component-standards/${component_code}`,
);
return response.data.data;
},
// 컴포넌트 생성
createComponent: async (data: Partial<ComponentStandard>): Promise<ComponentStandard> => {
const response = await apiClient.post<ApiResponse<ComponentStandard>>("/admin/component-standards", data);
return response.data.data;
},
// 컴포넌트 수정
updateComponent: async (component_code: string, data: Partial<ComponentStandard>): Promise<ComponentStandard> => {
const response = await apiClient.put<ApiResponse<ComponentStandard>>(
`/admin/component-standards/${component_code}`,
data,
);
return response.data.data;
},
// 컴포넌트 삭제
deleteComponent: async (component_code: string): Promise<void> => {
await apiClient.delete(`/admin/component-standards/${component_code}`);
},
// 정렬 순서 업데이트
updateSortOrder: async (updates: Array<{ component_code: string; sort_order: number }>): Promise<void> => {
await apiClient.put("/admin/component-standards/sort/order", { updates });
},
// 컴포넌트 복제
duplicateComponent: async (data: {
source_code: string;
new_code: string;
new_name: string;
}): Promise<ComponentStandard> => {
const response = await apiClient.post<ApiResponse<ComponentStandard>>("/admin/component-standards/duplicate", data);
return response.data.data;
},
// 카테고리 목록 조회
getCategories: async (): Promise<string[]> => {
const response = await apiClient.get<ApiResponse<string[]>>("/admin/component-standards/categories");
return response.data.data;
},
// 통계 조회
getStatistics: async (): Promise<{
total: number;
byCategory: Array<{ category: string; count: number }>;
byStatus: Array<{ status: string; count: number }>;
}> => {
const response = await apiClient.get<ApiResponse<any>>("/admin/component-standards/statistics");
return response.data.data;
},
};
// React Query 훅들
export const useComponents = (params: ComponentQueryParams = {}) => {
return useQuery({
queryKey: ["components", params],
queryFn: () => componentApi.getComponents(params),
staleTime: 5 * 60 * 1000, // 5분
});
};
export const useComponent = (component_code: string) => {
return useQuery({
queryKey: ["component", component_code],
queryFn: () => componentApi.getComponent(component_code),
enabled: !!component_code,
});
};
export const useComponentCategories = () => {
return useQuery({
queryKey: ["component-categories"],
queryFn: componentApi.getCategories,
staleTime: 10 * 60 * 1000, // 10분
});
};
export const useComponentStatistics = () => {
return useQuery({
queryKey: ["component-statistics"],
queryFn: componentApi.getStatistics,
staleTime: 2 * 60 * 1000, // 2분
});
};
// Mutation 훅들
export const useCreateComponent = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: componentApi.createComponent,
onSuccess: () => {
// 컴포넌트 목록 새로고침
queryClient.invalidateQueries({ queryKey: ["components"] });
queryClient.invalidateQueries({ queryKey: ["component-categories"] });
queryClient.invalidateQueries({ queryKey: ["component-statistics"] });
},
});
};
export const useUpdateComponent = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ component_code, data }: { component_code: string; data: Partial<ComponentStandard> }) =>
componentApi.updateComponent(component_code, data),
onSuccess: (data, variables) => {
// 특정 컴포넌트와 목록 새로고침
queryClient.invalidateQueries({ queryKey: ["component", variables.component_code] });
queryClient.invalidateQueries({ queryKey: ["components"] });
queryClient.invalidateQueries({ queryKey: ["component-statistics"] });
},
});
};
export const useDeleteComponent = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: componentApi.deleteComponent,
onSuccess: () => {
// 컴포넌트 목록 새로고침
queryClient.invalidateQueries({ queryKey: ["components"] });
queryClient.invalidateQueries({ queryKey: ["component-categories"] });
queryClient.invalidateQueries({ queryKey: ["component-statistics"] });
},
});
};
export const useUpdateSortOrder = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: componentApi.updateSortOrder,
onSuccess: () => {
// 컴포넌트 목록 새로고침
queryClient.invalidateQueries({ queryKey: ["components"] });
},
});
};
export const useDuplicateComponent = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: componentApi.duplicateComponent,
onSuccess: () => {
// 컴포넌트 목록 새로고침
queryClient.invalidateQueries({ queryKey: ["components"] });
queryClient.invalidateQueries({ queryKey: ["component-statistics"] });
},
});
};