1- import { ChangeEvent , FormEvent , FunctionComponent , useState } from 'react' ;
1+ import React , { ChangeEvent , FormEvent , useState } from 'react' ;
22import Toast from 'react-bootstrap/Toast' ;
33import CopyToClipboard from 'react-copy-to-clipboard' ;
44
@@ -10,60 +10,95 @@ import { generateHash } from '../services/generateHash';
1010import { InputReadonly } from './InputReadonly/InputReadonly' ;
1111import { Footer } from './Footer/Footer' ;
1212
13- export const App : FunctionComponent = ( ) => {
14- const title = 'Password Hash Generator Tool for phpMyFAQ' ;
13+ export const App : React . FC = ( ) => {
14+ const title = 'Password Hash Generator Tool for phpMyFAQ' ;
1515
16- const [ salt , setSalt ] = useState ( '' ) ;
17- const [ userName , setUserName ] = useState ( '' ) ;
18- const [ password , setPassword ] = useState ( '' ) ;
19- const [ generatedHash , setGeneratedHash ] = useState ( '' ) ;
20- const [ showToast , setShowToast ] = useState ( false ) ;
16+ const [ formData , setFormData ] = useState ( {
17+ salt : '' ,
18+ userName : '' ,
19+ password : '' ,
20+ generatedHash : '' ,
21+ } ) ;
22+ const [ showToast , setShowToast ] = useState ( false ) ;
23+ const [ toastMessage , setToastMessage ] = useState ( '' ) ;
2124
22- const handleSaltChange = ( event : ChangeEvent < HTMLInputElement > ) => setSalt ( event . target . value ) ;
23- const handleUserNameChange = ( event : ChangeEvent < HTMLInputElement > ) => setUserName ( event . target . value ) ;
24- const handlePasswordChange = ( event : ChangeEvent < HTMLInputElement > ) => setPassword ( event . target . value ) ;
25+ // Handle input change
26+ const handleInputChange = ( event : ChangeEvent < HTMLInputElement > ) => {
27+ const { name, value } = event . target ;
28+ setFormData ( ( prevData ) => ( {
29+ ...prevData ,
30+ [ name ] : value ,
31+ } ) ) ;
32+ } ;
2533
26- const handleSubmit = ( event : FormEvent < HTMLFormElement > ) => {
27- event . preventDefault ( ) ;
28- const hash = generateHash ( userName , password , salt ) ;
29- setGeneratedHash ( hash )
30- } ;
34+ // Handle form submit
35+ const handleSubmit = ( event : FormEvent < HTMLFormElement > ) => {
36+ event . preventDefault ( ) ;
37+ const { userName, password, salt } = formData ;
3138
32- return < >
33- < div className = "position-absolute w-100 d-flex flex-column p-4" >
34- < Toast onClose = { ( ) => setShowToast ( false ) } show = { showToast } delay = { 3000 } style = { {
35- position : 'absolute' ,
36- top : '1em' ,
37- right : '1em' ,
38- } } autohide >
39- < Toast . Header >
40- < strong className = "mr-auto" > { title } </ strong >
41- </ Toast . Header >
42- < Toast . Body > Generated hash successfully copied to clipboard!</ Toast . Body >
43- </ Toast >
44- </ div >
45- < div className = "App container" >
46- < Header title = { title } />
47- < div className = "row justify-content-md-center" >
48- < div className = "col-lg-6 col-sm-12" >
49- < form onSubmit = { handleSubmit } >
50- < Input label = { 'Your phpMyFAQ Salt' } onChange = { handleSaltChange } />
51- < Input label = { 'Your Username' } onChange = { handleUserNameChange } />
52- < InputPassword label = { 'New Password' } onChange = { handlePasswordChange } />
53- < Button type = { ButtonType . SUBMIT } > Generate hash!</ Button >
54- {
55- generatedHash &&
56- < div >
57- < InputReadonly label = { 'Generated Hash' } value = { generatedHash } />
58- < CopyToClipboard text = { generatedHash } onCopy = { ( ) => setShowToast ( true ) } >
59- < Button type = { ButtonType . BUTTON } > Copy to clipboard</ Button >
60- </ CopyToClipboard >
61- </ div >
62- }
63- </ form >
64- </ div >
65- </ div >
66- < Footer />
67- </ div >
68- </ > ;
69- }
39+ if ( ! userName || ! password || ! salt ) {
40+ setToastMessage ( 'Please fill in all fields.' ) ;
41+ setShowToast ( true ) ;
42+ return ;
43+ }
44+
45+ const hash = generateHash ( userName , password , salt ) ;
46+ setFormData ( ( prevData ) => ( {
47+ ...prevData ,
48+ generatedHash : hash ,
49+ } ) ) ;
50+ setToastMessage ( 'Hash generated successfully!' ) ;
51+ setShowToast ( true ) ;
52+ } ;
53+
54+ const { salt, userName, password, generatedHash } = formData ;
55+
56+ return (
57+ < >
58+ { /* Toast Notification */ }
59+ < div className = "position-absolute w-100 d-flex flex-column p-4" >
60+ < Toast
61+ onClose = { ( ) => setShowToast ( false ) }
62+ show = { showToast }
63+ delay = { 3000 }
64+ autohide
65+ style = { {
66+ position : 'absolute' ,
67+ top : '1em' ,
68+ right : '1em' ,
69+ } }
70+ >
71+ < Toast . Header >
72+ < strong className = "mr-auto" > { title } </ strong >
73+ </ Toast . Header >
74+ < Toast . Body > { toastMessage } </ Toast . Body >
75+ </ Toast >
76+ </ div >
77+
78+ { /* Main Content */ }
79+ < div className = "App container" >
80+ < Header title = { title } />
81+ < div className = "row justify-content-md-center" >
82+ < div className = "col-lg-6 col-sm-12" >
83+ < form onSubmit = { handleSubmit } >
84+ < Input label = "Your phpMyFAQ Salt" onChange = { handleInputChange } value = { salt } name = "salt" required />
85+ < Input label = "Your Username" onChange = { handleInputChange } value = { userName } name = "userName" required />
86+ < InputPassword label = "New Password" onChange = { handleInputChange } value = { password } name = "password" required />
87+ < Button type = { ButtonType . SUBMIT } > Generate hash!</ Button >
88+
89+ { generatedHash && (
90+ < div class = "mt-4" >
91+ < InputReadonly label = "Generated Hash" value = { generatedHash } />
92+ < CopyToClipboard text = { generatedHash } onCopy = { ( ) => setToastMessage ( 'Generated hash successfully copied to clipboard!' ) } >
93+ < Button type = { ButtonType . BUTTON } > Copy to clipboard</ Button >
94+ </ CopyToClipboard >
95+ </ div >
96+ ) }
97+ </ form >
98+ </ div >
99+ </ div >
100+ < Footer />
101+ </ div >
102+ </ >
103+ ) ;
104+ } ;
0 commit comments