11
22import { useEffect , useState } from "react" ;
3- import { Settings as SettingsIcon , Moon , Sun , Monitor , Type , Eye , Contrast } from "lucide-react" ;
3+ import { Settings as SettingsIcon , Moon , Sun , Monitor , Type , Eye , Contrast , DatabaseIcon } from "lucide-react" ;
44import { Button } from "@/components/ui/button" ;
55import {
66 Sheet ,
@@ -16,6 +16,9 @@ import {
1616 SelectTrigger ,
1717 SelectValue ,
1818} from "@/components/ui/select" ;
19+ import { indexedDBStorage } from "@/utils/indexedDBStorage" ;
20+ import { toast } from "@/hooks/use-toast" ;
21+ import { Note , Task } from "@/pages/Index" ;
1922
2023interface SettingsProps {
2124 isOpen : boolean ;
@@ -27,6 +30,8 @@ export const Settings = ({ isOpen, onClose }: SettingsProps) => {
2730 const [ fontSize , setFontSize ] = useState ( "medium" ) ;
2831 const [ highContrast , setHighContrast ] = useState ( false ) ;
2932 const [ reducedMotion , setReducedMotion ] = useState ( false ) ;
33+ const [ dataCleared , setDataCleared ] = useState ( false ) ;
34+ const [ isImportingData , setIsImportingData ] = useState ( false ) ;
3035
3136 useEffect ( ( ) => {
3237 const storedTheme = localStorage . getItem ( "current-theme" ) ;
@@ -35,6 +40,94 @@ export const Settings = ({ isOpen, onClose }: SettingsProps) => {
3540 }
3641 } , [ ] ) ;
3742
43+ useEffect ( ( ) => {
44+ const checkData = async ( ) => {
45+ try {
46+ const [ notes , tasks ] = await Promise . all ( [
47+ indexedDBStorage . loadNotes ( ) ,
48+ indexedDBStorage . loadTasks ( ) ,
49+ ] ) ;
50+ setDataCleared ( notes . length === 0 && tasks . length === 0 ) ;
51+ } catch ( error ) {
52+ console . error ( "Error checking data:" , error ) ;
53+ setDataCleared ( false ) ;
54+ }
55+ } ;
56+ checkData ( ) ;
57+ } , [ ] ) ;
58+
59+
60+ useEffect ( ( ) => {
61+ const handleDataCleared = ( ) => setDataCleared ( true ) ;
62+ window . addEventListener ( "data-cleared" , handleDataCleared ) ;
63+ return ( ) => window . removeEventListener ( "data-cleared" , handleDataCleared ) ;
64+ } , [ ] ) ;
65+
66+ const handleImportData = ( ) => {
67+ // Open file browser and look for json files
68+ const input = document . createElement ( 'input' ) ;
69+ input . type = 'file' ;
70+ input . accept = '.json' ;
71+ input . onchange = ( event ) => {
72+ const file = ( event . target as HTMLInputElement ) . files ?. [ 0 ] ;
73+ if ( file ) {
74+ const reader = new FileReader ( ) ;
75+ reader . onload = ( e ) => {
76+ const data = e . target ?. result ;
77+ if ( typeof data === 'string' ) {
78+ try {
79+ const parsedData = JSON . parse ( data ) ;
80+ if ( parsedData && ( Array . isArray ( parsedData . notes ) || Array . isArray ( parsedData . tasks ) ) ) {
81+ const notes = Array . isArray ( parsedData . notes ) ? parsedData . notes : null ;
82+ const tasks = Array . isArray ( parsedData . tasks ) ? parsedData . tasks : null ;
83+
84+ // Import notes if present
85+ const notesPromise = notes ? indexedDBStorage . saveNotes ( notes ) : Promise . resolve ( ) ;
86+ // Import tasks if present
87+ const tasksPromise = tasks ? indexedDBStorage . saveTasks ( tasks ) : Promise . resolve ( ) ;
88+
89+ Promise . all ( [ notesPromise , tasksPromise ] )
90+ . then ( ( ) => {
91+ toast ( {
92+ title : "Data imported successfully!" ,
93+ description : "Your notes and/or tasks have been imported. Please refresh the page to see the changes." ,
94+ variant : "success"
95+ } ) ;
96+ } )
97+ . catch ( ( error ) => {
98+ console . error ( "Error importing data:" , error ) ;
99+ toast ( {
100+ title : "Import Error" ,
101+ description : "There was an error importing your data." ,
102+ variant : "destructive"
103+ } ) ;
104+ } ) ;
105+ } else {
106+ alert ( "Invalid JSON structure. Please ensure the file contains 'notes' and/or 'tasks' arrays." ) ;
107+ }
108+ } catch ( error ) {
109+ console . error ( "Error parsing JSON data:" , error ) ;
110+ alert ( "Invalid JSON file. Please upload a valid file." ) ;
111+ }
112+ }
113+ } ;
114+ reader . readAsText ( file ) ;
115+ }
116+ } ;
117+ input . click ( ) ;
118+ } ;
119+
120+ const clearData = ( ) => {
121+ indexedDBStorage . clearAllData ( ) . then ( ( ) => {
122+ setDataCleared ( true ) ;
123+ // Optionally, dispatch event if other components need to know
124+ window . dispatchEvent ( new Event ( "data-cleared" ) ) ;
125+ } ) . catch ( ( error ) => {
126+ console . error ( "Error clearing data:" , error ) ;
127+ alert ( "Failed to clear data. Please try again." ) ;
128+ } ) ;
129+ } ;
130+
38131 const handleThemeChange = ( newTheme : string ) => {
39132 setTheme ( newTheme ) ;
40133 localStorage . setItem ( "current-theme" , newTheme ) ;
@@ -138,7 +231,7 @@ export const Settings = ({ isOpen, onClose }: SettingsProps) => {
138231 { /* Accessibility Options */ }
139232 < div className = "space-y-4" >
140233 < h4 className = "text-sm font-medium text-muted-foreground" > Accessibility</ h4 >
141-
234+
142235 < div className = "flex items-center justify-between" >
143236 < div className = "flex items-center space-x-2" >
144237 < Contrast className = "h-4 w-4" />
@@ -168,9 +261,38 @@ export const Settings = ({ isOpen, onClose }: SettingsProps) => {
168261 { reducedMotion ? "On" : "Off" }
169262 </ Button >
170263 </ div >
264+ < div className = "flex items-center justify-between" >
265+ < div className = "flex items-center space-x-2" >
266+ < DatabaseIcon className = "h-4 w-4" />
267+ < span className = "text-sm" > Data Management</ span >
268+ </ div >
269+ < Button
270+ variant = { dataCleared ? "ghost" : "outline" }
271+ size = "sm"
272+ onClick = { ( ) => {
273+ clearData ( ) ;
274+ setTimeout ( ( ) => {
275+ window . location . reload ( ) ;
276+ } , 1000 ) ;
277+ } }
278+ className = { `h-6 w-20 ${ dataCleared ? "text-neon-purple" : "text-red-600" } text-xs` }
279+ disabled = { dataCleared }
280+ >
281+ { dataCleared ? "No Data" : "Clear Data" }
282+ </ Button >
283+ < Button
284+ variant = "outline"
285+ size = "sm"
286+ onClick = { handleImportData }
287+ className = "h-6 w-24 text-xs text-neon-green"
288+ >
289+ Import Data
290+ </ Button >
291+ </ div >
171292 </ div >
172293 </ div >
173294 </ SheetContent >
174295 </ Sheet >
175296 ) ;
176297} ;
298+
0 commit comments