diff --git a/src/src/app/components/trip/trip.component.html b/src/src/app/components/trip/trip.component.html index 7a414a3..2617620 100644 --- a/src/src/app/components/trip/trip.component.html +++ b/src/src/app/components/trip/trip.component.html @@ -1,5 +1,5 @@
-
+
@@ -16,6 +16,20 @@
+ @if (trip?.archived) { +
+
This Trip is archived, you cannot modify it.
+
+ @if (trip?.archival_review) { + + } + +
+
+ } +
-
-@if (trip?.archived) { -
-
-
Archived
- -
- This Trip is archived, you cannot modify it. -
-} + @if (isArchivalReviewDisplayed) { +
+ {{ trip?.archival_review }}
+ } +
diff --git a/src/src/app/components/trip/trip.component.ts b/src/src/app/components/trip/trip.component.ts index 0c08515..126feb7 100644 --- a/src/src/app/components/trip/trip.component.ts +++ b/src/src/app/components/trip/trip.component.ts @@ -63,6 +63,7 @@ import { TripInviteMemberModalComponent } from "../../modals/trip-invite-member- import { calculateDistanceBetween } from "../../shared/haversine"; import { orderByPipe } from "../../shared/order-by.pipe"; import { TripNotesModalComponent } from "../../modals/trip-notes-modal/trip-notes-modal.component"; +import { TripArchiveModalComponent } from "../../modals/trip-archive-modal/trip-archive-modal.component"; @Component({ selector: "app-trip", @@ -99,6 +100,7 @@ export class TripComponent implements AfterViewInit { selectedItem?: TripItem & { status?: TripStatus }; tableExpandableMode = false; isPrinting = false; + isArchivalReviewDisplayed = false; isMapFullscreen = false; isMapFullscreenDays = false; @@ -185,7 +187,7 @@ export class TripComponent implements AfterViewInit { label: "Archive", icon: "pi pi-box", command: () => { - this.toggleArchiveTrip(); + this.openArchiveTripModal(); }, }, { @@ -942,30 +944,59 @@ export class TripComponent implements AfterViewInit { }); } - toggleArchiveTrip() { - const currentArchiveStatus = this.trip?.archived; + openUnarchiveTripModal() { const modal = this.dialogService.open(YesNoModalComponent, { - header: "Confirm Action", + header: "Restore Trip", modal: true, closable: true, dismissableMask: true, breakpoints: { "640px": "90vw", }, - data: `${currentArchiveStatus ? "Restore" : "Archive"} ${this.trip?.name} ?${currentArchiveStatus ? "" : " This will make everything read-only."}`, + data: `Restore ${this.trip?.name} ?`, })!; modal.onClose.pipe(take(1)).subscribe({ next: (bool) => { - if (bool) - this.apiService - .putTrip({ archived: !currentArchiveStatus }, this.trip?.id!) - .pipe(take(1)) - .subscribe({ - next: () => { - this.trip!.archived = !currentArchiveStatus; - }, - }); + if (!bool) return; + this.apiService + .putTrip({ archived: false }, this.trip?.id!) + .pipe(take(1)) + .subscribe({ + next: (trip) => (this.trip = trip), + }); + }, + }); + } + + openArchiveTripModal() { + if (!this.trip) return; + const currentArchiveStatus = this.trip?.archived; + const modal = this.dialogService.open(TripArchiveModalComponent, { + header: `Archive ${this.trip.name}`, + modal: true, + closable: true, + dismissableMask: true, + width: "30vw", + breakpoints: { + "1024px": "60vw", + "640px": "90vw", + }, + data: this.trip, + })!; + + modal.onClose.pipe(take(1)).subscribe({ + next: (review: string) => { + if (review === undefined) return; + this.apiService + .putTrip( + { archived: !currentArchiveStatus, archival_review: review }, + this.trip?.id!, + ) + .pipe(take(1)) + .subscribe({ + next: (trip) => (this.trip = trip), + }); }, }); } @@ -1853,7 +1884,7 @@ export class TripComponent implements AfterViewInit { next: (notes: string) => { if (notes === undefined) return; this.apiService - .putTrip({ notes: notes ?? "" }, this.trip!.id) + .putTrip({ notes: notes }, this.trip!.id) .pipe(take(1)) .subscribe({ next: (trip) => (this.trip = trip), diff --git a/src/src/app/modals/trip-archive-modal/trip-archive-modal.component.html b/src/src/app/modals/trip-archive-modal/trip-archive-modal.component.html new file mode 100644 index 0000000..d48aa01 --- /dev/null +++ b/src/src/app/modals/trip-archive-modal/trip-archive-modal.component.html @@ -0,0 +1,17 @@ +
+
+ You're about to archive your Trip! This will make the Trip read-only.
+ You can review your trip and add general feedback. You can also skip this part and delete everything. +
+ +
+ + + + +
+ +
+ +
+
\ No newline at end of file diff --git a/src/src/app/modals/trip-archive-modal/trip-archive-modal.component.scss b/src/src/app/modals/trip-archive-modal/trip-archive-modal.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/src/app/modals/trip-archive-modal/trip-archive-modal.component.ts b/src/src/app/modals/trip-archive-modal/trip-archive-modal.component.ts new file mode 100644 index 0000000..3f389a1 --- /dev/null +++ b/src/src/app/modals/trip-archive-modal/trip-archive-modal.component.ts @@ -0,0 +1,54 @@ +import { Component } from "@angular/core"; +import { FormControl, ReactiveFormsModule } from "@angular/forms"; +import { ButtonModule } from "primeng/button"; +import { DynamicDialogConfig, DynamicDialogRef } from "primeng/dynamicdialog"; +import { FloatLabelModule } from "primeng/floatlabel"; +import { TextareaModule } from "primeng/textarea"; +import { Trip } from "../../types/trip"; + +@Component({ + selector: "app-trip-archive-modal", + imports: [ + FloatLabelModule, + TextareaModule, + ButtonModule, + ReactiveFormsModule, + ], + standalone: true, + templateUrl: "./trip-archive-modal.component.html", + styleUrl: "./trip-archive-modal.component.scss", +}) +export class TripArchiveModalComponent { + review = new FormControl(""); + + constructor( + private ref: DynamicDialogRef, + private config: DynamicDialogConfig, + ) { + this.computeReviewPlaceholder(this.config.data); + } + + computeReviewPlaceholder(trip: Trip) { + if (trip.archival_review) { + this.review.setValue(trip.archival_review); + return; + } + if (!trip.days.length) return; + let placeholder = "General feedback:\n\n"; + trip.days.forEach((day, index) => { + placeholder += `\nDay ${index + 1} (${day.label})\n`; + if (!day.items.length) placeholder += " No activities.\n"; + else + day.items.forEach( + (item) => (placeholder += ` - ${item.time} | ${item.text}\n`), + ); + }); + placeholder += "\nAnything else?"; + this.review.setValue(placeholder); + } + + closeDialog() { + // Normalize data for API POST + this.ref.close(this.review.value); + } +} diff --git a/src/src/app/modals/trip-notes-modal/trip-notes-modal.component.ts b/src/src/app/modals/trip-notes-modal/trip-notes-modal.component.ts index 0f9f6b4..d84eeef 100644 --- a/src/src/app/modals/trip-notes-modal/trip-notes-modal.component.ts +++ b/src/src/app/modals/trip-notes-modal/trip-notes-modal.component.ts @@ -18,7 +18,7 @@ import { TextareaModule } from "primeng/textarea"; styleUrl: "./trip-notes-modal.component.scss", }) export class TripNotesModalComponent { - notes = new FormControl(''); + notes = new FormControl(""); isEditing: boolean = false; constructor( diff --git a/src/src/app/types/trip.ts b/src/src/app/types/trip.ts index a23a9c0..afaa30f 100644 --- a/src/src/app/types/trip.ts +++ b/src/src/app/types/trip.ts @@ -21,6 +21,7 @@ export interface Trip { collaborators: TripMember[]; currency: string; notes?: string; + archival_review?: string; // POST / PUT places: Place[];