Connect to api and setup basic homepage

This commit is contained in:
rui hildt 2020-02-09 19:40:34 +01:00
parent 3792b8e79f
commit d12f09ed08
7 changed files with 215 additions and 3 deletions

76
package-lock.json generated
View File

@ -1078,6 +1078,29 @@
"resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz",
"integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg=="
},
"@emotion/is-prop-valid": {
"version": "0.8.6",
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.6.tgz",
"integrity": "sha512-mnZMho3Sq8BfzkYYRVc8ilQTnc8U02Ytp6J1AwM6taQStZ3AhsEJBX2LzhA/LJirNCwM2VtHL3VFIZ+sNJUgUQ==",
"requires": {
"@emotion/memoize": "0.7.4"
}
},
"@emotion/memoize": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw=="
},
"@emotion/stylis": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
"integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ=="
},
"@emotion/unitless": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
},
"@hapi/address": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
@ -2492,6 +2515,22 @@
"resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.6.tgz",
"integrity": "sha512-1aGDUfL1qOOIoqk9QKGIo2lANk+C7ko/fqH0uIyC71x3PEGz0uVP8ISgfEsFuG+FKmjHTvFK/nNM8dowpmUxLA=="
},
"babel-plugin-styled-components": {
"version": "1.10.7",
"resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.7.tgz",
"integrity": "sha512-MBMHGcIA22996n9hZRf/UJLVVgkEOITuR2SvjHLb5dSTUyR4ZRGn+ngITapes36FI3WLxZHfRhkA1ffHxihOrg==",
"requires": {
"@babel/helper-annotate-as-pure": "^7.0.0",
"@babel/helper-module-imports": "^7.0.0",
"babel-plugin-syntax-jsx": "^6.18.0",
"lodash": "^4.17.11"
}
},
"babel-plugin-syntax-jsx": {
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
"integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY="
},
"babel-plugin-syntax-object-rest-spread": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
@ -3003,6 +3042,11 @@
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
},
"camelize": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz",
"integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
},
"caniuse-api": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
@ -3649,6 +3693,11 @@
"postcss": "^7.0.5"
}
},
"css-color-keywords": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
"integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU="
},
"css-color-names": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
@ -3739,6 +3788,16 @@
"resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz",
"integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w=="
},
"css-to-react-native": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz",
"integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==",
"requires": {
"camelize": "^1.0.0",
"css-color-keywords": "^1.0.0",
"postcss-value-parser": "^4.0.2"
}
},
"css-tree": {
"version": "1.0.0-alpha.37",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
@ -12803,6 +12862,23 @@
"schema-utils": "^2.6.4"
}
},
"styled-components": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.0.1.tgz",
"integrity": "sha512-E0xKTRIjTs4DyvC1MHu/EcCXIj6+ENCP8hP01koyoADF++WdBUOrSGwU1scJRw7/YaYOhDvvoad6VlMG+0j53A==",
"requires": {
"@babel/helper-module-imports": "^7.0.0",
"@babel/traverse": "^7.4.5",
"@emotion/is-prop-valid": "^0.8.3",
"@emotion/stylis": "^0.8.4",
"@emotion/unitless": "^0.7.4",
"babel-plugin-styled-components": ">= 1",
"css-to-react-native": "^3.0.0",
"hoist-non-react-statics": "^3.0.0",
"shallowequal": "^1.1.0",
"supports-color": "^5.5.0"
}
},
"stylehacks": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz",

View File

@ -12,7 +12,8 @@
"react-dom": "^16.12.0",
"react-router-dom": "^5.1.2",
"react-scripts": "3.3.1",
"react-sigma": "^1.2.34"
"react-sigma": "^1.2.34",
"styled-components": "^5.0.1"
},
"scripts": {
"start": "react-scripts start",

View File

@ -24,7 +24,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
<title>Dijkstra</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

View File

@ -1,11 +1,14 @@
import React, { useEffect } from 'react';
import React from 'react';
import { Layout } from 'antd';
import HomeView from './components/HomeView';
import 'antd/dist/antd.css';
function App() {
return (
<Layout>
<h1>Dijkstra</h1>
<p>Dijkstra is an app thas uses Dijkstra algorithm to display the shortest path between different cities in Belgium.</p>
<HomeView/>
</Layout>
);
}

View File

View File

@ -0,0 +1,126 @@
import React, { useState ,useEffect } from "react";
import Axios from '../utils/API';
import { Select, Button, Icon } from 'antd';
const { Option } = Select;
function HomeView() {
const [cities, setCities] = useState([]);
const [startingPoint, setStartingPoint] = useState();
const [destination, setDestination] = useState();
const [shortestPath, setShortestPath] = useState();
const [errorMessage, setErrorMessage] = useState();
useEffect(() => {
async function fetchData() {
try {
const { data } = await Axios.get(
`/countries/1`
);
setCities(data);
} catch (error) {
console.error(error);
}
};
fetchData();
}, []);
function handleStart(city_id) {
// eslint-disable-next-line
let [ startingPoint ] = cities.filter(city => city.id == city_id);
setStartingPoint(startingPoint);
}
function handleDestination(city_id) {
// eslint-disable-next-line
let [ destination ] = cities.filter(city => city.id == city_id);
setDestination(destination);
}
function handleSubmit() {
if (startingPoint === destination) {
setErrorMessage('Starting Point and Destination must be different cities.');
return
} else if (startingPoint && destination) {
async function getPath() {
try {
const response = await Axios.get(
`/path`,
{
params: {
start_city_id: startingPoint.id,
end_city_id: destination.id
}
}
);
setShortestPath(response.data)
setErrorMessage();
} catch (error) {
console.error(error);
}
}
getPath();
} else {
setErrorMessage('Please select a Starting point and a Destination');
}
}
return(
<main>
<section>
<h2>Select Starting Point</h2>
<div>
<Select defaultValue="Belgium" disabled>
</Select>
<Select
defaultValue="Choose a city"
onChange={handleStart}
>
{cities.map(city => (
<Option key={city.id}>{city.name}</Option>
))}
</Select>
</div>
</section>
<section>
<h2>Select Destination</h2>
<div>
<Select defaultValue="Belgium" disabled>
</Select>
<Select
defaultValue="Choose a city"
onChange={handleDestination}
>
{cities.map(city => (
<Option key={city.id}>{city.name}</Option>
))}
</Select>
</div>
</section>
<section>
<Button
type="primary"
onClick={handleSubmit}
>
Get shortest path between the cities
<Icon type="right" />
</Button>
{errorMessage &&
<p>{errorMessage}</p>
}
</section>
{
shortestPath &&
<section>
<h2>Shortest path from {startingPoint.name} to {destination.name}</h2>
<p>{shortestPath.path.map(city => (
<><span>{city.name}</span><Icon type="right" /></>
))}
</p>
</section>
}
</main>
);
}
export default HomeView

6
src/utils/API.js Normal file
View File

@ -0,0 +1,6 @@
import axios from "axios";
export default axios.create({
baseURL: "https://dijkstra-backend.herokuapp.com/api",
responseType: "json"
});