/** * Status Configuration Utility * * 상태 관련 설정(OPTIONS, LABELS, STYLES)을 단일 설정에서 생성하는 유틸리티 * * 사용 예시: * ```ts * const { STATUS_OPTIONS, STATUS_LABELS, STATUS_STYLES, getStatusLabel, getStatusStyle } = * createStatusConfig({ * pending: { label: '대기', style: 'warning' }, * completed: { label: '완료', style: 'success' }, * rejected: { label: '반려', style: 'destructive' }, * }, { includeAll: true, allLabel: '전체' }); * ``` */ // 프리셋 스타일 정의 export type StatusStylePreset = | 'default' | 'success' | 'warning' | 'destructive' | 'info' | 'muted' | 'orange' | 'purple'; // 프리셋 스타일 맵 (Badge 스타일 - 배경 + 텍스트) export const BADGE_STYLE_PRESETS: Record = { default: 'bg-gray-100 text-gray-800', success: 'bg-green-100 text-green-800', warning: 'bg-yellow-100 text-yellow-800', destructive: 'bg-red-100 text-red-800', info: 'bg-blue-100 text-blue-800', muted: 'bg-gray-100 text-gray-500', orange: 'bg-orange-100 text-orange-800', purple: 'bg-purple-100 text-purple-800', }; // 프리셋 스타일 맵 (Text 스타일 - 텍스트만) export const TEXT_STYLE_PRESETS: Record = { default: 'text-gray-600 font-medium', success: 'text-green-600 font-medium', warning: 'text-yellow-600 font-medium', destructive: 'text-red-500 font-medium', info: 'text-blue-500 font-medium', muted: 'text-gray-400 font-medium', orange: 'text-orange-500 font-medium', purple: 'text-purple-500 font-medium', }; // 단일 상태 설정 타입 export interface StatusItemConfig { /** 표시 라벨 */ label: string; /** 프리셋 스타일 또는 커스텀 클래스 */ style: StatusStylePreset | string; } // createStatusConfig 옵션 export interface CreateStatusConfigOptions { /** '전체' 옵션 포함 여부 (기본값: false) */ includeAll?: boolean; /** '전체' 옵션 라벨 (기본값: '전체') */ allLabel?: string; /** 스타일 모드: 'badge' (배경+텍스트) 또는 'text' (텍스트만) */ styleMode?: 'badge' | 'text'; } // 반환 타입 export interface StatusConfig { /** Select 컴포넌트용 옵션 배열 */ STATUS_OPTIONS: ReadonlyArray<{ value: T | 'all'; label: string }>; /** 상태별 라벨 맵 */ STATUS_LABELS: Record; /** 상태별 스타일 맵 */ STATUS_STYLES: Record; /** 상태값으로 라벨 가져오기 */ getStatusLabel: (status: T) => string; /** 상태값으로 스타일 가져오기 */ getStatusStyle: (status: T) => string; } /** * 상태 설정 생성 유틸리티 * * @param config - 상태별 설정 객체 * @param options - 추가 옵션 * @returns STATUS_OPTIONS, STATUS_LABELS, STATUS_STYLES 및 헬퍼 함수 */ export function createStatusConfig( config: Record, options: CreateStatusConfigOptions = {} ): StatusConfig { const { includeAll = false, allLabel = '전체', styleMode = 'badge' } = options; const stylePresets = styleMode === 'badge' ? BADGE_STYLE_PRESETS : TEXT_STYLE_PRESETS; // STATUS_LABELS 생성 const STATUS_LABELS = Object.entries(config).reduce( (acc, [key, value]) => { acc[key as T] = (value as StatusItemConfig).label; return acc; }, {} as Record ); // STATUS_STYLES 생성 const STATUS_STYLES = Object.entries(config).reduce( (acc, [key, value]) => { const { style } = value as StatusItemConfig; // 프리셋 스타일이면 변환, 아니면 커스텀 클래스 그대로 사용 acc[key as T] = style in stylePresets ? stylePresets[style as StatusStylePreset] : style; return acc; }, {} as Record ); // STATUS_OPTIONS 생성 const statusOptions = Object.entries(config).map(([key, value]) => ({ value: key as T, label: (value as StatusItemConfig).label, })); const STATUS_OPTIONS = includeAll ? [{ value: 'all' as const, label: allLabel }, ...statusOptions] : statusOptions; // 헬퍼 함수 const getStatusLabel = (status: T): string => STATUS_LABELS[status] || status; const getStatusStyle = (status: T): string => STATUS_STYLES[status] || ''; return { STATUS_OPTIONS: STATUS_OPTIONS as ReadonlyArray<{ value: T | 'all'; label: string }>, STATUS_LABELS, STATUS_STYLES, getStatusLabel, getStatusStyle, }; } /** * 프리셋 스타일을 CSS 클래스로 변환하는 헬퍼 */ export function getPresetStyle( preset: StatusStylePreset, mode: 'badge' | 'text' = 'badge' ): string { const presets = mode === 'badge' ? BADGE_STYLE_PRESETS : TEXT_STYLE_PRESETS; return presets[preset] || presets.default; } export default createStatusConfig;