Passport

by evgkch

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/react-with-addons.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/JSXTransformer.js"></script>
<div id="app"></div>

SCSS

$grey-color: #f3f3f4;
$primary-color: #293846;

.passport {
  display: flex;
  flex-direction: column;
  width: 500px;
  border: solid 2px $primary-color;
  padding: 10px;
  
  .passport-header {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    
    .action-buttons {
        display: flex;
        flex-direction: row;
        
        .icon-box {
         margin-right: 10px;
         
          .icon {
            display: flex;
            justify-content: center;
            align-items: center;
            width: 25px;
            height: 25px;
            background-color: $grey-color;
            border: solid 2px $primary-color;
            border-radius: 100%;
            cursor: pointer;
          }
        }
      }
    
    .searcher {
      display: flex;
      flex-direction: row;
      
      .searcher-button {
        display: flex;
        justify-content: center;
        align-items: center;
        padding: 5px;
        color: white;
        background-color: $primary-color;
        cursor: pointer;
      }
    }
  }
  
  .passport-content {
    margin-top: 20px;
    
    .passport-content-item {
      display: flex;
      flex-direction: row;
      margin-bottom: 10px;
        
      textarea {
        padding: 5px;
        resize: none;
        outline:none;
        border: solid 2px $primary-color;
        width: 400px;
        min-height: 40px;
      }

      .text-box {
        padding: 5px;
        background-color: white;
        border: solid 2px white;
        width: 400px;
        min-height: 40px;
      }
    }
  }
}

Babel + JSX

const data = Array.from({ length: 5 }, (v, k) => `Test text ${k}`);

const Mode = { read: 'read', record: 'record' };

const keys = { enter: 13, esc: 27 };

const PassportController = (dispatch, getState) => class ctrl {
  static _createItem(text = '', mode = Mode.record) {
    return { id:`${Math.random().toString(16)}`, text: text, mode: mode, checked: false };
  }
  static _getItems() {
  	return getState().items;
  }
  static _getBuffer() {
  	return getState().buffer;
  }
  static _getItemMode(id) {
  	for (const item of this._getItems.call(this)) {
    	if (item.id === id) return item.mode;
    }
  }
  static _getNotEmptyItems() {
    return this._getItems.call(this).filter(item => item.text.length !== 0);
  }
	static fetchItems() {
  	dispatch({ items: data.map(item => this._createItem(item, Mode.read)) });
  }
  static clearBuffer() {
  	dispatch({ buffer: {} });
  }
  static addItem() {
    dispatch({ items: [
    	this._createItem.call(this),
      ...this._getNotEmptyItems.call(this).map(item => ({ ...item, mode: Mode.read }))
    ] })
  }
	static changeItem(id) {
  	if (this._getItemMode.call(this, id) === Mode.read) {
    	dispatch({ items: this._getNotEmptyItems.call(this)
        .map(item =>
          item.id === id
            ? ({ ...item, mode: Mode.record })
            : ({ ... item, mode: Mode.read })
        )
      });
    }
  }
  static saveItem() {
  	const buffer = this._getBuffer.call(this);
    dispatch({ items: this._getItems.call(this)
      .map(item =>
        item.id === buffer.id
          ? ({ ...item, text: buffer.text, mode: Mode.read })
          : item
      )
      .filter(item => item.text.length !== 0)
    });
  }
  static addTextToBuffer(id, text) {
  	dispatch({ buffer: { id: id, text: text } });
  }
  static selectItem(id) {
  	dispatch({ items: this._getItems.call(this)
    	.map(item => item.id === id
      	? ({ ...item, checked: !item.checked })
        : item
      )
    });
  }
  static deleteSelectedItems() {
 ...