From 275d15f68f38c842fac3f618daeb752120bc695f Mon Sep 17 00:00:00 2001 From: Carlos Santos <4a.santos@gmail.com> Date: Thu, 24 Jul 2025 17:33:48 +0200 Subject: [PATCH] frontend: add loading state for room creation with spinner and loading messages --- .../room-wizard/room-wizard.component.html | 54 ++++++++++---- .../room-wizard/room-wizard.component.scss | 73 +++++++++++++++++++ .../room-wizard/room-wizard.component.ts | 22 ++++-- 3 files changed, 128 insertions(+), 21 deletions(-) diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.html b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.html index b689b13..b76796e 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.html +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.html @@ -18,21 +18,45 @@
- @switch (currentStep()?.id) { - @case ('basic') { - - } - @case ('recording') { - - } - @case ('recordingTrigger') { - - } - @case ('recordingLayout') { - - } - @case ('preferences') { - + @if (isCreatingRoom()) { + +
+
+
+
+ video_chat +

{{ editMode ? 'Updating Room' : 'Creating Room' }}

+
+

+ {{ + editMode + ? 'Please wait while we update your room settings...' + : 'Please wait while we set up your video room...' + }} +

+
+
+ +
+
+
+ } @else { + @switch (currentStep()?.id) { + @case ('basic') { + + } + @case ('recording') { + + } + @case ('recordingTrigger') { + + } + @case ('recordingLayout') { + + } + @case ('preferences') { + + } } }
diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.scss b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.scss index ce1bbcc..d50b069 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.scss +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.scss @@ -77,6 +77,65 @@ } } +// Room Creation Loading State +.room-creation-loading { + @include ov-flex-center; + flex-direction: column; + height: 100%; + min-height: 400px; + text-align: center; + padding: var(--ov-meet-spacing-xl); + + .loading-content { + @include ov-flex-center; + flex-direction: column; + gap: var(--ov-meet-spacing-xl); + width: 100%; + + .loading-header { + margin-bottom: var(--ov-meet-spacing-lg); + + .loading-title { + @include ov-flex-center; + gap: var(--ov-meet-spacing-md); + margin-bottom: var(--ov-meet-spacing-md); + + .loading-icon { + @include ov-icon(xl); + animation: pulse 2s ease-in-out infinite; + } + + h2 { + margin: 0; + font-size: var(--ov-meet-font-size-xl); + font-weight: var(--ov-meet-font-weight-medium); + color: var(--ov-meet-text-primary); + } + } + + .loading-subtitle { + font-size: var(--ov-meet-font-size-md); + color: var(--ov-meet-text-secondary); + margin: 0; + animation: fadeIn 1s ease-out 0.5s both; + } + } + + .loading-spinner-container { + mat-spinner { + margin: 0 auto; + + ::ng-deep { + .mdc-circular-progress__determinate-circle, + .mdc-circular-progress__indeterminate-circle-graphic { + stroke: var(--ov-meet-color-primary); + } + } + } + } + } +} + // Responsive design using the system mixins @include ov-tablet-down { .wizard-container { @@ -90,6 +149,20 @@ font-size: var(--ov-meet-font-size-xl); } } + + .room-creation-loading { + padding: var(--ov-meet-spacing-lg); + + .loading-content { + .loading-header { + .loading-title { + h2 { + font-size: var(--ov-meet-font-size-lg); + } + } + } + } + } } @include ov-mobile-down { diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.ts b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.ts index c417c08..a4d82ac 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.ts +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.ts @@ -1,10 +1,11 @@ import { CommonModule } from '@angular/common'; -import { Component, computed, OnInit, Signal } from '@angular/core'; +import { Component, computed, OnInit, Signal, signal } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { MatIconModule } from '@angular/material/icon'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSlideToggleModule } from '@angular/material/slide-toggle'; import { ActivatedRoute } from '@angular/router'; -import { StepIndicatorComponent, WizardNavComponent } from '@lib/components'; +import { SpinnerComponent, StepIndicatorComponent, WizardNavComponent } from '@lib/components'; import { WizardNavigationConfig, WizardStep } from '@lib/models'; import { NavigationService, NotificationService, RoomService, RoomWizardStateService } from '@lib/services'; import { MeetRoomOptions } from '@lib/typings/ce'; @@ -21,8 +22,10 @@ import { RoomPreferencesComponent } from './steps/room-preferences/room-preferen CommonModule, StepIndicatorComponent, WizardNavComponent, + SpinnerComponent, MatButtonModule, MatIconModule, + MatProgressSpinnerModule, MatSlideToggleModule, RoomWizardBasicInfoComponent, RecordingPreferencesComponent, @@ -37,6 +40,7 @@ export class RoomWizardComponent implements OnInit { editMode: boolean = false; roomId?: string; existingRoomData?: MeetRoomOptions; + isCreatingRoom = signal(false); steps: Signal; currentStep: Signal; @@ -114,21 +118,27 @@ export class RoomWizardComponent implements OnInit { const roomOptions = this.wizardService.roomOptions(); console.log('Wizard completed with data:', roomOptions); + // Activate loading state + this.isCreatingRoom.set(true); + try { if (this.editMode && this.roomId && roomOptions.preferences) { await this.roomService.updateRoom(this.roomId, roomOptions.preferences); + await this.navigationService.navigateTo('rooms', undefined, true); this.notificationService.showSnackbar('Room updated successfully'); } else { // Create new room - await this.roomService.createRoom(roomOptions); - this.notificationService.showSnackbar('Room created successfully'); + const { moderatorRoomUrl } = await this.roomService.createRoom(roomOptions); + await this.navigationService.redirectTo(moderatorRoomUrl); } - - await this.navigationService.navigateTo('rooms', undefined, true); } catch (error) { const errorMessage = `Failed to ${this.editMode ? 'update' : 'create'} room`; this.notificationService.showSnackbar(errorMessage); console.error(errorMessage, error); + } finally { + this.wizardService.resetWizard(); + // Deactivate loading state + this.isCreatingRoom.set(false); } } }