File
Implements
Methods
fetchActivities
|
fetchActivities()
|
|
|
fetchCategories
|
fetchCategories()
|
|
|
filteredActivities
|
filteredActivities()
|
|
|
selectActivity
|
selectActivity(activity)
|
|
Parameters :
Name |
Optional |
activity |
No
|
|
toggleCategorySelection
|
toggleCategorySelection(category: string, value: string)
|
|
|
updateChecked
|
updateChecked(key, value)
|
|
Parameters :
Name |
Optional |
key |
No
|
value |
No
|
|
activities
|
Type : []
|
Default value : []
|
|
categoryvalues
|
Type : []
|
Default value : []
|
|
mobile
|
Type : boolean
|
Default value : false
|
|
selectedCategories
|
Type : string[]
|
Default value : []
|
|
import { Location } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { DbConnectionService } from '../db-connection.service';
import { catchError, map, tap } from 'rxjs/operators';
interface Activity {
activityValues: string;
mapNumber: number;
name: string;
picture: string;
status: string;
}
@Component({
selector: 'app-activitieslist',
templateUrl: './activitieslist.component.html',
styleUrls: ['./activitieslist.component.scss']
})
export class ActivitieslistComponent implements OnInit {
tripId: number;
activities = [];
categoryvalues = [];
selected: number;
mobile: boolean = false;
constructor(
private route: ActivatedRoute,
private db: DbConnectionService,
private location: Location,
private router: Router
) { }
// filteredActivities = () => {
// }
// getSelectedValues() {
// return this.activities.
// }
ngOnInit(): void {
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
this.mobile = true
}
this.route.params.subscribe(r => {
this.selected = -1;
// error handling
if (!r["tripId"] || isNaN(Number(r["tripId"])))
return alert("Invalid TripID");
// extract tripID and activity from url
this.tripId = Number(r["tripId"])
this.fetchActivities();
this.fetchCategories();
});
}
fetchActivities() {
// fetch Activities
this.db.executeQuery(`SELECT * FROM MainActivityTypesView WHERE status = 'ACTIVE'`).then(r => {
// set data
this.activities = r["data"];
this.selected = 0; //default selected to first
console.log(this.activities)
});
}
//ToDo: filter
fetchCategories() {
// fetch Categories
this.db.executeQuery(`SELECT * FROM CategoryValue`).then(r => {
// set data
r["data"].forEach(x => {
if (x.category in this.categoryvalues)
this.categoryvalues[x.category].push({ value: x.name, checked: false })
else
this.categoryvalues[x.category] = [{ value: x.name, checked: false }]
});
});
console.log(this.categoryvalues)
}
updateChecked(key, value) {
console.log(this.categoryvalues)
console.log(key)
console.log(value)
for (const item of this.categoryvalues[key]) {
if (item.value === value) {
item.checked = true;
console.log(this.categoryvalues)
return;
}
}
this.filteredActivities();
}
selectedCategories: string[] = [];
filteredActivities(): Activity[] {
return this.activities.filter(activity => {
// For each category, check if the activity value matches the selected value for that category
return Object.keys(this.selectedCategories).every(category => {
const selectedValue = this.selectedCategories[category];
if (selectedValue !== null) {
const activityCategories = activity.activityValues.split(', ');
return activityCategories.includes(selectedValue);
} else {
return true; // if no value is selected, include all activities
}
});
});
}
// toggleCategorySelection(category: string) {
// if (this.selectedCategories.includes(category)) {
// this.selectedCategories = this.selectedCategories.filter(c => c !== category);
// } else {
// this.selectedCategories.push(category);
// }
// }
toggleCategorySelection(category: string, value: string) {
if (this.selectedCategories[category] === value) {
// If the selected value is the same as the current value, deselect the category
this.selectedCategories[category] = null;
} else {
// Otherwise, select the new value for the category
this.selectedCategories[category] = value;
}
console.log(this.selectedCategories)
}
selectActivity(activity) {
// if (this.selected < 0)
// return;
// let activity = this.activities[this.selected];
// Fetch person amount
// this.db.executeQuery(`SELECT persons FROM Trip WHERE tripID=${this.tripId}`).then(r1 => {
// let persons = r1["data"][0]["persons"];
// // fetch recommended nights of mainactivity
// // this.db.executeQuery(`SELECT recommendedNights FROM MainActivityType WHERE name="${activity['name']}"`).then(r2 => {
// // let nights = r2["data"][0]["recommendedNights"];
// // fetch next available date
// this.db.executeQuery(`SELECT endDate FROM ((SELECT tripID, startDate as endDate, 'ARRIVAL' as name FROM Trip) UNION (SELECT tripID, DATE_ADD(startDate, INTERVAL nights DAY) as endDate, mainActivityType as name FROM MainActivity)) AS T WHERE tripID=${this.tripId} ORDER BY endDate DESC LIMIT 1`).then(r3 => {
// let date = r3["data"][0]["endDate"];
// create new Activity with default values
// this.db.executeQuery(`INSERT INTO MainActivity (tripID, mainActivityType, persons, startDate) VALUES (${this.tripId}, '${activity['name']}', ${persons}, '${date}')`).then(r => {
// redirect with mainActivityID
// this.router.navigateByUrl(`trip/${this.tripId}/activity/${r["data"].insertId}`);
this.router.navigateByUrl(`trip/${this.tripId}/activitytype/${activity['name']}`);
// })
// })
// })
// })
}
back() {
// go to previous page
this.location.back();
}
}
<div class="header d-flex justify-content-between">
<h2>Select Activity</h2>
<app-wizard [selectedStep]="1" [tripID]=this.tripId></app-wizard>
</div>
<div class="middle-container">
<div *ngIf="!mobile" class="col-md-2">
<div class="custom-card filters">
<h4 class="card-title">Filter by</h4>
<div class="filter-part" *ngFor="let c of categoryvalues | keyvalue">
<h5 class="filter-title"> {{c.key}} </h5>
<hr />
<!-- <div class="btn-group-toggle btn-group-vertical" data-toggle="buttons">
<label class="custom-checkbox" *ngFor="let cv of c.value">
<input type="checkbox" class="btn-check" autocomplete="off"
(change)="toggleCategorySelection(cv.value)">
<span>{{cv.value}}</span>
</label>
</div> -->
<div class="btn-group-toggle btn-group-vertical" data-toggle="buttons">
<label class="custom-radio" *ngFor="let cv of c.value">
<input type="radio" class="btn-check" autocomplete="off"
[checked]="cv.value === selectedCategories[c.key]"
name="{{c.key}}"
(click)="toggleCategorySelection(c.key, cv.value)">
<span>{{cv.value}}</span>
</label>
</div>
</div>
</div>
</div>
<div class="col">
<div class="row custom-card activities">
<div class="col-sm-6 d-flex justify-content-center"
*ngFor="let activity of filteredActivities(); let i = index">
<div class="card activity custom-box-shadow" (click)="selectActivity(activity)">
<span class="activity-index">{{activity.mapNumber}}</span>
<img class="card-img-top"
[src]="activity.picture ? activity.picture : 'https://via.placeholder.com/140x100'">
<div class="card-body">
<div class="card-title">{{activity.name}}</div>
<div class="card-content">{{activity.activityValues}}</div>
<!-- <div class="card-price"> From €120 pp </div> -->
<!-- <div class="row">
<div class="col">
<button class="btn btn-footer-card" (click)="selectActivity()">
Add
</button>
</div>
<div class="col">
<button class="btn btn-footer-card" id="info">
Info
</button>
</div>
</div> -->
</div>
</div>
</div>
</div>
</div>
<div *ngIf="!mobile" class="col-md-4">
<div class="custom-card">
<iframe class="iframe-auto-height custom-box-shadow"
src="https://www.google.com/maps/d/embed?mid=1eUi2YXbBCIJR3TWurtu87RDW5BRHYiv_&ehbc=2E312F" frameborder="0"
scrolling="no" width="480" height="480"></iframe>
</div>
</div>
</div>
<div class="footer d-flex justify-content-between">
<button type="button" class="btn btn-back" (click)="back()"><i class="bi bi-back"></i> Back</button>
<button type="button" class="btn btn-next" [routerLink]="['/trip', tripId, 'itinerary']"> <i class="bi bi-map"></i>
{{ !mobile? 'View
Itinerary' : 'Itinerary'}}</button>
<!-- <button type="button" class="btn btn-add-activity" (click)="createActivity()" [disabled]="selected < 0">{{ !mobile?
'Add Activity' : 'Add'}}</button> -->
</div>
@import 'variables';
@import 'footer';
@import 'header';
@import 'custom-checkbox';
@import 'custom-card';
.filters {
.filter-part {
margin-bottom: 12px;
.filter-title {
margin-bottom: 0px;
}
hr {
margin: 6px 0px;
}
}
}
.activities {
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;
}
.card.activity {
width: 20rem;
margin-bottom: 15px;
border: 2px solid $secondary-background-color;
max-height: 280px;
.activity-index {
font-family: Roboto;
background-color: #0288D1;
color: white;
border: 1px solid white;
border-radius: 50%;
position: absolute;
right: 0;
top: 0;
width: 27px;
height: 27px;
margin: 8px;
padding: 1px;
text-align: center;
}
.card-body {
padding: 8px 12px;
color: #2F4F4F;
.card-title {
font-weight: 600;
font-size: 14pt;
margin: 0px;
}
.card-price {
font-weight: 500;
color: darkgray;
margin-top: 15px;
text-align: left;
}
.btn-edit {
text-align: right;
}
}
// &.selected-card {
// border-color: $primary-button-color;
// opacity: 1;
// }
&:hover {
cursor: pointer;
}
}
}
.iframe-auto-height {
height: 99%;
width: 100%;
overflow: auto;
margin: 0;
padding: 0;
border: none;
background: transparent;
}
#info {
background-color: #0288D1;
right: 15px;
position: absolute;
}
Legend
Html element with directive