11import "./NotesActions.css" ;
22import { type ChangeEventHandler , useCallback , useContext , useRef , useState } from "react" ;
33import Modal from "react-modal" ;
4+ import { Tooltip } from "react-tooltip" ;
45import { type INotesContext , NotesContext } from "../../NotesProvider/NotesProvider" ;
56import { RemoteSources } from "../../RemoteSources/RemoteSources" ;
67
@@ -26,10 +27,15 @@ export function NotesActions() {
2627 handleRedo,
2728 handleImport,
2829 handleExport,
30+ handleDeleteNotes,
2931 handleSetRemoteSources,
3032 } = useContext ( NotesContext ) as INotesContext ;
3133
34+ const [ confirmButtonTimeoutId , setConfirmButtonTimeoutId ] = useState < number | null > ( null ) ;
35+ const [ secondsLeft , setSecondsLeft ] = useState ( 3 ) ;
3236 const [ isModalOpen , setModalOpen ] = useState ( false ) ;
37+ const [ confirmDelete , setConfirmDelete ] = useState ( false ) ;
38+ const confirmDeleteDisabled = confirmDelete && secondsLeft > 0 ;
3339
3440 const fileImport = useRef < HTMLInputElement > ( null ) ;
3541 const onImport = useCallback ( ( ) => {
@@ -62,6 +68,46 @@ export function NotesActions() {
6268 setModalOpen ( ( x ) => ! x ) ;
6369 } , [ ] ) ;
6470
71+ const resetDeleteState = useCallback ( ( ) => {
72+ setSecondsLeft ( 3 ) ;
73+ setConfirmDelete ( false ) ;
74+ if ( confirmButtonTimeoutId ) {
75+ window . clearTimeout ( confirmButtonTimeoutId ) ;
76+ setConfirmButtonTimeoutId ( null ) ;
77+ }
78+ } , [ confirmButtonTimeoutId ] ) ;
79+
80+ const initiateDeleteCountdown = useCallback ( ( ) => {
81+ setSecondsLeft ( 3 ) ;
82+ setConfirmDelete ( true ) ;
83+ setConfirmButtonTimeoutId (
84+ window . setTimeout ( ( ) => {
85+ setSecondsLeft ( 3 ) ;
86+ setConfirmDelete ( false ) ;
87+ } , 10000 ) ,
88+ ) ;
89+ const disabledButtonIntervalId = window . setInterval ( ( ) => {
90+ setSecondsLeft ( ( x ) => {
91+ if ( x <= 1 ) {
92+ window . clearInterval ( disabledButtonIntervalId ) ;
93+ return 0 ;
94+ }
95+ return x - 1 ;
96+ } ) ;
97+ } , 1000 ) ;
98+ } , [ ] ) ;
99+
100+ const deleteNotes = useCallback ( ( ) => {
101+ if ( confirmDeleteDisabled ) return ;
102+
103+ if ( confirmDelete ) {
104+ handleDeleteNotes ( ) ;
105+ resetDeleteState ( ) ;
106+ } else {
107+ initiateDeleteCountdown ( ) ;
108+ }
109+ } , [ confirmDelete , confirmDeleteDisabled , handleDeleteNotes , resetDeleteState , initiateDeleteCountdown ] ) ;
110+
65111 return (
66112 < >
67113 < div className = "notes-actions" >
@@ -73,8 +119,18 @@ export function NotesActions() {
73119 </ button >
74120 < button onClick = { onImport } > 📂 import</ button >
75121 < button onClick = { handleExport } > 💾 export</ button >
122+ < button
123+ data-tooltip-id = "delete-tooltip"
124+ data-tooltip-content = { confirmDelete ? "Yes, delete" : "Delete all notes" }
125+ data-tooltip-place = "bottom"
126+ disabled = { confirmDeleteDisabled }
127+ onClick = { deleteNotes }
128+ >
129+ { confirmDelete ? ( secondsLeft > 0 ? `Wait (${ secondsLeft } )` : "❌" ) : "🗑️" }
130+ </ button >
76131 < button onClick = { toggleModal } > ⚙︎</ button >
77132 </ div >
133+ < Tooltip id = "delete-tooltip" />
78134 < input ref = { fileImport } onChange = { handleFileSelected } type = "file" style = { { display : "none" } } />
79135 < Modal style = { modalStyles } isOpen = { isModalOpen } onRequestClose = { toggleModal } contentLabel = "Settings" >
80136 < button className = "settings-close" onClick = { toggleModal } >
0 commit comments