Move logic to NotesList component.
authorAlexandre Segura <mex.zktk@gmail.com>
Fri, 23 Jun 2017 18:01:40 +0200
changeset 84 bf35a7737f94
parent 83 76a4e4b11762
child 85 e17899ced2b8
Move logic to NotesList component.
client/package.json
client/src/components/Note.js
client/src/components/NotesList.js
--- a/client/package.json	Fri Jun 23 17:58:21 2017 +0200
+++ b/client/package.json	Fri Jun 23 18:01:40 2017 +0200
@@ -11,6 +11,7 @@
     "react": "^15.5.4",
     "react-bootstrap": "^0.31.0",
     "react-dom": "^15.5.4",
+    "react-overlays": "^0.7.0",
     "react-portal": "^3.1.0",
     "react-redux": "^5.0.5",
     "react-router-redux": "next",
--- a/client/src/components/Note.js	Fri Jun 23 17:58:21 2017 +0200
+++ b/client/src/components/Note.js	Fri Jun 23 18:01:40 2017 +0200
@@ -1,28 +1,15 @@
 import React, { Component } from 'react';
-import { connect } from 'react-redux';
-import { bindActionCreators } from 'redux';
 import PropTypes from 'prop-types';
 import { formatTimestamp } from '../utils';
 import SlateEditor from './SlateEditor';
-import * as notesActions from '../actions/notesActions';
 
 class Note extends Component {
 
-  state = {
-    edit: false
-  }
-
-  enterEditMode = () => {
-    const { edit } = this.state;
-    if (edit) return;
-    this.setState({ edit: true })
-  }
-
   onClickDelete = (e) => {
     e.preventDefault();
     e.stopPropagation();
 
-    this.props.notesActions.deleteNote(this.props.note);
+    this.props.onDelete();
   }
 
   onClickButton = (e) => {
@@ -32,25 +19,25 @@
     const html = this.refs.editor.asHtml();
     const categories = this.refs.editor.asCategories();
 
-    this.props.notesActions.updateNote(this.props.note, {
+    const data = {
       plain,
       raw,
       html,
       categories
-    });
+    }
 
-    this.setState({ edit: false })
+    this.props.onSave(this.props.note, data);
   }
 
   onClickClose = (e) => {
     e.preventDefault();
     e.stopPropagation();
 
-    this.setState({ edit: false })
+    this.props.onClose();
   }
 
   renderNoteContent() {
-    if (this.state.edit) {
+    if (this.props.isEditing) {
       return (
         <div className="note-content">
           <SlateEditor ref="editor"
@@ -66,7 +53,7 @@
   }
 
   renderNoteRight() {
-    if (this.state.edit) {
+    if (this.props.isEditing) {
       return (
         <a onClick={this.onClickClose}>
           <span className="material-icons">close</span>
@@ -83,7 +70,7 @@
 
   render() {
     return (
-      <div id={"note-" + this.props.note._id} className="note" onClick={ this.enterEditMode }>
+      <div id={"note-" + this.props.note._id} className="note" onClick={ this.props.onClick }>
         <span className="start">{ formatTimestamp(this.props.note.startedAt) }</span>
         <span className="finish">{ formatTimestamp(this.props.note.finishedAt) }</span>
         { this.renderNoteContent() }
@@ -97,17 +84,7 @@
 }
 
 Note.propTypes = {
-  note: PropTypes.object.isRequired
+  note: PropTypes.object.isRequired,
 };
 
-function mapStateToProps(state, props) {
-  return props;
-}
-
-function mapDispatchToProps(dispatch) {
-  return {
-    notesActions: bindActionCreators(notesActions, dispatch),
-  }
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(Note);
+export default Note;
--- a/client/src/components/NotesList.js	Fri Jun 23 17:58:21 2017 +0200
+++ b/client/src/components/NotesList.js	Fri Jun 23 18:01:40 2017 +0200
@@ -1,30 +1,100 @@
-import React from 'react';
-
+import React, { Component } from 'react';
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
 import PropTypes from 'prop-types';
 import Immutable from 'immutable';
+import { Alert, Modal, Button } from 'react-bootstrap';
+import Note from './Note';
+import * as notesActions from '../actions/notesActions';
 
-import { Alert } from 'react-bootstrap';
+class NotesList extends Component {
+
+  state = {
+    editingNote: null,
+    noteToDelete: null,
+    showModal: false,
+  }
+
+  enterEditMode = (note) => {
+    this.setState({ editingNote: note });
+  }
 
-import Note from './Note';
+  closeNote = () => {
+    this.setState({ editingNote: null });
+  }
+
+  confirmDelete = (note) => {
+    this.setState({
+      showModal: true,
+      noteToDelete: note
+    })
+  }
+
+  deleteNote = () => {
+    const { noteToDelete } = this.state;
+    this.props.notesActions.deleteNote(noteToDelete);
+    this.closeModal();
+  }
 
-const NotesList = ({notes}) => {
+  closeModal = () => {
+    this.setState({
+      showModal: false,
+      noteToDelete: null
+    })
+  }
+
+  updateNote = (note, data) => {
+    this.props.notesActions.updateNote(note, data);
+  }
+
+  render() {
+    if (this.props.notes.size === 0) {
+      return (
+        <Alert bsStyle="warning">No notes yet. Add notes with the textarea below.</Alert>
+      );
+    }
+
+    return (
+      <div>
 
-  if (notes.size === 0) {
-    return (
-      <Alert bsStyle="warning">No notes yet. Add notes with the textarea below.</Alert>
+        {this.props.notes.map((note) =>
+          <Note
+            note={ note }
+            key={ note._id }
+            onClick={ this.enterEditMode.bind(this, note) }
+            onClose={ this.closeNote }
+            onDelete={ this.confirmDelete.bind(this, note) }
+            onSave={ this.updateNote }
+            isEditing={ this.state.editingNote && note === this.state.editingNote } />
+        )}
+
+        <Modal show={this.state.showModal} onHide={this.closeModal}>
+          <Modal.Body>
+            Are you sure?
+          </Modal.Body>
+          <Modal.Footer>
+            <Button bsStyle="primary" onClick={ this.deleteNote }>Confirm</Button>
+            <Button onClick={ this.closeModal }>Close</Button>
+          </Modal.Footer>
+        </Modal>
+
+      </div>
     );
   }
-  return (
-    <div>
-      {notes.map((note) =>
-        <Note note={note} key={note._id} />
-      )}
-    </div>
-  );
 };
 
 NotesList.propTypes = {
   notes: PropTypes.instanceOf(Immutable.List).isRequired
 };
 
-export default NotesList;
+function mapStateToProps(state, props) {
+  return props;
+}
+
+function mapDispatchToProps(dispatch) {
+  return {
+    notesActions: bindActionCreators(notesActions, dispatch),
+  }
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(NotesList);