Visual edit in Lovable
Edited UI in Lovable
This commit is contained in:
84
src/App.tsx
84
src/App.tsx
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
|
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
|
||||||
import { SplashScreen } from '@capacitor/splash-screen';
|
import { SplashScreen } from '@capacitor/splash-screen';
|
||||||
@@ -27,27 +26,36 @@ const handleError = (error: Error | unknown) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 오류 경계 컴포넌트
|
// 오류 경계 컴포넌트
|
||||||
class ErrorBoundary extends React.Component<
|
class ErrorBoundary extends React.Component<{
|
||||||
{ children: React.ReactNode },
|
children: React.ReactNode;
|
||||||
{ hasError: boolean; error: Error | null }
|
}, {
|
||||||
> {
|
hasError: boolean;
|
||||||
constructor(props: { children: React.ReactNode }) {
|
error: Error | null;
|
||||||
|
}> {
|
||||||
|
constructor(props: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = { hasError: false, error: null };
|
this.state = {
|
||||||
|
hasError: false,
|
||||||
|
error: null
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static getDerivedStateFromError(error: Error) {
|
static getDerivedStateFromError(error: Error) {
|
||||||
return { hasError: true, error };
|
return {
|
||||||
|
hasError: true,
|
||||||
|
error
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
|
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
|
||||||
handleError({ error, errorInfo });
|
handleError({
|
||||||
|
error,
|
||||||
|
errorInfo
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.state.hasError) {
|
if (this.state.hasError) {
|
||||||
return (
|
return <div className="min-h-screen flex items-center justify-center p-4 bg-gray-50">
|
||||||
<div className="min-h-screen flex items-center justify-center p-4 bg-gray-50">
|
|
||||||
<div className="bg-white p-8 rounded-lg shadow-lg max-w-md w-full">
|
<div className="bg-white p-8 rounded-lg shadow-lg max-w-md w-full">
|
||||||
<h1 className="text-2xl font-bold text-red-600 mb-4">오류가 발생했습니다</h1>
|
<h1 className="text-2xl font-bold text-red-600 mb-4">오류가 발생했습니다</h1>
|
||||||
<p className="text-gray-600 mb-4">
|
<p className="text-gray-600 mb-4">
|
||||||
@@ -56,21 +64,15 @@ class ErrorBoundary extends React.Component<
|
|||||||
<pre className="bg-gray-100 p-4 rounded text-xs overflow-auto max-h-40 mb-4">
|
<pre className="bg-gray-100 p-4 rounded text-xs overflow-auto max-h-40 mb-4">
|
||||||
{this.state.error?.message}
|
{this.state.error?.message}
|
||||||
</pre>
|
</pre>
|
||||||
<button
|
<button onClick={() => window.location.reload()} className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 w-full">
|
||||||
onClick={() => window.location.reload()}
|
|
||||||
className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 w-full"
|
|
||||||
>
|
|
||||||
페이지 새로고침
|
페이지 새로고침
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.props.children;
|
return this.props.children;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
// 앱 로딩이 완료되었을 때 스플래시 화면을 숨김
|
// 앱 로딩이 완료되었을 때 스플래시 화면을 숨김
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -90,46 +92,40 @@ function App() {
|
|||||||
console.error('앱 준비 오류:', err);
|
console.error('앱 준비 오류:', err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 앱 준비 함수 실행
|
// 앱 준비 함수 실행
|
||||||
onAppReady();
|
onAppReady();
|
||||||
|
|
||||||
// 추가 보호장치: 페이지 로드 시 다시 실행
|
// 추가 보호장치: 페이지 로드 시 다시 실행
|
||||||
const handleLoad = () => {
|
const handleLoad = () => {
|
||||||
// 즉시 스플래시 화면을 숨김 시도
|
// 즉시 스플래시 화면을 숨김 시도
|
||||||
SplashScreen.hide().catch(() => {});
|
SplashScreen.hide().catch(() => {});
|
||||||
|
|
||||||
// 백업 시도
|
// 백업 시도
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
SplashScreen.hide().catch(() => {});
|
SplashScreen.hide().catch(() => {});
|
||||||
}, 300);
|
}, 300);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('load', handleLoad);
|
window.addEventListener('load', handleLoad);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('load', handleLoad);
|
window.removeEventListener('load', handleLoad);
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
return <ErrorBoundary>
|
||||||
return (
|
|
||||||
<ErrorBoundary>
|
|
||||||
<AuthContextWrapper>
|
<AuthContextWrapper>
|
||||||
<BudgetProvider>
|
<BudgetProvider>
|
||||||
<Router>
|
<Router>
|
||||||
<div className="flex flex-col min-h-screen">
|
<div className="flex flex-col min-h-screen">
|
||||||
<div className="pt-[10px]"></div> {/* 상단 여백 5px에서 10px로 증가 */}
|
<div className="pt-[10px] py-[15px]"></div> {/* 상단 여백 5px에서 10px로 증가 */}
|
||||||
<NavBar />
|
<NavBar />
|
||||||
<div className="flex-grow">
|
<div className="flex-grow">
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<Index />} />
|
<Route path="/" element={<Index />} />
|
||||||
<Route path="/login" element={<Login />} />
|
<Route path="/login" element={<Login />} />
|
||||||
<Route path="/register" element={<Register />} />
|
<Route path="/register" element={<Register />} />
|
||||||
<Route path="/profile" element={
|
<Route path="/profile" element={<PrivateRoute>
|
||||||
<PrivateRoute>
|
|
||||||
<ProfileManagement />
|
<ProfileManagement />
|
||||||
</PrivateRoute>
|
</PrivateRoute>} />
|
||||||
} />
|
|
||||||
<Route path="/settings" element={<Settings />} />
|
<Route path="/settings" element={<Settings />} />
|
||||||
{/* 지출 페이지는 더 이상 인증이 필요하지 않음 */}
|
{/* 지출 페이지는 더 이상 인증이 필요하지 않음 */}
|
||||||
<Route path="/transactions" element={<Transactions />} />
|
<Route path="/transactions" element={<Transactions />} />
|
||||||
@@ -137,18 +133,14 @@ function App() {
|
|||||||
<Route path="/analytics" element={<Analytics />} />
|
<Route path="/analytics" element={<Analytics />} />
|
||||||
{/* 보안 및 개인정보 페이지도 로그인 없이 접근 가능하도록 수정 */}
|
{/* 보안 및 개인정보 페이지도 로그인 없이 접근 가능하도록 수정 */}
|
||||||
<Route path="/security-privacy" element={<SecurityPrivacySettings />} />
|
<Route path="/security-privacy" element={<SecurityPrivacySettings />} />
|
||||||
<Route path="/notifications" element={
|
<Route path="/notifications" element={<PrivateRoute>
|
||||||
<PrivateRoute>
|
|
||||||
<NotificationSettings />
|
<NotificationSettings />
|
||||||
</PrivateRoute>
|
</PrivateRoute>} />
|
||||||
} />
|
|
||||||
<Route path="/help-support" element={<HelpSupport />} />
|
<Route path="/help-support" element={<HelpSupport />} />
|
||||||
<Route path="/forgot-password" element={<ForgotPassword />} />
|
<Route path="/forgot-password" element={<ForgotPassword />} />
|
||||||
<Route path="/payment-methods" element={
|
<Route path="/payment-methods" element={<PrivateRoute>
|
||||||
<PrivateRoute>
|
|
||||||
<PaymentMethods />
|
<PaymentMethods />
|
||||||
</PrivateRoute>
|
</PrivateRoute>} />
|
||||||
} />
|
|
||||||
<Route path="*" element={<NotFound />} />
|
<Route path="*" element={<NotFound />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</div>
|
</div>
|
||||||
@@ -157,8 +149,6 @@ function App() {
|
|||||||
</Router>
|
</Router>
|
||||||
</BudgetProvider>
|
</BudgetProvider>
|
||||||
</AuthContextWrapper>
|
</AuthContextWrapper>
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
export default App;
|
||||||
export default App;
|
|
||||||
Reference in New Issue
Block a user