Display results nicer
This commit is contained in:
parent
bedcf95596
commit
3a5dfdd115
@ -31,7 +31,22 @@ div.item {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
pre {
|
||||
width: 100%;
|
||||
overflow: scroll;
|
||||
#results {
|
||||
> ul {
|
||||
> li {
|
||||
padding: 5px 0;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #ddd;
|
||||
}
|
||||
> ul {
|
||||
display: none;
|
||||
}
|
||||
&.expand {
|
||||
> ul {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
51
client/actions/results.js
Normal file
51
client/actions/results.js
Normal file
@ -0,0 +1,51 @@
|
||||
import { pick } from 'lowline';
|
||||
|
||||
export const DELETE_RESULT = 'DELETE_RESULT';
|
||||
|
||||
const baseUrl = '/api/results';
|
||||
|
||||
const headers = {
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
accept: 'application/json',
|
||||
};
|
||||
|
||||
export const FETCH_RESULTS = 'FETCH_RESULTS';
|
||||
|
||||
// query can be a query string (without ?, ie not a search string)
|
||||
export function fetchResults(query = {}) {
|
||||
query = typeof query === 'string' ? query : qs.stringify(query);
|
||||
|
||||
return (dispatch) => {
|
||||
fetch(`${baseUrl}${query ? `?${query}` : ''}`, {
|
||||
credentials: 'same-origin',
|
||||
headers,
|
||||
}).then((res) => res.json())
|
||||
.then((json) => {
|
||||
const actions = [receiveResults(json.results || [])];
|
||||
|
||||
if (json.perPage) {
|
||||
actions.push(setPagination(pick(json, 'perPage', 'totalCount')));
|
||||
}
|
||||
|
||||
dispatch(batchActions(actions));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export const RECEIVE_RESULTS = 'RECEIVE_RESULTS';
|
||||
|
||||
export function receiveResults(json) {
|
||||
return {
|
||||
type: RECEIVE_RESULTS,
|
||||
payload: json,
|
||||
receivedAt: Date.now(),
|
||||
};
|
||||
}
|
||||
|
||||
export const REMOVE_RESULTS = 'REMOVE_RESULTS';
|
||||
|
||||
export function removeResults() {
|
||||
return {
|
||||
type: REMOVE_RESULTS,
|
||||
};
|
||||
}
|
||||
13
client/components/Link.jsx
Normal file
13
client/components/Link.jsx
Normal file
@ -0,0 +1,13 @@
|
||||
import { h } from 'preact';
|
||||
|
||||
import formatTime from '../util/formatTime';
|
||||
|
||||
export default (props) => (
|
||||
<li>
|
||||
<span class="line">{props.Line.Name}</span>
|
||||
<ul>
|
||||
<li>{formatTime(props.DepDateTime)} {props.From.Name}</li>
|
||||
<li>{formatTime(props.ArrDateTime)} {props.To.Name}</li>
|
||||
</ul>
|
||||
</li>
|
||||
);
|
||||
25
client/components/Result.jsx
Normal file
25
client/components/Result.jsx
Normal file
@ -0,0 +1,25 @@
|
||||
import { h, Component } from 'preact';
|
||||
|
||||
import Link from './Link';
|
||||
|
||||
import formatTime from '../util/formatTime';
|
||||
|
||||
export default class Result extends Component {
|
||||
toggle() {
|
||||
console.log('toggle');
|
||||
this.setState({
|
||||
expand: !this.state.expand,
|
||||
})
|
||||
}
|
||||
|
||||
render(props, { expand }) {
|
||||
return (
|
||||
<li className={{ expand }} onClick={() => this.toggle()}>
|
||||
{formatTime(props.DepDateTime)} - {formatTime(props.ArrDateTime)}
|
||||
<ul>
|
||||
{props.RouteLinks.RouteLink.map((link, i) => <Link key={i} {...link} />)}
|
||||
</ul>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
}
|
||||
24
client/components/ResultList.jsx
Normal file
24
client/components/ResultList.jsx
Normal file
@ -0,0 +1,24 @@
|
||||
import { h, Component } from 'preact';
|
||||
|
||||
import Result from './Result';
|
||||
import store from '../store';
|
||||
|
||||
export default class ResultList extends Component {
|
||||
componentDidMount() {
|
||||
this.unsubscribe = store.subscribe(() => this.forceUpdate());
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.unsubscribe();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { results } = store.getState();
|
||||
console.log(results);
|
||||
|
||||
return (
|
||||
<ul>{results && results.map((result, i) => <Result key={i} {...result} />)}</ul>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
import { $, $$ } from 'dollr';
|
||||
import dragula from 'dragula';
|
||||
|
||||
import { h, render } from 'preact';
|
||||
import ResultList from './components/ResultList';
|
||||
|
||||
import store from './store';
|
||||
import { receiveResults } from './actions/results';
|
||||
const result = $('pre');
|
||||
const containers = $$('.location');
|
||||
|
||||
@ -34,7 +38,8 @@ drake.on('drop', (el, target, source) => {
|
||||
return res.json();
|
||||
}).then((json) => {
|
||||
console.log(json);
|
||||
result.textContent = JSON.stringify(json, null, ' ')
|
||||
// result.textContent = JSON.stringify(json, null, ' ')
|
||||
store.dispatch(receiveResults(json));
|
||||
}).catch((err) => {
|
||||
console.log('error');
|
||||
console.log(err);
|
||||
@ -46,10 +51,6 @@ function prevent(e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
document.body.addEventListener('touchmove', (e) => {
|
||||
if (e.target.classList.contains('item')) e.preventDefault();
|
||||
}, { passive: false });
|
||||
|
||||
drake.on('over', (el, target, source) => {
|
||||
if (target !== source) {
|
||||
target.classList.add('over');
|
||||
@ -62,3 +63,8 @@ drake.on('out', (el, target, source) => {
|
||||
}
|
||||
});
|
||||
|
||||
render(
|
||||
<ResultList />,
|
||||
$('#results')
|
||||
);
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ export default ({ articleUrl, protocol, hostname, websocketsPort, INITIAL_STATE,
|
||||
<div data-location="brother" class="location l03"><div data-location="brother" class="item"><span>Brother</span></div></div>
|
||||
<div data-location="therapist" class="location l04"><div data-location="therapist" class="item"><span>The Rapist</span></div></div>
|
||||
</div>
|
||||
<pre></pre>
|
||||
<div id="results"></div>
|
||||
<script src={"/js/app" + (js ? js.suffix : '') + '.js'} />
|
||||
</body>
|
||||
</html>
|
||||
|
||||
16
client/reducers/results.js
Normal file
16
client/reducers/results.js
Normal file
@ -0,0 +1,16 @@
|
||||
import {
|
||||
RECEIVE_RESULTS,
|
||||
REMOVE_RESULTS,
|
||||
} from '../actions/results';
|
||||
|
||||
export default (state = null, action) => {
|
||||
switch (action.type) {
|
||||
case RECEIVE_RESULTS:
|
||||
return action.payload || [];
|
||||
case REMOVE_RESULTS:
|
||||
return null;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
7
client/reducers/root.js
Normal file
7
client/reducers/root.js
Normal file
@ -0,0 +1,7 @@
|
||||
import { combineReducers } from 'redux';
|
||||
|
||||
import results from './results';
|
||||
|
||||
export default combineReducers({
|
||||
results,
|
||||
});
|
||||
15
client/store.js
Normal file
15
client/store.js
Normal file
@ -0,0 +1,15 @@
|
||||
import thunkMiddleware from 'redux-thunk';
|
||||
import createLogger from 'redux-logger';
|
||||
import { createStore, applyMiddleware } from 'redux';
|
||||
|
||||
const loggerMiddleware = createLogger();
|
||||
|
||||
import rootReducer from './reducers/root';
|
||||
|
||||
export default createStore(
|
||||
rootReducer,
|
||||
applyMiddleware(
|
||||
thunkMiddleware,
|
||||
loggerMiddleware
|
||||
)
|
||||
);
|
||||
3
client/util/formatTime.js
Normal file
3
client/util/formatTime.js
Normal file
@ -0,0 +1,3 @@
|
||||
export default function formatDateTime(str) {
|
||||
return str.split('T')[1].slice(0, -3);
|
||||
}
|
||||
@ -17,15 +17,22 @@
|
||||
"chalk": "^1.1.3",
|
||||
"cookie-parser": "^1.4.3",
|
||||
"dollr": "^0.1.2",
|
||||
"dragula": "^3.7.2",
|
||||
"dragula": "github:lohfu/dragula",
|
||||
"easy-tz": "^0.1.1",
|
||||
"express": "^4.14.1",
|
||||
"express-session": "^1.15.1",
|
||||
"jsx-node": "^0.2.2",
|
||||
"lodash": "^4.17.4",
|
||||
"lowline": "^0.1.3",
|
||||
"midwest": "github:thebitmill/midwest",
|
||||
"midwest-service-errors": "^0.2.0",
|
||||
"morgan": "^1.8.1",
|
||||
"pg": "^6.1.2",
|
||||
"preact": "^7.2.0",
|
||||
"react-dragula": "^1.1.17",
|
||||
"redux": "^3.6.0",
|
||||
"redux-logger": "^2.8.1",
|
||||
"redux-thunk": "^2.2.0",
|
||||
"require-dir": "^0.3.1",
|
||||
"superagent": "^3.5.0",
|
||||
"useragent": "^2.1.12",
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
const format = require('easy-tz/cjs/format');
|
||||
|
||||
const request = require('superagent');
|
||||
|
||||
// import get from 'get-value';
|
||||
@ -50,15 +52,32 @@ function formatStation(json) {
|
||||
return `${encodeURIComponent(json.name)}|${json.id}|${types[json.type]}`
|
||||
}
|
||||
|
||||
function formatTime(date) {
|
||||
date = date || new Date();
|
||||
|
||||
return format(null, 'YYYY-MM-DD HH:mm', date);
|
||||
|
||||
|
||||
}
|
||||
console.log(formatTime());
|
||||
|
||||
function formatLink(link) {
|
||||
|
||||
}
|
||||
|
||||
function formatResult(result) {
|
||||
return _.omit(result, 'Prices');
|
||||
}
|
||||
|
||||
console.log(new Date('2017-02-24T17:16:00'.split('T').join(' ')).toLocaleString());
|
||||
|
||||
const journeysPath = [ 'soap:Envelope', 'soap:Body', 'GetJourneyResponse', 'GetJourneyResult', 'Journeys', 'Journey']
|
||||
// http://www.labs.skanetrafiken.se/v2.2/resultspage.asp?cmdaction=next&selPointFr=malm%F6%20C|80000|0&selPointTo=landskrona|82000|0&LastStart=2017-02-23%2016:38
|
||||
router.post('/trip', (req, res, next) => {
|
||||
request(`http://www.labs.skanetrafiken.se/v2.2/resultspage.asp?cmdaction=next&selPointFr=${formatStation(stations[req.body.from])}&selPointTo=${formatStation(stations[req.body.to])}&LastStart=2017-02-23%2016:38`).then((response) =>{
|
||||
request(`http://www.labs.skanetrafiken.se/v2.2/resultspage.asp?cmdaction=next&selPointFr=${formatStation(stations[req.body.from])}&selPointTo=${formatStation(stations[req.body.to])}&LastStart=${encodeURIComponent(formatTime(req.body.datetime))}`).then((response) =>{
|
||||
const result = _.get(xml2json.toJson(response.text, { object: true }), journeysPath);
|
||||
|
||||
result.forEach((obj) => {
|
||||
delete obj.Prices
|
||||
});
|
||||
|
||||
result.forEach(formatResult);
|
||||
|
||||
res.json(result);
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user