From 299e80e5a2e315c588a83ca9cb0b54554259fd34 Mon Sep 17 00:00:00 2001 From: Patrick Gebhardt Date: Thu, 18 Jun 2020 02:10:06 +0200 Subject: [PATCH] Add basic details page --- frontend/src/app/app-routing.module.ts | 2 + frontend/src/app/app.component.ts | 1 - frontend/src/app/app.module.ts | 4 +- .../components/region/region.component.scss | 2 + .../components/result/result.component.scss | 2 + .../app/containers/home/home.component.html | 2 +- .../app/containers/home/home.component.scss | 2 +- .../src/app/containers/home/home.component.ts | 6 ++- .../region-details.component.html | 14 ++++++ .../region-details.component.scss | 49 +++++++++++++++++++ .../region-details.component.spec.ts | 25 ++++++++++ .../region-details.component.ts | 25 ++++++++++ .../containers/search/search.component.html | 6 ++- .../containers/search/search.component.scss | 9 +++- .../app/containers/search/search.component.ts | 14 +++++- frontend/src/app/mock/mock-data.ts | 2 +- 16 files changed, 153 insertions(+), 12 deletions(-) create mode 100644 frontend/src/app/containers/region-details/region-details.component.html create mode 100644 frontend/src/app/containers/region-details/region-details.component.scss create mode 100644 frontend/src/app/containers/region-details/region-details.component.spec.ts create mode 100644 frontend/src/app/containers/region-details/region-details.component.ts diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts index 9113578..90657fb 100644 --- a/frontend/src/app/app-routing.module.ts +++ b/frontend/src/app/app-routing.module.ts @@ -3,11 +3,13 @@ import {RouterModule, Routes} from '@angular/router'; import {HomeComponent} from './containers/home/home.component'; import {NotfoundComponent} from './containers/notfound/notfound.component'; import {SearchComponent} from './containers/search/search.component'; +import {RegionDetailsComponent} from './containers/region-details/region-details.component'; const routes: Routes = [ {path: 'home', component: HomeComponent}, {path: 'search', component: SearchComponent}, + {path: 'region/:id', component: RegionDetailsComponent}, {path: '', redirectTo: 'home', pathMatch: 'full'}, {path: '**', component: NotfoundComponent} ]; diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts index 3ceca05..6906737 100644 --- a/frontend/src/app/app.component.ts +++ b/frontend/src/app/app.component.ts @@ -11,6 +11,5 @@ export class AppComponent implements OnInit { } ngOnInit(): void { - } } diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index 813e250..1469f21 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -25,6 +25,7 @@ import {MatButtonToggleModule, MatCheckboxModule, MatDividerModule} from '@angul import {FormsModule} from '@angular/forms'; import {RegionComponent} from './components/region/region.component'; import {ResultComponent} from './components/result/result.component'; +import {RegionDetailsComponent} from './containers/region-details/region-details.component'; @NgModule({ @@ -35,7 +36,8 @@ import {ResultComponent} from './components/result/result.component'; SearchComponent, SearchInputComponent, RegionComponent, - ResultComponent + ResultComponent, + RegionDetailsComponent ], imports: [ BrowserModule, diff --git a/frontend/src/app/components/region/region.component.scss b/frontend/src/app/components/region/region.component.scss index 31c1a57..ef5c040 100644 --- a/frontend/src/app/components/region/region.component.scss +++ b/frontend/src/app/components/region/region.component.scss @@ -6,6 +6,8 @@ > .region-img { flex: 0 0 auto; width: 100%; + height: 15rem; + object-fit: cover; } > .region-footer { diff --git a/frontend/src/app/components/result/result.component.scss b/frontend/src/app/components/result/result.component.scss index d1ccd17..e4d5c72 100644 --- a/frontend/src/app/components/result/result.component.scss +++ b/frontend/src/app/components/result/result.component.scss @@ -6,6 +6,8 @@ > .result-img { flex: 0 0 auto; width: 100%; + height: 15rem; + object-fit: cover; } > .result-footer { diff --git a/frontend/src/app/containers/home/home.component.html b/frontend/src/app/containers/home/home.component.html index e819426..8a89191 100644 --- a/frontend/src/app/containers/home/home.component.html +++ b/frontend/src/app/containers/home/home.component.html @@ -1,6 +1,6 @@

Explore the world

- +
diff --git a/frontend/src/app/containers/home/home.component.scss b/frontend/src/app/containers/home/home.component.scss index 9f4764c..3a76279 100644 --- a/frontend/src/app/containers/home/home.component.scss +++ b/frontend/src/app/containers/home/home.component.scss @@ -14,6 +14,6 @@ app-search-input { flex-direction: column; > app-region { - margin-bottom: 1rem; + margin-bottom: 2rem; } } diff --git a/frontend/src/app/containers/home/home.component.ts b/frontend/src/app/containers/home/home.component.ts index 786f7af..934d0e3 100644 --- a/frontend/src/app/containers/home/home.component.ts +++ b/frontend/src/app/containers/home/home.component.ts @@ -1,6 +1,7 @@ import {Component, OnInit} from '@angular/core'; import {Region} from '../../interfaces/region.interface'; import {DataService} from '../../services/data.service'; +import {Router} from '@angular/router'; @Component({ selector: 'app-home', @@ -11,11 +12,14 @@ export class HomeComponent implements OnInit { regions: Region[]; - constructor(private ds: DataService) { + constructor(private ds: DataService, private router: Router) { } async ngOnInit() { this.regions = await this.ds.getAllRegions(); } + onRegionClick(region: Region) { + this.router.navigate(['/region', region.region_id]).catch(console.log); + } } diff --git a/frontend/src/app/containers/region-details/region-details.component.html b/frontend/src/app/containers/region-details/region-details.component.html new file mode 100644 index 0000000..7c0a8bb --- /dev/null +++ b/frontend/src/app/containers/region-details/region-details.component.html @@ -0,0 +1,14 @@ +
+ +
+
+ {{region.country}} + {{region.name}} +
+
+

{{region.description}}

+
+ +
+ +
diff --git a/frontend/src/app/containers/region-details/region-details.component.scss b/frontend/src/app/containers/region-details/region-details.component.scss new file mode 100644 index 0000000..d209399 --- /dev/null +++ b/frontend/src/app/containers/region-details/region-details.component.scss @@ -0,0 +1,49 @@ +:host { + display: flex; + flex-direction: column; + height: 100%; +} + +.region-img { + width: 100%; + object-fit: cover; + height: 10rem; + margin-bottom: 1.5rem; +} + +.region-details-header { + display: flex; + flex-direction: row; + + > .region-title { + flex: 0 1 auto; + display: flex; + flex-direction: column; + margin: 0.25rem 0; + + > .region-name { + font-weight: bold; + font-size: 2rem; + } + + > .region-country { + text-transform: uppercase; + font-size: 1.2rem; + } + + } +} + +.region-decsription { + text-align: justify; + margin: 0.5rem 0; +} + + +.spinner { + flex: 1 1 auto; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; +} diff --git a/frontend/src/app/containers/region-details/region-details.component.spec.ts b/frontend/src/app/containers/region-details/region-details.component.spec.ts new file mode 100644 index 0000000..d424aac --- /dev/null +++ b/frontend/src/app/containers/region-details/region-details.component.spec.ts @@ -0,0 +1,25 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {RegionDetailsComponent} from './region-details.component'; + +describe('RegionDetailsComponent', () => { + let component: RegionDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [RegionDetailsComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(RegionDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/containers/region-details/region-details.component.ts b/frontend/src/app/containers/region-details/region-details.component.ts new file mode 100644 index 0000000..fa52f51 --- /dev/null +++ b/frontend/src/app/containers/region-details/region-details.component.ts @@ -0,0 +1,25 @@ +import {Component, OnInit} from '@angular/core'; +import {Region} from '../../interfaces/region.interface'; +import {ActivatedRoute, ParamMap} from '@angular/router'; +import {DataService} from '../../services/data.service'; +import {switchMap} from 'rxjs/operators'; + +@Component({ + selector: 'app-region-details', + templateUrl: './region-details.component.html', + styleUrls: ['./region-details.component.scss'] +}) +export class RegionDetailsComponent implements OnInit { + + region: Region; + + constructor(private route: ActivatedRoute, private ds: DataService) { + } + + ngOnInit() { + this.route.paramMap.pipe( + switchMap((params: ParamMap) => this.ds.getRegion(parseInt(params.get('id'), 10))) + ).subscribe((region: Region) => this.region = region); + } + +} diff --git a/frontend/src/app/containers/search/search.component.html b/frontend/src/app/containers/search/search.component.html index 5889769..90af0e8 100644 --- a/frontend/src/app/containers/search/search.component.html +++ b/frontend/src/app/containers/search/search.component.html @@ -2,9 +2,11 @@ -
+

Results ({{results.length}}):

- +
+ +
diff --git a/frontend/src/app/containers/search/search.component.scss b/frontend/src/app/containers/search/search.component.scss index 69ebfab..4791b8f 100644 --- a/frontend/src/app/containers/search/search.component.scss +++ b/frontend/src/app/containers/search/search.component.scss @@ -8,8 +8,13 @@ } } -.resultCard { - margin-bottom: 0.5rem; +.result-container { + display: flex; + flex-direction: column; + + > app-result { + margin-bottom: 2rem; + } } .spinner { diff --git a/frontend/src/app/containers/search/search.component.ts b/frontend/src/app/containers/search/search.component.ts index 60f5996..fbedc78 100644 --- a/frontend/src/app/containers/search/search.component.ts +++ b/frontend/src/app/containers/search/search.component.ts @@ -1,5 +1,5 @@ import {Component, ElementRef, OnInit, ViewChild} from '@angular/core'; -import {ActivatedRoute} from '@angular/router'; +import {ActivatedRoute, Router} from '@angular/router'; import {Result} from '../../interfaces/result.interface'; import {DataService} from '../../services/data.service'; @@ -16,15 +16,25 @@ export class SearchComponent implements OnInit { @ViewChild('result', {static: false}) resultDiv: ElementRef; - constructor(private route: ActivatedRoute, private ds: DataService) { + constructor(private route: ActivatedRoute, private ds: DataService, private router: Router) { } async ngOnInit() { this.route.queryParams.subscribe(async params => { this.queryString = params.q; this.results = undefined; + + if (!this.queryString || this.queryString.length === 0) { + this.results = []; + return; + } + this.results = await this.ds.searchRegions(this.queryString); this.resultDiv.nativeElement.scrollIntoView({behavior: 'smooth', block: 'start'}); }); } + + onResultClick(result: Result) { + this.router.navigate(['/region', result.region_id]).catch(console.log); + } } diff --git a/frontend/src/app/mock/mock-data.ts b/frontend/src/app/mock/mock-data.ts index d19da52..b3d0e61 100644 --- a/frontend/src/app/mock/mock-data.ts +++ b/frontend/src/app/mock/mock-data.ts @@ -2691,7 +2691,7 @@ export const MOCK_REGIONS: Region[] = [ region_id: 6, name: 'Sao Paolo', country: 'Brazil', - description: null, + description: 'São Paulo (/ˌsaʊ ˈpaʊloʊ/; Portuguese pronunciation: [sɐ̃w̃ ˈpawlu]) is a municipality in the Southeast Region of Brazil. The metropolis is an alpha global city (as listed by the GaWC) and the most populous city in Brazil, the Americas, the Western Hemisphere and the Southern Hemisphere, besides being the largest Portuguese-speaking city in the world. The municipality is also the world\'s 4th largest city proper by population. The city is the capital of the surrounding state of São Paulo, the most populous and wealthiest state in Brazil. It exerts strong international influences in commerce, finance, arts and entertainment. The name of the city honors the Apostle, Saint Paul of Tarsus. The city\'s metropolitan area, the Greater São Paulo, ranks as the most populous in Brazil and the 12th most populous on Earth. The process of conurbation between the metropolitan areas located around the Greater São Paulo (Campinas, Santos, Sorocaba and São José dos Campos) created the São Paulo Macrometropolis, a megalopolis with more than 30 million inhabitants, one of the most populous urban agglomerations in the world.', temperature_mean_max: [ 27.1, 28.1,