-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
128 lines (105 loc) · 3.19 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//@ts-check
"use strict"
const R = require('ramda');
const sogralData = require('./sogral-data.json');
// replaceContent :: HTMLElement -> String -> ()
const replaceContent = R.curry( ($elem, content) => $elem.innerHTML = content );
// sel :: String -> HTMLElement -> HTMLElement
const sel = R.curry( (query, $parent) => $parent.querySelector(query) );
// on :: HTMLElement -> String -> Function -> ()
const on = R.curry ( ($el, ev, fn) => $el.addEventListener(ev, fn) );
// numVal :: HTMLInputElement -> Number
const numVal = R.compose( Number, R.prop('value') );
// NOTE: Why not json? To be url safe maybe... Just encodeUrl(json)?
function saveState($doc, depart, dest) {
const searchObj = new URLSearchParams();
searchObj.set('depart', depart);
searchObj.set('dest', dest);
const hashStr = searchObj.toString();
$doc.location.hash = hashStr;
return hashStr;
}
function loadState($doc, data) {
const hashStr = $doc.location.hash.slice(1);
const searchObj = new URLSearchParams(hashStr);
const state = {
depart: searchObj.get('depart'),
dest: searchObj.get('dest'),
}
if (state.depart && state.dest) {
sel('#depart', $doc).value = state.depart;
updateDests($doc, data);
sel('#dest', $doc).value = state.dest;
updateOutput($doc, data);
}
return state;
}
// generateOptions :: Array Object -> String
const generateOptions = R.pipe( R.map(x => `<option value="${x.code}">${x.name}</option>`), R.join('') );
function updateDeparts($doc, data) {
replaceContent(
sel('#depart', $doc),
generateOptions( data.departs )
)
}
function updateDests($doc, data) {
const depart = numVal( sel('#depart', $doc) );
replaceContent(
sel('#dest', $doc),
generateOptions( data.departs.find(d => d.code == depart).dests )
)
}
// voyages :: (Object, Number, Number) -> Array Object
const voyages = R.curry( (data, departCode, destCode) => {
try {
return data
.departs
.find(depart => depart.code === departCode)
.dests
.find(dest => dest.code === destCode)
.voyages;
} catch(e) {
return [];
}
});
// generateLine :: Object -> String
const generateLine = ({heure, prix, ligne, transporteur}) => `
<tr class="voyage">
<td class="heure">${heure}</td>
<td class="prix">${prix} DA</td>
<td class="ligne">${ligne}</td>
<td class="transporteur">${transporteur}</td>
</tr>`;
// generateOutput :: Array Object -> String
function generateOutput(voyages) {
if (voyages.length === 0) {
return 'Error: There are no trips to show.'
} else {
return voyages.map(generateLine).join('');
}
}
function updateOutput($doc, data) {
const replaceOutput = replaceContent( sel('#output', $doc) );
const [depart, dest] = R.map( R.compose(numVal, sel(R.__, $doc)), ['#depart', '#dest'] );
saveState($doc, depart, dest);
R.pipe(
voyages,
//R.tap(console.info),
generateOutput,
replaceOutput,
)(data, depart, dest);
}
(function setup($doc, data) {
on(
sel('#depart', $doc),
'change',
(_event) => updateDests($doc, data)
);
on(
sel('form', $doc),
'change',
(_event) => updateOutput($doc, data)
);
updateDeparts($doc, data);
loadState($doc, data);
})(document, sogralData);