diff --git a/public/index.html b/public/index.html index ffa91a2..249fc28 100644 --- a/public/index.html +++ b/public/index.html @@ -1,16 +1,19 @@ - - - - - - - - - React App - - - - -
- - - + + + \ No newline at end of file diff --git a/src/actions/actionTypes.js b/src/actions/actionTypes.js index 5d8e658..62b425b 100644 --- a/src/actions/actionTypes.js +++ b/src/actions/actionTypes.js @@ -1,3 +1,6 @@ export const LOG_IN_SUCCESS = 'LOG_IN_SUCCESS'; export const LOG_OUT = 'LOG_OUT'; -export const REQUEST_AUTHENTICATION = 'REQUEST_AUTHENTICATION'; \ No newline at end of file +export const REQUEST_AUTHENTICATION = 'REQUEST_AUTHENTICATION'; + +export const ADD_NOTES = "ADD_NOTES"; +export const REMOVE_NOTES = "REMOVE_NOTES"; \ No newline at end of file diff --git a/src/actions/notesAction.js b/src/actions/notesAction.js new file mode 100644 index 0000000..899d98e --- /dev/null +++ b/src/actions/notesAction.js @@ -0,0 +1,11 @@ +import * as types from "./actionTypes"; + +export const addNotes = data => ({ + type: types.ADD_NOTES, + payload: data +}); + +export const removeNotes = index => ({ + type: types.REMOVE_NOTES, + payload: index +}); diff --git a/src/containers/App.js b/src/containers/App.js index 22ec679..6c4aebf 100644 --- a/src/containers/App.js +++ b/src/containers/App.js @@ -1,9 +1,6 @@ -import React, { Component } from 'react'; -import { - Switch, - Route -} from 'react-router-dom'; -import '../styles/App.css'; +import React, { Component } from "react"; +import { Switch, Route } from "react-router-dom"; +import "../styles/App.css"; import Landing from "./LandingPage"; import Login from "./LoginPage"; @@ -13,19 +10,21 @@ import Dashboard from "./Dashboard"; import Footer from "../components/Footer"; export default class App extends Component { - render() { - console.log(this.props) - return ( -
- - - - - - - -
- ); - } + render() { + console.log(this.props); + return ( +
+
+ + + + + + + +
+
+ ); + } } diff --git a/src/containers/Dashboard.js b/src/containers/Dashboard.js index fea8d63..28c0c22 100644 --- a/src/containers/Dashboard.js +++ b/src/containers/Dashboard.js @@ -1,38 +1,106 @@ import React from "react"; -import { connect } from 'react-redux'; -import { logOutUser } from '../actions/sessionAction'; - +import { connect } from "react-redux"; +import { logOutUser } from "../actions/sessionAction"; +import { addNotes, removeNotes } from "../actions/notesAction"; +import { Link } from "react-router-dom"; +import "../styles/Dashboard.css"; class Dashboard extends React.Component { - handleLogout() { - const { dispatch } = this.props; - dispatch(logOutUser()) - } - componentWillMount() { - const { history, session } = this.props; - if (!session) { - history.push('/'); - } - } - componentWillReceiveProps(nextProps) { - if (!nextProps.session) { - const { history } = nextProps; - history.push('/'); - } + state = { + note: undefined + }; + handleLogout() { + this.props.logOutUser(); + } + componentWillMount() { + const { history, session } = this.props; + if (!session) { + history.push("/"); } - render() { - return ( -
- - -
- ); + } + componentWillReceiveProps(nextProps) { + if (!nextProps.session) { + const { history } = nextProps; + history.push("/"); } + } + onChange = e => { + this.setState({ + note: e.target.value + }); + }; + onAdd = () => { + if (!this.state.note) return; + this.props.addNotes(this.state.note); + this.setState({ + note: "" + }); + }; + onRemove = id => { + this.props.removeNotes(id); + }; + render() { + const { notes } = this.props; + return ( +
+
+
+ + logo + +

Brime Notes

+
+
+ +
+
+
+
+ + +
+
+ {notes.map((note, index) => ( +
+
{note}
+
+ this.onRemove(index)} + > + close + +
+
+ ))} +
+
+
+ ); + } } const mapStateToProps = state => { - const { session } = state; - return { - session - } -} -export default connect(mapStateToProps)(Dashboard); \ No newline at end of file + const { session, notes } = state; + return { + session, + notes + }; +}; +const mapDispatchToProps = dispatch => ({ + addNotes: data => dispatch(addNotes(data)), + removeNotes: index => dispatch(removeNotes(index)), + logOutUser: () => dispatch(logOutUser()) +}); +export default connect( + mapStateToProps, + mapDispatchToProps +)(Dashboard); diff --git a/src/containers/LandingPage.js b/src/containers/LandingPage.js index 02352f8..bca77e5 100644 --- a/src/containers/LandingPage.js +++ b/src/containers/LandingPage.js @@ -1,15 +1,21 @@ import React from "react"; -import { Link } from 'react-router-dom'; +import { Link } from "react-router-dom"; export default class Landing extends React.Component { - render() { - return ( -
- logo -

Brime Notes

-

Notes Like Never Before

- Login -
- ); - } + render() { + return ( +
+ + logo + +

Brime Notes

+

Notes Like Never Before

+ Login +
+ ); + } } diff --git a/src/containers/LoginPage.js b/src/containers/LoginPage.js index 680adf0..3ce5000 100644 --- a/src/containers/LoginPage.js +++ b/src/containers/LoginPage.js @@ -1,77 +1,101 @@ import React from "react"; -import { Link } from 'react-router-dom'; -import { connect } from 'react-redux'; -import { autheticate } from '../actions/sessionAction' +import { Link } from "react-router-dom"; +import { connect } from "react-redux"; +import { autheticate } from "../actions/sessionAction"; class Login extends React.Component { - constructor(props) { - super(props); - this.state = { credentials: { uid: 'peter@klaven', password: 'password' } } - this.onChange = this.onChange.bind(this); - this.onFormSubmit = this.onFormSubmit.bind(this); - } + constructor(props) { + super(props); + this.state = { credentials: { uid: "peter@klaven", password: "password" } }; + this.onChange = this.onChange.bind(this); + this.onFormSubmit = this.onFormSubmit.bind(this); + } - onChange(event) { - const field = event.target.name; - const credentials = this.state.credentials; - credentials[field] = event.target.value; - return this.setState({ credentials: credentials }); - } + onChange(event) { + const field = event.target.name; + const credentials = this.state.credentials; + credentials[field] = event.target.value; + return this.setState({ credentials: credentials }); + } - onFormSubmit(event) { - event.preventDefault(); - const { dispatch } = this.props; - dispatch(autheticate(this.state.credentials)) + onFormSubmit(event) { + event.preventDefault(); + const { dispatch } = this.props; + dispatch(autheticate(this.state.credentials)); + } + componentWillMount() { + const { history, session } = this.props; + if (session) { + history.push("/dashboard"); } - componentWillMount() { - const { history, session } = this.props; - if (session) { - history.push('/dashboard'); - } + } + componentWillReceiveProps(nextProps) { + if (nextProps.session) { + const { history } = nextProps; + history.push("/dashboard"); } - componentWillReceiveProps(nextProps) { - if (nextProps.session) { - const { history } = nextProps; - history.push('/dashboard'); - } - } - - render() { - console.log(this.props.session); - return ( -
-

Login

-
-
-
-
+ } -
-
+ render() { + console.log(this.props.session); + return ( +
+

Login

+ +
+ +
+ +
- -
+ +
+ +
-
- Forget Pssword?

- New User?Create account -
+ +
- -
- ); - } +
+ + Forget Pssword? + +
+ New User? + Create account +
+ +
+ ); + } } const mapStateToProps = state => { - const { session } = state; - return { - session - } -} -export default connect(mapStateToProps)(Login); \ No newline at end of file + const { session } = state; + return { + session + }; +}; +export default connect(mapStateToProps)(Login); diff --git a/src/reducers/index.js b/src/reducers/index.js index 716f0a4..0f1f35e 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -1,9 +1,11 @@ -import {combineReducers} from 'redux'; -import session from './sessionReducer'; +import { combineReducers } from "redux"; +import session from "./sessionReducer"; +import notes from "./notesReducer"; const rootReducer = combineReducers({ // short hand property names - session -}) + session, + notes +}); -export default rootReducer; \ No newline at end of file +export default rootReducer; diff --git a/src/reducers/initialState.js b/src/reducers/initialState.js index 95d72a3..3982cdf 100644 --- a/src/reducers/initialState.js +++ b/src/reducers/initialState.js @@ -1,3 +1,7 @@ export default { - session: !!sessionStorage.jwt -} \ No newline at end of file + session: !!sessionStorage.jwt, + notes: + typeof localStorage.getItem("brime_notes") === "string" + ? JSON.parse(localStorage.getItem("brime_notes")) + : [] +}; diff --git a/src/reducers/notesReducer.js b/src/reducers/notesReducer.js new file mode 100644 index 0000000..2fa478f --- /dev/null +++ b/src/reducers/notesReducer.js @@ -0,0 +1,22 @@ +import * as types from "../actions/actionTypes"; +import initialState from "./initialState"; + +export default function Reducer(state = initialState.notes, action) { + switch (action.type) { + case types.ADD_NOTES: { + let notes = [...state]; + notes.push(action.payload); + localStorage.setItem("brime_notes", JSON.stringify(notes)); + return notes; + } + case types.REMOVE_NOTES: { + let notes = [...state]; + notes.splice(action.payload, 1); + localStorage.setItem("brime_notes", JSON.stringify(notes)); + return notes; + } + + default: + return state; + } +} diff --git a/src/reducers/sessionReducer.js b/src/reducers/sessionReducer.js index 56239e2..527c6d3 100644 --- a/src/reducers/sessionReducer.js +++ b/src/reducers/sessionReducer.js @@ -4,7 +4,6 @@ import initialState from './initialState'; export default function sessionReducer(state = initialState.session, action) { switch(action.type) { case types.LOG_IN_SUCCESS: - alert('LoggedIn'); return !!sessionStorage.jwt case types.LOG_OUT: return !!sessionStorage.jwt diff --git a/src/styles/App.css b/src/styles/App.css index b8a3fc4..2a8c835 100644 --- a/src/styles/App.css +++ b/src/styles/App.css @@ -1,7 +1,17 @@ +body { + margin: 0; + padding: 0; + font-family: sans-serif; +} + .App { text-align: center; + padding: 8px 18px; + background: #f0efe9; +} +.App > .content { + height: calc(100vh - 70px); } - .App-logo { animation: App-logo-spin infinite 20s linear; height: 80px; @@ -22,16 +32,16 @@ margin: auto; width: 50%; padding-top: 30px; - } +} -input{ - width: 50%; - padding: 12px 20px; - margin: 8px 0; - display: inline-block; - border: 1px solid #ccc; - box-sizing: border-box; - border-radius: 10px; +input { + width: 50%; + padding: 12px 20px; + margin: 8px 0; + display: inline-block; + border: 1px solid #ccc; + box-sizing: border-box; + border-radius: 10px; } input:hover { opacity: 0.8; @@ -39,38 +49,39 @@ input:hover { } button { - background-color: #4CAF50; - color: white; - padding: 14px 20px; - margin: 8px 0; - border: none; - cursor: pointer; - width: 20%; - border-radius: 5px; + background-color: #50e3a4; + color: #31815e; + padding: 14px 20px; + margin: 8px 0; + border: none; + cursor: pointer; + border-radius: 5px; } button:hover { - opacity: 0.8; - box-shadow: 1px 1px 0.5px #888888; + opacity: 0.8; + box-shadow: 1px 1px 0.5px #888888; } .cancelbtn { - width: auto; - padding: 10px 18px; - background-color: #f44336; + width: auto; + padding: 10px 18px; + background-color: #f44336; } .container { - padding: 16px; + padding: 16px; } - @keyframes App-logo-spin { - from { transform: rotate(0deg); } - to { transform: rotate(360deg); } + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } } footer { - position: absolute; right: 0; bottom: 0; left: 0; diff --git a/src/styles/Dashboard.css b/src/styles/Dashboard.css new file mode 100644 index 0000000..17f652e --- /dev/null +++ b/src/styles/Dashboard.css @@ -0,0 +1,60 @@ +.brime-layout { + display: flex; + flex-direction: column; + padding-bottom: 36px; +} +.brime-layout .header { + display: flex; + justify-content: space-between; +} +.brime-layout .header > .left { + display: flex; + align-items: center; +} +.brime-layout .header > .left > a { + margin-right: 16px; +} +.brime-layout .content { + display: flex; + flex-direction: column; +} +.brime-layout .header .content .notes-input { + display: flex; +} + +.notes-input > input { + margin-right: 16px; + width: 350px; +} + +.note-card { + display: flex; + justify-content: space-between; + padding: 16px; + max-width: 150px; + margin-bottom: 8px; + margin-right: 8px; + background: #fff; + min-width: 250px; + + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1), 0 3px 6px rgba(0, 0, 0, 0.13); +} +.note-card .value { + font-weight: 300; + color: rgb(73, 73, 73); +} +.notes-list { + display: flex; + justify-items: center; + + flex-wrap: wrap; + align-items: flex-start; + text-align: left; + font-family: 'Mali', cursive; + margin-top: 24px; +} +.note-card .action i { + font-size: 14px; + cursor: pointer; + color: rgb(219, 219, 219); +}