Personal Dashboard

Notes.jsx 3.2KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import React from 'react'
  2. import { connect } from 'react-redux'
  3. import MarkdownIt from 'markdown-it'
  4. import { Card, Placeholder, Icon } from '../../Shared/Components'
  5. import { Menu, MenuDivider, MenuItem, EditableText, Intent, Button, Alert } from '@blueprintjs/core'
  6. import { SELECT_NOTE, UPDATE_NOTE, UPDATE_SELECTED_NOTE, ADD_NOTE, REMOVE_NOTE, UNSELECT_NOTE } from '../../Store/Actions'
  7. import './Notes.scss'
  8. const md = new MarkdownIt()
  9. const NotesList = ({ notes, select }) =>
  10. <div>
  11. { notes.map(e => <MenuItem key={e.id} text={e.title} onClick={() => select(e)}></MenuItem>) }
  12. </div>
  13. class AlertButton extends React.Component {
  14. state = { open: false }
  15. close = () => this.setState({ open: false })
  16. show = () => this.setState({ open: true })
  17. confirm = () => {
  18. this.props.onConfirm()
  19. this.close();
  20. }
  21. render() {
  22. return (
  23. <Button iconName={this.props.iconName} className={this.props.className} onClick={this.show}>
  24. <Alert intent={Intent.DANGER} isOpen={this.state.open}
  25. confirmButtonText={this.props.confirmButtonText} cancelButtonText={this.props.cancelButtonText}
  26. onConfirm={this.confirm} onCancel={this.close} >
  27. {this.props.children}
  28. </Alert>
  29. </Button>
  30. );
  31. }
  32. }
  33. const Note = ({ note, update, remove }) =>
  34. <div className="Note">
  35. <AlertButton iconName="trash" className="trash-btn"
  36. confirmButtonText="delete" cancelButtonText={"Cancel"}
  37. onConfirm={() => remove(note)}>
  38. Do you really want to delete this note ? You won't be able to recover it.
  39. </AlertButton>
  40. <h2>{note.title}</h2>
  41. <div className="editor">
  42. <EditableText className="source" multiline value={note.content} onChange={value => update({...note, content: value})}></EditableText>
  43. <div className="preview" dangerouslySetInnerHTML={{__html: md.render(note.content)}}></div>
  44. </div>
  45. </div>
  46. const NotesTemplate = ({ notes, selectedNote, selectNote, updateNote, addNote, removeNote }) =>
  47. <div className="Notes">
  48. <Card className="List">
  49. <Menu>
  50. <MenuDivider title="Notes"/>
  51. <NotesList notes={notes} select={selectNote}/>
  52. <MenuDivider />
  53. <MenuItem iconName="plus" text="New note" onClick={addNote}/>
  54. </Menu>
  55. </Card>
  56. <Card className="content">
  57. { selectedNote ? <Note note={selectedNote} update={updateNote} remove={removeNote} /> :
  58. <Placeholder iconName="clipboard" title="No note selected" description="Choose one in the list on the left"/> }
  59. </Card>
  60. </div>
  61. const Notes = connect(
  62. state => ({ notes: state.note.notes, selectedNote: state.note.selectedNote }),
  63. dispatch => ({
  64. addNote: () => dispatch(ADD_NOTE()),
  65. selectNote: note => dispatch(SELECT_NOTE(note)),
  66. removeNote: note => {
  67. dispatch(REMOVE_NOTE(note))
  68. dispatch(UNSELECT_NOTE())
  69. },
  70. updateNote: note => {
  71. dispatch(UPDATE_NOTE(note))
  72. dispatch(UPDATE_SELECTED_NOTE(note))
  73. }
  74. })
  75. )(NotesTemplate)
  76. export default Notes