Add support for character selection
This commit is contained in:
3 files changed
+58
-8
No files matched your search
@@ -13,6 +13,6 @@ A basic password generator app.
|
|||||||
## Features
|
## Features
|
||||||
|
|
||||||
- [x] Custom length select, with presets
|
- [x] Custom length select, with presets
|
||||||
- [ ] Choose what characters to use
|
- [x] Choose what characters to use
|
||||||
- [x] Regenerate password
|
- [x] Regenerate password
|
||||||
- [x] Copy password
|
- [x] Copy password
|
||||||
+10
-3
@@ -17,6 +17,7 @@ body {
|
|||||||
--col6: rgb(96, 96, 96);
|
--col6: rgb(96, 96, 96);
|
||||||
--col7: rgb(112, 112, 112);
|
--col7: rgb(112, 112, 112);
|
||||||
--col8: rgb(128, 128, 128);
|
--col8: rgb(128, 128, 128);
|
||||||
|
--col9: rgb(144, 144, 144);
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
@@ -32,7 +33,7 @@ p {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.form {
|
.form {
|
||||||
@apply flex flex-col items-center gap-2;
|
@apply flex flex-col items-center gap-2 mb-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.slider-section {
|
.slider-section {
|
||||||
@@ -47,14 +48,20 @@ button {
|
|||||||
@apply bg-(--col3) hover:bg-(--col5) border border-(--col5) hover:border-(--col7) rounded-lg cursor-pointer transition-colors;
|
@apply bg-(--col3) hover:bg-(--col5) border border-(--col5) hover:border-(--col7) rounded-lg cursor-pointer transition-colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
.preset-buttons {
|
.preset-buttons,
|
||||||
|
.char-selection-buttons {
|
||||||
@apply flex gap-2 flex-wrap justify-center;
|
@apply flex gap-2 flex-wrap justify-center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.preset-btn {
|
.preset-btn,
|
||||||
|
.char-selection-buttons button {
|
||||||
@apply px-2 py-1;
|
@apply px-2 py-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.char-selection-buttons button.char-selected {
|
||||||
|
@apply bg-(--col5) hover:bg-(--col7) border-(--col7) hover:border-(--col9);
|
||||||
|
}
|
||||||
|
|
||||||
.generate-btn {
|
.generate-btn {
|
||||||
@apply px-4 py-2;
|
@apply px-4 py-2;
|
||||||
}
|
}
|
||||||
|
|||||||
+47
-4
@@ -7,18 +7,32 @@ function App () {
|
|||||||
const [length, setLength] = useState(8)
|
const [length, setLength] = useState(8)
|
||||||
const [copied, setCopied] = useState(false)
|
const [copied, setCopied] = useState(false)
|
||||||
|
|
||||||
|
const [useUpper, setUseUpper] = useState<boolean>(true)
|
||||||
|
const [useLower, setUseLower] = useState<boolean>(true)
|
||||||
|
const [useNumbers, setUseNumbers] = useState<boolean>(true)
|
||||||
|
const [useSymbols, setUseSymbols] = useState<boolean>(true)
|
||||||
|
|
||||||
const presets = [6, 8, 12, 16, 24, 32, 50, 100, 200, 250]
|
const presets = [6, 8, 12, 16, 24, 32, 50, 100, 200, 250]
|
||||||
|
|
||||||
|
const charsUpper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||||
|
const charsLower = 'abcdefghijklmnopqrstuvwxyz'
|
||||||
|
const charsNumber = '0123456789'
|
||||||
|
const charsSymbols = '!@#$%^&*'
|
||||||
|
|
||||||
const generatePassword = useCallback(() => {
|
const generatePassword = useCallback(() => {
|
||||||
const chars =
|
const chars =
|
||||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*'
|
(useUpper ? charsUpper : '') +
|
||||||
|
(useLower ? charsLower : '') +
|
||||||
|
(useNumbers ? charsNumber : '') +
|
||||||
|
(useSymbols ? charsSymbols : '')
|
||||||
|
if (chars == '') return setPassword('')
|
||||||
setPassword(
|
setPassword(
|
||||||
Array.from(
|
Array.from(
|
||||||
{ length },
|
{ length },
|
||||||
() => chars[Math.floor(Math.random() * chars.length)]
|
() => chars[Math.floor(Math.random() * chars.length)]
|
||||||
).join('')
|
).join('')
|
||||||
)
|
)
|
||||||
}, [length])
|
}, [length, useUpper, useLower, useNumbers, useSymbols])
|
||||||
|
|
||||||
const copyToClipboard = () => {
|
const copyToClipboard = () => {
|
||||||
navigator.clipboard.writeText(password)
|
navigator.clipboard.writeText(password)
|
||||||
@@ -68,8 +82,38 @@ function App () {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<p>Characters to use</p>
|
||||||
|
<div className='char-selection-buttons'>
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
className={useUpper ? 'char-selected' : ''}
|
||||||
|
onClick={() => setUseUpper(!useUpper)}
|
||||||
|
>
|
||||||
|
Use uppercase
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
className={useLower ? 'char-selected' : ''}
|
||||||
|
onClick={() => setUseLower(!useLower)}
|
||||||
|
>
|
||||||
|
Use lowercases
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
className={useNumbers ? 'char-selected' : ''}
|
||||||
|
onClick={() => setUseNumbers(!useNumbers)}
|
||||||
|
>
|
||||||
|
Use numbers
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
className={useSymbols ? 'char-selected' : ''}
|
||||||
|
onClick={() => setUseSymbols(!useSymbols)}
|
||||||
|
>
|
||||||
|
Use symbols
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
{password && (
|
|
||||||
<div className='result-section'>
|
<div className='result-section'>
|
||||||
<p className='password-display'>{password}</p>
|
<p className='password-display'>{password}</p>
|
||||||
<div className='result-buttons'>
|
<div className='result-buttons'>
|
||||||
@@ -85,7 +129,6 @@ function App () {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
</main>
|
</main>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user