feat(WEB): 작업지시 수정 페이지 및 생산 관리 기능 개선
신규 기능: - 작업지시 수정 페이지 추가 (/production/work-orders/[id]/edit) - WorkOrderEdit 컴포넌트 신규 생성 - bulk-actions.ts 일괄 작업 유틸리티 추가 - toast-utils.ts 알림 유틸리티 추가 기능 개선: - ProductionDashboard 대시보드 액션 및 표시 개선 - WorkOrderCreate 생성 화면 개선 - WorkResultList 작업 결과 목록 타입 및 표시 개선 - EstimateDetailForm 견적 폼 개선 - QuoteRegistration 견적 등록 개선 - client-management-sales-admin 거래처 관리 개선 - error-handler.ts 에러 처리 개선
This commit is contained in:
@@ -104,14 +104,31 @@ export const handleApiError = async (response: Response): Promise<never> => {
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 디버그 모드 설정
|
||||
* - true: 에러 코드 표시 (개발/테스트)
|
||||
* - false: 메시지만 표시 (프로덕션)
|
||||
*
|
||||
* TODO: 프로덕션 배포 시 false로 변경하거나 환경변수 사용
|
||||
*/
|
||||
const SHOW_ERROR_CODE = true;
|
||||
|
||||
/**
|
||||
* 에러 객체에서 사용자 친화적인 메시지 추출
|
||||
* @param error - 발생한 에러 객체 (ApiError, Error, unknown)
|
||||
* @param includeCode - 에러 코드 포함 여부 (기본값: SHOW_ERROR_CODE 설정 따름)
|
||||
* @returns 사용자에게 표시할 에러 메시지
|
||||
*/
|
||||
export const getErrorMessage = (error: unknown): string => {
|
||||
export const getErrorMessage = (error: unknown, includeCode?: boolean): string => {
|
||||
const showCode = includeCode ?? SHOW_ERROR_CODE;
|
||||
|
||||
if (error instanceof DuplicateCodeError) {
|
||||
return showCode
|
||||
? `[${error.status}] ${error.message} (코드: ${error.duplicateCode})`
|
||||
: error.message;
|
||||
}
|
||||
if (error instanceof ApiError) {
|
||||
return error.message;
|
||||
return showCode ? `[${error.status}] ${error.message}` : error.message;
|
||||
}
|
||||
if (error instanceof Error) {
|
||||
return error.message;
|
||||
|
||||
116
src/lib/api/toast-utils.ts
Normal file
116
src/lib/api/toast-utils.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* API 에러 토스트 유틸리티
|
||||
* - 개발 중 디버깅을 위해 에러 코드와 메시지를 함께 표시
|
||||
* - 나중에 프로덕션에서 코드 숨기려면 이 파일만 수정하면 됨
|
||||
*/
|
||||
import { toast } from 'sonner';
|
||||
import { ApiError, DuplicateCodeError, getErrorMessage } from './error-handler';
|
||||
|
||||
/**
|
||||
* 디버그 모드 설정
|
||||
* - true: 에러 코드 표시 (개발/테스트)
|
||||
* - false: 메시지만 표시 (프로덕션)
|
||||
*
|
||||
* TODO: 프로덕션 배포 시 false로 변경하거나 환경변수 사용
|
||||
*/
|
||||
const SHOW_ERROR_CODE = true;
|
||||
|
||||
/**
|
||||
* API 에러를 토스트로 표시
|
||||
* - ApiError: [상태코드] 메시지 형식
|
||||
* - DuplicateCodeError: 중복 코드 정보 포함
|
||||
* - 일반 Error: 메시지만 표시
|
||||
*
|
||||
* @param error - 발생한 에러 객체
|
||||
* @param fallbackMessage - 에러 메시지가 없을 때 표시할 기본 메시지
|
||||
*/
|
||||
export function toastApiError(
|
||||
error: unknown,
|
||||
fallbackMessage = '오류가 발생했습니다.'
|
||||
): void {
|
||||
// DuplicateCodeError - 중복 코드 에러 (별도 처리 필요할 수 있음)
|
||||
if (error instanceof DuplicateCodeError) {
|
||||
const message = SHOW_ERROR_CODE
|
||||
? `[${error.status}] ${error.message} (코드: ${error.duplicateCode})`
|
||||
: error.message;
|
||||
toast.error(message);
|
||||
return;
|
||||
}
|
||||
|
||||
// ApiError - HTTP 에러
|
||||
if (error instanceof ApiError) {
|
||||
const message = SHOW_ERROR_CODE
|
||||
? `[${error.status}] ${error.message}`
|
||||
: error.message;
|
||||
|
||||
// Validation 에러가 있으면 첫 번째 에러도 표시
|
||||
if (error.errors && SHOW_ERROR_CODE) {
|
||||
const firstErrorField = Object.keys(error.errors)[0];
|
||||
if (firstErrorField) {
|
||||
const firstError = error.errors[firstErrorField][0];
|
||||
toast.error(`${message}\n${firstErrorField}: ${firstError}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
toast.error(message);
|
||||
return;
|
||||
}
|
||||
|
||||
// 일반 Error
|
||||
if (error instanceof Error) {
|
||||
toast.error(error.message || fallbackMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
// unknown 타입
|
||||
toast.error(fallbackMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* API 성공 토스트
|
||||
* - 일관된 성공 메시지 표시
|
||||
*
|
||||
* @param message - 성공 메시지
|
||||
*/
|
||||
export function toastSuccess(message: string): void {
|
||||
toast.success(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* API 경고 토스트
|
||||
*
|
||||
* @param message - 경고 메시지
|
||||
*/
|
||||
export function toastWarning(message: string): void {
|
||||
toast.warning(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* API 정보 토스트
|
||||
*
|
||||
* @param message - 정보 메시지
|
||||
*/
|
||||
export function toastInfo(message: string): void {
|
||||
toast.info(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 에러 메시지 포맷팅 (토스트 외 용도)
|
||||
* - 에러 코드 포함 여부는 SHOW_ERROR_CODE 설정 따름
|
||||
*
|
||||
* @param error - 발생한 에러 객체
|
||||
* @param fallbackMessage - 기본 메시지
|
||||
* @returns 포맷팅된 에러 메시지
|
||||
*/
|
||||
export function formatApiError(
|
||||
error: unknown,
|
||||
fallbackMessage = '오류가 발생했습니다.'
|
||||
): string {
|
||||
if (error instanceof ApiError) {
|
||||
return SHOW_ERROR_CODE
|
||||
? `[${error.status}] ${error.message}`
|
||||
: error.message;
|
||||
}
|
||||
return getErrorMessage(error) || fallbackMessage;
|
||||
}
|
||||
Reference in New Issue
Block a user