diff --git a/src/meta/play-meta.js b/src/meta/play-meta.js
index 22057fdc9a..7d6afa6e65 100644
--- a/src/meta/play-meta.js
+++ b/src/meta/play-meta.js
@@ -12,7 +12,8 @@ import {
ReactTodoApp,
ExpandingCards,
AnalogClock,
- //import play here
+ PasswordGenerator,
+//import play here
} from "plays";
export const plays = [
@@ -185,5 +186,17 @@ export const plays = [
cover: "",
blog: "",
video: "",
+ }, {
+ id: 'pl-password-generator',
+ name: 'Password Generator',
+ description: 'Its a simple password generator built in react using what user can generate password and customize their requirements in choosing characters and number while generating a medium or strong level password.',
+ component: () => {return },
+ path: '/plays/password-generator',
+ level: 'Beginner',
+ tags: 'PasswordGenerator',
+ github: 'Angryman18',
+ cover: 'https://securityintelligence.com/wp-content/uploads/2018/10/si-eight-character-password-feature.jpg',
+ blog: '',
+ video: ''
}, //replace new play item here
];
diff --git a/src/plays/index.js b/src/plays/index.js
index 1353b6d97b..95867efe46 100644
--- a/src/plays/index.js
+++ b/src/plays/index.js
@@ -14,4 +14,5 @@ export { default as ReactTodoApp } from 'plays/react-todo-app/ReactTodoApp';
export { default as ExpandingCards } from 'plays/expanding-cards/ExpandingCards';
export { default as AnalogClock } from 'plays/analog-clock/AnalogClock';
+export { default as PasswordGenerator } from 'plays/password-generator/PasswordGenerator';
//add export here
diff --git a/src/plays/password-generator/PasswordGenerator.jsx b/src/plays/password-generator/PasswordGenerator.jsx
new file mode 100644
index 0000000000..d378ebd0de
--- /dev/null
+++ b/src/plays/password-generator/PasswordGenerator.jsx
@@ -0,0 +1,205 @@
+import { getPlayById } from "meta/play-meta-util";
+
+import PlayHeader from "common/playlists/PlayHeader";
+import { useEffect, useState } from "react";
+
+import "./password-generator-style.css";
+import data from "./data.json";
+
+const config = {
+ length: 12,
+ numbers: true,
+ special: true,
+ uppercase: true,
+ lowercase: true,
+};
+
+function PasswordGenerator(props) {
+ // Do not remove the below lines.
+ // The following code is to fetch the current play from the URL
+ const { id } = props;
+ const play = getPlayById(id);
+
+ // Your Code Start below.
+ const [password, setPassword] = useState({ status: false, password: "" });
+ const [passwordConfig, setPasswordConfig] = useState({ ...config });
+ const [error, setError] = useState(false);
+
+ // generating lowercase characters
+ data.lowercase = data?.uppercase?.map((i) => i.toLowerCase());
+
+ // generate a random number within limit which is provided
+ const randomNumberGenerator = (limit) => {
+ let result = 0;
+ while (limit) {
+ result = Math.floor(Math.random() * Math.floor(Math.random() * 100));
+ if (result < limit) return result;
+ continue;
+ }
+ };
+
+ // arrange data to feed the generatePassword function
+ const arrangeData = () => {
+ const { numbers, special, uppercase, lowercase } = passwordConfig;
+
+ const parseData = (val, key) => {
+ if (val) return data[key];
+ return [];
+ };
+
+ const concated = [
+ ...parseData(numbers, "numbers"),
+ ...parseData(special, "special"),
+ ...parseData(uppercase, "uppercase"),
+ ...parseData(lowercase, "lowercase"),
+ ];
+ return concated;
+ };
+
+ // Generate a random password
+ const generatePassword = () => {
+ setError(false);
+ const concated = arrangeData();
+ let finalPassword = "";
+ for (let i = 0; i < passwordConfig.length; i++) {
+ finalPassword += concated[randomNumberGenerator(concated.length)];
+ }
+ return finalPassword;
+ };
+
+ // generate password button click handler
+ const generateHander = () => {
+ const finalPassword = generatePassword();
+ setPassword({ status: false, password: finalPassword });
+ };
+
+ // handling checkbox and updating the config
+ const handleCheckedItem = (name, checked) => {
+ const modifiedConfig = { ...passwordConfig };
+ delete modifiedConfig.length;
+ delete modifiedConfig.excludeSimilarCharacters;
+ modifiedConfig[name] = checked;
+ const values = Object.values(modifiedConfig).filter((i) => i === true);
+ if (values.length === 0) {
+ return setError(true);
+ }
+ setPasswordConfig({ ...passwordConfig, [name]: checked });
+ setError(false);
+ };
+
+ // Copy the password to the clipboard
+ const onCopyClick = (e) => {
+ e.preventDefault();
+ navigator.clipboard.writeText(password.password);
+ setPassword({ ...password, status: true });
+ };
+
+ useEffect(() => {
+ generateHander();
+ }, []);
+
+ const ErrorBox = () => {
+ return
You cannot Uncheck All At Once.
;
+ };
+
+ return (
+
+
+
+ {/* Your Code Starts Here */}
+
+
Password Generator
+
+ {error && }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Your Code Ends Here */}
+
+
+ );
+}
+
+const CheckBox = ({ name, checked, getCheckedItem, id }) => {
+ const checkboxChangeHandler = (id) => (e) => {
+ getCheckedItem(id, e.target.checked);
+ };
+
+ return (
+
+
+
+
+ );
+};
+
+export default PasswordGenerator;
diff --git a/src/plays/password-generator/Readme.md b/src/plays/password-generator/Readme.md
new file mode 100644
index 0000000000..e7de99062c
--- /dev/null
+++ b/src/plays/password-generator/Readme.md
@@ -0,0 +1,16 @@
+# Password Generator
+The `Password Generator` project is a fun project which shows the usecase of some concept in ReactJS.
+
+- Multiple Checkbox Handling.
+- Managing Complex logic to generate random password
+- Use and manage multiple nested `useState` hooks
+- Use of `useEffect` hook in ReactJS.
+- Also how to copy text and handle error are shown.
+
+# File Contents
+
+For now all the necessary components, functions and logics are managed inside `PasswordGenerator.jsx` file.and the css are contained inside `password-generator-style.css`
+
+also there is a `data.json` which is the main source and feeding requied data into the `PasswordGenerator.jsx` component.
+
+Happy Learning!
\ No newline at end of file
diff --git a/src/plays/password-generator/data.json b/src/plays/password-generator/data.json
new file mode 100644
index 0000000000..d450eeb5d3
--- /dev/null
+++ b/src/plays/password-generator/data.json
@@ -0,0 +1,5 @@
+{
+ "uppercase": ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"],
+ "numbers": ["0","1","2","3","4","5","6","7","8","9"],
+ "special": ["!","@","#","$","%","^","&","*","(",")","-","_","=","+","[","{","]","}","|",";",":","'","\"",",",".","<",">","/","?"]
+}
\ No newline at end of file
diff --git a/src/plays/password-generator/password-generator-style.css b/src/plays/password-generator/password-generator-style.css
new file mode 100644
index 0000000000..308b676d37
--- /dev/null
+++ b/src/plays/password-generator/password-generator-style.css
@@ -0,0 +1,138 @@
+
+
+.main {
+ padding: 0;
+ margin: 0;
+ box-sizing: border-box;
+}
+
+.title {
+ text-align: center;
+}
+
+.section {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+}
+
+.section > div:nth-of-type(2) {
+ position: relative;
+ /* background-color: black; */
+}
+
+.copy-button {
+ position: absolute;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ border: 2px solid #187B86;
+ border-left: none;
+ border-bottom-right-radius: 5px;
+ border-top-right-radius: 5px;
+ padding: 0 10px;
+ font-size: 20px;
+ background-color: #187B86;
+ outline: none;
+ color: white;
+ transition: 100ms;
+}
+
+.copy-button:hover {
+ background-color: #135088;
+ border: 2px solid #135088;
+ border-left: none;
+}
+
+.copid {
+ background-color: #135088;
+ border: 2px solid #135088;
+ border-left: none;
+}
+
+.section > div:nth-of-type(1) {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ grid-template-rows: 1fr 1fr;
+ width: 400px;
+ column-gap: 25px;
+ row-gap: 20px;
+ margin: 25px 0;
+}
+
+.password-input {
+ padding: 10px;
+ outline: none;
+ border: 2px solid #ccc;
+ border-radius: 5px;
+ font-size: 1.3rem;
+ font-weight: bold;
+ width: 400px;
+ /* max-width: 400px; */
+ color: gray;
+}
+
+
+.generate {
+ padding: 10px 1rem;
+ outline: none;
+ font-size: 1.5rem;
+ outline: none;
+ background: rgb(0,128,0, 0.8);
+ border: none;
+ color: white;
+ cursor: pointer;
+ border-radius: 5px;
+ transition: 100ms;
+}
+
+.generate:hover {
+ background: rgb(0,128,0, 1);
+}
+
+.checkbox-comp {
+ padding: 0;
+ margin: 0;
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.checkbox {
+ width: 20px;
+ height: 20px;
+ float: right;
+}
+
+.select {
+ width: 45px;
+ height: 25px;
+ font-size: 1rem;
+ float: right;
+ margin: 0;
+}
+
+.error {
+ color: red;
+ font-size: 1rem;
+ text-align: center;
+}
+
+@media screen and (max-width: 600px) {
+ .section > div:nth-of-type(1) {
+ grid-template-columns: 1fr;
+ grid-template-rows: 1fr;
+ width: 100%;
+ }
+
+ .password-input {
+ font-size: 1rem;
+ width: 100%;
+ }
+ .copy-button {
+ padding: 0 5px;
+ font-size: 16px;
+ }
+}
\ No newline at end of file