Compare commits

...

29 Commits

Author SHA1 Message Date
André Wahlberg
0d26321055 Update style for snackbar notification 2020-12-15 10:53:19 +01:00
André Wahlberg
c294b60b5a Minor layout adjustments 2020-12-11 19:14:01 +01:00
André Wahlberg
13bf20c2ea Hide snackbar option to view traffic info if already on that page 2020-12-11 19:05:30 +01:00
André Wahlberg
30bcbd0286 Add 'Show less' in detailed traffic info paragraph 2020-12-11 18:23:51 +01:00
André Wahlberg
6fc5fd8ea4 Add snackbar notification for disruptions 2020-12-11 18:19:55 +01:00
André Wahlberg
b07708f3e9 Add border to button for alternative routes 2020-12-11 17:00:36 +01:00
André Wahlberg
84fa5e0597 Change usernames to stop names 2020-12-11 17:00:02 +01:00
williameriksson126
c0a64784ac Change: Disruption json file values 2020-12-11 11:38:42 +01:00
André Wahlberg
98db97627b Layout fixes 2020-12-11 11:01:43 +01:00
William Eriksson
b56e334d00
Merge pull request #14 from thefeli73/we-new-users
Add: new locations
2020-12-11 10:08:31 +01:00
William Eriksson
c1fe945a41
Merge branch 'main' into we-new-users 2020-12-11 10:08:22 +01:00
williameriksson126
919fd4b438 Add: new locations 2020-12-11 10:06:24 +01:00
André Wahlberg
be292c8aa3 Change of track and fix minor design flaws 2020-12-10 13:55:34 +01:00
williameriksson126
f7cbe39b0d Merge conflicts and small fixes 2020-12-10 13:21:09 +01:00
williameriksson126
078393335a Add: Update user disruption status when user is not selected 2020-12-10 13:19:07 +01:00
André Wahlberg
5cafe99946 Present correct information about track in traffic info 2020-12-10 12:48:36 +01:00
André Wahlberg
28d549de28 Minor design and typo fixes 2020-12-10 12:47:20 +01:00
williameriksson126
cd2a61947f Add: DateTime handling when displaying delay 2020-12-10 12:32:40 +01:00
williameriksson126
cf977ccb1f Almost done, final touches needed 2020-12-10 11:47:46 +01:00
André Wahlberg
1b3f5abd25 Fix nonexisting info being displayed oddly 2020-12-10 11:17:10 +01:00
André Wahlberg
9e185ef941 Fix wrong function name 2020-12-10 11:16:18 +01:00
williameriksson126
031829d4f9 Add: Traffic info now shows disruption data as well. Format of new time needs to be rewritten 2020-12-10 11:15:17 +01:00
williameriksson126
2b8c08e082 Change: departureuser4 to work correctly and updated UI for disruptions 2020-12-10 11:01:43 +01:00
William Eriksson
19282607ba
Merge pull request #13 from thefeli73/we-out-of-creativity-for-names
Add: Progress
2020-12-10 10:46:10 +01:00
William Eriksson
308bd7b99f
Merge branch 'main' into we-out-of-creativity-for-names 2020-12-10 10:45:54 +01:00
André Wahlberg
8e21856eb2 Update page when changing user 2020-12-10 10:43:43 +01:00
williameriksson126
df3e181e2e Add: Progress 2020-12-10 10:43:43 +01:00
André Wahlberg
211257ac67 Fix traffic info crash 2020-12-10 10:24:02 +01:00
William Eriksson
3b6aed2e41
Merge pull request #12 from thefeli73/we-departureboard-example
Add: json files for departure board for all users
2020-12-10 10:15:45 +01:00
44 changed files with 835 additions and 414 deletions

5
package-lock.json generated
View File

@ -10111,6 +10111,11 @@
"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",

View File

@ -7,6 +7,7 @@
"@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", "axios": "^0.21.0",
"moment": "^2.29.1",
"react": "^17.0.1", "react": "^17.0.1",
"react-axios": "^2.0.3", "react-axios": "^2.0.3",
"react-dom": "^17.0.1", "react-dom": "^17.0.1",

View File

@ -1,29 +1,53 @@
{ {
"DepartureBoard": { "DepartureBoard": {
"noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestDepartureBoard.xsd", "noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestDepartureBoard.xsd",
"servertime": "10:09", "servertime": "09:38",
"serverdate": "2020-12-10", "serverdate": "2020-12-11",
"Departure": { "Departures": [
{
"name": "Buss MEXP", "name": "Buss MEXP",
"sname": "MEXP", "sname": "MEXP",
"journeyNumber": "24", "journeyNumber": "22",
"type": "BUS", "type": "BUS",
"stopid": "9022014014754002", "stopid": "9022014014751002",
"stop": "Bollestadsvägen, Kungälv", "stop": "Guddeby",
"time": "10:09", "time": "09:40",
"date": "2020-12-10", "date": "2020-12-11",
"journeyid": "9015014621000024", "journeyid": "9015014621000022",
"direction": "Marstrand", "direction": "Marstrand",
"track": "B", "track": "B",
"rtTime": "10:11", "rtTime": "09:44",
"rtDate": "2020-12-10", "rtDate": "2020-12-11",
"fgColor": "#006C93", "fgColor": "#006C93",
"bgColor": "#FFFFFF", "bgColor": "#FFFFFF",
"stroke": "Solid", "stroke": "Solid",
"accessibility": "wheelChair", "accessibility": "wheelChair",
"JourneyDetailRef": { "JourneyDetailRef": {
"ref": "https://api.vasttrafik.se/bin/rest.exe/v2/journeyDetail?ref=347217%2F124275%2F19874%2F105802%2F80%3Fdate%3D2020-12-10%26station_evaId%3D14754002%26station_type%3Ddep%26format%3Djson%26" "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,29 +1,53 @@
{ {
"DepartureBoard": { "DepartureBoard": {
"noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestDepartureBoard.xsd", "noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestDepartureBoard.xsd",
"servertime": "10:10", "servertime": "09:41",
"serverdate": "2020-12-10", "serverdate": "2020-12-11",
"Departure": { "Departures": [
{
"name": "Buss MEXP", "name": "Buss MEXP",
"sname": "MEXP", "sname": "MEXP",
"journeyNumber": "24", "journeyNumber": "22",
"type": "BUS", "type": "BUS",
"stopid": "9022014014020002", "stopid": "9022014014010002",
"stop": "Ekelöv västra, Kungälv", "stop": "Hålta kyrka",
"time": "10:10", "time": "09:47",
"date": "2020-12-10", "date": "2020-12-11",
"journeyid": "9015014621000024", "journeyid": "9015014621000022",
"direction": "Marstrand", "direction": "Marstrand",
"track": "B", "track": "B",
"rtTime": "10:13", "rtTime": "09:50",
"rtDate": "2020-12-10", "rtDate": "2020-12-11",
"fgColor": "#006C93", "fgColor": "#006C93",
"bgColor": "#FFFFFF", "bgColor": "#FFFFFF",
"stroke": "Solid", "stroke": "Solid",
"accessibility": "wheelChair", "accessibility": "wheelChair",
"JourneyDetailRef": { "JourneyDetailRef": {
"ref": "https://api.vasttrafik.se/bin/rest.exe/v2/journeyDetail?ref=740262%2F255290%2F59460%2F217024%2F80%3Fdate%3D2020-12-10%26station_evaId%3D14020002%26station_type%3Ddep%26format%3Djson%26" "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,27 +1,53 @@
{ {
"DepartureBoard": { "DepartureBoard": {
"noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestDepartureBoard.xsd", "noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestDepartureBoard.xsd",
"servertime": "10:10", "servertime": "09:44",
"serverdate": "2020-12-10", "serverdate": "2020-12-11",
"Departure": { "Departures": [
{
"name": "Buss MEXP", "name": "Buss MEXP",
"sname": "MEXP", "sname": "MEXP",
"journeyNumber": "24", "journeyNumber": "22",
"type": "BUS", "type": "BUS",
"stopid": "9022014014751002", "stopid": "9022014014614002",
"stop": "Guddeby, Kungälv", "stop": "Stenskärsvägen",
"time": "10:07", "time": "09:52",
"date": "2020-12-10", "date": "2020-12-11",
"journeyid": "9015014621000024", "journeyid": "9015014621000022",
"direction": "Marstrand", "direction": "Marstrand",
"track": "B", "track": "B",
"rtTime": "09:57",
"rtDate": "2020-12-11",
"fgColor": "#006C93", "fgColor": "#006C93",
"bgColor": "#FFFFFF", "bgColor": "#FFFFFF",
"stroke": "Solid", "stroke": "Solid",
"accessibility": "wheelChair", "accessibility": "wheelChair",
"JourneyDetailRef": { "JourneyDetailRef": {
"ref": "https://api.vasttrafik.se/bin/rest.exe/v2/journeyDetail?ref=473190%2F166266%2F666560%2F175550%2F80%3Fdate%3D2020-12-10%26station_evaId%3D14751002%26station_type%3Ddep%26format%3Djson%26" "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,31 +1,29 @@
{ {
"DepartureBoard": { "DepartureBoard": {
"noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestDepartureBoard.xsd", "noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestDepartureBoard.xsd",
"servertime": "10:11", "servertime": "09:45",
"serverdate": "2020-12-10", "serverdate": "2020-12-11",
"Departure": [ "Departures": [{
{
"name": "Buss 928", "name": "Buss 928",
"sname": "928", "sname": "928",
"journeyNumber": "10", "journeyNumber": "10",
"type": "BUS", "type": "BUS",
"stopid": "9022014014225001", "stopid": "9022014014225001",
"stop": "Skrämmenborg, Kungälv", "stop": "Skrämmenborg",
"time": "15:19", "time": "15:19",
"date": "2020-12-10", "date": "2020-12-11",
"journeyid": "9015014692800010", "journeyid": "9015014692800010",
"direction": "Kärna", "direction": "Kärna",
"track": "A", "track": "A",
"rtTime": "15:19", "rtTime": "15:19",
"rtDate": "2020-12-10", "rtDate": "2020-12-11",
"fgColor": "#006C93", "fgColor": "#006C93",
"bgColor": "#FFFFFF", "bgColor": "#FFFFFF",
"stroke": "Solid", "stroke": "Solid",
"accessibility": "wheelChair", "accessibility": "wheelChair",
"JourneyDetailRef": { "JourneyDetailRef": {
"ref": "https://api.vasttrafik.se/bin/rest.exe/v2/journeyDetail?ref=261732%2F87569%2F149176%2F12656%2F80%3Fdate%3D2020-12-10%26station_evaId%3D14225001%26station_type%3Ddep%26format%3Djson%26" "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,15 +1,12 @@
{ {
"situationNumber": "RT1", "situationNumber": "RT1",
"severity":"normal", "severity":"normal",
"title":"Stannar inte på dessa hållplatser", "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":[ "affectedStopPoints":[
{ {
"gid": "9022014014020001", "gid": "9022014014614001",
"name": "Ekelöv västra, Kungälv" "name": "Stenskärsvägen"
},
{
"gid": "9022014014751001",
"name": "Guddeby, Kungälv"
} }
] ]
} }

View File

@ -1,11 +1,20 @@
{ {
"situationNumber": "RT2", "situationNumber": "RT2",
"severity":"normal", "severity":"normal",
"title":"Försening", "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":[ "affectedStopPoints":[
{ {
"gid": "9021014014225000", "gid": "9022014014751001",
"name": "Skrämmenborg, Kungälv" "name": "Guddeby"
},
{
"gid": "9022014014010001",
"name": "Hålta kyrka"
},
{
"gid": "9022014014614001",
"name": "Stenskärsvägen"
} }
] ]
} }

View File

@ -1,36 +1,36 @@
{ {
"LocationList": { "LocationList": {
"noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestLocation.xsd", "noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestLocation.xsd",
"servertime": "16:48", "servertime": "09:34",
"serverdate": "2020-12-09", "serverdate": "2020-12-11",
"StopLocation": [ "StopLocation": [
{ {
"name": "Bollestadsvägen, Kungälv", "name": "Guddeby",
"id": "9022014014754001", "id": "9022014014751001",
"lat": "57.888940", "lat": "57.874665",
"lon": "11.885663", "lon": "11.903884",
"track": "A" "track": "A"
}, },
{ {
"name": "Bollestadsvägen, Kungälv", "name": "Guddeby",
"id": "9021014014754000", "id": "9021014014751000",
"lat": "57.889030", "lat": "57.874710",
"lon": "11.885708" "lon": "11.903929"
}, },
{ {
"name": "Bollestadsvägen, Kungälv", "name": "Guddeby",
"id": "9022014014754002", "id": "9022014014751002",
"lat": "57.889111", "lat": "57.874746",
"lon": "11.885753", "lon": "11.903965",
"track": "B" "track": "B"
}, },
{ {
"name": "Bredsten, Kungälv", "name": "Stället",
"id": "9022014014753002", "id": "9022014014744001",
"lat": "57.886450", "lat": "57.869784",
"lon": "11.889529", "lon": "11.904172",
"track": "B" "track": "A"
} }
] ]
} }
} }

View File

@ -1,36 +1,36 @@
{ {
"LocationList": { "LocationList": {
"noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestLocation.xsd", "noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestLocation.xsd",
"servertime": "16:47", "servertime": "09:35",
"serverdate": "2020-12-09", "serverdate": "2020-12-11",
"StopLocation": [ "StopLocation": [
{ {
"name": "Ekelöv västra, Kungälv", "name": "Hålta kyrka",
"id": "9022014014020001", "id": "9022014014010001",
"lat": "57.892527", "lat": "57.895125",
"lon": "11.865321", "lon": "11.827854",
"track": "A" "track": "A"
}, },
{ {
"name": "Ekelöv västra, Kungälv", "name": "Hålta kyrka",
"id": "9021014014020000", "id": "9021014014010000",
"lat": "57.892608", "lat": "57.895206",
"lon": "11.865312" "lon": "11.827647"
}, },
{ {
"name": "Ekelöv västra, Kungälv", "name": "Hålta kyrka",
"id": "9022014014020002", "id": "9022014014010002",
"lat": "57.892689", "lat": "57.895278",
"lon": "11.865285", "lon": "11.827440",
"track": "B" "track": "B"
}, },
{ {
"name": "Ekelöv östra, Kungälv", "name": "Hålta skola",
"id": "9022014014021002", "id": "9022014014015001",
"lat": "57.892994", "lat": "57.896015",
"lon": "11.873923", "lon": "11.824555",
"track": "B" "track": "A"
} }
] ]
} }
} }

View File

@ -1,36 +1,36 @@
{ {
"LocationList": { "LocationList": {
"noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestLocation.xsd", "noNamespaceSchemaLocation": "http://api.vasttrafik.se/v1/hafasRestLocation.xsd",
"servertime": "16:45", "servertime": "09:36",
"serverdate": "2020-12-09", "serverdate": "2020-12-11",
"StopLocation": [ "StopLocation": [
{ {
"name": "Guddeby, Kungälv", "name": "Stenskärsvägen",
"id": "9022014014751001", "id": "9022014014614001",
"lat": "57.874665", "lat": "57.894594",
"lon": "11.903884", "lon": "11.740128",
"track": "A" "track": "A"
}, },
{ {
"name": "Guddeby, Kungälv", "name": "Stenskärsvägen",
"id": "9021014014751000", "id": "9022014014614002",
"lat": "57.874710", "lat": "57.894729",
"lon": "11.903929" "lon": "11.739984",
},
{
"name": "Guddeby, Kungälv",
"id": "9022014014751002",
"lat": "57.874746",
"lon": "11.903965",
"track": "B" "track": "B"
}, },
{ {
"name": "Stället, Kungälv", "name": "Stenskärsvägen",
"id": "9022014014744001", "id": "9021014014614000",
"lat": "57.869784", "lat": "57.894738",
"lon": "11.904172", "lon": "11.739858"
"track": "A" },
{
"name": "Tjuvkilsboden",
"id": "9022014014615002",
"lat": "57.892743",
"lon": "11.743490",
"track": "B"
} }
] ]
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,12 +2,12 @@ import "./variables.css";
import "./App.css"; import "./App.css";
import React, { Component } from "react"; import React, { Component } from "react";
import { BrowserRouter as Router, Route } from "react-router-dom"; import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Snackbar from "@material-ui/core/Snackbar";
import IconButton from "@material-ui/core/IconButton";
import globalData from './GlobalData.js';
import BottomMenu from "./components/BottomMenu.js"; import BottomMenu from "./components/BottomMenu.js";
import NearbyStation from "./components/NearbyStation.js";
import Disruption from "./components/Disruption.js";
import StationDisruption from "./components/StationDisruption.js";
import Tickets from "./components/pages/Tickets.js"; import Tickets from "./components/pages/Tickets.js";
import TicketsBuy from "./components/pages/TicketsBuy.js"; import TicketsBuy from "./components/pages/TicketsBuy.js";
@ -15,9 +15,21 @@ import Travel from "./components/pages/Travel.js";
import TrafficInfo from "./components/pages/TrafficInfo.js"; import TrafficInfo from "./components/pages/TrafficInfo.js";
import "./variables.css"; 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> <Router>
<div className="App"> <div className="App">
@ -28,6 +40,32 @@ class App extends Component {
<Route path="/traffic" exact component={TrafficInfo} /> <Route path="/traffic" exact component={TrafficInfo} />
<BottomMenu /> <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>,
]}
/>
</div> </div>
</Router> </Router>
); );

View File

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

View File

@ -12,7 +12,6 @@ class AccessToken {
axios.post('https://api.vasttrafik.se/token','grant_type=client_credentials&scope=device_'+this.device, {headers} ) axios.post('https://api.vasttrafik.se/token','grant_type=client_credentials&scope=device_'+this.device, {headers} )
.then(response => { .then(response => {
console.log(response);
this.token = response.data.access_token this.token = response.data.access_token
}); });
} }

View File

@ -9,15 +9,15 @@
*/ */
class Departure { class Departure {
constructor(lineName, finalStop, originalTime, trafficInfo) { constructor(lineName, finalStop, originalTime) {
this.lineName = lineName; this.sname = lineName;
this.finalStop = finalStop; this.direction = finalStop;
this.originalTime = originalTime; this.time = originalTime;
this.trafficInfo = trafficInfo;
} }
timeUpdate(time) { timeUpdate(time, trafficInfo) {
this.newTime = time; this.newTime = time;
this.trafficInfo = trafficInfo;
} }
} }

View File

@ -4,14 +4,16 @@
name : String (Användarnamn) name : String (Användarnamn)
deviceId : Int (Enhetens ID) deviceId : Int (Enhetens ID)
location : Coordinates (Användarens koordinater) location : Coordinates (Användarens koordinater)
track : String (Nuvarande hållplatsläge)
*/ */
class User { class User {
constructor(name, deviceId, location, stoppointgid) { constructor(name, deviceId, location, stoppointgid, track) {
this.name = name; this.name = name;
this.deviceId = deviceId; this.deviceId = deviceId;
this.location = location; this.location = location;
this.stoppointgid = stoppointgid; this.stoppointgid = stoppointgid;
this.track = track;
} }
} }

View File

@ -21,12 +21,9 @@ class Diruption extends React.Component {
'Authorization': 'Bearer ' + this.state.tokenClass.token 'Authorization': 'Bearer ' + this.state.tokenClass.token
}; };
console.log('Attempted connection')
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/'+this.state.gid, { headers })
//axios.get('https://api.vasttrafik.se/ts/v1/traffic-situations/stoppoint/9022014005700002', { headers }) //axios.get('https://api.vasttrafik.se/ts/v1/traffic-situations/stoppoint/9022014005700002', { headers })
.then(response => { .then(response => {
console.log(response)
this.setState({ this.setState({
disruptions: response.data disruptions: response.data
}) })

View File

@ -1,54 +1,124 @@
import addNotification from "react-push-notification"; import moment from "moment";
import globData from '../GlobalData.js'; 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 ex1 from '../APIexamples/disruption1.json'
import ex2 from '../APIexamples/disruption2.json' import ex2 from '../APIexamples/disruption2.json'
import Button from './Button.js';
import disruptIcon from '../img/flash.svg';
class DisruptionButton extends Button { class DisruptionButton extends Button {
state = { constructor(props) {
super(props);
this.state = {
jsonLocation: this.props.path, jsonLocation: this.props.path,
disruption: "" 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 = () => { genDisrupt = () => {
this.state.disruption = "" this.genUsers()
if(this.state.jsonLocation === "ex1"){
this.state.disruption = undefined
if (this.state.jsonLocation === "ex1") {
for (let stopPoint of ex1.affectedStopPoints) { for (let stopPoint of ex1.affectedStopPoints) {
if(stopPoint.gid === globData.user.stoppointgid){ for (let user of globalData.users) {
this.state.disruption = ex1 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;
} }
} }
} else if (this.state.jsonLocation === "ex2"){ 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 stopPoint of ex2.affectedStopPoints) {
if(stopPoint.gid === globData.user.stoppointgid){ for (let user of globalData.users) {
this.state.disruption = ex2 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();
} }
} }
} }
console.log(this.state.disruption) globalData.disruption = this.state.disruption
globData.disruption = this.state.disruption
addNotification({
title: "Warning",
subtitle: "This is a subtitle",
message: "This is a very long message",
theme: "blue",
native: true, // when using native, your OS will handle theming.
});
} }
render() { render() {
return ( return (
<Button onClick={this.props.onClick.concat([this.genDisrupt])} className="disruptBtn"> <div>
<img src={disruptIcon} alt="" /> <Button onClick={this.props.onClick.concat([this.genDisrupt, this.updatePage])} className="disruptBtn">
<span>Generera Störning</span> {this.props.children}
</Button> </Button>
</div>
); );
} }
} }

View File

@ -1,5 +1,5 @@
import globData from '../GlobalData.js'; import globalData from '../GlobalData.js';
import locationuser1 from '../APIexamples/locationuser1.json' import locationuser1 from '../APIexamples/locationuser1.json'
import locationuser2 from '../APIexamples/locationuser2.json' import locationuser2 from '../APIexamples/locationuser2.json'
@ -15,13 +15,13 @@ class FindStops extends Button {
locations : [] locations : []
} }
findStops = () => { findStops = () => {
if(globData.user.deviceId === "1"){ if(globalData.user.deviceId === "1"){
this.state.locations = locationuser1.LocationList.StopLocation this.state.locations = locationuser1.LocationList.StopLocation
}else if (globData.user.deviceId === "2"){ }else if (globalData.user.deviceId === "2"){
this.state.locations = locationuser2.LocationList.StopLocation this.state.locations = locationuser2.LocationList.StopLocation
}else if (globData.user.deviceId === "3"){ }else if (globalData.user.deviceId === "3"){
this.state.locations = locationuser3.LocationList.StopLocation this.state.locations = locationuser3.LocationList.StopLocation
}else if (globData.user.deviceId === "4"){ }else if (globalData.user.deviceId === "4"){
this.state.locations = locationuser4.LocationList.StopLocation this.state.locations = locationuser4.LocationList.StopLocation
} }
} }

View File

@ -5,14 +5,14 @@ class MenuButton extends Button {
render() { render() {
if (this.props.childOrderReverse) { if (this.props.childOrderReverse) {
return ( return (
<Button> <Button className="menuButton">
<span>{this.props.label}</span> <span>{this.props.label}</span>
<img src={this.props.icon} alt="" /> <img src={this.props.icon} alt="" />
</Button> </Button>
); );
} else { } else {
return ( return (
<Button> <Button className="menuButton">
<img src={this.props.icon} alt="" /> <img src={this.props.icon} alt="" />
<span>{this.props.label}</span> <span>{this.props.label}</span>
</Button> </Button>

View File

@ -9,7 +9,7 @@ import Button from './Button.js';
import './css/NavigationDrawer.css'; import './css/NavigationDrawer.css';
import userIcon from '../img/user.svg'; import userIcon from '../img/user.svg';
import FindStops from './FindStops.js'; import disruptIcon from '../img/flash.svg';
class NavigationDrawer extends Component { class NavigationDrawer extends Component {
@ -45,16 +45,22 @@ class NavigationDrawer extends Component {
this.popupElem.current.show(); this.popupElem.current.show();
}; };
hidePopup = () => {
this.popupElem.current.hide();
};
updatePage = () => {
globalData.currentPage.render();
}
render() { render() {
return ( return (
<> <>
<Popup ref={this.popupElem}> <Popup ref={this.popupElem}>
<h3>Välj hållplats:</h3> <h3>Välj scenario:</h3>
<ul> <ul>
<li><Button>Hållplats 1</Button></li> <li><DisruptionButton path={"ex1"} onClick={[this.hidePopup]}>Störningsscenario 1</DisruptionButton></li>
<li><Button>Hållplats 2</Button></li> <li><DisruptionButton path={"ex2"} onClick={[this.hidePopup]}>Störningsscenario 2</DisruptionButton></li>
<li><Button>Hållplats 3</Button></li>
<li><Button>Hållplats 4</Button></li>
</ul> </ul>
</Popup> </Popup>
@ -65,13 +71,11 @@ class NavigationDrawer extends Component {
<span>example@gmail.com</span> <span>example@gmail.com</span>
</header> </header>
<div id="navList"> <div id="navList">
<SelectUserButton path={"user1"} username="user1"/> <SelectUserButton path={"user1"} username="Guddeby"/>
<SelectUserButton path={"user2"} username="user2"/> <SelectUserButton path={"user2"} username="Hålta kyrka"/>
<SelectUserButton path={"user3"} username="user3"/> <SelectUserButton path={"user3"} username="Stenskärsvägen"/>
<SelectUserButton path={"user4"} username="user4"/> <SelectUserButton path={"user4"} username="Kuröd"/>
<FindStops/> <Button onClick={[this.showPopup, this.close]} className="disruptBtn"><img src={disruptIcon} alt="" />Generera Störning</Button>
<DisruptionButton path={"ex1"} onClick={[this.showPopup, this.close]} />
<DisruptionButton path={"ex2"} onClick={[this.showPopup, this.close]} />
</div> </div>
<hr /> <hr />
<span id="version">Projektgrupp 3 - Utmaning 7</span> <span id="version">Projektgrupp 3 - Utmaning 7</span>

View File

@ -28,11 +28,8 @@ class NearbyStation extends React.Component {
'Authorization': 'Bearer ' + this.state.tokenClass.token 'Authorization': 'Bearer ' + this.state.tokenClass.token
}; };
console.log('Attempted connection')
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 }) 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 => { .then(response => {
console.log(response.data.LocationList.StopLocation)
this.setState({ this.setState({
stops: response.data.LocationList.StopLocation, stops: response.data.LocationList.StopLocation,
}) })

View File

@ -1,36 +1,90 @@
import globalData from '../GlobalData.js';
import globData from '../GlobalData.js';
import user1 from '../APIexamples/user1.json' import user1 from '../APIexamples/user1.json'
import user2 from '../APIexamples/user2.json' import user2 from '../APIexamples/user2.json'
import user3 from '../APIexamples/user3.json' import user3 from '../APIexamples/user3.json'
import user4 from '../APIexamples/user4.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 Button from './Button.js';
import disruptIcon from '../img/flash.svg'; import userIcon from '../img/userDark.svg';
class SelectUserButton extends Button { class SelectUserButton extends Button {
selectUser = () => { state = {
if(this.props.path === "user1"){ first: false,
globData.user = user1 u1: user1,
}else if (this.props.path === "user2"){ u2: user2,
globData.user = user2 u3: user3,
}else if (this.props.path === "user3"){ u4: user4,
globData.user = user3
}else if (this.props.path === "user4"){
globData.user = 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() { render() {
return ( return (
<Button onClick={[this.selectUser]} className="disruptBtn"> <Button onClick={[this.selectUser, this.updatePage]} className="disruptBtn">
<img src={disruptIcon} alt="" /> <img src={userIcon} alt="" />
<span>{this.props.username}</span> {this.props.username}
</Button> </Button>
); );
} }
} }
export default SelectUserButton; export default SelectUserButton;

View File

@ -23,14 +23,11 @@ class StationDisruption extends React.Component {
'Authorization': 'Bearer ' + this.state.tokenClass.token 'Authorization': 'Bearer ' + this.state.tokenClass.token
}; };
console.log('Attempted connection')
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 }) 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 => { .then(response => {
console.log(response.data.LocationList.StopLocation)
}) })
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/'+this.state.gid, { headers })
.then(response => { .then(response => {
console.log(response)
this.setState({ this.setState({
disruptions: response.data disruptions: response.data
}) })

View File

@ -1,16 +1,69 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import Button from './Button.js';
import Popup from './Popup.js';
import globalData from '../GlobalData.js';
import './css/StopTitle.css'; import './css/StopTitle.css';
class StopTitle extends Component { 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() { render() {
return ( return (
<div id="stopTitle"> <div id="stopTitle">
<h1>{this.props.stop.name}</h1> <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> <div>
<h3>{this.props.stop.locations[0]}</h3> <h3>
<button>Byt Läge</button> <span>{"Läge " + globalData.user.track}</span>
</h3>
<Button className="changeTrackBtn" onClick={[this.showPopup]}>Byt Läge</Button>
</div> </div>
:
(this.props.stop.name !== undefined ?
<></>
: <h3>Vänligen aktivera platsåtkomst</h3>
)
}
</div> </div>
); );
} }

View File

@ -39,13 +39,13 @@ class TrafficEntry extends Component {
<div> <div>
<div className="timeColumn"> <div className="timeColumn">
{!lineInterference && {!lineInterference &&
<span>{this.props.departure.originalTime}</span> <span>{this.props.departure.time}</span>
} }
{lineInterference && {lineInterference &&
<> <>
<div style={{display: "flex", flexDirection: "column"}}> <div style={{display: "flex", flexDirection: "column"}}>
<span style={{color: "red", fontWeight: "bold"}}>{this.props.departure.newTime}</span> <span style={{color: "red", fontWeight: "bold"}}>{this.props.departure.newTime}</span>
<span style={{textDecoration: "line-through"}}>{this.props.departure.originalTime}</span> <span style={{textDecoration: "line-through"}}>{this.props.departure.time}</span>
</div> </div>
<img src={warningIcon} alt=""></img> <img src={warningIcon} alt=""></img>
</> </>
@ -53,13 +53,16 @@ class TrafficEntry extends Component {
</div> </div>
<div className="lineColumn"> <div className="lineColumn">
<div> <div>
<span className="lineName">{this.props.departure.lineName}</span> <span className="lineName">{this.props.departure.sname}</span>
<img src={busIcon} alt=""></img> <img src={busIcon} alt=""></img>
<span className="destination">{"Mot " + this.props.departure.finalStop}</span> <span className="destination">{"Mot " + this.props.departure.direction}</span>
</div> </div>
{lineInterference && {lineInterference &&
<div className="infoWrapper" onClick={this.toggle}> <div className="infoWrapper" onClick={this.toggle}>
<p className={`${this.state.expanded ? "expanded" : ""}`}>{trafficInfo}</p> <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> <span style={{display: (this.state.expanded ? "none" : "block") }}><u>Visa mer</u></span>
</div> </div>
} }
@ -69,7 +72,7 @@ class TrafficEntry extends Component {
{lineInterference && {lineInterference &&
<Link to={ <Link to={
{ pathname: "/travel" { pathname: "/travel"
, to: this.props.departure.finalStop , to: this.props.departure.direction
} }
}>Hitta annan resväg</Link> }>Hitta annan resväg</Link>
} }

View File

@ -8,6 +8,7 @@ class TrafficList extends Component {
render() { render() {
let entries = []; let entries = [];
if (this.props.departures) {
let i = 0; // React requires elems in array to have associated unique key let i = 0; // React requires elems in array to have associated unique key
this.props.departures.forEach(departure => { this.props.departures.forEach(departure => {
@ -22,6 +23,7 @@ class TrafficList extends Component {
// Add separator after the last element // Add separator after the last element
entries.push(<hr key={i++} />); entries.push(<hr key={i++} />);
}
return ( return (
<div id="trafficList"> <div id="trafficList">

View File

@ -5,6 +5,8 @@
transform: translate(-50%, -50%) scale(0); transform: translate(-50%, -50%) scale(0);
transform-origin: center; transform-origin: center;
background: white; background: white;
display: flex !important;
flex-direction: column !important;
width: 55vw; width: 55vw;
height: 39vh; height: 39vh;
padding: 3vh 5vw; padding: 3vh 5vw;
@ -21,16 +23,26 @@
.popup h3 { .popup h3 {
margin-bottom: 20px; margin-bottom: 20px;
display: block;
font-size: 1.17em;
font-weight: bold !important;
text-align: center;
color: black !important;
} }
.popup ul { .popup ul {
list-style: none; list-style: none;
width: 100%;
} }
.popup li button { .popup li button {
width: 100%; width: 100% !important;
padding: 8% 0; height: 50px;
font-size: 16px; padding: 8% 0 !important;
font-size: 16px !important;
display: flex;
align-items: center;
justify-content: center;
} }
.popupClose { .popupClose {

View File

@ -8,6 +8,7 @@
justify-content: space-evenly; justify-content: space-evenly;
padding: 0 5vw; padding: 0 5vw;
z-index: 4; z-index: 4;
max-width: 80vw;
} }
#stopTitle h1, #stopTitle h3 { #stopTitle h1, #stopTitle h3 {
@ -15,7 +16,7 @@
} }
#stopTitle h1 { #stopTitle h1 {
font-size: 9vw; font-size: 3.5vh;
} }
#stopTitle h3 { #stopTitle h3 {
@ -23,9 +24,9 @@
color: var(--colorDiscrete); color: var(--colorDiscrete);
} }
@media screen and (min-width: 350px) { @media screen and (min-width: 400px) {
#stopTitle h1 { #stopTitle h1 {
font-size: 35px; font-size: 4vh;
} }
#stopTitle h3 { #stopTitle h3 {
@ -37,9 +38,10 @@
#stopTitle div { #stopTitle div {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center;
} }
#stopTitle button { .changeTrackBtn {
width: auto; width: auto;
height: 100%; height: 100%;
box-shadow: none; box-shadow: none;
@ -51,6 +53,6 @@
border-radius: calc(var(--topMenuHeight) / 15); border-radius: calc(var(--topMenuHeight) / 15);
} }
#stopTitle button:active { .changeTrackBtn:active {
background: rgba(0, 0, 0, 0.3); background: rgba(0, 0, 0, 0.3);
} }

View File

@ -6,7 +6,7 @@
justify-content: space-evenly; justify-content: space-evenly;
} }
#topMenu button { #topMenu .menuButton {
width: var(--topMenuHeight); width: var(--topMenuHeight);
height: calc(var(--topMenuHeight) / 1.3); height: calc(var(--topMenuHeight) / 1.3);
display: flex; display: flex;
@ -17,7 +17,7 @@
box-shadow: var(--boxShadow); box-shadow: var(--boxShadow);
} }
#topMenu button:active { #topMenu .menuButton:active {
background: rgb(235, 235, 235); background: rgb(235, 235, 235);
} }

View File

@ -20,7 +20,7 @@
width: 90%; width: 90%;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-evenly; justify-content: flex-start;
margin-bottom: 2vh; margin-bottom: 2vh;
} }
@ -39,7 +39,7 @@
.trafficEntry div p { .trafficEntry div p {
text-align: left; text-align: left;
padding: 3vh 0 0 0; padding: 2vh 0 0 0;
} }
.trafficEntry div div { .trafficEntry div div {
@ -50,13 +50,17 @@
.trafficEntry div div div { .trafficEntry div div div {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: space-around;
align-items: flex-end; align-items: flex-end;
} }
.timeColumn div:first-child, .lineColumn div:first-child {
height: 5.5vh;
}
.timeColumn { .timeColumn {
flex-basis: 15%; flex-basis: 20%;
justify-content: space-between !important; justify-content: flex-start !important;
align-items: center; align-items: center;
} }
@ -78,8 +82,8 @@
} }
.lineColumn img { .lineColumn img {
width: 7.5vw; flex-basis: 25%;
margin-right: 10px; height: 9vw;
} }
.infoWrapper p { .infoWrapper p {
@ -89,7 +93,7 @@
flex-grow: 1; flex-grow: 1;
display: block; display: block;
white-space: nowrap; white-space: nowrap;
max-height: 3.5vw; max-height: 4.5vw;
} }
.infoWrapper span { .infoWrapper span {
@ -106,12 +110,20 @@
color: white; color: white;
font-size: 6vw; font-size: 6vw;
font-weight: 100; font-weight: 100;
margin-right: 10px; padding: 1vw 2.5vw;
padding: 1vw 4vw; border-radius: var(--borderRadius);
font-family: 'Roboto Light';
height: 7vw;
flex-basis: 35%;
} }
.destination { .destination {
flex-basis: 40%;
height: 9vw;
font-size: 4vw;
text-align: left; text-align: left;
display: flex;
align-items: flex-end;
} }
.trafficEntry a { .trafficEntry a {
@ -123,4 +135,5 @@
border-radius: var(--borderRadius); border-radius: var(--borderRadius);
box-shadow: var(--boxShadow); box-shadow: var(--boxShadow);
text-decoration: none; text-decoration: none;
border: 1px solid rgba(0, 0, 0, 0.2);
} }

View File

@ -2,9 +2,12 @@ import React, { Component } from 'react';
import Header from '../Header.js'; import Header from '../Header.js';
import MainArea from '../MainArea.js'; import MainArea from '../MainArea.js';
import globalData from '../../GlobalData.js';
class Tickets extends Component { class Tickets extends Component {
render() { render() {
globalData.currentPage = this;
return ( return (
<> <>
<Header title="Biljetter" /> <Header title="Biljetter" />

View File

@ -9,8 +9,12 @@ import clockIcon from '../../img/clock.svg';
import calendarIcon from '../../img/calendar.svg'; import calendarIcon from '../../img/calendar.svg';
import recurringIcon from '../../img/redo.svg'; import recurringIcon from '../../img/redo.svg';
import globalData from '../../GlobalData.js';
class TicketsBuy extends Component { class TicketsBuy extends Component {
render() { render() {
globalData.currentPage = this;
return ( return (
<> <>
<Header title="Köp biljett" /> <Header title="Köp biljett" />

View File

@ -6,38 +6,21 @@ import MainArea from "../MainArea.js";
import StopTitle from "../StopTitle.js"; import StopTitle from "../StopTitle.js";
import TrafficList from "../TrafficList.js"; import TrafficList from "../TrafficList.js";
import Stop from "../../classes/Stop.js"; import globalData from '../../GlobalData.js';
import Departure from "../../classes/Departure.js";
class TrafficInfo extends Component { class TrafficInfo extends Component {
render() { render() {
/* TEST DATA - TO BE REPLACED */ globalData.currentPage = this;
let testStop = new Stop(
"Lemmingsgatan",
["Läge A", "Läge B", "Läge C"],
[
new Departure(
"519",
"Heden",
"11:59",
"Trafikolycka vid Partille Centrum. Olyckan ska ha inträffat i höjd med brandstationen och det är oklart om någon är skadad. Polis på väg. Två av bilarna behöver bärgas från platsen. Inga uppgifter om personskador."
),
new Departure("58", "Västra Eriksberg", "12:07"),
]
);
testStop.departures[0].timeUpdate("16:50");
/* TEST DATA - TO BE REPLACED */
return ( return (
<> <>
<Header title="Trafikinfo" /> <Header title="Trafikinfo" />
<TopMenu> <TopMenu>
<StopTitle stop={testStop} /> <StopTitle stop={globalData.stop} />
</TopMenu> </TopMenu>
<MainArea> <MainArea>
<TrafficList departures={testStop.departures} /> <TrafficList departures={globalData.stop.departures} />
</MainArea> </MainArea>
</> </>
); );

View File

@ -7,8 +7,12 @@ import TripSelector from '../TripSelector.js';
import '../css/TripSelector.css'; import '../css/TripSelector.css';
import globalData from '../../GlobalData.js';
class Travel extends Component { class Travel extends Component {
render() { render() {
globalData.currentPage = this;
return ( return (
<> <>
<Header title="Reseplanering" /> <Header title="Reseplanering" />

8
src/img/close.svg Normal file
View File

@ -0,0 +1,8 @@
<?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>

After

Width:  |  Height:  |  Size: 691 B

19
src/img/userDark.svg Normal file
View File

@ -0,0 +1,19 @@
<?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>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -33,3 +33,76 @@ button {
opacity: 0; opacity: 0;
pointer-events: none; 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,9 +5,7 @@ import App from './App';
import reportWebVitals from './reportWebVitals'; import reportWebVitals from './reportWebVitals';
ReactDOM.render( ReactDOM.render(
<React.StrictMode> <App />,
<App />
</React.StrictMode>,
document.getElementById('root') document.getElementById('root')
); );