src/app/home/home.component.ts
selector | app-home |
styleUrls | ./home.component.scss |
templateUrl | ./home.component.html |
Properties |
Methods |
Accessors |
constructor(db: DbConnectionService, router: Router, route: ActivatedRoute)
|
||||||||||||
Defined in src/app/home/home.component.ts:29
|
||||||||||||
Parameters :
|
createTrip |
createTrip()
|
Defined in src/app/home/home.component.ts:76
|
Returns :
any
|
getDate |
getDate()
|
Defined in src/app/home/home.component.ts:72
|
Returns :
any
|
getPlaces |
getPlaces()
|
Defined in src/app/home/home.component.ts:117
|
Returns :
void
|
isNewTrip |
isNewTrip()
|
Defined in src/app/home/home.component.ts:67
|
Returns :
any
|
ngOnInit |
ngOnInit()
|
Defined in src/app/home/home.component.ts:36
|
Returns :
void
|
setCar | ||||
setCar(persons)
|
||||
Defined in src/app/home/home.component.ts:125
|
||||
Parameters :
Returns :
"rav4" | "Prado" | "Van"
|
toMysqlDate | ||||||
toMysqlDate(date: Date)
|
||||||
Defined in src/app/home/home.component.ts:112
|
||||||
Parameters :
Returns :
any
|
defaultArrivalPlace |
Type : string
|
Default value : "Kigali"
|
Defined in src/app/home/home.component.ts:16
|
defaultDeparturePlace |
Type : string
|
Default value : "Kigali"
|
Defined in src/app/home/home.component.ts:17
|
form |
Default value : new FormGroup({
arrivalDate: new FormControl<Date | null>(null),
departureDate: new FormControl<Date | null>(null),
arrivalPlace: new FormControl<string | null>(null),
departurePlace: new FormControl<string | null>(null),
personAmount: new FormControl<number | null>(null),
})
|
Defined in src/app/home/home.component.ts:19
|
mobile |
Type : boolean
|
Default value : false
|
Defined in src/app/home/home.component.ts:29
|
personDefault |
Type : number
|
Default value : 2
|
Defined in src/app/home/home.component.ts:14
|
personRange |
Type : number[]
|
Default value : [1, 7]
|
Defined in src/app/home/home.component.ts:15
|
places |
Type : string[]
|
Default value : []
|
Defined in src/app/home/home.component.ts:27
|
tripId |
Type : number
|
Defined in src/app/home/home.component.ts:28
|
arrivalDate |
getarrivalDate()
|
Defined in src/app/home/home.component.ts:59
|
departureDate |
getdepartureDate()
|
Defined in src/app/home/home.component.ts:63
|
import { Component, Input, OnInit, ViewChild } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { MatDateRangePicker } from '@angular/material/datepicker';
import { ActivatedRoute, Router } from '@angular/router';
import { DbConnectionService } from '../db-connection.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
personDefault: number = 2
personRange: number[] = [1, 7]
defaultArrivalPlace = "Kigali"
defaultDeparturePlace = "Kigali"
form = new FormGroup({
arrivalDate: new FormControl<Date | null>(null),
departureDate: new FormControl<Date | null>(null),
arrivalPlace: new FormControl<string | null>(null),
departurePlace: new FormControl<string | null>(null),
personAmount: new FormControl<number | null>(null),
});
places: string[] = [];
tripId: number;
mobile: boolean = false;
constructor(
private db: DbConnectionService,
private router: Router,
private route: ActivatedRoute) { }
ngOnInit(): void {
if (window.screen.width < 1000) { // 768px portrait
this.mobile = true;
}
this.route.params.subscribe(r => {
this.tripId = Number(r["tripId"])
if (!this.isNewTrip()) {
this.db.executeQuery(`SELECT * FROM Trip WHERE tripID=${this.tripId}`).then(r => {
let trip = r["data"][0]
this.form.setValue({
arrivalDate: new Date(trip["startDate"]),
departureDate: new Date(trip["endDate"]),
arrivalPlace: trip["arrivalPlace"],
departurePlace: trip["departurePlace"],
personAmount: trip["persons"]
})
})
}
});
this.getPlaces()
}
public get arrivalDate(): Date {
return this.form.get('arrivalDate').value;
}
public get departureDate(): Date {
return this.form.get('departureDate').value;
}
isNewTrip() {
return isNaN(this.tripId);
}
// get todays date
getDate() {
return new Date();
}
createTrip() {
let data = this.form.getRawValue();
// error handling
// missing data
if (Object.values(data).some(x => !x))
return alert("Please enter " + Object.entries(data).filter(o => !o[1]).map(o => o[0]).join(", "))
// invalid person amount
if (data.personAmount < this.personRange[0] || data.personAmount > this.personRange[1])
return alert("Invalid Person Amount\nMust be between " + this.personRange[0] + " and " + this.personRange[1])
if (this.isNewTrip()) {
// create new customer
this.db.executeQuery("INSERT INTO Customer () VALUES ()").then(r => {
let customerID = r["data"].insertId
// create new trip
this.db.executeQuery(
`INSERT INTO Trip (customerID, startDate, endDate, persons, arrivalPlace, departurePlace, transport) VALUES (${customerID},'${this.toMysqlDate(data.arrivalDate)}','${this.toMysqlDate(data.departureDate)}',${data.personAmount},'${data.arrivalPlace}','${data.departurePlace}', '${this.setCar(data.personAmount)}')`
).then(r2 => {
// redirect with tripid
this.router.navigateByUrl(`trip/${r2["data"].insertId}/activities`)
})
});
} else {
this.db.executeQuery(
`UPDATE Trip SET startDate = '${this.toMysqlDate(data.arrivalDate)}', endDate = '${this.toMysqlDate(data.departureDate)}', persons = ${data.personAmount}, arrivalPlace = '${data.arrivalPlace}', departurePlace = '${data.departurePlace}', transport = '${this.setCar(data.personAmount)}' WHERE TripID=${this.tripId}`
).then(r => {
// redirect with tripid
this.router.navigateByUrl(`trip/${this.tripId}/itinerary`)
})
}
}
// js date to mysql date (fixes 1 day off bug)
toMysqlDate(date: Date) {
date.setHours(12)
return date.toISOString().split('T')[0];
}
getPlaces() {
// get all places
this.db.executeQuery("SELECT name FROM Place").then(r => {
// extract names and store
this.places = r["data"].map((x: Object) => x["name"])
})
}
setCar(persons) {
if (persons < 4) {
return "rav4"
}
else if (persons == 4) {
return "Prado"
}
else {
return "Van"
}
}
}
<div *ngIf= "!mobile" class= "logo"></div>
<div *ngIf= "mobile" class= "mobile-logo"></div>
<div class="home d-flex justify-content-center">
<div class="header">
<span [ngClass]="!mobile? 'title' : 'mobile-title'">Create your trip</span>
<br />
<span *ngIf="!mobile" class="subtitle">{{!mobile? 'Adventurous travel in Rwanda and Uganda' : 'In Rwanda and Uganda'}}</span>
</div>
<!-- For desktop -->
<div class="card custom-box-shadow">
<div class="card-body">
<form [formGroup]="form">
<div [ngClass]="!mobile? 'form-row' : ''">
<div class="col form-group">
<label for="arrivalPlace">Period</label>
<!-- Material is used but hidden -->
<mat-form-field class="date-input" appearance="fill" id="datepicker">
<mat-date-range-input [rangePicker]="picker" [min]="getDate()">
<input matStartDate formControlName="arrivalDate" placeholder="Arrival Date">
<input matEndDate formControlName="departureDate" placeholder="Departure Date">
</mat-date-range-input>
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-date-range-picker #picker></mat-date-range-picker>
<mat-error *ngIf="form.controls.arrivalDate.hasError('matStartDateInvalid')">Invalid Arrival date</mat-error>
<mat-error *ngIf="form.controls.departureDate.hasError('matEndDateInvalid')">Invalid Departure date</mat-error>
</mat-form-field>
<!-- End of hidden material-->
<div class="input-group date-range" (click)="picker.open()">
<input type="text" class="form-control" placeholder="Arrival - Departure Date" aria-label="Arrival - Departure Date"
aria-describedby="range-addon" readonly [ngModel]="arrivalDate | dateRangeFormat: departureDate" [ngModelOptions]="{standalone: true}">
<div class="input-group-append calendar-append">
<span class="input-group-text" id="range-addon">
<i class="bi bi-calendar2-range"></i>
</span>
</div>
</div>
</div>
<div class="col form-group">
<label for="arrivalPlace">Arrival place</label>
<select class="form-control" id="arrivalPlace" formControlName="arrivalPlace" [(ngModel)]="defaultArrivalPlace">
<option *ngFor="let place of places" [value]="place"> {{place}} </option>
</select>
</div>
<div class="col form-group">
<label for="departurePlace">Departure place</label>
<select class="form-control" id="departurePlace" formControlName="departurePlace" [(ngModel)]="defaultDeparturePlace">
<option *ngFor="let place of places" [value]="place"> {{place}} </option>
</select>
</div>
<div class="col d-flex ">
<div class="form-group">
<label for="inputPersonAmount">Travelers</label>
<div class="input-group">
<input type="number" class="form-control travelers-input" [(ngModel)]="personDefault" [min]="personRange[0]" [max]="personRange[1]"
id="inputPersonAmount" formControlName="personAmount">
</div>
</div>
<button class="btn lets-go-btn" type="button" (click)="createTrip()">Let's Go!</button>
</div>
</div>
</form>
</div>
</div>
</div>
<!-- Footer -->
<footer *ngIf="!mobile" class="text-center text-lg-start bg-light text-muted">
<div class="text-center p-2" style="background-color: rgba(0, 0, 0, 0.05);">
© 2021 Responsible Travel Africa .
<a class="text-reset fw-bold" href="https://responsibletravelafrica.com/">responsibletravelafrica.com</a>
. <a class="text-reset fw-bold" href="https://www.afriguideme.com/terms-and-conditions">Terms and conditions </a>
. <a class="text-reset fw-bold" href="https://www.afriguideme.com/privacy-policy/">Privacy</a>
</div>
<!-- Copyright -->
</footer>
<!-- Footer -->
./home.component.scss
@import 'variables';
@import 'custom-date-picker';
.logo {
position: absolute;
top: 0;
left: 0;
width: 224px;
height: 87px;
margin: 25px;
background-image: url("../../assets/logo.png");
background-repeat: no-repeat;
background-size: cover;
background-position: left top;
}
.header {
background-color: transparent;
color: white;
text-align: center;
margin-top: 125px;
.title {
font-family: 'Pacifico';
font-size: 48pt;
}
.mobile-title {
font-family: 'Pacifico';
font-size: 30pt;
}
.subtitle {
font-size: 28pt;
}
}
.home {
height: 94.9%;
background-image: url("../../assets/image_22.png");
background-repeat: no-repeat;
background-size: cover;
background-position: center bottom;
.card {
position: absolute;
bottom: 90px;
background-color: rgba(255, 255, 255, 0.8);
}
label {
color: darkslategray;
font-weight: 600;
}
.calendar-append {
cursor: pointer;
}
.date-range {
.form-control[readonly] {
background-color: white;
color: #495057;
}
}
.travelers-input {
border-radius: 0.25rem;
min-width: 100px;
}
.lets-go-btn {
height: 38px;
margin-top: 32px;
margin-left: 8px;
}
}
@media only screen and (max-width: 500px) {
.home {
height: 100%;
.card {
bottom: 20px;
}
}
}