Mrr Todo list shortest example

by mikolalex

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/bundle.js"></script>
<div id="app"></div>

SCSS

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

.stationSelect {
  padding: 20px;
  text-align: center;
  input {
    font-size: 20px;
  }
  button {
    padding: 2px;
  }
}

.stationSelect > * {
  display: inline-block;
  vertical-align: top;
}

.cart {
  
  text-align: right;
  background-color: grey;
  color: white;
  padding: 10px;
  
}

.train {
  border: 1px solid black;
  margin: 5px;
  padding: 5px;
}
.selectSeats {
  padding: 15px 0 5px 0;
  & input {
  }
}

.seatDetails {
  padding: 10px;
}

.toCart {
  text-align: center;
  button {
    font-size: 20px;
    padding: 5px;
  }
}

.popup {
  position: absolute;
  left: 0;
  right: 0;
  padding: 10px;
  font-size: 20px;
  background-color: orange;
  color: white;
  text-align: center;
  
}

.options li {
  list-style: none;
  text-align: left;
  cursor: pointer;
  border-bottom: 1px solid grey;
  &:hover {
    color: white;
    background-color: grey;
  }
}

.inp {
  position: relative;
}

.clear {
  position: absolute;
  right: 0;
  top: 0;
  padding: 4px;
  cursor: pointer;
}

Babel + JSX

const { withMrr } = mrr;

const isEmpty = a => a === '';
const always = a => () => a;
const id = a => a;
const prop = a => b => b ? b[a] : null;

const options = ['Бердичев', 'Бершадь', 'Жмеринка'];

const getMatchedStations = a => options.filter(s => a && (s.indexOf(a) === 0));
const wait = time => () => new Promise(cb => setTimeout(cb, time));

const trains = [{
    id: 10,
    num: '124',
    from: 'Kyiv',
    to: 'Kostyantynivka',
    seats: 10,
}, {
    id: 11,
    num: '001',
    from: 'Ivano-Frankivsk',
    to: 'Kostyantynivka',
    seats: 20,
}, {
    id: 12,
    num: '787',
    from: 'Kharkiv',
    to: 'Kostyantynivka',
    seats: 23,
}];

const fetch1 = () => {
    return new Promise(res => {
        setTimeout(() => {
            res({ toJSON: () => trains });
        }, 500);
    })
}

const getTrains = (from, to, date) => fetch1('/get_trains?from=' + from + '&to=' + to + '&date=' + date).then(res => res.toJSON());

const OptionsInput = withMrr(props => ({
    $init: {
          options: [],
    },
    val: ['merge', 'valInput', [always(''), 'clear'], 'selectOption'],
    options: [props.getOptions, 'val'],
    optionsShown: ['toggle', 'valInput', 'selectOption'],
}), (state, props, $) => <div>
    <div className="inp">
        <input placeholder={ props.placeholder } onChange={ $('valInput') } value={ state.val } />      { state.val && <div className="clear" onClick={ $('clear') }>
            X
        </div> }
    </div>
    { state.optionsShown && <ul className="options">
    {
        state.options.map(s => <li onClick={ $('selectOption', s) }>{ s }</li>)
    }
    </ul> }

</div>)


const TrainSeats = withMrr({
    $log: true,
    "selectSeats": [
        (seatsNumber, { id }) => new Array(Number(seatsNumber)).fill(true).map(() => ({ trainId: id })), 
        '-seatsNumber', '-$props', 'select'],
    seatsNumber: [always(0), 'selectSeats'],
}, (state, props, $) => <div className="train">
    Поезд №{ props.num } { props.from } - { props.to }....