@@ -4,17 +4,43 @@ import TextField from '@mui/material/TextField';
44import DialogContent from '@mui/material/DialogContent' ;
55import DialogTitle from '@mui/material/DialogTitle' ;
66import DialogActions from '@mui/material/DialogActions' ;
7+ import IconButton from '@mui/material/IconButton' ;
8+ import Grid from '@mui/material/Grid' ;
79import Button from '@mui/material/Button' ;
10+ import RefreshIcon from '@mui/icons-material/Refresh' ;
11+ import VisibilityOffIcon from '@mui/icons-material/VisibilityOff' ;
12+ import VisibilityIcon from '@mui/icons-material/Visibility' ;
813import { MainContext } from '../../contexts/MainContextProvider' ;
14+ import PasswordStrength from '../../utils/PasswordStrength' ;
15+ import LinearProgressWithLabel from '../LinearProgressWithLabel' ;
16+ import { setError } from '../../reducers/MainReducer/Actions' ;
17+ import { generatePasswordArray , getFullCharacterSet } from '../../reducers/PasswordReducer/Actions' ;
18+ import { PasswordContext } from '../../contexts/PasswordContextProvider' ;
919
1020const CreatePasswordDialog = ( { open, onCreate, onClose } ) => {
11- const [ state ] = useContext ( MainContext ) ;
21+ const [ state , d1 ] = useContext ( MainContext ) ;
22+ const [ state2 ] = useContext ( PasswordContext ) ;
23+
1224 const language = state . languages [ state . languageIndex ] ;
25+ const {
26+ min,
27+ max,
28+ smallLetters,
29+ capitalLetters,
30+ spaces,
31+ specialCharacters,
32+ numbers,
33+ brackets,
34+ useAdvanced,
35+ characterSet,
36+ allowDuplicates,
37+ } = state2 ;
1338
1439 const [ title , setTitle ] = useState ( '' ) ;
1540 const [ description , setDescription ] = useState ( '' ) ;
1641 const [ url , setUrl ] = useState ( '' ) ;
1742 const [ password , setPassword ] = useState ( '' ) ;
43+ const [ showPassword , setShowPassword ] = useState ( false ) ;
1844
1945 /**
2046 * Close the dialog
@@ -39,6 +65,43 @@ const CreatePasswordDialog = ({ open, onCreate, onClose }) => {
3965 handleClose ( ) ;
4066 } ;
4167
68+ /**
69+ * Handle the key up event
70+ * @param e The event argument
71+ */
72+ const handleKeyUp = ( e ) => {
73+ if ( e . key === 'Enter' && password . length > 0 && title . length > 0 ) {
74+ create ( ) ;
75+ }
76+ } ;
77+
78+ /**
79+ * Generate passwords
80+ */
81+ const generatePassword = ( ) => {
82+ const simpleCharacterSet = getFullCharacterSet (
83+ characterSet ,
84+ useAdvanced ,
85+ smallLetters ,
86+ capitalLetters ,
87+ spaces ,
88+ numbers ,
89+ specialCharacters ,
90+ brackets ,
91+ ) ;
92+ if ( ! simpleCharacterSet || simpleCharacterSet . length === 0 || min > max || max < min ) {
93+ return ;
94+ }
95+
96+ generatePasswordArray ( min , max , simpleCharacterSet , 1 , allowDuplicates , null )
97+ . then ( ( res ) => {
98+ setPassword ( res [ 0 ] ) ;
99+ } )
100+ . catch ( ( err ) => {
101+ d1 ( setError ( err ) ) ;
102+ } ) ;
103+ } ;
104+
42105 return (
43106 < Dialog
44107 open = { open }
@@ -49,45 +112,82 @@ const CreatePasswordDialog = ({ open, onCreate, onClose }) => {
49112 { language . createPassword }
50113 </ DialogTitle >
51114 < DialogContent >
52- < TextField
53- sx = { { mt : 2 } }
54- value = { title }
55- error = { title . length === 0 }
56- label = { language . title }
57- onChange = { ( e ) => setTitle ( e . target . value ) }
58- autoComplete = "off"
59- variant = "outlined"
60- fullWidth
61- />
62- < TextField
63- sx = { { mt : 2 } }
64- value = { description }
65- label = { language . description }
66- onChange = { ( e ) => setDescription ( e . target . value ) }
67- autoComplete = "off"
68- variant = "outlined"
69- fullWidth
70- />
71- < TextField
72- sx = { { mt : 2 } }
73- value = { url }
74- label = { language . url }
75- onChange = { ( e ) => setUrl ( e . target . value ) }
76- autoComplete = "off"
77- variant = "outlined"
78- fullWidth
79- />
80- < TextField
81- sx = { { mt : 2 } }
82- value = { password }
83- type = "password"
84- error = { password . length === 0 }
85- label = { language . password }
86- onChange = { ( e ) => setPassword ( e . target . value ) }
87- autoComplete = "off"
88- variant = "outlined"
89- fullWidth
90- />
115+ < Grid container spacing = { 2 } sx = { { mt : 2 } } >
116+ < Grid item xs = { 12 } md = { 12 } lg = { 12 } >
117+ < TextField
118+ value = { title }
119+ error = { title . length === 0 }
120+ label = { language . title }
121+ onChange = { ( e ) => setTitle ( e . target . value ) }
122+ onKeyUp = { handleKeyUp }
123+ autoComplete = "off"
124+ variant = "outlined"
125+ fullWidth
126+ />
127+ </ Grid >
128+ < Grid item xs = { 12 } md = { 12 } lg = { 12 } >
129+ < TextField
130+ value = { description }
131+ label = { language . description }
132+ onChange = { ( e ) => setDescription ( e . target . value ) }
133+ onKeyUp = { handleKeyUp }
134+ autoComplete = "off"
135+ variant = "outlined"
136+ fullWidth
137+ />
138+ </ Grid >
139+ < Grid item xs = { 12 } md = { 12 } lg = { 12 } >
140+ < TextField
141+ value = { url }
142+ label = { language . url }
143+ onChange = { ( e ) => setUrl ( e . target . value ) }
144+ onKeyUp = { handleKeyUp }
145+ autoComplete = "off"
146+ variant = "outlined"
147+ fullWidth
148+ />
149+ </ Grid >
150+ < Grid item xs = { 12 } md = { 8 } lg = { 8 } >
151+ < TextField
152+ value = { password }
153+ type = { showPassword ? 'text' : 'password' }
154+ error = { password . length === 0 }
155+ label = { language . password }
156+ onChange = { ( e ) => setPassword ( e . target . value ) }
157+ onKeyUp = { handleKeyUp }
158+ autoComplete = "off"
159+ variant = "outlined"
160+ fullWidth
161+ />
162+ </ Grid >
163+ < Grid item xs = { 6 } md = { 2 } lg = { 2 } >
164+ < IconButton
165+ color = "primary"
166+ size = "large"
167+ sx = { { width : '100%' , height : '100%' } }
168+ onClick = { ( ) => setShowPassword ( ! showPassword ) }
169+ >
170+ { showPassword ? (
171+ < VisibilityOffIcon fontSize = "inherit" />
172+ ) : (
173+ < VisibilityIcon fontSize = "inherit" />
174+ ) }
175+ </ IconButton >
176+ </ Grid >
177+ < Grid item xs = { 6 } md = { 2 } lg = { 2 } >
178+ < IconButton
179+ color = "primary"
180+ size = "large"
181+ sx = { { width : '100%' , height : '100%' } }
182+ onClick = { generatePassword }
183+ >
184+ < RefreshIcon fontSize = "inherit" />
185+ </ IconButton >
186+ </ Grid >
187+ < Grid item xs = { 12 } md = { 12 } lg = { 12 } >
188+ < LinearProgressWithLabel value = { PasswordStrength ( password ) } />
189+ </ Grid >
190+ </ Grid >
91191 </ DialogContent >
92192 < DialogActions >
93193 < Button onClick = { handleClose } >
0 commit comments