1
+ import React , { useEffect } from 'react'
2
+ import { Editor } from 'novel'
3
+ import { MdOutlineAddToPhotos } from "react-icons/md" ;
4
+ import { IoMdCloseCircleOutline } from "react-icons/io" ;
5
+ import { FaChevronRight } from "react-icons/fa" ;
6
+
7
+ type Props = { }
8
+
9
+ const NoteComponent = ( props : Props ) => {
10
+ const [ keys , setKeys ] = React . useState < string [ ] > ( [ ] )
11
+ const [ sideBarOpen , setSideBarOpen ] = React . useState < boolean > ( false )
12
+ const [ selectedKey , setSelectedKey ] = React . useState < string > ( 'novel_content' )
13
+
14
+ const generateKey = ( ) => {
15
+ const localkeys = localStorage . getItem ( 'keys' )
16
+ const key = Math . random ( ) . toString ( 36 ) . substring ( 7 )
17
+ //check if key exists
18
+ if ( localkeys ) {
19
+ const parsedKeys = JSON . parse ( localkeys )
20
+ if ( parsedKeys . includes ( key ) ) {
21
+ generateKey ( )
22
+ }
23
+ else {
24
+ setKeys ( [ ...parsedKeys , key ] )
25
+ localStorage . setItem ( 'keys' , JSON . stringify ( [ ...parsedKeys , key ] ) )
26
+ setSelectedKey ( key )
27
+ localStorage . setItem ( 'selectedKey' , key )
28
+ }
29
+ }
30
+ }
31
+
32
+ useEffect ( ( ) => {
33
+ const localkeys = localStorage . getItem ( 'keys' )
34
+ if ( localkeys ) {
35
+ setKeys ( JSON . parse ( localkeys ) )
36
+ }
37
+ else {
38
+ localStorage . setItem ( 'keys' , JSON . stringify ( [ 'novel_content' ] ) )
39
+ }
40
+
41
+ const localSelectedKey = localStorage . getItem ( 'selectedKey' )
42
+ if ( localSelectedKey ) {
43
+ setSelectedKey ( localSelectedKey )
44
+ }
45
+ else {
46
+ localStorage . setItem ( 'selectedKey' , 'novel_content' )
47
+ }
48
+
49
+ }
50
+ , [ ] )
51
+
52
+ const selectKey = ( key : string ) => {
53
+ setSelectedKey ( key )
54
+ localStorage . setItem ( 'selectedKey' , key )
55
+ }
56
+
57
+ const handleRemove = ( key : string ) => {
58
+ selectKey ( 'novel_content' )
59
+ const localkeys = localStorage . getItem ( 'keys' )
60
+ if ( localkeys ) {
61
+ const parsedKeys = JSON . parse ( localkeys )
62
+ const filteredKeys = parsedKeys . filter ( ( k : string ) => k !== key )
63
+ setKeys ( filteredKeys )
64
+ localStorage . removeItem ( key )
65
+ localStorage . setItem ( 'keys' , JSON . stringify ( filteredKeys ) )
66
+ }
67
+ }
68
+
69
+ return (
70
+ < div className = 'w-full relative min-h-[100vh] bg-gray' >
71
+ {
72
+ ! sideBarOpen && (
73
+ < button onClick = { ( ) => {
74
+ setSideBarOpen ( true )
75
+ } } className = 'w-10 h-10 flex z-[99] justify-center items-center rounded-l-lg top-[10vh] right-0 fixed bg-white' >
76
+ < MdOutlineAddToPhotos className = 'text-[20px]' />
77
+ </ button >
78
+ )
79
+ }
80
+ < div className = { `h-[100vh] p-[2%] w-[20vw] bg-gray border-l border-white/10 fixed top-0 transition-all duration-1000 ${ sideBarOpen ? 'right-0' : '-right-full'
81
+ } z-[100]`} >
82
+ < div className = 'w-full flex mb-[1vh] justify-between items-center' >
83
+ < h1 className = 'text-2xl text-gray font-bold' > Notes</ h1 >
84
+ < div className = 'flex gap-[0.5rem]' >
85
+ < button onClick = { generateKey } className = 'w-10 h-10 flex justify-center items-center rounded-lg bg-gray/80 text-white' >
86
+ < MdOutlineAddToPhotos className = 'text-[20px]' />
87
+ </ button >
88
+ < button onClick = { ( ) => setSideBarOpen ( false ) } className = 'w-10 h-10 flex justify-center items-center rounded-lg bg-gray/80 text-white' >
89
+ < FaChevronRight className = 'text-[20px]' />
90
+ </ button >
91
+ </ div >
92
+ </ div >
93
+ < div className = 'flex flex-col gap-2' >
94
+
95
+ { keys . map ( ( key , index ) => {
96
+ return (
97
+ < div key = { key } className = { `p-3 transition-all flex justify-start px-[5%] duration-200 rounded-md ${ selectedKey === key ? 'bg-gray text-white' : 'bg-gray text-white opacity-50' } ` } >
98
+ < p onClick = { ( ) => selectKey ( key ) } className = 'w-[90%] cursor-pointer text-start truncate' >
99
+ {
100
+ key === 'novel_content' ? 'Default Note' : `Note ${ index } `
101
+ }
102
+ </ p >
103
+ { key !== 'novel_content' && < button onClick = {
104
+ ( ) => handleRemove ( key )
105
+ } className = 'w-[10%] text-center' >
106
+ < IoMdCloseCircleOutline className = 'text-[20px]' />
107
+ </ button > }
108
+
109
+ </ div >
110
+ )
111
+ } ) }
112
+ </ div >
113
+ </ div >
114
+ < Editor key = { selectedKey } storageKey = { selectedKey } defaultValue = { {
115
+ "type" : "doc" ,
116
+ "content" : [
117
+ {
118
+ "type" : "paragraph"
119
+ }
120
+ ]
121
+ } } onUpdate = { ( e ) => {
122
+ console . log ( e )
123
+ } } className = 'h-full text-white/80 w-full' />
124
+ </ div >
125
+ )
126
+ }
127
+
128
+ export default NoteComponent
0 commit comments