diff --git a/src/src/app/components/dashboard/dashboard.component.html b/src/src/app/components/dashboard/dashboard.component.html
index 29b27a1..a8f513c 100644
--- a/src/src/app/components/dashboard/dashboard.component.html
+++ b/src/src/app/components/dashboard/dashboard.component.html
@@ -6,6 +6,11 @@
(closeEmitter)="closePlaceBox()">
}
+@if (selectedGPX) {
+
+}
+
diff --git a/src/src/app/components/dashboard/dashboard.component.ts b/src/src/app/components/dashboard/dashboard.component.ts
index 2e07042..1718c35 100644
--- a/src/src/app/components/dashboard/dashboard.component.ts
+++ b/src/src/app/components/dashboard/dashboard.component.ts
@@ -41,6 +41,7 @@ import { YesNoModalComponent } from "../../modals/yes-no-modal/yes-no-modal.comp
import { CategoryCreateModalComponent } from "../../modals/category-create-modal/category-create-modal.component";
import { AuthService } from "../../services/auth.service";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
+import { PlaceGPXComponent } from "../../shared/place-gpx/place-gpx.component";
export interface ContextMenuItem {
text: string;
@@ -62,6 +63,7 @@ export interface MarkerOptions extends L.MarkerOptions {
standalone: true,
imports: [
PlaceBoxComponent,
+ PlaceGPXComponent,
FormsModule,
SkeletonModule,
ToggleSwitchModule,
@@ -102,6 +104,7 @@ export class DashboardComponent implements OnInit, AfterViewInit {
visiblePlaces: Place[] = [];
selectedPlace?: Place;
categories: Category[] = [];
+ selectedGPX?: Place;
filter_display_visited = false;
filter_display_favorite_only = false;
@@ -531,21 +534,24 @@ export class DashboardComponent implements OnInit, AfterViewInit {
}
displayGPXOnMap(gpx: string) {
- if (!this.map) return;
+ if (!this.map || !this.selectedPlace) return;
if (!this.gpxLayerGroup)
this.gpxLayerGroup = L.layerGroup().addTo(this.map);
this.gpxLayerGroup.clearLayers();
try {
const gpxPolyline = gpxToPolyline(gpx);
+ const selectedPlaceWithGPX = { ...this.selectedPlace, gpx };
+
gpxPolyline.on("click", () => {
- this.gpxLayerGroup?.removeLayer(gpxPolyline);
+ this.selectedGPX = selectedPlaceWithGPX;
});
this.gpxLayerGroup?.addLayer(gpxPolyline);
this.map.fitBounds(gpxPolyline.getBounds(), { padding: [20, 20] });
} catch {
this.utilsService.toast("error", "Error", "Couldn't parse GPX data");
}
+ this.closePlaceBox();
}
getPlaceGPX() {
@@ -816,6 +822,28 @@ export class DashboardComponent implements OnInit, AfterViewInit {
this.selectedPlace = undefined;
}
+ closePlaceGPX() {
+ this.selectedGPX = undefined;
+ }
+
+ downloadGPX() {
+ if (!this.selectedGPX?.gpx) return;
+ const dataBlob = new Blob([this.selectedGPX.gpx]);
+ const downloadURL = URL.createObjectURL(dataBlob);
+ const link = document.createElement("a");
+ link.href = downloadURL;
+ link.download = `TRIP_${this.selectedGPX.name}.gpx`;
+ link.click();
+ link.remove();
+ URL.revokeObjectURL(downloadURL);
+ }
+
+ removeGPX() {
+ if (!this.gpxLayerGroup) return;
+ this.gpxLayerGroup.clearLayers();
+ this.closePlaceGPX();
+ }
+
toGithub() {
this.utilsService.toGithubTRIP();
}
diff --git a/src/src/app/shared/place-gpx/place-gpx.component.html b/src/src/app/shared/place-gpx/place-gpx.component.html
new file mode 100644
index 0000000..db9b596
--- /dev/null
+++ b/src/src/app/shared/place-gpx/place-gpx.component.html
@@ -0,0 +1,22 @@
+@if (selectedPlace) {
+
+
+
+
+
![]()
+
+
Trace of {{ selectedPlace.name }}
+
+
+
+
+
+
+
+}
\ No newline at end of file
diff --git a/src/src/app/shared/place-gpx/place-gpx.component.scss b/src/src/app/shared/place-gpx/place-gpx.component.scss
new file mode 100644
index 0000000..0c5147a
--- /dev/null
+++ b/src/src/app/shared/place-gpx/place-gpx.component.scss
@@ -0,0 +1,25 @@
+.place-box-dialog {
+ animation: slideYcenteredX 0.3s both;
+ z-index: 999;
+ min-height: 100px;
+ max-height: 800px;
+ width: 95%;
+ max-width: 1200px;
+ background-color: #fff;
+ position: fixed;
+ bottom: 10px;
+ left: 50%;
+ transform: translateX(-50%);
+ transition: none;
+ box-shadow: 0px 10px 20px rgba(0, 0, 0, 0.1);
+ border-radius: 12px;
+ display: flex;
+ align-items: flex-end;
+
+ &-content {
+ position: relative;
+ padding: 2rem;
+ border-radius: 8px 8px 0 0;
+ width: 100%;
+ }
+}
diff --git a/src/src/app/shared/place-gpx/place-gpx.component.ts b/src/src/app/shared/place-gpx/place-gpx.component.ts
new file mode 100644
index 0000000..6a49da8
--- /dev/null
+++ b/src/src/app/shared/place-gpx/place-gpx.component.ts
@@ -0,0 +1,38 @@
+import {
+ ChangeDetectionStrategy,
+ Component,
+ EventEmitter,
+ Input,
+ Output,
+} from "@angular/core";
+import { ButtonModule } from "primeng/button";
+import { Place } from "../../types/poi";
+
+@Component({
+ selector: "app-place-gpx",
+ standalone: true,
+ imports: [ButtonModule],
+ templateUrl: "./place-gpx.component.html",
+ styleUrls: ["./place-gpx.component.scss"],
+ changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class PlaceGPXComponent {
+ @Input() selectedPlace: Place | undefined = undefined;
+ @Output() closeEmitter = new EventEmitter();
+ @Output() removeEmitter = new EventEmitter();
+ @Output() downloadEmitter = new EventEmitter();
+
+ constructor() {}
+
+ close() {
+ this.closeEmitter.emit();
+ }
+
+ removeTrace() {
+ this.removeEmitter.emit();
+ }
+
+ downloadTrace() {
+ this.downloadEmitter.emit()
+ }
+}