Updated the color of the "로그인하여 동기화" button and the sync toggle switch in the Settings page to the main app color.
147 lines
4.6 KiB
TypeScript
147 lines
4.6 KiB
TypeScript
|
|
import React, { useState, useEffect } from 'react';
|
|
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 { toast } from "@/hooks/useToast.wrapper";
|
|
import { useAuth } from "@/contexts/auth";
|
|
import { useNavigate } from "react-router-dom";
|
|
import { Button } from "@/components/ui/button";
|
|
|
|
const SyncSettings = () => {
|
|
const [enabled, setEnabled] = useState(isSyncEnabled());
|
|
const [syncing, setSyncing] = useState(false);
|
|
const [lastSync, setLastSync] = useState<string | null>(getLastSyncTime());
|
|
const { user } = useAuth();
|
|
const navigate = useNavigate();
|
|
|
|
useEffect(() => {
|
|
// 마지막 동기화 시간 업데이트
|
|
setLastSync(getLastSyncTime());
|
|
}, []);
|
|
|
|
const handleSyncToggle = async (checked: boolean) => {
|
|
if (!user && checked) {
|
|
toast({
|
|
title: "로그인 필요",
|
|
description: "데이터 동기화를 위해 로그인이 필요합니다.",
|
|
variant: "destructive"
|
|
});
|
|
return;
|
|
}
|
|
|
|
setEnabled(checked);
|
|
setSyncEnabled(checked);
|
|
|
|
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 handleManualSync = async () => {
|
|
if (!user) {
|
|
toast({
|
|
title: "로그인 필요",
|
|
description: "데이터 동기화를 위해 로그인이 필요합니다.",
|
|
variant: "destructive"
|
|
});
|
|
return;
|
|
}
|
|
|
|
try {
|
|
setSyncing(true);
|
|
await syncAllData(user.id);
|
|
toast({
|
|
title: "동기화 완료",
|
|
description: "모든 데이터가 클라우드에 동기화되었습니다.",
|
|
});
|
|
setLastSync(getLastSyncTime());
|
|
} catch (error) {
|
|
toast({
|
|
title: "동기화 오류",
|
|
description: "동기화 중 문제가 발생했습니다. 다시 시도해주세요.",
|
|
variant: "destructive"
|
|
});
|
|
} finally {
|
|
setSyncing(false);
|
|
}
|
|
};
|
|
|
|
const formatLastSyncTime = () => {
|
|
if (!lastSync) return "아직 동기화된 적 없음";
|
|
|
|
const date = new Date(lastSync);
|
|
return `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<div className="flex items-center justify-between">
|
|
<div className="space-y-0.5">
|
|
<div className="flex items-center gap-2">
|
|
<CloudUpload className="h-5 w-5 text-neuro-accent" />
|
|
<Label htmlFor="sync-toggle" className="text-base font-medium">
|
|
데이터 클라우드 동기화
|
|
</Label>
|
|
</div>
|
|
<p className="text-sm text-muted-foreground">
|
|
여러 기기에서 예산 및 지출 데이터를 동기화합니다.
|
|
</p>
|
|
</div>
|
|
<Switch
|
|
id="sync-toggle"
|
|
checked={enabled}
|
|
onCheckedChange={handleSyncToggle}
|
|
className="data-[state=checked]:bg-neuro-accent"
|
|
/>
|
|
</div>
|
|
|
|
{enabled && (
|
|
<div className="space-y-3">
|
|
<div className="flex justify-between items-center text-sm">
|
|
<span className="text-muted-foreground">마지막 동기화: {formatLastSyncTime()}</span>
|
|
{user ? (
|
|
<button
|
|
onClick={handleManualSync}
|
|
disabled={syncing}
|
|
className="neuro-button py-1 px-3 flex items-center gap-1 bg-neuro-accent text-white hover:bg-neuro-accent/90"
|
|
>
|
|
<RefreshCw className={`h-4 w-4 ${syncing ? 'animate-spin' : ''}`} />
|
|
<span>{syncing ? '동기화 중...' : '지금 동기화'}</span>
|
|
</button>
|
|
) : (
|
|
<Button
|
|
onClick={() => navigate('/login')}
|
|
size="sm"
|
|
className="py-1 px-3 bg-neuro-accent text-white hover:bg-neuro-accent/90"
|
|
>
|
|
로그인하여 동기화
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default SyncSettings;
|