JSFiddle - React, Tailwind, and code Playground

by mcsf

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<div id="app"></div>

CSS

@keyframes fade {
  from { opacity: 1; transform: scaleY(1); }
  25% { opacity: 0; transform: scaleY(1); height: 100%; }
  50% { opacity: 0; transform: scaleY(1); height: 0; }
  to { opacity: 0; transform: scaleY(0); height: 0; }
}

.active {
  font-weight: bold;
}

li:not(.active) {
  color: #aaa;
  animation: 1s linear 1s forwards fade;
}

Babel + JSX

Object.assign(window, R)
  
//shuffle = (xs) =>
//	xs.length <= 1 ? xs : (
//  	converge(randCons, [head, pipe(tail, shuffle)])(xs)
//  )
//  
//randCons = (a, bs) =>
//	(Math.random() * 2) > 1.5
//  ? [a].concat(bs)
//  : bs.concat(a)

const between = (a, b, n) =>
  [a, n, b].every((n, i, arr) =>
  	! i || (arr[i - 1] <= n))

randIndexesN = (n) => pipe(
	length,
	range(0),
  _.shuffle,
  take(n))
  
tails = xs =>
	! xs.length ? [[]] : (
  	[xs].concat(tails(tail(xs)))
  )

main = () => {
	ReactDOM.render(<App />, document.getElementById('app'))
}

App = () =>
	<article>
    <section>
      <Cribbs />
    </section>
    <section>
      <Pairings />
    </section>
	</article>
  
getCribbs = () =>
	cartesian(getWeekdays(), getTimeslots())
  
cartesian = (xs, ys) =>
	chain(y => xs.map(x => [x, y]))(ys)
  
getWeekdays = () =>
	[ 'mon', 'tue', 'wed', 'thu', 'fri' ]

getTimeslots = () =>
	range(10, 19)
  
Cribbs = pipe(
	getCribbs,
  flip(converge)([identity, randIndexesN(1)])(
    (cribbs, selected) =>
    	<ul>
    	  {cribbs.map(([d, t], i) =>
        	<li className={contains(i, selected) && 'active'}>
            {d} <em>{t}:00</em>
          </li>
        )}
    	</ul>
   )
)

folks = take(5, [
  'Alpha',
  'Beta',
  'Gamma',
  'Delta',
  'Epsilon',
])

getPairings = pipe(
	always(folks),
  tails,
  chain(converge((x, ys) => ys.map(y => [x, y]), [nth(0), tail]))
)

satisfyEdgesN = (n) => (xs) => {
	const pred = (edges) => between(
    Math.floor((folks.length / 2) * n),
    1 + Math.floor((folks.length / 2) * n),
    edges.length)
    
  const vertices = pipe(
  	chain(([a, b]) => [a, b]),
    uniq
  )(xs)
  
	const filterEdges = (order) => {
  	const counts = pipe(
    	map(v => [v, 0]),
      fromPairs
    )(vertices)
    const inc = tap(v => counts[v]++)
    return order
    .filter(i => {
    	const [a, b] = xs[i]
    	return counts[a] < n &&
        counts[b] < n &&
        inc(a) && inc(b)
    })
  }
  
  const run = pipe(
  	length,
    range(0),
   ...