-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Angular v17 + Material 3 Upgrade: Coworking and Ambassadors Features (#…
…522) * Refactor Folder Structure of Ambassador Page * Refactor Component Names * Refactor Coworking Service and XL Service * Refactor Ambassador Room * Remove Unecessary Files * Refactor Reservation Service * Add Attributions, Remove Unused Imports * Refactor all HTML in Coworking / Ambassadors to use new control flow * Fix Consistency in Fonts In Panes
- Loading branch information
1 parent
1b10b52
commit 94d1d56
Showing
40 changed files
with
593 additions
and
896 deletions.
There are no files selected for viewing
9 changes: 3 additions & 6 deletions
9
frontend/src/app/coworking/ambassador-home/ambassador-home-routing.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 1 addition & 15 deletions
16
frontend/src/app/coworking/ambassador-home/ambassador-home.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1 @@ | ||
<nav mat-tab-nav-bar [tabPanel]="tabPanel" color="accent"> | ||
<a | ||
mat-tab-link | ||
*ngFor="let link of links" | ||
[routerLink]="link.path" | ||
routerLinkActive | ||
#rla="routerLinkActive" | ||
[routerLinkActiveOptions]="{ exact: false }" | ||
[active]="rla.isActive" | ||
>{{ link.label }}</a | ||
> | ||
</nav> | ||
<mat-tab-nav-panel #tabPanel> | ||
<router-outlet></router-outlet> | ||
</mat-tab-nav-panel> | ||
<tab-container [links]="links" /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,12 @@ | ||
/** | ||
* This component is the primary screen for ambassadors at the check-in desk. | ||
* | ||
* @author Kris Jordan <[email protected]> | ||
* @author Kris Jordan <[email protected]>, Ajay Gandecha <[email protected]> | ||
* @copyright 2023 - 2024 | ||
* @license MIT | ||
*/ | ||
|
||
import { Component, OnDestroy, OnInit } from '@angular/core'; | ||
import { Component, OnInit } from '@angular/core'; | ||
import { Router } from '@angular/router'; | ||
|
||
@Component({ | ||
|
@@ -19,18 +19,19 @@ export class AmbassadorPageComponent implements OnInit { | |
{ | ||
label: 'XL Reservations', | ||
path: '/coworking/ambassador/xl', | ||
default: true | ||
icon: 'chair_alt' | ||
}, | ||
{ label: 'Room Reservations', path: '/coworking/ambassador/room' } | ||
{ | ||
label: 'Room Reservations', | ||
path: '/coworking/ambassador/room', | ||
icon: 'meeting_room' | ||
} | ||
]; | ||
|
||
constructor(private router: Router) {} | ||
|
||
ngOnInit(): void { | ||
// Find the default link and navigate to it | ||
const defaultLink = this.links.find((link) => link.default); | ||
if (defaultLink) { | ||
this.router.navigate([defaultLink.path]); | ||
} | ||
this.router.navigate(['/coworking/ambassador/xl']); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
137 changes: 137 additions & 0 deletions
137
frontend/src/app/coworking/ambassador-home/ambassador-room/ambassador-room.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
@if (upcomingReservations()) { @if (upcomingReservations().length > 0) { | ||
<mat-pane class="content" appearance="outlined"> | ||
<mat-card-header> | ||
<mat-card-title>Upcoming Reservations</mat-card-title> | ||
</mat-card-header> | ||
<mat-card-content> | ||
<table mat-table [dataSource]="upcomingReservations()"> | ||
<ng-container matColumnDef="id"> | ||
<th mat-header-cell *matHeaderCellDef>ID</th> | ||
<td mat-cell *matCellDef="let reservation">{{ reservation.id }}</td> | ||
</ng-container> | ||
<ng-container matColumnDef="name"> | ||
<th mat-header-cell *matHeaderCellDef>Name</th> | ||
<td mat-cell *matCellDef="let reservation"> | ||
{{ reservation.users[0].first_name }} | ||
{{ reservation.users[0].last_name }} | ||
</td> | ||
</ng-container> | ||
<ng-container matColumnDef="date"> | ||
<th mat-header-cell *matHeaderCellDef>Date</th> | ||
<td mat-cell *matCellDef="let reservation"> | ||
{{ reservation.start | date: 'dd MMM yyyy' }} | ||
</td> | ||
</ng-container> | ||
<ng-container matColumnDef="start"> | ||
<th mat-header-cell *matHeaderCellDef>Start</th> | ||
<td mat-cell *matCellDef="let reservation"> | ||
{{ reservation.start | date: 'shortTime' }} | ||
</td> | ||
</ng-container> | ||
<ng-container matColumnDef="end"> | ||
<th mat-header-cell *matHeaderCellDef>End</th> | ||
<td mat-cell *matCellDef="let reservation"> | ||
{{ reservation.end | date: 'shortTime' }} | ||
</td> | ||
</ng-container> | ||
<ng-container matColumnDef="room"> | ||
<th mat-header-cell *matHeaderCellDef>Room</th> | ||
<td mat-cell *matCellDef="let reservation"> | ||
{{ reservation.room.id }} | ||
</td> | ||
</ng-container> | ||
<ng-container matColumnDef="actions"> | ||
<th mat-header-cell *matHeaderCellDef>Actions</th> | ||
<td mat-cell *matCellDef="let reservation"> | ||
<button | ||
mat-flat-button | ||
(click)="this.ambassadorService.checkIn(reservation)" | ||
[disabled]="this.ambassadorService.isCheckInDisabled(reservation)"> | ||
Check-in | ||
</button> | ||
<button | ||
mat-flat-button | ||
class="tertiary-button" | ||
(click)="this.ambassadorService.cancel(reservation)"> | ||
Cancel | ||
</button> | ||
</td> | ||
</ng-container> | ||
<tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr> | ||
<tr mat-row *matRowDef="let reservation; columns: columnsToDisplay"></tr> | ||
</table> | ||
</mat-card-content> | ||
</mat-pane> | ||
} @else { | ||
<mat-pane class="content" appearance="outlined"> | ||
<mat-card-header> | ||
<mat-card-title>Upcoming Reservations</mat-card-title> | ||
</mat-card-header> | ||
<mat-card-content><p>No upcoming reservations.</p></mat-card-content> | ||
</mat-pane> | ||
} } @if(activeReservations()) { @if(activeReservations().length > 0) { | ||
<mat-pane class="content" appearance="outlined"> | ||
<mat-card-header> | ||
<mat-card-title>Active Reservations</mat-card-title> | ||
</mat-card-header> | ||
<mat-card-content> | ||
<table mat-table [dataSource]="activeReservations()"> | ||
<ng-container matColumnDef="id"> | ||
<th mat-header-cell *matHeaderCellDef>ID</th> | ||
<td mat-cell *matCellDef="let reservation">{{ reservation.id }}</td> | ||
</ng-container> | ||
<ng-container matColumnDef="name"> | ||
<th mat-header-cell *matHeaderCellDef>Name</th> | ||
<td mat-cell *matCellDef="let reservation"> | ||
{{ reservation.users[0].first_name }} | ||
{{ reservation.users[0].last_name }} | ||
</td> | ||
</ng-container> | ||
<ng-container matColumnDef="date"> | ||
<th mat-header-cell *matHeaderCellDef>Date</th> | ||
<td mat-cell *matCellDef="let reservation"> | ||
{{ reservation.start | date: 'dd MMM yyyy' }} | ||
</td> | ||
</ng-container> | ||
<ng-container matColumnDef="start"> | ||
<th mat-header-cell *matHeaderCellDef>Start</th> | ||
<td mat-cell *matCellDef="let reservation"> | ||
{{ reservation.start | date: 'shortTime' }} | ||
</td> | ||
</ng-container> | ||
<ng-container matColumnDef="end"> | ||
<th mat-header-cell *matHeaderCellDef>End</th> | ||
<td mat-cell *matCellDef="let reservation"> | ||
{{ reservation.end | date: 'shortTime' }} | ||
</td> | ||
</ng-container> | ||
<ng-container matColumnDef="room"> | ||
<th mat-header-cell *matHeaderCellDef>Room</th> | ||
<td mat-cell *matCellDef="let reservation"> | ||
{{ reservation.room.id }} | ||
</td> | ||
</ng-container> | ||
<ng-container matColumnDef="actions"> | ||
<th mat-header-cell *matHeaderCellDef>Actions</th> | ||
<td mat-cell *matCellDef="let reservation"> | ||
<button | ||
mat-flat-button | ||
class="tertiary-button" | ||
(click)="this.ambassadorService.checkOut(reservation)"> | ||
Check Out | ||
</button> | ||
</td> | ||
</ng-container> | ||
<tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr> | ||
<tr mat-row *matRowDef="let reservation; columns: columnsToDisplay"></tr> | ||
</table> | ||
</mat-card-content> | ||
</mat-pane> | ||
} @else { | ||
<mat-pane class="content" appearance="outlined"> | ||
<mat-card-header> | ||
<mat-card-title>Active Reservations</mat-card-title> | ||
</mat-card-header> | ||
<mat-card-content><p>It's lonely in here.</p></mat-card-content> | ||
</mat-pane> | ||
} } |
54 changes: 54 additions & 0 deletions
54
frontend/src/app/coworking/ambassador-home/ambassador-room/ambassador-room.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/** | ||
* @author Kris Jordan <[email protected]>, Ajay Gandecha <[email protected]> | ||
* @copyright 2023 - 2024 | ||
* @license MIT | ||
*/ | ||
|
||
import { Component, OnDestroy, OnInit, computed } from '@angular/core'; | ||
import { Route } from '@angular/router'; | ||
import { Subscription, timer, tap } from 'rxjs'; | ||
import { permissionGuard } from 'src/app/permission.guard'; | ||
import { AmbassadorRoomService } from './ambassador-room.service'; | ||
|
||
@Component({ | ||
selector: 'app-ambassador-room', | ||
templateUrl: './ambassador-room.component.html', | ||
styleUrls: ['./ambassador-room.component.css'] | ||
}) | ||
export class AmbassadorRoomComponent implements OnInit, OnDestroy { | ||
public static Route: Route = { | ||
path: 'room', | ||
component: AmbassadorRoomComponent, | ||
title: 'Room Reservations', | ||
canActivate: [permissionGuard('coworking.reservation.*', '*')], | ||
resolve: {} | ||
}; | ||
|
||
upcomingReservations = computed(() => { | ||
return this.ambassadorService.reservations().filter((r) => { | ||
return r.state == 'CONFIRMED'; | ||
}); | ||
}); | ||
|
||
activeReservations = computed(() => { | ||
return this.ambassadorService.reservations().filter((r) => { | ||
return r.state == 'CHECKED_IN'; | ||
}); | ||
}); | ||
|
||
columnsToDisplay = ['id', 'name', 'room', 'date', 'start', 'end', 'actions']; | ||
|
||
private refreshSubscription!: Subscription; | ||
|
||
constructor(public ambassadorService: AmbassadorRoomService) {} | ||
|
||
ngOnInit(): void { | ||
this.refreshSubscription = timer(0, 5000) | ||
.pipe(tap((_) => this.ambassadorService.fetchReservations())) | ||
.subscribe(); | ||
} | ||
|
||
ngOnDestroy(): void { | ||
this.refreshSubscription.unsubscribe(); | ||
} | ||
} |
16 changes: 0 additions & 16 deletions
16
frontend/src/app/coworking/ambassador-home/ambassador-room/ambassador-room.service.spec.ts
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,31 @@ | ||
/** | ||
* @author Kris Jordan <[email protected]>, Ajay Gandecha <[email protected]> | ||
* @copyright 2023 - 2024 | ||
* @license MIT | ||
*/ | ||
|
||
import { HttpClient } from '@angular/common/http'; | ||
import { Injectable } from '@angular/core'; | ||
import { Observable } from 'rxjs'; | ||
import { Injectable, WritableSignal, signal } from '@angular/core'; | ||
import { | ||
Reservation, | ||
ReservationJSON, | ||
parseReservationJSON | ||
} from '../../coworking.models'; | ||
import { RxReservations } from '../rx-reservations'; | ||
|
||
@Injectable({ | ||
providedIn: 'root' | ||
}) | ||
export class AmbassadorRoomService { | ||
private reservations: RxReservations = new RxReservations(); | ||
public reservations$: Observable<Reservation[]> = this.reservations.value$; | ||
private reservationsSignal: WritableSignal<Reservation[]> = signal([]); | ||
public reservations = this.reservationsSignal.asReadonly(); | ||
|
||
constructor(private http: HttpClient) {} | ||
|
||
fetchReservations(): void { | ||
this.http | ||
.get<ReservationJSON[]>('/api/coworking/ambassador/rooms') | ||
.subscribe((reservations) => { | ||
this.reservations.set(reservations.map(parseReservationJSON)); | ||
this.reservationsSignal.set(reservations.map(parseReservationJSON)); | ||
}); | ||
} | ||
|
||
|
@@ -37,10 +41,8 @@ export class AmbassadorRoomService { | |
id: reservation.id, | ||
state: 'CHECKED_IN' | ||
}) | ||
.subscribe((reservationJson) => { | ||
this.reservations.updateReservation( | ||
parseReservationJSON(reservationJson) | ||
); | ||
.subscribe((_) => { | ||
this.fetchReservations(); | ||
}); | ||
} | ||
|
||
|
@@ -50,10 +52,8 @@ export class AmbassadorRoomService { | |
id: reservation.id, | ||
state: 'CHECKED_OUT' | ||
}) | ||
.subscribe((reservationJson) => { | ||
this.reservations.updateReservation( | ||
parseReservationJSON(reservationJson) | ||
); | ||
.subscribe((_) => { | ||
this.fetchReservations(); | ||
}); | ||
} | ||
|
||
|
@@ -65,7 +65,7 @@ export class AmbassadorRoomService { | |
}) | ||
.subscribe({ | ||
next: (_) => { | ||
this.reservations.remove(reservation); | ||
this.fetchReservations(); | ||
}, | ||
error: (err) => { | ||
alert(err); | ||
|
Oops, something went wrong.