diff --git a/src/components/mvpsdvlpr/Display.jsx b/src/components/mvpsdvlpr/Display.jsx
new file mode 100644
index 000000000..d6c34d0af
--- /dev/null
+++ b/src/components/mvpsdvlpr/Display.jsx
@@ -0,0 +1,132 @@
+import React, { useState, useRef } from 'react'
+import Button from './container/button/Button'
+import Container from './container/Container'
+import Tooltip from './container/tooltip/Tooltip'
+
+import './styles/Display.css'
+import { copyToClipBoard, generatePassword } from './utils/Helpers'
+
+const Display = () => {
+ const [password, setPassword] = useState('')
+ const [rangeValue, setRange] = useState()
+ const [passwordProps, setPasswordProps] = useState()
+ const [tooltip, setTooltip] = useState(false)
+ const [type, setType] = useState('password')
+ const passwordRef = useRef(null)
+ let pwdDescription = ''
+
+ const generateNewPassword = () => {
+ const pwd =
+ rangeValue > 3
+ ? generatePassword(passwordProps, rangeValue)
+ : generatePassword(passwordProps, 3)
+ setPassword(pwd)
+ }
+
+ const copyClipBoard = (e) => {
+ e.preventDefault()
+ copyToClipBoard(passwordRef.current)
+ setTooltip(true)
+ setTimeout(() => {
+ setTooltip(false)
+ }, 2000)
+ }
+
+ const onSelectTag = (e) => {
+ setType(e.target.value)
+ }
+
+ const setBackgroundColor = (password) => {
+ if (password && password.length === 1 && password.length <= 5) {
+ pwdDescription = 'Bad password'
+ return '#cb473e'
+ } else if (password && password.length >= 6 && password.length <= 10) {
+ pwdDescription = 'Weak password'
+ return '#f07d58'
+ } else if (password && password.length > 10) {
+ pwdDescription = 'Strong password'
+ return '#55a95d'
+ } else {
+ pwdDescription = 'Bad password'
+ return '#cb473e'
+ }
+ }
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+ {password && password.length > 10
+ ? (
+ <>
+ {pwdDescription}
+ >
+ )
+ : (
+ <>
+ {pwdDescription}
+ >
+ )}
+
+
+
+
+
+
+
+
+
+
+ >
+ )
+}
+
+const selectTagStyle = {
+ backgroundColor: 'inherit',
+ color: '#506175',
+ width: '20%',
+ height: 'auto',
+ marginLeft: '-4px'
+}
+
+export default Display
diff --git a/src/components/mvpsdvlpr/Generatorpsswrd.jsx b/src/components/mvpsdvlpr/Generatorpsswrd.jsx
new file mode 100644
index 000000000..bccac83e7
--- /dev/null
+++ b/src/components/mvpsdvlpr/Generatorpsswrd.jsx
@@ -0,0 +1,14 @@
+import React from 'react'
+import Display from './Display'
+import Header from './Header'
+
+const Generatorpsswrd = () => {
+ return (
+ <>
+
+
+ >
+ )
+}
+
+export default Generatorpsswrd
diff --git a/src/components/mvpsdvlpr/Header.jsx b/src/components/mvpsdvlpr/Header.jsx
new file mode 100644
index 000000000..1a876df4d
--- /dev/null
+++ b/src/components/mvpsdvlpr/Header.jsx
@@ -0,0 +1,17 @@
+import React from 'react'
+
+import './styles/Header.css'
+const Header = () => {
+ return (
+
+
+
Strong Password Generator
+
+
Create strong passwords with Password Generator
+
+
+
+ )
+}
+
+export default Header
diff --git a/src/components/mvpsdvlpr/container/Container.jsx b/src/components/mvpsdvlpr/container/Container.jsx
new file mode 100644
index 000000000..2085b47f3
--- /dev/null
+++ b/src/components/mvpsdvlpr/container/Container.jsx
@@ -0,0 +1,219 @@
+import React, { useState, useEffect, useMemo } from 'react'
+
+import '../styles/Container.css'
+import { copyToClipBoard, generatePassword, setPasswordLength } from '../utils/Helpers'
+import Button from './button/Button'
+import CheckBox from './checkbox/CheckBox'
+import Slider from './slider/Slider'
+
+const CHECKBOX_LIST = [
+ {
+ id: 0,
+ name: 'uppercase',
+ label: 'Uppercase',
+ isChecked: true
+ },
+ {
+ id: 1,
+ name: 'lowercase',
+ label: 'Lowercase',
+ isChecked: true
+ },
+ {
+ id: 2,
+ name: 'symbols',
+ label: 'Symbols',
+ isChecked: true
+ },
+ {
+ id: 3,
+ name: 'numbers',
+ label: 'Numbers',
+ isChecked: true
+ }
+]
+
+const Container = (props) => {
+ const { setPassword, setRange, setPasswordProps, passwordRef, type } = props
+
+ const [rangeValue, setRangeValue] = useState(12)
+ const [checkbox, setCheckBox] = useState({
+ uppercase: true,
+ lowercase: true,
+ symbols: true,
+ numbers: true
+ })
+ const [checked, setChecked] = useState(false)
+ const [checkedName, setCheckedName] = useState('')
+ const [minMaxValue, setMinMaxValue] = useState({
+ min: 1,
+ max: 60
+ })
+
+ const { uppercase, lowercase, symbols, numbers } = checkbox
+ const { min, max } = minMaxValue
+
+ useEffect(() => {
+ setPasswordLength(rangeValue)
+ setRange(rangeValue)
+ setRangeValue(rangeValue)
+ passwordGenerated(checkbox, rangeValue)
+
+ checkBoxCount()
+
+ // eslint-disable-next-line
+ }, [uppercase, lowercase, symbols, numbers])
+
+ const checkBoxCount = () => {
+ const checkedCount = Object.keys(checkbox).filter((key) => checkbox[key])
+ const disabled = checkedCount.length === 1
+ const name = checkedCount[0]
+ if (disabled) {
+ setChecked(disabled)
+ setCheckedName(name)
+ } else {
+ setChecked(false)
+ setCheckedName('')
+ }
+ }
+
+ const updateCheckBoxes = () => {
+ if (type === 'pin') {
+ CHECKBOX_LIST.map((checkbox) => {
+ const name = checkbox.name
+ if (name !== 'numbers') {
+ checkbox.isChecked = false
+ const checkboxProps = {
+ name,
+ checkedName: name,
+ checked: true,
+ isChecked: checkbox.isChecked,
+ min: 0,
+ max: 15,
+ length: 3
+ }
+ checkBoxProperties(checkboxProps)
+ }
+ return ''
+ })
+ } else {
+ CHECKBOX_LIST.map((checkbox) => {
+ const name = checkbox.name
+ checkbox.isChecked = true
+ const checkboxProps = {
+ name,
+ checkedName: '',
+ checked: false,
+ isChecked: checkbox.isChecked,
+ min: 1,
+ max: 60,
+ length: 12
+ }
+ checkBoxProperties(checkboxProps)
+ return ''
+ })
+ }
+ }
+
+ const checkBoxProperties = (checkBoxProps) => {
+ const { name, checked, isChecked, checkedName, min, max, length } = checkBoxProps
+
+ setCheckBox((prevState) => ({ ...prevState, [name]: isChecked }))
+ setChecked(checked)
+ setCheckedName(checkedName)
+ setPasswordLength(length)
+ setMinMaxValue({ min, max })
+ setRangeValue(length)
+ setRange(length)
+ }
+
+ useMemo(updateCheckBoxes, [type])
+
+ const passwordGenerated = (checkbox, rangeValue) => {
+ const pwd =
+ rangeValue > 3 ? generatePassword(checkbox, rangeValue) : generatePassword(checkbox, 3)
+ setPassword(pwd)
+ setPasswordProps(checkbox)
+ }
+
+ const onChangeSlider = (e) => {
+ setPasswordLength(e.target.value)
+ setRangeValue(e.target.value)
+ setRange(e.target.value)
+ passwordGenerated(checkbox, e.target.value)
+ }
+
+ const onChangeCheckBox = (e) => {
+ if (type !== 'pin') {
+ const { name, checked } = e.target
+ CHECKBOX_LIST.map((checkbox) => {
+ if (checkbox.name === name) {
+ checkbox.isChecked = checked
+ setCheckBox((prevState) => ({ ...prevState, [name]: checkbox.isChecked }))
+ setPasswordLength(rangeValue)
+ setRangeValue(rangeValue)
+ }
+
+ return ''
+ })
+ }
+ }
+
+ const copyClipBoard = (elementRef) => (e) => {
+ e.preventDefault()
+ copyToClipBoard(elementRef)
+ }
+
+ return (
+
+
Use the slider, and select from the options.
+
+
+
+
+
+
+ {CHECKBOX_LIST.map((checkbox) => (
+
+ ))}
+
+
+
+
+
+
+
+ )
+}
+
+export default Container
diff --git a/src/components/mvpsdvlpr/container/button/Button.jsx b/src/components/mvpsdvlpr/container/button/Button.jsx
new file mode 100644
index 000000000..619abb33e
--- /dev/null
+++ b/src/components/mvpsdvlpr/container/button/Button.jsx
@@ -0,0 +1,15 @@
+import React from 'react'
+
+const Button = (props) => {
+ const { label, className, iconClass, handleClick } = props
+
+ return (
+ <>
+
+ >
+ )
+}
+
+export default Button
diff --git a/src/components/mvpsdvlpr/container/checkbox/CheckBox.jsx b/src/components/mvpsdvlpr/container/checkbox/CheckBox.jsx
new file mode 100644
index 000000000..41273ebfe
--- /dev/null
+++ b/src/components/mvpsdvlpr/container/checkbox/CheckBox.jsx
@@ -0,0 +1,28 @@
+import React from 'react'
+
+import '../../styles/CheckBox.css'
+const CheckBox = (props) => {
+ const { label, value, checked, name, onChange, disabled } = props
+
+ return (
+ <>
+
+
+
+ >
+ )
+}
+
+export default CheckBox
diff --git a/src/components/mvpsdvlpr/container/slider/Slider.jsx b/src/components/mvpsdvlpr/container/slider/Slider.jsx
new file mode 100644
index 000000000..27783b08b
--- /dev/null
+++ b/src/components/mvpsdvlpr/container/slider/Slider.jsx
@@ -0,0 +1,54 @@
+import React, { useState, useRef } from 'react'
+
+import '../../styles/Slider.css'
+
+const Slider = (props) => {
+ const { step, min, max, value, defaultLength, onChangeValue } = props
+
+ const rangeRef = useRef()
+ let [range, setRange] = useState()
+
+ const activeRangeColor = '#4aa1f3'
+ const rangeBackground = '#d7dcdf'
+
+ const handleChange = (max) => (e) => {
+ onChangeValue(e)
+ const value = e.target.value
+ setRange(value)
+ const progress = (value / max) * 100 + '%'
+ const newBackgroundStyle = `linear-gradient(90deg, ${activeRangeColor} 0% ${progress}, ${rangeBackground} ${progress} 100%)`
+ rangeRef.current.style.background = newBackgroundStyle
+ }
+
+ if (range !== defaultLength || !range) {
+ range = defaultLength
+ }
+
+ const progressValue = range
+ const progress = (progressValue / max) * 100 + '%'
+
+ const styleInput = {
+ background: `linear-gradient(90deg, ${activeRangeColor} 0% ${progress}, ${rangeBackground} ${progress} 100%)`
+ }
+
+ return (
+
+
+
+ {progressValue}
+
+
+ )
+}
+
+export default Slider
diff --git a/src/components/mvpsdvlpr/container/tooltip/Tooltip.jsx b/src/components/mvpsdvlpr/container/tooltip/Tooltip.jsx
new file mode 100644
index 000000000..5512d8ddc
--- /dev/null
+++ b/src/components/mvpsdvlpr/container/tooltip/Tooltip.jsx
@@ -0,0 +1,22 @@
+import React from 'react'
+
+import '../../styles/Tooltip.css'
+const Tooltip = (props) => {
+ const { message, position, displayTooltip } = props
+
+ return (
+ <>
+ {displayTooltip
+ ? (
+
+ )
+ : (
+ ''
+ )}
+ >
+ )
+}
+
+export default Tooltip
diff --git a/src/components/mvpsdvlpr/styles/CheckBox.css b/src/components/mvpsdvlpr/styles/CheckBox.css
new file mode 100644
index 000000000..66c65618e
--- /dev/null
+++ b/src/components/mvpsdvlpr/styles/CheckBox.css
@@ -0,0 +1,73 @@
+.checkbox-container {
+ margin: 0 auto;
+ text-align: center;
+ bottom: 10px;
+}
+
+.container {
+ display: block;
+ position: relative;
+ padding-left: 35px;
+ margin-bottom: 12px;
+ cursor: pointer;
+ font-size: 20px;
+ user-select: none;
+}
+
+.container h1 {
+ font-size: 20px;
+ font-weight: normal;
+}
+
+/* Hide the browser's default checkbox */
+.container .checkbox-input {
+ position: absolute;
+ opacity: 0;
+ cursor: pointer;
+ height: 0;
+ width: 0;
+}
+
+/* Create a custom checkbox */
+.checkmark {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 25px;
+ width: 25px;
+ background-color: #eee;
+ float: right;
+}
+
+/* On mouse-over, add a grey background color */
+.container:hover input ~ .checkmark {
+ background-color: #ccc;
+}
+
+/* When the checkbox is checked, add a blue background */
+.container input:checked ~ .checkmark {
+ background-color: #2196f3;
+}
+
+/* Create the checkmark/indicator (hidden when not checked) */
+.checkmark::after {
+ content: '';
+ position: absolute;
+ display: none;
+}
+
+/* Style the checkmark/indicator */
+.container .checkmark::after {
+ left: 10px;
+ top: 7px;
+ width: 5px;
+ height: 10px;
+ border: solid white;
+ border-width: 0 3px 3px 0;
+ transform: rotate(45deg);
+}
+
+/* Show the checkmark when checked */
+.container input:checked ~ .checkmark::after {
+ display: block;
+}
diff --git a/src/components/mvpsdvlpr/styles/Container.css b/src/components/mvpsdvlpr/styles/Container.css
new file mode 100644
index 000000000..916cda64c
--- /dev/null
+++ b/src/components/mvpsdvlpr/styles/Container.css
@@ -0,0 +1,19 @@
+.password-settings {
+ border: 1px solid #eaeaea;
+ border-radius: 5px;
+ background-color: #fff;
+ max-width: 800px;
+ margin: -10px auto 15px;
+ padding: 25px;
+}
+
+.password-settings h3 {
+ font-size: 18px;
+ font-weight: normal;
+}
+
+.password-btn {
+ background-color: #4aa1f3;
+ color: #fff !important;
+ font-weight: 600;
+}
diff --git a/src/components/mvpsdvlpr/styles/Display.css b/src/components/mvpsdvlpr/styles/Display.css
new file mode 100644
index 000000000..e38d376c6
--- /dev/null
+++ b/src/components/mvpsdvlpr/styles/Display.css
@@ -0,0 +1,36 @@
+.password-display-container {
+ border: 1px solid #eaeaea;
+ border-radius: 5px;
+ background-color: #cb473e;
+ display: flex;
+ position: relative;
+ max-width: 1100px;
+ height: 150px;
+ margin: 0 auto 10px;
+}
+
+.password-display {
+ width: 100%;
+ max-width: auto;
+ border: 0;
+ color: white;
+ font-size: 1.4rem;
+ text-align: left;
+ padding-left: 5px;
+ height: 100%;
+ line-height: 150px;
+}
+
+.password-display-input {
+ background-color: inherit;
+ border: none !important;
+ outline: none !important;
+ color: white;
+ height: 50%;
+ width: 100%;
+ font-weight: bold;
+}
+
+.password-display-input::selection {
+ background: none;
+}
diff --git a/src/components/mvpsdvlpr/styles/Header.css b/src/components/mvpsdvlpr/styles/Header.css
new file mode 100644
index 000000000..80ffb55be
--- /dev/null
+++ b/src/components/mvpsdvlpr/styles/Header.css
@@ -0,0 +1,18 @@
+.header {
+ color: #282c34;
+ position: relative;
+ padding: 55px 0;
+ text-align: center;
+}
+
+.h1 {
+ color: #ff554f;
+ font-size: 2.5rem !important;
+ text-align: center;
+ padding: 0 10px;
+}
+
+h4 {
+ color: #506175;
+ font-size: 1.5rem;
+}
diff --git a/src/components/mvpsdvlpr/styles/Slider.css b/src/components/mvpsdvlpr/styles/Slider.css
new file mode 100644
index 000000000..bd1d0417e
--- /dev/null
+++ b/src/components/mvpsdvlpr/styles/Slider.css
@@ -0,0 +1,73 @@
+.slider-container {
+ margin-bottom: 50px;
+}
+
+.slider {
+ width: 100%;
+}
+
+.range-slider {
+ appearance: none;
+ width: 90%;
+ height: 10px;
+ border-radius: 5px;
+ background: #d7dcdf;
+ outline: none;
+ padding: 0;
+ margin: 0;
+}
+
+.range-slider::-webkit-slider-thumb {
+ appearance: none;
+ width: 20px;
+ height: 20px;
+ border-radius: 50%;
+ background: #4aa1f3;
+ cursor: pointer;
+ box-shadow: 0 0 0 3px #fff, 0 0 0 6px #4aa1f3;
+ transition: background 0.15s ease-in-out;
+}
+
+.range-slider:active::-webkit-slider-thumb {
+ background: #4aa1f3;
+}
+
+.range-slider::-moz-range-thumb {
+ width: 20px;
+ height: 20px;
+ border: 0;
+ border-radius: 50%;
+ background: red;
+ cursor: pointer;
+ transition: background 0.15s ease-in-out;
+}
+
+::-moz-range-track {
+ background: #fff;
+ border: 0;
+}
+
+.range-slider-value {
+ display: inline-block;
+ position: relative;
+ width: 60px;
+ color: #fff;
+ line-height: 20px;
+ text-align: center;
+ border-radius: 3px;
+ background: #4aa1f3;
+ padding: 5px 10px;
+ margin-left: 12px;
+}
+
+.range-slider-value::after {
+ position: absolute;
+ top: 8px;
+ left: -7px;
+ width: 0;
+ height: 0;
+ border-top: 7px solid transparent;
+ border-right: 7px solid #4aa1f3;
+ border-bottom: 7px solid transparent;
+ content: '';
+}
diff --git a/src/components/mvpsdvlpr/styles/Tooltip.css b/src/components/mvpsdvlpr/styles/Tooltip.css
new file mode 100644
index 000000000..63953a253
--- /dev/null
+++ b/src/components/mvpsdvlpr/styles/Tooltip.css
@@ -0,0 +1,90 @@
+.tooltip {
+ position: relative;
+}
+
+.tooltip-bubble {
+ min-width: 120px;
+ max-width: 210px;
+ position: absolute;
+ z-index: 10;
+}
+
+.tooltip-bubble::after {
+ content: '';
+ position: absolute;
+}
+
+.tooltip-top {
+ bottom: 100%;
+ left: 50%;
+ padding-bottom: 9px;
+ transform: translateX(-50%);
+}
+
+.tooltip-top::after {
+ border-left: 9px solid transparent;
+ border-right: 9px solid transparent;
+ border-top: 9px solid rgb(0 0 0 / 50%);
+ bottom: 0;
+ left: 50%;
+ transform: translateX(-50%);
+}
+
+.tooltip-bottom {
+ top: 100%;
+ left: 50%;
+ padding-top: 9px;
+ transform: translateX(-50%);
+}
+
+.tooltip-bottom::after {
+ border-left: 9px solid transparent;
+ border-right: 9px solid transparent;
+ border-bottom: 9px solid #fff;
+ top: 0;
+ left: 50%;
+ transform: translateX(-50%);
+}
+
+.tooltip-left {
+ top: 50%;
+ right: 100%;
+ padding-right: 9px;
+ transform: translateY(-50%);
+}
+
+.tooltip-left::after {
+ border-left: 9px solid rgb(0 0 0 / 50%);
+ border-top: 9px solid transparent;
+ border-bottom: 9px solid transparent;
+ top: 50%;
+ right: 0;
+ transform: translateY(-50%);
+}
+
+.tooltip-right {
+ top: 50%;
+ left: 100%;
+ padding-left: 9px;
+ transform: translateY(-50%);
+}
+
+.tooltip-right::after {
+ border-right: 9px solid rgb(0 0 0 / 50%);
+ border-top: 9px solid transparent;
+ border-bottom: 9px solid transparent;
+ top: 50%;
+ left: 0;
+ transform: translateY(-50%);
+}
+
+.tooltip-message {
+ background: rgb(0 0 0 / 50%);
+ border-radius: 3px;
+ color: #fff;
+ font-size: 0.75rem;
+ line-height: 1.4;
+ padding: 0.75em;
+ text-align: center;
+ transition: opacity 1s ease-in-out;
+}
diff --git a/src/components/mvpsdvlpr/utils/Helpers.js b/src/components/mvpsdvlpr/utils/Helpers.js
new file mode 100644
index 000000000..6996cbc05
--- /dev/null
+++ b/src/components/mvpsdvlpr/utils/Helpers.js
@@ -0,0 +1,75 @@
+let characters = ''
+let passwordLength = 0
+
+const setUpperCase = (isUpperCase) => {
+ if (isUpperCase) {
+ characters += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ }
+ return ''
+}
+
+const setLowerCase = (isLowerCase) => {
+ if (isLowerCase) {
+ characters += 'abcdefghijklmnopqrstuvwxyz'
+ }
+ return ''
+}
+
+const setSymbols = (isSymbol) => {
+ if (isSymbol) {
+ characters += '!@#$%^&*()<>,.?/[]{}-=_+|/'
+ }
+ return ''
+}
+
+const setNumber = (isNumeric) => {
+ if (isNumeric) {
+ characters += '0123456789'
+ }
+ return ''
+}
+
+const getRandomInteger = (min, max) => {
+ return Math.floor(Math.random() * (max - min + 1)) + min
+}
+
+const passwordCharacters = () => {
+ const characterList = characters
+ let password = ''
+ if (characterList.length > 0) {
+ for (let i = 0; i < passwordLength; i++) {
+ password += characterList[getRandomInteger(0, characterList.length - 1)]
+ }
+ characters = ''
+ passwordLength = 0
+
+ return password
+ }
+}
+
+export const setPasswordLength = (length) => {
+ passwordLength = length
+ return passwordLength
+}
+
+export const generatePasswordLength = () => {
+ return passwordLength
+}
+
+export const generatePassword = (passwordProps, pwdLength) => {
+ const { uppercase, lowercase, symbols, numbers } = passwordProps
+
+ setPasswordLength(pwdLength)
+ setUpperCase(uppercase)
+ setLowerCase(lowercase)
+ setSymbols(symbols)
+ setNumber(numbers)
+
+ const password = passwordCharacters()
+ return password
+}
+
+export const copyToClipBoard = (elementRef) => {
+ elementRef.select()
+ document.execCommand('copy')
+}
diff --git a/src/pages/entry/mvpsdvlpr/index.astro b/src/pages/entry/mvpsdvlpr/index.astro
new file mode 100644
index 000000000..8b7186774
--- /dev/null
+++ b/src/pages/entry/mvpsdvlpr/index.astro
@@ -0,0 +1,8 @@
+---
+import Layout from '@layout'
+import Generatorpsswrd from '@components/mvpsdvlpr/Generatorpsswrd'
+---
+
+
+
+