refactor: 로딩 스피너 표준화 및 프로젝트 헬스 개선

- LoadingSpinner 컴포넌트 5가지 변형 구현
  - LoadingSpinner (인라인/버튼용)
  - ContentLoadingSpinner (상세/수정 페이지)
  - PageLoadingSpinner (페이지 전환)
  - TableLoadingSpinner (테이블/리스트)
  - ButtonSpinner (버튼 내부)
- 18개+ 페이지 로딩 UI 표준화
  - HR 페이지 (사원, 휴가, 부서, 급여, 근태)
  - 영업 페이지 (견적, 거래처)
  - 게시판, 팝업관리, 품목기준정보
- API 키 보안 개선 (NEXT_PUBLIC_API_KEY → API_KEY)
- Textarea 다크모드 스타일 개선
- DropdownField Radix UI Select 버그 수정 (key prop)
- 프로젝트 헬스 개선 계획서 문서화

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
byeongcheolryu
2025-12-20 14:33:11 +09:00
parent c6b605200d
commit d7f491fa84
50 changed files with 666 additions and 246 deletions

View File

@@ -1,8 +1,7 @@
'use client';
import { useMemo } from 'react';
import { DynamicFormData, ItemType, StructuredFieldConfig } from '../types';
import { ItemFieldResponse } from '@/types/item';
import { DynamicFormData, ItemType, StructuredFieldConfig, ItemFieldResponse } from '../types';
/**
* 부품 유형 탐지 결과
@@ -27,7 +26,7 @@ export interface UseFieldDetectionParams {
/** 폼 구조 정보 */
structure: StructuredFieldConfig | null;
/** 현재 선택된 품목 유형 (FG, PT, SM, RM, CS) */
selectedItemType: ItemType;
selectedItemType: ItemType | '';
/** 현재 폼 데이터 */
formData: DynamicFormData;
}

View File

@@ -1,9 +1,9 @@
'use client';
import { useEffect, useRef } from 'react';
import { DynamicFormData, ItemType, StructuredFieldConfig } from '../types';
import { BendingFieldKeys, CategoryKeyWithId } from './useItemCodeGeneration';
import { BendingDetail } from '@/types/item';
import type { DynamicFormData, DynamicFieldValue, ItemType, StructuredFieldConfig } from '../types';
import type { BendingFieldKeys, CategoryKeyWithId } from './useItemCodeGeneration';
import type { BendingDetail } from '@/types/item';
/**
* usePartTypeHandling 훅 입력 파라미터
@@ -20,7 +20,7 @@ export interface UsePartTypeHandlingParams {
/** 품목명 필드 키 */
itemNameKey: string;
/** 필드 값 설정 함수 */
setFieldValue: (key: string, value: unknown) => void;
setFieldValue: (key: string, value: DynamicFieldValue) => void;
/** 현재 폼 데이터 */
formData: DynamicFormData;
/** 절곡부품 필드 키 정보 */