diff --git a/frontend/projects/shared-meet-components/src/lib/guards/validate-access.guard.ts b/frontend/projects/shared-meet-components/src/lib/guards/validate-access.guard.ts
index ba50629..b49712c 100644
--- a/frontend/projects/shared-meet-components/src/lib/guards/validate-access.guard.ts
+++ b/frontend/projects/shared-meet-components/src/lib/guards/validate-access.guard.ts
@@ -32,6 +32,9 @@ export const validateRoomAccessGuard: CanActivateFn = async (
case 404:
// Room not found
return navigationService.redirectToErrorPage(ErrorReason.INVALID_ROOM);
+ case 409:
+ // Room is closed
+ return navigationService.redirectToErrorPage(ErrorReason.CLOSED_ROOM);
default:
return navigationService.redirectToErrorPage(ErrorReason.INTERNAL_ERROR);
}
diff --git a/frontend/projects/shared-meet-components/src/lib/models/navigation.model.ts b/frontend/projects/shared-meet-components/src/lib/models/navigation.model.ts
index da76132..ab79518 100644
--- a/frontend/projects/shared-meet-components/src/lib/models/navigation.model.ts
+++ b/frontend/projects/shared-meet-components/src/lib/models/navigation.model.ts
@@ -1,4 +1,5 @@
export enum ErrorReason {
+ CLOSED_ROOM = 'closed-room',
MISSING_ROOM_SECRET = 'missing-room-secret',
MISSING_RECORDING_SECRET = 'missing-recording-secret',
INVALID_ROOM_SECRET = 'invalid-room-secret',
diff --git a/frontend/projects/shared-meet-components/src/lib/pages/error/error.component.ts b/frontend/projects/shared-meet-components/src/lib/pages/error/error.component.ts
index 7fe0f68..492bdfb 100644
--- a/frontend/projects/shared-meet-components/src/lib/pages/error/error.component.ts
+++ b/frontend/projects/shared-meet-components/src/lib/pages/error/error.component.ts
@@ -50,6 +50,10 @@ export class ErrorComponent implements OnInit {
*/
private mapReasonToNameAndMessage(reason: string): { title: string; message: string } {
const reasonMap: { [key in ErrorReason]: { title: string; message: string } } = {
+ [ErrorReason.CLOSED_ROOM]: {
+ title: 'Closed room',
+ message: 'The room you are trying to access is closed'
+ },
[ErrorReason.MISSING_ROOM_SECRET]: {
title: 'Missing secret',
message: 'You need to provide a secret to join the room as a moderator or speaker'
diff --git a/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.html b/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.html
index acbaa85..d288e55 100644
--- a/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.html
+++ b/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.html
@@ -215,12 +215,16 @@
-
+
@@ -250,7 +254,7 @@
id="participant-name-submit"
type="submit"
class="join-button"
- [disabled]="participantForm.invalid"
+ [disabled]="participantForm.invalid || roomClosed"
>
Join Meeting
diff --git a/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.scss b/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.scss
index 4f1e2bb..76e1bbb 100644
--- a/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.scss
+++ b/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.scss
@@ -133,6 +133,16 @@
background: linear-gradient(135deg, var(--ov-meet-surface-color) 0%, var(--ov-meet-color-primary-light) 180%);
color: var(--ov-meet-text-on-primary);
}
+
+ &.room-closed-card {
+ .card-header {
+ background: linear-gradient(135deg, var(--ov-meet-surface-color) 0%, var(--ov-meet-color-warning) 180%);
+
+ .mat-icon {
+ color: var(--ov-meet-color-warning) !important;
+ }
+ }
+ }
}
// Secondary Card - Recordings styling
diff --git a/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.ts b/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.ts
index 1911767..ef3a288 100644
--- a/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.ts
+++ b/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.ts
@@ -1,4 +1,5 @@
import { Clipboard } from '@angular/cdk/clipboard';
+import { CommonModule } from '@angular/common';
import { Component, OnInit, Signal } from '@angular/core';
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { MatButtonModule, MatIconButton } from '@angular/material/button';
@@ -31,6 +32,7 @@ import {
import {
LeftEventReason,
MeetRoom,
+ MeetRoomStatus,
ParticipantRole,
WebComponentEvent,
WebComponentOutboundEventMessage
@@ -65,6 +67,7 @@ import { Subject, takeUntil } from 'rxjs';
imports: [
OpenViduComponentsUiModule,
ApiDirectiveModule,
+ CommonModule,
MatFormFieldModule,
MatInputModule,
FormsModule,
@@ -87,6 +90,7 @@ export class MeetingComponent implements OnInit {
hasRecordings = false;
showRecordingCard = false;
+ roomClosed = false;
showBackButton = true;
backButtonText = 'Back';
@@ -137,6 +141,7 @@ export class MeetingComponent implements OnInit {
this.roomId = this.roomService.getRoomId();
this.roomSecret = this.roomService.getRoomSecret();
this.room = await this.roomService.getRoom(this.roomId);
+ this.roomClosed = this.room.status === MeetRoomStatus.CLOSED;
await this.setBackButtonText();
await this.checkForRecordings();
@@ -218,6 +223,11 @@ export class MeetingComponent implements OnInit {
if (participantName) {
this.participantForm.get('name')?.setValue(participantName);
}
+
+ // Disable the form if the room is closed
+ if (this.roomClosed) {
+ this.participantForm.disable();
+ }
}
async goToRecordings() {
@@ -309,6 +319,10 @@ export class MeetingComponent implements OnInit {
// Room not found
await this.navigationService.redirectToErrorPage(ErrorReason.INVALID_ROOM, true);
break;
+ case 409:
+ // Room is closed
+ await this.navigationService.redirectToErrorPage(ErrorReason.CLOSED_ROOM, true);
+ break;
default:
await this.navigationService.redirectToErrorPage(ErrorReason.INTERNAL_ERROR, true);
}