diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b512c09
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+node_modules
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..3515d20
--- /dev/null
+++ b/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "keeper-web-app",
+ "version": "1.0.0",
+ "description": "",
+ "keywords": [],
+ "main": "src/index.js",
+ "dependencies": {
+ "@material-ui/core": "4.6.1",
+ "@material-ui/icons": "4.5.1",
+ "react": "16.8.6",
+ "react-dom": "16.8.6",
+ "react-scripts": "3.2.0",
+ "uuid": "3.3.3"
+ },
+ "devDependencies": {
+ "typescript": "3.3.3"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test --env=jsdom",
+ "eject": "react-scripts eject"
+ },
+ "browserslist": [
+ ">0.2%",
+ "not dead",
+ "not ie <= 11",
+ "not op_mini all"
+ ]
+}
\ No newline at end of file
diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..1fdff70
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,16 @@
+
+
+
+ Keeper App
+
+
+
+
+
+
+
+
+
+
diff --git a/public/styles.css b/public/styles.css
new file mode 100644
index 0000000..7aad295
--- /dev/null
+++ b/public/styles.css
@@ -0,0 +1,103 @@
+* {
+ padding: 0;
+ margin: 0;
+ box-sizing: border-box;
+}
+html {
+ font-family: "Montserrat", sans-serif;
+}
+body {
+ background: #eee;
+ background-image: url("https://www.transparenttextures.com/patterns/cubes.png");
+ padding: 0 16px;
+}
+
+header {
+ background-color: #f5ba13;
+ margin: auto -16px;
+ padding: 16px 32px;
+ box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3);
+}
+
+header h1 {
+ color: #fff;
+ font-family: "McLaren", cursive;
+ font-weight: 200;
+}
+
+footer {
+ position: absolute;
+ text-align: center;
+ bottom: 0;
+ width: 100%;
+ height: 2.5rem;
+}
+
+footer p {
+ color: #ccc;
+}
+.note {
+ background: #fff;
+ border-radius: 7px;
+ box-shadow: 0 2px 5px #ccc;
+ padding: 10px;
+ width: 240px;
+ margin: 16px;
+ float: left;
+}
+.note h1 {
+ font-size: 1.1em;
+ margin-bottom: 6px;
+}
+.note p {
+ font-size: 1.1em;
+ margin-bottom: 10px;
+ white-space: pre-wrap;
+ word-wrap: break-word;
+}
+
+.note button {
+ position: relative;
+ float: right;
+ margin-right: 10px;
+ color: #f5ba13;
+ border: none;
+ width: 36px;
+ height: 36px;
+ cursor: pointer;
+ outline: none;
+}
+
+form.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);
+}
+form.create-note input,
+form.create-note textarea {
+ width: 100%;
+ border: none;
+ padding: 4px;
+ outline: none;
+ font-size: 1.2em;
+ font-family: inherit;
+ resize: none;
+}
+form.create-note 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;
+}
diff --git a/src/components/App.jsx b/src/components/App.jsx
new file mode 100644
index 0000000..7d8fb97
--- /dev/null
+++ b/src/components/App.jsx
@@ -0,0 +1,44 @@
+import React, { useState } from "react";
+import Header from "./Header";
+import Footer from "./Footer";
+import Note from "./Note";
+import CreateArea from "./CreateArea";
+
+function App() {
+ const [notes, setNotes] = useState([]);
+
+ function addNote(newNote) {
+ setNotes(prevNotes => {
+ return [...prevNotes, newNote];
+ });
+ }
+
+ function deleteNote(id) {
+ setNotes(prevNotes => {
+ return prevNotes.filter((noteItem, index) => {
+ return index !== id;
+ });
+ });
+ }
+
+ return (
+
+
+
+ {notes.map((noteItem, index) => {
+ return (
+
+ );
+ })}
+
+
+ );
+}
+
+export default App;
diff --git a/src/components/CreateArea.jsx b/src/components/CreateArea.jsx
new file mode 100644
index 0000000..5c5a0ed
--- /dev/null
+++ b/src/components/CreateArea.jsx
@@ -0,0 +1,68 @@
+import React, { useState } from "react";
+import AddIcon from "@material-ui/icons/Add";
+import Fab from "@material-ui/core/Fab";
+import Zoom from "@material-ui/core/Zoom";
+
+function CreateArea(props) {
+ const [isExpanded, setExpanded] = useState(false);
+
+ const [note, setNote] = useState({
+ title: "",
+ content: ""
+ });
+
+ function handleChange(event) {
+ const { name, value } = event.target;
+
+ setNote(prevNote => {
+ return {
+ ...prevNote,
+ [name]: value
+ };
+ });
+ }
+
+ function submitNote(event) {
+ props.onAdd(note);
+ setNote({
+ title: "",
+ content: ""
+ });
+ event.preventDefault();
+ }
+
+ function expand() {
+ setExpanded(true);
+ }
+
+ return (
+
+ );
+}
+
+export default CreateArea;
diff --git a/src/components/Footer.jsx b/src/components/Footer.jsx
new file mode 100644
index 0000000..870e403
--- /dev/null
+++ b/src/components/Footer.jsx
@@ -0,0 +1,12 @@
+import React from "react";
+
+function Footer() {
+ const year = new Date().getFullYear();
+ return (
+
+ );
+}
+
+export default Footer;
diff --git a/src/components/Header.jsx b/src/components/Header.jsx
new file mode 100644
index 0000000..26e0015
--- /dev/null
+++ b/src/components/Header.jsx
@@ -0,0 +1,15 @@
+import React from "react";
+import HighlightIcon from "@material-ui/icons/Highlight";
+
+function Header() {
+ return (
+
+ );
+}
+
+export default Header;
diff --git a/src/components/Note.jsx b/src/components/Note.jsx
new file mode 100644
index 0000000..042c69a
--- /dev/null
+++ b/src/components/Note.jsx
@@ -0,0 +1,20 @@
+import React from "react";
+import DeleteIcon from "@material-ui/icons/Delete";
+
+function Note(props) {
+ function handleClick() {
+ props.onDelete(props.id);
+ }
+
+ return (
+
+
{props.title}
+
{props.content}
+
+
+ );
+}
+
+export default Note;
diff --git a/src/index.js b/src/index.js
new file mode 100644
index 0000000..0b68bb1
--- /dev/null
+++ b/src/index.js
@@ -0,0 +1,5 @@
+import React from "react";
+import ReactDOM from "react-dom";
+import App from "./components/App";
+
+ReactDOM.render(, document.getElementById("root"));