+
+ >
+}
+export default Header;
\ No newline at end of file
diff --git a/src/plays/keeper/Hooks/useLocalStorage.js b/src/plays/keeper/Hooks/useLocalStorage.js
new file mode 100644
index 0000000000..da842b6fb8
--- /dev/null
+++ b/src/plays/keeper/Hooks/useLocalStorage.js
@@ -0,0 +1,35 @@
+import { useState } from "react";
+
+function useLocalStorage(key, initialValue) {
+ // State to store our value
+ // Pass initial state function to useState so logic is only executed once
+ const [storedValue, setStoredValue] = useState(() => {
+ try {
+ // Get from local storage by key
+ const item = localStorage.getItem(key);
+ // Parse stored json or if none return initialValue
+ return item ? JSON.parse(item) : initialValue;
+ } catch (error) {
+ // If error also return initialValue
+ return initialValue;
+ }
+ });
+ // Return a wrapped version of useState's setter function that ...
+ // ... persists the new value to localStorage.
+ const setValue = (value) => {
+ try {
+ // Allow value to be a function so we have same API as useState
+ const valueToStore =
+ value instanceof Function ? value(storedValue) : value;
+ // Save state
+ setStoredValue(valueToStore);
+ // Save to local storage
+ window.localStorage.setItem(key, JSON.stringify(valueToStore));
+ } catch (error) {
+ // A more advanced implementation would handle the error case
+ console.log(error);
+ }
+ };
+ return [storedValue, setValue];
+}
+export default useLocalStorage;
\ No newline at end of file
diff --git a/src/plays/keeper/Keeper.css b/src/plays/keeper/Keeper.css
new file mode 100644
index 0000000000..47f4ec4dc1
--- /dev/null
+++ b/src/plays/keeper/Keeper.css
@@ -0,0 +1,121 @@
+.head {
+ background-color: #f5ba13;
+ margin: auto -16px;
+ padding: 16px 32px;
+ box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3);
+}
+
+.headsHeading {
+ color: #fff;
+ font-weight: 200;
+}
+
+.note {
+ background: #fff;
+ border-radius: 7px;
+ box-shadow: 0 2px 5px #ccc;
+ padding: 10px;
+ width: 240px;
+ margin: 16px;
+ float: left;
+}
+
+.notesHeading {
+ font-size: 1.1em;
+ margin-bottom: 6px;
+}
+
+.notesPara {
+ font-size: 1.1em;
+ margin-bottom: 10px;
+ white-space: pre-wrap;
+ word-wrap: break-word;
+}
+
+.notesButton {
+ position: relative;
+ float: right;
+ margin-right: 10px;
+ color: #f5ba13;
+ border: none;
+ width: 36px;
+ height: 36px;
+ cursor: pointer;
+ outline: none;
+}
+
+.create-note {
+ position: relative;
+ width: 480px;
+ margin: 30px auto 20px auto;
+ background: #fff;
+ padding: 15px;
+ border-radius: 7px;
+ box-shadow: 0 1px 5px rgb(138, 137, 137);
+}
+
+.create-note .create-input,
+.create-note .create-text {
+ width: 100%;
+ border: none;
+ padding: 4px;
+ outline: none;
+ font-size: 1.2em;
+ resize: none;
+}
+
+.create-note .create-button {
+ position: absolute;
+ right: 18px;
+ bottom: -18px;
+ background: #f5ba13;
+ color: #fff;
+ border: none;
+ border-radius: 50%;
+ width: 36px;
+ height: 36px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
+ cursor: pointer;
+ outline: none;
+}
+
+.create-button:hover {
+ background-color: black;
+}
+
+/* Media Query */
+
+@media(max-width: 514px) {
+ .create-note {
+ width: 21rem;
+ }
+}
+@media(max-width: 358px) {
+ .create-note {
+ width: 13rem;
+ }
+}
+@media(max-width: 304px) {
+ .create-note {
+ width: 12rem;
+ }
+ .note{
+ width:205px;
+ }
+}
+@media(max-width: 269px) {
+ .create-note {
+ width: 11rem;
+ }
+ .note{
+ width:182px;
+ }
+}
+@media(max-width: 269px) {
+ .create-note {
+ width: 9rem;
+ }
+ .note{
+ width:170px;
+ }
+}
diff --git a/src/plays/keeper/Keeper.jsx b/src/plays/keeper/Keeper.jsx
new file mode 100644
index 0000000000..b63b58203d
--- /dev/null
+++ b/src/plays/keeper/Keeper.jsx
@@ -0,0 +1,59 @@
+import { getPlayById } from 'meta/play-meta-util';
+import PlayHeader from 'common/playlists/PlayHeader';
+import './Keeper.css'
+import Header from './Header';
+import CreateArea from './CreateArea';
+import Note from './Notes';
+import useLocalStorage from './Hooks/useLocalStorage';
+
+function Keeper(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);
+ //code starts here
+ const [notes, setNotes] = useLocalStorage("notes", [
+ {
+ id: 0,
+ title: "Write Your Title",
+ content: "And, content here. :)"
+ }
+ ]); //notes array
+ //adding notes
+ function addNote(newNote) {
+ setNotes((prevNotes) => {
+ return [...prevNotes, newNote];
+ });
+ }
+ //deleting notes
+ function deleteNote(id) {
+ setNotes(prevNotes => {
+ return prevNotes.filter((noteItem, index) => {
+ return index !== id;
+ })
+ })
+ }
+ return (
+ <>
+
+
+
+ {/* Your Code Starts Here */}
+
+
+ {notes.map((noteItem, index) => {
+ return
+ })}
+
+
+ {/* Your Code Ends Here */}
+ >
+ );
+}
+export default Keeper;
\ No newline at end of file
diff --git a/src/plays/keeper/Notes.jsx b/src/plays/keeper/Notes.jsx
new file mode 100644
index 0000000000..6dc383f76d
--- /dev/null
+++ b/src/plays/keeper/Notes.jsx
@@ -0,0 +1,14 @@
+import { FaTrashAlt } from 'react-icons/fa';
+function Note(props) {
+ function handleClick() {
+ props.onDelete(props.id);
+ }
+ return <>
+
+
{props.title}
+
{props.content}
+
+
+ >
+}
+export default Note;
\ No newline at end of file
diff --git a/src/plays/keeper/README.md b/src/plays/keeper/README.md
new file mode 100644
index 0000000000..e7cd6a1cc2
--- /dev/null
+++ b/src/plays/keeper/README.md
@@ -0,0 +1,8 @@
+The `Keeper` demonstrates the following concepts in React:
+1. State & State Management in functional components.
+2. useState Hook
+3. useEffect Hook
+3. React DOM
+4. JSX
+
+This play has two input fields, one for `Title`, and another one for `Description`. After writing your notes you can click on the `add` button, and your notes will be added and will be save too until you `delete` them.