Add total costs to results

This commit is contained in:
Patrick Gebhardt 2020-06-25 12:18:24 +02:00
parent 6be202a0d2
commit 44b09a22e8
5 changed files with 83 additions and 29 deletions

View File

@ -1,6 +1,6 @@
<div class="result-mat-card">
<img alt="Picture of {{result.name}}" class="result-img"
src="https://travopti.de/api/v1/regions/{{result.region_id}}/image">
src="https://travopti.de/api/v1/regions/{{result.region_id}}/image">
<div class="result-title">
<div class="result-header">
<span class="result-name">{{result.name}}<span *ngIf="debug"> ({{result.score}})</span></span>
@ -10,14 +10,27 @@
<app-share-button [region]="result"></app-share-button>
</div>
<div class="result-details">
<mat-divider *ngIf="result.total_accommodation_costs"></mat-divider>
<div *ngIf="result.total_accommodation_costs" class="total-accommodation">
<mat-icon>euro</mat-icon>
<span matTooltip="Total accommodation">{{result.total_accommodation_costs|number:'1.2-2'}}€</span>
<mat-divider *ngIf="totalCosts"></mat-divider>
<div *ngIf="totalCosts" class="total-price-container">
<div matTooltip="Total">
<mat-icon>euro</mat-icon>
<span>{{totalCosts|number:'1.0-0'}}€</span>
</div>
<div matTooltip="Accommodation">
<mat-icon>hotel</mat-icon>
<span>{{totalAccommodation|number:'1.0-0'}}€</span>
</div>
<div matTooltip="Lifestyle">
<mat-icon>people</mat-icon>
<span>{{totalLifeStyle|number:'1.0-0'}}€</span>
</div>
<div (click)="onTravelCostRequest($event)" matTooltip="Travel (request)">
<mat-icon>commute</mat-icon>
<span>- - -</span>
</div>
</div>
<mat-divider *ngIf="result.scores.length > 0"></mat-divider>
<div *ngIf="result.scores.length > 0" class="searched-params">
<table>
<tr *ngFor="let score of result.scores" [ngClass]="{'undefined': score.value == undefined}">
<td>
@ -45,6 +58,6 @@
</table>
</div>
<mat-divider></mat-divider>
<div class="result-desc">Estimated values for your chosen travel dates</div>
<div class="result-desc">Estimated values for {{duration}} {{duration > 1 ? 'days' : 'day'}}</div>
</div>
</div>
</div>

View File

@ -4,33 +4,33 @@
flex-direction: column;
cursor: pointer;
>.result-img {
> .result-img {
flex: 0 0 auto;
width: 100%;
height: 15rem;
object-fit: cover;
}
>.result-title {
> .result-title {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 0.25rem;
>.result-header {
> .result-header {
flex: 1 1 auto;
display: flex;
flex-direction: row;
margin: 0.25rem 0;
align-items: center;
>.result-name {
> .result-name {
font-weight: bold;
font-size: larger;
margin-right: 0.25rem;
}
>.result-country {
> .result-country {
text-transform: uppercase;
font-size: small;
margin-right: 0.25rem;
@ -41,26 +41,29 @@
}
}
>.result-details {
> .result-details {
display: flex;
flex-direction: column;
>.total-accommodation {
margin: 0.5rem 0;
> .total-price-container {
display: flex;
flex-direction: row;
align-items: center;
font-weight: bold;
margin: 0.5rem 0;
>mat-icon {
margin-right: 0.5rem;
margin-left: 3px;
> div {
display: flex;
flex-direction: row;
align-items: center;
margin-right: 1rem;
> mat-icon {
margin-right: 0.25rem;
}
}
}
>.searched-params {
> .searched-params {
margin: 0.5rem 0
}
@ -96,7 +99,7 @@
margin-right: 1rem;
}
>mat-icon {
> mat-icon {
margin-right: 0.5rem;
}
}
}

View File

@ -1,4 +1,4 @@
import {Component, Input, OnInit} from '@angular/core';
import {Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';
import {Result} from '../../interfaces/result.interface';
import {REGION_PARAM_VIS} from '../../services/data.service';
@ -7,14 +7,23 @@ import {REGION_PARAM_VIS} from '../../services/data.service';
templateUrl: './result.component.html',
styleUrls: ['./result.component.scss']
})
export class ResultComponent implements OnInit {
export class ResultComponent implements OnInit, OnChanges {
@Input()
result: Result;
/** Date difference in days */
@Input()
duration: number;
@Input()
debug = false;
totalCosts: number;
totalAccommodation: number;
totalLifeStyle: number;
totalTravel: number;
/** Contains the visual definitions */
readonly PROPERTY_VIS_DEF = REGION_PARAM_VIS;
@ -24,4 +33,25 @@ export class ResultComponent implements OnInit {
ngOnInit() {
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.result || changes.duration) {
this.calculateTotalPrices();
}
}
onTravelCostRequest(event: MouseEvent) {
event.stopPropagation();
window.open(`https://www.google.com/flights?q=flight+to+${encodeURI(this.result.name)}`, '_blank');
}
private calculateTotalPrices() {
// Guard: undefined values
if (!this.result || !this.duration) {
return;
}
this.totalCosts = Math.round(this.result.average_per_day_costs * this.duration);
this.totalAccommodation = Math.round(this.result.accommodation_costs * this.duration);
this.totalLifeStyle = this.totalCosts - this.totalAccommodation;
}
}

View File

@ -21,7 +21,7 @@
</div>
<div class="result-container">
<app-result (click)="onResultClick(result)" *ngFor="let result of results" [debug]="debug"
[result]="result"></app-result>
[duration]="duration" [result]="result"></app-result>
</div>
</div>

View File

@ -2,6 +2,8 @@ import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {Result} from '../../interfaces/result.interface';
import {SearchService} from '../../services/search.service';
import {base64ToObj} from '../../utils/base64conversion';
import {Query} from '../../interfaces/search-request.interface';
interface SortOption {
name: string;
@ -28,6 +30,8 @@ export class SearchComponent implements OnInit {
sortDes = true;
/** Available sort options */
sortOptions: SortOption[] = [];
/** The difference between from and to in days */
duration: number;
debug = false;
@ -54,7 +58,7 @@ export class SearchComponent implements OnInit {
this.sortOptions = [
{name: 'Relevance', property: 'score', descending: true},
{name: 'Region name', property: 'name'},
{name: 'Accommodation price', property: 'accommodation_costs'}
{name: 'Price', property: 'average_per_day_costs'}
];
if (this.results.length > 0) {
@ -65,6 +69,10 @@ export class SearchComponent implements OnInit {
});
}
// Calculate duration
const {from, to} = base64ToObj(this.queryString) as Query;
const difference: number = (new Date(to)).getTime() - (new Date(from)).getTime();
this.duration = Math.round(difference / 1000 / 60 / 60 / 24);
});
}