diff --git a/frontend/angular.json b/frontend/angular.json
index bbc0f0c..8e00b53 100644
--- a/frontend/angular.json
+++ b/frontend/angular.json
@@ -25,7 +25,7 @@
"tsConfig": "src/tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": ["src/favicon.ico", "src/assets"],
- "styles": ["src/styles.scss", "src/colors.scss"],
+ "styles": ["src/styles.scss"],
"scripts": []
},
"configurations": {
diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.html b/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.html
index 5ee024a..f1918a9 100644
--- a/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.html
+++ b/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.html
@@ -1 +1,127 @@
-
+
+
+ @if (isLoading()) {
+
+ } @else {
+
+
+
+
+
+ palette
+
+ Appearance
+ Configure custom appearance for your rooms
+
+
+
+
+
+
+ @if (isThemeEnabled) {
+
+
+
+
+
+ }
+
+
+ }
+
diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.scss b/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.scss
index e69de29..d1d0c89 100644
--- a/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.scss
+++ b/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.scss
@@ -0,0 +1,204 @@
+@import '../../../../../../../src/assets/styles/design-tokens';
+
+.ov-page-container {
+ button {
+ padding: var(--ov-meet-button-padding-vertical) var(--ov-meet-button-padding-horizontal);
+ }
+}
+
+// Theme Configuration Section
+.theme-config-card {
+ .theme-form {
+ @extend .ov-settings-form-section;
+
+ .full-width {
+ width: 100%;
+ }
+
+ .section-title {
+ margin: 0;
+ }
+
+ .theme-toggle {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 var(--ov-meet-spacing-md) var(--ov-meet-spacing-md) 0;
+
+ ::ng-deep button {
+ padding: 0 !important;
+ }
+ }
+
+ // Input field styling
+ .mat-mdc-form-field {
+ margin-bottom: var(--ov-meet-spacing-lg);
+
+ ::ng-deep .mat-mdc-text-field-wrapper {
+ background-color: var(--ov-meet-surface-variant);
+ border-radius: var(--ov-meet-border-radius-sm);
+ }
+
+ ::ng-deep .mdc-notched-outline__leading,
+ ::ng-deep .mdc-notched-outline__notch,
+ ::ng-deep .mdc-notched-outline__trailing {
+ border-color: var(--ov-meet-border-color);
+ }
+ }
+
+ // Color picker grid layout - responsive and clean
+ .color-picker-grid {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: var(--ov-meet-spacing-xl);
+ margin: var(--ov-meet-spacing-lg) 0;
+
+ // Tablet and larger - maintain 4 columns
+ @include ov-tablet-up {
+ gap: var(--ov-meet-spacing-xxl);
+ }
+
+ // Small tablets - 2 columns
+ @include ov-tablet-down {
+ grid-template-columns: repeat(2, 1fr);
+ gap: var(--ov-meet-spacing-lg);
+ }
+
+ // Mobile - single column
+ @include ov-mobile-down {
+ grid-template-columns: 1fr;
+ gap: var(--ov-meet-spacing-md);
+ }
+ }
+
+ .color-picker-item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: var(--ov-meet-spacing-sm);
+ cursor: pointer;
+ transition:
+ transform 0.2s ease,
+ opacity 0.2s ease;
+
+ &:hover {
+ transform: translateY(-2px);
+ // opacity: 0.9;
+ }
+
+ &:active {
+ transform: translateY(0);
+ }
+
+ .color-label {
+ font-size: 0.875rem;
+ font-weight: 500;
+ color: var(--ov-meet-text-color-primary);
+ text-align: center;
+ margin-bottom: var(--ov-meet-spacing-xs);
+ user-select: none;
+ }
+
+ .color-circle-wrapper {
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ .color-input {
+ position: absolute;
+ opacity: 0;
+ width: 80px;
+ height: 80px;
+ cursor: pointer;
+ border: none;
+ background: none;
+ z-index: 2;
+
+ // &::-webkit-color-swatch-wrapper {
+ // padding: 0;
+ // border: none;
+ // border-radius: 50%;
+ // }
+
+ // &::-webkit-color-swatch {
+ // border: none;
+ // border-radius: 50%;
+ // }
+
+ // &::-moz-color-swatch {
+ // border: none;
+ // border-radius: 50%;
+ // }
+ }
+
+ .color-circle {
+ width: 80px;
+ height: 80px;
+ border-radius: var(--ov-meet-radius-lg);
+ border: 3px solid var(--ov-meet-border-color);
+ position: relative;
+ z-index: 1;
+ }
+ }
+ }
+
+ // Reset colors section
+ .reset-colors-section {
+ display: flex;
+ justify-content: center;
+ margin-top: var(--ov-meet-spacing-lg);
+ padding-top: var(--ov-meet-spacing-lg);
+ border-top: 1px solid var(--ov-meet-border-color);
+
+ .reset-colors-btn {
+ display: flex;
+ align-items: center;
+ gap: var(--ov-meet-spacing-xs);
+ font-size: 0.875rem;
+ color: var(--ov-meet-text-color-secondary);
+ border-color: var(--ov-meet-border-color);
+
+ &:hover {
+ color: var(--ov-meet-color-error);
+ border-color: var(--ov-meet-color-error);
+ }
+
+ mat-icon {
+ font-size: 18px;
+ width: 18px;
+ height: 18px;
+ }
+ }
+ }
+ }
+}
+
+// Card Actions - responsive button layout
+.mat-mdc-card-actions {
+ padding: var(--ov-meet-spacing-lg) var(--ov-meet-spacing-xl);
+ gap: var(--ov-meet-spacing-sm);
+ border-top: 1px solid var(--ov-meet-border-color);
+ margin: auto;
+ display: flex;
+ flex-wrap: wrap;
+
+ @include ov-mobile-down {
+ flex-direction: column;
+
+ .mat-mdc-button,
+ .mat-mdc-raised-button,
+ .mat-mdc-stroked-button {
+ width: 100%;
+ margin: var(--ov-meet-spacing-xs) 0;
+ }
+ }
+
+ @include ov-tablet-up {
+ justify-content: flex-start;
+
+ button:first-child {
+ margin-right: auto;
+ }
+ }
+}
diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.ts b/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.ts
index 7335c28..6e9a659 100644
--- a/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.ts
+++ b/frontend/projects/shared-meet-components/src/lib/pages/console/config/config.component.ts
@@ -1,12 +1,246 @@
-import { Component } from '@angular/core';
+import { Component, OnInit, signal } from '@angular/core';
+import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
+import { MatButtonModule } from '@angular/material/button';
+import { MatCardModule } from '@angular/material/card';
+import { MatDividerModule } from '@angular/material/divider';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatIconModule } from '@angular/material/icon';
+import { MatInputModule } from '@angular/material/input';
+import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
+import { MatSelectModule } from '@angular/material/select';
+import { MatSlideToggleModule } from '@angular/material/slide-toggle';
+import { MatTooltipModule } from '@angular/material/tooltip';
+import { GlobalConfigService, NotificationService } from '@lib/services';
+import { MeetAppearanceConfig, MeetRoomTheme, MeetRoomThemeMode } from '@lib/typings/ce';
+import {
+ OPENVIDU_COMPONENTS_DARK_THEME,
+ OPENVIDU_COMPONENTS_LIGHT_THEME,
+ OpenViduThemeService
+} from 'openvidu-components-angular';
+
+type ColorField = 'backgroundColor' | 'primaryColor' | 'secondaryColor' | 'surfaceColor';
+
+interface ThemeColors {
+ backgroundColor: string;
+ primaryColor: string;
+ secondaryColor: string;
+ surfaceColor: string;
+}
@Component({
- selector: 'ov-config',
- standalone: true,
- imports: [],
- templateUrl: './config.component.html',
- styleUrl: './config.component.scss'
+ selector: 'ov-config',
+ standalone: true,
+ imports: [
+ MatCardModule,
+ MatButtonModule,
+ MatIconModule,
+ MatInputModule,
+ MatFormFieldModule,
+ MatSelectModule,
+ MatSlideToggleModule,
+ MatTooltipModule,
+ MatProgressSpinnerModule,
+ MatDividerModule,
+ ReactiveFormsModule
+ ],
+ templateUrl: './config.component.html',
+ styleUrl: './config.component.scss'
})
-export class ConfigComponent {
+export class ConfigComponent implements OnInit {
+ isLoading = signal(true);
+ hasChanges = signal(false);
+ appearanceForm = new FormGroup({
+ enabled: new FormControl