diff --git a/package-lock.json b/package-lock.json index 0d31579..8203033 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,7 @@ "recharts": "^3.2.0", "sockjs-client": "^1.6.1", "tailwindcss": "^4.1.12", + "wx-gantt-data-provider": "^2.2.1", "wx-react-gantt": "^1.3.1", "zustand": "^5.0.8" }, @@ -5403,6 +5404,21 @@ "node": ">=0.10.0" } }, + "node_modules/wx-gantt-data-provider": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/wx-gantt-data-provider/-/wx-gantt-data-provider-2.2.1.tgz", + "integrity": "sha512-uNFFCtXSSwlkRQQuFm8LI7sZ1+HEatY/ND40fSxX4LLSUeYHcIeOZcFfFI8ImCsW7M7Q7QG0r7n/8vrll4xamw==", + "license": "MIT", + "dependencies": { + "wx-lib-data-provider": "1.5.1" + } + }, + "node_modules/wx-lib-data-provider": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/wx-lib-data-provider/-/wx-lib-data-provider-1.5.1.tgz", + "integrity": "sha512-ebKYlnmXOuwgQ/812Ux06Uz7tIG3P8euUHB0/hwhL0+Buged+00uFII3bkXQ7jh5DbsTugFqPlzlKTJFQ2l0TA==", + "license": "MIT" + }, "node_modules/wx-react-gantt": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/wx-react-gantt/-/wx-react-gantt-1.3.1.tgz", diff --git a/package.json b/package.json index fc78787..945b272 100644 --- a/package.json +++ b/package.json @@ -22,17 +22,18 @@ "@tanstack/react-table": "^8.21.3", "axios": "^1.12.1", "dayjs": "^1.11.18", + "lodash": "^4.17.21", "react": "^18.3.1", "react-big-calendar": "^1.19.4", "react-dom": "^18.3.1", "react-error-boundary": "^6.0.0", "react-router-dom": "^7.8.2", - "sockjs-client": "^1.6.1", "recharts": "^3.2.0", + "sockjs-client": "^1.6.1", "tailwindcss": "^4.1.12", + "wx-gantt-data-provider": "^2.2.1", "wx-react-gantt": "^1.3.1", - "zustand": "^5.0.8", - "lodash": "^4.17.21" + "zustand": "^5.0.8" }, "devDependencies": { "@eslint/js": "^9.33.0", diff --git a/src/components/common/ErrorBoundary.jsx b/src/components/common/ErrorBoundary.jsx new file mode 100644 index 0000000..fc61bb6 --- /dev/null +++ b/src/components/common/ErrorBoundary.jsx @@ -0,0 +1,72 @@ +import React from 'react'; +import { AlertTriangle, RefreshCw } from '@mui/icons-material'; + +class ErrorBoundary extends React.Component { + constructor(props) { + super(props); + this.state = { hasError: false, error: null, errorInfo: null }; + } + + static getDerivedStateFromError() { + // 다음 렌더링에서 폴백 UI가 보이도록 상태를 업데이트 합니다. + return { hasError: true }; + } + + componentDidCatch(error, errorInfo) { + // 에러 리포팅 서비스에 에러를 기록할 수도 있습니다 + console.error('ErrorBoundary caught an error:', error, errorInfo); + this.setState({ + error: error, + errorInfo: errorInfo + }); + } + + handleRetry = () => { + this.setState({ hasError: false, error: null, errorInfo: null }); + }; + + render() { + if (this.state.hasError) { + // 커스텀 에러 UI를 렌더링할 수 있습니다 + return ( +
+ {this.props.message || '컴포넌트를 로드하는 중 문제가 발생했습니다.'} +
+ + {import.meta.env.DEV && this.state.error && ( +
+ {this.state.errorInfo.componentStack}
+
+