From 1676fb1649dbe715069af032ff1f09b91a5c65b8 Mon Sep 17 00:00:00 2001
From: "gpt-engineer-app[bot]"
<159125892+gpt-engineer-app[bot]@users.noreply.github.com>
Date: Sat, 15 Mar 2025 05:17:38 +0000
Subject: [PATCH] Fix display issue
Addresses a problem where the screen was not displaying correctly.
---
src/App.tsx | 121 ++++++++++++++++++------
src/components/SyncSettings.tsx | 159 +++++++++++++++++---------------
src/utils/sync/syncSettings.ts | 10 ++
src/utils/syncUtils.ts | 23 +++--
4 files changed, 205 insertions(+), 108 deletions(-)
diff --git a/src/App.tsx b/src/App.tsx
index 00f637c..bf499c5 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -4,6 +4,7 @@ import { Toaster as Sonner } from "@/components/ui/sonner";
import { TooltipProvider } from "@/components/ui/tooltip";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { BrowserRouter, Routes, Route } from "react-router-dom";
+import { useState, useEffect } from "react";
import Index from "./pages/Index";
import Transactions from "./pages/Transactions";
import Analytics from "./pages/Analytics";
@@ -18,32 +19,100 @@ import Login from "./pages/Login";
import Register from "./pages/Register";
import ForgotPassword from "./pages/ForgotPassword";
-const queryClient = new QueryClient();
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ retry: 1,
+ refetchOnWindowFocus: false,
+ },
+ },
+});
-const App = () => (
-
-
-
-
-
-
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
-
-
-
-
-);
+const App = () => {
+ const [isLoaded, setIsLoaded] = useState(false);
+
+ useEffect(() => {
+ // 애플리케이션 초기화 및 로딩 상태 관리
+ try {
+ // 기본 예산 데이터 초기화
+ if (!localStorage.getItem('budgetData')) {
+ const defaultBudgetData = {
+ daily: {
+ targetAmount: 40000,
+ spentAmount: 0,
+ remainingAmount: 40000
+ },
+ weekly: {
+ targetAmount: 280000,
+ spentAmount: 0,
+ remainingAmount: 280000
+ },
+ monthly: {
+ targetAmount: 1200000,
+ spentAmount: 0,
+ remainingAmount: 1200000
+ }
+ };
+ localStorage.setItem('budgetData', JSON.stringify(defaultBudgetData));
+ }
+
+ // 기본 카테고리 예산 설정
+ if (!localStorage.getItem('categoryBudgets')) {
+ const defaultCategoryBudgets = {
+ 식비: 400000,
+ 생활비: 600000,
+ 교통비: 200000
+ };
+ localStorage.setItem('categoryBudgets', JSON.stringify(defaultCategoryBudgets));
+ }
+
+ // 빈 트랜잭션 배열 초기화
+ if (!localStorage.getItem('transactions')) {
+ localStorage.setItem('transactions', JSON.stringify([]));
+ }
+
+ setIsLoaded(true);
+ } catch (error) {
+ console.error('앱 초기화 중 오류 발생:', error);
+ // 오류가 발생해도 앱 로딩
+ setIsLoaded(true);
+ }
+ }, []);
+
+ if (!isLoaded) {
+ return
;
+ }
+
+ return (
+
+
+
+
+
+
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
+
+
+ );
+};
export default App;
diff --git a/src/components/SyncSettings.tsx b/src/components/SyncSettings.tsx
index fa15b34..c06cb47 100644
--- a/src/components/SyncSettings.tsx
+++ b/src/components/SyncSettings.tsx
@@ -1,121 +1,128 @@
import React, { useState, useEffect } from 'react';
-import { Button } from '@/components/ui/button';
-import { Switch } from '@/components/ui/switch';
-import { Label } from '@/components/ui/label';
-import { Loader2, CloudUpload } from 'lucide-react';
-import { isSyncEnabled, setSyncEnabled, syncAllData } from '@/utils/syncUtils';
-import { supabase } from '@/lib/supabase';
-import { toast } from '@/components/ui/use-toast';
+import { Switch } from "@/components/ui/switch";
+import { Label } from "@/components/ui/label";
+import { CloudUpload, RefreshCw } from "lucide-react";
+import { isSyncEnabled, setSyncEnabled, syncAllData, getLastSyncTime } from "@/utils/syncUtils";
+import { supabase } from "@/lib/supabase";
+import { toast } from "@/components/ui/use-toast";
const SyncSettings = () => {
- const [syncEnabled, setSyncEnabledState] = useState(isSyncEnabled());
- const [loading, setLoading] = useState(false);
- const [userId, setUserId] = useState(null);
-
+ const [enabled, setEnabled] = useState(isSyncEnabled());
+ const [user, setUser] = useState(null);
+ const [syncing, setSyncing] = useState(false);
+ const [lastSync, setLastSync] = useState(getLastSyncTime());
+
useEffect(() => {
- // 현재 로그인한 사용자 가져오기
+ // 사용자 정보 가져오기
const getUser = async () => {
- const { data: { user } } = await supabase.auth.getUser();
- setUserId(user?.id || null);
+ const { data } = await supabase.auth.getUser();
+ setUser(data.user);
};
-
getUser();
+
+ // 마지막 동기화 시간 업데이트
+ setLastSync(getLastSyncTime());
}, []);
-
- const handleSyncToggle = (checked: boolean) => {
- setSyncEnabledState(checked);
+
+ const handleSyncToggle = async (checked: boolean) => {
+ setEnabled(checked);
setSyncEnabled(checked);
- if (checked) {
- toast({
- title: "동기화 활성화됨",
- description: "데이터가 클라우드에 자동으로 백업됩니다.",
- });
- } else {
- toast({
- title: "동기화 비활성화됨",
- description: "데이터가 이 기기에만 저장됩니다.",
- });
+ if (checked && user) {
+ // 동기화 활성화 시 즉시 동기화 실행
+ try {
+ setSyncing(true);
+ await syncAllData(user.id);
+ toast({
+ title: "동기화 설정 완료",
+ description: "모든 데이터가 클라우드에 동기화되었습니다.",
+ });
+ setLastSync(getLastSyncTime());
+ } catch (error) {
+ toast({
+ title: "동기화 오류",
+ description: "동기화 중 문제가 발생했습니다. 다시 시도해주세요.",
+ variant: "destructive"
+ });
+ } finally {
+ setSyncing(false);
+ }
}
};
-
- const handleSyncNow = async () => {
- if (!userId) {
+
+ const handleManualSync = async () => {
+ if (!user) {
toast({
- title: "로그인이 필요합니다",
- description: "동기화를 사용하려면 먼저 로그인해주세요.",
+ title: "로그인 필요",
+ description: "데이터 동기화를 위해 로그인이 필요합니다.",
variant: "destructive"
});
return;
}
- setLoading(true);
try {
- await syncAllData(userId);
+ setSyncing(true);
+ await syncAllData(user.id);
toast({
title: "동기화 완료",
- description: "모든 데이터가 성공적으로 동기화되었습니다."
+ description: "모든 데이터가 클라우드에 동기화되었습니다.",
});
+ setLastSync(getLastSyncTime());
} catch (error) {
- console.error("동기화 오류:", error);
toast({
- title: "동기화 실패",
- description: "데이터 동기화 중 오류가 발생했습니다.",
+ title: "동기화 오류",
+ description: "동기화 중 문제가 발생했습니다. 다시 시도해주세요.",
variant: "destructive"
});
} finally {
- setLoading(false);
+ setSyncing(false);
}
};
+ const formatLastSyncTime = () => {
+ if (!lastSync) return "아직 동기화된 적 없음";
+
+ const date = new Date(lastSync);
+ return `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
+ };
+
return (
-
+
-
-
데이터 동기화
-
- 여러 기기에서 데이터를 동기화하고 백업합니다
+
+
+
+
+
+
+ 여러 기기에서 예산 및 지출 데이터를 동기화합니다.
- {syncEnabled && (
-
-
-
- 마지막 동기화: {new Date().toLocaleString('ko-KR')}
-
+ {enabled && (
+
+
+ 마지막 동기화: {formatLastSyncTime()}
+
+
)}
-
- {!userId && (
-
- 동기화를 사용하려면 로그인이 필요합니다
-
- )}
);
};
diff --git a/src/utils/sync/syncSettings.ts b/src/utils/sync/syncSettings.ts
index f9de300..1fbfb61 100644
--- a/src/utils/sync/syncSettings.ts
+++ b/src/utils/sync/syncSettings.ts
@@ -14,3 +14,13 @@ export const isSyncEnabled = (): boolean => {
export const setSyncEnabled = (enabled: boolean): void => {
localStorage.setItem('syncEnabled', enabled.toString());
};
+
+// 최종 동기화 시간 관리
+export const getLastSyncTime = (): string | null => {
+ return localStorage.getItem('lastSyncTime');
+};
+
+export const setLastSyncTime = (): void => {
+ const now = new Date().toISOString();
+ localStorage.setItem('lastSyncTime', now);
+};
diff --git a/src/utils/syncUtils.ts b/src/utils/syncUtils.ts
index 5ecc153..9c7e8cc 100644
--- a/src/utils/syncUtils.ts
+++ b/src/utils/syncUtils.ts
@@ -1,5 +1,5 @@
-import { isSyncEnabled, setSyncEnabled } from './sync/syncSettings';
+import { isSyncEnabled, setSyncEnabled, getLastSyncTime, setLastSyncTime } from './sync/syncSettings';
import { uploadTransactions, downloadTransactions } from './sync/transactionSync';
import { uploadBudgets, downloadBudgets } from './sync/budgetSync';
@@ -10,7 +10,9 @@ export {
uploadTransactions,
downloadTransactions,
uploadBudgets,
- downloadBudgets
+ downloadBudgets,
+ getLastSyncTime,
+ setLastSyncTime
};
/**
@@ -19,8 +21,17 @@ export {
export const syncAllData = async (userId: string): Promise
=> {
if (!userId || !isSyncEnabled()) return;
- await downloadTransactions(userId);
- await downloadBudgets(userId);
- await uploadTransactions(userId);
- await uploadBudgets(userId);
+ try {
+ console.log('데이터 동기화 시작...');
+ await downloadTransactions(userId);
+ await downloadBudgets(userId);
+ await uploadTransactions(userId);
+ await uploadBudgets(userId);
+
+ // 동기화 시간 업데이트
+ setLastSyncTime();
+ console.log('데이터 동기화 완료!');
+ } catch (error) {
+ console.error('동기화 중 오류 발생:', error);
+ }
};