Add nearby places

This commit is contained in:
Patrick Gebhardt 2020-06-23 23:02:41 +02:00
parent 846410e6bf
commit 56b8c06b84
10 changed files with 167 additions and 2 deletions

View File

@ -28,6 +28,7 @@ import {
MatChipsModule,
MatDialogModule,
MatDividerModule,
MatListModule,
MatRadioModule,
MatSliderModule,
MatSlideToggleModule,
@ -48,6 +49,7 @@ import {ShareDialogComponent} from './dialogs/share-dialog/share-dialog.componen
import {TeamComponent} from './containers/team/team.component';
import {DeviceDetectorModule} from 'ngx-device-detector';
import {ToggleSliderComponent} from './components/toggle-slider/toggle-slider.component';
import {PlaceComponent} from './components/place/place.component';
@NgModule({
@ -67,7 +69,8 @@ import {ToggleSliderComponent} from './components/toggle-slider/toggle-slider.co
ShareButtonComponent,
ShareDialogComponent,
TeamComponent,
ToggleSliderComponent
ToggleSliderComponent,
PlaceComponent
],
imports: [
BrowserModule,
@ -97,7 +100,8 @@ import {ToggleSliderComponent} from './components/toggle-slider/toggle-slider.co
MatRadioModule,
MatSlideToggleModule,
MatSliderModule,
MatChipsModule
MatChipsModule,
MatListModule
],
providers: [],
bootstrap: [AppComponent],

View File

@ -0,0 +1,6 @@
<mat-card>
<img [src]="place.img_url" alt="Image of {{place.place_name}}">
<div class="footer">
<span class="name">{{place.place_name}}</span>
</div>
</mat-card>

View File

@ -0,0 +1,28 @@
mat-card {
padding: 0;
display: flex;
flex-direction: column;
}
img {
flex: 0 0 auto;
width: 20rem;
height: 11.25rem;
object-fit: cover;
}
.footer {
width: 20rem;
padding: 0.5rem;
box-sizing: border-box;
flex: 0 1 auto;
display: flex;
flex-direction: row;
.name {
flex: 0 1 auto;
overflow-x: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}

View File

@ -0,0 +1,25 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {PlaceComponent} from './place.component';
describe('PlaceComponent', () => {
let component: PlaceComponent;
let fixture: ComponentFixture<PlaceComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [PlaceComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PlaceComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,20 @@
import {Component, Input, OnInit} from '@angular/core';
import {Place} from '../../interfaces/places.interface';
@Component({
selector: 'app-place',
templateUrl: './place.component.html',
styleUrls: ['./place.component.scss']
})
export class PlaceComponent implements OnInit {
@Input()
place: Place;
constructor() {
}
ngOnInit() {
}
}

View File

@ -66,6 +66,12 @@
</mat-tab>
</mat-tab-group>
</div>
<div class="places-container">
<span class="group-title">Places</span>
<div class="places">
<app-place *ngFor="let place of places" [place]="place"></app-place>
</div>
</div>
</div>
<div *ngIf="!region" class="spinner">

View File

@ -42,6 +42,7 @@
> .more-btn {
color: #8f8f8f;
cursor: pointer;
}
}
@ -66,6 +67,27 @@
}
.places-container {
display: flex;
flex-direction: column;
> .group-title {
font-size: 1.5rem;
margin-bottom: 1rem;
}
> .places {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
app-place {
margin: 0.5rem;
}
}
}
.spinner {
flex: 1 1 auto;
display: flex;

View File

@ -4,6 +4,7 @@ import {ActivatedRoute, ParamMap} from '@angular/router';
import {DataService} from '../../services/data.service';
import {switchMap} from 'rxjs/operators';
import {SearchParameter} from '../../interfaces/search-request.interface';
import {Place} from '../../interfaces/places.interface';
@Component({
@ -36,6 +37,8 @@ export class RegionDetailsComponent implements AfterViewInit {
/** Extend the description text */
isDescExtended = false;
places: Place[] = [];
constructor(private route: ActivatedRoute, private ds: DataService) {
}
@ -45,6 +48,7 @@ export class RegionDetailsComponent implements AfterViewInit {
).subscribe((region: Region) => {
this.region = region;
this.uriRegionName = encodeURI(this.region.name.toLowerCase());
this.ds.getPlacesByRegion(this.region.region_id).then(places => this.places = places);
setTimeout(() => {
if (this.container) {
this.container.nativeElement.scrollIntoView();

View File

@ -0,0 +1,20 @@
export interface Place {
/** The place id */
place_id: number;
/** The id of the parent region */
region_id: number;
/** The name of the place in english */
place_name: string;
/** The longitude position */
lon: number;
/** The latitude position */
lat: number;
/** The user rating between 0 and 5 */
rating: number;
/** Nearby address */
vicinity: string;
/** Google photo reference */
photo_reference: string;
/** URL to the image */
img_url: string;
}

View File

@ -3,7 +3,11 @@ import {HttpClient, HttpParams} from '@angular/common/http';
import {Preset} from '../interfaces/preset.interface';
import {Result} from '../interfaces/result.interface';
import {Region} from '../interfaces/region.interface';
import {Place} from '../interfaces/places.interface';
/**
* The data service handles all API interactions.
*/
@Injectable({
providedIn: 'root'
})
@ -16,16 +20,27 @@ export class DataService {
constructor(private http: HttpClient) {
}
/**
* Get results for specific search query.
* @param query The search query
*/
public searchRegions(query: string): Promise<Result[]> {
const params = new HttpParams().set('q', query);
return this.http.get<Result[]>(this.API_URL + '/search', {params}).toPromise();
}
/**
* Get all search presets.
*/
public getAllPresets(): Promise<Preset[]> {
return this.http.get<Preset[]>(this.API_URL + '/search/presets').toPromise();
}
/**
* Gets all regions.
* @param max Limit the returned regions. Selected regions are random.
*/
public async getAllRegions(max?: number): Promise<Region[]> {
let params = new HttpParams();
if (max) {
@ -38,6 +53,10 @@ export class DataService {
return regions;
}
/**
* Gets one region by its id.
* @param id The region id
*/
public async getRegion(id: number): Promise<Region> {
if (this.regionCache.has(id)) {
return this.regionCache.get(id);
@ -48,8 +67,19 @@ export class DataService {
return region;
}
/**
* Returns POIs near the region.
* @param id The regions id
*/
public getPlacesByRegion(id: number): Promise<Place[]> {
return this.http.get<Place[]>(`${this.API_URL}/regions/${id}/nearby`).toPromise();
}
}
/**
* Defines meta data for all region parameters.
*/
export const REGION_PARAM_VIS: RegionParamVisLookup = {
temperature_mean: {
icon: 'wb_sunny',