diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index d3941421c3aa9bc5122e740c5a34c005febd1a58..a074565f328ca74524f09b7549d83168e36f07cc 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,36 +1,40 @@ -import { NgModule } from '@angular/core'; -import { PreloadAllModules, RouterModule, Routes } from '@angular/router'; - -const routes: Routes = [ - { - path: '', - redirectTo: 'login', - pathMatch: 'full' - }, - { - path: 'home', - loadChildren: () => import('./home/home.module').then(m => m.HomePageModule) - }, - { - path: 'list', - loadChildren: () => import('./list/list.module').then(m => m.ListPageModule) - }, - { - path: 'login', - loadChildren: () => import('./auth/login/login.module').then( m => m.LoginPageModule) - }, - { - path: 'register', - loadChildren: () => import('./auth/register/register.module').then( m => m.RegisterPageModule) +import { NgModule } from '@angular/core'; +import { PreloadAllModules, RouterModule, Routes } from '@angular/router'; + +const routes: Routes = [ + { + path: '', + redirectTo: 'login', + pathMatch: 'full' + }, + { + path: 'home', + loadChildren: () => import('./home/home.module').then(m => m.HomePageModule) + }, + { + path: 'list', + loadChildren: () => import('./list/list.module').then(m => m.ListPageModule) + }, + { + path: 'login', + loadChildren: () => import('./auth/login/login.module').then( m => m.LoginPageModule) + }, + { + path: 'register', + loadChildren: () => import('./auth/register/register.module').then( m => m.RegisterPageModule) + }, { + path: 'myreservation', + loadChildren: () => import('./myreservation/myreservation.module').then( m => m.MyreservationPageModule) } - - -]; -@NgModule({ - imports: [ - RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }) - ], - exports: [RouterModule] -}) -export class AppRoutingModule {} + + +]; + +@NgModule({ + imports: [ + RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }) + ], + exports: [RouterModule] +}) +export class AppRoutingModule {} diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 69934437a4b088d4bb7eabfeac3ac0922fa06e7a..90896ac20bbb4484d4f41a62e57e7794a4f70634 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -23,6 +23,11 @@ export class AppComponent { url: '/home', icon: 'home' }, + { + title: 'My Reservation', + url: '/myreservation', + icon: 'clipboard' + }, { title: 'Logout', url: '/login', diff --git a/src/app/home/home.page.html b/src/app/home/home.page.html index 59baf6927de11e15f88a2e24ccf7b344d6b3ccdf..7a3a36cb7b6416288c7d216c5859656a85f240ec 100644 --- a/src/app/home/home.page.html +++ b/src/app/home/home.page.html @@ -12,8 +12,8 @@ - +
diff --git a/src/app/home/home.page.ts b/src/app/home/home.page.ts index 1df890bff5829f2038e31a5d0e5c6bae181c9597..62d3c518f624544c2b0ddea72f0bd28cc50ccdac 100644 --- a/src/app/home/home.page.ts +++ b/src/app/home/home.page.ts @@ -91,10 +91,6 @@ export class HomePage { }); } - - - - loadmap(style) { // Obtain the default map types from the platform object var mapStyle = "raster"; @@ -263,7 +259,6 @@ export class HomePage { this.isBikeReserved=false; }, (error) => console.log(error)); }); - } } diff --git a/src/app/myreservation/myreservation-routing.module.ts b/src/app/myreservation/myreservation-routing.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..9b5fb9f3d98d059c35db1c5b723adaf1624cb68c --- /dev/null +++ b/src/app/myreservation/myreservation-routing.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +import { MyreservationPage } from './myreservation.page'; + +const routes: Routes = [ + { + path: '', + component: MyreservationPage + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class MyreservationPageRoutingModule {} diff --git a/src/app/myreservation/myreservation.module.ts b/src/app/myreservation/myreservation.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..aaf6b5af89541878e353d848a843c1777367ee8e --- /dev/null +++ b/src/app/myreservation/myreservation.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { IonicModule } from '@ionic/angular'; + +import { MyreservationPageRoutingModule } from './myreservation-routing.module'; + +import { MyreservationPage } from './myreservation.page'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + MyreservationPageRoutingModule + ], + declarations: [MyreservationPage] +}) +export class MyreservationPageModule {} diff --git a/src/app/myreservation/myreservation.page.html b/src/app/myreservation/myreservation.page.html new file mode 100644 index 0000000000000000000000000000000000000000..76a54fc513bcac7766a7718eaa9a00f1121d6f5d --- /dev/null +++ b/src/app/myreservation/myreservation.page.html @@ -0,0 +1,57 @@ + + + + + + + My Reservation + + + + + + + + No reservation found + + +
+
+ + +
+
+
+ + + Bike Name + {{bikeDetails.name}} + + + Battery Level + + + {{bikeDetails.batteryPercentage +" %"}} + + + + Bike Location + {{bikeDetails.address}} + + + Bike Distance + {{ bikeDetails.distance +" m"}} + + + + Hire + + + Cancel Reservation + + + +
+
+
+
\ No newline at end of file diff --git a/src/app/myreservation/myreservation.page.scss b/src/app/myreservation/myreservation.page.scss new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/app/myreservation/myreservation.page.spec.ts b/src/app/myreservation/myreservation.page.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..13da4644692cf67e8de0ecd4522e7eda36438b82 --- /dev/null +++ b/src/app/myreservation/myreservation.page.spec.ts @@ -0,0 +1,24 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { IonicModule } from '@ionic/angular'; + +import { MyreservationPage } from './myreservation.page'; + +describe('MyreservationPage', () => { + let component: MyreservationPage; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ MyreservationPage ], + imports: [IonicModule.forRoot()] + }).compileComponents(); + + fixture = TestBed.createComponent(MyreservationPage); + component = fixture.componentInstance; + fixture.detectChanges(); + })); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/myreservation/myreservation.page.ts b/src/app/myreservation/myreservation.page.ts new file mode 100644 index 0000000000000000000000000000000000000000..0991f09a1debb13519eda27090ef31e8d9bebbe4 --- /dev/null +++ b/src/app/myreservation/myreservation.page.ts @@ -0,0 +1,264 @@ +import { Component, OnInit, ViewChild, ElementRef } from '@angular/core'; + +import { Geolocation } from '@ionic-native/geolocation/ngx'; +import { RestService } from '../rest.service'; +import { Observable } from 'rxjs'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { Storage } from '@ionic/storage'; +import { ToastService } from '../services/toast.service'; +import { Router } from '@angular/router'; + +declare var H: any; + +@Component({ + selector: 'app-myreservation', + templateUrl: './myreservation.page.html', + styleUrls: ['./myreservation.page.scss'], +}) +export class MyreservationPage implements OnInit { + private platform: any; + private map: any; + // Get an instance of the routing service: + private mapRouter: any; + + reservedBike: any = {}; + bikeDetails: any = {}; + + noReservation = true; + + private currentLocation = { lat: 0, lng: 0 }; + + // Create the parameters for the routing request: + private routingParameters = { + // The routing mode: + mode: 'shortest;pedestrian', + // The start point of the route: + waypoint0: 'geo!50.1120423728813,8.68340740740811', + // The end point of the route: + waypoint1: 'geo!52.5309916298853,13.3846220493377', + // To retrieve the shape of the route we choose the route + // representation mode 'display' + representation: 'display' + }; + + @ViewChild("mapElement", { static: false }) + public mapElement: ElementRef; + + constructor(private geolocation: Geolocation, + public restService: RestService, + public httpClient: HttpClient, + private storage: Storage, + private toastService: ToastService, + private router: Router) { + this.platform = new H.service.Platform({ + 'apikey': 'tiVTgBnPbgV1spie5U2MSy-obhD9r2sGiOCbBzFY2_k' + }); + this.mapRouter = this.platform.getRoutingService(); + } + + ngOnInit() { + this.getReservedBike(); + } + + ngAfterViewInit() { + + } + + getReservedBike() { + this.storage.get('token').then((token) => { + const headers = new HttpHeaders().set("Authorization", "Bearer " + token); + //call reserved bike api + let reserveUrl = 'http://193.196.52.237:8081/active-rent'; + let bikeReservationStatusApi = this.httpClient.get(reserveUrl, { headers }); + bikeReservationStatusApi.subscribe((resp: any) => { + console.log('Reserved Bike', resp); + if (resp.data) { + this.reservedBike = resp.data; + //Call Bike Details api + let bikeDetailsUrl = 'http://193.196.52.237:8081/bikes/' + this.reservedBike.bikeId; + let bikeDetailsApi = this.httpClient.get(bikeDetailsUrl, { headers }); + bikeDetailsApi.subscribe((resp: any) => { + console.log('Bike Details', resp); + this.bikeDetails = resp.data; + this.noReservation = false; + + // display map + setTimeout(() => { + this.loadmap(); + }, 1000); + window.addEventListener('resize', () => this.map.getViewPort().resize()); + }, (reservedBikeError) => console.log(reservedBikeError)); + } + }, (bikeDetailsError) => console.log(bikeDetailsError)); + }); + } + + cancelReservation() { + this.storage.get('token').then((token) => { + let url = 'http://193.196.52.237:8081/reservation' + '?bikeId=' + this.bikeDetails.id; + const headers = new HttpHeaders().set("Authorization", "Bearer " + token); + let bikeApi = this.httpClient.delete(url, { headers }); + bikeApi.subscribe((resp) => { + console.log('Reservation Cancelled: ', resp); + this.toastService.showToast("Bike Reservation successfully cancelled."); + this.router.navigateByUrl('/home'); + }, (error) => console.log(error)); + }); + } + + loadmap() { + var defaultLayers = this.platform.createDefaultLayers(); + this.map = new H.Map( + this.mapElement.nativeElement, + defaultLayers.raster.normal.map, + { + zoom: 17, + pixelRatio: window.devicePixelRatio || 1 + } + ); + + var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(this.map)); + var ui = H.ui.UI.createDefault(this.map, defaultLayers); + ui.removeControl("mapsettings"); + // create custom one + var ms = new H.ui.MapSettingsControl({ + baseLayers: [{ + label: "3D", layer: defaultLayers.vector.normal.map + }, { + label: "Normal", layer: defaultLayers.raster.normal.map + }, { + label: "Satellite", layer: defaultLayers.raster.satellite.map + }, { + label: "Terrain", layer: defaultLayers.raster.terrain.map + } + ], + layers: [{ + label: "layer.traffic", layer: defaultLayers.vector.normal.traffic + }, + { + label: "layer.incidents", layer: defaultLayers.vector.normal.trafficincidents + } + ] + }); + ui.addControl("customized", ms); + var mapSettings = ui.getControl('customized'); + var zoom = ui.getControl('zoom'); + mapSettings.setAlignment('top-right'); + zoom.setAlignment('left-top'); + + //get user location + this.getLocation(this.map); + + var img = ['../../../assets/images/100_percent.png', '../../../assets/images/75_percent.png', '../../../assets/images/50_percent.png', '../../../assets/images/25_percent.png', '../../../assets/images/0_percent.png']; + if (this.bikeDetails.batteryPercentage < 100 && this.bikeDetails.batteryPercentage >= 75) { + this.addMarker(Number(this.bikeDetails.lat), Number(this.bikeDetails.lon), img[0]); + } + else if (this.bikeDetails.batteryPercentage < 75 && this.bikeDetails.batteryPercentage >= 50) { + this.addMarker(Number(this.bikeDetails.lat), Number(this.bikeDetails.lon), img[1]); + } + else if (this.bikeDetails.batteryPercentage < 50 && this.bikeDetails.batteryPercentage >= 25) { + this.addMarker(Number(this.bikeDetails.lat), Number(this.bikeDetails.lon), img[2]); + } else if (this.bikeDetails.batteryPercentage < 25 && this.bikeDetails.batteryPercentage >= 0) { + this.addMarker(Number(this.bikeDetails.lat), Number(this.bikeDetails.lon), img[3]); + } + } + + getLocation(map) { + this.geolocation.getCurrentPosition( + { + maximumAge: 1000, timeout: 5000, + enableHighAccuracy: true + } + ).then((resp) => { + let lat = resp.coords.latitude + let lng = resp.coords.longitude + this.currentLocation.lat = resp.coords.latitude; + this.currentLocation.lng = resp.coords.longitude; + this.moveMapToGiven(map, lat, lng); + // set routing params + this.routingParameters.waypoint1 = 'geo!' + this.bikeDetails.lat + ',' + this.bikeDetails.lon; + this.routingParameters.waypoint0 = 'geo!' + this.currentLocation.lat + ',' + this.currentLocation.lng; + + // show route on map + this.mapRouter.calculateRoute(this.routingParameters, this.onResult.bind(this), + (error) => { + alert(error.message); + }); + }, er => { + alert('Can not retrieve Location') + }).catch((error) => { + alert('Error getting location - ' + JSON.stringify(error)) + }); + } + + moveMapToGiven(map, lat, lng) { + var icon = new H.map.Icon('../../../assets/images/current_location.png'); + // Create a marker using the previously instantiated icon: + var marker = new H.map.Marker({ lat: lat, lng: lng }, { icon: icon }); + // Add the marker to the map: + map.addObject(marker); + map.setCenter({ lat: lat, lng: lng }); + } + + addMarker(lat, lng, img) { + var icon = new H.map.Icon(img); + // Create a marker using the previously instantiated icon: + var marker = new H.map.Marker({ lat: lat, lng: lng }, { icon: icon }); + // Add the marker to the map: + this.map.addObject(marker); + } + + + // Define a callback function to process the routing response: + onResult(result) { + var route, + routeShape, + startPoint, + endPoint, + linestring; + if (result.response.route) { + // Pick the first route from the response: + route = result.response.route[0]; + // Pick the route's shape: + routeShape = route.shape; + + // Create a linestring to use as a point source for the route line + linestring = new H.geo.LineString(); + + // Push all the points in the shape into the linestring: + routeShape.forEach(function (point) { + var parts = point.split(','); + linestring.pushLatLngAlt(parts[0], parts[1]); + }); + + // Retrieve the mapped positions of the requested waypoints: + startPoint = route.waypoint[0].mappedPosition; + endPoint = route.waypoint[1].mappedPosition; + + // Create a polyline to display the route: + var routeLine = new H.map.Polyline(linestring, { + /* style: { + lineWidth: 10, + fillColor: 'white', + strokeColor: 'rgba(255, 255, 255, 1)', + lineDash: [0, 2], + lineTailCap: 'arrow-tail', + lineHeadCap: 'arrow-head' + } */ + style: { + lineWidth: 5, + strokeColor: 'rgba(0, 128, 255, 0.7)', + lineDash: [0, 2] + } + }); + + // Add the route polyline and the two markers to the map: + this.map.addObjects([routeLine]); + + // Set the map's viewport to make the whole route visible: + this.map.getViewModel().setLookAtData({ bounds: routeLine.getBoundingBox() }); + //this.map.setZoom(this.map.getZoom() - 4.3, true); + } + }; + +} diff --git a/src/assets/images/bike2gologo.png b/src/assets/images/bike2gologo.png index 03ef687e2a677670be246f79533c0bd0b1e80b50..91d91c1610162aa0a6f5664783ef8ba061510da4 100644 Binary files a/src/assets/images/bike2gologo.png and b/src/assets/images/bike2gologo.png differ