From 9631303b3c5ae68d2e494022d6437220a033bb83 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 23:27:21 +0000 Subject: [PATCH] Refactor SecurityPrivacySettings component Refactor the SecurityPrivacySettings component into smaller, more manageable sub-components for improved readability and maintainability. The functionality of the page remains unchanged. --- src/components/security/DataResetSection.tsx | 91 +++++++++ .../security/SaveSettingsButton.tsx | 41 ++++ src/components/security/SecurityHeader.tsx | 27 +++ .../security/SecuritySettingItem.tsx | 52 +++++ .../security/SecuritySettingsList.tsx | 50 +++++ src/components/security/types.ts | 10 + src/pages/SecurityPrivacySettings.tsx | 180 ++---------------- 7 files changed, 284 insertions(+), 167 deletions(-) create mode 100644 src/components/security/DataResetSection.tsx create mode 100644 src/components/security/SaveSettingsButton.tsx create mode 100644 src/components/security/SecurityHeader.tsx create mode 100644 src/components/security/SecuritySettingItem.tsx create mode 100644 src/components/security/SecuritySettingsList.tsx create mode 100644 src/components/security/types.ts diff --git a/src/components/security/DataResetSection.tsx b/src/components/security/DataResetSection.tsx new file mode 100644 index 0000000..2242d2b --- /dev/null +++ b/src/components/security/DataResetSection.tsx @@ -0,0 +1,91 @@ + +import React, { useState } from 'react'; +import { Trash2 } from 'lucide-react'; +import { Button } from '@/components/ui/button'; +import { useToast } from '@/hooks/use-toast'; +import { useNavigate } from 'react-router-dom'; +import { resetAllStorageData } from '@/utils/storageUtils'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogClose +} from '@/components/ui/dialog'; + +const DataResetSection = () => { + const [isResetDialogOpen, setIsResetDialogOpen] = useState(false); + const { toast } = useToast(); + const navigate = useNavigate(); + + const handleResetAllData = () => { + // 데이터 초기화 수행 + try { + resetAllStorageData(); + toast({ + title: "모든 데이터가 초기화되었습니다.", + description: "모든 예산, 지출 내역, 설정이 초기화되었습니다.", + }); + setIsResetDialogOpen(false); + // 초기화 후 설정 페이지로 이동 + setTimeout(() => navigate('/settings'), 1000); + } catch (error) { + console.error('데이터 초기화 실패:', error); + toast({ + title: "데이터 초기화 실패", + description: "데이터를 초기화하는 중 문제가 발생했습니다.", + variant: "destructive", + }); + } + }; + + return ( + <> +
+
+
+ +
+
+

데이터 초기화

+

모든 예산, 지출 내역, 설정이 초기화됩니다.

+
+
+ +
+ + {/* Reset Dialog */} + + + + 정말 모든 데이터를 초기화하시겠습니까? + + 이 작업은 되돌릴 수 없으며, 모든 예산, 지출 내역, 설정이 영구적으로 삭제됩니다. + + + + + + + + + + + + ); +}; + +export default DataResetSection; diff --git a/src/components/security/SaveSettingsButton.tsx b/src/components/security/SaveSettingsButton.tsx new file mode 100644 index 0000000..d8a85e3 --- /dev/null +++ b/src/components/security/SaveSettingsButton.tsx @@ -0,0 +1,41 @@ + +import React from 'react'; +import { Button } from '@/components/ui/button'; +import { useNavigate } from 'react-router-dom'; +import { useToast } from '@/hooks/use-toast'; + +type SaveSettingsButtonProps = { + onSave?: () => void; +}; + +const SaveSettingsButton = ({ onSave }: SaveSettingsButtonProps) => { + const navigate = useNavigate(); + const { toast } = useToast(); + + const handleSave = () => { + // 사용자 정의 저장 함수가 있으면 실행 + if (onSave) { + onSave(); + } + + // 기본 저장 동작 + toast({ + title: "보안 설정이 저장되었습니다.", + description: "변경사항이 성공적으로 적용되었습니다.", + }); + navigate('/settings'); + }; + + return ( +
+ +
+ ); +}; + +export default SaveSettingsButton; diff --git a/src/components/security/SecurityHeader.tsx b/src/components/security/SecurityHeader.tsx new file mode 100644 index 0000000..fd08118 --- /dev/null +++ b/src/components/security/SecurityHeader.tsx @@ -0,0 +1,27 @@ + +import React from 'react'; +import { ArrowLeft } from 'lucide-react'; +import { useNavigate } from 'react-router-dom'; +import { Button } from '@/components/ui/button'; + +const SecurityHeader = () => { + const navigate = useNavigate(); + + return ( +
+
+ +

보안 및 개인정보

+
+
+ ); +}; + +export default SecurityHeader; diff --git a/src/components/security/SecuritySettingItem.tsx b/src/components/security/SecuritySettingItem.tsx new file mode 100644 index 0000000..5f9d412 --- /dev/null +++ b/src/components/security/SecuritySettingItem.tsx @@ -0,0 +1,52 @@ + +import React from 'react'; +import { Switch } from '@/components/ui/switch'; +import { Label } from '@/components/ui/label'; + +type SecuritySettingItemProps = { + id: string; + title: string; + description: string; + icon: React.ReactNode; + enabled: boolean; + onToggle: (id: string) => void; +}; + +const SecuritySettingItem = ({ + id, + title, + description, + icon, + enabled, + onToggle +}: SecuritySettingItemProps) => { + return ( +
+
+
+ {icon} +
+
+

{title}

+

{description}

+
+
+
+ onToggle(id)} + className="data-[state=checked]:bg-neuro-income" + /> + +
+
+ ); +}; + +export default SecuritySettingItem; diff --git a/src/components/security/SecuritySettingsList.tsx b/src/components/security/SecuritySettingsList.tsx new file mode 100644 index 0000000..9dd6df0 --- /dev/null +++ b/src/components/security/SecuritySettingsList.tsx @@ -0,0 +1,50 @@ + +import React from 'react'; +import { useToast } from '@/hooks/use-toast'; +import SecuritySettingItem from './SecuritySettingItem'; +import { SecuritySetting } from './types'; + +type SecuritySettingsListProps = { + settings: SecuritySetting[]; + setSettings: React.Dispatch>; +}; + +const SecuritySettingsList = ({ settings, setSettings }: SecuritySettingsListProps) => { + const { toast } = useToast(); + + const handleToggle = (id: string) => { + setSettings( + settings.map((setting) => + setting.id === id ? { ...setting, enabled: !setting.enabled } : setting + ) + ); + + // 토스트 메시지로 상태 변경 알림 + const setting = settings.find(s => s.id === id); + if (setting) { + const newState = !setting.enabled; + toast({ + title: `${setting.title}이(가) ${newState ? '활성화' : '비활성화'}되었습니다.`, + description: "보안 설정이 변경되었습니다.", + }); + } + }; + + return ( +
+ {settings.map((setting) => ( + + ))} +
+ ); +}; + +export default SecuritySettingsList; diff --git a/src/components/security/types.ts b/src/components/security/types.ts new file mode 100644 index 0000000..42d1155 --- /dev/null +++ b/src/components/security/types.ts @@ -0,0 +1,10 @@ + +import { ReactNode } from 'react'; + +export type SecuritySetting = { + id: string; + title: string; + description: string; + icon: ReactNode; + enabled: boolean; +}; diff --git a/src/pages/SecurityPrivacySettings.tsx b/src/pages/SecurityPrivacySettings.tsx index f055ccc..5d4de32 100644 --- a/src/pages/SecurityPrivacySettings.tsx +++ b/src/pages/SecurityPrivacySettings.tsx @@ -1,35 +1,13 @@ import React, { useState } from 'react'; -import { ArrowLeft, Shield, Lock, Key, Fingerprint, Eye, EyeOff, UserX, Trash2 } from 'lucide-react'; -import { useNavigate } from 'react-router-dom'; -import { Button } from '@/components/ui/button'; -import { Switch } from '@/components/ui/switch'; -import { Label } from '@/components/ui/label'; -import { useToast } from '@/hooks/use-toast'; -import { - Dialog, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogClose -} from '@/components/ui/dialog'; -import { resetAllStorageData } from '@/utils/storageUtils'; - -type SecuritySetting = { - id: string; - title: string; - description: string; - icon: React.ReactNode; - enabled: boolean; -}; +import { Shield, Lock, Key, Fingerprint, Eye, EyeOff, UserX } from 'lucide-react'; +import SecurityHeader from '@/components/security/SecurityHeader'; +import SecuritySettingsList from '@/components/security/SecuritySettingsList'; +import DataResetSection from '@/components/security/DataResetSection'; +import SaveSettingsButton from '@/components/security/SaveSettingsButton'; +import { SecuritySetting } from '@/components/security/types'; const SecurityPrivacySettings = () => { - const navigate = useNavigate(); - const { toast } = useToast(); - const [isResetDialogOpen, setIsResetDialogOpen] = useState(false); - const [settings, setSettings] = useState([ { id: 'twoFactor', @@ -82,155 +60,23 @@ const SecurityPrivacySettings = () => { }, ]); - const handleToggle = (id: string) => { - setSettings( - settings.map((setting) => - setting.id === id ? { ...setting, enabled: !setting.enabled } : setting - ) - ); - - // 토스트 메시지로 상태 변경 알림 - const setting = settings.find(s => s.id === id); - if (setting) { - const newState = !setting.enabled; - toast({ - title: `${setting.title}이(가) ${newState ? '활성화' : '비활성화'}되었습니다.`, - description: "보안 설정이 변경되었습니다.", - }); - } - }; - - const saveSettings = () => { - // 여기에 설정 저장 로직 추가 - toast({ - title: "보안 설정이 저장되었습니다.", - description: "변경사항이 성공적으로 적용되었습니다.", - }); - navigate('/settings'); - }; - - const handleResetAllData = () => { - // 데이터 초기화 수행 - try { - resetAllStorageData(); - toast({ - title: "모든 데이터가 초기화되었습니다.", - description: "모든 예산, 지출 내역, 설정이 초기화되었습니다.", - }); - setIsResetDialogOpen(false); - // 초기화 후 설정 페이지로 이동 - setTimeout(() => navigate('/settings'), 1000); - } catch (error) { - console.error('데이터 초기화 실패:', error); - toast({ - title: "데이터 초기화 실패", - description: "데이터를 초기화하는 중 문제가 발생했습니다.", - variant: "destructive", - }); - } - }; - return (
{/* Header */} -
-
- -

보안 및 개인정보

-
-
+ {/* Security Settings */} -
- {settings.map((setting) => ( -
-
-
- {setting.icon} -
-
-

{setting.title}

-

{setting.description}

-
-
-
- handleToggle(setting.id)} - className="data-[state=checked]:bg-neuro-income" - /> - -
-
- ))} -
+ {/* Data Reset Section */} -
-
-
- -
-
-

데이터 초기화

-

모든 예산, 지출 내역, 설정이 초기화됩니다.

-
-
- -
- - {/* Reset Dialog */} - - - - 정말 모든 데이터를 초기화하시겠습니까? - - 이 작업은 되돌릴 수 없으며, 모든 예산, 지출 내역, 설정이 영구적으로 삭제됩니다. - - - - - - - - - - + {/* Save Button */} -
- -
+
);