summaryrefslogtreecommitdiffstats
path: root/web/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'web/index.js')
-rw-r--r--web/index.js151
1 files changed, 151 insertions, 0 deletions
diff --git a/web/index.js b/web/index.js
new file mode 100644
index 0000000..316e73f
--- /dev/null
+++ b/web/index.js
@@ -0,0 +1,151 @@
1const apiBaseUrl = "https://api.routemon.fautchen.eu";
2
3const dialog = document.querySelector("dialog");
4const closeButton = document.querySelector("dialog button");
5closeButton.addEventListener("click", () => {
6 dialog.close();
7});
8
9let map = L.map("map");
10
11L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
12 attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
13}).addTo(map);
14
15let layerGroup = L.layerGroup().addTo(map);
16
17document.forms["gpx-upload-form"].addEventListener("submit", (event) => {
18 event.preventDefault();
19 const gpxFileInput = document.getElementById("gpx-file-input");
20 if (gpxFileInput.files.length !== 1) {
21 alert("Voor de upload moet er exact één GPX-bestand zijn geselecteerd");
22 return;
23 }
24 load(gpxFileInput.files[0]);
25});
26
27function el(name, attrs, ...children) {
28 const node = document.createElement(name);
29 for (const [k, v] of Object.entries(attrs)) {
30 node.setAttribute(k, v);
31 }
32 node.replaceChildren(...children);
33 return node;
34}
35
36function txt(s) {
37 return document.createTextNode(s);
38}
39
40function tbl(rowcols) {
41 return el("table", {},
42 el("tbody", {},
43 ...rowcols.map((cols) =>
44 el("tr", {},
45 ...cols.map((col) => el("td", {}, col)),
46 ))));
47}
48
49async function showProblem(rsp) {
50 const problem = await rsp.json();
51
52 document.getElementById("dialog-title").innerText = problem.title;
53 if (problem.detail)
54 document.getElementById("dialog-message").innerText = problem.detail;
55 else
56 document.getElementById("dialog-message").innerText = "";
57 dialog.showModal();
58
59 let rows = [
60 [txt("HTTP-statuscode"),
61 el("a", { "href": "https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/" + rsp.status },
62 txt(rsp.status + " (" + rsp.statusText + ")"))],
63 [txt("Probleemtype"),
64 el("code", {}, txt(problem.type))],
65 [txt("Trace-ID"),
66 el("code", {}, txt(rsp.headers.get("X-Routemon-Trace-Id")))],
67 ];
68 if (problem.instance) {
69 rows.push([txt("Instantie"),
70 el("code", {}, txt(problem.instance))]);
71 }
72 document.getElementById("dialog-more-info").replaceChildren(tbl(rows));
73
74 return;
75}
76
77async function getSysinfo() {
78 const rsp = await fetch(apiBaseUrl + "/sysinfo", {
79 method: "GET",
80 headers: {
81 "Accept-Language": "nl-NL",
82 },
83 });
84 if (!rsp.ok) {
85 await showProblem(rsp);
86 return;
87 }
88
89 const res = await rsp.json();
90 document.getElementById("situation-publication-of").innerText = new Date(res.using_publication_of).toLocaleString();
91}
92
93async function load(gpxFile) {
94 const rsp = await fetch(apiBaseUrl + "/gpx", {
95 method: "POST",
96 headers: {
97 "Accept-Language": "nl-NL",
98 },
99 body: gpxFile,
100 });
101 if (!rsp.ok) {
102 await showProblem(rsp);
103 return;
104 }
105
106 const res = await rsp.json();
107 layerGroup.clearLayers();
108
109 let bounds = null;
110 for (const track of res.tracks) {
111 for (const segment of track.segments) {
112 const polyline = L.polyline(segment.points, { color: "blue" }).addTo(layerGroup);
113 if (bounds === null) {
114 bounds = polyline.getBounds();
115 } else {
116 bounds.extend(polyline.getBounds());
117 }
118 }
119 }
120 if (bounds !== null) {
121 map.fitBounds(bounds);
122 }
123
124 res.relevant_situations.forEach((sit) => {
125 let firstComment = sit.comments[0] || "";
126 const lfIndex = firstComment.indexOf("\n");
127 if (lfIndex !== -1) {
128 firstComment = firstComment.substring(0, lfIndex);
129 }
130 const commentEl =
131 el("div", {},
132 el("code", {}, txt(sit.id)),
133 txt(": " + firstComment));
134
135 const markerLayer = L.marker(sit.location);
136 markerLayer.addTo(layerGroup).bindPopup(commentEl);
137
138 sit.relevant_road_closures.forEach((rc) => {
139 rc.relevant_lss.forEach((ls) => {
140 const lineLayer = L.polyline(ls, {
141 color: "purple",
142 dashArray: "5, 10",
143 dashOffset: "0",
144 });
145 lineLayer.addTo(layerGroup);
146 });
147 });
148 });
149}
150
151getSysinfo();