229 lines
6.8 KiB
TypeScript
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"] });
|
|
},
|
|
});
|
|
};
|