diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..59e5db6
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,4 @@
+{
+ "presets": ["es2015"],
+ "presets": ["react"]
+}
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..05b1cf3
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,5 @@
+**/node_modules/*
+**/vendor/*
+**/*.min.js
+**/coverage/*
+**/build/*
diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 0000000..8dc6807
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,21 @@
+{
+ "rules": {
+ "no-console": "off",
+ "indent": [ "error", 2 ],
+ "quotes": [ "error", "single" ],
+ "semi": ["error", "always"],
+ "linebreak-style": [ "error", "unix" ]
+ },
+ "env": {
+ "es6": true,
+ "node": true,
+ "mocha": true,
+ "jasmine": true
+ },
+ "ecmaFeatures": {
+ "modules": true,
+ "experimentalObjectRestSpread": true,
+ "impliedStrict": true
+ },
+ "extends": "eslint:recommended"
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..345130c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,136 @@
+# Created by https://www.gitignore.io/api/osx,vim,node,macos,windows
+
+### macOS ###
+*.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+### Node ###
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (http://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules/
+jspm_packages/
+
+# Typescript v1 declaration files
+typings/
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env
+
+
+### OSX ###
+
+# Icon must end with two \r
+
+# Thumbnails
+
+# Files that might appear in the root of a volume
+
+# Directories potentially created on remote AFP share
+
+### Vim ###
+# swap
+[._]*.s[a-v][a-z]
+[._]*.sw[a-p]
+[._]s[a-v][a-z]
+[._]sw[a-p]
+# session
+Session.vim
+# temporary
+.netrwhist
+*~
+# auto-generated tag files
+tags
+
+### Windows ###
+# Windows thumbnail cache files
+Thumbs.db
+ehthumbs.db
+ehthumbs_vista.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# End of https://www.gitignore.io/api/osx,vim,node,macos,windows
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..d8fafa1
--- /dev/null
+++ b/package.json
@@ -0,0 +1,40 @@
+{
+ "name": "23-components_and_routing",
+ "version": "1.0.0",
+ "description": " 23: Components and Routing ======",
+ "main": "index.js",
+ "scripts": {
+ "build": "webpack",
+ "watch": "webpack-dev-server --inline --hot"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/Jamesbillard12/23-components_and_routing.git"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "bugs": {
+ "url": "https://github.com/Jamesbillard12/23-components_and_routing/issues"
+ },
+ "homepage": "https://github.com/Jamesbillard12/23-components_and_routing#readme",
+ "dependencies": {
+ "babel-core": "^6.26.0",
+ "babel-loader": "^7.1.2",
+ "babel-preset-es2015": "^6.24.1",
+ "babel-preset-react": "^6.24.1",
+ "css-loader": "^0.28.5",
+ "extract-text-webpack-plugin": "^3.0.0",
+ "file-loader": "^0.11.2",
+ "html-webpack-plugin": "^2.30.1",
+ "node-sass": "^4.5.3",
+ "react": "^15.6.1",
+ "react-dom": "^15.6.1",
+ "react-router-dom": "^4.1.2",
+ "sass-loader": "^6.0.6",
+ "url-loader": "^0.5.9",
+ "uuid": "^3.1.0",
+ "webpack": "^3.5.5",
+ "webpack-dev-server": "^2.7.1"
+ }
+}
diff --git a/src/component/dashboard-container/index.js b/src/component/dashboard-container/index.js
new file mode 100644
index 0000000..a1c619e
--- /dev/null
+++ b/src/component/dashboard-container/index.js
@@ -0,0 +1,31 @@
+import React from 'react';
+import uuid from 'uuid/v1';
+
+import NoteCreateForm from '../note-create-form';
+
+class DashboardContainer extends React.Component {
+ constructor(props) {
+ super(props)
+ this.noteCreate = this.noteCreate.bind(this);
+ }
+
+ noteCreate(note) {
+ note.id = uuid();
+ this.props.getNote.setState(state => ({
+ notesArr: [...state.notesArr, note]
+ }));
+ }
+
+ render() {
+ return (
+
+
+
+ )
+ }
+}
+
+export default DashboardContainer;
diff --git a/src/component/navbar/assets/cloud.png b/src/component/navbar/assets/cloud.png
new file mode 100644
index 0000000..b7e4bf9
Binary files /dev/null and b/src/component/navbar/assets/cloud.png differ
diff --git a/src/component/navbar/assets/unicorn.png b/src/component/navbar/assets/unicorn.png
new file mode 100644
index 0000000..ec0b79a
Binary files /dev/null and b/src/component/navbar/assets/unicorn.png differ
diff --git a/src/component/navbar/index.js b/src/component/navbar/index.js
new file mode 100644
index 0000000..2f4418e
--- /dev/null
+++ b/src/component/navbar/index.js
@@ -0,0 +1,25 @@
+import './style/style.scss';
+
+import React from 'react';
+import {Link} from 'react-router-dom';
+
+
+class Navbar extends React.Component {
+ render() {
+ return (
+
+
+
+ Unicornotes
+
+
+
+ )
+ }
+}
+
+export default Navbar
diff --git a/src/component/navbar/style/style.scss b/src/component/navbar/style/style.scss
new file mode 100644
index 0000000..9ace9dd
--- /dev/null
+++ b/src/component/navbar/style/style.scss
@@ -0,0 +1,11 @@
+@import "src/style/theme/vars.scss";
+
+.title{
+ background-color: $brand-primary;
+ border-bottom: 1em solid $brand-tertiery;
+ background-image: url('../assets/cloud.png');
+}
+
+.unicornimg{
+ width: 10em;
+}
diff --git a/src/component/note-create-form/assets/cloud.png b/src/component/note-create-form/assets/cloud.png
new file mode 100644
index 0000000..934f21e
Binary files /dev/null and b/src/component/note-create-form/assets/cloud.png differ
diff --git a/src/component/note-create-form/assets/sun.png b/src/component/note-create-form/assets/sun.png
new file mode 100644
index 0000000..5ee6955
Binary files /dev/null and b/src/component/note-create-form/assets/sun.png differ
diff --git a/src/component/note-create-form/index.js b/src/component/note-create-form/index.js
new file mode 100644
index 0000000..5983ac8
--- /dev/null
+++ b/src/component/note-create-form/index.js
@@ -0,0 +1,69 @@
+import './style/style.scss';
+
+
+import React from 'react';
+
+class NoteCreateForm extends React.Component {
+ constructor(props) {
+ super(props);
+
+ let title = props.noteUpdate ? props.noteUpdate.title : '';
+ let content = props.noteUpdate ? props.noteUpdate.content : '';
+
+ this.state ={
+ title,
+ editing: false,
+ completed: false,
+ content
+ }
+ this.handleChange = this.handleChange.bind(this);
+ this.handleSubmit = this.handleSubmit.bind(this);
+ }
+
+ handleChange(e) {
+ this.setState({
+ [e.target.name]: e.target.value
+ })
+ }
+
+ handleSubmit(e) {
+ e.preventDefault();
+ if(this.props.submitTitle == 'Update Note') {
+ this.props.handleSubmit(this.state, this.props.noteUpdate.id);
+ }else{
+ this.props.handleSubmit(this.state);
+ }
+ }
+
+ render() {
+ return (
+
+ )
+ }
+}
+
+export default NoteCreateForm;
diff --git a/src/component/note-create-form/style/style.scss b/src/component/note-create-form/style/style.scss
new file mode 100644
index 0000000..5b526db
--- /dev/null
+++ b/src/component/note-create-form/style/style.scss
@@ -0,0 +1,58 @@
+@import "../../../style/theme/vars.scss";
+
+
+.inputContainer{
+ background-image: url('../assets/cloud.png');
+ background-repeat: no-repeat;
+ background-size: contain;
+ background-position: center;
+}
+
+.buttonContainer{
+ background-image: url('../assets/sun.png');
+ background-repeat: no-repeat;
+ background-size: contain;
+ background-position: center;
+}
+
+.button{
+ margin-top: 1em;
+ background: transparent;
+ font-size: 4vw;
+ color: #808080;
+}
+
+::-webkit-input-placeholder { /* WebKit, Blink, Edge */
+ color: #808080;
+}
+:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
+ color: #808080;
+ opacity: 1;
+}
+::-moz-placeholder { /* Mozilla Firefox 19+ */
+ color: #808080;
+ opacity: 1;
+}
+:-ms-input-placeholder { /* Internet Explorer 10-11 */
+ color: #808080;
+}
+::-ms-input-placeholder { /* Microsoft Edge */
+ color: #808080;
+}
+
+input:focus+.underline {
+ transform: scale(1);
+}
+
+.underline {
+ margin-top: 4em;
+ background-color: $brand-secodary;
+ display: inline-block;
+ height: 3px;
+ position: absolute;
+ -webkit-transform: scale(0, 1);
+ transform: scale(0, 1);
+ -webkit-transition: all 0.2s linear;
+ transition: all 0.2s linear;
+ width: 18em;
+}
diff --git a/src/component/note-item/assets/border.png b/src/component/note-item/assets/border.png
new file mode 100644
index 0000000..dc2e350
Binary files /dev/null and b/src/component/note-item/assets/border.png differ
diff --git a/src/component/note-item/index.js b/src/component/note-item/index.js
new file mode 100644
index 0000000..28da8c0
--- /dev/null
+++ b/src/component/note-item/index.js
@@ -0,0 +1,71 @@
+import './style/style.scss';
+
+import React from 'react';
+import NoteCreateForm from '../note-create-form';
+
+class NoteItem extends React.Component {
+ constructor(props){
+ super(props);
+ this.state = {
+ editing: null,
+ }
+
+ this.updateNote = this.updateNote.bind(this);
+ this.handleDelete = this.handleDelete.bind(this);
+ this.setTrue = this.setTrue.bind(this);
+ }
+
+ handleDelete() {
+ this.props.deleteNote(this.props.note.id);
+ }
+
+ setTrue() {
+ this.setState({ editing: true });
+ }
+
+ updateNote(note, id) {
+ note.id = id;
+ let notes = this.props.notesArr;
+ notes = notes.map(prevNote => {
+ return id === prevNote.id ? note : prevNote
+ });
+ this.props.app.setState({ notesArr: notes});
+ this.setState({ editing: false });
+ }
+
+ render() {
+ return (
+
+ {
+ this.state.editing == true ?
+
+ :
+
+
+
+ *{this.props.note.title}*
+
+
+
+ {this.props.note.content}
+
+
+
+
+
+
+ }
+
+ );
+ }
+}
+
+export default NoteItem;
diff --git a/src/component/note-item/style/style.scss b/src/component/note-item/style/style.scss
new file mode 100644
index 0000000..9e93576
--- /dev/null
+++ b/src/component/note-item/style/style.scss
@@ -0,0 +1,10 @@
+
+.noteStyle{
+ background-image: url('../assets/border.png');
+ background-size: contain;
+ background-repeat: no-repeat;
+}
+
+.deleteButton{
+ background: transparent;
+}
diff --git a/src/component/note-list/index.js b/src/component/note-list/index.js
new file mode 100644
index 0000000..edf03c4
--- /dev/null
+++ b/src/component/note-list/index.js
@@ -0,0 +1,31 @@
+import './style/style.scss';
+
+import React from 'react';
+import NoteItem from '../note-item';
+
+class NoteList extends React.Component {
+ constructor(props){
+ super(props);
+ }
+
+ render() {
+ return (
+
+
+ {this.props.notesArr.map((item, i) => {
+ return (
+
+ );
+ }
+ )}
+
+
+ );
+ }
+}
+
+export default NoteList;
diff --git a/src/component/note-list/style/style.scss b/src/component/note-list/style/style.scss
new file mode 100644
index 0000000..2b9e5ed
--- /dev/null
+++ b/src/component/note-list/style/style.scss
@@ -0,0 +1,8 @@
+.orderList{
+ display:flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: center;
+ align-content: center;
+ align-items: flex-start;
+}
diff --git a/src/index.html b/src/index.html
new file mode 100644
index 0000000..696b740
--- /dev/null
+++ b/src/index.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main.js b/src/main.js
new file mode 100644
index 0000000..5c5e801
--- /dev/null
+++ b/src/main.js
@@ -0,0 +1,68 @@
+import './style/main.scss';
+
+import React from 'react';
+import ReactDOM from 'react-dom';
+import {BrowserRouter, Route} from 'react-router-dom';
+
+import DashboardContainer from './component/dashboard-container';
+import NoteList from './component/note-list';
+import Navbar from './component/navbar';
+
+class App extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ notesArr: []
+ }
+ this.getNote = this.getNote.bind(this);
+ this.deleteNote = this.deleteNote.bind(this);
+ }
+
+ getNote() {
+ return {
+ state: this.state,
+ setState: this.setState.bind(this)
+ }
+ }
+
+ deleteNote(id) {
+ let notes = this.state.notesArr;
+ notes = notes.filter(note => note.id !== id);
+ this.setState({ notesArr: notes });
+ }
+
+ getApp() {
+ return {
+ state: this.state,
+ setState: this.setState.bind(this)
+ }
+ }
+
+
+
+ componentDidUpdate(){
+ console.log('___STATE___', this.state);
+ }
+
+ render() {
+ return (
+
+ )
+ }
+}
+
+ReactDOM.render(, document.getElementById('root'));
diff --git a/src/style/base/base.scss b/src/style/base/base.scss
new file mode 100644
index 0000000..483ea6d
--- /dev/null
+++ b/src/style/base/base.scss
@@ -0,0 +1,37 @@
+@import "../theme/vars.scss";
+@import url("https://fonts.googleapis.com/css?family=Bonbon");
+@import url("https://fonts.googleapis.com/css?family=Open+Sans");
+
+input{
+ border: none;
+ background: transparent;
+ outline: none;
+
+}
+
+button{
+ border: none;
+}
+
+h1{
+ font-size: 3em;
+ font-family: 'Bonbon', cursive;
+}
+
+h2{
+ font-size: 2em;
+ font-family: 'Bonbon', cursive;
+}
+
+p{
+ font-family: 'Open Sans', sans-serif;
+}
+
+html, body{
+ height: 100%;
+ background-color: $brand-secodary;
+}
+
+main{
+ height:auto;
+}
diff --git a/src/style/base/reset.scss b/src/style/base/reset.scss
new file mode 100644
index 0000000..0e5f2e0
--- /dev/null
+++ b/src/style/base/reset.scss
@@ -0,0 +1,43 @@
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, hgroup, menu, nav, section {
+ display: block;
+}
+body {
+ line-height: 1;
+}
+ol, ul {
+ list-style: none;
+}
+blockquote, q {
+ quotes: none;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: '';
+ content: none;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
diff --git a/src/style/layout/form.scss b/src/style/layout/form.scss
new file mode 100644
index 0000000..6e20057
--- /dev/null
+++ b/src/style/layout/form.scss
@@ -0,0 +1,48 @@
+form{
+ display:flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: space-around;
+ align-content: center;
+ align-items: center;
+}
+
+input {
+ margin-top: 2em;
+ margin-bottom: 1em;
+ text-align: center;
+ font-size: 4vw;
+ width: 26vw;
+}
+
+.inputContainer{
+ display:flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: center;
+ align-content: center;
+ align-items: center;
+ width:30%;
+ height:100%;
+ margin-top: 1em;
+ padding-top: 1em;
+ padding-bottom: 1em;
+}
+
+.buttonContainer{
+ display:flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: center;
+ align-content: center;
+ align-items: center;
+ width:50%;
+ height:100%;
+ margin-top: -6em;
+ padding-top: 2em;
+ padding-bottom: 2em;
+}
+
+.button{
+ margin-top: 1em;
+}
diff --git a/src/style/layout/navbar.scss b/src/style/layout/navbar.scss
new file mode 100644
index 0000000..fe22228
--- /dev/null
+++ b/src/style/layout/navbar.scss
@@ -0,0 +1,19 @@
+
+.title{
+ display:flex;
+ flex-direction: column;
+ flex-wrap: wrap;
+ justify-content: center;
+ align-content: center;
+ align-items: center;
+ padding-bottom: 1em;
+ padding-top: 1em;
+ background-repeat: no-repeat;
+ background-position: center bottom;
+ background-size: contain;
+}
+
+.titleName{
+ padding-top: 1vw;
+ margin-bottom: 1em;
+}
diff --git a/src/style/layout/note.scss b/src/style/layout/note.scss
new file mode 100644
index 0000000..0701416
--- /dev/null
+++ b/src/style/layout/note.scss
@@ -0,0 +1,70 @@
+.noteStyle{
+ display:flex;
+ flex-direction: column;
+ flex-wrap: wrap;
+ justify-content: flex-start;
+ align-content: center;
+ align-items: flex-start;
+ word-wrap: break-word;
+ height: 30em;
+ width: 36em;
+}
+
+section .noteText{
+ margin-left: 8em;
+ padding-top: 6em;
+ width: 56%;
+}
+
+.textAlign{
+ display:flex;
+ flex-direction: column;
+ flex-wrap: wrap;
+ justify-content: center;
+ align-content: center;
+ align-items: center;
+}
+
+.setP{
+ width: 100%;
+ height:14em;
+}
+
+.update{
+ z-index: 100000000000;
+ width: 36em;
+}
+
+.update form div input{
+ width: 5em;
+}
+
+.update form div input:focus+.underline {
+ transform: scale(1);
+}
+
+.update .underline {
+ margin-top: 4em;
+ background-color: $brand-primary;
+ display: inline-block;
+ height: 3px;
+ position: absolute;
+ -webkit-transform: scale(0, 1);
+ transform: scale(0, 1);
+ -webkit-transition: all 0.2s linear;
+ transition: all 0.2s linear;
+ width: 16em;
+}
+
+.update form .inputContainer{
+ width:50%;
+ height:100%;
+ margin-top: 1em;
+ padding-top: 1em;
+ padding-bottom: 1em;
+}
+
+.update form .buttonContainer{
+ margin-top: -2em;
+ width: 13em;
+}
diff --git a/src/style/layout/wrapper.scss b/src/style/layout/wrapper.scss
new file mode 100644
index 0000000..de7dff4
--- /dev/null
+++ b/src/style/layout/wrapper.scss
@@ -0,0 +1,4 @@
+.wrapper{
+ width: 100%;
+ height: 100%;
+}
diff --git a/src/style/main.scss b/src/style/main.scss
new file mode 100644
index 0000000..06718b1
--- /dev/null
+++ b/src/style/main.scss
@@ -0,0 +1,6 @@
+@import "./base/reset.scss";
+@import "./theme/vars.scss";
+@import "./base/base.scss";
+@import "./layout/navbar.scss";
+@import "./layout/form.scss";
+@import "./layout/note.scss";
diff --git a/src/style/theme/vars.scss b/src/style/theme/vars.scss
new file mode 100644
index 0000000..e775b34
--- /dev/null
+++ b/src/style/theme/vars.scss
@@ -0,0 +1,3 @@
+$brand-primary: #ffb6c1;
+$brand-secodary: #89cff0;
+$brand-tertiery: #ffff00;
diff --git a/webpack.config.js b/webpack.config.js
new file mode 100644
index 0000000..97658f4
--- /dev/null
+++ b/webpack.config.js
@@ -0,0 +1,38 @@
+'use strict';
+
+const HtmlPlugin = require('html-webpack-plugin');
+const ExtractPlugin = require('extract-text-webpack-plugin');
+
+module.exports = {
+ devtool: 'cheap-module-eval-source-map',
+ devServer: {
+ historyApiFallback: true
+ },
+ entry: `${__dirname}/src/main.js`,
+ output: {
+ path: `${__dirname}/build`,
+ publicPath: '/',
+ filename: 'bundle-[hash].js'
+ },
+ plugins: [
+ new HtmlPlugin({ template: `${__dirname}/src/index.html` }),
+ new ExtractPlugin('bundle-[hash].css')
+ ],
+ module: {
+ rules: [
+ {
+ test: /\.js$/,
+ exclude: /node_modules/,
+ loader: 'babel-loader'
+ },
+ {
+ test: /\.scss$/,
+ loader: ExtractPlugin.extract(['css-loader', 'sass-loader'])
+ },
+ {
+ test: /\.(jpg|jpeg|gif|png|tiff|svg)$/,
+ loader: 'file-loader',
+ },
+ ]
+ }
+}