167 lines
4.7 KiB
TypeScript
167 lines
4.7 KiB
TypeScript
|
|
"use client";
|
||
|
|
|
||
|
|
import { useQuery } from "@tanstack/react-query";
|
||
|
|
import { WebTypeStandard } from "./admin/useWebTypes";
|
||
|
|
import { ButtonActionStandard } from "./admin/useButtonActions";
|
||
|
|
|
||
|
|
// API 응답 인터페이스
|
||
|
|
interface ApiResponse<T> {
|
||
|
|
success: boolean;
|
||
|
|
data?: T;
|
||
|
|
message?: string;
|
||
|
|
error?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 쿼리 파라미터 인터페이스
|
||
|
|
interface ScreenStandardQueryParams {
|
||
|
|
active?: string;
|
||
|
|
category?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 화면관리에서 사용할 표준 정보 조회 훅
|
||
|
|
* 관리 페이지와 달리 읽기 전용으로 사용
|
||
|
|
*/
|
||
|
|
export const useScreenStandards = () => {
|
||
|
|
// 활성화된 웹타입 조회
|
||
|
|
const {
|
||
|
|
data: webTypes,
|
||
|
|
isLoading: isLoadingWebTypes,
|
||
|
|
error: webTypesError,
|
||
|
|
} = useQuery({
|
||
|
|
queryKey: ["screenStandards", "webTypes"],
|
||
|
|
queryFn: async (): Promise<WebTypeStandard[]> => {
|
||
|
|
const response = await fetch("/api/screen/web-types?active=Y", {
|
||
|
|
headers: {
|
||
|
|
Authorization: `Bearer ${localStorage.getItem("token")}`,
|
||
|
|
"Content-Type": "application/json",
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
if (!response.ok) {
|
||
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||
|
|
}
|
||
|
|
|
||
|
|
const result: ApiResponse<WebTypeStandard[]> = await response.json();
|
||
|
|
|
||
|
|
if (!result.success) {
|
||
|
|
throw new Error(result.error || "Failed to fetch web types");
|
||
|
|
}
|
||
|
|
|
||
|
|
return result.data || [];
|
||
|
|
},
|
||
|
|
staleTime: 10 * 60 * 1000, // 10분간 캐시 유지 (관리 페이지보다 길게)
|
||
|
|
cacheTime: 30 * 60 * 1000, // 30분간 메모리 보관
|
||
|
|
});
|
||
|
|
|
||
|
|
// 활성화된 버튼 액션 조회
|
||
|
|
const {
|
||
|
|
data: buttonActions,
|
||
|
|
isLoading: isLoadingButtonActions,
|
||
|
|
error: buttonActionsError,
|
||
|
|
} = useQuery({
|
||
|
|
queryKey: ["screenStandards", "buttonActions"],
|
||
|
|
queryFn: async (): Promise<ButtonActionStandard[]> => {
|
||
|
|
const response = await fetch("/api/screen/button-actions?active=Y", {
|
||
|
|
headers: {
|
||
|
|
Authorization: `Bearer ${localStorage.getItem("token")}`,
|
||
|
|
"Content-Type": "application/json",
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
if (!response.ok) {
|
||
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||
|
|
}
|
||
|
|
|
||
|
|
const result: ApiResponse<ButtonActionStandard[]> = await response.json();
|
||
|
|
|
||
|
|
if (!result.success) {
|
||
|
|
throw new Error(result.error || "Failed to fetch button actions");
|
||
|
|
}
|
||
|
|
|
||
|
|
return result.data || [];
|
||
|
|
},
|
||
|
|
staleTime: 10 * 60 * 1000, // 10분간 캐시 유지
|
||
|
|
cacheTime: 30 * 60 * 1000, // 30분간 메모리 보관
|
||
|
|
});
|
||
|
|
|
||
|
|
// 웹타입 카테고리별 그룹화
|
||
|
|
const webTypesByCategory =
|
||
|
|
webTypes?.reduce((acc, webType) => {
|
||
|
|
if (!acc[webType.category]) {
|
||
|
|
acc[webType.category] = [];
|
||
|
|
}
|
||
|
|
acc[webType.category].push(webType);
|
||
|
|
return acc;
|
||
|
|
}, {} as Record<string, WebTypeStandard[]>) || {};
|
||
|
|
|
||
|
|
// 버튼 액션 카테고리별 그룹화
|
||
|
|
const buttonActionsByCategory =
|
||
|
|
buttonActions?.reduce((acc, action) => {
|
||
|
|
if (!acc[action.category]) {
|
||
|
|
acc[action.category] = [];
|
||
|
|
}
|
||
|
|
acc[action.category].push(action);
|
||
|
|
return acc;
|
||
|
|
}, {} as Record<string, ButtonActionStandard[]>) || {};
|
||
|
|
|
||
|
|
// 웹타입 드롭다운 옵션 생성
|
||
|
|
const webTypeOptions =
|
||
|
|
webTypes?.map((webType) => ({
|
||
|
|
value: webType.web_type,
|
||
|
|
label: webType.type_name,
|
||
|
|
labelEng: webType.type_name_eng,
|
||
|
|
category: webType.category,
|
||
|
|
description: webType.description,
|
||
|
|
})) || [];
|
||
|
|
|
||
|
|
// 버튼 액션 드롭다운 옵션 생성
|
||
|
|
const buttonActionOptions =
|
||
|
|
buttonActions?.map((action) => ({
|
||
|
|
value: action.action_type,
|
||
|
|
label: action.action_name,
|
||
|
|
labelEng: action.action_name_eng,
|
||
|
|
category: action.category,
|
||
|
|
description: action.description,
|
||
|
|
icon: action.default_icon,
|
||
|
|
color: action.default_color,
|
||
|
|
variant: action.default_variant,
|
||
|
|
})) || [];
|
||
|
|
|
||
|
|
return {
|
||
|
|
// 원본 데이터
|
||
|
|
webTypes: webTypes || [],
|
||
|
|
buttonActions: buttonActions || [],
|
||
|
|
|
||
|
|
// 그룹화된 데이터
|
||
|
|
webTypesByCategory,
|
||
|
|
buttonActionsByCategory,
|
||
|
|
|
||
|
|
// 드롭다운 옵션
|
||
|
|
webTypeOptions,
|
||
|
|
buttonActionOptions,
|
||
|
|
|
||
|
|
// 로딩 상태
|
||
|
|
isLoading: isLoadingWebTypes || isLoadingButtonActions,
|
||
|
|
isLoadingWebTypes,
|
||
|
|
isLoadingButtonActions,
|
||
|
|
|
||
|
|
// 에러
|
||
|
|
error: webTypesError || buttonActionsError,
|
||
|
|
webTypesError,
|
||
|
|
buttonActionsError,
|
||
|
|
|
||
|
|
// 유틸리티 메서드
|
||
|
|
getWebType: (webType: string) =>
|
||
|
|
webTypes?.find((w) => w.web_type === webType),
|
||
|
|
getButtonAction: (actionType: string) =>
|
||
|
|
buttonActions?.find((a) => a.action_type === actionType),
|
||
|
|
getWebTypesByCategory: (category: string) =>
|
||
|
|
webTypesByCategory[category] || [],
|
||
|
|
getButtonActionsByCategory: (category: string) =>
|
||
|
|
buttonActionsByCategory[category] || [],
|
||
|
|
};
|
||
|
|
};
|
||
|
|
|
||
|
|
|