Compare commits

..

No commits in common. "main" and "we-basicButtonClass" have entirely different histories.

88 changed files with 118 additions and 2824 deletions

View File

@ -25,37 +25,20 @@ Tutorials för React går att hitta [här](https://www.youtube.com/playlist?list
* ``public/index.html`` är den enda HTML-fil vi kommer ha i appen, detta eftersom vi bygger en s.k. SPA (Single Page Application). Man ändrar oftast inget i denna fil utöver möjligtvis innehållet i ``<head>``, detta eftersom React hanterar hela vårt UI. * ``public/index.html`` är den enda HTML-fil vi kommer ha i appen, detta eftersom vi bygger en s.k. SPA (Single Page Application). Man ändrar oftast inget i denna fil utöver möjligtvis innehållet i ``<head>``, detta eftersom React hanterar hela vårt UI.
* Ursprungspunkten för React är ``src/index.js``. * Ursprungspunkten för React är ``src/index.js``.
<!--
## Upplägg ## Upplägg
```mermaid ``` mermaid
classDiagram classDiagram
class User
User : String deviceId
User : Coordinates location
User : nearbyStops()
class Coordinates class User
Coordinates : Float lon User : Subscription[] subs
Coordinates : Float lat User : Location loc
class Stop class Line
Stop : String name
Stop : Track[] locations
Stop : Departure[] departures
class Departure class Subscription
Departure : String lineName Subscription : Line line
Departure : Stop finalStop
Departure : String time
Departure : String trafficInfo
class Track
Track : String name
User <.. Coordinates
User <.. Stop
Stop <.. Departure
Departure <.. Stop
Stop <.. Track
``` ```
-->

157
package-lock.json generated
View File

@ -3030,14 +3030,6 @@
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.0.2.tgz", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.0.2.tgz",
"integrity": "sha512-arU1h31OGFu+LPrOLGZ7nB45v940NMDMEJeNmbutu57P+UFDVnkZg3e+J1I2HJRZ9hT7gO8J91dn/PMrAiKakA==" "integrity": "sha512-arU1h31OGFu+LPrOLGZ7nB45v940NMDMEJeNmbutu57P+UFDVnkZg3e+J1I2HJRZ9hT7gO8J91dn/PMrAiKakA=="
}, },
"axios": {
"version": "0.21.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.0.tgz",
"integrity": "sha512-fmkJBknJKoZwem3/IKSSLpkdNXZeBu5Q7GA/aRsr2btgrptmSCxi2oFjZHqGdK9DoTil9PIHlPIZw2EcRJXRvw==",
"requires": {
"follow-redirects": "^1.10.0"
}
},
"axobject-query": { "axobject-query": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
@ -3446,15 +3438,6 @@
"integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
"optional": true "optional": true
}, },
"bindings": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"optional": true,
"requires": {
"file-uri-to-path": "1.0.0"
}
},
"bluebird": { "bluebird": {
"version": "3.7.2", "version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
@ -6352,12 +6335,6 @@
} }
} }
}, },
"file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
"optional": true
},
"filesize": { "filesize": {
"version": "6.1.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz", "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz",
@ -6992,19 +6969,6 @@
"resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
"integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ=="
}, },
"history": {
"version": "4.10.1",
"resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
"integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
"requires": {
"@babel/runtime": "^7.1.2",
"loose-envify": "^1.2.0",
"resolve-pathname": "^3.0.0",
"tiny-invariant": "^1.0.2",
"tiny-warning": "^1.0.0",
"value-equal": "^1.0.1"
}
},
"hmac-drbg": { "hmac-drbg": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@ -7015,14 +6979,6 @@
"minimalistic-crypto-utils": "^1.0.1" "minimalistic-crypto-utils": "^1.0.1"
} }
}, },
"hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"requires": {
"react-is": "^16.7.0"
}
},
"hoopy": { "hoopy": {
"version": "0.1.4", "version": "0.1.4",
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
@ -9953,15 +9909,6 @@
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="
}, },
"mini-create-react-context": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz",
"integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==",
"requires": {
"@babel/runtime": "^7.12.1",
"tiny-warning": "^1.0.3"
}
},
"mini-css-extract-plugin": { "mini-css-extract-plugin": {
"version": "0.11.3", "version": "0.11.3",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.3.tgz", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.3.tgz",
@ -10111,11 +10058,6 @@
"minimist": "^1.2.5" "minimist": "^1.2.5"
} }
}, },
"moment": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
},
"move-concurrently": { "move-concurrently": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@ -10153,12 +10095,6 @@
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
}, },
"nan": {
"version": "2.14.2",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
"optional": true
},
"nanoid": { "nanoid": {
"version": "3.1.16", "version": "3.1.16",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.16.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.16.tgz",
@ -12281,11 +12217,6 @@
"whatwg-fetch": "^3.4.1" "whatwg-fetch": "^3.4.1"
} }
}, },
"react-axios": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/react-axios/-/react-axios-2.0.3.tgz",
"integrity": "sha512-63kY2iupdRgbvPq9G8xmM0NWUnt2Q5YmpotMoLQsxKOzKXKZg2Lo6CzF/bcZvtmv3WnfjBU6Bg8nZQO28eIAZw=="
},
"react-dev-utils": { "react-dev-utils": {
"version": "11.0.0", "version": "11.0.0",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.0.tgz", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.0.tgz",
@ -12391,67 +12322,11 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
}, },
"react-native-push-notification": {
"version": "6.1.3",
"resolved": "https://registry.npmjs.org/react-native-push-notification/-/react-native-push-notification-6.1.3.tgz",
"integrity": "sha512-qNbFCkObCXwSFQbK6hJyx1Bym1D7V4XM8iN2L6eL3GAdNLmeBTdLdx3mPbKJtuaDJ1+deniFTQ2rz6hU4ELOXA=="
},
"react-push-notification": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/react-push-notification/-/react-push-notification-1.3.0.tgz",
"integrity": "sha512-hyYKZqwtNOgRP74fAafVIivEr99vUtH0nDgcWkPKd302BhMuUMr5wuuEX236bSbCoM4nxlOge1m0CKIEtWBqLA=="
},
"react-refresh": { "react-refresh": {
"version": "0.8.3", "version": "0.8.3",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz",
"integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==" "integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg=="
}, },
"react-router": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz",
"integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==",
"requires": {
"@babel/runtime": "^7.1.2",
"history": "^4.9.0",
"hoist-non-react-statics": "^3.1.0",
"loose-envify": "^1.3.1",
"mini-create-react-context": "^0.4.0",
"path-to-regexp": "^1.7.0",
"prop-types": "^15.6.2",
"react-is": "^16.6.0",
"tiny-invariant": "^1.0.2",
"tiny-warning": "^1.0.0"
},
"dependencies": {
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
},
"path-to-regexp": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
"integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
"requires": {
"isarray": "0.0.1"
}
}
}
},
"react-router-dom": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz",
"integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==",
"requires": {
"@babel/runtime": "^7.1.2",
"history": "^4.9.0",
"loose-envify": "^1.3.1",
"prop-types": "^15.6.2",
"react-router": "5.2.0",
"tiny-invariant": "^1.0.2",
"tiny-warning": "^1.0.0"
}
},
"react-scripts": { "react-scripts": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-4.0.0.tgz", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-4.0.0.tgz",
@ -12907,11 +12782,6 @@
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="
}, },
"resolve-pathname": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz",
"integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng=="
},
"resolve-url": { "resolve-url": {
"version": "0.2.1", "version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@ -14648,16 +14518,6 @@
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q="
}, },
"tiny-invariant": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz",
"integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw=="
},
"tiny-warning": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
},
"tmp": { "tmp": {
"version": "0.0.33", "version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@ -15116,11 +14976,6 @@
"spdx-expression-parse": "^3.0.0" "spdx-expression-parse": "^3.0.0"
} }
}, },
"value-equal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
"integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw=="
},
"vary": { "vary": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@ -15293,11 +15148,7 @@
"version": "1.2.13", "version": "1.2.13",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"optional": true, "optional": true
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
}, },
"glob-parent": { "glob-parent": {
"version": "3.1.0", "version": "3.1.0",
@ -15883,11 +15734,7 @@
"version": "1.2.13", "version": "1.2.13",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"optional": true, "optional": true
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
}, },
"glob-parent": { "glob-parent": {
"version": "3.1.0", "version": "3.1.0",

View File

@ -6,14 +6,8 @@
"@testing-library/jest-dom": "^5.11.6", "@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "^11.1.2", "@testing-library/react": "^11.1.2",
"@testing-library/user-event": "^12.2.2", "@testing-library/user-event": "^12.2.2",
"axios": "^0.21.0",
"moment": "^2.29.1",
"react": "^17.0.1", "react": "^17.0.1",
"react-axios": "^2.0.3",
"react-dom": "^17.0.1", "react-dom": "^17.0.1",
"react-native-push-notification": "^6.1.3",
"react-push-notification": "^1.3.0",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.0", "react-scripts": "4.0.0",
"web-vitals": "^0.2.4" "web-vitals": "^0.2.4"
}, },

View File

@ -3,13 +3,17 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="theme-color" content="#01aaeb" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> <meta name="theme-color" content="#000000" />
<meta name="description" content="Störningar i kollektivtrafiken" /> <meta
<meta name='viewport' content='minimal-ui, width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=0' > name="description"
<meta name=apple-mobile-web-app-capable content=yes> content="Web site created using create-react-app"
<meta name=apple-mobile-web-app-status-bar-style content=black> />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo.png" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!-- <!--
Notice the use of %PUBLIC_URL% in the tags above. Notice the use of %PUBLIC_URL% in the tags above.
@ -25,5 +29,15 @@
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div> <div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body> </body>
</html> </html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

BIN
public/logo192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
public/logo512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -1,6 +1,6 @@
{ {
"short_name": "Västtrafik", "short_name": "React App",
"name": "Störningar i kollektivtrafiken", "name": "Create React App Sample",
"icons": [ "icons": [
{ {
"src": "favicon.ico", "src": "favicon.ico",
@ -8,13 +8,18 @@
"type": "image/x-icon" "type": "image/x-icon"
}, },
{ {
"src": "logo.png", "src": "logo192.png",
"type": "image/png", "type": "image/png",
"sizes": "135x135" "sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
} }
], ],
"start_url": ".", "start_url": ".",
"display": "fullscreen", "display": "standalone",
"theme_color": "#01aaeb", "theme_color": "#000000",
"background_color": "#f0f8fa" "background_color": "#ffffff"
} }

View File

@ -1,53 +0,0 @@
{
"DepartureBoard": {
"noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestDepartureBoard.xsd",
"servertime": "09:38",
"serverdate": "2020-12-11",
"Departures": [
{
"name": "Buss MEXP",
"sname": "MEXP",
"journeyNumber": "22",
"type": "BUS",
"stopid": "9022014014751002",
"stop": "Guddeby",
"time": "09:40",
"date": "2020-12-11",
"journeyid": "9015014621000022",
"direction": "Marstrand",
"track": "B",
"rtTime": "09:44",
"rtDate": "2020-12-11",
"fgColor": "#006C93",
"bgColor": "#FFFFFF",
"stroke": "Solid",
"accessibility": "wheelChair",
"JourneyDetailRef": {
"ref": "https://api.vasttrafik.se/bin/rest.exe/v2/journeyDetail?ref=715722%2F247121%2F629948%2F76401%2F80%3Fdate%3D2020-12-11%26station_evaId%3D14751002%26station_type%3Ddep%26format%3Djson%26"
}
},
{
"name": "Buss 927",
"sname": "927",
"journeyNumber": "2",
"type": "BUS",
"stopid": "9022014014751002",
"stop": "Guddeby",
"time": "12:29",
"date": "2020-12-11",
"journeyid": "9015014692700002",
"direction": "Tjuvkil",
"track": "B",
"rtTime": "12:30",
"rtDate": "2020-12-11",
"fgColor": "#006C93",
"bgColor": "#FFFFFF",
"stroke": "Solid",
"accessibility": "wheelChair",
"JourneyDetailRef": {
"ref": "https://api.vasttrafik.se/bin/rest.exe/v2/journeyDetail?ref=286581%2F125303%2F109682%2F40686%2F80%3Fdate%3D2020-12-11%26station_evaId%3D14751002%26station_type%3Ddep%26format%3Djson%26"
}
}
]
}
}

View File

@ -1,53 +0,0 @@
{
"DepartureBoard": {
"noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestDepartureBoard.xsd",
"servertime": "09:41",
"serverdate": "2020-12-11",
"Departures": [
{
"name": "Buss MEXP",
"sname": "MEXP",
"journeyNumber": "22",
"type": "BUS",
"stopid": "9022014014010002",
"stop": "Hålta kyrka",
"time": "09:47",
"date": "2020-12-11",
"journeyid": "9015014621000022",
"direction": "Marstrand",
"track": "B",
"rtTime": "09:50",
"rtDate": "2020-12-11",
"fgColor": "#006C93",
"bgColor": "#FFFFFF",
"stroke": "Solid",
"accessibility": "wheelChair",
"JourneyDetailRef": {
"ref": "https://api.vasttrafik.se/bin/rest.exe/v2/journeyDetail?ref=514476%2F180039%2F54148%2F144419%2F80%3Fdate%3D2020-12-11%26station_evaId%3D14010002%26station_type%3Ddep%26format%3Djson%26"
}
},
{
"name": "Buss 927",
"sname": "927",
"journeyNumber": "2",
"type": "BUS",
"stopid": "9022014014010002",
"stop": "Hålta kyrka",
"time": "12:38",
"date": "2020-12-11",
"journeyid": "9015014692700002",
"direction": "Tjuvkil",
"track": "B",
"rtTime": "12:38",
"rtDate": "2020-12-11",
"fgColor": "#006C93",
"bgColor": "#FFFFFF",
"stroke": "Solid",
"accessibility": "wheelChair",
"JourneyDetailRef": {
"ref": "https://api.vasttrafik.se/bin/rest.exe/v2/journeyDetail?ref=667647%2F252325%2F917844%2F236373%2F80%3Fdate%3D2020-12-11%26station_evaId%3D14010002%26station_type%3Ddep%26format%3Djson%26"
}
}
]
}
}

View File

@ -1,53 +0,0 @@
{
"DepartureBoard": {
"noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestDepartureBoard.xsd",
"servertime": "09:44",
"serverdate": "2020-12-11",
"Departures": [
{
"name": "Buss MEXP",
"sname": "MEXP",
"journeyNumber": "22",
"type": "BUS",
"stopid": "9022014014614002",
"stop": "Stenskärsvägen",
"time": "09:52",
"date": "2020-12-11",
"journeyid": "9015014621000022",
"direction": "Marstrand",
"track": "B",
"rtTime": "09:57",
"rtDate": "2020-12-11",
"fgColor": "#006C93",
"bgColor": "#FFFFFF",
"stroke": "Solid",
"accessibility": "wheelChair",
"JourneyDetailRef": {
"ref": "https://api.vasttrafik.se/bin/rest.exe/v2/journeyDetail?ref=341064%2F122235%2F154456%2F36461%2F80%3Fdate%3D2020-12-11%26station_evaId%3D14614002%26station_type%3Ddep%26format%3Djson%26"
}
},
{
"name": "Buss 320",
"sname": "320",
"journeyNumber": "10",
"type": "BUS",
"stopid": "9022014014614002",
"stop": "Stenskärsvägen",
"time": "10:44",
"date": "2020-12-11",
"journeyid": "9015014632000010",
"direction": "Tjuvkil",
"track": "B",
"rtTime": "10:44",
"rtDate": "2020-12-11",
"fgColor": "#006C93",
"bgColor": "#FFFFFF",
"stroke": "Solid",
"accessibility": "wheelChair",
"JourneyDetailRef": {
"ref": "https://api.vasttrafik.se/bin/rest.exe/v2/journeyDetail?ref=931884%2F318653%2F795430%2F87087%2F80%3Fdate%3D2020-12-11%26station_evaId%3D14614002%26station_type%3Ddep%26format%3Djson%26"
}
}
]
}
}

View File

@ -1,29 +0,0 @@
{
"DepartureBoard": {
"noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestDepartureBoard.xsd",
"servertime": "09:45",
"serverdate": "2020-12-11",
"Departures": [{
"name": "Buss 928",
"sname": "928",
"journeyNumber": "10",
"type": "BUS",
"stopid": "9022014014225001",
"stop": "Skrämmenborg",
"time": "15:19",
"date": "2020-12-11",
"journeyid": "9015014692800010",
"direction": "Kärna",
"track": "A",
"rtTime": "15:19",
"rtDate": "2020-12-11",
"fgColor": "#006C93",
"bgColor": "#FFFFFF",
"stroke": "Solid",
"accessibility": "wheelChair",
"JourneyDetailRef": {
"ref": "https://api.vasttrafik.se/bin/rest.exe/v2/journeyDetail?ref=110424%2F37130%2F997492%2F461938%2F80%3Fdate%3D2020-12-11%26station_evaId%3D14225001%26station_type%3Ddep%26format%3Djson%26"
}
}]
}
}

View File

@ -1,12 +0,0 @@
{
"situationNumber": "RT1",
"severity":"normal",
"title":"Nabbensbergsvägen närmast Edsvägen helt avstängd och trafiken hänvisas istället via Korsebergsvägen. Samtidigt tas den tillfälliga förbifarten bort på Edsvägen och trafiken kommer att ledas förbi den nya cirkulationsplatsen i de två västra körfälten tills arbetet på Nabbensbergsvägen är klart Hastighet: 50km/h",
"time":"00:07",
"affectedStopPoints":[
{
"gid": "9022014014614001",
"name": "Stenskärsvägen"
}
]
}

View File

@ -1,20 +0,0 @@
{
"situationNumber": "RT2",
"severity":"normal",
"title":"På grund av renovation av Nordreälvsbron i Kungälv från 10 november, 2019 till sommaren 2022 är det risk för förseningar på vissa Västtrafik bussar.",
"time":"00:09",
"affectedStopPoints":[
{
"gid": "9022014014751001",
"name": "Guddeby"
},
{
"gid": "9022014014010001",
"name": "Hålta kyrka"
},
{
"gid": "9022014014614001",
"name": "Stenskärsvägen"
}
]
}

View File

@ -1,36 +0,0 @@
{
"LocationList": {
"noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestLocation.xsd",
"servertime": "09:34",
"serverdate": "2020-12-11",
"StopLocation": [
{
"name": "Guddeby",
"id": "9022014014751001",
"lat": "57.874665",
"lon": "11.903884",
"track": "A"
},
{
"name": "Guddeby",
"id": "9021014014751000",
"lat": "57.874710",
"lon": "11.903929"
},
{
"name": "Guddeby",
"id": "9022014014751002",
"lat": "57.874746",
"lon": "11.903965",
"track": "B"
},
{
"name": "Stället",
"id": "9022014014744001",
"lat": "57.869784",
"lon": "11.904172",
"track": "A"
}
]
}
}

View File

@ -1,36 +0,0 @@
{
"LocationList": {
"noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestLocation.xsd",
"servertime": "09:35",
"serverdate": "2020-12-11",
"StopLocation": [
{
"name": "Hålta kyrka",
"id": "9022014014010001",
"lat": "57.895125",
"lon": "11.827854",
"track": "A"
},
{
"name": "Hålta kyrka",
"id": "9021014014010000",
"lat": "57.895206",
"lon": "11.827647"
},
{
"name": "Hålta kyrka",
"id": "9022014014010002",
"lat": "57.895278",
"lon": "11.827440",
"track": "B"
},
{
"name": "Hålta skola",
"id": "9022014014015001",
"lat": "57.896015",
"lon": "11.824555",
"track": "A"
}
]
}
}

View File

@ -1,36 +0,0 @@
{
"LocationList": {
"noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestLocation.xsd",
"servertime": "09:36",
"serverdate": "2020-12-11",
"StopLocation": [
{
"name": "Stenskärsvägen",
"id": "9022014014614001",
"lat": "57.894594",
"lon": "11.740128",
"track": "A"
},
{
"name": "Stenskärsvägen",
"id": "9022014014614002",
"lat": "57.894729",
"lon": "11.739984",
"track": "B"
},
{
"name": "Stenskärsvägen",
"id": "9021014014614000",
"lat": "57.894738",
"lon": "11.739858"
},
{
"name": "Tjuvkilsboden",
"id": "9022014014615002",
"lat": "57.892743",
"lon": "11.743490",
"track": "B"
}
]
}
}

View File

@ -1,35 +0,0 @@
{
"LocationList": {
"noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestLocation.xsd",
"servertime": "09:37",
"serverdate": "2020-12-11",
"StopLocation": [
{
"name": "Kuröd",
"id": "9022014014762001",
"lat": "57.856687",
"lon": "11.864727",
"track": "A"
},
{
"name": "Kuröd",
"id": "9021014014762000",
"lat": "57.856831",
"lon": "11.864260"
},
{
"name": "Kuröd",
"id": "9022014014762002",
"lat": "57.856966",
"lon": "11.863774",
"track": "B"
},
{
"name": "Skrämmenborg",
"id": "9021014014225000",
"lat": "57.863528",
"lon": "11.867406"
}
]
}
}

View File

@ -1,5 +0,0 @@
{
"name": "Användare 1",
"deviceId": "1",
"stoppointgid": "9022014014751001"
}

View File

@ -1,5 +0,0 @@
{
"name": "Användare 2",
"deviceId": "2",
"stoppointgid": "9022014014010001"
}

View File

@ -1,5 +0,0 @@
{
"name": "Användare 3",
"deviceId": "3",
"stoppointgid": "9022014014614001"
}

View File

@ -1,5 +0,0 @@
{
"name": "Användare 4",
"deviceId": "4",
"stoppointgid": "9022014014762001"
}

View File

@ -3,7 +3,6 @@
text-align: center; text-align: center;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background: var(--colorBg);
} }
.App-logo { .App-logo {

View File

@ -1,73 +1,25 @@
import "./variables.css"; import './App.css';
import "./App.css"; import React, { Component } from 'react';
import NavigationDrawer from './components/NavigationDrawer.js'
import React, { Component } from "react"; import Header from './components/Header.js'
import { BrowserRouter as Router, Route, Link } from "react-router-dom"; import PageArea from './components/PageArea.js'
import Snackbar from "@material-ui/core/Snackbar"; import BottomMenu from './components/BottomMenu.js'
import IconButton from "@material-ui/core/IconButton";
import globalData from './GlobalData.js';
import BottomMenu from "./components/BottomMenu.js";
import Tickets from "./components/pages/Tickets.js";
import TicketsBuy from "./components/pages/TicketsBuy.js";
import Travel from "./components/pages/Travel.js";
import TrafficInfo from "./components/pages/TrafficInfo.js";
import "./variables.css";
import warningIcon from './img/warning.svg';
import closeIcon from './img/close.svg';
class App extends Component { class App extends Component {
currentPageName = () => {
if (globalData.currentPage.constructor !== undefined)
return globalData.currentPage.constructor.name;
else
return "";
};
render() { render() {
globalData.root = this;
return ( return (
<Router>
<div className="App"> <div className="App">
<Route path="/" exact component={TicketsBuy} /> {/*
<Route path="/tickets" exact component={Tickets} /> <Button
<Route path="/ticketsBuy" exact component={TicketsBuy} /> title = "placeholderTitle"
<Route path="/travel" exact component={Travel} /> destination = "placeholderDestination"
<Route path="/traffic" exact component={TrafficInfo} />
<BottomMenu />
<Snackbar
anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
open={globalData.snackbarVisible}
autoHideDuration={3000}
onClose={() => globalData.snackbarVisible = false}
message={
<div id="snackDisruptInfo">
<img src={warningIcon} alt="" />
<span id="message-id">Trafikstörning upptäckt</span>
</div>
}
action={[
<IconButton
key="close"
aria-label="Close"
color="inherit"
onClick={() => { globalData.snackbarVisible = false; globalData.root.forceUpdate() }}
>
{this.currentPageName() !== "TrafficInfo" &&
<Link to="/traffic">Visa trafikinfo</Link>
}
<img src={closeIcon} alt="" />
</IconButton>,
]}
/> />
*/}
<NavigationDrawer />
<Header />
<PageArea />
<BottomMenu />
</div> </div>
</Router>
); );
} }
} }

View File

@ -1,21 +0,0 @@
import User from './classes/User.js';
import Disruption from './classes/Disruption.js'
import Coordinates from './classes/Coordinates.js';
import Stop from './classes/Stop.js'
let globalData = {
users : [],
user: new User(
"Exempelanvändare",
"123",
new Coordinates(),
"123"
),
disruption: new Disruption(
),
stop: new Stop(
),
currentPage: ""
};
export default globalData;

View File

@ -1,20 +0,0 @@
import axios from 'axios';
class AccessToken {
credentials = 'NXR5N2d4bUFmUWxVSERIZG03a2dhcVh3SzVJYTp3cElPVVJuSkpjVHRPNnJPUlltWVlQcTR3WGth'
device = '123'
constructor() {
const headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + this.credentials
};
axios.post('https://api.vasttrafik.se/token','grant_type=client_credentials&scope=device_'+this.device, {headers} )
.then(response => {
this.token = response.data.access_token
});
}
}
export default AccessToken

View File

@ -1,15 +0,0 @@
/*
Denna klass är en modell för platskoordinater.
lon : Float (Longitud)
lat : Float (Latitud)
*/
class Coordinates {
constructor(lon, lat) {
this.lon = lon;
this.lat = lat;
}
}
export default Coordinates;

View File

@ -1,24 +0,0 @@
/*
Denna klass är en modell för avgångar.
lineName : String (Linjenamnet)
finalStop : Stop (Ändhållplats)
originalTime : String (Ursprunglig Avgångstid)
newTime : String (Ny Avgångstid)
trafficInfo : String (Trafikinformation)
*/
class Departure {
constructor(lineName, finalStop, originalTime) {
this.sname = lineName;
this.direction = finalStop;
this.time = originalTime;
}
timeUpdate(time, trafficInfo) {
this.newTime = time;
this.trafficInfo = trafficInfo;
}
}
export default Departure;

View File

@ -1,11 +0,0 @@
class Disruption {
constructor(situationNumber, severity, title, affectedStopPoints) {
this.situationNumber = situationNumber;
this.severity = severity;
this.title = title;
this.affectedStopPoints = affectedStopPoints;
}
}
export default Disruption;

View File

@ -1,31 +0,0 @@
/*
Denna klass är en modell för hållplatser.
name : String (Hållplatsens namn)
locations : Track[] (Möjliga lägen)
departures : Departure[] (Avgångar från hållplatsen)
*/
class Stop {
constructor(name, id, lat, lon, locations, departures) {
this.name = name;
this.id = id;
this.lat = lat;
this.lon = lon;
this.locations = locations;
this.departures = departures;
}
}
/*
Från västtrafiks api ett element i listan av hållplatser ser ut som följande
"id": "string",
"lon": "string",
"idx": "string",
"weight": "string",
"name": "string",
"track": "string",
"lat": "string"
*/
export default Stop;

View File

@ -1,13 +0,0 @@
/*
Denna klass är en modell för hållplatslägen, ex. "Läge A" eller "Spår 3".
name : String (Lägets namn)
*/
class Track {
constructor(name) {
this.name = name;
}
}
export default Track;

View File

@ -1,20 +0,0 @@
/*
Denna klass är en modell för användare.
name : String (Användarnamn)
deviceId : Int (Enhetens ID)
location : Coordinates (Användarens koordinater)
track : String (Nuvarande hållplatsläge)
*/
class User {
constructor(name, deviceId, location, stoppointgid, track) {
this.name = name;
this.deviceId = deviceId;
this.location = location;
this.stoppointgid = stoppointgid;
this.track = track;
}
}
export default User;

View File

@ -1,33 +1,13 @@
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import MenuButton from './MenuButton';
import './css/BottomMenu.css'; import './css/BottomMenu.css';
import ticketsIcon from '../img/tickets.svg'; import React, { Component } from 'react';
import ticketsBuyIcon from '../img/tickets+.svg';
import travelIcon from '../img/tram.svg';
import trafficIcon from '../img/traffic.svg';
class BottomMenu extends Component { class BottomMenu extends Component {
render() { render() {
return ( return (
<div id="bottomMenu"> <div id="bottomMenu">
<Link to="/tickets"> <button>Biljetter</button>
<MenuButton label="Biljetter" icon={ticketsIcon}/> <button>Köp biljett</button>
</Link> <button>Reseplanering</button>
<Link to="/ticketsBuy">
<MenuButton label="Köp biljett" icon={ticketsBuyIcon}/>
</Link>
<Link to="/travel">
<MenuButton label="Reseplanering" icon={travelIcon}/>
</Link>
<Link to="/traffic">
<MenuButton label="Trafikinfo" icon={trafficIcon}/>
</Link>
</div> </div>
); );
} }

View File

@ -1,30 +1,14 @@
import React, { Component } from 'react'; import React, {Component} from 'react'
import './css/Button.css';
class Button extends Component { class Button extends Component {
// Multiple onClick functions
onClick = () => {
if (this.props.onClick !== null
&& this.props.onClick !== undefined) {
if (Array.isArray(this.props.onClick)) {
this.props.onClick.forEach(func => {
func();
});
} else {
console.log("Error when parsing Button onClick functions. Make sure the functions are passed as an array.");
}
}
}
render() { render() {
return ( return (
<button className={this.props.className} onClick={this.onClick}> <a href={this.props.destination}>
{this.props.children} {this.props.title}
</button> </a>
); );
} }
} }
// TODO Add css
export default Button; export default Button

View File

@ -1,57 +0,0 @@
import React from 'react';
import axios from 'axios';
import AccessToken from '../classes/AccessToken'
class Diruption extends React.Component {
state = {
gid: '9022014005700002',
disruptions: [],
token: undefined,
tokenClass: new AccessToken()
}
handleChangeGid = event => {
this.setState({ lat: event.target.value});
}
handleSubmit = event => {
event.preventDefault();
const headers = {
'Authorization': 'Bearer ' + this.state.tokenClass.token
};
axios.get('https://api.vasttrafik.se/ts/v1/traffic-situations/stoppoint/'+this.state.gid, { headers })
//axios.get('https://api.vasttrafik.se/ts/v1/traffic-situations/stoppoint/9022014005700002', { headers })
.then(response => {
this.setState({
disruptions: response.data
})
})
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>
Stoppoint Gid:
<input type="text" name="gid" onChange={this.handleChangeGid} />
</label>
<button type="submit">Find traffic disruptions</button>
</form>
<h1>
{this.state.gid}
</h1>
{this.state.disruptions.map((item) =>
<div>
<h1>
{item.description}
</h1>
</div>
)}
</div>
)
}
}
export default Diruption

View File

@ -1,127 +0,0 @@
import moment from "moment";
import globalData from '../GlobalData.js';
import Button from './Button.js';
import user1 from '../APIexamples/user1.json'
import user2 from '../APIexamples/user2.json'
import user3 from '../APIexamples/user3.json'
import user4 from '../APIexamples/user4.json'
import locationuser1 from '../APIexamples/locationuser1.json'
import locationuser2 from '../APIexamples/locationuser2.json'
import locationuser3 from '../APIexamples/locationuser3.json'
import locationuser4 from '../APIexamples/locationuser4.json'
import departureuser1 from '../APIexamples/departureuser1.json'
import departureuser2 from '../APIexamples/departureuser2.json'
import departureuser3 from '../APIexamples/departureuser3.json'
import departureuser4 from '../APIexamples/departureuser4.json'
import ex1 from '../APIexamples/disruption1.json'
import ex2 from '../APIexamples/disruption2.json'
class DisruptionButton extends Button {
constructor(props) {
super(props);
this.state = {
jsonLocation: this.props.path,
disruption: "",
u1: user1,
u2: user2,
u3: user3,
u4: user4,
};
}
updatePage = () => {
globalData.currentPage.forceUpdate();
}
showMomentTime = (time) => {
return (time.format("HH:mm"))
}
genUsers = () => {
if (globalData.users.length < 2) {
this.state.first = true;
this.state.u1.stop = locationuser1.LocationList.StopLocation[0];
this.state.u1.stop.departures = departureuser1.DepartureBoard.Departures;
this.state.u2.stop = locationuser2.LocationList.StopLocation[0];
this.state.u2.stop.departures = departureuser2.DepartureBoard.Departures;
this.state.u3.stop = locationuser3.LocationList.StopLocation[0];
this.state.u3.stop.departures = departureuser3.DepartureBoard.Departures;
this.state.u4.stop = locationuser4.LocationList.StopLocation[0];
this.state.u4.stop.departures = departureuser4.DepartureBoard.Departures;
globalData.users = [
this.state.u1,
this.state.u2,
this.state.u3,
this.state.u4
]
}
}
genDisrupt = () => {
this.genUsers()
this.state.disruption = undefined
if (this.state.jsonLocation === "ex1") {
for (let stopPoint of ex1.affectedStopPoints) {
for (let user of globalData.users) {
if (stopPoint.gid === user.stoppointgid) {
this.state.disruption = ex1;
var old1t = moment(user.stop.departures[0].time, "HH:mm");
old1t.add(ex1.time, "HH:mm");
user.stop.departures[0].newTime = this.showMomentTime(old1t);
user.stop.departures[0].trafficInfo = ex1.title;
}
}
if (stopPoint.gid === globalData.user.stoppointgid) {
this.state.disruption = ex1;
var old2t = moment(globalData.stop.departures[0].time, "HH:mm");
old2t.add(ex1.time, "HH:mm");
globalData.stop.departures[0].newTime = this.showMomentTime(old2t);
globalData.stop.departures[0].trafficInfo = ex1.title;
globalData.snackbarVisible = true; globalData.root.forceUpdate();
}
}
} else if (this.state.jsonLocation === "ex2") {
for (let stopPoint of ex2.affectedStopPoints) {
for (let user of globalData.users) {
if (stopPoint.gid === user.stoppointgid) {
this.state.disruption = ex2;
var old3t = moment(user.stop.departures[0].time, "HH:mm");
old3t.add(ex2.time, "HH:mm");
user.stop.departures[0].newTime = this.showMomentTime(old3t);
user.stop.departures[0].trafficInfo = ex2.title;
}
}
if (stopPoint.gid === globalData.user.stoppointgid) {
this.state.disruption = ex2;
var old4t = moment(globalData.stop.departures[0].time, "HH:mm");
old4t.add(ex2.time, "HH:mm");
globalData.stop.departures[0].newTime = this.showMomentTime(old4t);
globalData.stop.departures[0].trafficInfo = ex2.title;
globalData.snackbarVisible = true; globalData.root.forceUpdate();
}
}
}
globalData.disruption = this.state.disruption
}
render() {
return (
<div>
<Button onClick={this.props.onClick.concat([this.genDisrupt, this.updatePage])} className="disruptBtn">
{this.props.children}
</Button>
</div>
);
}
}
export default DisruptionButton;

View File

@ -1,45 +0,0 @@
import globalData from '../GlobalData.js';
import locationuser1 from '../APIexamples/locationuser1.json'
import locationuser2 from '../APIexamples/locationuser2.json'
import locationuser3 from '../APIexamples/locationuser3.json'
import locationuser4 from '../APIexamples/locationuser4.json'
import StopSelectButton from './StopSelectButton.js';
import Button from './Button.js';
import disruptIcon from '../img/flash.svg';
class FindStops extends Button {
state = {
locations : []
}
findStops = () => {
if(globalData.user.deviceId === "1"){
this.state.locations = locationuser1.LocationList.StopLocation
}else if (globalData.user.deviceId === "2"){
this.state.locations = locationuser2.LocationList.StopLocation
}else if (globalData.user.deviceId === "3"){
this.state.locations = locationuser3.LocationList.StopLocation
}else if (globalData.user.deviceId === "4"){
this.state.locations = locationuser4.LocationList.StopLocation
}
}
render() {
return (
<>
<Button onClick={[this.findStops]} className="disruptBtn">
<img src={disruptIcon} alt="" />
<span>Select nearby stops</span>
</Button>
{this.state.locations.map((item) =>
<StopSelectButton stop={item}/>
)}
</>
);
}
}
export default FindStops;

View File

@ -1,31 +1,12 @@
import './css/Header.css';
import React, { Component } from 'react'; import React, { Component } from 'react';
import NavigationDrawer from './NavigationDrawer.js';
import './css/Header.css';
import navIcon from '../img/menu.svg'
class Header extends Component { class Header extends Component {
constructor(props) {
super(props);
this.navDrawerElem = React.createRef();
}
handleClick = () => {
this.navDrawerElem.current.toggle();
};
render() { render() {
return ( return (
<>
<NavigationDrawer ref={this.navDrawerElem} />
<header> <header>
<button id="navBtn"><img src={navIcon} alt="" onClick={this.handleClick} /></button> <button id="navDrawBtn"></button>
<h1 id="pageTitle">{this.props.title}</h1>
</header> </header>
</>
); );
} }
} }

View File

@ -1,15 +0,0 @@
import React, { Component } from 'react';
import './css/MainArea.css';
class MainArea extends Component {
render() {
return (
<main style={this.props.style}>
{this.props.children}
</main>
);
}
}
export default MainArea;

View File

@ -1,24 +0,0 @@
import Button from './Button.js';
class MenuButton extends Button {
render() {
if (this.props.childOrderReverse) {
return (
<Button className="menuButton">
<span>{this.props.label}</span>
<img src={this.props.icon} alt="" />
</Button>
);
} else {
return (
<Button className="menuButton">
<img src={this.props.icon} alt="" />
<span>{this.props.label}</span>
</Button>
);
}
}
}
export default MenuButton;

View File

@ -1,87 +1,10 @@
import './css/NavigationDrawer.css';
import React, { Component } from 'react'; import React, { Component } from 'react';
import globalData from '../GlobalData.js';
import DisruptionButton from "./DisruptionButton.js";
import SelectUserButton from "./SelectUserButton.js"
import Popup from './Popup.js';
import Button from './Button.js';
import './css/NavigationDrawer.css';
import userIcon from '../img/user.svg';
import disruptIcon from '../img/flash.svg';
class NavigationDrawer extends Component { class NavigationDrawer extends Component {
constructor(props) {
super(props);
this.popupElem = React.createRef();
}
state = {
open: false
};
toggle = () => {
if (this.state.open)
this.close();
else
this.open();
};
open = () => {
this.setState({
open: true
});
};
close = () => {
this.setState({
open: false
});
};
showPopup = () => {
this.popupElem.current.show();
};
hidePopup = () => {
this.popupElem.current.hide();
};
updatePage = () => {
globalData.currentPage.render();
}
render() { render() {
return ( return (
<> <div id="navDrawer"></div>
<Popup ref={this.popupElem}>
<h3>Välj scenario:</h3>
<ul>
<li><DisruptionButton path={"ex1"} onClick={[this.hidePopup]}>Störningsscenario 1</DisruptionButton></li>
<li><DisruptionButton path={"ex2"} onClick={[this.hidePopup]}>Störningsscenario 2</DisruptionButton></li>
</ul>
</Popup>
<div id="navDrawer" className={`${this.state.open ? "open" : ""}`}>
<header>
<img src={userIcon} alt="" />
<span>{globalData.user.name}</span>
<span>example@gmail.com</span>
</header>
<div id="navList">
<SelectUserButton path={"user1"} username="Guddeby"/>
<SelectUserButton path={"user2"} username="Hålta kyrka"/>
<SelectUserButton path={"user3"} username="Stenskärsvägen"/>
<SelectUserButton path={"user4"} username="Kuröd"/>
<Button onClick={[this.showPopup, this.close]} className="disruptBtn"><img src={disruptIcon} alt="" />Generera Störning</Button>
</div>
<hr />
<span id="version">Projektgrupp 3 - Utmaning 7</span>
</div>
<div id="clickArea" className={`${this.state.open ? "" : "hidden"}`} onClick={this.close} />
</>
); );
} }
} }

View File

@ -1,67 +0,0 @@
import React from 'react';
import axios from 'axios';
import AccessToken from '../classes/AccessToken';
import StopComponent from './StopComponent';
import Stop from '../classes/Stop';
class NearbyStation extends React.Component {
state = {
lat: '57.7',
long: '12.0',
stops: [],
token: undefined,
tokenClass: new AccessToken()
}
handleChangeLat = event => {
this.setState({ lat: event.target.value});
}
handleChangeLong = event => {
this.setState({ long: event.target.value});
}
handleSubmit = event => {
event.preventDefault();
const headers = {
'Authorization': 'Bearer ' + this.state.tokenClass.token
};
axios.get('https://api.vasttrafik.se/bin/rest.exe/v2/location.nearbystops?originCoordLat='+this.state.lat+'&originCoordLong='+this.state.long+'&maxNo=5&format=json', { headers })
.then(response => {
this.setState({
stops: response.data.LocationList.StopLocation,
})
})
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>
Lattitude coord:
<input type="text" name="lat" onChange={this.handleChangeLat} />
</label>
<label>
Longitude coord:
<input type="text" name="long" onChange={this.handleChangeLong} />
</label>
<button type="submit">Stops</button>
</form>
<h1>
{this.state.lat}
</h1>
<h1>
{this.state.long}
</h1>
{this.state.stops.map((item) =>
<StopComponent stop={item} />
)}
</div>
)
}
}
export default NearbyStation

View File

@ -0,0 +1,12 @@
import './css/PageArea.css';
import React, { Component } from 'react';
class PageArea extends Component {
render() {
return (
<div id="pageArea"></div>
);
}
}
export default PageArea;

View File

@ -1,36 +0,0 @@
import React, { Component } from 'react';
import './css/Popup.css';
class Popup extends Component {
state = {
visible: false
};
show = () => {
this.setState({
visible: true
});
};
hide = () => {
this.setState({
visible: false
});
};
render() {
return (
<>
<div className={`${this.state.visible ? "" : "hidden"}` + " popupClose"} onClick={this.hide} />
<div className={`${this.state.visible ? "visible" : ""}` + " popup " + this.props.className}>
{this.props.children}
</div>
</>
);
}
}
export default Popup;

View File

@ -1,90 +0,0 @@
import globalData from '../GlobalData.js';
import user1 from '../APIexamples/user1.json'
import user2 from '../APIexamples/user2.json'
import user3 from '../APIexamples/user3.json'
import user4 from '../APIexamples/user4.json'
import locationuser1 from '../APIexamples/locationuser1.json'
import locationuser2 from '../APIexamples/locationuser2.json'
import locationuser3 from '../APIexamples/locationuser3.json'
import locationuser4 from '../APIexamples/locationuser4.json'
import departureuser1 from '../APIexamples/departureuser1.json'
import departureuser2 from '../APIexamples/departureuser2.json'
import departureuser3 from '../APIexamples/departureuser3.json'
import departureuser4 from '../APIexamples/departureuser4.json'
import Button from './Button.js';
import userIcon from '../img/userDark.svg';
class SelectUserButton extends Button {
state = {
first: false,
u1: user1,
u2: user2,
u3: user3,
u4: user4,
}
genUsers = () => {
if (globalData.users.length < 2) {
this.state.first = true;
this.state.u1.stop = locationuser1.LocationList.StopLocation[0];
this.state.u1.stop.departures = departureuser1.DepartureBoard.Departures;
this.state.u2.stop = locationuser2.LocationList.StopLocation[0];
this.state.u2.stop.departures = departureuser2.DepartureBoard.Departures;
this.state.u3.stop = locationuser3.LocationList.StopLocation[0];
this.state.u3.stop.departures = departureuser3.DepartureBoard.Departures;
this.state.u4.stop = locationuser4.LocationList.StopLocation[0];
this.state.u4.stop.departures = departureuser4.DepartureBoard.Departures;
globalData.users = [
this.state.u1,
this.state.u2,
this.state.u3,
this.state.u4
]
}
}
selectUser = () => {
this.genUsers()
if(this.props.path === "user1"){
globalData.user = user1
globalData.user.track = locationuser1.LocationList.StopLocation[0].track
globalData.stop = locationuser1.LocationList.StopLocation[0]
globalData.stop.departures = departureuser1.DepartureBoard.Departures
}else if (this.props.path === "user2"){
globalData.user = user2
globalData.user.track = locationuser2.LocationList.StopLocation[0].track
globalData.stop = locationuser2.LocationList.StopLocation[0]
globalData.stop.departures = departureuser2.DepartureBoard.Departures
}else if (this.props.path === "user3"){
globalData.user = user3
globalData.user.track = locationuser3.LocationList.StopLocation[0].track
globalData.stop = locationuser3.LocationList.StopLocation[0]
globalData.stop.departures = departureuser3.DepartureBoard.Departures
}else if (this.props.path === "user4"){
globalData.user = user4
globalData.user.track = locationuser4.LocationList.StopLocation[0].track
globalData.stop = locationuser4.LocationList.StopLocation[0]
globalData.stop.departures = departureuser4.DepartureBoard.Departures
}
}
updatePage = () => {
globalData.currentPage.forceUpdate();
}
render() {
return (
<Button onClick={[this.selectUser, this.updatePage]} className="disruptBtn">
<img src={userIcon} alt="" />
{this.props.username}
</Button>
);
}
}
export default SelectUserButton;

View File

@ -1,61 +0,0 @@
import React from 'react';
import axios from 'axios';
import AccessToken from '../classes/AccessToken'
class StationDisruption extends React.Component {
state = {
gid: '9022014005700002',
lat: '57.7',
long: '12.0',
disruptions: [],
token: undefined,
tokenClass: new AccessToken()
}
handleChangeGid = event => {
this.setState({ lat: event.target.value});
}
handleSubmit = event => {
event.preventDefault();
const headers = {
'Authorization': 'Bearer ' + this.state.tokenClass.token
};
axios.get('https://api.vasttrafik.se/bin/rest.exe/v2/location.nearbystops?originCoordLat='+this.state.lat+'&originCoordLong='+this.state.long+'&maxNo=5&format=json', { headers })
.then(response => {
})
axios.get('https://api.vasttrafik.se/ts/v1/traffic-situations/stoppoint/'+this.state.gid, { headers })
.then(response => {
this.setState({
disruptions: response.data
})
})
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>
Stoppoint Gid:
<input type="text" name="gid" onChange={this.handleChangeGid} />
</label>
<button type="submit">Find traffic disruptions</button>
</form>
<h1>
{this.state.gid}
</h1>
{this.state.disruptions.map((item) =>
<div>
<h1>
{item.description}
</h1>
</div>
)}
</div>
)
}
}
export default StationDisruption

View File

@ -1,19 +0,0 @@
import React, {Component} from 'react';
class StopComponent extends Component {
render() {
return (
<div>
<h1>
{this.props.stop.name},
{this.props.stop.id},
{this.props.stop.lat},
{this.props.stop.lon},
{this.props.stop.track}
</h1>
</div>
);
}
}
// TODO Add css
export default StopComponent

View File

@ -1,22 +0,0 @@
import React, {Component} from 'react';
import globalData from '../GlobalData';
import Button from './Button.js';
class StopSelectButton extends Component {
selectStop = () => {
globalData.stop = this.props.stop
}
render() {
return (
<>
<Button onClick={[this.selectStop]}>
<span>{this.props.stop.name}</span>
</Button>
</>
);
}
}
// TODO Add css
export default StopSelectButton

View File

@ -1,72 +0,0 @@
import React, { Component } from 'react';
import Button from './Button.js';
import Popup from './Popup.js';
import globalData from '../GlobalData.js';
import './css/StopTitle.css';
class StopTitle extends Component {
constructor(props) {
super(props);
this.popupElem = React.createRef();
}
showPopup = () => {
this.popupElem.current.show();
};
hidePopup = () => {
this.popupElem.current.hide();
};
setTrackA = () => {
globalData.user.track = "A";
};
setTrackB = () => {
globalData.user.track = "B";
};
updatePage = () => {
globalData.currentPage.forceUpdate();
}
render() {
return (
<div id="stopTitle">
<Popup ref={this.popupElem} className="">
<h3>Välj läge:</h3>
<ul>
<>
<li><Button onClick={[this.setTrackA, this.updatePage, this.hidePopup]}>{"Läge A"}</Button></li>
<li><Button onClick={[this.setTrackB, this.updatePage, this.hidePopup]}>{"Läge B"}</Button></li>
</>
</ul>
</Popup>
<h1>{this.props.stop.name !== undefined ?
this.props.stop.name
: "Hållplats saknas"
}</h1>
{this.props.stop.name !== undefined && this.props.stop.track !== undefined ?
<div>
<h3>
<span>{"Läge " + globalData.user.track}</span>
</h3>
<Button className="changeTrackBtn" onClick={[this.showPopup]}>Byt Läge</Button>
</div>
:
(this.props.stop.name !== undefined ?
<></>
: <h3>Vänligen aktivera platsåtkomst</h3>
)
}
</div>
);
}
}
export default StopTitle;

View File

@ -1,15 +0,0 @@
import React, { Component } from 'react';
import './css/TopMenu.css';
class TopMenu extends Component {
render() {
return (
<div id="topMenu">
{this.props.children}
</div>
);
}
}
export default TopMenu;

View File

@ -1,84 +0,0 @@
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import './css/TrafficInfo.css';
import busIcon from '../img/bus.svg';
import warningIcon from '../img/warning.svg';
class TrafficEntry extends Component {
state = {
expanded: false
};
toggle = () => {
if (this.state.expanded)
this.collapse();
else
this.expand();
};
expand = () => {
this.setState({
expanded: true
});
};
collapse = () => {
this.setState({
expanded: false
});
};
render() {
let trafficInfo = this.props.departure.trafficInfo;
let lineInterference = trafficInfo !== "" && trafficInfo !== null && trafficInfo !== undefined;
return (
<div className="trafficEntry">
<div>
<div className="timeColumn">
{!lineInterference &&
<span>{this.props.departure.time}</span>
}
{lineInterference &&
<>
<div style={{display: "flex", flexDirection: "column"}}>
<span style={{color: "red", fontWeight: "bold"}}>{this.props.departure.newTime}</span>
<span style={{textDecoration: "line-through"}}>{this.props.departure.time}</span>
</div>
<img src={warningIcon} alt=""></img>
</>
}
</div>
<div className="lineColumn">
<div>
<span className="lineName">{this.props.departure.sname}</span>
<img src={busIcon} alt=""></img>
<span className="destination">{"Mot " + this.props.departure.direction}</span>
</div>
{lineInterference &&
<div className="infoWrapper" onClick={this.toggle}>
<p className={`${this.state.expanded ? "expanded" : ""}`}>
{trafficInfo}
<span style={{display: (this.state.expanded ? "inline" : "none"), marginLeft: "5px" }}><u>Visa mindre</u></span>
</p>
<span style={{display: (this.state.expanded ? "none" : "block") }}><u>Visa mer</u></span>
</div>
}
</div>
</div>
{lineInterference &&
<Link to={
{ pathname: "/travel"
, to: this.props.departure.direction
}
}>Hitta annan resväg</Link>
}
</div>
);
}
}
export default TrafficEntry;

View File

@ -1,38 +0,0 @@
import React, { Component } from 'react';
import TrafficEntry from './TrafficEntry.js';
import './css/TrafficInfo.css';
class TrafficList extends Component {
render() {
let entries = [];
if (this.props.departures) {
let i = 0; // React requires elems in array to have associated unique key
this.props.departures.forEach(departure => {
entries.push(
<TrafficEntry key={i++} departure={departure} />
);
});
// Add separator between every element
const intersperse = (arr, sep) => arr.reduce((a,v)=>[...a,v,sep],[]).slice(0,-1);
entries = intersperse(entries, (<hr key={i++} />));
// Add separator after the last element
entries.push(<hr key={i++} />);
}
return (
<div id="trafficList">
{entries.map(element => {
return element
})}
</div>
);
}
}
export default TrafficList;

View File

@ -1,17 +0,0 @@
import React, { Component } from 'react';
class TripSelector extends Component {
render() {
return (
<form>
<label>Från:</label>
<input type="text" placeholder="Hållplats/Adress/Plats" defaultValue={this.props.from}/>
<hr/>
<label>Till:</label>
<input type="text" placeholder="Hållplats/Adress/Plats" defaultValue={this.props.to} />
</form>
);
}
}
export default TripSelector;

View File

@ -1,38 +1,18 @@
#bottomMenu { #bottomMenu {
width: 100%; width: 100%;
height: 9vh; height: 8vh;
min-height: 70px; background: lightcoral;
background: white;
display: flex; display: flex;
justify-content: space-evenly; justify-content: space-evenly;
border-top: 2px solid rgba(0, 0, 0, 0.05);
}
#bottomMenu a {
display: contents;
text-decoration: none;
} }
#bottomMenu button { #bottomMenu button {
background: none; background: none;
border: none; border: none;
font-size: 0.9em; font-size: 0.9em;
margin-bottom: 5px;
flex-basis: calc(100%/3); flex-basis: calc(100%/3);
display: flex; display: flex;
flex-direction: column; align-items: flex-end;
align-items: center;
justify-content: space-evenly; justify-content: space-evenly;
word-break: break-word;
}
#bottomMenu button:active {
background: rgba(0, 0, 0, 0.1);
}
#bottomMenu button span {
color: black;
}
#bottomMenu button img {
width: 25px;
} }

View File

@ -1,7 +0,0 @@
button:active {
background: rgba(0, 0, 0, 0.1);
}
a:active {
background: rgba(0, 0, 0, 0.1);
}

View File

@ -1,21 +1,5 @@
header { header {
width: 100vw; width: 100vw;
display: flex; height: 15vh;
flex-direction: row; background: burlywood;
align-items: center;
padding: 15px 15px 12vh 15px;
top: 0;
background: linear-gradient(90deg, var(--colorVT1), var(--colorVT2));
}
#navBtn img {
height: 1.4em;
}
#pageTitle {
font-size: 1.2em;
letter-spacing: 0.3px;
color: white;
font-family: 'Roboto Light', sans-serif;
padding: 0 0 0 25px;
} }

View File

@ -1,8 +0,0 @@
main {
width: 100vw;
flex: 1 1 auto;
display: flex;
flex-flow: column;
justify-content: flex-start;
overflow: hidden scroll;
}

View File

@ -1,83 +0,0 @@
#navDrawer {
width: 70vw;
height: 100%;
position: fixed;
top: 0;
left: -70vw;
background: white;
overflow: hidden;
z-index: 10;
transition: .35s;
display: flex;
flex-flow: column;
}
.open {
left: 0 !important;
}
#navDrawer header {
width: 100%;
padding: 4vh 0;
color: white;
font-size: 16px;
flex-basis: 15vh;
flex-direction: column;
justify-content: space-evenly;
}
#navDrawer header img {
width: 35px;
}
#navList {
flex-basis: 70vh;
display: flex;
flex-flow: column;
align-items: flex-start;
}
.disruptBtn {
height: 50px;
width: 100%;
padding: 0 0 0 5vw;
display: flex;
align-items: center;
align-self: flex-start;
font-size: 14px;
}
.disruptBtn:active {
background: rgba(0, 0, 0, 0.1);
}
.disruptBtn img {
height: 55%;
margin-right: 10px;
}
#clickArea {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.75);
position: fixed;
z-index: 5;
transition: .15s;
}
#navDrawer hr {
width: 90%;
margin: 0 10px 5px 0;
align-self: flex-end;
opacity: 0.5;
flex-basis: auto;
}
#version {
align-self: flex-end;
margin-right: 10px;
font-size: 14px;
color: var(--colorDiscrete);
min-height: 50px;
}

View File

@ -0,0 +1,4 @@
#pageArea {
width: 100vw;
flex: 1 1 auto;
}

View File

@ -1,56 +0,0 @@
.popup {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0);
transform-origin: center;
background: white;
display: flex !important;
flex-direction: column !important;
width: 55vw;
height: 39vh;
padding: 3vh 5vw;
box-shadow: var(--boxShadow);
border-radius: var(--borderRadius);
transition: .35s;
z-index: 11;
}
.visible {
pointer-events: all;
transform: translate(-50%, -50%) scale(1);
}
.popup h3 {
margin-bottom: 20px;
display: block;
font-size: 1.17em;
font-weight: bold !important;
text-align: center;
color: black !important;
}
.popup ul {
list-style: none;
width: 100%;
}
.popup li button {
width: 100% !important;
height: 50px;
padding: 8% 0 !important;
font-size: 16px !important;
display: flex;
align-items: center;
justify-content: center;
}
.popupClose {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.75);
z-index: 11;
}

View File

@ -1,58 +0,0 @@
#stopTitle {
text-align: left;
background: white;
border-radius: var(--borderRadius);
box-shadow: var(--boxShadow);
display: flex;
flex-direction: column;
justify-content: space-evenly;
padding: 0 5vw;
z-index: 4;
max-width: 80vw;
}
#stopTitle h1, #stopTitle h3 {
font-weight: 100;
}
#stopTitle h1 {
font-size: 3.5vh;
}
#stopTitle h3 {
font-size: 5vw;
color: var(--colorDiscrete);
}
@media screen and (min-width: 400px) {
#stopTitle h1 {
font-size: 4vh;
}
#stopTitle h3 {
font-size: 20px;
color: var(--colorDiscrete);
}
}
#stopTitle div {
display: flex;
flex-direction: row;
align-items: center;
}
.changeTrackBtn {
width: auto;
height: 100%;
box-shadow: none;
background: rgba(0, 0, 0, 0.2);
display: block;
flex-flow: row;
margin-left: 10px;
padding: 0 2.5vw;
border-radius: calc(var(--topMenuHeight) / 15);
}
.changeTrackBtn:active {
background: rgba(0, 0, 0, 0.3);
}

View File

@ -1,32 +0,0 @@
#topMenu {
width: 100vw;
height: var(--topMenuHeight);
margin-top: calc(var(--topMenuHeight) / -2);
display: inline-flex;
justify-content: space-evenly;
}
#topMenu .menuButton {
width: var(--topMenuHeight);
height: calc(var(--topMenuHeight) / 1.3);
display: flex;
flex-flow: column;
justify-content: space-evenly;
background: white;
border-radius: calc(var(--topMenuHeight) / 15);
box-shadow: var(--boxShadow);
}
#topMenu .menuButton:active {
background: rgb(235, 235, 235);
}
#topMenu img {
width: 100%;
height: 40%;
}
#topMenu button span {
width: 100%;
font-size: calc(var(--topMenuHeight) / 7);
}

View File

@ -1,139 +0,0 @@
#trafficList {
height: 100%;
margin-top: 40px;
padding-bottom: 40px;
background: white;
}
.trafficEntry {
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
width: 100vw;
padding: 8vw 0;
background: white;
font-size: 3.5vw;
}
.trafficEntry div {
width: 90%;
display: flex;
flex-direction: row;
justify-content: flex-start;
margin-bottom: 2vh;
}
.trafficEntry div:only-child {
margin-bottom: 0;
}
.trafficEntry div:only-child > .timeColumn,
.trafficEntry div:only-child > .lineColumn {
margin-bottom: 0;
}
.trafficEntry div:only-child > .timeColumn {
justify-content: center !important;
}
.trafficEntry div p {
text-align: left;
padding: 2vh 0 0 0;
}
.trafficEntry div div {
display: flex;
flex-direction: column;
}
.trafficEntry div div div {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: flex-end;
}
.timeColumn div:first-child, .lineColumn div:first-child {
height: 5.5vh;
}
.timeColumn {
flex-basis: 20%;
justify-content: flex-start !important;
align-items: center;
}
.timeColumn div {
align-items: center !important;
}
.timeColumn img {
width: 3.5vw;
}
.lineColumn {
flex-basis: 75%;
max-width: 75%;
}
.lineColumn div {
margin-bottom: 0px;
}
.lineColumn img {
flex-basis: 25%;
height: 9vw;
}
.infoWrapper p {
text-overflow: ellipsis;
overflow: hidden;
flex-basis: 75%;
flex-grow: 1;
display: block;
white-space: nowrap;
max-height: 4.5vw;
}
.infoWrapper span {
flex-basis: 25%;
}
.expanded {
white-space: normal !important;
max-height: none !important;
}
.lineName {
background: var(--colorLine);
color: white;
font-size: 6vw;
font-weight: 100;
padding: 1vw 2.5vw;
border-radius: var(--borderRadius);
font-family: 'Roboto Light';
height: 7vw;
flex-basis: 35%;
}
.destination {
flex-basis: 40%;
height: 9vw;
font-size: 4vw;
text-align: left;
display: flex;
align-items: flex-end;
}
.trafficEntry a {
width: 90%;
font-size: 4vw;
font-weight: bold;
color: var(--colorVT1);
padding: 4vw 0;
border-radius: var(--borderRadius);
box-shadow: var(--boxShadow);
text-decoration: none;
border: 1px solid rgba(0, 0, 0, 0.2);
}

View File

@ -1,32 +0,0 @@
form {
width: 65vw;
height: calc(var(--topMenuHeight));
background: white;
display: flex;
flex-flow: row wrap;
justify-content: space-evenly;
align-items: center;
font-size: 15px;
padding: 1vw 2vw;
border-radius: var(--borderRadius);
box-shadow: var(--boxShadow);
}
label {
flex-basis: 20%;
height: 15px;
}
input {
flex-basis: 70%;
height: 15px;
border: none;
}
hr {
--width: 90%;
flex-basis: var(--width);
margin: 0 calc((100% - var(--width)) / 2);
opacity: 0.5;
}

View File

@ -1,22 +0,0 @@
import React, { Component } from 'react';
import Header from '../Header.js';
import MainArea from '../MainArea.js';
import globalData from '../../GlobalData.js';
class Tickets extends Component {
render() {
globalData.currentPage = this;
return (
<>
<Header title="Biljetter" />
<MainArea style={{justifyContent: "space-evenly"}}>
<p>Du har inga biljetter</p>
</MainArea>
</>
);
}
}
export default Tickets;

View File

@ -1,34 +0,0 @@
import React, { Component } from 'react';
import Header from '../Header.js';
import TopMenu from '../TopMenu.js';
import MenuButton from '../MenuButton.js';
import MainArea from '../MainArea.js';
import clockIcon from '../../img/clock.svg';
import calendarIcon from '../../img/calendar.svg';
import recurringIcon from '../../img/redo.svg';
import globalData from '../../GlobalData.js';
class TicketsBuy extends Component {
render() {
globalData.currentPage = this;
return (
<>
<Header title="Köp biljett" />
<TopMenu>
<MenuButton label="Enkelbiljett" icon={clockIcon} />
<MenuButton label="Periodbiljett" icon={calendarIcon} />
<MenuButton label="Dygnsbiljett" icon={recurringIcon} />
</TopMenu>
<MainArea style={{justifyContent: "space-evenly"}}>
<p>Du har inga tidigare köp</p>
</MainArea>
</>
);
}
}
export default TicketsBuy;

View File

@ -1,30 +0,0 @@
import React, { Component } from "react";
import Header from "../Header.js";
import TopMenu from "../TopMenu.js";
import MainArea from "../MainArea.js";
import StopTitle from "../StopTitle.js";
import TrafficList from "../TrafficList.js";
import globalData from '../../GlobalData.js';
class TrafficInfo extends Component {
render() {
globalData.currentPage = this;
return (
<>
<Header title="Trafikinfo" />
<TopMenu>
<StopTitle stop={globalData.stop} />
</TopMenu>
<MainArea>
<TrafficList departures={globalData.stop.departures} />
</MainArea>
</>
);
}
}
export default TrafficInfo;

View File

@ -1,32 +0,0 @@
import React, { Component } from 'react';
import Header from '../Header.js';
import TopMenu from '../TopMenu.js';
import MainArea from '../MainArea.js';
import TripSelector from '../TripSelector.js';
import '../css/TripSelector.css';
import globalData from '../../GlobalData.js';
class Travel extends Component {
render() {
globalData.currentPage = this;
return (
<>
<Header title="Reseplanering" />
<TopMenu>
<TripSelector
from={this.props.location.from}
to={this.props.location.to}
/>
</TopMenu>
<MainArea style={{justifyContent: "space-evenly"}}>
</MainArea>
</>
);
}
}
export default Travel;

Binary file not shown.

View File

@ -1,71 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<path d="M53.333,234.667v-64C59.221,170.667,64,165.888,64,160s-4.779-10.667-10.667-10.667C23.915,149.333,0,173.269,0,202.667
V224c0,17.643,14.357,32,32,32h21.333C59.221,256,64,251.221,64,245.333S59.221,234.667,53.333,234.667z"/>
</g>
</g>
<g>
<g>
<path d="M458.667,149.333c-5.888,0-10.667,4.779-10.667,10.667s4.779,10.667,10.667,10.667v64
c-5.888,0-10.667,4.779-10.667,10.667S452.779,256,458.667,256H480c17.643,0,32-14.357,32-32v-21.333
C512,173.269,488.085,149.333,458.667,149.333z"/>
</g>
</g>
<g>
<g>
<path d="M181.333,448c-5.888,0-10.667,4.779-10.667,10.667h-64c0-5.888-4.779-10.667-10.667-10.667s-10.667,4.779-10.667,10.667
V480c0,17.643,14.357,32,32,32H160c17.643,0,32-14.357,32-32v-21.333C192,452.779,187.221,448,181.333,448z"/>
</g>
</g>
<g>
<g>
<path d="M416,448c-5.888,0-10.667,4.779-10.667,10.667h-64c0-5.888-4.779-10.667-10.667-10.667S320,452.779,320,458.667V480
c0,17.643,14.357,32,32,32h42.667c17.643,0,32-14.357,32-32v-21.333C426.667,452.779,421.888,448,416,448z"/>
</g>
</g>
<g>
<g>
<path d="M416,0H96C66.581,0,42.667,23.936,42.667,53.333V416c0,29.397,23.915,53.333,53.333,53.333h320
c29.419,0,53.333-23.936,53.333-53.333V53.333C469.333,23.936,445.419,0,416,0z M138.667,42.667h234.667c17.643,0,32,14.357,32,32
c0,17.643-14.357,32-32,32H138.667c-17.643,0-32-14.357-32-32C106.667,57.024,121.024,42.667,138.667,42.667z M138.667,405.333
c-17.643,0-32-14.357-32-32c0-17.643,14.357-32,32-32c17.643,0,32,14.357,32,32C170.667,390.976,156.309,405.333,138.667,405.333z
M373.333,405.333c-17.643,0-32-14.357-32-32c0-17.643,14.357-32,32-32c17.643,0,32,14.357,32,32
C405.333,390.976,390.976,405.333,373.333,405.333z M426.667,266.667c0,17.643-14.357,32-32,32H117.333c-17.643,0-32-14.357-32-32
V160c0-17.643,14.357-32,32-32h277.333c17.643,0,32,14.357,32,32V266.667z"/>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -1,59 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<g>
<circle cx="386" cy="210" r="20"/>
<path d="M432,40h-26V20c0-11.046-8.954-20-20-20c-11.046,0-20,8.954-20,20v20h-91V20c0-11.046-8.954-20-20-20
c-11.046,0-20,8.954-20,20v20h-90V20c0-11.046-8.954-20-20-20s-20,8.954-20,20v20H80C35.888,40,0,75.888,0,120v312
c0,44.112,35.888,80,80,80h153c11.046,0,20-8.954,20-20c0-11.046-8.954-20-20-20H80c-22.056,0-40-17.944-40-40V120
c0-22.056,17.944-40,40-40h25v20c0,11.046,8.954,20,20,20s20-8.954,20-20V80h90v20c0,11.046,8.954,20,20,20s20-8.954,20-20V80h91
v20c0,11.046,8.954,20,20,20c11.046,0,20-8.954,20-20V80h26c22.056,0,40,17.944,40,40v114c0,11.046,8.954,20,20,20
c11.046,0,20-8.954,20-20V120C512,75.888,476.112,40,432,40z"/>
<path d="M391,270c-66.72,0-121,54.28-121,121s54.28,121,121,121s121-54.28,121-121S457.72,270,391,270z M391,472
c-44.663,0-81-36.336-81-81s36.337-81,81-81c44.663,0,81,36.336,81,81S435.663,472,391,472z"/>
<path d="M420,371h-9v-21c0-11.046-8.954-20-20-20c-11.046,0-20,8.954-20,20v41c0,11.046,8.954,20,20,20h29
c11.046,0,20-8.954,20-20C440,379.954,431.046,371,420,371z"/>
<circle cx="299" cy="210" r="20"/>
<circle cx="212" cy="297" r="20"/>
<circle cx="125" cy="210" r="20"/>
<circle cx="125" cy="297" r="20"/>
<circle cx="125" cy="384" r="20"/>
<circle cx="212" cy="384" r="20"/>
<circle cx="212" cy="210" r="20"/>
</g>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1 +0,0 @@
<svg height="384pt" viewBox="0 0 384 384" width="384pt" xmlns="http://www.w3.org/2000/svg"><path d="m343.59375 101.039062c-7.953125 3.847657-11.28125 13.417969-7.433594 21.367188 10.511719 21.714844 15.839844 45.121094 15.839844 69.59375 0 88.222656-71.777344 160-160 160s-160-71.777344-160-160 71.777344-160 160-160c36.558594 0 70.902344 11.9375 99.328125 34.519531 6.894531 5.503907 16.976563 4.351563 22.480469-2.566406 5.503906-6.914063 4.351562-16.984375-2.570313-22.480469-33.652343-26.746094-76-41.472656-119.238281-41.472656-105.863281 0-192 86.136719-192 192s86.136719 192 192 192 192-86.136719 192-192c0-29.335938-6.40625-57.449219-19.039062-83.527344-3.839844-7.96875-13.441407-11.289062-21.367188-7.433594zm0 0"/><path d="m192 64c-8.832031 0-16 7.167969-16 16v112c0 8.832031 7.167969 16 16 16h80c8.832031 0 16-7.167969 16-16s-7.167969-16-16-16h-64v-96c0-8.832031-7.167969-16-16-16zm0 0"/></svg>

Before

Width:  |  Height:  |  Size: 906 B

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 329 329" style="enable-background:new 0 0 329 329;" xml:space="preserve">
<path d="M194.6,164.8L322.7,36.7c8.3-8.3,8.3-21.8,0-30.1s-21.8-8.3-30.1,0l-128.1,128L36.4,6.5c-8.3-8.3-21.8-8.3-30.1,0
s-8.3,21.8,0,30.1l128.1,128.1L6.3,292.9c-8.3,8.3-8.3,21.8,0,30.1c4.2,4.2,9.6,6.2,15.1,6.2s10.9-2.1,15.1-6.2l128.1-128.1
l128,128.1c4.2,4.2,9.6,6.2,15.1,6.2s10.9-2.1,15.1-6.2c8.3-8.3,8.3-21.8,0-30.1L194.6,164.8z"/>
</svg>

Before

Width:  |  Height:  |  Size: 691 B

View File

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<path d="M400.268,175.599c-1.399-3.004-4.412-4.932-7.731-4.932h-101.12l99.797-157.568c1.664-2.628,1.766-5.956,0.265-8.678
C389.977,1.69,387.109,0,384.003,0H247.47c-3.234,0-6.187,1.826-7.637,4.719l-128,256c-1.323,2.637-1.178,5.777,0.375,8.294
c1.562,2.517,4.301,4.053,7.262,4.053h87.748l-95.616,227.089c-1.63,3.883-0.179,8.388,3.413,10.59
c1.382,0.845,2.918,1.254,4.446,1.254c2.449,0,4.864-1.05,6.537-3.029l273.067-324.267
C401.206,182.161,401.667,178.611,400.268,175.599z"/>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1005 B

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 341.3 341.3" style="enable-background:new 0 0 341.3 341.3;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g>
<g>
<rect y="277.3" class="st0" width="341.3" height="42.7"/>
</g>
</g>
<g>
<g>
<rect y="149.3" class="st0" width="341.3" height="42.7"/>
</g>
</g>
<g>
<g>
<rect y="21.3" class="st0" width="341.3" height="42.7"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 656 B

View File

@ -1 +0,0 @@
<svg height="512pt" viewBox="0 0 512 512" width="512pt" xmlns="http://www.w3.org/2000/svg"><path d="m502.121094 1.214844c-5.972656-2.453125-12.863282-1.109375-17.429688 3.476562l-57.597656 57.601563c-47.488281-39.210938-108.417969-62.292969-171.09375-62.292969-141.164062 0-256 114.835938-256 256s114.835938 256 256 256c68.332031 0 132.609375-26.644531 180.96875-75.03125 8.34375-8.339844 8.34375-21.820312 0-30.164062-8.339844-8.339844-21.820312-8.339844-30.164062 0-40.296876 40.320312-93.867188 62.527343-150.804688 62.527343-117.632812 0-213.332031-95.699219-213.332031-213.332031s95.699219-213.332031 213.332031-213.332031c51.414062 0 101.332031 18.496093 140.777344 49.917969l-50.75 50.773437c-4.585938 4.585937-5.929688 11.457031-3.476563 17.429687 2.472657 5.972657 8.296875 9.878907 14.78125 9.878907h138.667969c8.832031 0 16-7.167969 16-16v-138.667969c0-6.484375-3.902344-12.308594-9.878906-14.785156zm0 0"/></svg>

Before

Width:  |  Height:  |  Size: 924 B

View File

@ -1,56 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<style type="text/css">
.st0{clip-path:url(#SVGID_2_);}
.st1{display:none;}
.st2{display:inline;fill:#FF0000;}
</style>
<g id="Capa_1">
</g>
<g id="Layer_4">
<g>
<defs>
<polygon id="SVGID_1_" points="0,0 0,512 299,512 299,393.4 184.1,393.4 184.1,327.8 299,327.8 298.9,234.3 364.5,234.3
364.5,327.8 479.4,327.8 479.4,393.4 364.5,393.4 362.9,512 512,512 512,0 "/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
</clipPath>
<g class="st0">
<g>
<path d="M448.7,128.2l-10.6,10.6c-8.7,8.7-20.2,13.4-32.4,13.4s-23.8-4.8-32.4-13.4c-8.7-8.7-13.4-20.2-13.4-32.4
s4.8-23.8,13.4-32.4l10.6-10.6L320.5,0L0,320.5l63.3,63.3l10.6-10.6c8.7-8.7,20.2-13.4,32.4-13.4s23.8,4.8,32.4,13.4
c8.7,8.7,13.4,20.2,13.4,32.4s-4.8,23.8-13.4,32.4l-10.6,10.6l63.3,63.3L512,191.5L448.7,128.2z M169.6,447.6
c8.2-12.3,12.7-26.8,12.7-42c0-20.3-7.9-39.3-22.2-53.7c-14.3-14.3-33.4-22.2-53.7-22.2c-15.2,0-29.7,4.4-42,12.7l-21.9-21.9
l278-278l21.9,21.9c-8.2,12.3-12.7,26.8-12.7,42c0,20.3,7.9,39.3,22.2,53.7c14.3,14.3,33.4,22.2,53.7,22.2
c15.2,0,29.7-4.4,42-12.7l21.9,21.9l-278,278L169.6,447.6z"/>
</g>
</g>
<g class="st0">
<g>
<rect x="284" y="197.9" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -63.0406 273.8113)" width="30" height="30.1"/>
</g>
</g>
<g class="st0">
<g>
<rect x="241.4" y="155.3" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -45.3836 231.2101)" width="30" height="30.1"/>
</g>
</g>
<g class="st0">
<g>
<rect x="326.6" y="240.5" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -80.6853 316.4155)" width="30" height="30.1"/>
</g>
</g>
</g>
</g>
<g id="Layer_3" class="st1">
<polygon class="st2" points="298.9,234.3 364.5,234.3 364.5,327.8 479.4,327.8 479.4,393.4 364.5,393.4 364.5,486.9 298.9,486.9
299,393.4 184.1,393.4 184.1,327.8 299,327.8 "/>
</g>
<g id="Layer_2">
<rect x="312.4" y="273.8" transform="matrix(-1.836970e-16 1 -1 -1.836970e-16 692.3611 28.913)" width="38.6" height="173.7"/>
<rect x="312.4" y="273.8" transform="matrix(-1 -1.224647e-16 1.224647e-16 -1 663.4481 721.2742)" width="38.6" height="173.7"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<path d="M448.678,128.219l-10.607,10.608c-8.667,8.667-20.191,13.44-32.449,13.44c-12.258,0-23.78-4.773-32.448-13.44
c-8.667-8.667-13.44-20.191-13.44-32.448s4.773-23.781,13.44-32.449l10.608-10.608L320.459,0L0,320.459l63.322,63.322
l10.608-10.608c8.667-8.667,20.191-13.44,32.449-13.44c12.258,0,23.78,4.773,32.448,13.44c8.667,8.667,13.44,20.191,13.44,32.448
s-4.773,23.781-13.44,32.449l-10.608,10.608L191.541,512L512,191.541L448.678,128.219z M169.61,447.636
c8.237-12.343,12.662-26.839,12.662-42.015c0-20.272-7.894-39.33-22.229-53.664c-14.334-14.335-33.393-22.229-53.664-22.229
c-15.176,0-29.672,4.425-42.015,12.662l-21.932-21.931L320.459,42.432l21.931,21.932c-8.237,12.343-12.662,26.839-12.662,42.015
c0,20.272,7.894,39.33,22.229,53.664c14.334,14.335,33.393,22.229,53.664,22.229c15.176,0,29.672-4.425,42.015-12.662
l21.932,21.931L191.541,469.568L169.61,447.636z"/>
</g>
</g>
<g>
<g>
<rect x="284.001" y="197.94" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -63.0395 273.8137)" width="30.004" height="30.124"/>
</g>
</g>
<g>
<g>
<rect x="241.404" y="155.325" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -45.3819 231.2119)" width="30.004" height="30.124"/>
</g>
</g>
<g>
<g>
<rect x="326.607" y="240.541" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -80.684 316.4184)" width="30.004" height="30.124"/>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,2 +0,0 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><g><path d="M256,184a56,56,0,1,0,56,56A56.063,56.063,0,0,0,256,184Zm0,96a40,40,0,1,1,40-40A40.045,40.045,0,0,1,256,280Z"/><path d="M256,56a56,56,0,1,0,56,56A56.063,56.063,0,0,0,256,56Zm0,96a40,40,0,1,1,40-40A40.045,40.045,0,0,1,256,152Z"/><path d="M256,312a56,56,0,1,0,56,56A56.063,56.063,0,0,0,256,312Zm0,96a40,40,0,1,1,40-40A40.045,40.045,0,0,1,256,408Z"/><path d="M368,304a8,8,0,0,0,7.89-6.68l16-96A8.007,8.007,0,0,0,384,192H352V168h16a8,8,0,0,0,7.89-6.68l16-96A8.007,8.007,0,0,0,384,56H352V40a8,8,0,0,0-8-8H319.71A28.043,28.043,0,0,0,292,8H220a28.043,28.043,0,0,0-27.71,24H168a8,8,0,0,0-8,8V56H128a8.007,8.007,0,0,0-7.89,9.32l16,96A8,8,0,0,0,144,168h16v24H128a8.007,8.007,0,0,0-7.89,9.32l16,96A8,8,0,0,0,144,304h16v16H128a8.007,8.007,0,0,0-7.89,9.32l16,96A8,8,0,0,0,144,432h16v8a8,8,0,0,0,8,8h48v48a8,8,0,0,0,8,8h64a8,8,0,0,0,8-8V448h48a8,8,0,0,0,8-8v-8h16a8,8,0,0,0,7.89-6.68l16-96A8.007,8.007,0,0,0,384,320H352V304ZM352,72h22.56l-13.34,80H352Zm0,136h22.56l-13.34,80H352ZM160,416h-9.22l-13.34-80H160Zm0-128h-9.22l-13.34-80H160Zm0-136h-9.22L137.44,72H160ZM220,24h72a12.014,12.014,0,0,1,11.31,8H208.69A12.014,12.014,0,0,1,220,24Zm60,464H232V448h48Zm56-56H176V48H336Zm38.56-96-13.34,80H352V336Z"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1,8 +0,0 @@
<?xml version='1.0' encoding='iso-8859-1'?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 470 470" xmlns:xlink="http://www.w3.org/1999/xlink" enable-background="new 0 0 470 470">
<g>
<path d="m386.032,146.681h-9.045v-23.144c0-25.859-21.038-46.898-46.898-46.898h-70.411l26.433-61.639h25.056c4.143,0 7.5-3.358 7.5-7.5s-3.357-7.5-7.5-7.5h-29.929c-0.023,0-0.045,0-0.068,0h-90.215c-0.023,0-0.047,0-0.07,0h-29.929c-4.143,0-7.5,3.358-7.5,7.5s3.357,7.5 7.5,7.5h25.056l26.433,61.639h-72.533c-25.86,0-46.898,21.039-46.898,46.898v23.144h-9.045c-11.304,0-20.5,9.196-20.5,20.5v50.88c0,4.142 3.357,7.5 7.5,7.5s7.5-3.358 7.5-7.5v-50.88c0-3.033 2.468-5.5 5.5-5.5h9.045v240.819c0,4.142 3.357,7.5 7.5,7.5h41.893l-47.197,47.197c-2.145,2.145-2.786,5.371-1.625,8.173 1.16,2.803 3.896,4.63 6.929,4.63h268.975c3.033,0 5.769-1.827 6.929-4.63 1.161-2.803 0.52-6.028-1.625-8.173l-30-29.999c-0.003-0.002-17.199-17.198-17.199-17.198h41.893c4.143,0 7.5-3.358 7.5-7.5v-240.819h9.045c3.032,0 5.5,2.467 5.5,5.5v50.88c0,4.142 3.357,7.5 7.5,7.5s7.5-3.358 7.5-7.5v-50.88c0-11.304-9.196-20.5-20.5-20.5zm-183.7-131.681h67.459l-26.433,61.639h-14.593l-26.433-61.639zm-94.319,108.537c0-17.588 14.31-31.898 31.898-31.898h83.86c0.018,0 0.036,0.004 0.054,0.004 0.026,0 0.052-0.004 0.078-0.004h24.365c0.049,0 81.82,0 81.82,0 17.589,0 31.898,14.31 31.898,31.898v23.144h-253.973v-23.144zm79.487,178.247v-140.103h95v140.104h-95zm-68.881,153.215l15-15h202.761l15,15h-232.761zm202.761-30h-172.761l15-15h142.76l15.001,15zm40.607-30h-253.974v-233.319h64.487v140.104h-41.987c-4.143,0-7.5,3.358-7.5,7.5s3.357,7.5 7.5,7.5h208.975c4.143,0 7.5-3.358 7.5-7.5s-3.357-7.5-7.5-7.5h-41.988v-140.104h64.487v233.319z"/>
<path d="M290,126.66c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H180c-4.143,0-7.5,3.358-7.5,7.5s3.357,7.5,7.5,7.5H290z"/>
<path d="m235,333.392c-12.406,0-22.5,10.093-22.5,22.5s10.094,22.5 22.5,22.5 22.5-10.093 22.5-22.5-10.094-22.5-22.5-22.5zm0,30c-4.136,0-7.5-3.364-7.5-7.5s3.364-7.5 7.5-7.5 7.5,3.364 7.5,7.5-3.364,7.5-7.5,7.5z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 460.8 460.8" style="enable-background:new 0 0 460.8 460.8;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g>
<g>
<path class="st0" d="M230.4,0c-65.8,0-119.6,53.8-119.6,119.6s53.8,119.6,119.6,119.6s119.6-53.8,119.6-119.6S296.3,0,230.4,0z"/>
</g>
</g>
<g>
<g>
<path class="st0" d="M435.8,334.9c-3.1-7.8-7.3-15.2-12-21.9c-24-35.5-61.1-59-102.9-64.8c-5.2-0.5-11,0.5-15.2,3.7
c-21.9,16.2-48.1,24.6-75.2,24.6s-53.3-8.4-75.2-24.6c-4.2-3.1-9.9-4.7-15.2-3.7c-41.8,5.7-79.4,29.3-102.9,64.8
c-4.7,6.8-8.9,14.6-12,21.9c-1.6,3.1-1,6.8,0.5,9.9c4.2,7.3,9.4,14.6,14.1,20.9c7.3,9.9,15.2,18.8,24,27.2
c7.3,7.3,15.7,14.1,24,20.9c41.3,30.8,90.9,47,142.1,47s100.8-16.2,142.1-47c8.4-6.3,16.7-13.6,24-20.9c8.4-8.4,16.7-17.2,24-27.2
c5.2-6.8,9.9-13.6,14.1-20.9C436.8,341.7,437.3,338,435.8,334.9z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 460.8 460.8" style="enable-background:new 0 0 460.8 460.8;" xml:space="preserve">
<g>
<g>
<path d="M230.4,0c-65.8,0-119.6,53.8-119.6,119.6s53.8,119.6,119.6,119.6S350,185.4,350,119.6S296.3,0,230.4,0z"/>
</g>
</g>
<g>
<g>
<path d="M435.8,334.9c-3.1-7.8-7.3-15.2-12-21.9c-24-35.5-61.1-59-102.9-64.8c-5.2-0.5-11,0.5-15.2,3.7
c-21.9,16.2-48.1,24.6-75.2,24.6s-53.3-8.4-75.2-24.6c-4.2-3.1-9.9-4.7-15.2-3.7c-41.8,5.7-79.4,29.3-102.9,64.8
c-4.7,6.8-8.9,14.6-12,21.9c-1.6,3.1-1,6.8,0.5,9.9c4.2,7.3,9.4,14.6,14.1,20.9c7.3,9.9,15.2,18.8,24,27.2
c7.3,7.3,15.7,14.1,24,20.9c41.3,30.8,90.9,47,142.1,47s100.8-16.2,142.1-47c8.4-6.3,16.7-13.6,24-20.9c8.4-8.4,16.7-17.2,24-27.2
c5.2-6.8,9.9-13.6,14.1-20.9C436.8,341.7,437.3,338,435.8,334.9z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<style type="text/css">
.st0{fill:#ED556C;}
</style>
<g>
<g>
<path class="st0" d="M501.4,384L320.5,51.5c-29.1-48.9-99.9-49-129,0L10.6,384c-29.7,50,6.3,113.3,64.5,113.3h361.7
C495,497.2,531.1,434,501.4,384z M256,437.2c-16.5,0-30-13.5-30-30s13.5-30,30-30s30,13.5,30,30S272.5,437.2,256,437.2z
M286,317.2c0,16.5-13.5,30-30,30s-30-13.5-30-30v-150c0-16.5,13.5-30,30-30s30,13.5,30,30V317.2z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 765 B

View File

@ -3,11 +3,6 @@
src: url('fonts/roboto-regular.ttf') format('truetype'); /* Safari, Android, iOS */ src: url('fonts/roboto-regular.ttf') format('truetype'); /* Safari, Android, iOS */
} }
@font-face {
font-family: 'Roboto Light';
src: url('fonts/roboto-light.ttf') format('truetype'); /* Safari, Android, iOS */
}
* { * {
margin: 0; margin: 0;
padding: 0; padding: 0;
@ -19,90 +14,3 @@ html, body, #root, #app {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
#root {
overflow: hidden;
}
button {
background: none;
border: none;
}
.hidden {
opacity: 0;
pointer-events: none;
}
.MuiSnackbar-root {
width: 90%;
left: 50% !important;
bottom: 90px !important;
transform: translateX(-50%);
}
.MuiSnackbarContent-root {
background: white !important;
color: black !important;
justify-content: space-between;
padding: 3.5vw 4vw !important;
border: 1px solid rgba(0, 0, 0, 0.2);
}
.MuiSnackbarContent-action {
flex-basis: 38%;
justify-content: flex-end;
margin-left: 0 !important;
margin-right: 0 !important;
padding-left: 0 !important;
height: 7.5vw;
align-items: center;
}
.MuiButtonBase-root{
width: 100%;
padding: 0 !important;
justify-content: space-between;
}
.MuiButtonBase-root:active {
background: none;
}
.MuiTouchRipple-root {
display: none;
}
.MuiSnackbarContent-message {
flex-basis: 60%;
padding: 0 !important;
}
.MuiIconButton-label {
justify-content: flex-end !important;
}
.MuiIconButton-label a {
align-items: center;
font-size: 3.5vw;
color: black;
text-decoration: none;
margin-right: 5vw;
}
.MuiIconButton-label img {
height: 3.5vw;
}
#snackDisruptInfo {
display: flex;
height: 7.5vw;
align-items: center;
font-size: 3.5vw;
font-weight: bold;
}
#snackDisruptInfo img {
height: 100%;
margin-right: 15px;
}

View File

@ -5,7 +5,9 @@ import App from './App';
import reportWebVitals from './reportWebVitals'; import reportWebVitals from './reportWebVitals';
ReactDOM.render( ReactDOM.render(
<App />, <React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root') document.getElementById('root')
); );

7
src/logo.svg Normal file
View File

@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
<g fill="#61DAFB">
<path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
<circle cx="420.9" cy="296.5" r="45.7"/>
<path d="M520.5 78.1z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -1,11 +0,0 @@
:root {
--colorVT1: rgb(1, 170, 235);
--colorVT2: rgb(25, 212, 245);
--colorBg: rgb(240, 248, 250);
--colorLine: rgb(0, 108, 144);
--colorDiscrete: rgba(0, 0, 0, 0.4);
--topMenuHeight: 15vh;
--borderRadius: calc(var(--topMenuHeight) / 15);
--boxShadow: 0px 1px 5px -1px rgba(0, 0, 0, 0.3);
}