File

src/app/home/home.component.ts

Implements

OnInit

Metadata

Index

Properties
Methods
Accessors

Constructor

constructor(db: DbConnectionService, router: Router, route: ActivatedRoute)
Parameters :
Name Type Optional
db DbConnectionService No
router Router No
route ActivatedRoute No

Methods

createTrip
createTrip()
Returns : any
getDate
getDate()
Returns : any
getPlaces
getPlaces()
Returns : void
isNewTrip
isNewTrip()
Returns : any
ngOnInit
ngOnInit()
Returns : void
setCar
setCar(persons)
Parameters :
Name Optional
persons No
Returns : "rav4" | "Prado" | "Van"
toMysqlDate
toMysqlDate(date: Date)
Parameters :
Name Type Optional
date Date No
Returns : any

Properties

defaultArrivalPlace
Type : string
Default value : "Kigali"
defaultDeparturePlace
Type : string
Default value : "Kigali"
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), })
mobile
Type : boolean
Default value : false
personDefault
Type : number
Default value : 2
personRange
Type : number[]
Default value : [1, 7]
places
Type : string[]
Default value : []
tripId
Type : number

Accessors

arrivalDate
getarrivalDate()
departureDate
getdepartureDate()
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;
      }
   }
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""