src/app/activity/activity.component.ts
selector | app-activity |
styleUrls | ./activity.component.scss |
templateUrl | ./activity.component.html |
constructor(route: ActivatedRoute, db: DbConnectionService, fb: FormBuilder, router: Router)
|
|||||||||||||||
Defined in src/app/activity/activity.component.ts:40
|
|||||||||||||||
Parameters :
|
mainActivity | |
Type : Object | null
|
|
Default value : null
|
|
Defined in src/app/activity/activity.component.ts:20
|
addDays | |||||||||
addDays(date, days: number)
|
|||||||||
Defined in src/app/activity/activity.component.ts:263
|
|||||||||
Parameters :
Returns :
any
|
cancelMainActivity |
cancelMainActivity()
|
Defined in src/app/activity/activity.component.ts:71
|
Returns :
void
|
Async confirmActivity |
confirmActivity()
|
Defined in src/app/activity/activity.component.ts:246
|
Returns :
any
|
dateDiffInDays |
dateDiffInDays(a: Date, b: Date)
|
Defined in src/app/activity/activity.component.ts:279
|
Returns :
any
|
Async dayActivityChange | ||||||||
dayActivityChange(dateIndex, dayActivity, checkboxValue)
|
||||||||
Defined in src/app/activity/activity.component.ts:193
|
||||||||
Parameters :
Returns :
any
|
Async fetchDayActivities |
fetchDayActivities()
|
Defined in src/app/activity/activity.component.ts:176
|
Returns :
any
|
fetchDayActivityTypes |
fetchDayActivityTypes()
|
Defined in src/app/activity/activity.component.ts:169
|
Returns :
void
|
fetchDayByDayView |
fetchDayByDayView()
|
Defined in src/app/activity/activity.component.ts:236
|
Returns :
void
|
fetchMainActivityDetails |
fetchMainActivityDetails()
|
Defined in src/app/activity/activity.component.ts:81
|
Returns :
void
|
fetchMainActivityTypeDetails |
fetchMainActivityTypeDetails()
|
Defined in src/app/activity/activity.component.ts:162
|
Returns :
void
|
fetchThisActivityView |
fetchThisActivityView()
|
Defined in src/app/activity/activity.component.ts:216
|
Returns :
void
|
fetchTransport |
fetchTransport()
|
Defined in src/app/activity/activity.component.ts:152
|
Returns :
void
|
fetchTripInfo |
fetchTripInfo()
|
Defined in src/app/activity/activity.component.ts:230
|
Returns :
void
|
getDayNr | ||||||
getDayNr(date: Date)
|
||||||
Defined in src/app/activity/activity.component.ts:275
|
||||||
Parameters :
Returns :
any
|
isDayActivitySelected | ||||||
isDayActivitySelected(dateIndex, dayActivity)
|
||||||
Defined in src/app/activity/activity.component.ts:189
|
||||||
Parameters :
Returns :
any
|
myRange |
myRange(min: number, max: number)
|
Defined in src/app/activity/activity.component.ts:242
|
Returns :
any
|
ngOnInit |
ngOnInit()
|
Defined in src/app/activity/activity.component.ts:48
|
Returns :
void
|
toMysqlDate | ||||
toMysqlDate(date)
|
||||
Defined in src/app/activity/activity.component.ts:270
|
||||
Parameters :
Returns :
any
|
activityDates |
Type : Date[]
|
Default value : []
|
Defined in src/app/activity/activity.component.ts:39
|
activityId |
Type : number
|
Defined in src/app/activity/activity.component.ts:19
|
dayActivityTypes |
Type : Object[]
|
Default value : []
|
Defined in src/app/activity/activity.component.ts:22
|
editMode |
Type : boolean
|
Default value : false
|
Defined in src/app/activity/activity.component.ts:29
|
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),
})
|
Defined in src/app/activity/activity.component.ts:31
|
loading |
Type : boolean
|
Default value : true
|
Defined in src/app/activity/activity.component.ts:28
|
mainActivityType |
Type : Object
|
Defined in src/app/activity/activity.component.ts:21
|
mobile |
Type : boolean
|
Default value : false
|
Defined in src/app/activity/activity.component.ts:26
|
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"
}
|
Defined in src/app/activity/activity.component.ts:13
|
selectedDayActivities |
Type : string[][]
|
Default value : []
|
Defined in src/app/activity/activity.component.ts:40
|
transportOptions |
Type : Object[]
|
Default value : []
|
Defined in src/app/activity/activity.component.ts:23
|
trip |
Type : Object
|
Default value : null
|
Defined in src/app/activity/activity.component.ts:24
|
tripId |
Type : number
|
Defined in src/app/activity/activity.component.ts:18
|
tripSummary |
Type : Object[]
|
Default value : []
|
Defined in src/app/activity/activity.component.ts:25
|
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%;
}
}