File

src/app/activity/activity.component.ts

Implements

OnInit

Metadata

Index

Properties
Methods
Inputs

Constructor

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

Inputs

mainActivity
Type : Object | null
Default value : null

Methods

addDays
addDays(date, days: number)
Parameters :
Name Type Optional
date No
days number No
Returns : any
cancelMainActivity
cancelMainActivity()
Returns : void
Async confirmActivity
confirmActivity()
Returns : any
dateDiffInDays
dateDiffInDays(a: Date, b: Date)
Parameters :
Name Type Optional
a Date No
b Date No
Returns : any
Async dayActivityChange
dayActivityChange(dateIndex, dayActivity, checkboxValue)
Parameters :
Name Optional
dateIndex No
dayActivity No
checkboxValue No
Returns : any
Async fetchDayActivities
fetchDayActivities()
Returns : any
fetchDayActivityTypes
fetchDayActivityTypes()
Returns : void
fetchDayByDayView
fetchDayByDayView()
Returns : void
fetchMainActivityDetails
fetchMainActivityDetails()
Returns : void
fetchMainActivityTypeDetails
fetchMainActivityTypeDetails()
Returns : void
fetchThisActivityView
fetchThisActivityView()
Returns : void
fetchTransport
fetchTransport()
Returns : void
fetchTripInfo
fetchTripInfo()
Returns : void
getDayNr
getDayNr(date: Date)
Parameters :
Name Type Optional
date Date No
Returns : any
isDayActivitySelected
isDayActivitySelected(dateIndex, dayActivity)
Parameters :
Name Optional
dateIndex No
dayActivity No
Returns : any
myRange
myRange(min: number, max: number)
Parameters :
Name Type Optional
min number No
max number No
Returns : any
ngOnInit
ngOnInit()
Returns : void
toMysqlDate
toMysqlDate(date)
Parameters :
Name Optional
date No
Returns : any

Properties

activityDates
Type : Date[]
Default value : []
activityId
Type : number
dayActivityTypes
Type : Object[]
Default value : []
editMode
Type : boolean
Default value : false
form
Default value : new FormGroup({ startDate: new FormControl<Date | null>(null), transport: new FormControl<string | null>(null), personAmount: new FormControl<number | null>(null), numberOfNights: new FormControl<number | null>(null), comment: new FormControl<string | null>(null), })
loading
Type : boolean
Default value : true
mainActivityType
Type : Object
mobile
Type : boolean
Default value : false
noLastDayActivity
Type : Object
Default value : { name: 'empty', description: "You can leave the last day of the activity empty. This way, you can fill this day with with a" }
selectedDayActivities
Type : string[][]
Default value : []
transportOptions
Type : Object[]
Default value : []
trip
Type : Object
Default value : null
tripId
Type : number
tripSummary
Type : Object[]
Default value : []
import { Component, Input, OnInit } from '@angular/core';
import { FormArray, FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { DbConnectionService } from '../db-connection.service';

@Component({
   selector: 'app-activity',
   templateUrl: './activity.component.html',
   styleUrls: ['./activity.component.scss']
})
export class ActivityComponent implements OnInit {

   noLastDayActivity: Object = {
      name: 'empty',
      description: "You can leave the last day of the activity empty. This way, you can fill this day with with a"
   }

   tripId: number;
   activityId: number;
   @Input() mainActivity: Object|null = null;
   mainActivityType: Object;
   dayActivityTypes: Object[] = [];
   transportOptions: Object[] = [];
   trip: Object = null;
   tripSummary: Object[] = [];
   mobile: boolean = false;

   loading: boolean = true;
   editMode: boolean = false; // changes action buttons

   form = new FormGroup({
      startDate: new FormControl<Date | null>(null),
      transport: new FormControl<string | null>(null),
      personAmount: new FormControl<number | null>(null),
      numberOfNights: new FormControl<number | null>(null),
      comment: new FormControl<string | null>(null),
   });

   activityDates: Date[] = [];
   selectedDayActivities: string[][] = [];

   constructor(private route: ActivatedRoute,
      private db: DbConnectionService,
      private fb: FormBuilder,
      private router: Router) { }


   ngOnInit(): void {

      if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
         this.mobile = true
      }

      this.route.params.subscribe(r => {
         // error handling
         if (!r["tripId"] || isNaN(Number(r["tripId"])))
            return alert("Invalid TripID");
         if (!r["activityId"] || isNaN(Number(r["activityId"])))
            return alert("Invalid activityId");
         // extract tripID and activityID from url
         this.tripId = Number(r["tripId"]);
         this.activityId = Number(r["activityId"]);

         this.fetchMainActivityDetails();
      });
      this.route.queryParams.subscribe(r => {
         this.editMode = Boolean(r["edit"])
      })
   }

   cancelMainActivity() {
      // Delete All DayActivities linked to MainActivity and delete MainActivity
      this.db.executeQuery(`DELETE FROM DayActivity WHERE activityID=${this.activityId}`).then(r => {
         this.db.executeQuery(`DELETE FROM MainActivity WHERE activityID=${this.activityId}`).then(r2 => {
            this.router.navigateByUrl(`/trip/${this.tripId}/activities`);
         })
      })

   }

   fetchMainActivityDetails() {
      this.db.executeQuery(`SELECT * FROM MainActivity WHERE activityID=${this.activityId}`).then(r => {
         this.mainActivity = r["data"][0];
         this.form.patchValue({
            'startDate': new Date(this.mainActivity['startDate']),
            'transport': this.mainActivity['transport'],
            'personAmount': this.mainActivity['persons'],
            'numberOfNights': this.mainActivity['nights'],
            'comment': this.mainActivity['comment']
         });
         this.fetchThisActivityView();

         this.form.get("startDate").valueChanges.subscribe(newStartDate => {

            this.db.executeQuery(`DELETE FROM DayActivity WHERE activityID=${this.activityId}`).then(_ => {
               this.selectedDayActivities = this.selectedDayActivities.map(_ => []);
            })

            // Update DB
            this.db.executeQuery(`UPDATE MainActivity SET startDate = '${this.toMysqlDate(newStartDate)}' WHERE activityID=${this.activityId}`).then(_ => {
               this.fetchThisActivityView();
            })
         })

         this.form.get("transport").valueChanges.subscribe(newTransport => {
            // Update DB
            this.db.executeQuery(`UPDATE MainActivity SET transport = '${newTransport}' WHERE activityID=${this.activityId}`).then(_ => {
               this.fetchThisActivityView();
            })
         })

         this.form.get("personAmount").valueChanges.subscribe(newPersonAmount => {
            // Update DB
            this.db.executeQuery(`UPDATE MainActivity SET persons = ${newPersonAmount} WHERE activityID=${this.activityId}`).then(_ => {
               this.fetchThisActivityView();
            })
         })

         this.form.get("numberOfNights").valueChanges.subscribe(newNights => {
            if (newNights < this.activityDates.length-1) { // decreased nr of nights
               for (let i = this.activityDates.length - 1; i > newNights; i--)
                  // delete all dayActivities on date
                  this.db.executeQuery(`DELETE FROM DayActivity WHERE activityID=${this.activityId} AND date='${this.toMysqlDate(this.activityDates[i])}'`)
               this.activityDates = this.activityDates.splice(0, newNights+1)
               this.selectedDayActivities = this.selectedDayActivities.splice(0, newNights+1)
            } else if (newNights >= this.activityDates.length){ // increased nr of nights
               let newDays = newNights - this.activityDates.length + 1;
               for(let i = 1; i <= newDays; i++){
                  this.activityDates.push(this.addDays(this.activityDates[this.activityDates.length-1], 1));
                  this.selectedDayActivities.push([]);
               }
            }

            //this.fetchDayByDayView();

            // Update DB
            this.db.executeQuery(`UPDATE MainActivity SET nights = ${newNights} WHERE activityID=${this.activityId}`).then(r => {
               this.fetchThisActivityView();
            })
            
         })

         this.fetchMainActivityTypeDetails();
         this.fetchDayActivityTypes();
         this.fetchDayActivities();
         this.fetchTripInfo();
         // this.fetchDayByDayView();
         this.fetchTransport();
      })
   }

   fetchTransport() {
      this.db.executeQuery(`SELECT * FROM Transport_MainActivityType WHERE mainActivityType='${this.mainActivity['mainActivityType']}' ORDER BY createdAt`).then(r => {
         let transportOptions = r["data"];
         if (!this.mainActivity["transport"] && transportOptions.length === 1)
            this.form.patchValue({ 'transport': transportOptions[0]['transport'] })
         if (transportOptions.length > 1)
            this.transportOptions = transportOptions;
      })
   }

   fetchMainActivityTypeDetails() {
      this.db.executeQuery(`SELECT * FROM MainActivityType WHERE name="${this.mainActivity['mainActivityType']}"`).then(r => {
         this.mainActivityType = r["data"][0];
         
      })
   }

   fetchDayActivityTypes() {
      this.db.executeQuery(`SELECT D.* FROM MainActivityType_DayActivityType AS M INNER JOIN DayActivityType AS D ON M.dayActivityType=D.name WHERE mainActivityType="${this.mainActivity['mainActivityType']}" AND D.status = "ACTIVE" order by isDefault desc, name`).then(r => {
         this.dayActivityTypes = r["data"];
      })
   }

   // fetch chosen day activities
   async fetchDayActivities() {
      let activityDates = [];
      let selectedDayActivities = [];
      for(let i = 0; i < this.form.value.numberOfNights+1; i++){
         let d = this.addDays(this.form.value.startDate, i);
         activityDates.push(d);
         const r =  await this.db.executeQuery(`SELECT dayActivityType FROM DayActivity WHERE ActivityID=${this.activityId} AND date='${this.toMysqlDate(d)}'`)
         selectedDayActivities.push(r["data"].map(x => x.dayActivityType));
      }
      this.activityDates = activityDates;
      this.selectedDayActivities = selectedDayActivities;
   }

   isDayActivitySelected(dateIndex, dayActivity){
      return this.selectedDayActivities[dateIndex].includes(dayActivity.name)
   }

   async dayActivityChange(dateIndex, dayActivity, checkboxValue){
      if (checkboxValue){ // add day activity
         await this.db.executeQuery(`INSERT INTO DayActivity (activityID, dayActivityType, date) VALUES (${this.activityId}, '${dayActivity.name}', '${this.toMysqlDate(this.activityDates[dateIndex])}')`)
         this.selectedDayActivities[dateIndex].push(dayActivity.name);
      } else { // delete day activity
         await this.db.executeQuery(`DELETE FROM DayActivity WHERE activityID=${this.activityId} AND dayActivityType='${dayActivity.name}' AND date='${this.toMysqlDate(this.activityDates[dateIndex])}'`)
         this.selectedDayActivities[dateIndex] = this.selectedDayActivities[dateIndex].filter(x => x !== dayActivity.name)
      }
      this.fetchThisActivityView();
   }


   /* appendNewDayActivity() {
      let d = this.activities.length > 0 ? this.addDays(this.activities.at(-1).value["date"], 1) : this.form.value["startDate"];
      this.appendDayActivity(d, null, null);

   } */

   // appendNothingActivity() {
   //    let d = this.activities.length > 0 ? this.addDays(this.activities.at(-1).value["date"], 1) : this.form.value["startDate"];
   //    this.appendActivity(d, this.noLastDayActivity['name'], null);
   // }

   fetchThisActivityView() {
      this.db.executeQuery(`SELECT * FROM ThisActivityView WHERE activityID=${this.activityId}`).then(r => {
         //need to include the active activity
         let editMainActivity = r["data"][0]
         this.mainActivity['price'] = editMainActivity['totalPrice'];
         this.mainActivity['startDate'] = editMainActivity['startDate'];
         this.mainActivity['nights'] = editMainActivity['nights'];
         this.mainActivity['persons'] = editMainActivity['persons'];
         
         // this.mainActivity['dayActivities'] = r["data"][0]['dayActivities'];
         // console.log(r["data"][0])
      })
   }

   fetchTripInfo() {
      this.db.executeQuery(`SELECT startDate, endDate, persons FROM Trip WHERE tripID=${this.tripId}`).then(r => {
         this.trip = r["data"][0];
      })
   }

   fetchDayByDayView() {
      this.db.executeQuery(`SELECT * from DayByDayView WHERE tripID=${this.tripId}`).then(r => {
         this.tripSummary = r["data"];
      })
   }

   myRange(min: number, max: number) {
      return [...Array(max + 1).keys()].splice(min)
   }

   async confirmActivity() {
      if (this.form.value['comment'])
         // console.log(`UPDATE MainActivity SET comment='${this.form.value['comment']}' WHERE activityID=${this.activityId}`)
      await this.db.executeQuery(`UPDATE MainActivity SET comment='${this.form.value['comment']}' WHERE activityID=${this.activityId}`)
      //instert activity price into HistoricPriceTable
      await this.db.executeQuery(`INSERT INTO HistoricPrice (mainActivityID, price) VALUES (${this.activityId}, (select totalPrice from TotalPriceView where activityID = ${this.activityId}));`)
         
      if (this.form.value['numberOfNights'] === 0) {
         // Navigate to itinerary page
         this.router.navigateByUrl(`/trip/${this.tripId}/activities`);
      }
      else {
         // Navigate to Accomodation Page
         this.router.navigateByUrl(`/trip/${this.tripId}/accommodation/${this.activityId}`);
      }
   }

   addDays(date, days: number) {
      let result = new Date(date);
      result.setDate(result.getDate() + days);
      return result;
   }

   // js date to mysql date (fixes 1 day off bug)
   toMysqlDate(date) {
      date.setHours(12)
      return date.toISOString().split('T')[0];
   }

   getDayNr(date: Date) {
      return this.dateDiffInDays(new Date(this.trip["startDate"]), date);
   }

   dateDiffInDays(a: Date, b: Date) {
      // Discard the time and time-zone information.
      const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
      const utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
      const _MS_PER_DAY = 1000 * 60 * 60 * 24;
      return Math.floor((utc2 - utc1) / _MS_PER_DAY);
   }

}
<div class="header d-flex justify-content-between">
   <h2>Select Day Events</h2>
   <app-wizard [selectedStep]="2" [tripID] = this.tripId></app-wizard>
</div>

<div class="middle-container mobile-container">
   <div class="col">
      <div class="custom-card">
         <h3>{{mainActivity ? mainActivity['mainActivityType'] : 'LOADING...'}}</h3>
         <hr />
         <div *ngIf="mainActivityType">{{mainActivityType['description']}}</div>
         <form [formGroup]="form" *ngIf="mainActivity">
            <div class="form-group date-picker">
               <label for="startDate">Arrive at Activity</label>
               <mat-form-field class="w-100" appearance="fill" id="datepicker" *ngIf="trip">
                  <input  matInput formControlName="startDate" [matDatepicker]="picker" [min]="trip['startDate']" [max]="trip['endDate']">
                  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
                  <mat-datepicker #picker></mat-datepicker>
               </mat-form-field>
            </div>
            <div class="form-group push-up-cause-fucked-material" *ngIf="trip">
               <label for="personAmount">Participants for {{mainActivity['mainActivityType']}}</label>
               <div id="personAmount">
                  <div class="form-check form-check-inline" *ngFor="let persons of myRange(1, trip['persons'])">
                     <input class="form-check-input" type="radio" formControlName="personAmount"
                        [id]="'numberOfPersons' + persons" [value]="persons">
                     <label class="form-check-label" [for]="'numberOfPersons' + persons">{{persons}}</label>
                  </div>
               </div>
            </div>
            <div class="form-group" *ngIf="transportOptions.length > 1">
               <label for="transport">Transport</label>
               <div id="transport">
                  <div class="form-check form-check-inline" *ngFor="let transport of transportOptions">
                     <input class="form-check-input" type="radio" formControlName="transport"
                        [id]="'transportOption' + transport.transport" [value]="transport.transport">
                     <label class="form-check-label" [for]="'transportOption' + transport.transport">{{transport.transport}}</label>
                  </div>
               </div>
            </div>
            <!-- {{form.value.transport}} -->
            <div class="form-group" *ngIf="mainActivityType && (form.value.transport !==null || transportOptions.length <= 1)">
               <label for="nrOfNights">Number of Nights (* = recommended)</label>
               <div id="nrOfNights">
                  <div class="form-check form-check-inline" *ngFor="let nights of myRange(mainActivityType['minNights'], mainActivityType['maxNights'])">
                     <input class="form-check-input custom-radio" type="radio" formControlName="numberOfNights"
                        [id]="'numberOfNights' + nights" [value]="nights">
                     <label class="form-check-label" [for]="'numberOfNights' + nights">{{nights}}<span
                           *ngIf="nights === mainActivityType.recommendedNights">*</span></label>
                  </div>
               </div>   
            </div>
            <ng-container *ngIf="dayActivityTypes && form.value.numberOfNights !== null">
               <ng-container *ngFor="let date of activityDates; let i = index">
                  <div class="form-group">
                     <label for="dayActivity">Day {{i}}:
                        {{toMysqlDate(date)| date: 'dd-MM-yyyy'}}</label>
                     <div id="dayActivity">
                        <div class="form-check form-check-inline" *ngFor="let dayActivity of dayActivityTypes">
                           <input class="form-check-input" [id]="dayActivity.name + i" type="checkbox" (click)="dayActivityChange(i, dayActivity, $event.target.checked)" [checked]="isDayActivitySelected(i, dayActivity)">
                           <label class="form-check-label" [for]="dayActivity.name + i">{{dayActivity.name}}</label>
                           <span class="fa-stack" *ngIf="dayActivity.description" [ngbPopover]="dayActivity.description" triggers="mouseenter:mouseleave"
                           popoverClass="myclass">
                              <i class="fa fa-circle fa-stack-1x icon-background2"></i>
                              <i class="fa fa-info fa-stack-1x"></i> 
                             </span>
                        </div>
                     </div>
                  </div> 
               </ng-container>
            </ng-container>
            <div class="form-group" *ngIf="form.value.numberOfNights !== null">
               <label for="commentTextarea">Add Comment</label>
               <textarea class="form-control" id="commentTextarea" rows="3" formControlName="comment"></textarea>
            </div>
         </form>
         <!-- <button *ngIf="!mobile" class="btn btn-next">
            [disabled]="activities.length !== (form.value['numberOfNights'] + 1)"
            <span>{{editMode ? 'Update' : 'Confirm'}} Activity</span>
         </button> -->
      </div>
   </div>
   <div *ngIf="!mobile" class="col-md-3">
      <div class="custom-card" *ngIf="mainActivity">
         <app-yourtrip [mainActivity] = "mainActivity"></app-yourtrip>
      </div>
   </div>
</div>

<div class="footer d-flex justify-content-between">
   <button *ngIf="!editMode" type="button" class="btn btn-back" (click)="cancelMainActivity()"><i class="bi bi-trash"></i> Cancel {{!mobile ? 'Activity' : ''}}</button>
   <button *ngIf="editMode" type="button" class="btn btn-back" [routerLink]="['/trip', tripId, 'itinerary']"><i class="bi bi-back"></i> Back</button>
   <button type="button" class="btn btn-next" (click)="confirmActivity()"><i class="bi bi-check-circle"></i> {{editMode ? 'Update' : 'Confirm'}} {{!mobile ? 'Activity' : ''}}</button>
</div>

./activity.component.scss

@import 'variables';
@import 'footer';
@import 'header';
@import 'custom-checkbox';
@import 'custom-card';
@import 'custom-table';
@import 'info-circle';


::ng-deep .popover-body {
   width: 15rem;
}

.footer {
   .btn {
      width: 175px;
   }

   .btn-add-activity {
      background-color: #28A745;
   }
}

.custom-card {
   overflow-y: auto;

   &::-webkit-scrollbar {
      border-radius: 3px;
      width: 10px;
   }

   /* Track */
   &::-webkit-scrollbar-track {
      background: #f1f1f1;
   }

   /* Handle */
   &::-webkit-scrollbar-thumb {
      border-radius: 3px;
      background: $secondary-button-color;
   }

   /* Handle on hover */
   &::-webkit-scrollbar-thumb:hover {
      background: $primary-button-color;
   }
}

label {
   color: grey;
   font-weight: 600;
}

.form-check-label {
   color: darkslategray;
   font-weight: normal;
}

.push-up-cause-fucked-material {
   margin-top: -20px;
}

.date-picker {
   margin-top: 10px;

   ::ng-deep .mat-form-field-label-wrapper {
      top: -1.5em;
   }

   ::ng-deep .mat-form-field-appearance-outline.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label {
      transform: translateY(-1.1em) scale(.75);
      width: 133.33333%;
   }

   ::ng-deep .mat-form-field-appearance-fill .mat-form-field-flex {
      padding: 5px 10px !important;
      background-color: white;
   }

   ::ng-deep .mat-form-field-flex>.mat-form-field-infix {
      padding: 0px !important
   }
}

#dateInput {
   background-color: #f1f1f1;
}

@media only screen and (max-width: 950px) {
   .mobile-container {
      padding-left: 10%;
      padding-right: 10%;
   }

}

@media only screen and (max-width: 600px) {
   .mobile-container{
      padding-left: 0%;
      padding-right: 0%;
   }
}


Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""