tickera-angular-components 0.0.1-dev.4 → 0.0.1-dev.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,41 +1,204 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, makeEnvironmentProviders, PLATFORM_ID, Inject, Injectable, signal, LOCALE_ID, computed, inject, EventEmitter, Input, Output, ViewEncapsulation, Component, Self, Optional, Injector, HostListener, forwardRef, effect, ViewChild } from '@angular/core';
2
+ import { InjectionToken, makeEnvironmentProviders, PLATFORM_ID, Inject, Injectable, signal, LOCALE_ID, computed, inject, EventEmitter, Input, Output, Component, ViewEncapsulation, Self, Optional, Injector, HostListener, forwardRef, effect, ViewChild } from '@angular/core';
3
+ import * as i2$1 from '@jsverse/transloco';
4
+ import { provideTransloco, TranslocoModule } from '@jsverse/transloco';
5
+ import { from, throwError, BehaviorSubject, Subject, of } from 'rxjs';
3
6
  import * as i1 from '@angular/common/http';
4
7
  import { HttpHeaders } from '@angular/common/http';
5
- import { throwError, BehaviorSubject, Subject, of } from 'rxjs';
6
8
  import { catchError, distinctUntilChanged, debounceTime, switchMap, takeUntil, map } from 'rxjs/operators';
7
- import * as i2$1 from '@angular/common';
9
+ import * as i2 from '@angular/common';
8
10
  import { isPlatformBrowser, formatDate, CommonModule, DatePipe } from '@angular/common';
9
11
  import { toast } from 'ngx-sonner';
10
12
  import { toObservable } from '@angular/core/rxjs-interop';
11
- import * as i2 from '@jsverse/transloco';
12
- import { TranslocoModule } from '@jsverse/transloco';
13
13
  import * as i3 from '@angular/router';
14
- import { RouterLink } from '@angular/router';
14
+ import { RouterLink, RouterModule } from '@angular/router';
15
15
  import * as i1$1 from '@angular/forms';
16
16
  import { FormsModule, ReactiveFormsModule, Validators, NgControl, NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
17
17
  import { DEFAULT_TOOLBAR, Editor, toHTML, NgxEditorComponent, NgxEditorMenuComponent } from 'ngx-editor';
18
18
  import * as i2$2 from '@ng-select/ng-select';
19
19
  import { NgSelectModule } from '@ng-select/ng-select';
20
20
 
21
+ var formErrors$1 = {
22
+ required: "Este campo es requerido",
23
+ minlength: "Debe tener al menos {{minLength}} caracteres",
24
+ maxlength: "No debe exceder {{maxLength}} caracteres",
25
+ pattern: "El formato no es válido",
26
+ email: "El formato no es válido",
27
+ mustMatch: "Las contraseñas no coinciden",
28
+ invalidField: "Campo inválido",
29
+ invalidSelection: "Selección inválida"
30
+ };
31
+ var common$1 = {
32
+ selectOption: "Seleccionar opción"
33
+ };
34
+ var fileUpload$1 = {
35
+ dropSingle: "Arrastra y suelta un archivo aquí, o haz clic para seleccionar",
36
+ dropMultiple: "Arrastra y suelta archivos aquí, o haz clic para seleccionar",
37
+ allowedExtensions: "Extensiones permitidas:",
38
+ maxSize: "Tamaño máximo:",
39
+ sizeError: "El archivo {{fileName}} excede el tamaño máximo de {{maxSize}} MB",
40
+ extensionError: "El archivo {{fileName}} no tiene una extensión permitida. Use: {{extensions}}",
41
+ fileTypeImages: "Imágenes",
42
+ fileTypeExcel: "Excel",
43
+ fileTypeWord: "Word",
44
+ fileTypeText: "Texto",
45
+ fileTypeOther: "Otro"
46
+ };
47
+ var deleteConfirmation$1 = {
48
+ warning: "¿Estás seguro de que deseas eliminar este elemento?",
49
+ instructions: "Escriba <strong>eliminar</strong> para confirmar",
50
+ placeholder: "Escriba eliminar",
51
+ cancel: "Cancelar",
52
+ "delete": "Eliminar"
53
+ };
54
+ var changePassword$1 = {
55
+ title: "Cambiar contraseña",
56
+ newPasswordLabel: "Nueva contraseña",
57
+ newPasswordPlaceholder: "Ingrese la nueva contraseña",
58
+ confirmPasswordLabel: "Confirmar contraseña",
59
+ confirmPasswordPlaceholder: "Confirme la nueva contraseña",
60
+ cancel: "Cancelar",
61
+ save: "Guardar",
62
+ saving: "Guardando..."
63
+ };
64
+ var es = {
65
+ formErrors: formErrors$1,
66
+ common: common$1,
67
+ fileUpload: fileUpload$1,
68
+ deleteConfirmation: deleteConfirmation$1,
69
+ changePassword: changePassword$1
70
+ };
71
+
72
+ var formErrors = {
73
+ required: "This field is required",
74
+ minlength: "Must be at least {{minLength}} characters",
75
+ maxlength: "Must not exceed {{maxLength}} characters",
76
+ pattern: "Invalid format",
77
+ email: "Invalid format",
78
+ mustMatch: "Passwords do not match",
79
+ invalidField: "Invalid field",
80
+ invalidSelection: "Invalid selection"
81
+ };
82
+ var common = {
83
+ selectOption: "Select option"
84
+ };
85
+ var fileUpload = {
86
+ dropSingle: "Drag and drop a file here, or click to select",
87
+ dropMultiple: "Drag and drop files here, or click to select",
88
+ allowedExtensions: "Allowed extensions:",
89
+ maxSize: "Maximum size:",
90
+ sizeError: "File {{fileName}} exceeds maximum size of {{maxSize}} MB",
91
+ extensionError: "File {{fileName}} has an invalid extension. Use: {{extensions}}",
92
+ fileTypeImages: "Images",
93
+ fileTypeExcel: "Excel",
94
+ fileTypeWord: "Word",
95
+ fileTypeText: "Text",
96
+ fileTypeOther: "Other"
97
+ };
98
+ var deleteConfirmation = {
99
+ warning: "Are you sure you want to delete this item?",
100
+ instructions: "Type <strong>delete</strong> to confirm",
101
+ placeholder: "Type delete",
102
+ cancel: "Cancel",
103
+ "delete": "Delete"
104
+ };
105
+ var changePassword = {
106
+ title: "Change password",
107
+ newPasswordLabel: "New password",
108
+ newPasswordPlaceholder: "Enter new password",
109
+ confirmPasswordLabel: "Confirm password",
110
+ confirmPasswordPlaceholder: "Confirm new password",
111
+ cancel: "Cancel",
112
+ save: "Save",
113
+ saving: "Saving..."
114
+ };
115
+ var en = {
116
+ formErrors: formErrors,
117
+ common: common,
118
+ fileUpload: fileUpload,
119
+ deleteConfirmation: deleteConfirmation,
120
+ changePassword: changePassword
121
+ };
122
+
123
+ const translations = {
124
+ es,
125
+ en,
126
+ };
127
+ class TickeraTranslocoLoader {
128
+ getTranslation(lang) {
129
+ const translation = translations[lang] || translations['es'];
130
+ return from(Promise.resolve(translation));
131
+ }
132
+ }
133
+
134
+ const STORAGE_KEY = 'tickera_lang';
135
+ const DEFAULT_LANG = 'es';
136
+ const AVAILABLE_LANGS = ['es', 'en'];
137
+ function getStoredLanguage() {
138
+ try {
139
+ const stored = localStorage.getItem(STORAGE_KEY);
140
+ if (stored && AVAILABLE_LANGS.includes(stored)) {
141
+ return stored;
142
+ }
143
+ }
144
+ catch {
145
+ // localStorage not available
146
+ }
147
+ return '';
148
+ }
149
+ function setStoredLanguage(lang) {
150
+ try {
151
+ localStorage.setItem(STORAGE_KEY, lang);
152
+ }
153
+ catch {
154
+ // localStorage not available
155
+ }
156
+ }
157
+ function getBrowserLanguage() {
158
+ const nav = typeof navigator !== 'undefined' ? navigator : null;
159
+ if (!nav)
160
+ return DEFAULT_LANG;
161
+ // Check navigator.language and navigator.languages
162
+ const browserLangs = nav.languages || [nav.language];
163
+ for (const lang of browserLangs) {
164
+ if (!lang)
165
+ continue;
166
+ // Exact match (e.g., "es", "en")
167
+ const shortLang = lang.split('-')[0].toLowerCase();
168
+ if (AVAILABLE_LANGS.includes(shortLang)) {
169
+ return shortLang;
170
+ }
171
+ }
172
+ return DEFAULT_LANG;
173
+ }
174
+ function resolveLanguage() {
175
+ // 1. Check localStorage first
176
+ const stored = getStoredLanguage();
177
+ if (stored)
178
+ return stored;
179
+ // 2. Detect from browser
180
+ return getBrowserLanguage();
181
+ }
182
+
21
183
  const TICKERA_COMPONENTS_CONFIG = new InjectionToken('TICKERA_COMPONENTS_CONFIG');
22
184
  function provideTickeraComponents(config) {
23
- return makeEnvironmentProviders([{ provide: TICKERA_COMPONENTS_CONFIG, useValue: config }]);
185
+ const defaultLang = config.defaultLang || 'es';
186
+ const availableLangs = config.availableLangs || ['es', 'en'];
187
+ const detectedLang = resolveLanguage();
188
+ return makeEnvironmentProviders([
189
+ { provide: TICKERA_COMPONENTS_CONFIG, useValue: config },
190
+ ...provideTransloco({
191
+ config: {
192
+ defaultLang: detectedLang,
193
+ availableLangs,
194
+ reRenderOnLangChange: true,
195
+ fallbackLang: defaultLang,
196
+ },
197
+ loader: TickeraTranslocoLoader,
198
+ }),
199
+ ]);
24
200
  }
25
201
 
26
- const ALERT_BASE_CLASSES = 'border rounded relative flex items-center gap-2 px-4 py-2';
27
- const ALERT_COLOR_CLASSES = {
28
- success: 'bg-green-100 border-green-400 text-green-700',
29
- error: 'bg-red-100 border-red-400 text-red-700',
30
- warning: 'bg-yellow-100 border-yellow-400 text-yellow-700',
31
- info: 'bg-blue-100 border-blue-400 text-blue-700',
32
- };
33
- const ALERT_SIZE_CLASSES = {
34
- xs: 'px-2 py-1 text-xs',
35
- sm: 'px-4 py-2 text-sm',
36
- md: 'px-6 py-3 text-base',
37
- lg: 'px-8 py-4 text-lg',
38
- };
39
202
  const ALERT_ICONS = {
40
203
  success: 'ri-check-line',
41
204
  error: 'ri-error-warning-line',
@@ -44,33 +207,18 @@ const ALERT_ICONS = {
44
207
  };
45
208
 
46
209
  const BUTTON_VARIANT_CLASSES = {
47
- primary: 'bg-red-600 hover:bg-red-700 focus:ring-red-500 text-white',
48
- secondary: 'bg-purple-600 hover:bg-purple-700 focus:ring-purple-500 text-white',
49
- terciary: 'bg-gray-500 hover:bg-gray-600 focus:ring-gray-500 text-white',
50
- success: 'bg-green-600 hover:bg-green-700 focus:ring-green-500 text-green-900',
51
- transparent: 'bg-transparent hover:bg-gray-100 focus:ring-gray-500 text-gray-700 ',
210
+ primary: 'btn-primary',
211
+ secondary: 'btn-secondary',
212
+ tertiary: 'btn-tertiary',
213
+ success: 'btn-success',
214
+ transparent: 'btn-transparent',
52
215
  };
53
- const BASE_BUTTON_CLASSES = [
54
- 'w-full',
55
- 'cursor-pointer',
56
- 'flex',
57
- 'justify-center',
58
- 'gap-2',
59
- 'border',
60
- 'border-transparent',
61
- 'rounded-md',
62
- 'font-medium',
63
- 'focus:outline-none',
64
- 'focus:ring-2',
65
- 'focus:ring-offset-2',
66
- 'disabled:opacity-50',
67
- 'disabled:cursor-not-allowed',
68
- ].join(' ');
216
+ const BASE_BUTTON_CLASSES = 'btn';
69
217
  const BUTTON_SIZES_CLASSES = {
70
- xs: 'text-xs py-1 px-2',
71
- sm: 'text-sm py-2 px-4',
72
- md: 'text-base py-3 px-6',
73
- lg: 'text-lg py-4 px-8',
218
+ xs: 'btn-xs',
219
+ sm: 'btn-sm',
220
+ md: 'btn-md',
221
+ lg: 'btn-lg',
74
222
  };
75
223
 
76
224
  const FORM_ERROR_MESSAGES = {
@@ -1233,18 +1381,22 @@ class AppButtonComponent {
1233
1381
  this.clicked.emit();
1234
1382
  }
1235
1383
  get buttonClasses() {
1236
- const disabledClasses = this.disabled ? 'opacity-50 cursor-not-allowed' : '';
1237
- const variantClasses = BUTTON_VARIANT_CLASSES[this.variant];
1238
- const loadingClasses = this.loading ? 'opacity-50 cursor-not-allowed' : '';
1239
- const sizeClasses = BUTTON_SIZES_CLASSES[this.size];
1240
- return `${BASE_BUTTON_CLASSES} ${disabledClasses} ${variantClasses} ${loadingClasses} ${sizeClasses}`;
1384
+ return [
1385
+ 'btn',
1386
+ `btn-${this.variant}`,
1387
+ `btn-${this.size}`,
1388
+ this.disabled ? 'btn-disabled' : '',
1389
+ this.loading ? 'btn-loading' : '',
1390
+ ]
1391
+ .filter(Boolean)
1392
+ .join(' ');
1241
1393
  }
1242
1394
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: AppButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1243
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: AppButtonComponent, isStandalone: true, selector: "app-button", inputs: { disabled: "disabled", loading: "loading", type: "type", variant: "variant", text: "text", size: "size", loadingText: "loadingText", icon: "icon" }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<button\n [type]=\"type\"\n [disabled]=\"loading || disabled\"\n class=\"{{ buttonClasses }}\"\n (click)=\"handleClick()\"\n>\n @if (icon && !loading) {\n <i class=\"{{ icon }}\"></i>\n }\n\n @if (loading) {\n <i class=\"ri-refresh-line animate-spin\"></i>\n }\n\n {{ loading ? loadingText : text }}\n</button>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }], encapsulation: i0.ViewEncapsulation.None });
1395
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: AppButtonComponent, isStandalone: true, selector: "app-button", inputs: { disabled: "disabled", loading: "loading", type: "type", variant: "variant", text: "text", size: "size", loadingText: "loadingText", icon: "icon" }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<button\n [type]=\"type\"\n [disabled]=\"loading || disabled\"\n [class]=\"buttonClasses\"\n (click)=\"handleClick()\"\n>\n @if (icon && !loading) {\n <i class=\"btn-icon\" [ngClass]=\"icon\"></i>\n }\n\n @if (loading) {\n <i class=\"btn-icon btn-icon-spin ri-refresh-line\"></i>\n }\n\n {{ loading ? loadingText : text }}\n</button>\n", styles: [":host{display:block;width:100%}.btn{width:100%;cursor:pointer;display:flex;justify-content:center;gap:.5rem;border:1px solid transparent;border-radius:.375rem;font-weight:500;outline:none}.btn:focus{box-shadow:0 0 0 2px #fff,0 0 0 4px #4f46e5}.btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.btn-primary{background-color:#dc2626;color:#fff}.btn-primary:hover:not(:disabled){background-color:#b91c1c}.btn-secondary{background-color:#7c3aed;color:#fff}.btn-secondary:hover:not(:disabled){background-color:#6d28d9}.btn-tertiary{background-color:#6b7280;color:#fff}.btn-tertiary:hover:not(:disabled){background-color:#4b5563}.btn-success{background-color:#16a34a;color:#14532d}.btn-success:hover:not(:disabled){background-color:#15803d}.btn-transparent{background-color:transparent;color:#374151}.btn-transparent:hover:not(:disabled){background-color:#f3f4f6}@media(prefers-color-scheme:dark){.btn-transparent{color:#d1d5db}.btn-transparent:hover:not(:disabled){background-color:#1f2937}}.btn-xs{font-size:.75rem;padding:.25rem .5rem}.btn-sm{font-size:.875rem;padding:.5rem 1rem}.btn-md{font-size:1rem;padding:.75rem 1.5rem}.btn-lg{font-size:1.125rem;padding:1rem 2rem}.btn-disabled,.btn-loading{opacity:.5;cursor:not-allowed;pointer-events:none}.btn-icon{display:inline-flex;align-items:center;justify-content:center}.btn-icon-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
1244
1396
  }
1245
1397
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: AppButtonComponent, decorators: [{
1246
1398
  type: Component,
1247
- args: [{ selector: 'app-button', standalone: true, imports: [CommonModule], encapsulation: ViewEncapsulation.None, template: "<button\n [type]=\"type\"\n [disabled]=\"loading || disabled\"\n class=\"{{ buttonClasses }}\"\n (click)=\"handleClick()\"\n>\n @if (icon && !loading) {\n <i class=\"{{ icon }}\"></i>\n }\n\n @if (loading) {\n <i class=\"ri-refresh-line animate-spin\"></i>\n }\n\n {{ loading ? loadingText : text }}\n</button>\n" }]
1399
+ args: [{ selector: 'app-button', standalone: true, imports: [CommonModule], template: "<button\n [type]=\"type\"\n [disabled]=\"loading || disabled\"\n [class]=\"buttonClasses\"\n (click)=\"handleClick()\"\n>\n @if (icon && !loading) {\n <i class=\"btn-icon\" [ngClass]=\"icon\"></i>\n }\n\n @if (loading) {\n <i class=\"btn-icon btn-icon-spin ri-refresh-line\"></i>\n }\n\n {{ loading ? loadingText : text }}\n</button>\n", styles: [":host{display:block;width:100%}.btn{width:100%;cursor:pointer;display:flex;justify-content:center;gap:.5rem;border:1px solid transparent;border-radius:.375rem;font-weight:500;outline:none}.btn:focus{box-shadow:0 0 0 2px #fff,0 0 0 4px #4f46e5}.btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.btn-primary{background-color:#dc2626;color:#fff}.btn-primary:hover:not(:disabled){background-color:#b91c1c}.btn-secondary{background-color:#7c3aed;color:#fff}.btn-secondary:hover:not(:disabled){background-color:#6d28d9}.btn-tertiary{background-color:#6b7280;color:#fff}.btn-tertiary:hover:not(:disabled){background-color:#4b5563}.btn-success{background-color:#16a34a;color:#14532d}.btn-success:hover:not(:disabled){background-color:#15803d}.btn-transparent{background-color:transparent;color:#374151}.btn-transparent:hover:not(:disabled){background-color:#f3f4f6}@media(prefers-color-scheme:dark){.btn-transparent{color:#d1d5db}.btn-transparent:hover:not(:disabled){background-color:#1f2937}}.btn-xs{font-size:.75rem;padding:.25rem .5rem}.btn-sm{font-size:.875rem;padding:.5rem 1rem}.btn-md{font-size:1rem;padding:.75rem 1.5rem}.btn-lg{font-size:1.125rem;padding:1rem 2rem}.btn-disabled,.btn-loading{opacity:.5;cursor:not-allowed;pointer-events:none}.btn-icon{display:inline-flex;align-items:center;justify-content:center}.btn-icon-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
1248
1400
  }], propDecorators: { clicked: [{
1249
1401
  type: Output
1250
1402
  }], disabled: [{
@@ -1266,7 +1418,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
1266
1418
  }] } });
1267
1419
 
1268
1420
  class AppLinkButtonComponent {
1269
- BASE_BUTTON_CLASSES = BASE_BUTTON_CLASSES;
1270
1421
  disabled = false;
1271
1422
  loading = false;
1272
1423
  target = '_self';
@@ -1278,18 +1429,22 @@ class AppLinkButtonComponent {
1278
1429
  size = 'md';
1279
1430
  variant = 'primary';
1280
1431
  get buttonClasses() {
1281
- const disabledClasses = this.disabled ? 'opacity-50 cursor-not-allowed' : '';
1282
- const variantClasses = BUTTON_VARIANT_CLASSES[this.variant];
1283
- const loadingClasses = this.loading ? 'opacity-50 cursor-not-allowed' : '';
1284
- const sizeClasses = BUTTON_SIZES_CLASSES[this.size] || 'text-base';
1285
- return [BASE_BUTTON_CLASSES, disabledClasses, variantClasses, loadingClasses, sizeClasses].join(' ');
1432
+ return [
1433
+ 'btn',
1434
+ `btn-${this.variant}`,
1435
+ `btn-${this.size}`,
1436
+ this.disabled ? 'btn-disabled' : '',
1437
+ this.loading ? 'btn-loading' : '',
1438
+ ]
1439
+ .filter(Boolean)
1440
+ .join(' ');
1286
1441
  }
1287
1442
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: AppLinkButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1288
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: AppLinkButtonComponent, isStandalone: true, selector: "app-link-button", inputs: { disabled: "disabled", loading: "loading", target: "target", text: "text", icon: "icon", loadingText: "loadingText", route: "route", queryParams: "queryParams", size: "size", variant: "variant" }, ngImport: i0, template: "<a\n class=\"{{ buttonClasses }}\"\n [routerLink]=\"!disabled ? route : null\"\n [queryParams]=\"queryParams\"\n [target]=\"target\"\n>\n @if (icon) {\n <i [class]=\"icon\"></i>\n }\n\n {{ loading ? loadingText : text }}\n</a>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: TranslocoModule }], encapsulation: i0.ViewEncapsulation.None });
1443
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: AppLinkButtonComponent, isStandalone: true, selector: "app-link-button", inputs: { disabled: "disabled", loading: "loading", target: "target", text: "text", icon: "icon", loadingText: "loadingText", route: "route", queryParams: "queryParams", size: "size", variant: "variant" }, ngImport: i0, template: "<a\n class=\"{{ buttonClasses }}\"\n [routerLink]=\"!disabled ? route : null\"\n [queryParams]=\"queryParams\"\n [target]=\"target\"\n>\n @if (icon) {\n <i [class]=\"icon\"></i>\n }\n\n {{ loading ? loadingText : text }}\n</a>\n", styles: [":host{display:block;width:100%}.btn{width:100%;cursor:pointer;display:flex;justify-content:center;gap:.5rem;border:1px solid transparent;border-radius:.375rem;font-weight:500;outline:none}.btn:focus{box-shadow:0 0 0 2px #fff,0 0 0 4px #4f46e5}.btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.btn-primary{background-color:#dc2626;color:#fff}.btn-primary:hover:not(:disabled){background-color:#b91c1c}.btn-secondary{background-color:#7c3aed;color:#fff}.btn-secondary:hover:not(:disabled){background-color:#6d28d9}.btn-tertiary{background-color:#6b7280;color:#fff}.btn-tertiary:hover:not(:disabled){background-color:#4b5563}.btn-success{background-color:#16a34a;color:#14532d}.btn-success:hover:not(:disabled){background-color:#15803d}.btn-transparent{background-color:transparent;color:#374151}.btn-transparent:hover:not(:disabled){background-color:#f3f4f6}@media(prefers-color-scheme:dark){.btn-transparent{color:#d1d5db}.btn-transparent:hover:not(:disabled){background-color:#1f2937}}.btn-xs{font-size:.75rem;padding:.25rem .5rem}.btn-sm{font-size:.875rem;padding:.5rem 1rem}.btn-md{font-size:1rem;padding:.75rem 1.5rem}.btn-lg{font-size:1.125rem;padding:1rem 2rem}.btn-disabled,.btn-loading{opacity:.5;cursor:not-allowed;pointer-events:none}.btn-icon{display:inline-flex;align-items:center;justify-content:center}.btn-icon-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: TranslocoModule }], encapsulation: i0.ViewEncapsulation.None });
1289
1444
  }
1290
1445
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: AppLinkButtonComponent, decorators: [{
1291
1446
  type: Component,
1292
- args: [{ selector: 'app-link-button', standalone: true, imports: [CommonModule, RouterLink, TranslocoModule], encapsulation: ViewEncapsulation.None, template: "<a\n class=\"{{ buttonClasses }}\"\n [routerLink]=\"!disabled ? route : null\"\n [queryParams]=\"queryParams\"\n [target]=\"target\"\n>\n @if (icon) {\n <i [class]=\"icon\"></i>\n }\n\n {{ loading ? loadingText : text }}\n</a>\n" }]
1447
+ args: [{ selector: 'app-link-button', standalone: true, imports: [CommonModule, RouterLink, RouterModule, TranslocoModule], encapsulation: ViewEncapsulation.None, template: "<a\n class=\"{{ buttonClasses }}\"\n [routerLink]=\"!disabled ? route : null\"\n [queryParams]=\"queryParams\"\n [target]=\"target\"\n>\n @if (icon) {\n <i [class]=\"icon\"></i>\n }\n\n {{ loading ? loadingText : text }}\n</a>\n", styles: [":host{display:block;width:100%}.btn{width:100%;cursor:pointer;display:flex;justify-content:center;gap:.5rem;border:1px solid transparent;border-radius:.375rem;font-weight:500;outline:none}.btn:focus{box-shadow:0 0 0 2px #fff,0 0 0 4px #4f46e5}.btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.btn-primary{background-color:#dc2626;color:#fff}.btn-primary:hover:not(:disabled){background-color:#b91c1c}.btn-secondary{background-color:#7c3aed;color:#fff}.btn-secondary:hover:not(:disabled){background-color:#6d28d9}.btn-tertiary{background-color:#6b7280;color:#fff}.btn-tertiary:hover:not(:disabled){background-color:#4b5563}.btn-success{background-color:#16a34a;color:#14532d}.btn-success:hover:not(:disabled){background-color:#15803d}.btn-transparent{background-color:transparent;color:#374151}.btn-transparent:hover:not(:disabled){background-color:#f3f4f6}@media(prefers-color-scheme:dark){.btn-transparent{color:#d1d5db}.btn-transparent:hover:not(:disabled){background-color:#1f2937}}.btn-xs{font-size:.75rem;padding:.25rem .5rem}.btn-sm{font-size:.875rem;padding:.5rem 1rem}.btn-md{font-size:1rem;padding:.75rem 1.5rem}.btn-lg{font-size:1.125rem;padding:1rem 2rem}.btn-disabled,.btn-loading{opacity:.5;cursor:not-allowed;pointer-events:none}.btn-icon{display:inline-flex;align-items:center;justify-content:center}.btn-icon-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
1293
1448
  }], propDecorators: { disabled: [{
1294
1449
  type: Input
1295
1450
  }], loading: [{
@@ -1317,24 +1472,15 @@ class AppAlertComponent {
1317
1472
  text = '';
1318
1473
  closeable = false;
1319
1474
  size = 'md';
1320
- get alertColorClasses() {
1321
- return ALERT_COLOR_CLASSES[this.type] ?? ALERT_COLOR_CLASSES.success;
1322
- }
1323
- get alertSizeClasses() {
1324
- return ALERT_SIZE_CLASSES[this.size] ?? ALERT_SIZE_CLASSES.sm;
1325
- }
1326
- get alertClasses() {
1327
- return `${ALERT_BASE_CLASSES} ${this.alertColorClasses} ${this.alertSizeClasses}`;
1328
- }
1329
1475
  get alertIcon() {
1330
1476
  return ALERT_ICONS[this.type] ?? ALERT_ICONS.info;
1331
1477
  }
1332
1478
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: AppAlertComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1333
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: AppAlertComponent, isStandalone: true, selector: "app-alert", inputs: { type: "type", text: "text", closeable: "closeable", size: "size" }, ngImport: i0, template: "<div class=\"{{ alertClasses }}\" role=\"alert\">\n <div class=\"flex items-center gap-2\">\n <i class=\"{{ alertIcon }}\"></i>\n <span>{{ text }}</span>\n </div>\n\n @if (closeable) {\n <span\n class=\"absolute top-0 bottom-0 right-0 h-full w-8 flex items-center justify-center cursor-pointer\"\n >\n <i class=\"ri-close-line\"></i>\n </span>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }], encapsulation: i0.ViewEncapsulation.None });
1479
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: AppAlertComponent, isStandalone: true, selector: "app-alert", inputs: { type: "type", text: "text", closeable: "closeable", size: "size" }, ngImport: i0, template: "<div class=\"alert\" [class]=\"'alert--' + type + ' alert--' + size\" role=\"alert\">\n <div class=\"alert-content\">\n <i class=\"{{ alertIcon }}\"></i>\n <span>{{ text }}</span>\n </div>\n\n @if (closeable) {\n <span class=\"alert-close\">\n <i class=\"ri-close-line\"></i>\n </span>\n }\n</div>\n", styles: [".alert{position:relative;display:flex;align-items:center;gap:.5rem;border:1px solid;border-radius:.125rem}.alert--success{background-color:#dcfce7;border-color:#4ade80;color:#15803d}.alert--error{background-color:#fee2e2;border-color:#f87171;color:#b91c1c}.alert--warning{background-color:#fef9c3;border-color:#facc15;color:#a16207}.alert--info{background-color:#dbeafe;border-color:#60a5fa;color:#1d4ed8}.alert--xs{padding:.25rem .5rem;font-size:.75rem}.alert--sm{padding:.5rem 1rem;font-size:.875rem}.alert--md{padding:.75rem 1.5rem;font-size:1rem}.alert--lg{padding:1rem 2rem;font-size:1.125rem}.alert-content{display:flex;align-items:center;gap:.5rem}.alert-close{position:absolute;top:0;bottom:0;right:0;height:100%;width:2rem;display:flex;align-items:center;justify-content:center;cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], encapsulation: i0.ViewEncapsulation.None });
1334
1480
  }
1335
1481
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: AppAlertComponent, decorators: [{
1336
1482
  type: Component,
1337
- args: [{ selector: 'app-alert', standalone: true, imports: [CommonModule], encapsulation: ViewEncapsulation.None, template: "<div class=\"{{ alertClasses }}\" role=\"alert\">\n <div class=\"flex items-center gap-2\">\n <i class=\"{{ alertIcon }}\"></i>\n <span>{{ text }}</span>\n </div>\n\n @if (closeable) {\n <span\n class=\"absolute top-0 bottom-0 right-0 h-full w-8 flex items-center justify-center cursor-pointer\"\n >\n <i class=\"ri-close-line\"></i>\n </span>\n }\n</div>\n" }]
1483
+ args: [{ selector: 'app-alert', standalone: true, imports: [CommonModule], encapsulation: ViewEncapsulation.None, template: "<div class=\"alert\" [class]=\"'alert--' + type + ' alert--' + size\" role=\"alert\">\n <div class=\"alert-content\">\n <i class=\"{{ alertIcon }}\"></i>\n <span>{{ text }}</span>\n </div>\n\n @if (closeable) {\n <span class=\"alert-close\">\n <i class=\"ri-close-line\"></i>\n </span>\n }\n</div>\n", styles: [".alert{position:relative;display:flex;align-items:center;gap:.5rem;border:1px solid;border-radius:.125rem}.alert--success{background-color:#dcfce7;border-color:#4ade80;color:#15803d}.alert--error{background-color:#fee2e2;border-color:#f87171;color:#b91c1c}.alert--warning{background-color:#fef9c3;border-color:#facc15;color:#a16207}.alert--info{background-color:#dbeafe;border-color:#60a5fa;color:#1d4ed8}.alert--xs{padding:.25rem .5rem;font-size:.75rem}.alert--sm{padding:.5rem 1rem;font-size:.875rem}.alert--md{padding:.75rem 1.5rem;font-size:1rem}.alert--lg{padding:1rem 2rem;font-size:1.125rem}.alert-content{display:flex;align-items:center;gap:.5rem}.alert-close{position:absolute;top:0;bottom:0;right:0;height:100%;width:2rem;display:flex;align-items:center;justify-content:center;cursor:pointer}\n"] }]
1338
1484
  }], propDecorators: { type: [{
1339
1485
  type: Input
1340
1486
  }], text: [{
@@ -1351,30 +1497,17 @@ class AppModalComponent {
1351
1497
  isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
1352
1498
  size = 'md';
1353
1499
  closeModal = new EventEmitter();
1354
- SIZE_CLASSES = {
1355
- xs: 'max-w-xs',
1356
- sm: 'max-w-sm',
1357
- md: 'max-w-md',
1358
- lg: 'max-w-lg',
1359
- xl: 'max-w-xl',
1360
- '2xl': 'max-w-2xl',
1361
- '3xl': 'max-w-3xl',
1362
- '4xl': 'max-w-4xl',
1363
- };
1364
- get sizeClass() {
1365
- return this.SIZE_CLASSES[this.size] ?? 'max-w-md';
1366
- }
1367
1500
  onCloseModal() {
1368
1501
  if (this.disableClose)
1369
1502
  return;
1370
1503
  this.closeModal.emit();
1371
1504
  }
1372
1505
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: AppModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1373
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: AppModalComponent, isStandalone: true, selector: "app-modal", inputs: { title: "title", disableClose: "disableClose", isOpen: "isOpen", size: "size" }, outputs: { closeModal: "closeModal" }, ngImport: i0, template: "@if (isOpen()) {\n <div class=\"fixed inset-0 flex items-center justify-center z-50\">\n <div class=\"absolute inset-0 bg-black opacity-50\" (click)=\"onCloseModal()\"></div>\n\n <div\n [class]=\"`${sizeClass} bg-white rounded-lg max-h-screen overflow-y-auto shadow-xl relative z-10 w-full`\"\n >\n @if (!disableClose || !!title) {\n <div class=\"flex justify-between items-center p-5 border-b border-gray-200\">\n <h3 class=\"text-lg font-semibold text-gray-800 m-0\">{{ title }}</h3>\n\n @if (!disableClose) {\n <button\n class=\"bg-none border-none text-2xl cursor-pointer text-gray-600 p-0 w-7.5 h-7.5 flex items-center justify-center hover:text-gray-800\"\n (click)=\"onCloseModal()\"\n >\n &times;\n </button>\n }\n </div>\n }\n\n <div class=\"p-5\">\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }], encapsulation: i0.ViewEncapsulation.None });
1506
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: AppModalComponent, isStandalone: true, selector: "app-modal", inputs: { title: "title", disableClose: "disableClose", isOpen: "isOpen", size: "size" }, outputs: { closeModal: "closeModal" }, ngImport: i0, template: "@if (isOpen()) {\n <div class=\"modal-overlay\">\n <div class=\"modal-backdrop\" (click)=\"onCloseModal()\"></div>\n\n <div class=\"modal-dialog\" [class]=\"'modal-dialog--' + size\">\n @if (!disableClose || !!title) {\n <div class=\"modal-header\">\n <h3 class=\"modal-title\">{{ title }}</h3>\n\n @if (!disableClose) {\n <button class=\"modal-close-button\" (click)=\"onCloseModal()\">&times;</button>\n }\n </div>\n }\n\n <div class=\"modal-body\">\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n}\n", styles: [".modal-overlay{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;z-index:50}.modal-backdrop{position:absolute;inset:0;background-color:#000;opacity:.5}.modal-dialog{position:relative;z-index:10;width:100%;background-color:#fff;border-radius:.5rem;max-height:100vh;overflow-y:auto;box-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a}.modal-dialog--xs{max-width:20rem}.modal-dialog--sm{max-width:24rem}.modal-dialog--md{max-width:28rem}.modal-dialog--lg{max-width:32rem}.modal-dialog--xl{max-width:36rem}.modal-dialog--2xl{max-width:42rem}.modal-dialog--3xl{max-width:48rem}.modal-dialog--4xl{max-width:56rem}.modal-header{display:flex;align-items:center;justify-content:space-between;padding:1.25rem;border-bottom:1px solid #e5e7eb}.modal-title{font-size:1.125rem;font-weight:600;color:#1f2937;margin:0}.modal-close-button{background:none;border:none;font-size:1.5rem;cursor:pointer;color:#4b5563;padding:0;width:1.875rem;height:1.875rem;display:flex;align-items:center;justify-content:center}.modal-close-button:hover{color:#1f2937}.modal-body{padding:1.25rem}.modal-body p:first-of-type{margin-top:0}.modal-body p:last-of-type{margin-bottom:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], encapsulation: i0.ViewEncapsulation.None });
1374
1507
  }
1375
1508
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: AppModalComponent, decorators: [{
1376
1509
  type: Component,
1377
- args: [{ selector: 'app-modal', standalone: true, imports: [CommonModule], encapsulation: ViewEncapsulation.None, template: "@if (isOpen()) {\n <div class=\"fixed inset-0 flex items-center justify-center z-50\">\n <div class=\"absolute inset-0 bg-black opacity-50\" (click)=\"onCloseModal()\"></div>\n\n <div\n [class]=\"`${sizeClass} bg-white rounded-lg max-h-screen overflow-y-auto shadow-xl relative z-10 w-full`\"\n >\n @if (!disableClose || !!title) {\n <div class=\"flex justify-between items-center p-5 border-b border-gray-200\">\n <h3 class=\"text-lg font-semibold text-gray-800 m-0\">{{ title }}</h3>\n\n @if (!disableClose) {\n <button\n class=\"bg-none border-none text-2xl cursor-pointer text-gray-600 p-0 w-7.5 h-7.5 flex items-center justify-center hover:text-gray-800\"\n (click)=\"onCloseModal()\"\n >\n &times;\n </button>\n }\n </div>\n }\n\n <div class=\"p-5\">\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n}\n" }]
1510
+ args: [{ selector: 'app-modal', standalone: true, imports: [CommonModule], encapsulation: ViewEncapsulation.None, template: "@if (isOpen()) {\n <div class=\"modal-overlay\">\n <div class=\"modal-backdrop\" (click)=\"onCloseModal()\"></div>\n\n <div class=\"modal-dialog\" [class]=\"'modal-dialog--' + size\">\n @if (!disableClose || !!title) {\n <div class=\"modal-header\">\n <h3 class=\"modal-title\">{{ title }}</h3>\n\n @if (!disableClose) {\n <button class=\"modal-close-button\" (click)=\"onCloseModal()\">&times;</button>\n }\n </div>\n }\n\n <div class=\"modal-body\">\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n}\n", styles: [".modal-overlay{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;z-index:50}.modal-backdrop{position:absolute;inset:0;background-color:#000;opacity:.5}.modal-dialog{position:relative;z-index:10;width:100%;background-color:#fff;border-radius:.5rem;max-height:100vh;overflow-y:auto;box-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a}.modal-dialog--xs{max-width:20rem}.modal-dialog--sm{max-width:24rem}.modal-dialog--md{max-width:28rem}.modal-dialog--lg{max-width:32rem}.modal-dialog--xl{max-width:36rem}.modal-dialog--2xl{max-width:42rem}.modal-dialog--3xl{max-width:48rem}.modal-dialog--4xl{max-width:56rem}.modal-header{display:flex;align-items:center;justify-content:space-between;padding:1.25rem;border-bottom:1px solid #e5e7eb}.modal-title{font-size:1.125rem;font-weight:600;color:#1f2937;margin:0}.modal-close-button{background:none;border:none;font-size:1.5rem;cursor:pointer;color:#4b5563;padding:0;width:1.875rem;height:1.875rem;display:flex;align-items:center;justify-content:center}.modal-close-button:hover{color:#1f2937}.modal-body{padding:1.25rem}.modal-body p:first-of-type{margin-top:0}.modal-body p:last-of-type{margin-bottom:0}\n"] }]
1378
1511
  }], propDecorators: { title: [{
1379
1512
  type: Input
1380
1513
  }], disableClose: [{
@@ -1405,11 +1538,11 @@ class LoadingmModalComponent {
1405
1538
  this.loadingModalService.close();
1406
1539
  }
1407
1540
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: LoadingmModalComponent, deps: [{ token: LoadingModalService }], target: i0.ɵɵFactoryTarget.Component });
1408
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.25", type: LoadingmModalComponent, isStandalone: true, selector: "loading-modal", ngImport: i0, template: "<app-modal [disableClose]=\"true\" [isOpen]=\"isOpen\" (closeModal)=\"closeModal()\">\n <div class=\"flex flex-col gap-4 py-6 w-full\">\n <div role=\"status\">\n <div class=\"flex items-center justify-center\">\n <div\n class=\"h-14 w-14 animate-spin rounded-full border-8 border-solid border-red-500 border-t-transparent\"\n ></div>\n </div>\n <span class=\"sr-only\">Loading...</span>\n </div>\n\n <p class=\"font-bold text-md text-center\">{{ title() }}</p>\n </div>\n</app-modal>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AppModalComponent, selector: "app-modal", inputs: ["title", "disableClose", "isOpen", "size"], outputs: ["closeModal"] }] });
1541
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.25", type: LoadingmModalComponent, isStandalone: true, selector: "loading-modal", ngImport: i0, template: "<app-modal [disableClose]=\"true\" [isOpen]=\"isOpen\" (closeModal)=\"closeModal()\">\n <div class=\"loading-modal-body\">\n <div role=\"status\">\n <div class=\"loading-modal-spinner-wrapper\">\n <div class=\"loading-modal-spinner\"></div>\n </div>\n <span class=\"loading-modal-hidden\">Loading...</span>\n </div>\n\n <p class=\"loading-modal-title\">{{ title() }}</p>\n </div>\n</app-modal>\n", styles: [".loading-modal-body{display:flex;flex-direction:column;gap:1rem;padding:1.5rem 0;width:100%}.loading-modal-spinner-wrapper{display:flex;align-items:center;justify-content:center}.loading-modal-spinner{height:3.5rem;width:3.5rem;border-radius:9999px;border:8px solid #ef4444;border-top-color:transparent;animation:loading-modal-spin 1s linear infinite}.loading-modal-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.loading-modal-title{font-weight:700;font-size:1rem;margin:0;text-align:center}@keyframes loading-modal-spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AppModalComponent, selector: "app-modal", inputs: ["title", "disableClose", "isOpen", "size"], outputs: ["closeModal"] }] });
1409
1542
  }
1410
1543
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: LoadingmModalComponent, decorators: [{
1411
1544
  type: Component,
1412
- args: [{ selector: 'loading-modal', standalone: true, imports: [CommonModule, AppModalComponent], template: "<app-modal [disableClose]=\"true\" [isOpen]=\"isOpen\" (closeModal)=\"closeModal()\">\n <div class=\"flex flex-col gap-4 py-6 w-full\">\n <div role=\"status\">\n <div class=\"flex items-center justify-center\">\n <div\n class=\"h-14 w-14 animate-spin rounded-full border-8 border-solid border-red-500 border-t-transparent\"\n ></div>\n </div>\n <span class=\"sr-only\">Loading...</span>\n </div>\n\n <p class=\"font-bold text-md text-center\">{{ title() }}</p>\n </div>\n</app-modal>\n" }]
1545
+ args: [{ selector: 'loading-modal', standalone: true, imports: [CommonModule, AppModalComponent], template: "<app-modal [disableClose]=\"true\" [isOpen]=\"isOpen\" (closeModal)=\"closeModal()\">\n <div class=\"loading-modal-body\">\n <div role=\"status\">\n <div class=\"loading-modal-spinner-wrapper\">\n <div class=\"loading-modal-spinner\"></div>\n </div>\n <span class=\"loading-modal-hidden\">Loading...</span>\n </div>\n\n <p class=\"loading-modal-title\">{{ title() }}</p>\n </div>\n</app-modal>\n", styles: [".loading-modal-body{display:flex;flex-direction:column;gap:1rem;padding:1.5rem 0;width:100%}.loading-modal-spinner-wrapper{display:flex;align-items:center;justify-content:center}.loading-modal-spinner{height:3.5rem;width:3.5rem;border-radius:9999px;border:8px solid #ef4444;border-top-color:transparent;animation:loading-modal-spin 1s linear infinite}.loading-modal-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.loading-modal-title{font-weight:700;font-size:1rem;margin:0;text-align:center}@keyframes loading-modal-spin{to{transform:rotate(360deg)}}\n"] }]
1413
1546
  }], ctorParameters: () => [{ type: LoadingModalService }] });
1414
1547
 
1415
1548
  class FormInputComponent {
@@ -1500,17 +1633,17 @@ class FormInputComponent {
1500
1633
  }
1501
1634
  return baseClasses;
1502
1635
  }
1503
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: FormInputComponent, deps: [{ token: i1$1.NgControl, optional: true, self: true }, { token: i2.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
1504
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: FormInputComponent, isStandalone: true, selector: "form-input", inputs: { label: "label", type: "type", name: "name", id: "id", placeholder: "placeholder", required: "required", readonly: "readonly", minlength: "minlength", min: "min", step: "step", pattern: "pattern", fieldGroupClass: "fieldGroupClass", autocomplete: "autocomplete" }, ngImport: i0, template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <input\n [type]=\"type\"\n [id]=\"inputId\"\n [name]=\"name\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [minlength]=\"minlength\"\n [pattern]=\"pattern || ''\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onInput($event)\"\n (blur)=\"onTouched()\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n [class.bg-white]=\"!readonly\"\n [class.bg-gray-200]=\"readonly\"\n [class.cursor-not-allowed]=\"readonly\"\n [class]=\"inputClasses\"\n [autocomplete]=\"autocomplete\"\n [min]=\"min\"\n [step]=\"step\"\n />\n </div>\n\n @if (showError) {\n <div class=\"text-red-500 text-xs mt-1\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }] });
1636
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: FormInputComponent, deps: [{ token: i1$1.NgControl, optional: true, self: true }, { token: i2$1.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
1637
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: FormInputComponent, isStandalone: true, selector: "form-input", inputs: { label: "label", type: "type", name: "name", id: "id", placeholder: "placeholder", required: "required", readonly: "readonly", minlength: "minlength", min: "min", step: "step", pattern: "pattern", fieldGroupClass: "fieldGroupClass", autocomplete: "autocomplete" }, ngImport: i0, template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"form-input-label\">\n {{ label }}\n\n @if (required) {\n <span class=\"form-input-required\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <input\n [type]=\"type\"\n [id]=\"inputId\"\n [name]=\"name\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [minlength]=\"minlength\"\n [pattern]=\"pattern || ''\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onInput($event)\"\n (blur)=\"onTouched()\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n [class.disabled]=\"readonly\"\n [class.error]=\"showError\"\n class=\"form-input\"\n [autocomplete]=\"autocomplete\"\n [min]=\"min\"\n [step]=\"step\"\n />\n </div>\n\n @if (showError) {\n <div class=\"form-input-error-message\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", styles: [".form-input-label{color:#374151;display:block;font-size:.875rem;font-weight:600;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.form-input-label{color:#d1d5db}}.form-input{background-color:#fff;border:1px solid #d1d5db;border-radius:.375rem;color:#111827;display:block;padding:.375rem .75rem;outline:1;outline-offset:1;outline-color:#d1d5db;width:100%}.form-input::placeholder{color:#9ca3af}.form-input:focus{outline:2;outline-offset:2;outline-color:#4f46e5}.form-input.error{outline-color:#ef4444}@media(prefers-color-scheme:dark){.form-input.error{background-color:#374151;outline-color:#ef4444}}.form-input.disabled{background-color:#e5e7eb;color:#6b7280;cursor:not-allowed}@media(prefers-color-scheme:dark){.form-input.disabled{background-color:#374151;color:#d1d5db}}@media screen and (min-width:768px){.form-input{font-size:.875rem}}.form-input-required{color:#ef4444}.form-input-error-message{color:#ef4444;font-size:.75rem;margin-top:.25rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }] });
1505
1638
  }
1506
1639
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: FormInputComponent, decorators: [{
1507
1640
  type: Component,
1508
- args: [{ selector: 'form-input', standalone: true, imports: [FormsModule, CommonModule, ReactiveFormsModule], template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <input\n [type]=\"type\"\n [id]=\"inputId\"\n [name]=\"name\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [minlength]=\"minlength\"\n [pattern]=\"pattern || ''\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onInput($event)\"\n (blur)=\"onTouched()\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n [class.bg-white]=\"!readonly\"\n [class.bg-gray-200]=\"readonly\"\n [class.cursor-not-allowed]=\"readonly\"\n [class]=\"inputClasses\"\n [autocomplete]=\"autocomplete\"\n [min]=\"min\"\n [step]=\"step\"\n />\n </div>\n\n @if (showError) {\n <div class=\"text-red-500 text-xs mt-1\">\n {{ errorMessage }}\n </div>\n }\n</div>\n" }]
1641
+ args: [{ selector: 'form-input', standalone: true, imports: [FormsModule, CommonModule, ReactiveFormsModule], template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"form-input-label\">\n {{ label }}\n\n @if (required) {\n <span class=\"form-input-required\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <input\n [type]=\"type\"\n [id]=\"inputId\"\n [name]=\"name\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [minlength]=\"minlength\"\n [pattern]=\"pattern || ''\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onInput($event)\"\n (blur)=\"onTouched()\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n [class.disabled]=\"readonly\"\n [class.error]=\"showError\"\n class=\"form-input\"\n [autocomplete]=\"autocomplete\"\n [min]=\"min\"\n [step]=\"step\"\n />\n </div>\n\n @if (showError) {\n <div class=\"form-input-error-message\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", styles: [".form-input-label{color:#374151;display:block;font-size:.875rem;font-weight:600;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.form-input-label{color:#d1d5db}}.form-input{background-color:#fff;border:1px solid #d1d5db;border-radius:.375rem;color:#111827;display:block;padding:.375rem .75rem;outline:1;outline-offset:1;outline-color:#d1d5db;width:100%}.form-input::placeholder{color:#9ca3af}.form-input:focus{outline:2;outline-offset:2;outline-color:#4f46e5}.form-input.error{outline-color:#ef4444}@media(prefers-color-scheme:dark){.form-input.error{background-color:#374151;outline-color:#ef4444}}.form-input.disabled{background-color:#e5e7eb;color:#6b7280;cursor:not-allowed}@media(prefers-color-scheme:dark){.form-input.disabled{background-color:#374151;color:#d1d5db}}@media screen and (min-width:768px){.form-input{font-size:.875rem}}.form-input-required{color:#ef4444}.form-input-error-message{color:#ef4444;font-size:.75rem;margin-top:.25rem}\n"] }]
1509
1642
  }], ctorParameters: () => [{ type: i1$1.NgControl, decorators: [{
1510
1643
  type: Self
1511
1644
  }, {
1512
1645
  type: Optional
1513
- }] }, { type: i2.TranslocoService }], propDecorators: { label: [{
1646
+ }] }, { type: i2$1.TranslocoService }], propDecorators: { label: [{
1514
1647
  type: Input
1515
1648
  }], type: [{
1516
1649
  type: Input
@@ -1580,8 +1713,8 @@ class DeleteConfirmationComponent {
1580
1713
  this.deleteConfirmationForm.reset();
1581
1714
  this.deleteConfirmationService.close();
1582
1715
  }
1583
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DeleteConfirmationComponent, deps: [{ token: i1$1.FormBuilder }, { token: DeleteConfirmationService }, { token: i2.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
1584
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: DeleteConfirmationComponent, isStandalone: true, selector: "delete-confirmation", ngImport: i0, template: "@if (isOpen()) {\n <app-modal [title]=\"title\" [isOpen]=\"isOpen\" (closeModal)=\"onCloseModal()\">\n <form\n [formGroup]=\"deleteConfirmationForm\"\n method=\"POST\"\n class=\"flex flex-col gap-4\"\n (ngSubmit)=\"onConfirmDelete()\"\n >\n <app-alert\n type=\"warning\"\n [text]=\"'deleteConfirmation.warning' | transloco\"\n size=\"sm\"\n [closeable]=\"false\"\n />\n\n <p class=\"text-xs text-gray-600\">\n {{ 'deleteConfirmation.instructions' | transloco }}\n\n <span\n class=\"inline-flex bg-gray-200 items-center px-2 py-1 gap-1 text-red-600 font-semibold text-sm rounded mt-1\"\n >\n {{ confirmationText }}\n </span>\n </p>\n\n <form-input\n name=\"confirmationText\"\n type=\"text\"\n class=\"flex-1\"\n [required]=\"true\"\n [autocomplete]=\"false\"\n formControlName=\"confirmationText\"\n [placeholder]=\"\n transloco.translate('deleteConfirmation.placeholder', { text: confirmationText })\n \"\n />\n\n <div class=\"flex space-x-3\">\n <app-button\n variant=\"terciary\"\n [text]=\"'deleteConfirmation.cancel' | transloco\"\n (click)=\"onCloseModal()\"\n size=\"sm\"\n />\n\n <app-button\n type=\"submit\"\n variant=\"primary\"\n [text]=\"'deleteConfirmation.delete' | transloco\"\n [disabled]=\"!isConfirmationValid\"\n size=\"sm\"\n />\n </div>\n </form>\n </app-modal>\n}\n", styles: [".delete-confirmation-modal{animation:fadeIn .3s ease-out}.delete-confirmation-content{animation:slideUp .3s ease-out}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}.confirmation-input{transition:all .2s ease}.confirmation-input:focus{box-shadow:0 0 0 3px #ef44441a}.confirmation-input.invalid{border-color:#dc2626}.confirmation-input.invalid:focus{border-color:#dc2626;box-shadow:0 0 0 3px #dc26261a}.delete-button{transition:all .2s ease}.delete-button:disabled{opacity:.5;cursor:not-allowed}.delete-button:not(:disabled):hover{transform:translateY(-1px);box-shadow:0 4px 12px #dc26264d}.warning-message{border-left:4px solid #f59e0b;background:linear-gradient(135deg,#fef3c7,#fde68a)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "component", type: AppButtonComponent, selector: "app-button", inputs: ["disabled", "loading", "type", "variant", "text", "size", "loadingText", "icon"], outputs: ["clicked"] }, { kind: "component", type: FormInputComponent, selector: "form-input", inputs: ["label", "type", "name", "id", "placeholder", "required", "readonly", "minlength", "min", "step", "pattern", "fieldGroupClass", "autocomplete"] }, { kind: "component", type: AppModalComponent, selector: "app-modal", inputs: ["title", "disableClose", "isOpen", "size"], outputs: ["closeModal"] }, { kind: "component", type: AppAlertComponent, selector: "app-alert", inputs: ["type", "text", "closeable", "size"] }, { kind: "pipe", type: i2.TranslocoPipe, name: "transloco" }], encapsulation: i0.ViewEncapsulation.None });
1716
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DeleteConfirmationComponent, deps: [{ token: i1$1.FormBuilder }, { token: DeleteConfirmationService }, { token: i2$1.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
1717
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: DeleteConfirmationComponent, isStandalone: true, selector: "delete-confirmation", ngImport: i0, template: "@if (isOpen()) {\n <app-modal [title]=\"title\" [isOpen]=\"isOpen\" (closeModal)=\"onCloseModal()\">\n <form\n [formGroup]=\"deleteConfirmationForm\"\n method=\"POST\"\n class=\"delete-confirmation-content\"\n (ngSubmit)=\"onConfirmDelete()\"\n >\n <app-alert\n type=\"warning\"\n [text]=\"'deleteConfirmation.warning' | transloco\"\n size=\"sm\"\n [closeable]=\"false\"\n />\n\n <p class=\"delete-confirmation-instructions\">\n {{ 'deleteConfirmation.instructions' | transloco }}\n\n <span class=\"delete-confirmation-highlight\">\n {{ confirmationText }}\n </span>\n </p>\n\n <form-input\n name=\"confirmationText\"\n type=\"text\"\n class=\"delete-confirmation-field\"\n [required]=\"true\"\n [autocomplete]=\"false\"\n formControlName=\"confirmationText\"\n [placeholder]=\"\n transloco.translate('deleteConfirmation.placeholder', { text: confirmationText })\n \"\n />\n\n <div class=\"delete-confirmation-actions\">\n <app-button\n variant=\"tertiary\"\n [text]=\"'deleteConfirmation.cancel' | transloco\"\n (click)=\"onCloseModal()\"\n size=\"sm\"\n />\n\n <app-button\n type=\"submit\"\n variant=\"primary\"\n [text]=\"'deleteConfirmation.delete' | transloco\"\n [disabled]=\"!isConfirmationValid\"\n size=\"sm\"\n />\n </div>\n </form>\n </app-modal>\n}\n", styles: [".delete-confirmation-content{display:flex;flex-direction:column;gap:1rem;animation:slideUp .3s ease-out}.delete-confirmation-instructions{font-size:.75rem;color:#4b5563;margin:0}@media(prefers-color-scheme:dark){.delete-confirmation-instructions{color:#9ca3af}}.delete-confirmation-highlight{display:inline-flex;align-items:center;gap:.25rem;padding:.25rem .5rem;margin-top:.25rem;background-color:#e5e7eb;color:#dc2626;font-weight:600;font-size:.875rem;border-radius:.375rem}@media(prefers-color-scheme:dark){.delete-confirmation-highlight{background-color:#374151}}.delete-confirmation-field{flex:1}.delete-confirmation-actions{display:flex;gap:.75rem}@keyframes slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "component", type: AppButtonComponent, selector: "app-button", inputs: ["disabled", "loading", "type", "variant", "text", "size", "loadingText", "icon"], outputs: ["clicked"] }, { kind: "component", type: FormInputComponent, selector: "form-input", inputs: ["label", "type", "name", "id", "placeholder", "required", "readonly", "minlength", "min", "step", "pattern", "fieldGroupClass", "autocomplete"] }, { kind: "component", type: AppModalComponent, selector: "app-modal", inputs: ["title", "disableClose", "isOpen", "size"], outputs: ["closeModal"] }, { kind: "component", type: AppAlertComponent, selector: "app-alert", inputs: ["type", "text", "closeable", "size"] }, { kind: "pipe", type: i2$1.TranslocoPipe, name: "transloco" }], encapsulation: i0.ViewEncapsulation.None });
1585
1718
  }
1586
1719
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DeleteConfirmationComponent, decorators: [{
1587
1720
  type: Component,
@@ -1593,17 +1726,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
1593
1726
  FormInputComponent,
1594
1727
  AppModalComponent,
1595
1728
  AppAlertComponent,
1596
- ], encapsulation: ViewEncapsulation.None, template: "@if (isOpen()) {\n <app-modal [title]=\"title\" [isOpen]=\"isOpen\" (closeModal)=\"onCloseModal()\">\n <form\n [formGroup]=\"deleteConfirmationForm\"\n method=\"POST\"\n class=\"flex flex-col gap-4\"\n (ngSubmit)=\"onConfirmDelete()\"\n >\n <app-alert\n type=\"warning\"\n [text]=\"'deleteConfirmation.warning' | transloco\"\n size=\"sm\"\n [closeable]=\"false\"\n />\n\n <p class=\"text-xs text-gray-600\">\n {{ 'deleteConfirmation.instructions' | transloco }}\n\n <span\n class=\"inline-flex bg-gray-200 items-center px-2 py-1 gap-1 text-red-600 font-semibold text-sm rounded mt-1\"\n >\n {{ confirmationText }}\n </span>\n </p>\n\n <form-input\n name=\"confirmationText\"\n type=\"text\"\n class=\"flex-1\"\n [required]=\"true\"\n [autocomplete]=\"false\"\n formControlName=\"confirmationText\"\n [placeholder]=\"\n transloco.translate('deleteConfirmation.placeholder', { text: confirmationText })\n \"\n />\n\n <div class=\"flex space-x-3\">\n <app-button\n variant=\"terciary\"\n [text]=\"'deleteConfirmation.cancel' | transloco\"\n (click)=\"onCloseModal()\"\n size=\"sm\"\n />\n\n <app-button\n type=\"submit\"\n variant=\"primary\"\n [text]=\"'deleteConfirmation.delete' | transloco\"\n [disabled]=\"!isConfirmationValid\"\n size=\"sm\"\n />\n </div>\n </form>\n </app-modal>\n}\n", styles: [".delete-confirmation-modal{animation:fadeIn .3s ease-out}.delete-confirmation-content{animation:slideUp .3s ease-out}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}.confirmation-input{transition:all .2s ease}.confirmation-input:focus{box-shadow:0 0 0 3px #ef44441a}.confirmation-input.invalid{border-color:#dc2626}.confirmation-input.invalid:focus{border-color:#dc2626;box-shadow:0 0 0 3px #dc26261a}.delete-button{transition:all .2s ease}.delete-button:disabled{opacity:.5;cursor:not-allowed}.delete-button:not(:disabled):hover{transform:translateY(-1px);box-shadow:0 4px 12px #dc26264d}.warning-message{border-left:4px solid #f59e0b;background:linear-gradient(135deg,#fef3c7,#fde68a)}\n"] }]
1597
- }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: DeleteConfirmationService }, { type: i2.TranslocoService }] });
1729
+ ], encapsulation: ViewEncapsulation.None, template: "@if (isOpen()) {\n <app-modal [title]=\"title\" [isOpen]=\"isOpen\" (closeModal)=\"onCloseModal()\">\n <form\n [formGroup]=\"deleteConfirmationForm\"\n method=\"POST\"\n class=\"delete-confirmation-content\"\n (ngSubmit)=\"onConfirmDelete()\"\n >\n <app-alert\n type=\"warning\"\n [text]=\"'deleteConfirmation.warning' | transloco\"\n size=\"sm\"\n [closeable]=\"false\"\n />\n\n <p class=\"delete-confirmation-instructions\">\n {{ 'deleteConfirmation.instructions' | transloco }}\n\n <span class=\"delete-confirmation-highlight\">\n {{ confirmationText }}\n </span>\n </p>\n\n <form-input\n name=\"confirmationText\"\n type=\"text\"\n class=\"delete-confirmation-field\"\n [required]=\"true\"\n [autocomplete]=\"false\"\n formControlName=\"confirmationText\"\n [placeholder]=\"\n transloco.translate('deleteConfirmation.placeholder', { text: confirmationText })\n \"\n />\n\n <div class=\"delete-confirmation-actions\">\n <app-button\n variant=\"tertiary\"\n [text]=\"'deleteConfirmation.cancel' | transloco\"\n (click)=\"onCloseModal()\"\n size=\"sm\"\n />\n\n <app-button\n type=\"submit\"\n variant=\"primary\"\n [text]=\"'deleteConfirmation.delete' | transloco\"\n [disabled]=\"!isConfirmationValid\"\n size=\"sm\"\n />\n </div>\n </form>\n </app-modal>\n}\n", styles: [".delete-confirmation-content{display:flex;flex-direction:column;gap:1rem;animation:slideUp .3s ease-out}.delete-confirmation-instructions{font-size:.75rem;color:#4b5563;margin:0}@media(prefers-color-scheme:dark){.delete-confirmation-instructions{color:#9ca3af}}.delete-confirmation-highlight{display:inline-flex;align-items:center;gap:.25rem;padding:.25rem .5rem;margin-top:.25rem;background-color:#e5e7eb;color:#dc2626;font-weight:600;font-size:.875rem;border-radius:.375rem}@media(prefers-color-scheme:dark){.delete-confirmation-highlight{background-color:#374151}}.delete-confirmation-field{flex:1}.delete-confirmation-actions{display:flex;gap:.75rem}@keyframes slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}\n"] }]
1730
+ }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: DeleteConfirmationService }, { type: i2$1.TranslocoService }] });
1598
1731
 
1599
1732
  class AuditInformationComponent {
1600
1733
  data = null;
1601
1734
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: AuditInformationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1602
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: AuditInformationComponent, isStandalone: true, selector: "app-audit-information", inputs: { data: "data" }, ngImport: i0, template: "@if (data) {\n <div class=\"w-full bg-white rounded-lg shadow-lg overflow-hidden\">\n <div class=\"border-b border-gray-200 last:border-b-0\">\n <div class=\"flex items-center justify-between p-4 bg-gray-50 border-b border-gray-200\">\n <p class=\"text-sm font-semibold\">Informaci\u00F3n de auditoria</p>\n </div>\n\n <div class=\"p-4 w-full\">\n <ul class=\"flex flex-col gap-4 list-none p-0 m-0 w-full text-xs\">\n <li class=\"flex flex-col items-start\">\n <span class=\"font-bold\">Fecha de creaci\u00F3n:</span>\n <span>{{ data.created_at | date: 'medium' }}</span>\n </li>\n\n @if (data.created_by_admin) {\n <li class=\"flex flex-col items-start\">\n <span class=\"font-bold\">Creado por:</span>\n <span>\n {{ data.created_by_admin.first_name }} - {{ data.created_by_admin.email }}\n </span>\n </li>\n }\n\n @if (data.updated_at) {\n <li class=\"flex flex-col items-start\">\n <span class=\"font-bold\">\u00DAltima actualizaci\u00F3n:</span>\n <span>{{ data.updated_at | date: 'medium' }}</span>\n </li>\n }\n\n @if (data.updated_by_admin) {\n <li class=\"flex flex-col items-start\">\n <span class=\"font-bold\">Actualizado por:</span>\n <span>\n {{ data.updated_by_admin.first_name }} - {{ data.updated_by_admin.email }}\n </span>\n </li>\n }\n\n @if (data.is_published && data.published_at) {\n <li class=\"flex flex-col items-start\">\n <span class=\"font-bold\">Fecha de publicaci\u00F3n:</span>\n <span>{{ data.published_at | date: 'medium' }}</span>\n </li>\n }\n\n @if (data.is_published && data.published_by_admin) {\n <li class=\"flex flex-col items-start\">\n <span class=\"font-bold\">Publicado por:</span>\n <span>\n {{ data.published_by_admin.first_name }} - {{ data.published_by_admin.email }}\n </span>\n </li>\n }\n </ul>\n </div>\n </div>\n </div>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i2$1.DatePipe, name: "date" }] });
1735
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: AuditInformationComponent, isStandalone: true, selector: "app-audit-information", inputs: { data: "data" }, ngImport: i0, template: "@if (data) {\n <div class=\"audit-information\">\n <div class=\"audit-information-section\">\n <div class=\"audit-information-header\">\n <p class=\"audit-information-header-title\">Informaci\u00F3n de auditoria</p>\n </div>\n\n <div class=\"audit-information-body\">\n <ul class=\"audit-information-list\">\n <li class=\"audit-information-item\">\n <span class=\"audit-information-label\">Fecha de creaci\u00F3n:</span>\n <span>{{ data.created_at | date: 'medium' }}</span>\n </li>\n\n @if (data.created_by_admin) {\n <li class=\"audit-information-item\">\n <span class=\"audit-information-label\">Creado por:</span>\n <span>\n {{ data.created_by_admin.first_name }} - {{ data.created_by_admin.email }}\n </span>\n </li>\n }\n\n @if (data.updated_at) {\n <li class=\"audit-information-item\">\n <span class=\"audit-information-label\">\u00DAltima actualizaci\u00F3n:</span>\n <span>{{ data.updated_at | date: 'medium' }}</span>\n </li>\n }\n\n @if (data.updated_by_admin) {\n <li class=\"audit-information-item\">\n <span class=\"audit-information-label\">Actualizado por:</span>\n <span>\n {{ data.updated_by_admin.first_name }} - {{ data.updated_by_admin.email }}\n </span>\n </li>\n }\n\n @if (data.is_published && data.published_at) {\n <li class=\"audit-information-item\">\n <span class=\"audit-information-label\">Fecha de publicaci\u00F3n:</span>\n <span>{{ data.published_at | date: 'medium' }}</span>\n </li>\n }\n\n @if (data.is_published && data.published_by_admin) {\n <li class=\"audit-information-item\">\n <span class=\"audit-information-label\">Publicado por:</span>\n <span>\n {{ data.published_by_admin.first_name }} - {{ data.published_by_admin.email }}\n </span>\n </li>\n }\n </ul>\n </div>\n </div>\n </div>\n}\n", styles: [".audit-information{width:100%;background-color:#fff;border-radius:.5rem;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;overflow:hidden}@media(prefers-color-scheme:dark){.audit-information{background-color:#1f2937}}.audit-information-section{border-bottom:1px solid #e5e7eb}.audit-information-section:last-child{border-bottom:none}@media(prefers-color-scheme:dark){.audit-information-section{border-color:#374151}}.audit-information-header{display:flex;align-items:center;justify-content:space-between;padding:1rem;background-color:#f9fafb;border-bottom:1px solid #e5e7eb}@media(prefers-color-scheme:dark){.audit-information-header{background-color:#111827;border-color:#374151}}.audit-information-header-title{font-size:.875rem;font-weight:600}@media(prefers-color-scheme:dark){.audit-information-header-title{color:#fff}}.audit-information-body{padding:1rem;width:100%}.audit-information-list{display:flex;flex-direction:column;gap:1rem;list-style:none;padding:0;margin:0;width:100%;font-size:.75rem}@media(prefers-color-scheme:dark){.audit-information-list{color:#d1d5db}}.audit-information-item{display:flex;flex-direction:column;align-items:flex-start}.audit-information-label{font-weight:700}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i2.DatePipe, name: "date" }] });
1603
1736
  }
1604
1737
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: AuditInformationComponent, decorators: [{
1605
1738
  type: Component,
1606
- args: [{ selector: 'app-audit-information', standalone: true, imports: [CommonModule, DatePipe], template: "@if (data) {\n <div class=\"w-full bg-white rounded-lg shadow-lg overflow-hidden\">\n <div class=\"border-b border-gray-200 last:border-b-0\">\n <div class=\"flex items-center justify-between p-4 bg-gray-50 border-b border-gray-200\">\n <p class=\"text-sm font-semibold\">Informaci\u00F3n de auditoria</p>\n </div>\n\n <div class=\"p-4 w-full\">\n <ul class=\"flex flex-col gap-4 list-none p-0 m-0 w-full text-xs\">\n <li class=\"flex flex-col items-start\">\n <span class=\"font-bold\">Fecha de creaci\u00F3n:</span>\n <span>{{ data.created_at | date: 'medium' }}</span>\n </li>\n\n @if (data.created_by_admin) {\n <li class=\"flex flex-col items-start\">\n <span class=\"font-bold\">Creado por:</span>\n <span>\n {{ data.created_by_admin.first_name }} - {{ data.created_by_admin.email }}\n </span>\n </li>\n }\n\n @if (data.updated_at) {\n <li class=\"flex flex-col items-start\">\n <span class=\"font-bold\">\u00DAltima actualizaci\u00F3n:</span>\n <span>{{ data.updated_at | date: 'medium' }}</span>\n </li>\n }\n\n @if (data.updated_by_admin) {\n <li class=\"flex flex-col items-start\">\n <span class=\"font-bold\">Actualizado por:</span>\n <span>\n {{ data.updated_by_admin.first_name }} - {{ data.updated_by_admin.email }}\n </span>\n </li>\n }\n\n @if (data.is_published && data.published_at) {\n <li class=\"flex flex-col items-start\">\n <span class=\"font-bold\">Fecha de publicaci\u00F3n:</span>\n <span>{{ data.published_at | date: 'medium' }}</span>\n </li>\n }\n\n @if (data.is_published && data.published_by_admin) {\n <li class=\"flex flex-col items-start\">\n <span class=\"font-bold\">Publicado por:</span>\n <span>\n {{ data.published_by_admin.first_name }} - {{ data.published_by_admin.email }}\n </span>\n </li>\n }\n </ul>\n </div>\n </div>\n </div>\n}\n" }]
1739
+ args: [{ selector: 'app-audit-information', standalone: true, imports: [CommonModule, DatePipe], template: "@if (data) {\n <div class=\"audit-information\">\n <div class=\"audit-information-section\">\n <div class=\"audit-information-header\">\n <p class=\"audit-information-header-title\">Informaci\u00F3n de auditoria</p>\n </div>\n\n <div class=\"audit-information-body\">\n <ul class=\"audit-information-list\">\n <li class=\"audit-information-item\">\n <span class=\"audit-information-label\">Fecha de creaci\u00F3n:</span>\n <span>{{ data.created_at | date: 'medium' }}</span>\n </li>\n\n @if (data.created_by_admin) {\n <li class=\"audit-information-item\">\n <span class=\"audit-information-label\">Creado por:</span>\n <span>\n {{ data.created_by_admin.first_name }} - {{ data.created_by_admin.email }}\n </span>\n </li>\n }\n\n @if (data.updated_at) {\n <li class=\"audit-information-item\">\n <span class=\"audit-information-label\">\u00DAltima actualizaci\u00F3n:</span>\n <span>{{ data.updated_at | date: 'medium' }}</span>\n </li>\n }\n\n @if (data.updated_by_admin) {\n <li class=\"audit-information-item\">\n <span class=\"audit-information-label\">Actualizado por:</span>\n <span>\n {{ data.updated_by_admin.first_name }} - {{ data.updated_by_admin.email }}\n </span>\n </li>\n }\n\n @if (data.is_published && data.published_at) {\n <li class=\"audit-information-item\">\n <span class=\"audit-information-label\">Fecha de publicaci\u00F3n:</span>\n <span>{{ data.published_at | date: 'medium' }}</span>\n </li>\n }\n\n @if (data.is_published && data.published_by_admin) {\n <li class=\"audit-information-item\">\n <span class=\"audit-information-label\">Publicado por:</span>\n <span>\n {{ data.published_by_admin.first_name }} - {{ data.published_by_admin.email }}\n </span>\n </li>\n }\n </ul>\n </div>\n </div>\n </div>\n}\n", styles: [".audit-information{width:100%;background-color:#fff;border-radius:.5rem;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;overflow:hidden}@media(prefers-color-scheme:dark){.audit-information{background-color:#1f2937}}.audit-information-section{border-bottom:1px solid #e5e7eb}.audit-information-section:last-child{border-bottom:none}@media(prefers-color-scheme:dark){.audit-information-section{border-color:#374151}}.audit-information-header{display:flex;align-items:center;justify-content:space-between;padding:1rem;background-color:#f9fafb;border-bottom:1px solid #e5e7eb}@media(prefers-color-scheme:dark){.audit-information-header{background-color:#111827;border-color:#374151}}.audit-information-header-title{font-size:.875rem;font-weight:600}@media(prefers-color-scheme:dark){.audit-information-header-title{color:#fff}}.audit-information-body{padding:1rem;width:100%}.audit-information-list{display:flex;flex-direction:column;gap:1rem;list-style:none;padding:0;margin:0;width:100%;font-size:.75rem}@media(prefers-color-scheme:dark){.audit-information-list{color:#d1d5db}}.audit-information-item{display:flex;flex-direction:column;align-items:flex-start}.audit-information-label{font-weight:700}\n"] }]
1607
1740
  }], propDecorators: { data: [{
1608
1741
  type: Input
1609
1742
  }] } });
@@ -1652,11 +1785,11 @@ class DynamicTableComponent {
1652
1785
  });
1653
1786
  }
1654
1787
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DynamicTableComponent, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component });
1655
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: DynamicTableComponent, isStandalone: true, selector: "dynamic-table", inputs: { title: "title", data: "data", headers: "headers", columnComponents: "columnComponents", isLoading: "isLoading", totalItems: "totalItems", itemsPerPage: "itemsPerPage", currentPage: "currentPage", showPagination: "showPagination", showSearch: "showSearch", showTitle: "showTitle" }, outputs: { pageChange: "pageChange", searchChange: "searchChange" }, ngImport: i0, template: "<div\n class=\"bg-white rounded-lg overflow-hidden border border-gray-200 dark:bg-gray-800 dark:border-gray-700\"\n>\n @if (showTitle || showSearch) {\n <div class=\"p-4 border-b border-gray-200 flex items-center justify-start dark:border-gray-700\">\n @if (showTitle) {\n <h2 class=\"text-lg font-semibold dark:text-white\">{{ title }}</h2>\n }\n\n @if (showSearch) {\n <input\n type=\"text\"\n (input)=\"onSearch($event)\"\n placeholder=\"Buscar...\"\n class=\"ml-auto block w-sm rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6 dark:bg-white/5 dark:text-white dark:outline-white/10 dark:placeholder:text-gray-500 dark:focus:outline-indigo-500\"\n />\n }\n </div>\n }\n\n <div class=\"overflow-x-auto\">\n <table class=\"w-full text-left border-collapse\">\n <thead class=\"bg-gray-100 text-gray-600 text-xs dark:bg-gray-700 dark:text-gray-300\">\n <tr>\n @for (header of headers; track header.key) {\n <th class=\"p-3 border-b border-gray-300 whitespace-nowrap dark:border-gray-600\">\n {{ header.label }}\n </th>\n }\n </tr>\n </thead>\n\n <tbody class=\"text-gray-700 text-xs dark:text-gray-200\">\n @if (isLoading) {\n <tr\n class=\"border-b even:bg-gray-100 border-gray-200 last:border-none transition-colors dark:even:bg-gray-700/50 dark:border-gray-700\"\n >\n @for (header of headers; track header.key) {\n <td class=\"p-3\">\n <div class=\"h-5 bg-gray-200 rounded animate-pulse w-full dark:bg-gray-600\"></div>\n </td>\n }\n </tr>\n }\n\n @for (row of data; track row) {\n <tr\n class=\"hover:bg-gray-200 border-b even:bg-gray-100 border-gray-200 last:border-none transition-colors dark:hover:bg-gray-700 dark:even:bg-gray-700/50 dark:border-gray-700\"\n >\n @for (header of headers; track header.key) {\n <td class=\"p-3 whitespace-nowrap\">\n @if (columnComponents[header.key]) {\n <ng-container\n *ngComponentOutlet=\"columnComponents[header.key]; injector: createInjector(row)\"\n ></ng-container>\n } @else {\n {{ row[header.key] || '---' }}\n }\n </td>\n }\n </tr>\n }\n\n @if ((!data || data.length < 1) && !isLoading) {\n <tr>\n <td\n [attr.colspan]=\"headers.length\"\n class=\"p-6 text-center text-gray-400 italic dark:text-gray-500\"\n >\n No se encontraron registros en el servidor.\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n\n @if (showPagination) {\n <div\n class=\"p-4 flex items-center justify-between bg-gray-50 border-gray-300 border-t dark:bg-gray-800/50 dark:border-gray-700\"\n >\n <div class=\"text-sm text-gray-500 dark:text-gray-400\">\n Mostrando p\u00E1gina\n <span class=\"font-semibold text-gray-800 dark:text-white\">{{ currentPage }}</span> de\n <span class=\"font-semibold text-gray-800 dark:text-white\">{{ totalPages }}</span>\n <span class=\"ml-1\">({{ totalItems }} registros totales)</span>\n </div>\n\n <div class=\"flex gap-2\">\n <button\n (click)=\"changePage(-1)\"\n [disabled]=\"currentPage === 1\"\n class=\"flex items-center px-4 py-2 border rounded-lg bg-white text-sm font-medium hover:bg-gray-100 disabled:opacity-40 disabled:cursor-not-allowed transition-all dark:bg-gray-700 dark:hover:bg-gray-600 dark:border-gray-600 dark:text-white\"\n >\n Anterior\n </button>\n <button\n (click)=\"changePage(1)\"\n [disabled]=\"currentPage >= totalPages\"\n class=\"flex items-center px-4 py-2 border rounded-lg bg-white text-sm font-medium hover:bg-gray-100 disabled:opacity-40 disabled:cursor-not-allowed transition-all dark:bg-gray-700 dark:hover:bg-gray-600 dark:border-gray-600 dark:text-white\"\n >\n Siguiente\n </button>\n </div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }] });
1788
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: DynamicTableComponent, isStandalone: true, selector: "dynamic-table", inputs: { title: "title", data: "data", headers: "headers", columnComponents: "columnComponents", isLoading: "isLoading", totalItems: "totalItems", itemsPerPage: "itemsPerPage", currentPage: "currentPage", showPagination: "showPagination", showSearch: "showSearch", showTitle: "showTitle" }, outputs: { pageChange: "pageChange", searchChange: "searchChange" }, ngImport: i0, template: "<div class=\"dynamic-table\">\n @if (showTitle || showSearch) {\n <div class=\"dynamic-table-toolbar\">\n @if (showTitle) {\n <h2 class=\"dynamic-table-title\">{{ title }}</h2>\n }\n\n @if (showSearch) {\n <input\n type=\"text\"\n (input)=\"onSearch($event)\"\n placeholder=\"Buscar...\"\n class=\"dynamic-table-search\"\n />\n }\n </div>\n }\n\n <div class=\"dynamic-table-scroll\">\n <table class=\"dynamic-table-table\">\n <thead class=\"dynamic-table-head\">\n <tr>\n @for (header of headers; track header.key) {\n <th class=\"dynamic-table-head-cell\">\n {{ header.label }}\n </th>\n }\n </tr>\n </thead>\n\n <tbody class=\"dynamic-table-body\">\n @if (isLoading) {\n <tr class=\"dynamic-table-row\">\n @for (header of headers; track header.key) {\n <td class=\"dynamic-table-cell\">\n <div class=\"dynamic-table-skeleton\"></div>\n </td>\n }\n </tr>\n }\n\n @for (row of data; track row) {\n <tr class=\"dynamic-table-row\">\n @for (header of headers; track header.key) {\n <td class=\"dynamic-table-cell dynamic-table-cell--nowrap\">\n @if (columnComponents[header.key]) {\n <ng-container\n *ngComponentOutlet=\"columnComponents[header.key]; injector: createInjector(row)\"\n ></ng-container>\n } @else {\n {{ row[header.key] || '---' }}\n }\n </td>\n }\n </tr>\n }\n\n @if ((!data || data.length < 1) && !isLoading) {\n <tr>\n <td [attr.colspan]=\"headers.length\" class=\"dynamic-table-empty\">\n No se encontraron registros en el servidor.\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n\n @if (showPagination) {\n <div class=\"dynamic-table-pagination\">\n <div class=\"dynamic-table-pagination-info\">\n Mostrando p\u00E1gina\n <span class=\"dynamic-table-pagination-strong\">{{ currentPage }}</span> de\n <span class=\"dynamic-table-pagination-strong\">{{ totalPages }}</span>\n <span class=\"dynamic-table-pagination-total\">({{ totalItems }} registros totales)</span>\n </div>\n\n <div class=\"dynamic-table-pagination-actions\">\n <button\n (click)=\"changePage(-1)\"\n [disabled]=\"currentPage === 1\"\n class=\"dynamic-table-pagination-button\"\n >\n Anterior\n </button>\n <button\n (click)=\"changePage(1)\"\n [disabled]=\"currentPage >= totalPages\"\n class=\"dynamic-table-pagination-button\"\n >\n Siguiente\n </button>\n </div>\n </div>\n }\n</div>\n", styles: [".dynamic-table{background-color:#fff;border-radius:.5rem;overflow:hidden;border:1px solid #e5e7eb}@media(prefers-color-scheme:dark){.dynamic-table{background-color:#1f2937;border-color:#374151}}.dynamic-table-toolbar{padding:1rem;border-bottom:1px solid #e5e7eb;display:flex;align-items:center;justify-content:flex-start}@media(prefers-color-scheme:dark){.dynamic-table-toolbar{border-color:#374151}}.dynamic-table-title{font-size:1.125rem;font-weight:600;margin:0}@media(prefers-color-scheme:dark){.dynamic-table-title{color:#fff}}.dynamic-table-search{display:block;margin-left:auto;max-width:24rem;border:1px solid #d1d5db;border-radius:.375rem;background-color:#fff;padding:.375rem .75rem;font-size:1rem;color:#111827;outline:1px solid #d1d5db;outline-offset:-1px}.dynamic-table-search::placeholder{color:#9ca3af}.dynamic-table-search:focus{outline:2px solid #4f46e5;outline-offset:-2px}@media(min-width:640px){.dynamic-table-search{font-size:.875rem}}@media(prefers-color-scheme:dark){.dynamic-table-search{background-color:#ffffff0d;color:#fff;outline-color:#ffffff1a}.dynamic-table-search::placeholder{color:#6b7280}.dynamic-table-search:focus{outline-color:#6366f1}}.dynamic-table-scroll{overflow-x:auto}.dynamic-table-table{width:100%;text-align:left;border-collapse:collapse}.dynamic-table-head{background-color:#f3f4f6;color:#4b5563;font-size:.75rem}@media(prefers-color-scheme:dark){.dynamic-table-head{background-color:#374151;color:#d1d5db}}.dynamic-table-head-cell{padding:.75rem;border-bottom:1px solid #d1d5db;white-space:nowrap}@media(prefers-color-scheme:dark){.dynamic-table-head-cell{border-color:#4b5563}}.dynamic-table-body{color:#374151;font-size:.75rem}@media(prefers-color-scheme:dark){.dynamic-table-body{color:#e5e7eb}}.dynamic-table-row{border-bottom:1px solid #e5e7eb;transition:background-color .15s ease-in-out}.dynamic-table-row:last-child{border-bottom:none}.dynamic-table-row:nth-child(2n){background-color:#f3f4f6}.dynamic-table-row:hover{background-color:#e5e7eb}@media(prefers-color-scheme:dark){.dynamic-table-row{border-color:#374151}.dynamic-table-row:nth-child(2n){background-color:#37415180}.dynamic-table-row:hover{background-color:#374151}}.dynamic-table-cell{padding:.75rem}.dynamic-table-cell--nowrap{white-space:nowrap}.dynamic-table-skeleton{height:1.25rem;width:100%;background-color:#e5e7eb;border-radius:.375rem;animation:dynamic-table-pulse 2s cubic-bezier(.4,0,.6,1) infinite}@media(prefers-color-scheme:dark){.dynamic-table-skeleton{background-color:#4b5563}}.dynamic-table-empty{padding:1.5rem;text-align:center;color:#9ca3af;font-style:italic}@media(prefers-color-scheme:dark){.dynamic-table-empty{color:#6b7280}}.dynamic-table-pagination{padding:1rem;display:flex;align-items:center;justify-content:space-between;background-color:#f9fafb;border-top:1px solid #d1d5db}@media(prefers-color-scheme:dark){.dynamic-table-pagination{background-color:#1f293780;border-color:#374151}}.dynamic-table-pagination-info{font-size:.875rem;color:#6b7280}@media(prefers-color-scheme:dark){.dynamic-table-pagination-info{color:#9ca3af}}.dynamic-table-pagination-strong{font-weight:600;color:#1f2937}@media(prefers-color-scheme:dark){.dynamic-table-pagination-strong{color:#fff}}.dynamic-table-pagination-total{margin-left:.25rem}.dynamic-table-pagination-actions{display:flex;gap:.5rem}.dynamic-table-pagination-button{display:flex;align-items:center;padding:.5rem 1rem;border:1px solid #d1d5db;border-radius:.5rem;background-color:#fff;font-size:.875rem;font-weight:500;transition:all .15s ease-in-out}.dynamic-table-pagination-button:hover{background-color:#f3f4f6}.dynamic-table-pagination-button:disabled{opacity:.4;cursor:not-allowed}@media(prefers-color-scheme:dark){.dynamic-table-pagination-button{background-color:#374151;border-color:#4b5563;color:#fff}.dynamic-table-pagination-button:hover{background-color:#4b5563}}@keyframes dynamic-table-pulse{0%,to{opacity:1}50%{opacity:.5}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }] });
1656
1789
  }
1657
1790
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DynamicTableComponent, decorators: [{
1658
1791
  type: Component,
1659
- args: [{ selector: 'dynamic-table', standalone: true, imports: [CommonModule], template: "<div\n class=\"bg-white rounded-lg overflow-hidden border border-gray-200 dark:bg-gray-800 dark:border-gray-700\"\n>\n @if (showTitle || showSearch) {\n <div class=\"p-4 border-b border-gray-200 flex items-center justify-start dark:border-gray-700\">\n @if (showTitle) {\n <h2 class=\"text-lg font-semibold dark:text-white\">{{ title }}</h2>\n }\n\n @if (showSearch) {\n <input\n type=\"text\"\n (input)=\"onSearch($event)\"\n placeholder=\"Buscar...\"\n class=\"ml-auto block w-sm rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6 dark:bg-white/5 dark:text-white dark:outline-white/10 dark:placeholder:text-gray-500 dark:focus:outline-indigo-500\"\n />\n }\n </div>\n }\n\n <div class=\"overflow-x-auto\">\n <table class=\"w-full text-left border-collapse\">\n <thead class=\"bg-gray-100 text-gray-600 text-xs dark:bg-gray-700 dark:text-gray-300\">\n <tr>\n @for (header of headers; track header.key) {\n <th class=\"p-3 border-b border-gray-300 whitespace-nowrap dark:border-gray-600\">\n {{ header.label }}\n </th>\n }\n </tr>\n </thead>\n\n <tbody class=\"text-gray-700 text-xs dark:text-gray-200\">\n @if (isLoading) {\n <tr\n class=\"border-b even:bg-gray-100 border-gray-200 last:border-none transition-colors dark:even:bg-gray-700/50 dark:border-gray-700\"\n >\n @for (header of headers; track header.key) {\n <td class=\"p-3\">\n <div class=\"h-5 bg-gray-200 rounded animate-pulse w-full dark:bg-gray-600\"></div>\n </td>\n }\n </tr>\n }\n\n @for (row of data; track row) {\n <tr\n class=\"hover:bg-gray-200 border-b even:bg-gray-100 border-gray-200 last:border-none transition-colors dark:hover:bg-gray-700 dark:even:bg-gray-700/50 dark:border-gray-700\"\n >\n @for (header of headers; track header.key) {\n <td class=\"p-3 whitespace-nowrap\">\n @if (columnComponents[header.key]) {\n <ng-container\n *ngComponentOutlet=\"columnComponents[header.key]; injector: createInjector(row)\"\n ></ng-container>\n } @else {\n {{ row[header.key] || '---' }}\n }\n </td>\n }\n </tr>\n }\n\n @if ((!data || data.length < 1) && !isLoading) {\n <tr>\n <td\n [attr.colspan]=\"headers.length\"\n class=\"p-6 text-center text-gray-400 italic dark:text-gray-500\"\n >\n No se encontraron registros en el servidor.\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n\n @if (showPagination) {\n <div\n class=\"p-4 flex items-center justify-between bg-gray-50 border-gray-300 border-t dark:bg-gray-800/50 dark:border-gray-700\"\n >\n <div class=\"text-sm text-gray-500 dark:text-gray-400\">\n Mostrando p\u00E1gina\n <span class=\"font-semibold text-gray-800 dark:text-white\">{{ currentPage }}</span> de\n <span class=\"font-semibold text-gray-800 dark:text-white\">{{ totalPages }}</span>\n <span class=\"ml-1\">({{ totalItems }} registros totales)</span>\n </div>\n\n <div class=\"flex gap-2\">\n <button\n (click)=\"changePage(-1)\"\n [disabled]=\"currentPage === 1\"\n class=\"flex items-center px-4 py-2 border rounded-lg bg-white text-sm font-medium hover:bg-gray-100 disabled:opacity-40 disabled:cursor-not-allowed transition-all dark:bg-gray-700 dark:hover:bg-gray-600 dark:border-gray-600 dark:text-white\"\n >\n Anterior\n </button>\n <button\n (click)=\"changePage(1)\"\n [disabled]=\"currentPage >= totalPages\"\n class=\"flex items-center px-4 py-2 border rounded-lg bg-white text-sm font-medium hover:bg-gray-100 disabled:opacity-40 disabled:cursor-not-allowed transition-all dark:bg-gray-700 dark:hover:bg-gray-600 dark:border-gray-600 dark:text-white\"\n >\n Siguiente\n </button>\n </div>\n </div>\n }\n</div>\n" }]
1792
+ args: [{ selector: 'dynamic-table', standalone: true, imports: [CommonModule], template: "<div class=\"dynamic-table\">\n @if (showTitle || showSearch) {\n <div class=\"dynamic-table-toolbar\">\n @if (showTitle) {\n <h2 class=\"dynamic-table-title\">{{ title }}</h2>\n }\n\n @if (showSearch) {\n <input\n type=\"text\"\n (input)=\"onSearch($event)\"\n placeholder=\"Buscar...\"\n class=\"dynamic-table-search\"\n />\n }\n </div>\n }\n\n <div class=\"dynamic-table-scroll\">\n <table class=\"dynamic-table-table\">\n <thead class=\"dynamic-table-head\">\n <tr>\n @for (header of headers; track header.key) {\n <th class=\"dynamic-table-head-cell\">\n {{ header.label }}\n </th>\n }\n </tr>\n </thead>\n\n <tbody class=\"dynamic-table-body\">\n @if (isLoading) {\n <tr class=\"dynamic-table-row\">\n @for (header of headers; track header.key) {\n <td class=\"dynamic-table-cell\">\n <div class=\"dynamic-table-skeleton\"></div>\n </td>\n }\n </tr>\n }\n\n @for (row of data; track row) {\n <tr class=\"dynamic-table-row\">\n @for (header of headers; track header.key) {\n <td class=\"dynamic-table-cell dynamic-table-cell--nowrap\">\n @if (columnComponents[header.key]) {\n <ng-container\n *ngComponentOutlet=\"columnComponents[header.key]; injector: createInjector(row)\"\n ></ng-container>\n } @else {\n {{ row[header.key] || '---' }}\n }\n </td>\n }\n </tr>\n }\n\n @if ((!data || data.length < 1) && !isLoading) {\n <tr>\n <td [attr.colspan]=\"headers.length\" class=\"dynamic-table-empty\">\n No se encontraron registros en el servidor.\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n\n @if (showPagination) {\n <div class=\"dynamic-table-pagination\">\n <div class=\"dynamic-table-pagination-info\">\n Mostrando p\u00E1gina\n <span class=\"dynamic-table-pagination-strong\">{{ currentPage }}</span> de\n <span class=\"dynamic-table-pagination-strong\">{{ totalPages }}</span>\n <span class=\"dynamic-table-pagination-total\">({{ totalItems }} registros totales)</span>\n </div>\n\n <div class=\"dynamic-table-pagination-actions\">\n <button\n (click)=\"changePage(-1)\"\n [disabled]=\"currentPage === 1\"\n class=\"dynamic-table-pagination-button\"\n >\n Anterior\n </button>\n <button\n (click)=\"changePage(1)\"\n [disabled]=\"currentPage >= totalPages\"\n class=\"dynamic-table-pagination-button\"\n >\n Siguiente\n </button>\n </div>\n </div>\n }\n</div>\n", styles: [".dynamic-table{background-color:#fff;border-radius:.5rem;overflow:hidden;border:1px solid #e5e7eb}@media(prefers-color-scheme:dark){.dynamic-table{background-color:#1f2937;border-color:#374151}}.dynamic-table-toolbar{padding:1rem;border-bottom:1px solid #e5e7eb;display:flex;align-items:center;justify-content:flex-start}@media(prefers-color-scheme:dark){.dynamic-table-toolbar{border-color:#374151}}.dynamic-table-title{font-size:1.125rem;font-weight:600;margin:0}@media(prefers-color-scheme:dark){.dynamic-table-title{color:#fff}}.dynamic-table-search{display:block;margin-left:auto;max-width:24rem;border:1px solid #d1d5db;border-radius:.375rem;background-color:#fff;padding:.375rem .75rem;font-size:1rem;color:#111827;outline:1px solid #d1d5db;outline-offset:-1px}.dynamic-table-search::placeholder{color:#9ca3af}.dynamic-table-search:focus{outline:2px solid #4f46e5;outline-offset:-2px}@media(min-width:640px){.dynamic-table-search{font-size:.875rem}}@media(prefers-color-scheme:dark){.dynamic-table-search{background-color:#ffffff0d;color:#fff;outline-color:#ffffff1a}.dynamic-table-search::placeholder{color:#6b7280}.dynamic-table-search:focus{outline-color:#6366f1}}.dynamic-table-scroll{overflow-x:auto}.dynamic-table-table{width:100%;text-align:left;border-collapse:collapse}.dynamic-table-head{background-color:#f3f4f6;color:#4b5563;font-size:.75rem}@media(prefers-color-scheme:dark){.dynamic-table-head{background-color:#374151;color:#d1d5db}}.dynamic-table-head-cell{padding:.75rem;border-bottom:1px solid #d1d5db;white-space:nowrap}@media(prefers-color-scheme:dark){.dynamic-table-head-cell{border-color:#4b5563}}.dynamic-table-body{color:#374151;font-size:.75rem}@media(prefers-color-scheme:dark){.dynamic-table-body{color:#e5e7eb}}.dynamic-table-row{border-bottom:1px solid #e5e7eb;transition:background-color .15s ease-in-out}.dynamic-table-row:last-child{border-bottom:none}.dynamic-table-row:nth-child(2n){background-color:#f3f4f6}.dynamic-table-row:hover{background-color:#e5e7eb}@media(prefers-color-scheme:dark){.dynamic-table-row{border-color:#374151}.dynamic-table-row:nth-child(2n){background-color:#37415180}.dynamic-table-row:hover{background-color:#374151}}.dynamic-table-cell{padding:.75rem}.dynamic-table-cell--nowrap{white-space:nowrap}.dynamic-table-skeleton{height:1.25rem;width:100%;background-color:#e5e7eb;border-radius:.375rem;animation:dynamic-table-pulse 2s cubic-bezier(.4,0,.6,1) infinite}@media(prefers-color-scheme:dark){.dynamic-table-skeleton{background-color:#4b5563}}.dynamic-table-empty{padding:1.5rem;text-align:center;color:#9ca3af;font-style:italic}@media(prefers-color-scheme:dark){.dynamic-table-empty{color:#6b7280}}.dynamic-table-pagination{padding:1rem;display:flex;align-items:center;justify-content:space-between;background-color:#f9fafb;border-top:1px solid #d1d5db}@media(prefers-color-scheme:dark){.dynamic-table-pagination{background-color:#1f293780;border-color:#374151}}.dynamic-table-pagination-info{font-size:.875rem;color:#6b7280}@media(prefers-color-scheme:dark){.dynamic-table-pagination-info{color:#9ca3af}}.dynamic-table-pagination-strong{font-weight:600;color:#1f2937}@media(prefers-color-scheme:dark){.dynamic-table-pagination-strong{color:#fff}}.dynamic-table-pagination-total{margin-left:.25rem}.dynamic-table-pagination-actions{display:flex;gap:.5rem}.dynamic-table-pagination-button{display:flex;align-items:center;padding:.5rem 1rem;border:1px solid #d1d5db;border-radius:.5rem;background-color:#fff;font-size:.875rem;font-weight:500;transition:all .15s ease-in-out}.dynamic-table-pagination-button:hover{background-color:#f3f4f6}.dynamic-table-pagination-button:disabled{opacity:.4;cursor:not-allowed}@media(prefers-color-scheme:dark){.dynamic-table-pagination-button{background-color:#374151;border-color:#4b5563;color:#fff}.dynamic-table-pagination-button:hover{background-color:#4b5563}}@keyframes dynamic-table-pulse{0%,to{opacity:1}50%{opacity:.5}}\n"] }]
1660
1793
  }], ctorParameters: () => [{ type: i0.Injector }], propDecorators: { title: [{
1661
1794
  type: Input
1662
1795
  }], data: [{
@@ -1696,49 +1829,15 @@ class LanguageSwitcherComponent {
1696
1829
  }
1697
1830
  switchLang(lang) {
1698
1831
  this.transloco.setActiveLang(lang);
1832
+ setStoredLanguage(lang);
1699
1833
  }
1700
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: LanguageSwitcherComponent, deps: [{ token: i2.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
1701
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: LanguageSwitcherComponent, isStandalone: true, selector: "language-switcher", ngImport: i0, template: `
1702
- <div class="flex items-center gap-1">
1703
- @for (lang of availableLangs; track lang) {
1704
- <button
1705
- (click)="switchLang(lang)"
1706
- class="cursor-pointer px-2 py-1 text-xs font-medium rounded transition-colors"
1707
- [class.bg-gray-800]="activeLang === lang"
1708
- [class.text-white]="activeLang === lang"
1709
- [class.text-gray-400]="activeLang !== lang"
1710
- [class.hover:text-white]="activeLang !== lang"
1711
- >
1712
- {{ lang | uppercase }}
1713
- </button>
1714
- }
1715
- </div>
1716
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2$1.UpperCasePipe, name: "uppercase" }] });
1834
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: LanguageSwitcherComponent, deps: [{ token: i2$1.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
1835
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: LanguageSwitcherComponent, isStandalone: true, selector: "language-switcher", ngImport: i0, template: "<div class=\"lang-switcher\">\n @for (lang of availableLangs; track lang) {\n <button\n (click)=\"switchLang(lang)\"\n class=\"lang-switcher-btn\"\n [class.active]=\"activeLang === lang\"\n [class.inactive]=\"activeLang !== lang\"\n >\n {{ lang | uppercase }}\n </button>\n }\n</div>\n", styles: [":host{display:block}.lang-switcher{display:flex;align-items:center;gap:.25rem}.lang-switcher-btn{cursor:pointer;padding:.25rem .5rem;font-size:.75rem;font-weight:500;border-radius:.125rem;transition:all .15s ease-in-out;border:none;background:transparent}.lang-switcher-btn.active{background-color:#1f2937;color:#fff}@media(prefers-color-scheme:dark){.lang-switcher-btn.active{background-color:#374151}}.lang-switcher-btn.inactive{color:#9ca3af}.lang-switcher-btn.inactive:hover{color:#fff}@media(prefers-color-scheme:dark){.lang-switcher-btn.inactive{color:#6b7280}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2.UpperCasePipe, name: "uppercase" }] });
1717
1836
  }
1718
1837
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: LanguageSwitcherComponent, decorators: [{
1719
1838
  type: Component,
1720
- args: [{
1721
- selector: 'language-switcher',
1722
- standalone: true,
1723
- imports: [CommonModule, TranslocoModule],
1724
- template: `
1725
- <div class="flex items-center gap-1">
1726
- @for (lang of availableLangs; track lang) {
1727
- <button
1728
- (click)="switchLang(lang)"
1729
- class="cursor-pointer px-2 py-1 text-xs font-medium rounded transition-colors"
1730
- [class.bg-gray-800]="activeLang === lang"
1731
- [class.text-white]="activeLang === lang"
1732
- [class.text-gray-400]="activeLang !== lang"
1733
- [class.hover:text-white]="activeLang !== lang"
1734
- >
1735
- {{ lang | uppercase }}
1736
- </button>
1737
- }
1738
- </div>
1739
- `,
1740
- }]
1741
- }], ctorParameters: () => [{ type: i2.TranslocoService }] });
1839
+ args: [{ selector: 'language-switcher', standalone: true, imports: [CommonModule, TranslocoModule], template: "<div class=\"lang-switcher\">\n @for (lang of availableLangs; track lang) {\n <button\n (click)=\"switchLang(lang)\"\n class=\"lang-switcher-btn\"\n [class.active]=\"activeLang === lang\"\n [class.inactive]=\"activeLang !== lang\"\n >\n {{ lang | uppercase }}\n </button>\n }\n</div>\n", styles: [":host{display:block}.lang-switcher{display:flex;align-items:center;gap:.25rem}.lang-switcher-btn{cursor:pointer;padding:.25rem .5rem;font-size:.75rem;font-weight:500;border-radius:.125rem;transition:all .15s ease-in-out;border:none;background:transparent}.lang-switcher-btn.active{background-color:#1f2937;color:#fff}@media(prefers-color-scheme:dark){.lang-switcher-btn.active{background-color:#374151}}.lang-switcher-btn.inactive{color:#9ca3af}.lang-switcher-btn.inactive:hover{color:#fff}@media(prefers-color-scheme:dark){.lang-switcher-btn.inactive{color:#6b7280}}\n"] }]
1840
+ }], ctorParameters: () => [{ type: i2$1.TranslocoService }] });
1742
1841
 
1743
1842
  class FormSelectComponent {
1744
1843
  ngControl;
@@ -1802,9 +1901,6 @@ class FormSelectComponent {
1802
1901
  get resolvedDefaultOptionLabel() {
1803
1902
  return this.defaultOptionLabel || this.transloco.translate('common.selectOption');
1804
1903
  }
1805
- get selectClasses() {
1806
- return this.showError ? ERROR_INPUT_CLASSES : BASE_INPUT_CLASSES;
1807
- }
1808
1904
  get fieldGroupClasses() {
1809
1905
  let baseClasses = '';
1810
1906
  if (this.fieldGroupClass) {
@@ -1815,17 +1911,17 @@ class FormSelectComponent {
1815
1911
  }
1816
1912
  return baseClasses;
1817
1913
  }
1818
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: FormSelectComponent, deps: [{ token: i1$1.NgControl, optional: true, self: true }, { token: i2.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
1819
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: FormSelectComponent, isStandalone: true, selector: "form-select", inputs: { label: "label", name: "name", id: "id", placeholder: "placeholder", required: "required", disabled: "disabled", readonly: "readonly", options: "options", fieldGroupClass: "fieldGroupClass", showDefaultOption: "showDefaultOption", defaultOptionLabel: "defaultOptionLabel" }, ngImport: i0, template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <select\n [id]=\"inputId\"\n [name]=\"name\"\n [required]=\"required\"\n [disabled]=\"disabled\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onSelectChange($event)\"\n (blur)=\"onTouched()\"\n [class]=\"selectClasses\"\n [class.bg-white]=\"!readonly\"\n [class.bg-gray-200]=\"readonly\"\n [class.cursor-not-allowed]=\"readonly\"\n >\n @if (showDefaultOption) {\n <option [value]=\"null\" disabled selected>{{ resolvedDefaultOptionLabel }}</option>\n }\n\n @for (option of options; track option.value) {\n <option [value]=\"option.value\" [disabled]=\"option.disabled\">\n {{ option.label }}\n </option>\n }\n </select>\n </div>\n\n @if (showError) {\n <div class=\"text-red-500 text-xs mt-1\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", styles: ["select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url(\"data:image/svg+xml;charset=US-ASCII,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:right .75rem center;background-size:1em;padding-right:2.5rem}select::-ms-expand{display:none}@-moz-document url-prefix(){select{text-indent:.01px;text-overflow:\"\";padding-right:.75rem}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }] });
1914
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: FormSelectComponent, deps: [{ token: i1$1.NgControl, optional: true, self: true }, { token: i2$1.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
1915
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: FormSelectComponent, isStandalone: true, selector: "form-select", inputs: { label: "label", name: "name", id: "id", placeholder: "placeholder", required: "required", disabled: "disabled", readonly: "readonly", options: "options", fieldGroupClass: "fieldGroupClass", showDefaultOption: "showDefaultOption", defaultOptionLabel: "defaultOptionLabel" }, ngImport: i0, template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"form-select-label\">\n {{ label }}\n\n @if (required) {\n <span class=\"form-select-required\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <select\n [id]=\"inputId\"\n [name]=\"name\"\n [required]=\"required\"\n [disabled]=\"disabled\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onSelectChange($event)\"\n (blur)=\"onTouched()\"\n class=\"form-select\"\n [class.disabled]=\"readonly\"\n [class.error]=\"showError\"\n >\n @if (showDefaultOption) {\n <option [value]=\"null\" disabled selected>{{ resolvedDefaultOptionLabel }}</option>\n }\n\n @for (option of options; track option.value) {\n <option [value]=\"option.value\" [disabled]=\"option.disabled\">\n {{ option.label }}\n </option>\n }\n </select>\n </div>\n\n @if (showError) {\n <div class=\"form-select-error-message\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", styles: [".form-select-label{color:#374151;display:block;font-size:.875rem;font-weight:600;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.form-select-label{color:#d1d5db}}.form-select{background-color:#fff;border:1px solid #d1d5db;border-radius:.375rem;color:#111827;display:block;padding:.375rem 2.5rem .375rem .75rem;outline:1px solid #d1d5db;outline-offset:1px;width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url(\"data:image/svg+xml;charset=US-ASCII,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:right .75rem center;background-size:1em}.form-select::-ms-expand{display:none}@-moz-document url-prefix(){.form-select{text-indent:.01px;text-overflow:\"\";padding-right:.75rem}}.form-select:focus{outline:2px solid #4f46e5;outline-offset:2px}.form-select.error{outline-color:#ef4444}@media(prefers-color-scheme:dark){.form-select.error{background-color:#374151;color:#fff;outline-color:#ef4444}}.form-select.disabled{background-color:#e5e7eb;color:#6b7280;cursor:not-allowed}@media(prefers-color-scheme:dark){.form-select.disabled{background-color:#374151;color:#d1d5db}}@media(min-width:768px){.form-select{font-size:.875rem}}.form-select-required{color:#ef4444}.form-select-error-message{color:#ef4444;font-size:.75rem;margin-top:.25rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }] });
1820
1916
  }
1821
1917
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: FormSelectComponent, decorators: [{
1822
1918
  type: Component,
1823
- args: [{ selector: 'form-select', standalone: true, imports: [FormsModule, CommonModule, ReactiveFormsModule], template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <select\n [id]=\"inputId\"\n [name]=\"name\"\n [required]=\"required\"\n [disabled]=\"disabled\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onSelectChange($event)\"\n (blur)=\"onTouched()\"\n [class]=\"selectClasses\"\n [class.bg-white]=\"!readonly\"\n [class.bg-gray-200]=\"readonly\"\n [class.cursor-not-allowed]=\"readonly\"\n >\n @if (showDefaultOption) {\n <option [value]=\"null\" disabled selected>{{ resolvedDefaultOptionLabel }}</option>\n }\n\n @for (option of options; track option.value) {\n <option [value]=\"option.value\" [disabled]=\"option.disabled\">\n {{ option.label }}\n </option>\n }\n </select>\n </div>\n\n @if (showError) {\n <div class=\"text-red-500 text-xs mt-1\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", styles: ["select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url(\"data:image/svg+xml;charset=US-ASCII,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:right .75rem center;background-size:1em;padding-right:2.5rem}select::-ms-expand{display:none}@-moz-document url-prefix(){select{text-indent:.01px;text-overflow:\"\";padding-right:.75rem}}\n"] }]
1919
+ args: [{ selector: 'form-select', standalone: true, imports: [FormsModule, CommonModule, ReactiveFormsModule], template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"form-select-label\">\n {{ label }}\n\n @if (required) {\n <span class=\"form-select-required\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <select\n [id]=\"inputId\"\n [name]=\"name\"\n [required]=\"required\"\n [disabled]=\"disabled\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onSelectChange($event)\"\n (blur)=\"onTouched()\"\n class=\"form-select\"\n [class.disabled]=\"readonly\"\n [class.error]=\"showError\"\n >\n @if (showDefaultOption) {\n <option [value]=\"null\" disabled selected>{{ resolvedDefaultOptionLabel }}</option>\n }\n\n @for (option of options; track option.value) {\n <option [value]=\"option.value\" [disabled]=\"option.disabled\">\n {{ option.label }}\n </option>\n }\n </select>\n </div>\n\n @if (showError) {\n <div class=\"form-select-error-message\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", styles: [".form-select-label{color:#374151;display:block;font-size:.875rem;font-weight:600;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.form-select-label{color:#d1d5db}}.form-select{background-color:#fff;border:1px solid #d1d5db;border-radius:.375rem;color:#111827;display:block;padding:.375rem 2.5rem .375rem .75rem;outline:1px solid #d1d5db;outline-offset:1px;width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url(\"data:image/svg+xml;charset=US-ASCII,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:right .75rem center;background-size:1em}.form-select::-ms-expand{display:none}@-moz-document url-prefix(){.form-select{text-indent:.01px;text-overflow:\"\";padding-right:.75rem}}.form-select:focus{outline:2px solid #4f46e5;outline-offset:2px}.form-select.error{outline-color:#ef4444}@media(prefers-color-scheme:dark){.form-select.error{background-color:#374151;color:#fff;outline-color:#ef4444}}.form-select.disabled{background-color:#e5e7eb;color:#6b7280;cursor:not-allowed}@media(prefers-color-scheme:dark){.form-select.disabled{background-color:#374151;color:#d1d5db}}@media(min-width:768px){.form-select{font-size:.875rem}}.form-select-required{color:#ef4444}.form-select-error-message{color:#ef4444;font-size:.75rem;margin-top:.25rem}\n"] }]
1824
1920
  }], ctorParameters: () => [{ type: i1$1.NgControl, decorators: [{
1825
1921
  type: Self
1826
1922
  }, {
1827
1923
  type: Optional
1828
- }] }, { type: i2.TranslocoService }], propDecorators: { label: [{
1924
+ }] }, { type: i2$1.TranslocoService }], propDecorators: { label: [{
1829
1925
  type: Input
1830
1926
  }], name: [{
1831
1927
  type: Input
@@ -1919,9 +2015,6 @@ class FormTextareaComponent {
1919
2015
  }
1920
2016
  return this.transloco.translate(`formErrors.${errorKey}`);
1921
2017
  }
1922
- get inputClasses() {
1923
- return this.showError ? ERROR_INPUT_CLASSES : BASE_INPUT_CLASSES;
1924
- }
1925
2018
  get fieldGroupClasses() {
1926
2019
  let baseClasses = '';
1927
2020
  if (this.fieldGroupClass) {
@@ -1932,17 +2025,17 @@ class FormTextareaComponent {
1932
2025
  }
1933
2026
  return baseClasses;
1934
2027
  }
1935
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: FormTextareaComponent, deps: [{ token: i1$1.NgControl, optional: true, self: true }, { token: i2.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
1936
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: FormTextareaComponent, isStandalone: true, selector: "form-textarea", inputs: { label: "label", name: "name", id: "id", placeholder: "placeholder", required: "required", readonly: "readonly", minlength: "minlength", maxlength: "maxlength", rows: "rows", cols: "cols", fieldGroupClass: "fieldGroupClass" }, ngImport: i0, template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <textarea\n [id]=\"inputId\"\n [name]=\"name\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [minlength]=\"minlength\"\n [maxlength]=\"maxlength\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onInput($event)\"\n (blur)=\"onTouched()\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n [class.bg-white]=\"!readonly\"\n [class.bg-gray-200]=\"readonly\"\n [class.cursor-not-allowed]=\"readonly\"\n [class]=\"inputClasses\"\n ></textarea>\n </div>\n\n @if (showError) {\n <div class=\"text-red-500 text-xs mt-1\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }] });
2028
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: FormTextareaComponent, deps: [{ token: i1$1.NgControl, optional: true, self: true }, { token: i2$1.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
2029
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: FormTextareaComponent, isStandalone: true, selector: "form-textarea", inputs: { label: "label", name: "name", id: "id", placeholder: "placeholder", required: "required", readonly: "readonly", minlength: "minlength", maxlength: "maxlength", rows: "rows", cols: "cols", fieldGroupClass: "fieldGroupClass" }, ngImport: i0, template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"form-textarea-label\">\n {{ label }}\n\n @if (required) {\n <span class=\"form-textarea-required\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <textarea\n [id]=\"inputId\"\n [name]=\"name\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [minlength]=\"minlength\"\n [maxlength]=\"maxlength\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onInput($event)\"\n (blur)=\"onTouched()\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n class=\"form-textarea\"\n [class.disabled]=\"readonly\"\n [class.error]=\"showError\"\n ></textarea>\n </div>\n\n @if (showError) {\n <div class=\"form-textarea-error-message\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", styles: [".form-textarea-label{color:#374151;display:block;font-size:.875rem;font-weight:600;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.form-textarea-label{color:#d1d5db}}.form-textarea{background-color:#fff;border:1px solid #d1d5db;border-radius:.375rem;color:#111827;display:block;padding:.375rem .75rem;outline:1px solid #d1d5db;outline-offset:1px;width:100%}.form-textarea::placeholder{color:#9ca3af}.form-textarea:focus{outline:2px solid #4f46e5;outline-offset:2px}.form-textarea.error{outline-color:#ef4444}@media(prefers-color-scheme:dark){.form-textarea.error{background-color:#374151;color:#fff;outline-color:#ef4444}}.form-textarea.disabled{background-color:#e5e7eb;color:#6b7280;cursor:not-allowed}@media(prefers-color-scheme:dark){.form-textarea.disabled{background-color:#374151;color:#d1d5db}}@media(min-width:768px){.form-textarea{font-size:.875rem}}.form-textarea-required{color:#ef4444}.form-textarea-error-message{color:#ef4444;font-size:.75rem;margin-top:.25rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }] });
1937
2030
  }
1938
2031
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: FormTextareaComponent, decorators: [{
1939
2032
  type: Component,
1940
- args: [{ selector: 'form-textarea', standalone: true, imports: [FormsModule, CommonModule, ReactiveFormsModule], template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <textarea\n [id]=\"inputId\"\n [name]=\"name\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [minlength]=\"minlength\"\n [maxlength]=\"maxlength\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onInput($event)\"\n (blur)=\"onTouched()\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n [class.bg-white]=\"!readonly\"\n [class.bg-gray-200]=\"readonly\"\n [class.cursor-not-allowed]=\"readonly\"\n [class]=\"inputClasses\"\n ></textarea>\n </div>\n\n @if (showError) {\n <div class=\"text-red-500 text-xs mt-1\">\n {{ errorMessage }}\n </div>\n }\n</div>\n" }]
2033
+ args: [{ selector: 'form-textarea', standalone: true, imports: [FormsModule, CommonModule, ReactiveFormsModule], template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"form-textarea-label\">\n {{ label }}\n\n @if (required) {\n <span class=\"form-textarea-required\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <textarea\n [id]=\"inputId\"\n [name]=\"name\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [minlength]=\"minlength\"\n [maxlength]=\"maxlength\"\n [rows]=\"rows\"\n [cols]=\"cols\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onInput($event)\"\n (blur)=\"onTouched()\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n class=\"form-textarea\"\n [class.disabled]=\"readonly\"\n [class.error]=\"showError\"\n ></textarea>\n </div>\n\n @if (showError) {\n <div class=\"form-textarea-error-message\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", styles: [".form-textarea-label{color:#374151;display:block;font-size:.875rem;font-weight:600;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.form-textarea-label{color:#d1d5db}}.form-textarea{background-color:#fff;border:1px solid #d1d5db;border-radius:.375rem;color:#111827;display:block;padding:.375rem .75rem;outline:1px solid #d1d5db;outline-offset:1px;width:100%}.form-textarea::placeholder{color:#9ca3af}.form-textarea:focus{outline:2px solid #4f46e5;outline-offset:2px}.form-textarea.error{outline-color:#ef4444}@media(prefers-color-scheme:dark){.form-textarea.error{background-color:#374151;color:#fff;outline-color:#ef4444}}.form-textarea.disabled{background-color:#e5e7eb;color:#6b7280;cursor:not-allowed}@media(prefers-color-scheme:dark){.form-textarea.disabled{background-color:#374151;color:#d1d5db}}@media(min-width:768px){.form-textarea{font-size:.875rem}}.form-textarea-required{color:#ef4444}.form-textarea-error-message{color:#ef4444;font-size:.75rem;margin-top:.25rem}\n"] }]
1941
2034
  }], ctorParameters: () => [{ type: i1$1.NgControl, decorators: [{
1942
2035
  type: Self
1943
2036
  }, {
1944
2037
  type: Optional
1945
- }] }, { type: i2.TranslocoService }], propDecorators: { label: [{
2038
+ }] }, { type: i2$1.TranslocoService }], propDecorators: { label: [{
1946
2039
  type: Input
1947
2040
  }], name: [{
1948
2041
  type: Input
@@ -2058,8 +2151,8 @@ class FormEditorComponent {
2058
2151
  }
2059
2152
  return baseClasses;
2060
2153
  }
2061
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: FormEditorComponent, deps: [{ token: i1$1.NgControl, optional: true, self: true }, { token: i2.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
2062
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: FormEditorComponent, isStandalone: true, selector: "form-editor", inputs: { label: "label", name: "name", id: "id", placeholder: "placeholder", required: "required", readonly: "readonly", toolbar: "toolbar", fieldGroupClass: "fieldGroupClass" }, ngImport: i0, template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div\n class=\"relative\"\n [class.opacity-50]=\"disabled\"\n [class.pointer-events-none]=\"disabled\"\n [class.cursor-not-allowed]=\"disabled\"\n >\n <ngx-editor [editor]=\"editor\" outputFormat=\"html\" [placeholder]=\"placeholder\">\n <ngx-editor-menu\n [editor]=\"editor\"\n [toolbar]=\"toolbar\"\n [disabled]=\"disabled\"\n ></ngx-editor-menu>\n </ngx-editor>\n </div>\n\n @if (showError) {\n <div class=\"text-red-500 text-xs mt-1\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: NgxEditorComponent, selector: "ngx-editor", inputs: ["editor", "outputFormat", "placeholder"], outputs: ["focusOut", "focusIn"] }, { kind: "component", type: NgxEditorMenuComponent, selector: "ngx-editor-menu", inputs: ["toolbar", "colorPresets", "disabled", "editor", "customMenuRef", "dropdownPlacement"] }] });
2154
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: FormEditorComponent, deps: [{ token: i1$1.NgControl, optional: true, self: true }, { token: i2$1.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
2155
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: FormEditorComponent, isStandalone: true, selector: "form-editor", inputs: { label: "label", name: "name", id: "id", placeholder: "placeholder", required: "required", readonly: "readonly", toolbar: "toolbar", fieldGroupClass: "fieldGroupClass" }, ngImport: i0, template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"form-editor-label\">\n {{ label }}\n\n @if (required) {\n <span class=\"form-editor-required\">*</span>\n }\n </label>\n }\n\n <div class=\"form-editor-wrapper\" [class.disabled]=\"disabled\">\n <ngx-editor [editor]=\"editor\" outputFormat=\"html\" [placeholder]=\"placeholder\">\n <ngx-editor-menu\n [editor]=\"editor\"\n [toolbar]=\"toolbar\"\n [disabled]=\"disabled\"\n ></ngx-editor-menu>\n </ngx-editor>\n </div>\n\n @if (showError) {\n <div class=\"form-editor-error-message\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", styles: [".form-editor-label{color:#374151;display:block;font-size:.875rem;font-weight:600;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.form-editor-label{color:#d1d5db}}.form-editor-wrapper{position:relative}.form-editor-wrapper.disabled{opacity:.5;pointer-events:none;cursor:not-allowed}.form-editor-required{color:#ef4444}.form-editor-error-message{color:#ef4444;font-size:.75rem;margin-top:.25rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: NgxEditorComponent, selector: "ngx-editor", inputs: ["editor", "outputFormat", "placeholder"], outputs: ["focusOut", "focusIn"] }, { kind: "component", type: NgxEditorMenuComponent, selector: "ngx-editor-menu", inputs: ["toolbar", "colorPresets", "disabled", "editor", "customMenuRef", "dropdownPlacement"] }] });
2063
2156
  }
2064
2157
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: FormEditorComponent, decorators: [{
2065
2158
  type: Component,
@@ -2069,12 +2162,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
2069
2162
  ReactiveFormsModule,
2070
2163
  NgxEditorComponent,
2071
2164
  NgxEditorMenuComponent,
2072
- ], template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div\n class=\"relative\"\n [class.opacity-50]=\"disabled\"\n [class.pointer-events-none]=\"disabled\"\n [class.cursor-not-allowed]=\"disabled\"\n >\n <ngx-editor [editor]=\"editor\" outputFormat=\"html\" [placeholder]=\"placeholder\">\n <ngx-editor-menu\n [editor]=\"editor\"\n [toolbar]=\"toolbar\"\n [disabled]=\"disabled\"\n ></ngx-editor-menu>\n </ngx-editor>\n </div>\n\n @if (showError) {\n <div class=\"text-red-500 text-xs mt-1\">\n {{ errorMessage }}\n </div>\n }\n</div>\n" }]
2165
+ ], template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"form-editor-label\">\n {{ label }}\n\n @if (required) {\n <span class=\"form-editor-required\">*</span>\n }\n </label>\n }\n\n <div class=\"form-editor-wrapper\" [class.disabled]=\"disabled\">\n <ngx-editor [editor]=\"editor\" outputFormat=\"html\" [placeholder]=\"placeholder\">\n <ngx-editor-menu\n [editor]=\"editor\"\n [toolbar]=\"toolbar\"\n [disabled]=\"disabled\"\n ></ngx-editor-menu>\n </ngx-editor>\n </div>\n\n @if (showError) {\n <div class=\"form-editor-error-message\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", styles: [".form-editor-label{color:#374151;display:block;font-size:.875rem;font-weight:600;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.form-editor-label{color:#d1d5db}}.form-editor-wrapper{position:relative}.form-editor-wrapper.disabled{opacity:.5;pointer-events:none;cursor:not-allowed}.form-editor-required{color:#ef4444}.form-editor-error-message{color:#ef4444;font-size:.75rem;margin-top:.25rem}\n"] }]
2073
2166
  }], ctorParameters: () => [{ type: i1$1.NgControl, decorators: [{
2074
2167
  type: Self
2075
2168
  }, {
2076
2169
  type: Optional
2077
- }] }, { type: i2.TranslocoService }], propDecorators: { label: [{
2170
+ }] }, { type: i2$1.TranslocoService }], propDecorators: { label: [{
2078
2171
  type: Input
2079
2172
  }], name: [{
2080
2173
  type: Input
@@ -2192,9 +2285,6 @@ class ColorPickerComponent {
2192
2285
  const touched = control.touched;
2193
2286
  return control.invalid ? dirty || touched : false;
2194
2287
  }
2195
- get inputClasses() {
2196
- return this.showError ? ERROR_INPUT_CLASSES : BASE_INPUT_CLASSES;
2197
- }
2198
2288
  get fieldGroupClasses() {
2199
2289
  let baseClasses = '';
2200
2290
  if (this.fieldGroupClass) {
@@ -2209,11 +2299,11 @@ class ColorPickerComponent {
2209
2299
  return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(color);
2210
2300
  }
2211
2301
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ColorPickerComponent, deps: [{ token: i1$1.NgControl, optional: true, self: true }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
2212
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: ColorPickerComponent, isStandalone: true, selector: "color-picker", inputs: { label: "label", name: "name", id: "id", placeholder: "placeholder", required: "required", readonly: "readonly", fieldGroupClass: "fieldGroupClass", showPreview: "showPreview", presetColors: "presetColors" }, outputs: { colorChange: "colorChange" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <div class=\"flex gap-2 items-center\">\n <!-- Color Input -->\n <div class=\"relative flex-1\">\n <input\n type=\"text\"\n [id]=\"inputId\"\n [name]=\"name\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onInputColorChange($event)\"\n (blur)=\"onTouched()\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n [class.bg-white]=\"!readonly\"\n [class.bg-gray-200]=\"readonly\"\n [class.cursor-not-allowed]=\"readonly\"\n [class]=\"inputClasses\"\n pattern=\"^#[0-9A-Fa-f]{6}$\"\n />\n\n <!-- Native Color Picker (Hidden) -->\n <input\n type=\"color\"\n class=\"absolute inset-0 opacity-0 cursor-pointer\"\n [disabled]=\"disabled || readonly\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onColorChange($event)\"\n />\n </div>\n\n <!-- Color Preview -->\n @if (showPreview) {\n <div class=\"flex items-center\">\n <div\n class=\"w-[37px] h-[37px] rounded-md border border-gray-300 cursor-pointer transition-all hover:scale-105\"\n [style.background-color]=\"value\"\n (click)=\"toggleDropdown()\"\n [class.cursor-not-allowed]=\"disabled || readonly\"\n [class.opacity-50]=\"disabled\"\n ></div>\n </div>\n }\n </div>\n\n <!-- Color Presets Dropdown -->\n @if (isDropdownOpen && !disabled && !readonly) {\n <div\n class=\"absolute z-50 mt-2 p-3 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg\"\n >\n <div class=\"grid grid-cols-5 gap-2 min-w-[200px]\">\n @for (color of presetColors; track color) {\n <button\n type=\"button\"\n class=\"w-8 h-8 rounded-md border-2 border-gray-300 hover:border-gray-400 transition-all hover:scale-110 focus:outline-none focus:ring-2 focus:ring-indigo-500\"\n [style.background-color]=\"color\"\n (click)=\"selectPresetColor(color)\"\n [attr.aria-label]=\"`Select color ${color}`\"\n ></button>\n }\n </div>\n\n <!-- Custom Color Input -->\n <div class=\"mt-3 pt-3 border-t border-gray-200 dark:border-gray-700\">\n <label class=\"text-xs text-gray-600 dark:text-gray-400 block mb-1\">Custom color:</label>\n <input\n type=\"color\"\n class=\"w-full h-8 rounded cursor-pointer\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onColorChange($event)\"\n />\n </div>\n </div>\n }\n </div>\n\n @if (showError) {\n <div class=\"text-red-500 text-xs mt-1\">Please enter a valid hex color (e.g., #FF5733)</div>\n }\n</div>\n", styles: [":host{display:block}.color-picker-dropdown{z-index:9999}.color-preview{transition:all .2s ease-in-out}.color-preset-button{transition:all .15s ease-in-out}.color-preset-button:focus{outline:2px solid #4f46e5;outline-offset:2px}@media(prefers-color-scheme:dark){.color-picker-dropdown{background-color:#1f2937;border-color:#374151}}@keyframes dropdownFadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.color-picker-dropdown{animation:dropdownFadeIn .15s ease-out}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }] });
2302
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: ColorPickerComponent, isStandalone: true, selector: "color-picker", inputs: { label: "label", name: "name", id: "id", placeholder: "placeholder", required: "required", readonly: "readonly", fieldGroupClass: "fieldGroupClass", showPreview: "showPreview", presetColors: "presetColors" }, outputs: { colorChange: "colorChange" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"color-picker-label\">\n {{ label }}\n\n @if (required) {\n <span class=\"color-picker-required\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <div class=\"color-picker-row\">\n <!-- Color Input -->\n <div class=\"color-picker-input-wrapper\">\n <input\n type=\"text\"\n [id]=\"inputId\"\n [name]=\"name\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onInputColorChange($event)\"\n (blur)=\"onTouched()\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n class=\"color-picker-input\"\n [class.disabled]=\"readonly\"\n [class.error]=\"showError\"\n pattern=\"^#[0-9A-Fa-f]{6}$\"\n />\n\n <!-- Native Color Picker (Hidden) -->\n <input\n type=\"color\"\n class=\"color-picker-native-input\"\n [disabled]=\"disabled || readonly\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onColorChange($event)\"\n />\n </div>\n\n <!-- Color Preview -->\n @if (showPreview) {\n <div class=\"color-picker-preview-wrapper\">\n <div\n class=\"color-picker-swatch\"\n [style.background-color]=\"value\"\n (click)=\"toggleDropdown()\"\n [class.disabled]=\"disabled || readonly\"\n ></div>\n </div>\n }\n </div>\n\n <!-- Color Presets Dropdown -->\n @if (isDropdownOpen && !disabled && !readonly) {\n <div class=\"color-picker-dropdown\">\n <div class=\"color-picker-presets\">\n @for (color of presetColors; track color) {\n <button\n type=\"button\"\n class=\"color-picker-preset-button\"\n [style.background-color]=\"color\"\n (click)=\"selectPresetColor(color)\"\n [attr.aria-label]=\"`Select color ${color}`\"\n ></button>\n }\n </div>\n\n <!-- Custom Color Input -->\n <div class=\"color-picker-custom\">\n <label class=\"color-picker-custom-label\">Custom color:</label>\n <input\n type=\"color\"\n class=\"color-picker-custom-input\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onColorChange($event)\"\n />\n </div>\n </div>\n }\n </div>\n\n @if (showError) {\n <div class=\"color-picker-error-message\">Please enter a valid hex color (e.g., #FF5733)</div>\n }\n</div>\n", styles: [":host{display:block}.color-picker-label{color:#374151;display:block;font-size:.875rem;font-weight:600;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.color-picker-label{color:#d1d5db}}.color-picker-required{color:#ef4444}.color-picker-row{display:flex;align-items:center;gap:.5rem}.color-picker-input-wrapper{position:relative;flex:1}.color-picker-input{background-color:#fff;border:1px solid #d1d5db;border-radius:.375rem;color:#111827;display:block;padding:.375rem .75rem;outline:1px solid #d1d5db;outline-offset:1px;width:100%}.color-picker-input::placeholder{color:#9ca3af}.color-picker-input:focus{outline:2px solid #4f46e5;outline-offset:2px}.color-picker-input.error{outline-color:#ef4444}@media(prefers-color-scheme:dark){.color-picker-input.error{background-color:#374151;color:#fff;outline-color:#ef4444}}.color-picker-input.disabled{background-color:#e5e7eb;color:#6b7280;cursor:not-allowed}@media(prefers-color-scheme:dark){.color-picker-input.disabled{background-color:#374151;color:#d1d5db}}.color-picker-native-input{position:absolute;inset:0;opacity:0;cursor:pointer}.color-picker-preview-wrapper{display:flex;align-items:center}.color-picker-swatch{width:37px;height:37px;border-radius:.375rem;border:1px solid #d1d5db;cursor:pointer;transition:all .15s ease-in-out}.color-picker-swatch:hover{transform:scale(1.05)}.color-picker-swatch.disabled{cursor:not-allowed;opacity:.5}.color-picker-dropdown{position:absolute;z-index:50;margin-top:.5rem;padding:.75rem;background-color:#fff;border:1px solid #e5e7eb;border-radius:.5rem;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;animation:dropdownFadeIn .15s ease-out}@media(prefers-color-scheme:dark){.color-picker-dropdown{background-color:#1f2937;border-color:#374151}}.color-picker-presets{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:.5rem;min-width:200px}.color-picker-preset-button{width:2rem;height:2rem;border-radius:.375rem;border:2px solid #d1d5db;cursor:pointer;transition:all .15s ease-in-out}.color-picker-preset-button:hover{border-color:#9ca3af;transform:scale(1.1)}.color-picker-preset-button:focus{outline:none;box-shadow:0 0 0 2px #6366f1}.color-picker-custom{margin-top:.75rem;padding-top:.75rem;border-top:1px solid #e5e7eb}@media(prefers-color-scheme:dark){.color-picker-custom{border-color:#374151}}.color-picker-custom-label{display:block;font-size:.75rem;color:#4b5563;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.color-picker-custom-label{color:#9ca3af}}.color-picker-custom-input{width:100%;height:2rem;border-radius:.375rem;cursor:pointer}.color-picker-error-message{color:#ef4444;font-size:.75rem;margin-top:.25rem}@keyframes dropdownFadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }] });
2213
2303
  }
2214
2304
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ColorPickerComponent, decorators: [{
2215
2305
  type: Component,
2216
- args: [{ selector: 'color-picker', standalone: true, imports: [FormsModule, CommonModule, ReactiveFormsModule], template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <div class=\"flex gap-2 items-center\">\n <!-- Color Input -->\n <div class=\"relative flex-1\">\n <input\n type=\"text\"\n [id]=\"inputId\"\n [name]=\"name\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onInputColorChange($event)\"\n (blur)=\"onTouched()\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n [class.bg-white]=\"!readonly\"\n [class.bg-gray-200]=\"readonly\"\n [class.cursor-not-allowed]=\"readonly\"\n [class]=\"inputClasses\"\n pattern=\"^#[0-9A-Fa-f]{6}$\"\n />\n\n <!-- Native Color Picker (Hidden) -->\n <input\n type=\"color\"\n class=\"absolute inset-0 opacity-0 cursor-pointer\"\n [disabled]=\"disabled || readonly\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onColorChange($event)\"\n />\n </div>\n\n <!-- Color Preview -->\n @if (showPreview) {\n <div class=\"flex items-center\">\n <div\n class=\"w-[37px] h-[37px] rounded-md border border-gray-300 cursor-pointer transition-all hover:scale-105\"\n [style.background-color]=\"value\"\n (click)=\"toggleDropdown()\"\n [class.cursor-not-allowed]=\"disabled || readonly\"\n [class.opacity-50]=\"disabled\"\n ></div>\n </div>\n }\n </div>\n\n <!-- Color Presets Dropdown -->\n @if (isDropdownOpen && !disabled && !readonly) {\n <div\n class=\"absolute z-50 mt-2 p-3 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg\"\n >\n <div class=\"grid grid-cols-5 gap-2 min-w-[200px]\">\n @for (color of presetColors; track color) {\n <button\n type=\"button\"\n class=\"w-8 h-8 rounded-md border-2 border-gray-300 hover:border-gray-400 transition-all hover:scale-110 focus:outline-none focus:ring-2 focus:ring-indigo-500\"\n [style.background-color]=\"color\"\n (click)=\"selectPresetColor(color)\"\n [attr.aria-label]=\"`Select color ${color}`\"\n ></button>\n }\n </div>\n\n <!-- Custom Color Input -->\n <div class=\"mt-3 pt-3 border-t border-gray-200 dark:border-gray-700\">\n <label class=\"text-xs text-gray-600 dark:text-gray-400 block mb-1\">Custom color:</label>\n <input\n type=\"color\"\n class=\"w-full h-8 rounded cursor-pointer\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onColorChange($event)\"\n />\n </div>\n </div>\n }\n </div>\n\n @if (showError) {\n <div class=\"text-red-500 text-xs mt-1\">Please enter a valid hex color (e.g., #FF5733)</div>\n }\n</div>\n", styles: [":host{display:block}.color-picker-dropdown{z-index:9999}.color-preview{transition:all .2s ease-in-out}.color-preset-button{transition:all .15s ease-in-out}.color-preset-button:focus{outline:2px solid #4f46e5;outline-offset:2px}@media(prefers-color-scheme:dark){.color-picker-dropdown{background-color:#1f2937;border-color:#374151}}@keyframes dropdownFadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.color-picker-dropdown{animation:dropdownFadeIn .15s ease-out}\n"] }]
2306
+ args: [{ selector: 'color-picker', standalone: true, imports: [FormsModule, CommonModule, ReactiveFormsModule], template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"color-picker-label\">\n {{ label }}\n\n @if (required) {\n <span class=\"color-picker-required\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <div class=\"color-picker-row\">\n <!-- Color Input -->\n <div class=\"color-picker-input-wrapper\">\n <input\n type=\"text\"\n [id]=\"inputId\"\n [name]=\"name\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onInputColorChange($event)\"\n (blur)=\"onTouched()\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n class=\"color-picker-input\"\n [class.disabled]=\"readonly\"\n [class.error]=\"showError\"\n pattern=\"^#[0-9A-Fa-f]{6}$\"\n />\n\n <!-- Native Color Picker (Hidden) -->\n <input\n type=\"color\"\n class=\"color-picker-native-input\"\n [disabled]=\"disabled || readonly\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onColorChange($event)\"\n />\n </div>\n\n <!-- Color Preview -->\n @if (showPreview) {\n <div class=\"color-picker-preview-wrapper\">\n <div\n class=\"color-picker-swatch\"\n [style.background-color]=\"value\"\n (click)=\"toggleDropdown()\"\n [class.disabled]=\"disabled || readonly\"\n ></div>\n </div>\n }\n </div>\n\n <!-- Color Presets Dropdown -->\n @if (isDropdownOpen && !disabled && !readonly) {\n <div class=\"color-picker-dropdown\">\n <div class=\"color-picker-presets\">\n @for (color of presetColors; track color) {\n <button\n type=\"button\"\n class=\"color-picker-preset-button\"\n [style.background-color]=\"color\"\n (click)=\"selectPresetColor(color)\"\n [attr.aria-label]=\"`Select color ${color}`\"\n ></button>\n }\n </div>\n\n <!-- Custom Color Input -->\n <div class=\"color-picker-custom\">\n <label class=\"color-picker-custom-label\">Custom color:</label>\n <input\n type=\"color\"\n class=\"color-picker-custom-input\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onColorChange($event)\"\n />\n </div>\n </div>\n }\n </div>\n\n @if (showError) {\n <div class=\"color-picker-error-message\">Please enter a valid hex color (e.g., #FF5733)</div>\n }\n</div>\n", styles: [":host{display:block}.color-picker-label{color:#374151;display:block;font-size:.875rem;font-weight:600;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.color-picker-label{color:#d1d5db}}.color-picker-required{color:#ef4444}.color-picker-row{display:flex;align-items:center;gap:.5rem}.color-picker-input-wrapper{position:relative;flex:1}.color-picker-input{background-color:#fff;border:1px solid #d1d5db;border-radius:.375rem;color:#111827;display:block;padding:.375rem .75rem;outline:1px solid #d1d5db;outline-offset:1px;width:100%}.color-picker-input::placeholder{color:#9ca3af}.color-picker-input:focus{outline:2px solid #4f46e5;outline-offset:2px}.color-picker-input.error{outline-color:#ef4444}@media(prefers-color-scheme:dark){.color-picker-input.error{background-color:#374151;color:#fff;outline-color:#ef4444}}.color-picker-input.disabled{background-color:#e5e7eb;color:#6b7280;cursor:not-allowed}@media(prefers-color-scheme:dark){.color-picker-input.disabled{background-color:#374151;color:#d1d5db}}.color-picker-native-input{position:absolute;inset:0;opacity:0;cursor:pointer}.color-picker-preview-wrapper{display:flex;align-items:center}.color-picker-swatch{width:37px;height:37px;border-radius:.375rem;border:1px solid #d1d5db;cursor:pointer;transition:all .15s ease-in-out}.color-picker-swatch:hover{transform:scale(1.05)}.color-picker-swatch.disabled{cursor:not-allowed;opacity:.5}.color-picker-dropdown{position:absolute;z-index:50;margin-top:.5rem;padding:.75rem;background-color:#fff;border:1px solid #e5e7eb;border-radius:.5rem;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;animation:dropdownFadeIn .15s ease-out}@media(prefers-color-scheme:dark){.color-picker-dropdown{background-color:#1f2937;border-color:#374151}}.color-picker-presets{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:.5rem;min-width:200px}.color-picker-preset-button{width:2rem;height:2rem;border-radius:.375rem;border:2px solid #d1d5db;cursor:pointer;transition:all .15s ease-in-out}.color-picker-preset-button:hover{border-color:#9ca3af;transform:scale(1.1)}.color-picker-preset-button:focus{outline:none;box-shadow:0 0 0 2px #6366f1}.color-picker-custom{margin-top:.75rem;padding-top:.75rem;border-top:1px solid #e5e7eb}@media(prefers-color-scheme:dark){.color-picker-custom{border-color:#374151}}.color-picker-custom-label{display:block;font-size:.75rem;color:#4b5563;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.color-picker-custom-label{color:#9ca3af}}.color-picker-custom-input{width:100%;height:2rem;border-radius:.375rem;cursor:pointer}.color-picker-error-message{color:#ef4444;font-size:.75rem;margin-top:.25rem}@keyframes dropdownFadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n"] }]
2217
2307
  }], ctorParameters: () => [{ type: i1$1.NgControl, decorators: [{
2218
2308
  type: Self
2219
2309
  }, {
@@ -2340,9 +2430,6 @@ class DateInputComponent {
2340
2430
  }
2341
2431
  return this.transloco.translate(`formErrors.${errorKey}`, {}, this.transloco.translate('formErrors.invalidField'));
2342
2432
  }
2343
- get inputClasses() {
2344
- return this.showError ? ERROR_INPUT_CLASSES : BASE_INPUT_CLASSES;
2345
- }
2346
2433
  get fieldGroupClasses() {
2347
2434
  let baseClasses = '';
2348
2435
  if (this.fieldGroupClass) {
@@ -2353,17 +2440,17 @@ class DateInputComponent {
2353
2440
  }
2354
2441
  return baseClasses;
2355
2442
  }
2356
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DateInputComponent, deps: [{ token: i1$1.NgControl, optional: true, self: true }, { token: i2.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
2357
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: DateInputComponent, isStandalone: true, selector: "date-input", inputs: { label: "label", type: "type", includeTime: "includeTime", name: "name", id: "id", placeholder: "placeholder", required: "required", readonly: "readonly", min: "min", max: "max", fieldGroupClass: "fieldGroupClass", dateFormat: "dateFormat" }, ngImport: i0, template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <input\n [type]=\"includeTime ? 'datetime-local' : type\"\n [id]=\"inputId\"\n [name]=\"name\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [min]=\"min\"\n [max]=\"max\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onInput($event)\"\n (blur)=\"onTouched()\"\n [disabled]=\"disabled\"\n [class]=\"inputClasses\"\n [readonly]=\"readonly\"\n />\n </div>\n\n @if (showError) {\n <div class=\"text-red-500 text-xs mt-1\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }] });
2443
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DateInputComponent, deps: [{ token: i1$1.NgControl, optional: true, self: true }, { token: i2$1.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
2444
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: DateInputComponent, isStandalone: true, selector: "date-input", inputs: { label: "label", type: "type", includeTime: "includeTime", name: "name", id: "id", placeholder: "placeholder", required: "required", readonly: "readonly", min: "min", max: "max", fieldGroupClass: "fieldGroupClass", dateFormat: "dateFormat" }, ngImport: i0, template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"date-input-label\">\n {{ label }}\n\n @if (required) {\n <span class=\"date-input-required\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <input\n [type]=\"includeTime ? 'datetime-local' : type\"\n [id]=\"inputId\"\n [name]=\"name\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [min]=\"min\"\n [max]=\"max\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onInput($event)\"\n (blur)=\"onTouched()\"\n [disabled]=\"disabled\"\n class=\"date-input\"\n [class.disabled]=\"readonly\"\n [class.error]=\"showError\"\n [readonly]=\"readonly\"\n />\n </div>\n\n @if (showError) {\n <div class=\"date-input-error-message\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", styles: [".date-input-label{color:#374151;display:block;font-size:.875rem;font-weight:600;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.date-input-label{color:#d1d5db}}.date-input{background-color:#fff;border:1px solid #d1d5db;border-radius:.375rem;color:#111827;display:block;padding:.375rem .75rem;outline:1px solid #d1d5db;outline-offset:1px;width:100%}.date-input::placeholder{color:#9ca3af}.date-input:focus{outline:2px solid #4f46e5;outline-offset:2px}.date-input.error{outline-color:#ef4444}@media(prefers-color-scheme:dark){.date-input.error{background-color:#374151;color:#fff;outline-color:#ef4444}}.date-input.disabled{background-color:#e5e7eb;color:#6b7280;cursor:not-allowed}@media(prefers-color-scheme:dark){.date-input.disabled{background-color:#374151;color:#d1d5db}}@media(min-width:768px){.date-input{font-size:.875rem}}.date-input-required{color:#ef4444}.date-input-error-message{color:#ef4444;font-size:.75rem;margin-top:.25rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }] });
2358
2445
  }
2359
2446
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DateInputComponent, decorators: [{
2360
2447
  type: Component,
2361
- args: [{ selector: 'date-input', standalone: true, imports: [FormsModule, CommonModule, ReactiveFormsModule], template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <input\n [type]=\"includeTime ? 'datetime-local' : type\"\n [id]=\"inputId\"\n [name]=\"name\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [min]=\"min\"\n [max]=\"max\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onInput($event)\"\n (blur)=\"onTouched()\"\n [disabled]=\"disabled\"\n [class]=\"inputClasses\"\n [readonly]=\"readonly\"\n />\n </div>\n\n @if (showError) {\n <div class=\"text-red-500 text-xs mt-1\">\n {{ errorMessage }}\n </div>\n }\n</div>\n" }]
2448
+ args: [{ selector: 'date-input', standalone: true, imports: [FormsModule, CommonModule, ReactiveFormsModule], template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"date-input-label\">\n {{ label }}\n\n @if (required) {\n <span class=\"date-input-required\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <input\n [type]=\"includeTime ? 'datetime-local' : type\"\n [id]=\"inputId\"\n [name]=\"name\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [min]=\"min\"\n [max]=\"max\"\n [(ngModel)]=\"value\"\n (ngModelChange)=\"onInput($event)\"\n (blur)=\"onTouched()\"\n [disabled]=\"disabled\"\n class=\"date-input\"\n [class.disabled]=\"readonly\"\n [class.error]=\"showError\"\n [readonly]=\"readonly\"\n />\n </div>\n\n @if (showError) {\n <div class=\"date-input-error-message\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", styles: [".date-input-label{color:#374151;display:block;font-size:.875rem;font-weight:600;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.date-input-label{color:#d1d5db}}.date-input{background-color:#fff;border:1px solid #d1d5db;border-radius:.375rem;color:#111827;display:block;padding:.375rem .75rem;outline:1px solid #d1d5db;outline-offset:1px;width:100%}.date-input::placeholder{color:#9ca3af}.date-input:focus{outline:2px solid #4f46e5;outline-offset:2px}.date-input.error{outline-color:#ef4444}@media(prefers-color-scheme:dark){.date-input.error{background-color:#374151;color:#fff;outline-color:#ef4444}}.date-input.disabled{background-color:#e5e7eb;color:#6b7280;cursor:not-allowed}@media(prefers-color-scheme:dark){.date-input.disabled{background-color:#374151;color:#d1d5db}}@media(min-width:768px){.date-input{font-size:.875rem}}.date-input-required{color:#ef4444}.date-input-error-message{color:#ef4444;font-size:.75rem;margin-top:.25rem}\n"] }]
2362
2449
  }], ctorParameters: () => [{ type: i1$1.NgControl, decorators: [{
2363
2450
  type: Self
2364
2451
  }, {
2365
2452
  type: Optional
2366
- }] }, { type: i2.TranslocoService }], propDecorators: { label: [{
2453
+ }] }, { type: i2$1.TranslocoService }], propDecorators: { label: [{
2367
2454
  type: Input
2368
2455
  }], type: [{
2369
2456
  type: Input
@@ -2431,36 +2518,6 @@ class ToggleSwitchComponent {
2431
2518
  get inputId() {
2432
2519
  return this.id || this.name;
2433
2520
  }
2434
- get toggleSizeClasses() {
2435
- switch (this.size) {
2436
- case 'sm':
2437
- return 'h-4 w-7';
2438
- case 'lg':
2439
- return 'h-7 w-14';
2440
- default:
2441
- return 'h-5 w-9';
2442
- }
2443
- }
2444
- get toggleThumbSizeClasses() {
2445
- switch (this.size) {
2446
- case 'sm':
2447
- return 'h-3 w-3';
2448
- case 'lg':
2449
- return 'h-6 w-6';
2450
- default:
2451
- return 'h-4 w-4';
2452
- }
2453
- }
2454
- get toggleThumbTranslateClasses() {
2455
- switch (this.size) {
2456
- case 'sm':
2457
- return 'translate-x-3';
2458
- case 'lg':
2459
- return 'translate-x-7';
2460
- default:
2461
- return 'translate-x-5';
2462
- }
2463
- }
2464
2521
  get fieldGroupClasses() {
2465
2522
  let baseClasses = '';
2466
2523
  if (this.fieldGroupClass) {
@@ -2472,11 +2529,11 @@ class ToggleSwitchComponent {
2472
2529
  return baseClasses;
2473
2530
  }
2474
2531
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ToggleSwitchComponent, deps: [{ token: i1$1.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component });
2475
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: ToggleSwitchComponent, isStandalone: true, selector: "toggle-switch", inputs: { label: "label", name: "name", id: "id", required: "required", disabled: "disabled", size: "size", fieldGroupClass: "fieldGroupClass", description: "description" }, outputs: { toggleClick: "toggleClick" }, ngImport: i0, template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div class=\"flex items-center\">\n <button\n type=\"button\"\n role=\"switch\"\n [id]=\"inputId\"\n [name]=\"name\"\n [attr.aria-checked]=\"value\"\n [attr.aria-required]=\"required\"\n [disabled]=\"disabled\"\n [class]=\"\n 'toggle-switch ' +\n size +\n (value ? ' checked' : ' unchecked') +\n (disabled ? ' disabled' : '')\n \"\n (click)=\"onToggle()\"\n >\n <span\n [class]=\"\n 'toggle-thumb ' +\n size +\n (value ? ' checked' : ' unchecked') +\n (disabled ? ' disabled' : '')\n \"\n ></span>\n </button>\n\n @if (description) {\n <span class=\"ml-3 text-sm text-gray-500 dark:text-gray-400\">{{ description }}</span>\n }\n </div>\n\n <!-- Hidden checkbox for form submission and accessibility -->\n <input\n type=\"checkbox\"\n [id]=\"inputId + '-hidden'\"\n [name]=\"name\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n [required]=\"required\"\n class=\"sr-only\"\n (change)=\"onToggle()\"\n />\n</div>\n", styles: [".toggle-switch{display:inline-flex;flex-shrink:0;position:relative;border:2px solid transparent;border-radius:9999px;cursor:pointer;transition:background-color .2s ease-in-out;outline:none}.toggle-switch:focus{box-shadow:0 0 0 2px #fff,0 0 0 4px #4f46e5}.toggle-switch.checked:not(.disabled){background-color:#4f46e5}.toggle-switch.unchecked:not(.disabled){background-color:#e5e7eb}.toggle-switch.disabled{background-color:#d1d5db;cursor:not-allowed;opacity:.5}.toggle-switch.sm{height:1rem;width:1.75rem;padding:0 2px;box-sizing:border-box}.toggle-switch.sm .toggle-thumb{height:calc(1rem - 6px);width:calc(1rem - 6px)}.toggle-switch.sm .toggle-thumb.checked{transform:translate(calc(.75rem - 2px))}.toggle-switch.md{height:1.25rem;width:2.25rem;padding:0 2px;box-sizing:border-box}.toggle-switch.md .toggle-thumb{height:calc(1.25rem - 6px);width:calc(1.25rem - 6px)}.toggle-switch.md .toggle-thumb.checked{transform:translate(calc(1rem - 2px))}.toggle-switch.lg{height:1.75rem;width:3.5rem;padding:0 2px;box-sizing:border-box}.toggle-switch.lg .toggle-thumb{height:calc(1.75rem - 6px);width:calc(1.75rem - 6px)}.toggle-switch.lg .toggle-thumb.checked{transform:translate(calc(1.75rem - 2px))}.toggle-thumb{pointer-events:none;display:inline-block;border-radius:50%;background-color:#fff;box-shadow:0 10px 15px -3px #0000001a;transition:transform .2s ease-in-out;margin:auto 0}.disabled .toggle-thumb{background-color:#9ca3af}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }] });
2532
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: ToggleSwitchComponent, isStandalone: true, selector: "toggle-switch", inputs: { label: "label", name: "name", id: "id", required: "required", disabled: "disabled", size: "size", fieldGroupClass: "fieldGroupClass", description: "description" }, outputs: { toggleClick: "toggleClick" }, ngImport: i0, template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"toggle-label\">\n {{ label }}\n\n @if (required) {\n <span class=\"toggle-required\">*</span>\n }\n </label>\n }\n\n <div class=\"toggle-container\">\n <button\n type=\"button\"\n role=\"switch\"\n [id]=\"inputId\"\n [name]=\"name\"\n [attr.aria-checked]=\"value\"\n [attr.aria-required]=\"required\"\n [disabled]=\"disabled\"\n [class]=\"\n 'toggle-switch ' +\n size +\n (value ? ' checked' : ' unchecked') +\n (disabled ? ' disabled' : '')\n \"\n (click)=\"onToggle()\"\n >\n <span\n [class]=\"\n 'toggle-thumb ' +\n size +\n (value ? ' checked' : ' unchecked') +\n (disabled ? ' disabled' : '')\n \"\n ></span>\n </button>\n\n @if (description) {\n <span class=\"toggle-description\">{{ description }}</span>\n }\n </div>\n\n <!-- Hidden checkbox for form submission and accessibility -->\n <input\n type=\"checkbox\"\n [id]=\"inputId + '-hidden'\"\n [name]=\"name\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n [required]=\"required\"\n class=\"toggle-hidden\"\n (change)=\"onToggle()\"\n />\n</div>\n", styles: [":host{display:block;width:100%}.toggle-label{display:block;font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.875rem;font-weight:500;color:#374151;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.toggle-label{color:#d1d5db}}.toggle-required{color:#ef4444}.toggle-container{display:flex;align-items:center}.toggle-description{margin-left:.75rem;font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.875rem;color:#6b7280}@media(prefers-color-scheme:dark){.toggle-description{color:#9ca3af}}.toggle-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.toggle-switch{display:inline-flex;flex-shrink:0;position:relative;border:2px solid transparent;border-radius:9999px;cursor:pointer;transition:background-color .2s ease-in-out;outline:none}.toggle-switch:focus{box-shadow:0 0 0 2px #fff,0 0 0 4px #4f46e5}.toggle-switch.checked:not(.disabled){background-color:#4f46e5}.toggle-switch.unchecked:not(.disabled){background-color:#e5e7eb}.toggle-switch.disabled{background-color:#d1d5db;cursor:not-allowed;opacity:.5}.toggle-switch.sm{height:1rem;width:1.75rem;padding:0 2px;box-sizing:border-box}.toggle-switch.sm .toggle-thumb{height:calc(1rem - 6px);width:calc(1rem - 6px)}.toggle-switch.sm .toggle-thumb.checked{transform:translate(calc(.75rem - 2px))}.toggle-switch.md{height:1.25rem;width:2.25rem;padding:0 2px;box-sizing:border-box}.toggle-switch.md .toggle-thumb{height:calc(1.25rem - 6px);width:calc(1.25rem - 6px)}.toggle-switch.md .toggle-thumb.checked{transform:translate(calc(1rem - 2px))}.toggle-switch.lg{height:1.75rem;width:3.5rem;padding:0 2px;box-sizing:border-box}.toggle-switch.lg .toggle-thumb{height:calc(1.75rem - 6px);width:calc(1.75rem - 6px)}.toggle-switch.lg .toggle-thumb.checked{transform:translate(calc(1.75rem - 2px))}.toggle-thumb{pointer-events:none;display:inline-block;border-radius:9999px;background-color:#fff;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;transition:transform .2s ease-in-out;margin:auto 0}.disabled .toggle-thumb{background-color:#9ca3af}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }] });
2476
2533
  }
2477
2534
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ToggleSwitchComponent, decorators: [{
2478
2535
  type: Component,
2479
- args: [{ selector: 'toggle-switch', standalone: true, imports: [FormsModule, CommonModule, ReactiveFormsModule], template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div class=\"flex items-center\">\n <button\n type=\"button\"\n role=\"switch\"\n [id]=\"inputId\"\n [name]=\"name\"\n [attr.aria-checked]=\"value\"\n [attr.aria-required]=\"required\"\n [disabled]=\"disabled\"\n [class]=\"\n 'toggle-switch ' +\n size +\n (value ? ' checked' : ' unchecked') +\n (disabled ? ' disabled' : '')\n \"\n (click)=\"onToggle()\"\n >\n <span\n [class]=\"\n 'toggle-thumb ' +\n size +\n (value ? ' checked' : ' unchecked') +\n (disabled ? ' disabled' : '')\n \"\n ></span>\n </button>\n\n @if (description) {\n <span class=\"ml-3 text-sm text-gray-500 dark:text-gray-400\">{{ description }}</span>\n }\n </div>\n\n <!-- Hidden checkbox for form submission and accessibility -->\n <input\n type=\"checkbox\"\n [id]=\"inputId + '-hidden'\"\n [name]=\"name\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n [required]=\"required\"\n class=\"sr-only\"\n (change)=\"onToggle()\"\n />\n</div>\n", styles: [".toggle-switch{display:inline-flex;flex-shrink:0;position:relative;border:2px solid transparent;border-radius:9999px;cursor:pointer;transition:background-color .2s ease-in-out;outline:none}.toggle-switch:focus{box-shadow:0 0 0 2px #fff,0 0 0 4px #4f46e5}.toggle-switch.checked:not(.disabled){background-color:#4f46e5}.toggle-switch.unchecked:not(.disabled){background-color:#e5e7eb}.toggle-switch.disabled{background-color:#d1d5db;cursor:not-allowed;opacity:.5}.toggle-switch.sm{height:1rem;width:1.75rem;padding:0 2px;box-sizing:border-box}.toggle-switch.sm .toggle-thumb{height:calc(1rem - 6px);width:calc(1rem - 6px)}.toggle-switch.sm .toggle-thumb.checked{transform:translate(calc(.75rem - 2px))}.toggle-switch.md{height:1.25rem;width:2.25rem;padding:0 2px;box-sizing:border-box}.toggle-switch.md .toggle-thumb{height:calc(1.25rem - 6px);width:calc(1.25rem - 6px)}.toggle-switch.md .toggle-thumb.checked{transform:translate(calc(1rem - 2px))}.toggle-switch.lg{height:1.75rem;width:3.5rem;padding:0 2px;box-sizing:border-box}.toggle-switch.lg .toggle-thumb{height:calc(1.75rem - 6px);width:calc(1.75rem - 6px)}.toggle-switch.lg .toggle-thumb.checked{transform:translate(calc(1.75rem - 2px))}.toggle-thumb{pointer-events:none;display:inline-block;border-radius:50%;background-color:#fff;box-shadow:0 10px 15px -3px #0000001a;transition:transform .2s ease-in-out;margin:auto 0}.disabled .toggle-thumb{background-color:#9ca3af}\n"] }]
2536
+ args: [{ selector: 'toggle-switch', standalone: true, imports: [FormsModule, CommonModule, ReactiveFormsModule], template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"toggle-label\">\n {{ label }}\n\n @if (required) {\n <span class=\"toggle-required\">*</span>\n }\n </label>\n }\n\n <div class=\"toggle-container\">\n <button\n type=\"button\"\n role=\"switch\"\n [id]=\"inputId\"\n [name]=\"name\"\n [attr.aria-checked]=\"value\"\n [attr.aria-required]=\"required\"\n [disabled]=\"disabled\"\n [class]=\"\n 'toggle-switch ' +\n size +\n (value ? ' checked' : ' unchecked') +\n (disabled ? ' disabled' : '')\n \"\n (click)=\"onToggle()\"\n >\n <span\n [class]=\"\n 'toggle-thumb ' +\n size +\n (value ? ' checked' : ' unchecked') +\n (disabled ? ' disabled' : '')\n \"\n ></span>\n </button>\n\n @if (description) {\n <span class=\"toggle-description\">{{ description }}</span>\n }\n </div>\n\n <!-- Hidden checkbox for form submission and accessibility -->\n <input\n type=\"checkbox\"\n [id]=\"inputId + '-hidden'\"\n [name]=\"name\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n [required]=\"required\"\n class=\"toggle-hidden\"\n (change)=\"onToggle()\"\n />\n</div>\n", styles: [":host{display:block;width:100%}.toggle-label{display:block;font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.875rem;font-weight:500;color:#374151;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.toggle-label{color:#d1d5db}}.toggle-required{color:#ef4444}.toggle-container{display:flex;align-items:center}.toggle-description{margin-left:.75rem;font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.875rem;color:#6b7280}@media(prefers-color-scheme:dark){.toggle-description{color:#9ca3af}}.toggle-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.toggle-switch{display:inline-flex;flex-shrink:0;position:relative;border:2px solid transparent;border-radius:9999px;cursor:pointer;transition:background-color .2s ease-in-out;outline:none}.toggle-switch:focus{box-shadow:0 0 0 2px #fff,0 0 0 4px #4f46e5}.toggle-switch.checked:not(.disabled){background-color:#4f46e5}.toggle-switch.unchecked:not(.disabled){background-color:#e5e7eb}.toggle-switch.disabled{background-color:#d1d5db;cursor:not-allowed;opacity:.5}.toggle-switch.sm{height:1rem;width:1.75rem;padding:0 2px;box-sizing:border-box}.toggle-switch.sm .toggle-thumb{height:calc(1rem - 6px);width:calc(1rem - 6px)}.toggle-switch.sm .toggle-thumb.checked{transform:translate(calc(.75rem - 2px))}.toggle-switch.md{height:1.25rem;width:2.25rem;padding:0 2px;box-sizing:border-box}.toggle-switch.md .toggle-thumb{height:calc(1.25rem - 6px);width:calc(1.25rem - 6px)}.toggle-switch.md .toggle-thumb.checked{transform:translate(calc(1rem - 2px))}.toggle-switch.lg{height:1.75rem;width:3.5rem;padding:0 2px;box-sizing:border-box}.toggle-switch.lg .toggle-thumb{height:calc(1.75rem - 6px);width:calc(1.75rem - 6px)}.toggle-switch.lg .toggle-thumb.checked{transform:translate(calc(1.75rem - 2px))}.toggle-thumb{pointer-events:none;display:inline-block;border-radius:9999px;background-color:#fff;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;transition:transform .2s ease-in-out;margin:auto 0}.disabled .toggle-thumb{background-color:#9ca3af}\n"] }]
2480
2537
  }], ctorParameters: () => [{ type: i1$1.NgControl, decorators: [{
2481
2538
  type: Self
2482
2539
  }, {
@@ -2558,11 +2615,11 @@ class FileUploadPreviewComponent {
2558
2615
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
2559
2616
  }
2560
2617
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: FileUploadPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2561
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: FileUploadPreviewComponent, isStandalone: true, selector: "file-upload-preview", inputs: { file: "file" }, outputs: { remove: "remove" }, ngImport: i0, template: "<div class=\"flex items-center justify-between p-3 bg-gray-50 rounded-lg border border-gray-200\">\n <div class=\"flex items-center space-x-3 flex-1 min-w-0\">\n <!-- File Preview/Icon -->\n <div class=\"flex-shrink-0\">\n @if (file.preview) {\n <img [src]=\"file.preview\" [alt]=\"file.name\" class=\"w-10 h-10 object-cover rounded-md\" />\n } @else {\n <div class=\"w-10 h-10 bg-gray-200 rounded-md flex items-center justify-center\">\n <i [class]=\"getFileTypeIcon(file) + ' text-gray-600 text-lg'\"></i>\n </div>\n }\n </div>\n\n <!-- File Info -->\n <div class=\"flex-1 min-w-0\">\n <p class=\"text-sm font-medium text-gray-900 truncate\">\n {{ file.name }}\n </p>\n <p class=\"text-xs text-gray-500\">\n @if (!!file.size) {\n {{ formatFileSize(file.size) }}\n }\n @if (file.extension) {\n \u2022 {{ file.extension.toUpperCase() }}\n }\n </p>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"flex items-center space-x-2 ml-4\">\n <app-button\n icon=\"ri-delete-bin-line\"\n (clicked)=\"removeFile()\"\n variant=\"primary\"\n size=\"xs\"\n title=\"Eliminar archivo\"\n />\n </div>\n</div>\n", styles: [".file-upload__drag-over{border-color:#60a5fa;background-color:#eff6ff}.file-upload__disabled{border-color:#e5e7eb;background-color:#f9fafb;cursor:not-allowed}.file-upload__preview{transition:all .2s ease-in-out}.file-upload__preview:hover{transform:scale(1.05)}.file-upload__file-item{transition:all .2s ease-in-out}.file-upload__file-item:hover{background-color:#f3f4f6;border-color:#d1d5db}.file-upload__remove-btn{transition:all .2s ease-in-out}.file-upload__remove-btn:hover{background-color:#fef2f2}.file-upload__remove-btn:active{transform:scale(.95)}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.file-upload__drag-active{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.file-upload__file-list{max-height:15rem;overflow-y:auto}.file-upload__file-list::-webkit-scrollbar{width:.5rem}.file-upload__file-list::-webkit-scrollbar-track{background-color:#f3f4f6;border-radius:9999px}.file-upload__file-list::-webkit-scrollbar-thumb{background-color:#d1d5db;border-radius:9999px}.file-upload__file-list::-webkit-scrollbar-thumb:hover{background-color:#9ca3af}.file-type-icon--image{color:#3b82f6}.file-type-icon--pdf{color:#ef4444}.file-type-icon--excel{color:#10b981}.file-type-icon--word{color:#2563eb}.file-type-icon--text{color:#6b7280}.file-type-icon--default{color:#9ca3af}@media(max-width:640px){.file-upload__file-item{padding:.5rem}.file-upload__file-info{font-size:.75rem}.file-upload__preview{width:2rem;height:2rem}}@media(prefers-color-scheme:dark){.file-upload__file-item{background-color:#1f2937;border-color:#374151}.file-upload__file-item:hover{background-color:#111827;border-color:#4b5563}.file-upload__file-info{color:#d1d5db}.file-upload__file-name{color:#f3f4f6}.file-upload__file-size{color:#9ca3af}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: AppButtonComponent, selector: "app-button", inputs: ["disabled", "loading", "type", "variant", "text", "size", "loadingText", "icon"], outputs: ["clicked"] }] });
2618
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: FileUploadPreviewComponent, isStandalone: true, selector: "file-upload-preview", inputs: { file: "file" }, outputs: { remove: "remove" }, ngImport: i0, template: "<div class=\"file-preview-item\">\n <div class=\"file-preview-content\">\n <!-- File Preview/Icon -->\n <div class=\"file-preview-icon-wrapper\">\n @if (file.preview) {\n <img [src]=\"file.preview\" [alt]=\"file.name\" class=\"file-preview-image\" />\n } @else {\n <div class=\"file-preview-icon-placeholder\">\n <i [class]=\"getFileTypeIcon(file) + ' file-preview-icon'\"></i>\n </div>\n }\n </div>\n\n <!-- File Info -->\n <div class=\"file-preview-info\">\n <p class=\"file-preview-name\">\n {{ file.name }}\n </p>\n <p class=\"file-preview-meta\">\n @if (!!file.size) {\n {{ formatFileSize(file.size) }}\n }\n @if (file.extension) {\n \u2022 {{ file.extension.toUpperCase() }}\n }\n </p>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"file-preview-actions\">\n <app-button\n icon=\"ri-delete-bin-line\"\n (clicked)=\"removeFile()\"\n variant=\"primary\"\n size=\"xs\"\n title=\"Eliminar archivo\"\n />\n </div>\n</div>\n", styles: [":host{display:block;width:100%}.file-preview-item{align-items:center;background-color:#f9fafb;border-radius:.5rem;border:1px solid #e5e7eb;box-sizing:border-box;display:flex;justify-content:space-between;padding:.75rem;width:100%;transition:all .2s ease-in-out}.file-preview-item:hover{background-color:#f3f4f6;border-color:#d1d5db}@media(prefers-color-scheme:dark){.file-preview-item{background-color:#1f2937;border-color:#374151}.file-preview-item:hover{background-color:#111827;border-color:#4b5563}}.file-preview-content{display:flex;align-items:center;gap:.75rem;flex:1;min-width:0}.file-preview-icon-wrapper{flex-shrink:0}.file-preview-image{width:2.5rem;height:2.5rem;object-fit:cover;border-radius:.375rem}.file-preview-icon-placeholder{width:2.5rem;height:2.5rem;background-color:#e5e7eb;border-radius:.375rem;display:flex;align-items:center;justify-content:center}@media(prefers-color-scheme:dark){.file-preview-icon-placeholder{background-color:#374151}}.file-preview-icon{color:#4b5563;font-size:1.125rem}@media(prefers-color-scheme:dark){.file-preview-icon{color:#9ca3af}}.file-preview-info{flex:1;min-width:0}.file-preview-name{color:#111827;font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.875rem;font-weight:500;margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media(prefers-color-scheme:dark){.file-preview-name{color:#f3f4f6}}.file-preview-meta{color:#6b7280;font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.75rem;margin:0}@media(prefers-color-scheme:dark){.file-preview-meta{color:#9ca3af}}.file-preview-actions{display:flex;align-items:center;gap:.5rem;margin-left:1rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: AppButtonComponent, selector: "app-button", inputs: ["disabled", "loading", "type", "variant", "text", "size", "loadingText", "icon"], outputs: ["clicked"] }] });
2562
2619
  }
2563
2620
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: FileUploadPreviewComponent, decorators: [{
2564
2621
  type: Component,
2565
- args: [{ selector: 'file-upload-preview', standalone: true, imports: [FormsModule, CommonModule, ReactiveFormsModule, AppButtonComponent], template: "<div class=\"flex items-center justify-between p-3 bg-gray-50 rounded-lg border border-gray-200\">\n <div class=\"flex items-center space-x-3 flex-1 min-w-0\">\n <!-- File Preview/Icon -->\n <div class=\"flex-shrink-0\">\n @if (file.preview) {\n <img [src]=\"file.preview\" [alt]=\"file.name\" class=\"w-10 h-10 object-cover rounded-md\" />\n } @else {\n <div class=\"w-10 h-10 bg-gray-200 rounded-md flex items-center justify-center\">\n <i [class]=\"getFileTypeIcon(file) + ' text-gray-600 text-lg'\"></i>\n </div>\n }\n </div>\n\n <!-- File Info -->\n <div class=\"flex-1 min-w-0\">\n <p class=\"text-sm font-medium text-gray-900 truncate\">\n {{ file.name }}\n </p>\n <p class=\"text-xs text-gray-500\">\n @if (!!file.size) {\n {{ formatFileSize(file.size) }}\n }\n @if (file.extension) {\n \u2022 {{ file.extension.toUpperCase() }}\n }\n </p>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"flex items-center space-x-2 ml-4\">\n <app-button\n icon=\"ri-delete-bin-line\"\n (clicked)=\"removeFile()\"\n variant=\"primary\"\n size=\"xs\"\n title=\"Eliminar archivo\"\n />\n </div>\n</div>\n", styles: [".file-upload__drag-over{border-color:#60a5fa;background-color:#eff6ff}.file-upload__disabled{border-color:#e5e7eb;background-color:#f9fafb;cursor:not-allowed}.file-upload__preview{transition:all .2s ease-in-out}.file-upload__preview:hover{transform:scale(1.05)}.file-upload__file-item{transition:all .2s ease-in-out}.file-upload__file-item:hover{background-color:#f3f4f6;border-color:#d1d5db}.file-upload__remove-btn{transition:all .2s ease-in-out}.file-upload__remove-btn:hover{background-color:#fef2f2}.file-upload__remove-btn:active{transform:scale(.95)}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.file-upload__drag-active{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.file-upload__file-list{max-height:15rem;overflow-y:auto}.file-upload__file-list::-webkit-scrollbar{width:.5rem}.file-upload__file-list::-webkit-scrollbar-track{background-color:#f3f4f6;border-radius:9999px}.file-upload__file-list::-webkit-scrollbar-thumb{background-color:#d1d5db;border-radius:9999px}.file-upload__file-list::-webkit-scrollbar-thumb:hover{background-color:#9ca3af}.file-type-icon--image{color:#3b82f6}.file-type-icon--pdf{color:#ef4444}.file-type-icon--excel{color:#10b981}.file-type-icon--word{color:#2563eb}.file-type-icon--text{color:#6b7280}.file-type-icon--default{color:#9ca3af}@media(max-width:640px){.file-upload__file-item{padding:.5rem}.file-upload__file-info{font-size:.75rem}.file-upload__preview{width:2rem;height:2rem}}@media(prefers-color-scheme:dark){.file-upload__file-item{background-color:#1f2937;border-color:#374151}.file-upload__file-item:hover{background-color:#111827;border-color:#4b5563}.file-upload__file-info{color:#d1d5db}.file-upload__file-name{color:#f3f4f6}.file-upload__file-size{color:#9ca3af}}\n"] }]
2622
+ args: [{ selector: 'file-upload-preview', standalone: true, imports: [FormsModule, CommonModule, ReactiveFormsModule, AppButtonComponent], template: "<div class=\"file-preview-item\">\n <div class=\"file-preview-content\">\n <!-- File Preview/Icon -->\n <div class=\"file-preview-icon-wrapper\">\n @if (file.preview) {\n <img [src]=\"file.preview\" [alt]=\"file.name\" class=\"file-preview-image\" />\n } @else {\n <div class=\"file-preview-icon-placeholder\">\n <i [class]=\"getFileTypeIcon(file) + ' file-preview-icon'\"></i>\n </div>\n }\n </div>\n\n <!-- File Info -->\n <div class=\"file-preview-info\">\n <p class=\"file-preview-name\">\n {{ file.name }}\n </p>\n <p class=\"file-preview-meta\">\n @if (!!file.size) {\n {{ formatFileSize(file.size) }}\n }\n @if (file.extension) {\n \u2022 {{ file.extension.toUpperCase() }}\n }\n </p>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"file-preview-actions\">\n <app-button\n icon=\"ri-delete-bin-line\"\n (clicked)=\"removeFile()\"\n variant=\"primary\"\n size=\"xs\"\n title=\"Eliminar archivo\"\n />\n </div>\n</div>\n", styles: [":host{display:block;width:100%}.file-preview-item{align-items:center;background-color:#f9fafb;border-radius:.5rem;border:1px solid #e5e7eb;box-sizing:border-box;display:flex;justify-content:space-between;padding:.75rem;width:100%;transition:all .2s ease-in-out}.file-preview-item:hover{background-color:#f3f4f6;border-color:#d1d5db}@media(prefers-color-scheme:dark){.file-preview-item{background-color:#1f2937;border-color:#374151}.file-preview-item:hover{background-color:#111827;border-color:#4b5563}}.file-preview-content{display:flex;align-items:center;gap:.75rem;flex:1;min-width:0}.file-preview-icon-wrapper{flex-shrink:0}.file-preview-image{width:2.5rem;height:2.5rem;object-fit:cover;border-radius:.375rem}.file-preview-icon-placeholder{width:2.5rem;height:2.5rem;background-color:#e5e7eb;border-radius:.375rem;display:flex;align-items:center;justify-content:center}@media(prefers-color-scheme:dark){.file-preview-icon-placeholder{background-color:#374151}}.file-preview-icon{color:#4b5563;font-size:1.125rem}@media(prefers-color-scheme:dark){.file-preview-icon{color:#9ca3af}}.file-preview-info{flex:1;min-width:0}.file-preview-name{color:#111827;font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.875rem;font-weight:500;margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media(prefers-color-scheme:dark){.file-preview-name{color:#f3f4f6}}.file-preview-meta{color:#6b7280;font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.75rem;margin:0}@media(prefers-color-scheme:dark){.file-preview-meta{color:#9ca3af}}.file-preview-actions{display:flex;align-items:center;gap:.5rem;margin-left:1rem}\n"] }]
2566
2623
  }], propDecorators: { file: [{
2567
2624
  type: Input,
2568
2625
  args: [{ required: true }]
@@ -2788,17 +2845,17 @@ class FileUploadComponent {
2788
2845
  return baseClasses;
2789
2846
  }
2790
2847
  get uploadAreaClasses() {
2791
- const baseClasses = 'border-2 border-dashed rounded-lg p-6 text-center transition-colors cursor-pointer';
2848
+ const baseClasses = 'file-upload-area';
2792
2849
  if (this.disabled) {
2793
- return `${baseClasses} border-gray-200 bg-gray-50 cursor-not-allowed`;
2850
+ return `${baseClasses} disabled`;
2794
2851
  }
2795
2852
  if (this.dragOver) {
2796
- return `${baseClasses} border-blue-400 bg-blue-50`;
2853
+ return `${baseClasses} drag-over`;
2797
2854
  }
2798
- return `${baseClasses} border-gray-300 hover:border-gray-400 hover:bg-gray-50`;
2855
+ return baseClasses;
2799
2856
  }
2800
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: FileUploadComponent, deps: [{ token: i1$1.NgControl, optional: true, self: true }, { token: i2.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
2801
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: FileUploadComponent, isStandalone: true, selector: "file-upload", inputs: { label: "label", name: "name", id: "id", required: "required", readonly: "readonly", fieldGroupClass: "fieldGroupClass", config: "config", accept: "accept" }, outputs: { fileSelected: "fileSelected", fileRemoved: "fileRemoved", validationError: "validationError" }, ngImport: i0, template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <!-- Upload Area -->\n <div\n class=\"relative\"\n (drop)=\"onDrop($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n >\n <div [class]=\"uploadAreaClasses\" (click)=\"!disabled && triggerFileInput()\">\n <input\n [id]=\"inputId\"\n [name]=\"name\"\n type=\"file\"\n [accept]=\"accept\"\n [multiple]=\"config.multiple\"\n [disabled]=\"disabled\"\n [required]=\"required\"\n (change)=\"onFileSelect($event)\"\n (blur)=\"onTouched()\"\n class=\"hidden\"\n />\n\n <div class=\"flex flex-col items-center space-y-2\">\n <i class=\"ri-upload-cloud-2-line text-3xl text-gray-400\"></i>\n <div class=\"text-sm text-gray-600\">\n <p class=\"font-medium\">\n @if (config.multiple) {\n {{ 'fileUpload.dropMultiple' | transloco }}\n } @else {\n {{ 'fileUpload.dropSingle' | transloco }}\n }\n </p>\n <p class=\"text-xs text-gray-500 mt-1\">\n @if (config.allowedExtensions && config.allowedExtensions.length > 0) {\n {{ 'fileUpload.allowedExtensions' | transloco }}\n {{ config.allowedExtensions.join(', ') }}\n }\n @if (config.maxFileSize) {\n \u2022 {{ 'fileUpload.maxSize' | transloco }} {{ formatFileSize(config.maxFileSize) }}\n }\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Files Preview -->\n @if (files.length > 0) {\n <div class=\"flex flex-col gap-2 mt-4\">\n @for (file of files; track file; let i = $index) {\n <file-upload-preview [file]=\"file\" (remove)=\"removeFile(i)\" />\n }\n </div>\n }\n\n <!-- Validation Error -->\n @if (showError) {\n <div class=\"text-red-500 text-xs mt-1\">\n {{ errorMessage }}\n </div>\n }\n\n <!-- File Type Legend -->\n @if (files.length === 0) {\n <div class=\"mt-3 flex flex-wrap gap-4 text-xs text-gray-500\">\n <div class=\"flex items-center space-x-1\">\n <i class=\"ri-image-line text-blue-500\"></i>\n <span>{{ 'fileUpload.fileTypeImages' | transloco }}</span>\n </div>\n <div class=\"flex items-center space-x-1\">\n <i class=\"ri-file-pdf-line text-red-500\"></i>\n <span>PDF</span>\n </div>\n <div class=\"flex items-center space-x-1\">\n <i class=\"ri-file-excel-line text-green-500\"></i>\n <span>{{ 'fileUpload.fileTypeExcel' | transloco }}</span>\n </div>\n <div class=\"flex items-center space-x-1\">\n <i class=\"ri-file-word-line text-blue-600\"></i>\n <span>{{ 'fileUpload.fileTypeWord' | transloco }}</span>\n </div>\n <div class=\"flex items-center space-x-1\">\n <i class=\"ri-file-text-line text-gray-500\"></i>\n <span>{{ 'fileUpload.fileTypeText' | transloco }}</span>\n </div>\n <div class=\"flex items-center space-x-1\">\n <i class=\"ri-file-line text-gray-400\"></i>\n <span>{{ 'fileUpload.fileTypeOther' | transloco }}</span>\n </div>\n </div>\n }\n</div>\n", styles: [".file-upload__drag-over{border-color:#60a5fa;background-color:#eff6ff}.file-upload__disabled{border-color:#e5e7eb;background-color:#f9fafb;cursor:not-allowed}.file-upload__preview{transition:all .2s ease-in-out}.file-upload__preview:hover{transform:scale(1.05)}.file-upload__file-item{transition:all .2s ease-in-out}.file-upload__file-item:hover{background-color:#f3f4f6;border-color:#d1d5db}.file-upload__remove-btn{transition:all .2s ease-in-out}.file-upload__remove-btn:hover{background-color:#fef2f2}.file-upload__remove-btn:active{transform:scale(.95)}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.file-upload__drag-active{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.file-upload__file-list{max-height:15rem;overflow-y:auto}.file-upload__file-list::-webkit-scrollbar{width:.5rem}.file-upload__file-list::-webkit-scrollbar-track{background-color:#f3f4f6;border-radius:9999px}.file-upload__file-list::-webkit-scrollbar-thumb{background-color:#d1d5db;border-radius:9999px}.file-upload__file-list::-webkit-scrollbar-thumb:hover{background-color:#9ca3af}.file-type-icon--image{color:#3b82f6}.file-type-icon--pdf{color:#ef4444}.file-type-icon--excel{color:#10b981}.file-type-icon--word{color:#2563eb}.file-type-icon--text{color:#6b7280}.file-type-icon--default{color:#9ca3af}@media(max-width:640px){.file-upload__file-item{padding:.5rem}.file-upload__file-info{font-size:.75rem}.file-upload__preview{width:2rem;height:2rem}}@media(prefers-color-scheme:dark){.file-upload__file-item{background-color:#1f2937;border-color:#374151}.file-upload__file-item:hover{background-color:#111827;border-color:#4b5563}.file-upload__file-info{color:#d1d5db}.file-upload__file-name{color:#f3f4f6}.file-upload__file-size{color:#9ca3af}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: TranslocoModule }, { kind: "component", type: FileUploadPreviewComponent, selector: "file-upload-preview", inputs: ["file"], outputs: ["remove"] }, { kind: "pipe", type: i2.TranslocoPipe, name: "transloco" }] });
2857
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: FileUploadComponent, deps: [{ token: i1$1.NgControl, optional: true, self: true }, { token: i2$1.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
2858
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: FileUploadComponent, isStandalone: true, selector: "file-upload", inputs: { label: "label", name: "name", id: "id", required: "required", readonly: "readonly", fieldGroupClass: "fieldGroupClass", config: "config", accept: "accept" }, outputs: { fileSelected: "fileSelected", fileRemoved: "fileRemoved", validationError: "validationError" }, ngImport: i0, template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"file-upload-label\">\n {{ label }}\n\n @if (required) {\n <span class=\"file-upload-required\">*</span>\n }\n </label>\n }\n\n <!-- Upload Area -->\n <div\n class=\"file-upload-container\"\n (drop)=\"onDrop($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n >\n <div [class]=\"uploadAreaClasses\" (click)=\"!disabled && triggerFileInput()\">\n <input\n [id]=\"inputId\"\n [name]=\"name\"\n type=\"file\"\n [accept]=\"accept\"\n [multiple]=\"config.multiple\"\n [disabled]=\"disabled\"\n [required]=\"required\"\n (change)=\"onFileSelect($event)\"\n (blur)=\"onTouched()\"\n class=\"file-upload-hidden\"\n />\n\n <div class=\"file-upload-content\">\n <i class=\"ri-upload-cloud-2-line file-upload-icon\"></i>\n <div class=\"file-upload-text\">\n <p class=\"file-upload-primary-text\">\n @if (config.multiple) {\n {{ 'fileUpload.dropMultiple' | transloco }}\n } @else {\n {{ 'fileUpload.dropSingle' | transloco }}\n }\n </p>\n <p class=\"file-upload-secondary-text\">\n @if (config.allowedExtensions && config.allowedExtensions.length > 0) {\n {{ 'fileUpload.allowedExtensions' | transloco }}\n {{ config.allowedExtensions.join(', ') }}\n }\n @if (config.maxFileSize) {\n \u2022 {{ 'fileUpload.maxSize' | transloco }} {{ formatFileSize(config.maxFileSize) }}\n }\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Files Preview -->\n @if (files.length > 0) {\n <div class=\"file-upload-list\">\n @for (file of files; track file; let i = $index) {\n <file-upload-preview [file]=\"file\" (remove)=\"removeFile(i)\" />\n }\n </div>\n }\n\n <!-- Validation Error -->\n @if (showError) {\n <div class=\"file-upload-error\">\n {{ errorMessage }}\n </div>\n }\n\n <!-- File Type Legend -->\n @if (files.length === 0) {\n <div class=\"file-upload-legend\">\n <div class=\"file-upload-legend-item\">\n <i class=\"ri-image-line file-upload-legend-icon-blue\"></i>\n <span>{{ 'fileUpload.fileTypeImages' | transloco }}</span>\n </div>\n <div class=\"file-upload-legend-item\">\n <i class=\"ri-file-pdf-line file-upload-legend-icon-red\"></i>\n <span>PDF</span>\n </div>\n <div class=\"file-upload-legend-item\">\n <i class=\"ri-file-excel-line file-upload-legend-icon-green\"></i>\n <span>{{ 'fileUpload.fileTypeExcel' | transloco }}</span>\n </div>\n <div class=\"file-upload-legend-item\">\n <i class=\"ri-file-word-line file-upload-legend-icon-word\"></i>\n <span>{{ 'fileUpload.fileTypeWord' | transloco }}</span>\n </div>\n <div class=\"file-upload-legend-item\">\n <i class=\"ri-file-text-line file-upload-legend-icon-gray\"></i>\n <span>{{ 'fileUpload.fileTypeText' | transloco }}</span>\n </div>\n <div class=\"file-upload-legend-item\">\n <i class=\"ri-file-line file-upload-legend-icon-muted\"></i>\n <span>{{ 'fileUpload.fileTypeOther' | transloco }}</span>\n </div>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%}.file-upload-label{display:block;font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.875rem;font-weight:500;color:#374151;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.file-upload-label{color:#d1d5db}}.file-upload-required{color:#ef4444}.file-upload-container{position:relative;width:100%}.file-upload-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.file-upload-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}.file-upload-icon{font-size:1.875rem;color:#9ca3af}.file-upload-text{font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.875rem;color:#4b5563}.file-upload-primary-text{font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:500;margin:0}.file-upload-secondary-text{color:#6b7280;font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.75rem;margin-top:.25rem;margin-bottom:0}.file-upload-area{border:2px dashed #d1d5db;border-radius:.5rem;padding:1.5rem;text-align:center;transition:all .2s ease-in-out;cursor:pointer}.file-upload-area:hover:not(.disabled):not(.drag-over){border-color:#9ca3af;background-color:#f9fafb}.file-upload-area.drag-over{border-color:#60a5fa;background-color:#eff6ff}.file-upload-area.disabled{border-color:#e5e7eb;background-color:#f9fafb;cursor:not-allowed}.file-upload-list{display:flex;flex-direction:column;gap:.5rem;margin-top:1rem}.file-upload-error{color:#ef4444;font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.75rem;margin-top:.25rem}.file-upload-legend{display:flex;flex-wrap:wrap;gap:1rem;margin-top:.75rem;font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.75rem;color:#6b7280}@media(prefers-color-scheme:dark){.file-upload-legend{color:#9ca3af}}.file-upload-legend-item{display:flex;align-items:center;gap:.25rem}.file-upload-legend-icon-blue{color:#3b82f6}.file-upload-legend-icon-red{color:#ef4444}.file-upload-legend-icon-green{color:#10b981}.file-upload-legend-icon-word{color:#2563eb}.file-upload-legend-icon-gray{color:#6b7280}.file-upload-legend-icon-muted{color:#9ca3af}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.file-upload-drag-active{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.file-upload-file-list{max-height:15rem;overflow-y:auto}.file-upload-file-list::-webkit-scrollbar{width:.5rem}.file-upload-file-list::-webkit-scrollbar-track{background-color:#f3f4f6;border-radius:9999px}.file-upload-file-list::-webkit-scrollbar-thumb{background-color:#d1d5db;border-radius:9999px}.file-upload-file-list::-webkit-scrollbar-thumb:hover{background-color:#9ca3af}.file-type-icon--image{color:#3b82f6}.file-type-icon--pdf{color:#ef4444}.file-type-icon--excel{color:#10b981}.file-type-icon--word{color:#2563eb}.file-type-icon--text{color:#6b7280}.file-type-icon--default{color:#9ca3af}@media(max-width:640px){.file-upload-area{padding:1rem}.file-upload-icon{font-size:1.25rem}.file-upload-text{font-size:.75rem}}@media(prefers-color-scheme:dark){.file-upload-area{border-color:#4b5563;background-color:#1f2937}.file-upload-area:hover:not(.disabled):not(.drag-over){border-color:#6b7280;background-color:#374151}.file-upload-area.drag-over{border-color:#60a5fa;background-color:#eff6ff}.file-upload-area.disabled{border-color:#374151;background-color:#111827}.file-upload-text{color:#d1d5db}.file-upload-primary-text{color:#f3f4f6}.file-upload-secondary-text{color:#9ca3af}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: TranslocoModule }, { kind: "component", type: FileUploadPreviewComponent, selector: "file-upload-preview", inputs: ["file"], outputs: ["remove"] }, { kind: "pipe", type: i2$1.TranslocoPipe, name: "transloco" }] });
2802
2859
  }
2803
2860
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: FileUploadComponent, decorators: [{
2804
2861
  type: Component,
@@ -2808,12 +2865,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
2808
2865
  ReactiveFormsModule,
2809
2866
  TranslocoModule,
2810
2867
  FileUploadPreviewComponent,
2811
- ], template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <!-- Upload Area -->\n <div\n class=\"relative\"\n (drop)=\"onDrop($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n >\n <div [class]=\"uploadAreaClasses\" (click)=\"!disabled && triggerFileInput()\">\n <input\n [id]=\"inputId\"\n [name]=\"name\"\n type=\"file\"\n [accept]=\"accept\"\n [multiple]=\"config.multiple\"\n [disabled]=\"disabled\"\n [required]=\"required\"\n (change)=\"onFileSelect($event)\"\n (blur)=\"onTouched()\"\n class=\"hidden\"\n />\n\n <div class=\"flex flex-col items-center space-y-2\">\n <i class=\"ri-upload-cloud-2-line text-3xl text-gray-400\"></i>\n <div class=\"text-sm text-gray-600\">\n <p class=\"font-medium\">\n @if (config.multiple) {\n {{ 'fileUpload.dropMultiple' | transloco }}\n } @else {\n {{ 'fileUpload.dropSingle' | transloco }}\n }\n </p>\n <p class=\"text-xs text-gray-500 mt-1\">\n @if (config.allowedExtensions && config.allowedExtensions.length > 0) {\n {{ 'fileUpload.allowedExtensions' | transloco }}\n {{ config.allowedExtensions.join(', ') }}\n }\n @if (config.maxFileSize) {\n \u2022 {{ 'fileUpload.maxSize' | transloco }} {{ formatFileSize(config.maxFileSize) }}\n }\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Files Preview -->\n @if (files.length > 0) {\n <div class=\"flex flex-col gap-2 mt-4\">\n @for (file of files; track file; let i = $index) {\n <file-upload-preview [file]=\"file\" (remove)=\"removeFile(i)\" />\n }\n </div>\n }\n\n <!-- Validation Error -->\n @if (showError) {\n <div class=\"text-red-500 text-xs mt-1\">\n {{ errorMessage }}\n </div>\n }\n\n <!-- File Type Legend -->\n @if (files.length === 0) {\n <div class=\"mt-3 flex flex-wrap gap-4 text-xs text-gray-500\">\n <div class=\"flex items-center space-x-1\">\n <i class=\"ri-image-line text-blue-500\"></i>\n <span>{{ 'fileUpload.fileTypeImages' | transloco }}</span>\n </div>\n <div class=\"flex items-center space-x-1\">\n <i class=\"ri-file-pdf-line text-red-500\"></i>\n <span>PDF</span>\n </div>\n <div class=\"flex items-center space-x-1\">\n <i class=\"ri-file-excel-line text-green-500\"></i>\n <span>{{ 'fileUpload.fileTypeExcel' | transloco }}</span>\n </div>\n <div class=\"flex items-center space-x-1\">\n <i class=\"ri-file-word-line text-blue-600\"></i>\n <span>{{ 'fileUpload.fileTypeWord' | transloco }}</span>\n </div>\n <div class=\"flex items-center space-x-1\">\n <i class=\"ri-file-text-line text-gray-500\"></i>\n <span>{{ 'fileUpload.fileTypeText' | transloco }}</span>\n </div>\n <div class=\"flex items-center space-x-1\">\n <i class=\"ri-file-line text-gray-400\"></i>\n <span>{{ 'fileUpload.fileTypeOther' | transloco }}</span>\n </div>\n </div>\n }\n</div>\n", styles: [".file-upload__drag-over{border-color:#60a5fa;background-color:#eff6ff}.file-upload__disabled{border-color:#e5e7eb;background-color:#f9fafb;cursor:not-allowed}.file-upload__preview{transition:all .2s ease-in-out}.file-upload__preview:hover{transform:scale(1.05)}.file-upload__file-item{transition:all .2s ease-in-out}.file-upload__file-item:hover{background-color:#f3f4f6;border-color:#d1d5db}.file-upload__remove-btn{transition:all .2s ease-in-out}.file-upload__remove-btn:hover{background-color:#fef2f2}.file-upload__remove-btn:active{transform:scale(.95)}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.file-upload__drag-active{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.file-upload__file-list{max-height:15rem;overflow-y:auto}.file-upload__file-list::-webkit-scrollbar{width:.5rem}.file-upload__file-list::-webkit-scrollbar-track{background-color:#f3f4f6;border-radius:9999px}.file-upload__file-list::-webkit-scrollbar-thumb{background-color:#d1d5db;border-radius:9999px}.file-upload__file-list::-webkit-scrollbar-thumb:hover{background-color:#9ca3af}.file-type-icon--image{color:#3b82f6}.file-type-icon--pdf{color:#ef4444}.file-type-icon--excel{color:#10b981}.file-type-icon--word{color:#2563eb}.file-type-icon--text{color:#6b7280}.file-type-icon--default{color:#9ca3af}@media(max-width:640px){.file-upload__file-item{padding:.5rem}.file-upload__file-info{font-size:.75rem}.file-upload__preview{width:2rem;height:2rem}}@media(prefers-color-scheme:dark){.file-upload__file-item{background-color:#1f2937;border-color:#374151}.file-upload__file-item:hover{background-color:#111827;border-color:#4b5563}.file-upload__file-info{color:#d1d5db}.file-upload__file-name{color:#f3f4f6}.file-upload__file-size{color:#9ca3af}}\n"] }]
2868
+ ], template: "<div [class]=\"fieldGroupClasses\">\n @if (label) {\n <label [for]=\"inputId\" class=\"file-upload-label\">\n {{ label }}\n\n @if (required) {\n <span class=\"file-upload-required\">*</span>\n }\n </label>\n }\n\n <!-- Upload Area -->\n <div\n class=\"file-upload-container\"\n (drop)=\"onDrop($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n >\n <div [class]=\"uploadAreaClasses\" (click)=\"!disabled && triggerFileInput()\">\n <input\n [id]=\"inputId\"\n [name]=\"name\"\n type=\"file\"\n [accept]=\"accept\"\n [multiple]=\"config.multiple\"\n [disabled]=\"disabled\"\n [required]=\"required\"\n (change)=\"onFileSelect($event)\"\n (blur)=\"onTouched()\"\n class=\"file-upload-hidden\"\n />\n\n <div class=\"file-upload-content\">\n <i class=\"ri-upload-cloud-2-line file-upload-icon\"></i>\n <div class=\"file-upload-text\">\n <p class=\"file-upload-primary-text\">\n @if (config.multiple) {\n {{ 'fileUpload.dropMultiple' | transloco }}\n } @else {\n {{ 'fileUpload.dropSingle' | transloco }}\n }\n </p>\n <p class=\"file-upload-secondary-text\">\n @if (config.allowedExtensions && config.allowedExtensions.length > 0) {\n {{ 'fileUpload.allowedExtensions' | transloco }}\n {{ config.allowedExtensions.join(', ') }}\n }\n @if (config.maxFileSize) {\n \u2022 {{ 'fileUpload.maxSize' | transloco }} {{ formatFileSize(config.maxFileSize) }}\n }\n </p>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Files Preview -->\n @if (files.length > 0) {\n <div class=\"file-upload-list\">\n @for (file of files; track file; let i = $index) {\n <file-upload-preview [file]=\"file\" (remove)=\"removeFile(i)\" />\n }\n </div>\n }\n\n <!-- Validation Error -->\n @if (showError) {\n <div class=\"file-upload-error\">\n {{ errorMessage }}\n </div>\n }\n\n <!-- File Type Legend -->\n @if (files.length === 0) {\n <div class=\"file-upload-legend\">\n <div class=\"file-upload-legend-item\">\n <i class=\"ri-image-line file-upload-legend-icon-blue\"></i>\n <span>{{ 'fileUpload.fileTypeImages' | transloco }}</span>\n </div>\n <div class=\"file-upload-legend-item\">\n <i class=\"ri-file-pdf-line file-upload-legend-icon-red\"></i>\n <span>PDF</span>\n </div>\n <div class=\"file-upload-legend-item\">\n <i class=\"ri-file-excel-line file-upload-legend-icon-green\"></i>\n <span>{{ 'fileUpload.fileTypeExcel' | transloco }}</span>\n </div>\n <div class=\"file-upload-legend-item\">\n <i class=\"ri-file-word-line file-upload-legend-icon-word\"></i>\n <span>{{ 'fileUpload.fileTypeWord' | transloco }}</span>\n </div>\n <div class=\"file-upload-legend-item\">\n <i class=\"ri-file-text-line file-upload-legend-icon-gray\"></i>\n <span>{{ 'fileUpload.fileTypeText' | transloco }}</span>\n </div>\n <div class=\"file-upload-legend-item\">\n <i class=\"ri-file-line file-upload-legend-icon-muted\"></i>\n <span>{{ 'fileUpload.fileTypeOther' | transloco }}</span>\n </div>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%}.file-upload-label{display:block;font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.875rem;font-weight:500;color:#374151;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.file-upload-label{color:#d1d5db}}.file-upload-required{color:#ef4444}.file-upload-container{position:relative;width:100%}.file-upload-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.file-upload-content{display:flex;flex-direction:column;align-items:center;gap:.5rem}.file-upload-icon{font-size:1.875rem;color:#9ca3af}.file-upload-text{font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.875rem;color:#4b5563}.file-upload-primary-text{font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:500;margin:0}.file-upload-secondary-text{color:#6b7280;font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.75rem;margin-top:.25rem;margin-bottom:0}.file-upload-area{border:2px dashed #d1d5db;border-radius:.5rem;padding:1.5rem;text-align:center;transition:all .2s ease-in-out;cursor:pointer}.file-upload-area:hover:not(.disabled):not(.drag-over){border-color:#9ca3af;background-color:#f9fafb}.file-upload-area.drag-over{border-color:#60a5fa;background-color:#eff6ff}.file-upload-area.disabled{border-color:#e5e7eb;background-color:#f9fafb;cursor:not-allowed}.file-upload-list{display:flex;flex-direction:column;gap:.5rem;margin-top:1rem}.file-upload-error{color:#ef4444;font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.75rem;margin-top:.25rem}.file-upload-legend{display:flex;flex-wrap:wrap;gap:1rem;margin-top:.75rem;font-family:Open Sans,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:.75rem;color:#6b7280}@media(prefers-color-scheme:dark){.file-upload-legend{color:#9ca3af}}.file-upload-legend-item{display:flex;align-items:center;gap:.25rem}.file-upload-legend-icon-blue{color:#3b82f6}.file-upload-legend-icon-red{color:#ef4444}.file-upload-legend-icon-green{color:#10b981}.file-upload-legend-icon-word{color:#2563eb}.file-upload-legend-icon-gray{color:#6b7280}.file-upload-legend-icon-muted{color:#9ca3af}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.file-upload-drag-active{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.file-upload-file-list{max-height:15rem;overflow-y:auto}.file-upload-file-list::-webkit-scrollbar{width:.5rem}.file-upload-file-list::-webkit-scrollbar-track{background-color:#f3f4f6;border-radius:9999px}.file-upload-file-list::-webkit-scrollbar-thumb{background-color:#d1d5db;border-radius:9999px}.file-upload-file-list::-webkit-scrollbar-thumb:hover{background-color:#9ca3af}.file-type-icon--image{color:#3b82f6}.file-type-icon--pdf{color:#ef4444}.file-type-icon--excel{color:#10b981}.file-type-icon--word{color:#2563eb}.file-type-icon--text{color:#6b7280}.file-type-icon--default{color:#9ca3af}@media(max-width:640px){.file-upload-area{padding:1rem}.file-upload-icon{font-size:1.25rem}.file-upload-text{font-size:.75rem}}@media(prefers-color-scheme:dark){.file-upload-area{border-color:#4b5563;background-color:#1f2937}.file-upload-area:hover:not(.disabled):not(.drag-over){border-color:#6b7280;background-color:#374151}.file-upload-area.drag-over{border-color:#60a5fa;background-color:#eff6ff}.file-upload-area.disabled{border-color:#374151;background-color:#111827}.file-upload-text{color:#d1d5db}.file-upload-primary-text{color:#f3f4f6}.file-upload-secondary-text{color:#9ca3af}}\n"] }]
2812
2869
  }], ctorParameters: () => [{ type: i1$1.NgControl, decorators: [{
2813
2870
  type: Self
2814
2871
  }, {
2815
2872
  type: Optional
2816
- }] }, { type: i2.TranslocoService }], propDecorators: { label: [{
2873
+ }] }, { type: i2$1.TranslocoService }], propDecorators: { label: [{
2817
2874
  type: Input
2818
2875
  }], name: [{
2819
2876
  type: Input
@@ -2990,17 +3047,17 @@ class AsyncSelectComponent {
2990
3047
  useExisting: forwardRef(() => AsyncSelectComponent),
2991
3048
  multi: true,
2992
3049
  },
2993
- ], usesOnChanges: true, ngImport: i0, template: "<div class=\"w-full\">\n @if (label) {\n <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <ng-select\n [items]=\"displayItems\"\n [multiple]=\"multiple\"\n [searchable]=\"searchable\"\n [clearable]=\"clearable\"\n [placeholder]=\"placeholder\"\n [loading]=\"loading || loadingSignal()\"\n [virtualScroll]=\"virtualScroll\"\n [notFoundText]=\"notFoundText\"\n [bindLabel]=\"bindLabel\"\n [bindValue]=\"bindValue\"\n [ngModel]=\"value\"\n [typeahead]=\"typeahead$\"\n [closeOnSelect]=\"!multiple\"\n (ngModelChange)=\"onSelectChange($event)\"\n (blur)=\"onTouched()\"\n (search)=\"onSearch($event)\"\n />\n\n @if (showError) {\n <div class=\"text-red-500 text-xs mt-1\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: NgSelectModule }, { kind: "component", type: i2$2.NgSelectComponent, selector: "ng-select", inputs: ["ariaLabelDropdown", "ariaLabel", "markFirst", "placeholder", "fixedPlaceholder", "notFoundText", "typeToSearchText", "preventToggleOnRightClick", "addTagText", "loadingText", "clearAllText", "dropdownPosition", "appendTo", "outsideClickEvent", "loading", "closeOnSelect", "hideSelected", "selectOnTab", "openOnEnter", "maxSelectedItems", "groupBy", "groupValue", "bufferAmount", "virtualScroll", "selectableGroup", "tabFocusOnClearButton", "selectableGroupAsModel", "searchFn", "trackByFn", "clearOnBackspace", "labelForId", "inputAttrs", "tabIndex", "readonly", "searchWhileComposing", "minTermLength", "editableSearchTerm", "ngClass", "typeahead", "multiple", "addTag", "searchable", "clearable", "deselectOnClick", "clearSearchOnAdd", "compareWith", "keyDownFn", "bindLabel", "bindValue", "appearance", "isOpen", "items"], outputs: ["bindLabelChange", "bindValueChange", "appearanceChange", "isOpenChange", "itemsChange", "blur", "focus", "change", "open", "close", "search", "clear", "add", "remove", "scroll", "scrollToEnd"], exportAs: ["ngSelect"] }] });
3050
+ ], usesOnChanges: true, ngImport: i0, template: "<div class=\"async-select-wrapper\">\n @if (label) {\n <label class=\"async-select-label\">\n {{ label }}\n @if (required) {\n <span class=\"async-select-required\">*</span>\n }\n </label>\n }\n\n <ng-select\n [items]=\"displayItems\"\n [multiple]=\"multiple\"\n [searchable]=\"searchable\"\n [clearable]=\"clearable\"\n [placeholder]=\"placeholder\"\n [loading]=\"loading || loadingSignal()\"\n [virtualScroll]=\"virtualScroll\"\n [notFoundText]=\"notFoundText\"\n [bindLabel]=\"bindLabel\"\n [bindValue]=\"bindValue\"\n [ngModel]=\"value\"\n [typeahead]=\"typeahead$\"\n [closeOnSelect]=\"!multiple\"\n [class.error]=\"showError\"\n (ngModelChange)=\"onSelectChange($event)\"\n (blur)=\"onTouched()\"\n (search)=\"onSearch($event)\"\n />\n\n @if (showError) {\n <div class=\"async-select-error-message\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", styles: [".async-select-wrapper{width:100%}.async-select-label{display:block;font-size:.875rem;font-weight:500;color:#374151;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.async-select-label{color:#d1d5db}}.async-select-required{color:#ef4444}.async-select-error-message{color:#ef4444;font-size:.75rem;margin-top:.25rem}.ng-select.ng-select-opened>.ng-select-container{background-color:#fff;border-color:#d1d5db}.ng-select.ng-select-opened>.ng-select-container .ng-arrow{border-top-color:#6b7280}.ng-select.ng-select-focused:not(.ng-select-opened)>.ng-select-container{border-color:#d1d5db;outline:2px solid #4f46e5;outline-offset:2px}.ng-select.ng-select-disabled>.ng-select-container{background-color:#e5e7eb;color:#6b7280;cursor:not-allowed}.ng-select.error>.ng-select-container{outline:2px solid #ef4444;outline-offset:2px}.ng-select .ng-has-value .ng-placeholder{display:none}.ng-select .ng-select-container{color:#111827;background-color:#fff;border:1px solid #d1d5db;border-radius:.375rem;min-height:0}.ng-select .ng-select-container .ng-value-container{padding:.375rem 0 .375rem .75rem}.ng-select .ng-select-container .ng-value-container .ng-placeholder{color:#9ca3af}.ng-select.ng-select-single .ng-select-container{display:flex;gap:.25rem;height:auto}.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{top:50%;transform:translateY(-50%);left:.75rem}.ng-select.ng-select-multiple .ng-select-container .ng-value-container{gap:.25rem}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value{align-items:center;background-color:#eef2ff;border-radius:.125rem;display:flex;color:#4338ca;flex-flow:row nowrap;font-size:.75rem;gap:.25rem;overflow:hidden;padding:.25rem}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon:hover{background-color:#e0e7ff}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value.ng-value-disabled{color:#6b7280;background-color:#f3f4f6}.ng-select .ng-clear-wrapper{align-items:center;color:#9ca3af;display:flex;flex-flow:column nowrap;justify-content:center}.ng-select .ng-clear-wrapper:hover .ng-clear{color:#ef4444}.ng-select .ng-spinner-loader{border-top-color:#4f46e533;border-right-color:#4f46e533;border-bottom-color:#4f46e533;border-left-color:#4f46e5}.ng-select .ng-arrow-wrapper .ng-arrow{border-top-color:#9ca3af}.ng-select .ng-arrow-wrapper:hover .ng-arrow{border-top-color:#4b5563}@media(prefers-color-scheme:dark){.ng-select.ng-select-opened>.ng-select-container{background-color:#1f2937;border-color:#4b5563}.ng-select.ng-select-disabled>.ng-select-container{background-color:#374151;color:#d1d5db}.ng-select .ng-select-container{color:#fff;background-color:#1f2937;border-color:#4b5563}.ng-select .ng-select-container .ng-value-container .ng-placeholder{color:#6b7280}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value{color:#a5b4fc;background-color:#4f46e533}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value.ng-value-disabled{color:#9ca3af;background-color:#374151}}.ng-dropdown-panel{background-color:#fff;border:1px solid #e5e7eb;border-radius:.375rem;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.ng-dropdown-panel.ng-select-bottom{margin-top:.25rem}.ng-dropdown-panel.ng-select-top{margin-bottom:.25rem}.ng-dropdown-panel .ng-dropdown-header,.ng-dropdown-panel .ng-dropdown-footer{border-color:#e5e7eb;padding:.5rem}.ng-dropdown-panel .ng-dropdown-panel-items::-webkit-scrollbar{width:4px;height:4px}.ng-dropdown-panel .ng-dropdown-panel-items::-webkit-scrollbar-track{background:transparent}.ng-dropdown-panel .ng-dropdown-panel-items::-webkit-scrollbar-thumb{background:#d1d5db;border-radius:9999px}.ng-dropdown-panel .ng-dropdown-panel-items::-webkit-scrollbar-thumb:hover{background:#9ca3af}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup{font-weight:500;color:#6b7280}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-marked{background-color:#f9fafb}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-selected{color:#374151;background-color:#eef2ff;font-weight:600}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option{background-color:#fff;color:#111827;font-size:.75rem;padding:.5rem .75rem}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected{color:#4338ca;background-color:#eef2ff}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked{background-color:#f9fafb}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-disabled{color:#d1d5db}@media(prefers-color-scheme:dark){.ng-dropdown-panel{background-color:#1f2937;border-color:#374151}.ng-dropdown-panel .ng-dropdown-header,.ng-dropdown-panel .ng-dropdown-footer{border-color:#374151}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup{color:#9ca3af}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-marked{background-color:#374151}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-selected{color:#fff;background-color:#4f46e533}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option{background-color:#1f2937;color:#f3f4f6}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected{color:#a5b4fc;background-color:#4f46e533}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked{background-color:#374151}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-disabled{color:#4b5563}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: NgSelectModule }, { kind: "component", type: i2$2.NgSelectComponent, selector: "ng-select", inputs: ["ariaLabelDropdown", "ariaLabel", "markFirst", "placeholder", "fixedPlaceholder", "notFoundText", "typeToSearchText", "preventToggleOnRightClick", "addTagText", "loadingText", "clearAllText", "dropdownPosition", "appendTo", "outsideClickEvent", "loading", "closeOnSelect", "hideSelected", "selectOnTab", "openOnEnter", "maxSelectedItems", "groupBy", "groupValue", "bufferAmount", "virtualScroll", "selectableGroup", "tabFocusOnClearButton", "selectableGroupAsModel", "searchFn", "trackByFn", "clearOnBackspace", "labelForId", "inputAttrs", "tabIndex", "readonly", "searchWhileComposing", "minTermLength", "editableSearchTerm", "ngClass", "typeahead", "multiple", "addTag", "searchable", "clearable", "deselectOnClick", "clearSearchOnAdd", "compareWith", "keyDownFn", "bindLabel", "bindValue", "appearance", "isOpen", "items"], outputs: ["bindLabelChange", "bindValueChange", "appearanceChange", "isOpenChange", "itemsChange", "blur", "focus", "change", "open", "close", "search", "clear", "add", "remove", "scroll", "scrollToEnd"], exportAs: ["ngSelect"] }], encapsulation: i0.ViewEncapsulation.None });
2994
3051
  }
2995
3052
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: AsyncSelectComponent, decorators: [{
2996
3053
  type: Component,
2997
- args: [{ selector: 'async-select', standalone: true, imports: [CommonModule, FormsModule, NgSelectModule], providers: [
3054
+ args: [{ selector: 'async-select', standalone: true, imports: [CommonModule, FormsModule, NgSelectModule], encapsulation: ViewEncapsulation.None, providers: [
2998
3055
  {
2999
3056
  provide: NG_VALUE_ACCESSOR,
3000
3057
  useExisting: forwardRef(() => AsyncSelectComponent),
3001
3058
  multi: true,
3002
3059
  },
3003
- ], template: "<div class=\"w-full\">\n @if (label) {\n <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n @if (required) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <ng-select\n [items]=\"displayItems\"\n [multiple]=\"multiple\"\n [searchable]=\"searchable\"\n [clearable]=\"clearable\"\n [placeholder]=\"placeholder\"\n [loading]=\"loading || loadingSignal()\"\n [virtualScroll]=\"virtualScroll\"\n [notFoundText]=\"notFoundText\"\n [bindLabel]=\"bindLabel\"\n [bindValue]=\"bindValue\"\n [ngModel]=\"value\"\n [typeahead]=\"typeahead$\"\n [closeOnSelect]=\"!multiple\"\n (ngModelChange)=\"onSelectChange($event)\"\n (blur)=\"onTouched()\"\n (search)=\"onSearch($event)\"\n />\n\n @if (showError) {\n <div class=\"text-red-500 text-xs mt-1\">\n {{ errorMessage }}\n </div>\n }\n</div>\n" }]
3060
+ ], template: "<div class=\"async-select-wrapper\">\n @if (label) {\n <label class=\"async-select-label\">\n {{ label }}\n @if (required) {\n <span class=\"async-select-required\">*</span>\n }\n </label>\n }\n\n <ng-select\n [items]=\"displayItems\"\n [multiple]=\"multiple\"\n [searchable]=\"searchable\"\n [clearable]=\"clearable\"\n [placeholder]=\"placeholder\"\n [loading]=\"loading || loadingSignal()\"\n [virtualScroll]=\"virtualScroll\"\n [notFoundText]=\"notFoundText\"\n [bindLabel]=\"bindLabel\"\n [bindValue]=\"bindValue\"\n [ngModel]=\"value\"\n [typeahead]=\"typeahead$\"\n [closeOnSelect]=\"!multiple\"\n [class.error]=\"showError\"\n (ngModelChange)=\"onSelectChange($event)\"\n (blur)=\"onTouched()\"\n (search)=\"onSearch($event)\"\n />\n\n @if (showError) {\n <div class=\"async-select-error-message\">\n {{ errorMessage }}\n </div>\n }\n</div>\n", styles: [".async-select-wrapper{width:100%}.async-select-label{display:block;font-size:.875rem;font-weight:500;color:#374151;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.async-select-label{color:#d1d5db}}.async-select-required{color:#ef4444}.async-select-error-message{color:#ef4444;font-size:.75rem;margin-top:.25rem}.ng-select.ng-select-opened>.ng-select-container{background-color:#fff;border-color:#d1d5db}.ng-select.ng-select-opened>.ng-select-container .ng-arrow{border-top-color:#6b7280}.ng-select.ng-select-focused:not(.ng-select-opened)>.ng-select-container{border-color:#d1d5db;outline:2px solid #4f46e5;outline-offset:2px}.ng-select.ng-select-disabled>.ng-select-container{background-color:#e5e7eb;color:#6b7280;cursor:not-allowed}.ng-select.error>.ng-select-container{outline:2px solid #ef4444;outline-offset:2px}.ng-select .ng-has-value .ng-placeholder{display:none}.ng-select .ng-select-container{color:#111827;background-color:#fff;border:1px solid #d1d5db;border-radius:.375rem;min-height:0}.ng-select .ng-select-container .ng-value-container{padding:.375rem 0 .375rem .75rem}.ng-select .ng-select-container .ng-value-container .ng-placeholder{color:#9ca3af}.ng-select.ng-select-single .ng-select-container{display:flex;gap:.25rem;height:auto}.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{top:50%;transform:translateY(-50%);left:.75rem}.ng-select.ng-select-multiple .ng-select-container .ng-value-container{gap:.25rem}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value{align-items:center;background-color:#eef2ff;border-radius:.125rem;display:flex;color:#4338ca;flex-flow:row nowrap;font-size:.75rem;gap:.25rem;overflow:hidden;padding:.25rem}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon:hover{background-color:#e0e7ff}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value.ng-value-disabled{color:#6b7280;background-color:#f3f4f6}.ng-select .ng-clear-wrapper{align-items:center;color:#9ca3af;display:flex;flex-flow:column nowrap;justify-content:center}.ng-select .ng-clear-wrapper:hover .ng-clear{color:#ef4444}.ng-select .ng-spinner-loader{border-top-color:#4f46e533;border-right-color:#4f46e533;border-bottom-color:#4f46e533;border-left-color:#4f46e5}.ng-select .ng-arrow-wrapper .ng-arrow{border-top-color:#9ca3af}.ng-select .ng-arrow-wrapper:hover .ng-arrow{border-top-color:#4b5563}@media(prefers-color-scheme:dark){.ng-select.ng-select-opened>.ng-select-container{background-color:#1f2937;border-color:#4b5563}.ng-select.ng-select-disabled>.ng-select-container{background-color:#374151;color:#d1d5db}.ng-select .ng-select-container{color:#fff;background-color:#1f2937;border-color:#4b5563}.ng-select .ng-select-container .ng-value-container .ng-placeholder{color:#6b7280}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value{color:#a5b4fc;background-color:#4f46e533}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value.ng-value-disabled{color:#9ca3af;background-color:#374151}}.ng-dropdown-panel{background-color:#fff;border:1px solid #e5e7eb;border-radius:.375rem;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.ng-dropdown-panel.ng-select-bottom{margin-top:.25rem}.ng-dropdown-panel.ng-select-top{margin-bottom:.25rem}.ng-dropdown-panel .ng-dropdown-header,.ng-dropdown-panel .ng-dropdown-footer{border-color:#e5e7eb;padding:.5rem}.ng-dropdown-panel .ng-dropdown-panel-items::-webkit-scrollbar{width:4px;height:4px}.ng-dropdown-panel .ng-dropdown-panel-items::-webkit-scrollbar-track{background:transparent}.ng-dropdown-panel .ng-dropdown-panel-items::-webkit-scrollbar-thumb{background:#d1d5db;border-radius:9999px}.ng-dropdown-panel .ng-dropdown-panel-items::-webkit-scrollbar-thumb:hover{background:#9ca3af}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup{font-weight:500;color:#6b7280}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-marked{background-color:#f9fafb}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-selected{color:#374151;background-color:#eef2ff;font-weight:600}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option{background-color:#fff;color:#111827;font-size:.75rem;padding:.5rem .75rem}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected{color:#4338ca;background-color:#eef2ff}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked{background-color:#f9fafb}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-disabled{color:#d1d5db}@media(prefers-color-scheme:dark){.ng-dropdown-panel{background-color:#1f2937;border-color:#374151}.ng-dropdown-panel .ng-dropdown-header,.ng-dropdown-panel .ng-dropdown-footer{border-color:#374151}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup{color:#9ca3af}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-marked{background-color:#374151}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-selected{color:#fff;background-color:#4f46e533}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option{background-color:#1f2937;color:#f3f4f6}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected{color:#a5b4fc;background-color:#4f46e533}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked{background-color:#374151}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-disabled{color:#4b5563}}\n"] }]
3004
3061
  }], ctorParameters: () => [], propDecorators: { config: [{
3005
3062
  type: Input
3006
3063
  }], items: [{
@@ -3088,8 +3145,8 @@ class ChangePasswordFormComponent {
3088
3145
  },
3089
3146
  });
3090
3147
  }
3091
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ChangePasswordFormComponent, deps: [{ token: i1$1.FormBuilder }, { token: ChangePasswordFormService }, { token: CustomerService }, { token: AdminService }, { token: ToastService }, { token: i2.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
3092
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: ChangePasswordFormComponent, isStandalone: true, selector: "change-password-form", providers: [AdminService, CustomerService], ngImport: i0, template: "@if (isOpen()) {\n <app-modal\n [title]=\"'changePassword.title' | transloco\"\n [isOpen]=\"isOpen\"\n (closeModal)=\"onCloseModal()\"\n >\n <form\n [formGroup]=\"changePasswordForm\"\n method=\"POST\"\n class=\"flex flex-col gap-4\"\n (ngSubmit)=\"onConfirmDelete()\"\n >\n <form-input\n [label]=\"'changePassword.newPasswordLabel' | transloco\"\n [placeholder]=\"'changePassword.newPasswordPlaceholder' | transloco\"\n name=\"password\"\n type=\"password\"\n class=\"flex-1\"\n [required]=\"true\"\n [autocomplete]=\"false\"\n formControlName=\"password\"\n />\n\n <form-input\n [label]=\"'changePassword.confirmPasswordLabel' | transloco\"\n [placeholder]=\"'changePassword.confirmPasswordPlaceholder' | transloco\"\n name=\"confirm_password\"\n type=\"password\"\n class=\"flex-1\"\n [required]=\"true\"\n [autocomplete]=\"false\"\n formControlName=\"confirm_password\"\n />\n\n <div class=\"flex space-x-3\">\n <app-button\n variant=\"terciary\"\n [text]=\"'changePassword.cancel' | transloco\"\n (click)=\"onCloseModal()\"\n size=\"sm\"\n />\n\n <app-button\n [disabled]=\"loading() || changePasswordForm.invalid || changePasswordForm.pristine\"\n [loading]=\"loading()\"\n type=\"submit\"\n variant=\"primary\"\n [text]=\"'changePassword.save' | transloco\"\n [loadingText]=\"'changePassword.saving' | transloco\"\n size=\"sm\"\n />\n </div>\n </form>\n </app-modal>\n}\n", styles: [".delete-confirmation-modal{animation:fadeIn .3s ease-out}.delete-confirmation-content{animation:slideUp .3s ease-out}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}.confirmation-input{transition:all .2s ease}.confirmation-input:focus{box-shadow:0 0 0 3px #ef44441a}.confirmation-input.invalid{border-color:#dc2626}.confirmation-input.invalid:focus{border-color:#dc2626;box-shadow:0 0 0 3px #dc26261a}.delete-button{transition:all .2s ease}.delete-button:disabled{opacity:.5;cursor:not-allowed}.delete-button:not(:disabled):hover{transform:translateY(-1px);box-shadow:0 4px 12px #dc26264d}.warning-message{border-left:4px solid #f59e0b;background:linear-gradient(135deg,#fef3c7,#fde68a)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "component", type: AppButtonComponent, selector: "app-button", inputs: ["disabled", "loading", "type", "variant", "text", "size", "loadingText", "icon"], outputs: ["clicked"] }, { kind: "component", type: FormInputComponent, selector: "form-input", inputs: ["label", "type", "name", "id", "placeholder", "required", "readonly", "minlength", "min", "step", "pattern", "fieldGroupClass", "autocomplete"] }, { kind: "component", type: AppModalComponent, selector: "app-modal", inputs: ["title", "disableClose", "isOpen", "size"], outputs: ["closeModal"] }, { kind: "pipe", type: i2.TranslocoPipe, name: "transloco" }], encapsulation: i0.ViewEncapsulation.None });
3148
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ChangePasswordFormComponent, deps: [{ token: i1$1.FormBuilder }, { token: ChangePasswordFormService }, { token: CustomerService }, { token: AdminService }, { token: ToastService }, { token: i2$1.TranslocoService }], target: i0.ɵɵFactoryTarget.Component });
3149
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: ChangePasswordFormComponent, isStandalone: true, selector: "change-password-form", providers: [AdminService, CustomerService], ngImport: i0, template: "@if (isOpen()) {\n <app-modal\n [title]=\"'changePassword.title' | transloco\"\n [isOpen]=\"isOpen\"\n (closeModal)=\"onCloseModal()\"\n >\n <form\n [formGroup]=\"changePasswordForm\"\n method=\"POST\"\n class=\"change-password-form-body\"\n (ngSubmit)=\"onConfirmDelete()\"\n >\n <form-input\n [label]=\"'changePassword.newPasswordLabel' | transloco\"\n [placeholder]=\"'changePassword.newPasswordPlaceholder' | transloco\"\n name=\"password\"\n type=\"password\"\n class=\"change-password-form-field\"\n [required]=\"true\"\n [autocomplete]=\"false\"\n formControlName=\"password\"\n />\n\n <form-input\n [label]=\"'changePassword.confirmPasswordLabel' | transloco\"\n [placeholder]=\"'changePassword.confirmPasswordPlaceholder' | transloco\"\n name=\"confirm_password\"\n type=\"password\"\n class=\"change-password-form-field\"\n [required]=\"true\"\n [autocomplete]=\"false\"\n formControlName=\"confirm_password\"\n />\n\n <div class=\"change-password-form-actions\">\n <app-button\n variant=\"tertiary\"\n [text]=\"'changePassword.cancel' | transloco\"\n (click)=\"onCloseModal()\"\n size=\"sm\"\n />\n\n <app-button\n [disabled]=\"loading() || changePasswordForm.invalid || changePasswordForm.pristine\"\n [loading]=\"loading()\"\n type=\"submit\"\n variant=\"primary\"\n [text]=\"'changePassword.save' | transloco\"\n [loadingText]=\"'changePassword.saving' | transloco\"\n size=\"sm\"\n />\n </div>\n </form>\n </app-modal>\n}\n", styles: [".change-password-form-body{display:flex;flex-direction:column;gap:1rem}.change-password-form-field{flex:1}.change-password-form-actions{display:flex;gap:.75rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "component", type: AppButtonComponent, selector: "app-button", inputs: ["disabled", "loading", "type", "variant", "text", "size", "loadingText", "icon"], outputs: ["clicked"] }, { kind: "component", type: FormInputComponent, selector: "form-input", inputs: ["label", "type", "name", "id", "placeholder", "required", "readonly", "minlength", "min", "step", "pattern", "fieldGroupClass", "autocomplete"] }, { kind: "component", type: AppModalComponent, selector: "app-modal", inputs: ["title", "disableClose", "isOpen", "size"], outputs: ["closeModal"] }, { kind: "pipe", type: i2$1.TranslocoPipe, name: "transloco" }], encapsulation: i0.ViewEncapsulation.None });
3093
3150
  }
3094
3151
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ChangePasswordFormComponent, decorators: [{
3095
3152
  type: Component,
@@ -3100,8 +3157,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
3100
3157
  AppButtonComponent,
3101
3158
  FormInputComponent,
3102
3159
  AppModalComponent,
3103
- ], providers: [AdminService, CustomerService], encapsulation: ViewEncapsulation.None, template: "@if (isOpen()) {\n <app-modal\n [title]=\"'changePassword.title' | transloco\"\n [isOpen]=\"isOpen\"\n (closeModal)=\"onCloseModal()\"\n >\n <form\n [formGroup]=\"changePasswordForm\"\n method=\"POST\"\n class=\"flex flex-col gap-4\"\n (ngSubmit)=\"onConfirmDelete()\"\n >\n <form-input\n [label]=\"'changePassword.newPasswordLabel' | transloco\"\n [placeholder]=\"'changePassword.newPasswordPlaceholder' | transloco\"\n name=\"password\"\n type=\"password\"\n class=\"flex-1\"\n [required]=\"true\"\n [autocomplete]=\"false\"\n formControlName=\"password\"\n />\n\n <form-input\n [label]=\"'changePassword.confirmPasswordLabel' | transloco\"\n [placeholder]=\"'changePassword.confirmPasswordPlaceholder' | transloco\"\n name=\"confirm_password\"\n type=\"password\"\n class=\"flex-1\"\n [required]=\"true\"\n [autocomplete]=\"false\"\n formControlName=\"confirm_password\"\n />\n\n <div class=\"flex space-x-3\">\n <app-button\n variant=\"terciary\"\n [text]=\"'changePassword.cancel' | transloco\"\n (click)=\"onCloseModal()\"\n size=\"sm\"\n />\n\n <app-button\n [disabled]=\"loading() || changePasswordForm.invalid || changePasswordForm.pristine\"\n [loading]=\"loading()\"\n type=\"submit\"\n variant=\"primary\"\n [text]=\"'changePassword.save' | transloco\"\n [loadingText]=\"'changePassword.saving' | transloco\"\n size=\"sm\"\n />\n </div>\n </form>\n </app-modal>\n}\n", styles: [".delete-confirmation-modal{animation:fadeIn .3s ease-out}.delete-confirmation-content{animation:slideUp .3s ease-out}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}.confirmation-input{transition:all .2s ease}.confirmation-input:focus{box-shadow:0 0 0 3px #ef44441a}.confirmation-input.invalid{border-color:#dc2626}.confirmation-input.invalid:focus{border-color:#dc2626;box-shadow:0 0 0 3px #dc26261a}.delete-button{transition:all .2s ease}.delete-button:disabled{opacity:.5;cursor:not-allowed}.delete-button:not(:disabled):hover{transform:translateY(-1px);box-shadow:0 4px 12px #dc26264d}.warning-message{border-left:4px solid #f59e0b;background:linear-gradient(135deg,#fef3c7,#fde68a)}\n"] }]
3104
- }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: ChangePasswordFormService }, { type: CustomerService }, { type: AdminService }, { type: ToastService }, { type: i2.TranslocoService }] });
3160
+ ], providers: [AdminService, CustomerService], encapsulation: ViewEncapsulation.None, template: "@if (isOpen()) {\n <app-modal\n [title]=\"'changePassword.title' | transloco\"\n [isOpen]=\"isOpen\"\n (closeModal)=\"onCloseModal()\"\n >\n <form\n [formGroup]=\"changePasswordForm\"\n method=\"POST\"\n class=\"change-password-form-body\"\n (ngSubmit)=\"onConfirmDelete()\"\n >\n <form-input\n [label]=\"'changePassword.newPasswordLabel' | transloco\"\n [placeholder]=\"'changePassword.newPasswordPlaceholder' | transloco\"\n name=\"password\"\n type=\"password\"\n class=\"change-password-form-field\"\n [required]=\"true\"\n [autocomplete]=\"false\"\n formControlName=\"password\"\n />\n\n <form-input\n [label]=\"'changePassword.confirmPasswordLabel' | transloco\"\n [placeholder]=\"'changePassword.confirmPasswordPlaceholder' | transloco\"\n name=\"confirm_password\"\n type=\"password\"\n class=\"change-password-form-field\"\n [required]=\"true\"\n [autocomplete]=\"false\"\n formControlName=\"confirm_password\"\n />\n\n <div class=\"change-password-form-actions\">\n <app-button\n variant=\"tertiary\"\n [text]=\"'changePassword.cancel' | transloco\"\n (click)=\"onCloseModal()\"\n size=\"sm\"\n />\n\n <app-button\n [disabled]=\"loading() || changePasswordForm.invalid || changePasswordForm.pristine\"\n [loading]=\"loading()\"\n type=\"submit\"\n variant=\"primary\"\n [text]=\"'changePassword.save' | transloco\"\n [loadingText]=\"'changePassword.saving' | transloco\"\n size=\"sm\"\n />\n </div>\n </form>\n </app-modal>\n}\n", styles: [".change-password-form-body{display:flex;flex-direction:column;gap:1rem}.change-password-form-field{flex:1}.change-password-form-actions{display:flex;gap:.75rem}\n"] }]
3161
+ }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: ChangePasswordFormService }, { type: CustomerService }, { type: AdminService }, { type: ToastService }, { type: i2$1.TranslocoService }] });
3105
3162
 
3106
3163
  class AdminSelectComponent {
3107
3164
  platformId;
@@ -3943,7 +4000,7 @@ class PerformanceMultiSelectComponent {
3943
4000
  useExisting: forwardRef(() => PerformanceMultiSelectComponent),
3944
4001
  multi: true,
3945
4002
  },
3946
- ], ngImport: i0, template: "<div class=\"w-full\">\n @if (label) {\n <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n </label>\n }\n\n @if (selectedIds.length > 0) {\n <div class=\"flex flex-wrap gap-1 mb-2\">\n @for (id of selectedIds; track id) {\n <span\n class=\"inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800\"\n >\n {{ getPerformanceLabel(id) }}\n <button\n type=\"button\"\n class=\"ml-1 hover:text-green-600 leading-none\"\n (click)=\"removePerformance(id)\"\n >\n &times;\n </button>\n </span>\n }\n </div>\n }\n\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n class=\"w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent\"\n (input)=\"onSearchChange($event)\"\n />\n\n @if (loading()) {\n <div class=\"flex items-center gap-2 mt-2 text-sm text-gray-500\">\n <div\n class=\"w-4 h-4 border-2 border-gray-200 border-t-green-500 rounded-full animate-spin\"\n ></div>\n Cargando funciones...\n </div>\n }\n\n @if (!loading() && filteredPerformances().length > 0) {\n <div\n class=\"mt-1 max-h-48 overflow-y-auto border border-gray-200 rounded-md divide-y divide-gray-100\"\n >\n @for (p of filteredPerformances(); track p.value) {\n <label class=\"flex items-center gap-2 px-3 py-2 hover:bg-gray-50 cursor-pointer text-sm\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(p.value)\"\n (change)=\"togglePerformance(p.value)\"\n class=\"w-4 h-4 accent-green-500 cursor-pointer\"\n />\n <span class=\"text-gray-700 select-none\">{{ p.label }}</span>\n </label>\n }\n </div>\n }\n\n @if (!loading() && filteredPerformances().length === 0) {\n <p class=\"text-sm text-gray-500 mt-1\">No se encontraron funciones</p>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] });
4003
+ ], ngImport: i0, template: "<div class=\"performance-multi-select\">\n @if (label) {\n <label class=\"performance-multi-select-label\">\n {{ label }}\n </label>\n }\n\n @if (selectedIds.length > 0) {\n <div class=\"performance-multi-select-tags\">\n @for (id of selectedIds; track id) {\n <span class=\"performance-multi-select-tag\">\n {{ getPerformanceLabel(id) }}\n <button\n type=\"button\"\n class=\"performance-multi-select-tag-remove\"\n (click)=\"removePerformance(id)\"\n >\n &times;\n </button>\n </span>\n }\n </div>\n }\n\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n class=\"performance-multi-select-search\"\n (input)=\"onSearchChange($event)\"\n />\n\n @if (loading()) {\n <div class=\"performance-multi-select-loading\">\n <div class=\"performance-multi-select-spinner\"></div>\n Cargando funciones...\n </div>\n }\n\n @if (!loading() && filteredPerformances().length > 0) {\n <div class=\"performance-multi-select-list\">\n @for (p of filteredPerformances(); track p.value) {\n <label class=\"performance-multi-select-option\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(p.value)\"\n (change)=\"togglePerformance(p.value)\"\n class=\"performance-multi-select-checkbox\"\n />\n <span class=\"performance-multi-select-option-label\">{{ p.label }}</span>\n </label>\n }\n </div>\n }\n\n @if (!loading() && filteredPerformances().length === 0) {\n <p class=\"performance-multi-select-empty\">No se encontraron funciones</p>\n }\n</div>\n", styles: [".performance-multi-select{width:100%}.performance-multi-select-label{display:block;font-size:.875rem;font-weight:500;color:#374151;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.performance-multi-select-label{color:#d1d5db}}.performance-multi-select-tags{display:flex;flex-wrap:wrap;gap:.25rem;margin-bottom:.5rem}.performance-multi-select-tag{display:inline-flex;align-items:center;gap:.25rem;padding:.25rem .5rem;border-radius:9999px;font-size:.75rem;font-weight:500;background-color:#dcfce7;color:#166534}.performance-multi-select-tag-remove{margin-left:.25rem;line-height:1}.performance-multi-select-tag-remove:hover{color:#16a34a}.performance-multi-select-search{width:100%;padding:.5rem .75rem;border:1px solid #d1d5db;border-radius:.375rem;font-size:.875rem}.performance-multi-select-search:focus{outline:none;box-shadow:0 0 0 2px #22c55e;border-color:transparent}.performance-multi-select-loading{display:flex;align-items:center;gap:.5rem;margin-top:.5rem;font-size:.875rem;color:#6b7280}.performance-multi-select-spinner{width:1rem;height:1rem;border:2px solid #e5e7eb;border-top-color:#22c55e;border-radius:9999px;animation:performance-multi-select-spin .6s linear infinite}.performance-multi-select-list{margin-top:.25rem;max-height:12rem;overflow-y:auto;border:1px solid #e5e7eb;border-radius:.375rem}.performance-multi-select-list>*+*{border-top:1px solid #f3f4f6}.performance-multi-select-option{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;font-size:.875rem;cursor:pointer}.performance-multi-select-option:hover{background-color:#f9fafb}.performance-multi-select-checkbox{width:1rem;height:1rem;accent-color:#22c55e;cursor:pointer}.performance-multi-select-option-label{color:#374151;-webkit-user-select:none;user-select:none}.performance-multi-select-empty{font-size:.875rem;color:#6b7280;margin-top:.25rem}@keyframes performance-multi-select-spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
3947
4004
  }
3948
4005
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PerformanceMultiSelectComponent, decorators: [{
3949
4006
  type: Component,
@@ -3953,7 +4010,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
3953
4010
  useExisting: forwardRef(() => PerformanceMultiSelectComponent),
3954
4011
  multi: true,
3955
4012
  },
3956
- ], template: "<div class=\"w-full\">\n @if (label) {\n <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n </label>\n }\n\n @if (selectedIds.length > 0) {\n <div class=\"flex flex-wrap gap-1 mb-2\">\n @for (id of selectedIds; track id) {\n <span\n class=\"inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800\"\n >\n {{ getPerformanceLabel(id) }}\n <button\n type=\"button\"\n class=\"ml-1 hover:text-green-600 leading-none\"\n (click)=\"removePerformance(id)\"\n >\n &times;\n </button>\n </span>\n }\n </div>\n }\n\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n class=\"w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent\"\n (input)=\"onSearchChange($event)\"\n />\n\n @if (loading()) {\n <div class=\"flex items-center gap-2 mt-2 text-sm text-gray-500\">\n <div\n class=\"w-4 h-4 border-2 border-gray-200 border-t-green-500 rounded-full animate-spin\"\n ></div>\n Cargando funciones...\n </div>\n }\n\n @if (!loading() && filteredPerformances().length > 0) {\n <div\n class=\"mt-1 max-h-48 overflow-y-auto border border-gray-200 rounded-md divide-y divide-gray-100\"\n >\n @for (p of filteredPerformances(); track p.value) {\n <label class=\"flex items-center gap-2 px-3 py-2 hover:bg-gray-50 cursor-pointer text-sm\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(p.value)\"\n (change)=\"togglePerformance(p.value)\"\n class=\"w-4 h-4 accent-green-500 cursor-pointer\"\n />\n <span class=\"text-gray-700 select-none\">{{ p.label }}</span>\n </label>\n }\n </div>\n }\n\n @if (!loading() && filteredPerformances().length === 0) {\n <p class=\"text-sm text-gray-500 mt-1\">No se encontraron funciones</p>\n }\n</div>\n" }]
4013
+ ], template: "<div class=\"performance-multi-select\">\n @if (label) {\n <label class=\"performance-multi-select-label\">\n {{ label }}\n </label>\n }\n\n @if (selectedIds.length > 0) {\n <div class=\"performance-multi-select-tags\">\n @for (id of selectedIds; track id) {\n <span class=\"performance-multi-select-tag\">\n {{ getPerformanceLabel(id) }}\n <button\n type=\"button\"\n class=\"performance-multi-select-tag-remove\"\n (click)=\"removePerformance(id)\"\n >\n &times;\n </button>\n </span>\n }\n </div>\n }\n\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n class=\"performance-multi-select-search\"\n (input)=\"onSearchChange($event)\"\n />\n\n @if (loading()) {\n <div class=\"performance-multi-select-loading\">\n <div class=\"performance-multi-select-spinner\"></div>\n Cargando funciones...\n </div>\n }\n\n @if (!loading() && filteredPerformances().length > 0) {\n <div class=\"performance-multi-select-list\">\n @for (p of filteredPerformances(); track p.value) {\n <label class=\"performance-multi-select-option\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(p.value)\"\n (change)=\"togglePerformance(p.value)\"\n class=\"performance-multi-select-checkbox\"\n />\n <span class=\"performance-multi-select-option-label\">{{ p.label }}</span>\n </label>\n }\n </div>\n }\n\n @if (!loading() && filteredPerformances().length === 0) {\n <p class=\"performance-multi-select-empty\">No se encontraron funciones</p>\n }\n</div>\n", styles: [".performance-multi-select{width:100%}.performance-multi-select-label{display:block;font-size:.875rem;font-weight:500;color:#374151;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.performance-multi-select-label{color:#d1d5db}}.performance-multi-select-tags{display:flex;flex-wrap:wrap;gap:.25rem;margin-bottom:.5rem}.performance-multi-select-tag{display:inline-flex;align-items:center;gap:.25rem;padding:.25rem .5rem;border-radius:9999px;font-size:.75rem;font-weight:500;background-color:#dcfce7;color:#166534}.performance-multi-select-tag-remove{margin-left:.25rem;line-height:1}.performance-multi-select-tag-remove:hover{color:#16a34a}.performance-multi-select-search{width:100%;padding:.5rem .75rem;border:1px solid #d1d5db;border-radius:.375rem;font-size:.875rem}.performance-multi-select-search:focus{outline:none;box-shadow:0 0 0 2px #22c55e;border-color:transparent}.performance-multi-select-loading{display:flex;align-items:center;gap:.5rem;margin-top:.5rem;font-size:.875rem;color:#6b7280}.performance-multi-select-spinner{width:1rem;height:1rem;border:2px solid #e5e7eb;border-top-color:#22c55e;border-radius:9999px;animation:performance-multi-select-spin .6s linear infinite}.performance-multi-select-list{margin-top:.25rem;max-height:12rem;overflow-y:auto;border:1px solid #e5e7eb;border-radius:.375rem}.performance-multi-select-list>*+*{border-top:1px solid #f3f4f6}.performance-multi-select-option{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;font-size:.875rem;cursor:pointer}.performance-multi-select-option:hover{background-color:#f9fafb}.performance-multi-select-checkbox{width:1rem;height:1rem;accent-color:#22c55e;cursor:pointer}.performance-multi-select-option-label{color:#374151;-webkit-user-select:none;user-select:none}.performance-multi-select-empty{font-size:.875rem;color:#6b7280;margin-top:.25rem}@keyframes performance-multi-select-spin{to{transform:rotate(360deg)}}\n"] }]
3957
4014
  }], ctorParameters: () => [{ type: undefined, decorators: [{
3958
4015
  type: Inject,
3959
4016
  args: [PLATFORM_ID]
@@ -4194,7 +4251,7 @@ class ProductMultiSelectComponent {
4194
4251
  useExisting: forwardRef(() => ProductMultiSelectComponent),
4195
4252
  multi: true,
4196
4253
  },
4197
- ], ngImport: i0, template: "<div class=\"w-full\">\n @if (label) {\n <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n </label>\n }\n\n @if (selectedIds.length > 0) {\n <div class=\"flex flex-wrap gap-1 mb-2\">\n @for (id of selectedIds; track id) {\n @let product = getProductOption(id);\n <span\n class=\"inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800\"\n >\n @if (product?.imageUrl) {\n <img [src]=\"product!.imageUrl\" alt=\"\" class=\"w-4 h-4 rounded-full object-cover\" />\n }\n {{ product?.label ?? id }}\n <button\n type=\"button\"\n class=\"ml-1 hover:text-green-600 leading-none\"\n (click)=\"removeProduct(id)\"\n >\n &times;\n </button>\n </span>\n }\n </div>\n }\n\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n class=\"w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent\"\n (input)=\"onSearchChange($event)\"\n />\n\n @if (loading()) {\n <div class=\"flex items-center gap-2 mt-2 text-sm text-gray-500\">\n <div\n class=\"w-4 h-4 border-2 border-gray-200 border-t-green-500 rounded-full animate-spin\"\n ></div>\n Cargando productos...\n </div>\n }\n\n @if (!loading() && filteredProducts().length > 0) {\n <div\n class=\"mt-1 max-h-48 overflow-y-auto border border-gray-200 rounded-md divide-y divide-gray-100\"\n >\n @for (p of filteredProducts(); track p.value) {\n <label class=\"flex items-center gap-2 px-3 py-2 hover:bg-gray-50 cursor-pointer text-sm\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(p.value)\"\n (change)=\"toggleProduct(p.value)\"\n class=\"w-4 h-4 accent-green-500 cursor-pointer\"\n />\n @if (p.imageUrl) {\n <img [src]=\"p.imageUrl\" alt=\"\" class=\"w-6 h-6 rounded object-cover\" />\n } @else {\n <div class=\"w-6 h-6 rounded bg-gray-200 flex items-center justify-center\">\n <i class=\"ri-image-line text-gray-400 text-xs\"></i>\n </div>\n }\n <span class=\"text-gray-700 select-none\">{{ p.label }}</span>\n </label>\n }\n </div>\n }\n\n @if (!loading() && filteredProducts().length === 0) {\n <p class=\"text-sm text-gray-500 mt-1\">No se encontraron productos</p>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] });
4254
+ ], ngImport: i0, template: "<div class=\"product-multi-select\">\n @if (label) {\n <label class=\"product-multi-select-label\">\n {{ label }}\n </label>\n }\n\n @if (selectedIds.length > 0) {\n <div class=\"product-multi-select-tags\">\n @for (id of selectedIds; track id) {\n @let product = getProductOption(id);\n <span class=\"product-multi-select-tag\">\n @if (product?.imageUrl) {\n <img [src]=\"product!.imageUrl\" alt=\"\" class=\"product-multi-select-tag-image\" />\n }\n {{ product?.label ?? id }}\n <button\n type=\"button\"\n class=\"product-multi-select-tag-remove\"\n (click)=\"removeProduct(id)\"\n >\n &times;\n </button>\n </span>\n }\n </div>\n }\n\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n class=\"product-multi-select-search\"\n (input)=\"onSearchChange($event)\"\n />\n\n @if (loading()) {\n <div class=\"product-multi-select-loading\">\n <div class=\"product-multi-select-spinner\"></div>\n Cargando productos...\n </div>\n }\n\n @if (!loading() && filteredProducts().length > 0) {\n <div class=\"product-multi-select-list\">\n @for (p of filteredProducts(); track p.value) {\n <label class=\"product-multi-select-option\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(p.value)\"\n (change)=\"toggleProduct(p.value)\"\n class=\"product-multi-select-checkbox\"\n />\n @if (p.imageUrl) {\n <img [src]=\"p.imageUrl\" alt=\"\" class=\"product-multi-select-option-image\" />\n } @else {\n <div class=\"product-multi-select-option-image-placeholder\">\n <i class=\"ri-image-line\"></i>\n </div>\n }\n <span class=\"product-multi-select-option-label\">{{ p.label }}</span>\n </label>\n }\n </div>\n }\n\n @if (!loading() && filteredProducts().length === 0) {\n <p class=\"product-multi-select-empty\">No se encontraron productos</p>\n }\n</div>\n", styles: [".product-multi-select{width:100%}.product-multi-select-label{display:block;font-size:.875rem;font-weight:500;color:#374151;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.product-multi-select-label{color:#d1d5db}}.product-multi-select-tags{display:flex;flex-wrap:wrap;gap:.25rem;margin-bottom:.5rem}.product-multi-select-tag{display:inline-flex;align-items:center;gap:.25rem;padding:.25rem .5rem;border-radius:9999px;font-size:.75rem;font-weight:500;background-color:#dcfce7;color:#166534}.product-multi-select-tag-image{width:1rem;height:1rem;border-radius:9999px;object-fit:cover}.product-multi-select-tag-remove{margin-left:.25rem;line-height:1}.product-multi-select-tag-remove:hover{color:#16a34a}.product-multi-select-search{width:100%;padding:.5rem .75rem;border:1px solid #d1d5db;border-radius:.375rem;font-size:.875rem}.product-multi-select-search:focus{outline:none;box-shadow:0 0 0 2px #22c55e;border-color:transparent}.product-multi-select-loading{display:flex;align-items:center;gap:.5rem;margin-top:.5rem;font-size:.875rem;color:#6b7280}.product-multi-select-spinner{width:1rem;height:1rem;border:2px solid #e5e7eb;border-top-color:#22c55e;border-radius:9999px;animation:product-multi-select-spin .6s linear infinite}.product-multi-select-list{margin-top:.25rem;max-height:12rem;overflow-y:auto;border:1px solid #e5e7eb;border-radius:.375rem}.product-multi-select-list>*+*{border-top:1px solid #f3f4f6}.product-multi-select-option{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;font-size:.875rem;cursor:pointer}.product-multi-select-option:hover{background-color:#f9fafb}.product-multi-select-checkbox{width:1rem;height:1rem;accent-color:#22c55e;cursor:pointer}.product-multi-select-option-image{width:1.5rem;height:1.5rem;border-radius:.125rem;object-fit:cover}.product-multi-select-option-image-placeholder{width:1.5rem;height:1.5rem;border-radius:.125rem;background-color:#e5e7eb;display:flex;align-items:center;justify-content:center}.product-multi-select-option-image-placeholder i{color:#9ca3af;font-size:.75rem}.product-multi-select-option-label{color:#374151;-webkit-user-select:none;user-select:none}.product-multi-select-empty{font-size:.875rem;color:#6b7280;margin-top:.25rem}@keyframes product-multi-select-spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
4198
4255
  }
4199
4256
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ProductMultiSelectComponent, decorators: [{
4200
4257
  type: Component,
@@ -4204,7 +4261,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
4204
4261
  useExisting: forwardRef(() => ProductMultiSelectComponent),
4205
4262
  multi: true,
4206
4263
  },
4207
- ], template: "<div class=\"w-full\">\n @if (label) {\n <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n </label>\n }\n\n @if (selectedIds.length > 0) {\n <div class=\"flex flex-wrap gap-1 mb-2\">\n @for (id of selectedIds; track id) {\n @let product = getProductOption(id);\n <span\n class=\"inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800\"\n >\n @if (product?.imageUrl) {\n <img [src]=\"product!.imageUrl\" alt=\"\" class=\"w-4 h-4 rounded-full object-cover\" />\n }\n {{ product?.label ?? id }}\n <button\n type=\"button\"\n class=\"ml-1 hover:text-green-600 leading-none\"\n (click)=\"removeProduct(id)\"\n >\n &times;\n </button>\n </span>\n }\n </div>\n }\n\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n class=\"w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent\"\n (input)=\"onSearchChange($event)\"\n />\n\n @if (loading()) {\n <div class=\"flex items-center gap-2 mt-2 text-sm text-gray-500\">\n <div\n class=\"w-4 h-4 border-2 border-gray-200 border-t-green-500 rounded-full animate-spin\"\n ></div>\n Cargando productos...\n </div>\n }\n\n @if (!loading() && filteredProducts().length > 0) {\n <div\n class=\"mt-1 max-h-48 overflow-y-auto border border-gray-200 rounded-md divide-y divide-gray-100\"\n >\n @for (p of filteredProducts(); track p.value) {\n <label class=\"flex items-center gap-2 px-3 py-2 hover:bg-gray-50 cursor-pointer text-sm\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(p.value)\"\n (change)=\"toggleProduct(p.value)\"\n class=\"w-4 h-4 accent-green-500 cursor-pointer\"\n />\n @if (p.imageUrl) {\n <img [src]=\"p.imageUrl\" alt=\"\" class=\"w-6 h-6 rounded object-cover\" />\n } @else {\n <div class=\"w-6 h-6 rounded bg-gray-200 flex items-center justify-center\">\n <i class=\"ri-image-line text-gray-400 text-xs\"></i>\n </div>\n }\n <span class=\"text-gray-700 select-none\">{{ p.label }}</span>\n </label>\n }\n </div>\n }\n\n @if (!loading() && filteredProducts().length === 0) {\n <p class=\"text-sm text-gray-500 mt-1\">No se encontraron productos</p>\n }\n</div>\n" }]
4264
+ ], template: "<div class=\"product-multi-select\">\n @if (label) {\n <label class=\"product-multi-select-label\">\n {{ label }}\n </label>\n }\n\n @if (selectedIds.length > 0) {\n <div class=\"product-multi-select-tags\">\n @for (id of selectedIds; track id) {\n @let product = getProductOption(id);\n <span class=\"product-multi-select-tag\">\n @if (product?.imageUrl) {\n <img [src]=\"product!.imageUrl\" alt=\"\" class=\"product-multi-select-tag-image\" />\n }\n {{ product?.label ?? id }}\n <button\n type=\"button\"\n class=\"product-multi-select-tag-remove\"\n (click)=\"removeProduct(id)\"\n >\n &times;\n </button>\n </span>\n }\n </div>\n }\n\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n class=\"product-multi-select-search\"\n (input)=\"onSearchChange($event)\"\n />\n\n @if (loading()) {\n <div class=\"product-multi-select-loading\">\n <div class=\"product-multi-select-spinner\"></div>\n Cargando productos...\n </div>\n }\n\n @if (!loading() && filteredProducts().length > 0) {\n <div class=\"product-multi-select-list\">\n @for (p of filteredProducts(); track p.value) {\n <label class=\"product-multi-select-option\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(p.value)\"\n (change)=\"toggleProduct(p.value)\"\n class=\"product-multi-select-checkbox\"\n />\n @if (p.imageUrl) {\n <img [src]=\"p.imageUrl\" alt=\"\" class=\"product-multi-select-option-image\" />\n } @else {\n <div class=\"product-multi-select-option-image-placeholder\">\n <i class=\"ri-image-line\"></i>\n </div>\n }\n <span class=\"product-multi-select-option-label\">{{ p.label }}</span>\n </label>\n }\n </div>\n }\n\n @if (!loading() && filteredProducts().length === 0) {\n <p class=\"product-multi-select-empty\">No se encontraron productos</p>\n }\n</div>\n", styles: [".product-multi-select{width:100%}.product-multi-select-label{display:block;font-size:.875rem;font-weight:500;color:#374151;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.product-multi-select-label{color:#d1d5db}}.product-multi-select-tags{display:flex;flex-wrap:wrap;gap:.25rem;margin-bottom:.5rem}.product-multi-select-tag{display:inline-flex;align-items:center;gap:.25rem;padding:.25rem .5rem;border-radius:9999px;font-size:.75rem;font-weight:500;background-color:#dcfce7;color:#166534}.product-multi-select-tag-image{width:1rem;height:1rem;border-radius:9999px;object-fit:cover}.product-multi-select-tag-remove{margin-left:.25rem;line-height:1}.product-multi-select-tag-remove:hover{color:#16a34a}.product-multi-select-search{width:100%;padding:.5rem .75rem;border:1px solid #d1d5db;border-radius:.375rem;font-size:.875rem}.product-multi-select-search:focus{outline:none;box-shadow:0 0 0 2px #22c55e;border-color:transparent}.product-multi-select-loading{display:flex;align-items:center;gap:.5rem;margin-top:.5rem;font-size:.875rem;color:#6b7280}.product-multi-select-spinner{width:1rem;height:1rem;border:2px solid #e5e7eb;border-top-color:#22c55e;border-radius:9999px;animation:product-multi-select-spin .6s linear infinite}.product-multi-select-list{margin-top:.25rem;max-height:12rem;overflow-y:auto;border:1px solid #e5e7eb;border-radius:.375rem}.product-multi-select-list>*+*{border-top:1px solid #f3f4f6}.product-multi-select-option{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;font-size:.875rem;cursor:pointer}.product-multi-select-option:hover{background-color:#f9fafb}.product-multi-select-checkbox{width:1rem;height:1rem;accent-color:#22c55e;cursor:pointer}.product-multi-select-option-image{width:1.5rem;height:1.5rem;border-radius:.125rem;object-fit:cover}.product-multi-select-option-image-placeholder{width:1.5rem;height:1.5rem;border-radius:.125rem;background-color:#e5e7eb;display:flex;align-items:center;justify-content:center}.product-multi-select-option-image-placeholder i{color:#9ca3af;font-size:.75rem}.product-multi-select-option-label{color:#374151;-webkit-user-select:none;user-select:none}.product-multi-select-empty{font-size:.875rem;color:#6b7280;margin-top:.25rem}@keyframes product-multi-select-spin{to{transform:rotate(360deg)}}\n"] }]
4208
4265
  }], ctorParameters: () => [{ type: undefined, decorators: [{
4209
4266
  type: Inject,
4210
4267
  args: [PLATFORM_ID]
@@ -4437,7 +4494,7 @@ class ShowMultiSelectComponent {
4437
4494
  useExisting: forwardRef(() => ShowMultiSelectComponent),
4438
4495
  multi: true,
4439
4496
  },
4440
- ], ngImport: i0, template: "<div class=\"w-full\">\n @if (label) {\n <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n </label>\n }\n\n @if (selectedIds.length > 0) {\n <div class=\"flex flex-wrap gap-1 mb-2\">\n @for (id of selectedIds; track id) {\n <span\n class=\"inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-800\"\n >\n {{ getShowLabel(id) }}\n <button\n type=\"button\"\n class=\"ml-1 hover:text-blue-600 leading-none\"\n (click)=\"removeShow(id)\"\n >\n &times;\n </button>\n </span>\n }\n </div>\n }\n\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n class=\"w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent\"\n (input)=\"onSearchChange($event)\"\n />\n\n @if (loading()) {\n <div class=\"flex items-center gap-2 mt-2 text-sm text-gray-500\">\n <div\n class=\"w-4 h-4 border-2 border-gray-200 border-t-blue-500 rounded-full animate-spin\"\n ></div>\n Cargando funciones...\n </div>\n }\n\n @if (!loading() && filteredShows().length > 0) {\n <div\n class=\"mt-1 max-h-48 overflow-y-auto border border-gray-200 rounded-md divide-y divide-gray-100\"\n >\n @for (show of filteredShows(); track show.value) {\n <label class=\"flex items-center gap-2 px-3 py-2 hover:bg-gray-50 cursor-pointer text-sm\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(show.value)\"\n (change)=\"toggleShow(show.value)\"\n class=\"w-4 h-4 accent-blue-500 cursor-pointer\"\n />\n <span class=\"text-gray-700 select-none\">{{ show.label }}</span>\n </label>\n }\n </div>\n }\n\n @if (!loading() && filteredShows().length === 0) {\n <p class=\"text-sm text-gray-500 mt-1\">No se encontraron funciones</p>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] });
4497
+ ], ngImport: i0, template: "<div class=\"show-multi-select\">\n @if (label) {\n <label class=\"show-multi-select-label\">\n {{ label }}\n </label>\n }\n\n @if (selectedIds.length > 0) {\n <div class=\"show-multi-select-tags\">\n @for (id of selectedIds; track id) {\n <span class=\"show-multi-select-tag\">\n {{ getShowLabel(id) }}\n <button type=\"button\" class=\"show-multi-select-tag-remove\" (click)=\"removeShow(id)\">\n &times;\n </button>\n </span>\n }\n </div>\n }\n\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n class=\"show-multi-select-search\"\n (input)=\"onSearchChange($event)\"\n />\n\n @if (loading()) {\n <div class=\"show-multi-select-loading\">\n <div class=\"show-multi-select-spinner\"></div>\n Cargando funciones...\n </div>\n }\n\n @if (!loading() && filteredShows().length > 0) {\n <div class=\"show-multi-select-list\">\n @for (show of filteredShows(); track show.value) {\n <label class=\"show-multi-select-option\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(show.value)\"\n (change)=\"toggleShow(show.value)\"\n class=\"show-multi-select-checkbox\"\n />\n <span class=\"show-multi-select-option-label\">{{ show.label }}</span>\n </label>\n }\n </div>\n }\n\n @if (!loading() && filteredShows().length === 0) {\n <p class=\"show-multi-select-empty\">No se encontraron funciones</p>\n }\n</div>\n", styles: [".show-multi-select{width:100%}.show-multi-select-label{display:block;font-size:.875rem;font-weight:500;color:#374151;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.show-multi-select-label{color:#d1d5db}}.show-multi-select-tags{display:flex;flex-wrap:wrap;gap:.25rem;margin-bottom:.5rem}.show-multi-select-tag{display:inline-flex;align-items:center;gap:.25rem;padding:.25rem .5rem;border-radius:9999px;font-size:.75rem;font-weight:500;background-color:#dbeafe;color:#1e40af}.show-multi-select-tag-remove{margin-left:.25rem;line-height:1}.show-multi-select-tag-remove:hover{color:#2563eb}.show-multi-select-search{width:100%;padding:.5rem .75rem;border:1px solid #d1d5db;border-radius:.375rem;font-size:.875rem}.show-multi-select-search:focus{outline:none;box-shadow:0 0 0 2px #3b82f6;border-color:transparent}.show-multi-select-loading{display:flex;align-items:center;gap:.5rem;margin-top:.5rem;font-size:.875rem;color:#6b7280}.show-multi-select-spinner{width:1rem;height:1rem;border:2px solid #e5e7eb;border-top-color:#3b82f6;border-radius:9999px;animation:show-multi-select-spin .6s linear infinite}.show-multi-select-list{margin-top:.25rem;max-height:12rem;overflow-y:auto;border:1px solid #e5e7eb;border-radius:.375rem}.show-multi-select-list>*+*{border-top:1px solid #f3f4f6}.show-multi-select-option{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;font-size:.875rem;cursor:pointer}.show-multi-select-option:hover{background-color:#f9fafb}.show-multi-select-checkbox{width:1rem;height:1rem;accent-color:#3b82f6;cursor:pointer}.show-multi-select-option-label{color:#374151;-webkit-user-select:none;user-select:none}.show-multi-select-empty{font-size:.875rem;color:#6b7280;margin-top:.25rem}@keyframes show-multi-select-spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
4441
4498
  }
4442
4499
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ShowMultiSelectComponent, decorators: [{
4443
4500
  type: Component,
@@ -4447,7 +4504,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
4447
4504
  useExisting: forwardRef(() => ShowMultiSelectComponent),
4448
4505
  multi: true,
4449
4506
  },
4450
- ], template: "<div class=\"w-full\">\n @if (label) {\n <label class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {{ label }}\n </label>\n }\n\n @if (selectedIds.length > 0) {\n <div class=\"flex flex-wrap gap-1 mb-2\">\n @for (id of selectedIds; track id) {\n <span\n class=\"inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-800\"\n >\n {{ getShowLabel(id) }}\n <button\n type=\"button\"\n class=\"ml-1 hover:text-blue-600 leading-none\"\n (click)=\"removeShow(id)\"\n >\n &times;\n </button>\n </span>\n }\n </div>\n }\n\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n class=\"w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent\"\n (input)=\"onSearchChange($event)\"\n />\n\n @if (loading()) {\n <div class=\"flex items-center gap-2 mt-2 text-sm text-gray-500\">\n <div\n class=\"w-4 h-4 border-2 border-gray-200 border-t-blue-500 rounded-full animate-spin\"\n ></div>\n Cargando funciones...\n </div>\n }\n\n @if (!loading() && filteredShows().length > 0) {\n <div\n class=\"mt-1 max-h-48 overflow-y-auto border border-gray-200 rounded-md divide-y divide-gray-100\"\n >\n @for (show of filteredShows(); track show.value) {\n <label class=\"flex items-center gap-2 px-3 py-2 hover:bg-gray-50 cursor-pointer text-sm\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(show.value)\"\n (change)=\"toggleShow(show.value)\"\n class=\"w-4 h-4 accent-blue-500 cursor-pointer\"\n />\n <span class=\"text-gray-700 select-none\">{{ show.label }}</span>\n </label>\n }\n </div>\n }\n\n @if (!loading() && filteredShows().length === 0) {\n <p class=\"text-sm text-gray-500 mt-1\">No se encontraron funciones</p>\n }\n</div>\n" }]
4507
+ ], template: "<div class=\"show-multi-select\">\n @if (label) {\n <label class=\"show-multi-select-label\">\n {{ label }}\n </label>\n }\n\n @if (selectedIds.length > 0) {\n <div class=\"show-multi-select-tags\">\n @for (id of selectedIds; track id) {\n <span class=\"show-multi-select-tag\">\n {{ getShowLabel(id) }}\n <button type=\"button\" class=\"show-multi-select-tag-remove\" (click)=\"removeShow(id)\">\n &times;\n </button>\n </span>\n }\n </div>\n }\n\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n class=\"show-multi-select-search\"\n (input)=\"onSearchChange($event)\"\n />\n\n @if (loading()) {\n <div class=\"show-multi-select-loading\">\n <div class=\"show-multi-select-spinner\"></div>\n Cargando funciones...\n </div>\n }\n\n @if (!loading() && filteredShows().length > 0) {\n <div class=\"show-multi-select-list\">\n @for (show of filteredShows(); track show.value) {\n <label class=\"show-multi-select-option\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(show.value)\"\n (change)=\"toggleShow(show.value)\"\n class=\"show-multi-select-checkbox\"\n />\n <span class=\"show-multi-select-option-label\">{{ show.label }}</span>\n </label>\n }\n </div>\n }\n\n @if (!loading() && filteredShows().length === 0) {\n <p class=\"show-multi-select-empty\">No se encontraron funciones</p>\n }\n</div>\n", styles: [".show-multi-select{width:100%}.show-multi-select-label{display:block;font-size:.875rem;font-weight:500;color:#374151;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.show-multi-select-label{color:#d1d5db}}.show-multi-select-tags{display:flex;flex-wrap:wrap;gap:.25rem;margin-bottom:.5rem}.show-multi-select-tag{display:inline-flex;align-items:center;gap:.25rem;padding:.25rem .5rem;border-radius:9999px;font-size:.75rem;font-weight:500;background-color:#dbeafe;color:#1e40af}.show-multi-select-tag-remove{margin-left:.25rem;line-height:1}.show-multi-select-tag-remove:hover{color:#2563eb}.show-multi-select-search{width:100%;padding:.5rem .75rem;border:1px solid #d1d5db;border-radius:.375rem;font-size:.875rem}.show-multi-select-search:focus{outline:none;box-shadow:0 0 0 2px #3b82f6;border-color:transparent}.show-multi-select-loading{display:flex;align-items:center;gap:.5rem;margin-top:.5rem;font-size:.875rem;color:#6b7280}.show-multi-select-spinner{width:1rem;height:1rem;border:2px solid #e5e7eb;border-top-color:#3b82f6;border-radius:9999px;animation:show-multi-select-spin .6s linear infinite}.show-multi-select-list{margin-top:.25rem;max-height:12rem;overflow-y:auto;border:1px solid #e5e7eb;border-radius:.375rem}.show-multi-select-list>*+*{border-top:1px solid #f3f4f6}.show-multi-select-option{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;font-size:.875rem;cursor:pointer}.show-multi-select-option:hover{background-color:#f9fafb}.show-multi-select-checkbox{width:1rem;height:1rem;accent-color:#3b82f6;cursor:pointer}.show-multi-select-option-label{color:#374151;-webkit-user-select:none;user-select:none}.show-multi-select-empty{font-size:.875rem;color:#6b7280;margin-top:.25rem}@keyframes show-multi-select-spin{to{transform:rotate(360deg)}}\n"] }]
4451
4508
  }], ctorParameters: () => [{ type: undefined, decorators: [{
4452
4509
  type: Inject,
4453
4510
  args: [PLATFORM_ID]
@@ -4649,11 +4706,11 @@ class DaySelectorGridComponent {
4649
4706
  track.scrollBy({ left: direction * (itemWidth + 8), behavior: 'smooth' });
4650
4707
  }
4651
4708
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DaySelectorGridComponent, deps: [{ token: PLATFORM_ID }, { token: PerformanceService }, { token: PerformancesListEventsService }, { token: ToastService }], target: i0.ɵɵFactoryTarget.Component });
4652
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: DaySelectorGridComponent, isStandalone: true, selector: "day-selector-grid", inputs: { displayMode: "displayMode" }, viewQueries: [{ propertyName: "carouselTrack", first: true, predicate: ["carouselTrack"], descendants: true }], ngImport: i0, template: "@if (loadingData()) {\n <div class=\"mt-3 grid grid-cols-4 gap-2 sm:grid-cols-10\">\n @for (i of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; track $index) {\n <div\n class=\"h-26 border border-neutral-200 dark:border-white/10 bg-neutral-100 dark:bg-white/[0.03] rounded-xl animate-pulse w-full\"\n ></div>\n }\n </div>\n}\n\n@if (!loadingData() && days().length < 1) {\n <app-alert\n type=\"error\"\n text=\"No se encontraron funciones disponibles\"\n size=\"md\"\n [closeable]=\"false\"\n />\n}\n\n@if (days().length > 0) {\n <p class=\"text-[11px] font-semibold tracking-[0.25em] text-neutral-500 uppercase\">\n Selecciona un d\u00EDa\n </p>\n}\n\n@if (displayMode === 'carousel' && days().length > 0) {\n <div class=\"relative mt-3\">\n <button\n type=\"button\"\n (click)=\"scrollCarousel(-1)\"\n class=\"absolute left-0 top-1/2 -translate-y-1/2 z-10 flex items-center justify-center w-8 h-8 rounded-full bg-white dark:bg-neutral-800 border border-neutral-200 dark:border-white/10 shadow-sm hover:bg-neutral-100 dark:hover:bg-neutral-700 transition cursor-pointer\"\n aria-label=\"Anterior\"\n >\n <i class=\"ri-arrow-left-s-line text-lg\"></i>\n </button>\n <div\n #carouselTrack\n class=\"flex overflow-x-auto snap-x snap-mandatory gap-2 px-10 py-1 scroll-smooth [&::-webkit-scrollbar]:hidden\"\n >\n @for (item of days(); track $index) {\n <button\n (click)=\"onToggle(item)\"\n class=\"snap-start flex-shrink-0 w-28 flex flex-col items-center cursor-pointer rounded-xl border border-neutral-200 dark:border-white/10 bg-neutral-50 dark:bg-white/[0.03] px-2 py-3 transition hover:border-neutral-300 dark:hover:border-white/25 hover:bg-neutral-200 dark:hover:bg-white/[0.06] text-neutral-800 dark:text-white\"\n [class.glow-red]=\"isDayActive(item)\"\n [class.border-red-500]=\"isDayActive(item)\"\n [class.bg-red-500]=\"isDayActive(item)\"\n [class.text-white]=\"isDayActive(item)\"\n [class.hover:bg-red-600]=\"isDayActive(item)\"\n [class.dark:hover:text-white]=\"isDayActive(item)\"\n >\n <span\n class=\"text-[10px] font-semibold tracking-widest text-neutral-500 dark:text-white/80\"\n [class.text-white]=\"isDayActive(item)\"\n >\n {{ item.date | date: 'EEE' | uppercase }}\n </span>\n <span class=\"my-0.5 text-2xl font-extrabold leading-none\">\n {{ item.date | date: 'dd' }}\n </span>\n <span\n class=\"text-[10px] font-medium tracking-widest text-neutral-500 dark:text-white/80\"\n [class.text-white]=\"isDayActive(item)\"\n >\n {{ item.date | date: 'MMM' }}\n </span>\n <span\n class=\"mt-2 rounded-full bg-neutral-200 dark:bg-black/25 px-1.5 py-px text-[9px] font-semibold\"\n [class.text-red-500]=\"isDayActive(item)\"\n [class.dark:text-white]=\"isDayActive(item)\"\n >\n {{ item.count | number: '1.0-2' }}\n </span>\n </button>\n }\n </div>\n <button\n type=\"button\"\n (click)=\"scrollCarousel(1)\"\n class=\"absolute right-0 top-1/2 -translate-y-1/2 z-10 flex items-center justify-center w-8 h-8 rounded-full bg-white dark:bg-neutral-800 border border-neutral-200 dark:border-white/10 shadow-sm hover:bg-neutral-100 dark:hover:bg-neutral-700 transition cursor-pointer\"\n aria-label=\"Siguiente\"\n >\n <i class=\"ri-arrow-right-s-line text-lg\"></i>\n </button>\n </div>\n} @else {\n <div class=\"mt-3 grid grid-cols-4 gap-2 sm:grid-cols-10\">\n @for (item of days(); track $index) {\n <button\n (click)=\"onToggle(item)\"\n class=\"flex flex-col items-center cursor-pointer rounded-xl border border-neutral-200 dark:border-white/10 bg-neutral-50 dark:bg-white/[0.03] px-2 py-3 transition hover:border-neutral-300 dark:hover:border-white/25 hover:bg-neutral-200 dark:hover:bg-white/[0.06] text-neutral-800 dark:text-white\"\n [class.glow-red]=\"isDayActive(item)\"\n [class.border-red-500]=\"isDayActive(item)\"\n [class.bg-red-500]=\"isDayActive(item)\"\n [class.text-white]=\"isDayActive(item)\"\n [class.hover:bg-red-600]=\"isDayActive(item)\"\n [class.dark:hover:text-white]=\"isDayActive(item)\"\n >\n <span\n class=\"text-[10px] font-semibold tracking-widest text-neutral-500 dark:text-white/80\"\n [class.text-white]=\"isDayActive(item)\"\n >\n {{ item.date | date: 'EEE' | uppercase }}\n </span>\n <span class=\"my-0.5 text-2xl font-extrabold leading-none\">\n {{ item.date | date: 'dd' }}\n </span>\n <span\n class=\"text-[10px] font-medium tracking-widest text-neutral-500 dark:text-white/80\"\n [class.text-white]=\"isDayActive(item)\"\n >\n {{ item.date | date: 'MMM' }}\n </span>\n <span\n class=\"mt-2 rounded-full bg-neutral-200 dark:bg-black/25 px-1.5 py-px text-[9px] font-semibold\"\n [class.text-red-500]=\"isDayActive(item)\"\n [class.dark:text-white]=\"isDayActive(item)\"\n >\n {{ item.count | number: '1.0-2' }}\n </span>\n </button>\n }\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AppAlertComponent, selector: "app-alert", inputs: ["type", "text", "closeable", "size"] }, { kind: "pipe", type: i2$1.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: i2$1.DecimalPipe, name: "number" }, { kind: "pipe", type: i2$1.DatePipe, name: "date" }] });
4709
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: DaySelectorGridComponent, isStandalone: true, selector: "day-selector-grid", inputs: { displayMode: "displayMode" }, viewQueries: [{ propertyName: "carouselTrack", first: true, predicate: ["carouselTrack"], descendants: true }], ngImport: i0, template: "@if (loadingData()) {\n <div class=\"day-selector-grid\">\n @for (i of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; track $index) {\n <div class=\"day-selector-grid-skeleton-item\"></div>\n }\n </div>\n}\n\n@if (!loadingData() && days().length < 1) {\n <app-alert\n type=\"error\"\n text=\"No se encontraron funciones disponibles\"\n size=\"md\"\n [closeable]=\"false\"\n />\n}\n\n@if (days().length > 0) {\n <p class=\"day-selector-heading\">Selecciona un d\u00EDa</p>\n}\n\n@if (displayMode === 'carousel' && days().length > 0) {\n <div class=\"day-selector-carousel\">\n <button\n type=\"button\"\n (click)=\"scrollCarousel(-1)\"\n class=\"day-selector-carousel-arrow day-selector-carousel-arrow--left\"\n aria-label=\"Anterior\"\n >\n <i class=\"ri-arrow-left-s-line\"></i>\n </button>\n <div #carouselTrack class=\"day-selector-carousel-track\">\n @for (item of days(); track $index) {\n <button\n (click)=\"onToggle(item)\"\n class=\"day-selector-carousel-item\"\n [class.day-selector-item--active]=\"isDayActive(item)\"\n >\n <span class=\"day-selector-item-weekday\">\n {{ item.date | date: 'EEE' | uppercase }}\n </span>\n <span class=\"day-selector-item-day\">\n {{ item.date | date: 'dd' }}\n </span>\n <span class=\"day-selector-item-month\">\n {{ item.date | date: 'MMM' }}\n </span>\n <span class=\"day-selector-item-count\">\n {{ item.count | number: '1.0-2' }}\n </span>\n </button>\n }\n </div>\n <button\n type=\"button\"\n (click)=\"scrollCarousel(1)\"\n class=\"day-selector-carousel-arrow day-selector-carousel-arrow--right\"\n aria-label=\"Siguiente\"\n >\n <i class=\"ri-arrow-right-s-line\"></i>\n </button>\n </div>\n} @else {\n <div class=\"day-selector-grid\">\n @for (item of days(); track $index) {\n <button\n (click)=\"onToggle(item)\"\n class=\"day-selector-grid-item\"\n [class.day-selector-item--active]=\"isDayActive(item)\"\n >\n <span class=\"day-selector-item-weekday\">\n {{ item.date | date: 'EEE' | uppercase }}\n </span>\n <span class=\"day-selector-item-day\">\n {{ item.date | date: 'dd' }}\n </span>\n <span class=\"day-selector-item-month\">\n {{ item.date | date: 'MMM' }}\n </span>\n <span class=\"day-selector-item-count\">\n {{ item.count | number: '1.0-2' }}\n </span>\n </button>\n }\n </div>\n}\n", styles: [".day-selector-heading{font-size:11px;font-weight:600;letter-spacing:.25em;color:#6b7280;text-transform:uppercase}.day-selector-grid{margin-top:.75rem;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.5rem}@media(min-width:640px){.day-selector-grid{grid-template-columns:repeat(10,minmax(0,1fr))}}.day-selector-grid-skeleton-item{height:6.5rem;width:100%;border-radius:.75rem;border:1px solid #e5e7eb;background-color:#f3f4f6;animation:day-selector-pulse 2s cubic-bezier(.4,0,.6,1) infinite}@media(prefers-color-scheme:dark){.day-selector-grid-skeleton-item{border-color:#ffffff1a;background-color:#ffffff08}}.day-selector-carousel-item,.day-selector-grid-item{display:flex;flex-direction:column;align-items:center;cursor:pointer;border-radius:.75rem;border:1px solid #e5e7eb;background-color:#f9fafb;padding:.75rem .5rem;transition:all .2s ease-in-out;color:#1f2937}.day-selector-carousel-item:hover,.day-selector-grid-item:hover{border-color:#d1d5db;background-color:#e5e7eb}@media(prefers-color-scheme:dark){.day-selector-carousel-item,.day-selector-grid-item{border-color:#ffffff1a;background-color:#ffffff08;color:#fff}.day-selector-carousel-item:hover,.day-selector-grid-item:hover{border-color:#ffffff40;background-color:#ffffff0f}}.day-selector-item--active{box-shadow:0 0 0 1px #ef444480,0 0 16px #ef444459;border-color:#ef4444;background-color:#ef4444;color:#fff}.day-selector-item--active:hover{background-color:#dc2626}@media(prefers-color-scheme:dark){.day-selector-item--active:hover{color:#fff}}.day-selector-item-weekday{font-size:10px;font-weight:600;letter-spacing:.05em;color:#6b7280}.day-selector-item--active .day-selector-item-weekday{color:#fff}@media(prefers-color-scheme:dark){.day-selector-item-weekday{color:#fffc}}.day-selector-item-day{margin-top:.125rem;margin-bottom:.125rem;font-size:1.5rem;font-weight:800;line-height:1}.day-selector-item-month{font-size:10px;font-weight:500;letter-spacing:.05em;color:#6b7280}.day-selector-item--active .day-selector-item-month{color:#fff}@media(prefers-color-scheme:dark){.day-selector-item-month{color:#fffc}}.day-selector-item-count{margin-top:.5rem;border-radius:9999px;background-color:#e5e7eb;padding:1px .375rem;font-size:9px;font-weight:600}.day-selector-item--active .day-selector-item-count{color:#ef4444}@media(prefers-color-scheme:dark){.day-selector-item-count{background-color:#00000040}.day-selector-item--active .day-selector-item-count{color:#fff}}.day-selector-carousel{position:relative;margin-top:.75rem}.day-selector-carousel-arrow{position:absolute;top:50%;transform:translateY(-50%);z-index:10;display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:9999px;background-color:#fff;border:1px solid #e5e7eb;box-shadow:0 1px 2px #0000000d;transition:background-color .2s ease-in-out;cursor:pointer}.day-selector-carousel-arrow--left{left:0}.day-selector-carousel-arrow--right{right:0}.day-selector-carousel-arrow:hover{background-color:#f3f4f6}@media(prefers-color-scheme:dark){.day-selector-carousel-arrow{background-color:#1f2937;border-color:#ffffff1a}.day-selector-carousel-arrow:hover{background-color:#374151}}.day-selector-carousel-track{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;gap:.5rem;padding:.25rem 2.5rem;scroll-behavior:smooth}.day-selector-carousel-track::-webkit-scrollbar{display:none}.day-selector-carousel-item{scroll-snap-align:start;flex-shrink:0;width:7rem}@keyframes day-selector-pulse{0%,to{opacity:1}50%{opacity:.5}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AppAlertComponent, selector: "app-alert", inputs: ["type", "text", "closeable", "size"] }, { kind: "pipe", type: i2.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: i2.DecimalPipe, name: "number" }, { kind: "pipe", type: i2.DatePipe, name: "date" }] });
4653
4710
  }
4654
4711
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DaySelectorGridComponent, decorators: [{
4655
4712
  type: Component,
4656
- args: [{ selector: 'day-selector-grid', standalone: true, imports: [CommonModule, AppAlertComponent], template: "@if (loadingData()) {\n <div class=\"mt-3 grid grid-cols-4 gap-2 sm:grid-cols-10\">\n @for (i of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; track $index) {\n <div\n class=\"h-26 border border-neutral-200 dark:border-white/10 bg-neutral-100 dark:bg-white/[0.03] rounded-xl animate-pulse w-full\"\n ></div>\n }\n </div>\n}\n\n@if (!loadingData() && days().length < 1) {\n <app-alert\n type=\"error\"\n text=\"No se encontraron funciones disponibles\"\n size=\"md\"\n [closeable]=\"false\"\n />\n}\n\n@if (days().length > 0) {\n <p class=\"text-[11px] font-semibold tracking-[0.25em] text-neutral-500 uppercase\">\n Selecciona un d\u00EDa\n </p>\n}\n\n@if (displayMode === 'carousel' && days().length > 0) {\n <div class=\"relative mt-3\">\n <button\n type=\"button\"\n (click)=\"scrollCarousel(-1)\"\n class=\"absolute left-0 top-1/2 -translate-y-1/2 z-10 flex items-center justify-center w-8 h-8 rounded-full bg-white dark:bg-neutral-800 border border-neutral-200 dark:border-white/10 shadow-sm hover:bg-neutral-100 dark:hover:bg-neutral-700 transition cursor-pointer\"\n aria-label=\"Anterior\"\n >\n <i class=\"ri-arrow-left-s-line text-lg\"></i>\n </button>\n <div\n #carouselTrack\n class=\"flex overflow-x-auto snap-x snap-mandatory gap-2 px-10 py-1 scroll-smooth [&::-webkit-scrollbar]:hidden\"\n >\n @for (item of days(); track $index) {\n <button\n (click)=\"onToggle(item)\"\n class=\"snap-start flex-shrink-0 w-28 flex flex-col items-center cursor-pointer rounded-xl border border-neutral-200 dark:border-white/10 bg-neutral-50 dark:bg-white/[0.03] px-2 py-3 transition hover:border-neutral-300 dark:hover:border-white/25 hover:bg-neutral-200 dark:hover:bg-white/[0.06] text-neutral-800 dark:text-white\"\n [class.glow-red]=\"isDayActive(item)\"\n [class.border-red-500]=\"isDayActive(item)\"\n [class.bg-red-500]=\"isDayActive(item)\"\n [class.text-white]=\"isDayActive(item)\"\n [class.hover:bg-red-600]=\"isDayActive(item)\"\n [class.dark:hover:text-white]=\"isDayActive(item)\"\n >\n <span\n class=\"text-[10px] font-semibold tracking-widest text-neutral-500 dark:text-white/80\"\n [class.text-white]=\"isDayActive(item)\"\n >\n {{ item.date | date: 'EEE' | uppercase }}\n </span>\n <span class=\"my-0.5 text-2xl font-extrabold leading-none\">\n {{ item.date | date: 'dd' }}\n </span>\n <span\n class=\"text-[10px] font-medium tracking-widest text-neutral-500 dark:text-white/80\"\n [class.text-white]=\"isDayActive(item)\"\n >\n {{ item.date | date: 'MMM' }}\n </span>\n <span\n class=\"mt-2 rounded-full bg-neutral-200 dark:bg-black/25 px-1.5 py-px text-[9px] font-semibold\"\n [class.text-red-500]=\"isDayActive(item)\"\n [class.dark:text-white]=\"isDayActive(item)\"\n >\n {{ item.count | number: '1.0-2' }}\n </span>\n </button>\n }\n </div>\n <button\n type=\"button\"\n (click)=\"scrollCarousel(1)\"\n class=\"absolute right-0 top-1/2 -translate-y-1/2 z-10 flex items-center justify-center w-8 h-8 rounded-full bg-white dark:bg-neutral-800 border border-neutral-200 dark:border-white/10 shadow-sm hover:bg-neutral-100 dark:hover:bg-neutral-700 transition cursor-pointer\"\n aria-label=\"Siguiente\"\n >\n <i class=\"ri-arrow-right-s-line text-lg\"></i>\n </button>\n </div>\n} @else {\n <div class=\"mt-3 grid grid-cols-4 gap-2 sm:grid-cols-10\">\n @for (item of days(); track $index) {\n <button\n (click)=\"onToggle(item)\"\n class=\"flex flex-col items-center cursor-pointer rounded-xl border border-neutral-200 dark:border-white/10 bg-neutral-50 dark:bg-white/[0.03] px-2 py-3 transition hover:border-neutral-300 dark:hover:border-white/25 hover:bg-neutral-200 dark:hover:bg-white/[0.06] text-neutral-800 dark:text-white\"\n [class.glow-red]=\"isDayActive(item)\"\n [class.border-red-500]=\"isDayActive(item)\"\n [class.bg-red-500]=\"isDayActive(item)\"\n [class.text-white]=\"isDayActive(item)\"\n [class.hover:bg-red-600]=\"isDayActive(item)\"\n [class.dark:hover:text-white]=\"isDayActive(item)\"\n >\n <span\n class=\"text-[10px] font-semibold tracking-widest text-neutral-500 dark:text-white/80\"\n [class.text-white]=\"isDayActive(item)\"\n >\n {{ item.date | date: 'EEE' | uppercase }}\n </span>\n <span class=\"my-0.5 text-2xl font-extrabold leading-none\">\n {{ item.date | date: 'dd' }}\n </span>\n <span\n class=\"text-[10px] font-medium tracking-widest text-neutral-500 dark:text-white/80\"\n [class.text-white]=\"isDayActive(item)\"\n >\n {{ item.date | date: 'MMM' }}\n </span>\n <span\n class=\"mt-2 rounded-full bg-neutral-200 dark:bg-black/25 px-1.5 py-px text-[9px] font-semibold\"\n [class.text-red-500]=\"isDayActive(item)\"\n [class.dark:text-white]=\"isDayActive(item)\"\n >\n {{ item.count | number: '1.0-2' }}\n </span>\n </button>\n }\n </div>\n}\n" }]
4713
+ args: [{ selector: 'day-selector-grid', standalone: true, imports: [CommonModule, AppAlertComponent], template: "@if (loadingData()) {\n <div class=\"day-selector-grid\">\n @for (i of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; track $index) {\n <div class=\"day-selector-grid-skeleton-item\"></div>\n }\n </div>\n}\n\n@if (!loadingData() && days().length < 1) {\n <app-alert\n type=\"error\"\n text=\"No se encontraron funciones disponibles\"\n size=\"md\"\n [closeable]=\"false\"\n />\n}\n\n@if (days().length > 0) {\n <p class=\"day-selector-heading\">Selecciona un d\u00EDa</p>\n}\n\n@if (displayMode === 'carousel' && days().length > 0) {\n <div class=\"day-selector-carousel\">\n <button\n type=\"button\"\n (click)=\"scrollCarousel(-1)\"\n class=\"day-selector-carousel-arrow day-selector-carousel-arrow--left\"\n aria-label=\"Anterior\"\n >\n <i class=\"ri-arrow-left-s-line\"></i>\n </button>\n <div #carouselTrack class=\"day-selector-carousel-track\">\n @for (item of days(); track $index) {\n <button\n (click)=\"onToggle(item)\"\n class=\"day-selector-carousel-item\"\n [class.day-selector-item--active]=\"isDayActive(item)\"\n >\n <span class=\"day-selector-item-weekday\">\n {{ item.date | date: 'EEE' | uppercase }}\n </span>\n <span class=\"day-selector-item-day\">\n {{ item.date | date: 'dd' }}\n </span>\n <span class=\"day-selector-item-month\">\n {{ item.date | date: 'MMM' }}\n </span>\n <span class=\"day-selector-item-count\">\n {{ item.count | number: '1.0-2' }}\n </span>\n </button>\n }\n </div>\n <button\n type=\"button\"\n (click)=\"scrollCarousel(1)\"\n class=\"day-selector-carousel-arrow day-selector-carousel-arrow--right\"\n aria-label=\"Siguiente\"\n >\n <i class=\"ri-arrow-right-s-line\"></i>\n </button>\n </div>\n} @else {\n <div class=\"day-selector-grid\">\n @for (item of days(); track $index) {\n <button\n (click)=\"onToggle(item)\"\n class=\"day-selector-grid-item\"\n [class.day-selector-item--active]=\"isDayActive(item)\"\n >\n <span class=\"day-selector-item-weekday\">\n {{ item.date | date: 'EEE' | uppercase }}\n </span>\n <span class=\"day-selector-item-day\">\n {{ item.date | date: 'dd' }}\n </span>\n <span class=\"day-selector-item-month\">\n {{ item.date | date: 'MMM' }}\n </span>\n <span class=\"day-selector-item-count\">\n {{ item.count | number: '1.0-2' }}\n </span>\n </button>\n }\n </div>\n}\n", styles: [".day-selector-heading{font-size:11px;font-weight:600;letter-spacing:.25em;color:#6b7280;text-transform:uppercase}.day-selector-grid{margin-top:.75rem;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.5rem}@media(min-width:640px){.day-selector-grid{grid-template-columns:repeat(10,minmax(0,1fr))}}.day-selector-grid-skeleton-item{height:6.5rem;width:100%;border-radius:.75rem;border:1px solid #e5e7eb;background-color:#f3f4f6;animation:day-selector-pulse 2s cubic-bezier(.4,0,.6,1) infinite}@media(prefers-color-scheme:dark){.day-selector-grid-skeleton-item{border-color:#ffffff1a;background-color:#ffffff08}}.day-selector-carousel-item,.day-selector-grid-item{display:flex;flex-direction:column;align-items:center;cursor:pointer;border-radius:.75rem;border:1px solid #e5e7eb;background-color:#f9fafb;padding:.75rem .5rem;transition:all .2s ease-in-out;color:#1f2937}.day-selector-carousel-item:hover,.day-selector-grid-item:hover{border-color:#d1d5db;background-color:#e5e7eb}@media(prefers-color-scheme:dark){.day-selector-carousel-item,.day-selector-grid-item{border-color:#ffffff1a;background-color:#ffffff08;color:#fff}.day-selector-carousel-item:hover,.day-selector-grid-item:hover{border-color:#ffffff40;background-color:#ffffff0f}}.day-selector-item--active{box-shadow:0 0 0 1px #ef444480,0 0 16px #ef444459;border-color:#ef4444;background-color:#ef4444;color:#fff}.day-selector-item--active:hover{background-color:#dc2626}@media(prefers-color-scheme:dark){.day-selector-item--active:hover{color:#fff}}.day-selector-item-weekday{font-size:10px;font-weight:600;letter-spacing:.05em;color:#6b7280}.day-selector-item--active .day-selector-item-weekday{color:#fff}@media(prefers-color-scheme:dark){.day-selector-item-weekday{color:#fffc}}.day-selector-item-day{margin-top:.125rem;margin-bottom:.125rem;font-size:1.5rem;font-weight:800;line-height:1}.day-selector-item-month{font-size:10px;font-weight:500;letter-spacing:.05em;color:#6b7280}.day-selector-item--active .day-selector-item-month{color:#fff}@media(prefers-color-scheme:dark){.day-selector-item-month{color:#fffc}}.day-selector-item-count{margin-top:.5rem;border-radius:9999px;background-color:#e5e7eb;padding:1px .375rem;font-size:9px;font-weight:600}.day-selector-item--active .day-selector-item-count{color:#ef4444}@media(prefers-color-scheme:dark){.day-selector-item-count{background-color:#00000040}.day-selector-item--active .day-selector-item-count{color:#fff}}.day-selector-carousel{position:relative;margin-top:.75rem}.day-selector-carousel-arrow{position:absolute;top:50%;transform:translateY(-50%);z-index:10;display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:9999px;background-color:#fff;border:1px solid #e5e7eb;box-shadow:0 1px 2px #0000000d;transition:background-color .2s ease-in-out;cursor:pointer}.day-selector-carousel-arrow--left{left:0}.day-selector-carousel-arrow--right{right:0}.day-selector-carousel-arrow:hover{background-color:#f3f4f6}@media(prefers-color-scheme:dark){.day-selector-carousel-arrow{background-color:#1f2937;border-color:#ffffff1a}.day-selector-carousel-arrow:hover{background-color:#374151}}.day-selector-carousel-track{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;gap:.5rem;padding:.25rem 2.5rem;scroll-behavior:smooth}.day-selector-carousel-track::-webkit-scrollbar{display:none}.day-selector-carousel-item{scroll-snap-align:start;flex-shrink:0;width:7rem}@keyframes day-selector-pulse{0%,to{opacity:1}50%{opacity:.5}}\n"] }]
4657
4714
  }], ctorParameters: () => [{ type: undefined, decorators: [{
4658
4715
  type: Inject,
4659
4716
  args: [PLATFORM_ID]
@@ -4677,11 +4734,11 @@ class PerformanceCardComponent {
4677
4734
  return this.listEventService.selectedPerformance()?.id === this.card.id;
4678
4735
  }
4679
4736
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PerformanceCardComponent, deps: [{ token: PerformancesListEventsService }], target: i0.ɵɵFactoryTarget.Component });
4680
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: PerformanceCardComponent, isStandalone: true, selector: "performance-card", inputs: { card: "card" }, ngImport: i0, template: "<div\n class=\"flex flex-col sm:flex-row items-center justify-between gap-4 rounded-2xl border px-5 py-4 transition\"\n [class.border-neutral-200]=\"!isSelected()\"\n [class.dark:border-neutral-700]=\"!isSelected()\"\n [class.bg-neutral-50]=\"!isSelected()\"\n [class.dark:bg-neutral-900]=\"!isSelected()\"\n [class.hover:border-neutral-300]=\"!isSelected()\"\n [class.dark:hover:border-neutral-600]=\"!isSelected()\"\n [class.border-brand]=\"isSelected()\"\n [class.bg-red-500/[0.08]]=\"isSelected()\"\n [class.glow-red]=\"isSelected()\"\n>\n <div class=\"flex rounded-sm overflow-hidden w-full h-auto min-h-20 sm:h-20 sm:w-20\">\n @if (card.show.images && card.show.images.length > 0) {\n <img\n [src]=\"card.show.images[0].full_url\"\n class=\"object-contain object-center max-h-full max-w-full mx-auto\"\n />\n } @else {\n <span class=\"flex bg-gray-200 h-20 w-full animate-pulse\"></span>\n }\n </div>\n\n <div class=\"flex flex-col flex-1 w-full\">\n <div\n class=\"text-2xl font-extrabold leading-none\"\n [class.text-neutral-800]=\"!isSelected()\"\n [class.dark:text-neutral-200]=\"!isSelected()\"\n [class.text-neutral-900]=\"isSelected()\"\n [class.dark:text-neutral-100]=\"isSelected()\"\n >\n {{ card.show.title }}\n </div>\n\n <div class=\"leading-none\">\n <span class=\"text-sm text-neutral-500 dark:text-neutral-400\">\n {{ card.start_time | date: `EEEE` | titlecase }}\n {{ card.start_time | date: `dd 'de' MMMM,` }}\n </span>\n\n <span class=\"font-extrabold text-lg text-neutral-800 dark:text-neutral-200\">\n {{ card.start_time | date: `hh:mm` }}\n </span>\n\n <span\n class=\"font-extrabold text-sm\"\n [class.text-neutral-800]=\"!isSelected()\"\n [class.dark:text-white]=\"!isSelected()\"\n [class.text-red-500]=\"isSelected()\"\n >\n {{ card.start_time | date: 'a' }}\n </span>\n </div>\n\n <div class=\"text-sm text-neutral-500 dark:text-neutral-400 leading-none\">\n Desde\n <span class=\"text-neutral-600 dark:text-neutral-300 font-semibold\">\n ${{ card.zone_price_cheapest | number: '1.0-2' }}\n </span>\n </div>\n </div>\n\n <div class=\"flex flex-col gap-2 w-full sm:w-[200px]\">\n <app-link-button\n [route]=\"`/admin/performances/${card.id}/reservation`\"\n text=\"Comprar entradas\"\n icon=\"ri-coupon-line\"\n variant=\"primary\"\n size=\"xs\"\n />\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AppLinkButtonComponent, selector: "app-link-button", inputs: ["disabled", "loading", "target", "text", "icon", "loadingText", "route", "queryParams", "size", "variant"] }, { kind: "pipe", type: i2$1.DecimalPipe, name: "number" }, { kind: "pipe", type: i2$1.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i2$1.DatePipe, name: "date" }] });
4737
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: PerformanceCardComponent, isStandalone: true, selector: "performance-card", inputs: { card: "card" }, ngImport: i0, template: "<div class=\"performance-card\" [class.performance-card--selected]=\"isSelected()\">\n <div class=\"performance-card-image\">\n @if (card.show.images && card.show.images.length > 0) {\n <img [src]=\"card.show.images[0].full_url\" class=\"performance-card-image-img\" />\n } @else {\n <span class=\"performance-card-image-placeholder\"></span>\n }\n </div>\n\n <div class=\"performance-card-info\">\n <div class=\"performance-card-title\">\n {{ card.show.title }}\n </div>\n\n <div class=\"performance-card-datetime\">\n <span class=\"performance-card-date\">\n {{ card.start_time | date: `EEEE` | titlecase }}\n {{ card.start_time | date: `dd 'de' MMMM,` }}\n </span>\n\n <span class=\"performance-card-time\">\n {{ card.start_time | date: `hh:mm` }}\n </span>\n\n <span class=\"performance-card-meridiem\">\n {{ card.start_time | date: 'a' }}\n </span>\n </div>\n\n <div class=\"performance-card-price\">\n Desde\n <span class=\"performance-card-price-value\">\n ${{ card.zone_price_cheapest | number: '1.0-2' }}\n </span>\n </div>\n </div>\n\n <div class=\"performance-card-actions\">\n <app-link-button\n [route]=\"`/admin/performances/${card.id}/reservation`\"\n text=\"Comprar entradas\"\n icon=\"ri-coupon-line\"\n variant=\"primary\"\n size=\"xs\"\n />\n </div>\n</div>\n", styles: [".performance-card{display:flex;flex-direction:column;align-items:center;justify-content:space-between;gap:1rem;border-radius:1rem;border:1px solid #e5e7eb;background-color:#f9fafb;padding:1rem 1.25rem;transition:all .2s ease-in-out}@media(min-width:640px){.performance-card{flex-direction:row}}.performance-card:hover{border-color:#d1d5db}@media(prefers-color-scheme:dark){.performance-card{border-color:#374151;background-color:#111827}.performance-card:hover{border-color:#4b5563}}.performance-card--selected{border-color:#ef4444;background-color:#ef444414;box-shadow:0 0 0 1px #ef444480,0 0 16px #ef444459}.performance-card--selected:hover{border-color:#ef4444}@media(prefers-color-scheme:dark){.performance-card--selected:hover{border-color:#ef4444}}.performance-card-image{display:flex;border-radius:.125rem;overflow:hidden;width:100%;height:auto;min-height:5rem}@media(min-width:640px){.performance-card-image{height:5rem;width:5rem}}.performance-card-image-img{object-fit:contain;object-position:center;max-height:100%;max-width:100%;margin-left:auto;margin-right:auto}.performance-card-image-placeholder{display:flex;background-color:#e5e7eb;height:5rem;width:100%;animation:performance-card-pulse 2s cubic-bezier(.4,0,.6,1) infinite}.performance-card-info{display:flex;flex-direction:column;flex:1;width:100%}.performance-card-title{font-size:1.5rem;font-weight:800;line-height:1;color:#1f2937}.performance-card--selected .performance-card-title{color:#111827}@media(prefers-color-scheme:dark){.performance-card-title{color:#e5e7eb}.performance-card--selected .performance-card-title{color:#f3f4f6}}.performance-card-datetime{line-height:1}.performance-card-date{font-size:.875rem;color:#6b7280}@media(prefers-color-scheme:dark){.performance-card-date{color:#9ca3af}}.performance-card-time{font-weight:800;font-size:1.125rem;color:#1f2937}@media(prefers-color-scheme:dark){.performance-card-time{color:#e5e7eb}}.performance-card-meridiem{font-weight:800;font-size:.875rem;color:#1f2937}.performance-card--selected .performance-card-meridiem{color:#ef4444}@media(prefers-color-scheme:dark){.performance-card-meridiem{color:#fff}.performance-card--selected .performance-card-meridiem{color:#ef4444}}.performance-card-price{font-size:.875rem;color:#6b7280;line-height:1}@media(prefers-color-scheme:dark){.performance-card-price{color:#9ca3af}}.performance-card-price-value{color:#4b5563;font-weight:600}@media(prefers-color-scheme:dark){.performance-card-price-value{color:#d1d5db}}.performance-card-actions{display:flex;flex-direction:column;gap:.5rem;width:100%}@media(min-width:640px){.performance-card-actions{width:200px}}@keyframes performance-card-pulse{0%,to{opacity:1}50%{opacity:.5}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AppLinkButtonComponent, selector: "app-link-button", inputs: ["disabled", "loading", "target", "text", "icon", "loadingText", "route", "queryParams", "size", "variant"] }, { kind: "pipe", type: i2.DecimalPipe, name: "number" }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i2.DatePipe, name: "date" }] });
4681
4738
  }
4682
4739
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PerformanceCardComponent, decorators: [{
4683
4740
  type: Component,
4684
- args: [{ selector: 'performance-card', standalone: true, imports: [CommonModule, AppLinkButtonComponent], template: "<div\n class=\"flex flex-col sm:flex-row items-center justify-between gap-4 rounded-2xl border px-5 py-4 transition\"\n [class.border-neutral-200]=\"!isSelected()\"\n [class.dark:border-neutral-700]=\"!isSelected()\"\n [class.bg-neutral-50]=\"!isSelected()\"\n [class.dark:bg-neutral-900]=\"!isSelected()\"\n [class.hover:border-neutral-300]=\"!isSelected()\"\n [class.dark:hover:border-neutral-600]=\"!isSelected()\"\n [class.border-brand]=\"isSelected()\"\n [class.bg-red-500/[0.08]]=\"isSelected()\"\n [class.glow-red]=\"isSelected()\"\n>\n <div class=\"flex rounded-sm overflow-hidden w-full h-auto min-h-20 sm:h-20 sm:w-20\">\n @if (card.show.images && card.show.images.length > 0) {\n <img\n [src]=\"card.show.images[0].full_url\"\n class=\"object-contain object-center max-h-full max-w-full mx-auto\"\n />\n } @else {\n <span class=\"flex bg-gray-200 h-20 w-full animate-pulse\"></span>\n }\n </div>\n\n <div class=\"flex flex-col flex-1 w-full\">\n <div\n class=\"text-2xl font-extrabold leading-none\"\n [class.text-neutral-800]=\"!isSelected()\"\n [class.dark:text-neutral-200]=\"!isSelected()\"\n [class.text-neutral-900]=\"isSelected()\"\n [class.dark:text-neutral-100]=\"isSelected()\"\n >\n {{ card.show.title }}\n </div>\n\n <div class=\"leading-none\">\n <span class=\"text-sm text-neutral-500 dark:text-neutral-400\">\n {{ card.start_time | date: `EEEE` | titlecase }}\n {{ card.start_time | date: `dd 'de' MMMM,` }}\n </span>\n\n <span class=\"font-extrabold text-lg text-neutral-800 dark:text-neutral-200\">\n {{ card.start_time | date: `hh:mm` }}\n </span>\n\n <span\n class=\"font-extrabold text-sm\"\n [class.text-neutral-800]=\"!isSelected()\"\n [class.dark:text-white]=\"!isSelected()\"\n [class.text-red-500]=\"isSelected()\"\n >\n {{ card.start_time | date: 'a' }}\n </span>\n </div>\n\n <div class=\"text-sm text-neutral-500 dark:text-neutral-400 leading-none\">\n Desde\n <span class=\"text-neutral-600 dark:text-neutral-300 font-semibold\">\n ${{ card.zone_price_cheapest | number: '1.0-2' }}\n </span>\n </div>\n </div>\n\n <div class=\"flex flex-col gap-2 w-full sm:w-[200px]\">\n <app-link-button\n [route]=\"`/admin/performances/${card.id}/reservation`\"\n text=\"Comprar entradas\"\n icon=\"ri-coupon-line\"\n variant=\"primary\"\n size=\"xs\"\n />\n </div>\n</div>\n" }]
4741
+ args: [{ selector: 'performance-card', standalone: true, imports: [CommonModule, AppLinkButtonComponent], template: "<div class=\"performance-card\" [class.performance-card--selected]=\"isSelected()\">\n <div class=\"performance-card-image\">\n @if (card.show.images && card.show.images.length > 0) {\n <img [src]=\"card.show.images[0].full_url\" class=\"performance-card-image-img\" />\n } @else {\n <span class=\"performance-card-image-placeholder\"></span>\n }\n </div>\n\n <div class=\"performance-card-info\">\n <div class=\"performance-card-title\">\n {{ card.show.title }}\n </div>\n\n <div class=\"performance-card-datetime\">\n <span class=\"performance-card-date\">\n {{ card.start_time | date: `EEEE` | titlecase }}\n {{ card.start_time | date: `dd 'de' MMMM,` }}\n </span>\n\n <span class=\"performance-card-time\">\n {{ card.start_time | date: `hh:mm` }}\n </span>\n\n <span class=\"performance-card-meridiem\">\n {{ card.start_time | date: 'a' }}\n </span>\n </div>\n\n <div class=\"performance-card-price\">\n Desde\n <span class=\"performance-card-price-value\">\n ${{ card.zone_price_cheapest | number: '1.0-2' }}\n </span>\n </div>\n </div>\n\n <div class=\"performance-card-actions\">\n <app-link-button\n [route]=\"`/admin/performances/${card.id}/reservation`\"\n text=\"Comprar entradas\"\n icon=\"ri-coupon-line\"\n variant=\"primary\"\n size=\"xs\"\n />\n </div>\n</div>\n", styles: [".performance-card{display:flex;flex-direction:column;align-items:center;justify-content:space-between;gap:1rem;border-radius:1rem;border:1px solid #e5e7eb;background-color:#f9fafb;padding:1rem 1.25rem;transition:all .2s ease-in-out}@media(min-width:640px){.performance-card{flex-direction:row}}.performance-card:hover{border-color:#d1d5db}@media(prefers-color-scheme:dark){.performance-card{border-color:#374151;background-color:#111827}.performance-card:hover{border-color:#4b5563}}.performance-card--selected{border-color:#ef4444;background-color:#ef444414;box-shadow:0 0 0 1px #ef444480,0 0 16px #ef444459}.performance-card--selected:hover{border-color:#ef4444}@media(prefers-color-scheme:dark){.performance-card--selected:hover{border-color:#ef4444}}.performance-card-image{display:flex;border-radius:.125rem;overflow:hidden;width:100%;height:auto;min-height:5rem}@media(min-width:640px){.performance-card-image{height:5rem;width:5rem}}.performance-card-image-img{object-fit:contain;object-position:center;max-height:100%;max-width:100%;margin-left:auto;margin-right:auto}.performance-card-image-placeholder{display:flex;background-color:#e5e7eb;height:5rem;width:100%;animation:performance-card-pulse 2s cubic-bezier(.4,0,.6,1) infinite}.performance-card-info{display:flex;flex-direction:column;flex:1;width:100%}.performance-card-title{font-size:1.5rem;font-weight:800;line-height:1;color:#1f2937}.performance-card--selected .performance-card-title{color:#111827}@media(prefers-color-scheme:dark){.performance-card-title{color:#e5e7eb}.performance-card--selected .performance-card-title{color:#f3f4f6}}.performance-card-datetime{line-height:1}.performance-card-date{font-size:.875rem;color:#6b7280}@media(prefers-color-scheme:dark){.performance-card-date{color:#9ca3af}}.performance-card-time{font-weight:800;font-size:1.125rem;color:#1f2937}@media(prefers-color-scheme:dark){.performance-card-time{color:#e5e7eb}}.performance-card-meridiem{font-weight:800;font-size:.875rem;color:#1f2937}.performance-card--selected .performance-card-meridiem{color:#ef4444}@media(prefers-color-scheme:dark){.performance-card-meridiem{color:#fff}.performance-card--selected .performance-card-meridiem{color:#ef4444}}.performance-card-price{font-size:.875rem;color:#6b7280;line-height:1}@media(prefers-color-scheme:dark){.performance-card-price{color:#9ca3af}}.performance-card-price-value{color:#4b5563;font-weight:600}@media(prefers-color-scheme:dark){.performance-card-price-value{color:#d1d5db}}.performance-card-actions{display:flex;flex-direction:column;gap:.5rem;width:100%}@media(min-width:640px){.performance-card-actions{width:200px}}@keyframes performance-card-pulse{0%,to{opacity:1}50%{opacity:.5}}\n"] }]
4685
4742
  }], ctorParameters: () => [{ type: PerformancesListEventsService }], propDecorators: { card: [{
4686
4743
  type: Input,
4687
4744
  args: [{ required: true }]
@@ -4742,11 +4799,11 @@ class PerformanceCardListComponent {
4742
4799
  return this.listEventService.selectedDay()?.date ?? null;
4743
4800
  }
4744
4801
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PerformanceCardListComponent, deps: [{ token: PLATFORM_ID }, { token: PerformanceService }, { token: PerformancesListEventsService }, { token: ToastService }], target: i0.ɵɵFactoryTarget.Component });
4745
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: PerformanceCardListComponent, isStandalone: true, selector: "performance-card-list", ngImport: i0, template: "@if (selectedDayDate) {\n <p class=\"text-[11px] font-bold tracking-[0.25em] text-neutral-500 uppercase\">\n <span>Funciones disponibles:</span>\n <span class=\"text-neutral-500 dark:text-neutral-400\">\n el {{ selectedDayDate | date: \"EEEE d 'de' MMMM\" }}\n </span>\n </p>\n}\n\n<div class=\"mt-4 flex flex-col gap-2 w-full\">\n @if (loadingData()) {\n @for (i of [1, 2]; track $index) {\n <div\n class=\"h-40 border border-neutral-200 dark:border-white/10 bg-neutral-100 dark:bg-white/[0.03] rounded-xl animate-pulse w-full\"\n ></div>\n }\n }\n\n @for (card of performances(); track $index) {\n <performance-card [card]=\"card\" />\n }\n</div>\n", dependencies: [{ kind: "component", type: PerformanceCardComponent, selector: "performance-card", inputs: ["card"] }, { kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i2$1.DatePipe, name: "date" }] });
4802
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: PerformanceCardListComponent, isStandalone: true, selector: "performance-card-list", ngImport: i0, template: "@if (selectedDayDate) {\n <p class=\"performance-card-list-heading\">\n <span>Funciones disponibles:</span>\n <span class=\"performance-card-list-heading-date\">\n el {{ selectedDayDate | date: \"EEEE d 'de' MMMM\" }}\n </span>\n </p>\n}\n\n<div class=\"performance-card-list\">\n @if (loadingData()) {\n @for (i of [1, 2]; track $index) {\n <div class=\"performance-card-list-skeleton\"></div>\n }\n }\n\n @for (card of performances(); track $index) {\n <performance-card [card]=\"card\" />\n }\n</div>\n", styles: [".performance-card-list-heading{font-size:11px;font-weight:700;letter-spacing:.25em;color:#6b7280;text-transform:uppercase}.performance-card-list-heading-date{color:#6b7280}@media(prefers-color-scheme:dark){.performance-card-list-heading-date{color:#9ca3af}}.performance-card-list{margin-top:1rem;display:flex;flex-direction:column;gap:.5rem;width:100%}.performance-card-list-skeleton{height:10rem;width:100%;border-radius:.75rem;border:1px solid #e5e7eb;background-color:#f3f4f6;animation:performance-card-list-pulse 2s cubic-bezier(.4,0,.6,1) infinite}@media(prefers-color-scheme:dark){.performance-card-list-skeleton{border-color:#ffffff1a;background-color:#ffffff08}}@keyframes performance-card-list-pulse{0%,to{opacity:1}50%{opacity:.5}}\n"], dependencies: [{ kind: "component", type: PerformanceCardComponent, selector: "performance-card", inputs: ["card"] }, { kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i2.DatePipe, name: "date" }] });
4746
4803
  }
4747
4804
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PerformanceCardListComponent, decorators: [{
4748
4805
  type: Component,
4749
- args: [{ selector: 'performance-card-list', standalone: true, imports: [PerformanceCardComponent, CommonModule], template: "@if (selectedDayDate) {\n <p class=\"text-[11px] font-bold tracking-[0.25em] text-neutral-500 uppercase\">\n <span>Funciones disponibles:</span>\n <span class=\"text-neutral-500 dark:text-neutral-400\">\n el {{ selectedDayDate | date: \"EEEE d 'de' MMMM\" }}\n </span>\n </p>\n}\n\n<div class=\"mt-4 flex flex-col gap-2 w-full\">\n @if (loadingData()) {\n @for (i of [1, 2]; track $index) {\n <div\n class=\"h-40 border border-neutral-200 dark:border-white/10 bg-neutral-100 dark:bg-white/[0.03] rounded-xl animate-pulse w-full\"\n ></div>\n }\n }\n\n @for (card of performances(); track $index) {\n <performance-card [card]=\"card\" />\n }\n</div>\n" }]
4806
+ args: [{ selector: 'performance-card-list', standalone: true, imports: [PerformanceCardComponent, CommonModule], template: "@if (selectedDayDate) {\n <p class=\"performance-card-list-heading\">\n <span>Funciones disponibles:</span>\n <span class=\"performance-card-list-heading-date\">\n el {{ selectedDayDate | date: \"EEEE d 'de' MMMM\" }}\n </span>\n </p>\n}\n\n<div class=\"performance-card-list\">\n @if (loadingData()) {\n @for (i of [1, 2]; track $index) {\n <div class=\"performance-card-list-skeleton\"></div>\n }\n }\n\n @for (card of performances(); track $index) {\n <performance-card [card]=\"card\" />\n }\n</div>\n", styles: [".performance-card-list-heading{font-size:11px;font-weight:700;letter-spacing:.25em;color:#6b7280;text-transform:uppercase}.performance-card-list-heading-date{color:#6b7280}@media(prefers-color-scheme:dark){.performance-card-list-heading-date{color:#9ca3af}}.performance-card-list{margin-top:1rem;display:flex;flex-direction:column;gap:.5rem;width:100%}.performance-card-list-skeleton{height:10rem;width:100%;border-radius:.75rem;border:1px solid #e5e7eb;background-color:#f3f4f6;animation:performance-card-list-pulse 2s cubic-bezier(.4,0,.6,1) infinite}@media(prefers-color-scheme:dark){.performance-card-list-skeleton{border-color:#ffffff1a;background-color:#ffffff08}}@keyframes performance-card-list-pulse{0%,to{opacity:1}50%{opacity:.5}}\n"] }]
4750
4807
  }], ctorParameters: () => [{ type: undefined, decorators: [{
4751
4808
  type: Inject,
4752
4809
  args: [PLATFORM_ID]
@@ -4757,11 +4814,11 @@ class PerformanceStepperComponent {
4757
4814
  title;
4758
4815
  highlight;
4759
4816
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PerformanceStepperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4760
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.25", type: PerformanceStepperComponent, isStandalone: true, selector: "performance-stepper", inputs: { stepLabel: "stepLabel", title: "title", highlight: "highlight" }, ngImport: i0, template: "<div class=\"flex items-center gap-2 text-[11px] font-semibold tracking-[0.25em] text-red-500\">\n <span class=\"h-px w-6 bg-red-500\"></span>\n {{ stepLabel }}\n</div>\n\n<h1 class=\"mt-3 text-5xl font-black leading-none tracking-tight sm:text-6xl\">\n <span class=\"text-neutral-800 dark:text-white\">{{ title }} </span\n ><span class=\"text-red-500\">{{ highlight }}</span>\n</h1>\n" });
4817
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.25", type: PerformanceStepperComponent, isStandalone: true, selector: "performance-stepper", inputs: { stepLabel: "stepLabel", title: "title", highlight: "highlight" }, ngImport: i0, template: "<div class=\"performance-stepper-label\">\n <span class=\"performance-stepper-label-bar\"></span>\n {{ stepLabel }}\n</div>\n\n<h1 class=\"performance-stepper-title\">\n <span class=\"performance-stepper-title-main\">{{ title }} </span\n ><span class=\"performance-stepper-title-highlight\">{{ highlight }}</span>\n</h1>\n", styles: [".performance-stepper-label{display:flex;align-items:center;gap:.5rem;font-size:11px;font-weight:600;letter-spacing:.25em;color:#ef4444}.performance-stepper-label-bar{height:1px;width:1.5rem;background-color:#ef4444}.performance-stepper-title{margin-top:.75rem;font-size:3rem;font-weight:900;line-height:1;letter-spacing:-.025em}@media(min-width:640px){.performance-stepper-title{font-size:3.75rem}}.performance-stepper-title-main{color:#1f2937}@media(prefers-color-scheme:dark){.performance-stepper-title-main{color:#fff}}.performance-stepper-title-highlight{color:#ef4444}\n"] });
4761
4818
  }
4762
4819
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PerformanceStepperComponent, decorators: [{
4763
4820
  type: Component,
4764
- args: [{ selector: 'performance-stepper', standalone: true, template: "<div class=\"flex items-center gap-2 text-[11px] font-semibold tracking-[0.25em] text-red-500\">\n <span class=\"h-px w-6 bg-red-500\"></span>\n {{ stepLabel }}\n</div>\n\n<h1 class=\"mt-3 text-5xl font-black leading-none tracking-tight sm:text-6xl\">\n <span class=\"text-neutral-800 dark:text-white\">{{ title }} </span\n ><span class=\"text-red-500\">{{ highlight }}</span>\n</h1>\n" }]
4821
+ args: [{ selector: 'performance-stepper', standalone: true, template: "<div class=\"performance-stepper-label\">\n <span class=\"performance-stepper-label-bar\"></span>\n {{ stepLabel }}\n</div>\n\n<h1 class=\"performance-stepper-title\">\n <span class=\"performance-stepper-title-main\">{{ title }} </span\n ><span class=\"performance-stepper-title-highlight\">{{ highlight }}</span>\n</h1>\n", styles: [".performance-stepper-label{display:flex;align-items:center;gap:.5rem;font-size:11px;font-weight:600;letter-spacing:.25em;color:#ef4444}.performance-stepper-label-bar{height:1px;width:1.5rem;background-color:#ef4444}.performance-stepper-title{margin-top:.75rem;font-size:3rem;font-weight:900;line-height:1;letter-spacing:-.025em}@media(min-width:640px){.performance-stepper-title{font-size:3.75rem}}.performance-stepper-title-main{color:#1f2937}@media(prefers-color-scheme:dark){.performance-stepper-title-main{color:#fff}}.performance-stepper-title-highlight{color:#ef4444}\n"] }]
4765
4822
  }], propDecorators: { stepLabel: [{
4766
4823
  type: Input,
4767
4824
  args: [{ required: true }]
@@ -4829,11 +4886,11 @@ class ShowsFilterComponent {
4829
4886
  this.listEventService.setSelectedPerformance(null);
4830
4887
  }
4831
4888
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ShowsFilterComponent, deps: [{ token: PLATFORM_ID }, { token: ShowService }, { token: PerformancesListEventsService }, { token: ToastService }, { token: i3.Router }], target: i0.ɵɵFactoryTarget.Component });
4832
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: ShowsFilterComponent, isStandalone: true, selector: "shows-filter", ngImport: i0, template: "<div class=\"flex flex-col gap-2 w-full\">\n @if (shows().length > 0) {\n <p class=\"text-[11px] font-semibold tracking-[0.25em] text-neutral-500 uppercase\">\n Filtrar por evento\n </p>\n }\n\n @if (loadingData()) {\n @for (i of [1, 2, 3]; track $index) {\n <div\n class=\"h-15 border border-neutral-200 dark:border-gray-500/10 bg-neutral-100 dark:bg-gray-500/[0.03] rounded-xl animate-pulse w-full\"\n ></div>\n }\n }\n\n @for (show of shows(); track $index) {\n <div\n class=\"flex items-center justify-between border-gray-500/10 bg-gray-500/[0.02] rounded-xl border px-3 py-3 w-full\"\n [class.glow-red]=\"isActive(show.id)\"\n >\n <div class=\"flex items-center gap-3\">\n <span class=\"h-10 w-10 rounded-sm overflow-hidden\">\n @if (show.images.length > 0) {\n <img\n [src]=\"show.images[0].full_url\"\n class=\"object-contain object-center max-h-full max-w-full mx-auto\"\n />\n } @else {\n <span class=\"flex bg-gray-200 h-full w-full animate-pulse\"></span>\n }\n </span>\n\n <div>\n <div class=\"text-sm font-semibold text-gray-500\">{{ show.title }}</div>\n @if (show.performances_quantity && show.performances_quantity > 0) {\n <div class=\"text-[11px] text-neutral-500\">\n {{ show.performances_quantity }} funciones\n </div>\n }\n </div>\n </div>\n\n <div class=\"text-sm font-bold text-gray-500\">\n @if (isActive(show.id)) {\n <app-button\n variant=\"terciary\"\n icon=\"ri-close-line\"\n size=\"xs\"\n (clicked)=\"onFilter(show)\"\n />\n } @else {\n <app-button variant=\"primary\" text=\"Filtrar\" size=\"xs\" (clicked)=\"onFilter(show)\" />\n }\n </div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "component", type: AppButtonComponent, selector: "app-button", inputs: ["disabled", "loading", "type", "variant", "text", "size", "loadingText", "icon"], outputs: ["clicked"] }, { kind: "ngmodule", type: CommonModule }] });
4889
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: ShowsFilterComponent, isStandalone: true, selector: "shows-filter", ngImport: i0, template: "<div class=\"shows-filter\">\n @if (shows().length > 0) {\n <p class=\"shows-filter-heading\">Filtrar por evento</p>\n }\n\n @if (loadingData()) {\n @for (i of [1, 2, 3]; track $index) {\n <div class=\"shows-filter-skeleton\"></div>\n }\n }\n\n @for (show of shows(); track $index) {\n <div class=\"shows-filter-item\" [class.shows-filter-item--active]=\"isActive(show.id)\">\n <div class=\"shows-filter-item-info\">\n <span class=\"shows-filter-item-image\">\n @if (show.images.length > 0) {\n <img [src]=\"show.images[0].full_url\" class=\"shows-filter-item-image-img\" />\n } @else {\n <span class=\"shows-filter-item-image-placeholder\"></span>\n }\n </span>\n\n <div>\n <div class=\"shows-filter-item-title\">{{ show.title }}</div>\n @if (show.performances_quantity && show.performances_quantity > 0) {\n <div class=\"shows-filter-item-count\">\n {{ show.performances_quantity }} funciones\n </div>\n }\n </div>\n </div>\n\n <div class=\"shows-filter-item-actions\">\n @if (isActive(show.id)) {\n <app-button\n variant=\"tertiary\"\n icon=\"ri-close-line\"\n size=\"xs\"\n (clicked)=\"onFilter(show)\"\n />\n } @else {\n <app-button variant=\"primary\" text=\"Filtrar\" size=\"xs\" (clicked)=\"onFilter(show)\" />\n }\n </div>\n </div>\n }\n</div>\n", styles: [".shows-filter{display:flex;flex-direction:column;gap:.5rem;width:100%}.shows-filter-heading{font-size:11px;font-weight:600;letter-spacing:.25em;color:#6b7280;text-transform:uppercase}.shows-filter-skeleton{height:3.75rem;width:100%;border-radius:.75rem;border:1px solid #e5e7eb;background-color:#f3f4f6;animation:shows-filter-pulse 2s cubic-bezier(.4,0,.6,1) infinite}@media(prefers-color-scheme:dark){.shows-filter-skeleton{border-color:#6b72801a;background-color:#6b728008}}.shows-filter-item{display:flex;align-items:center;justify-content:space-between;border-radius:.75rem;border:1px solid rgba(107,114,128,.1);background-color:#6b728005;padding:.75rem;width:100%}.shows-filter-item--active{box-shadow:0 0 0 1px #ef444480,0 0 16px #ef444459}.shows-filter-item-info{display:flex;align-items:center;gap:.75rem}.shows-filter-item-image{height:2.5rem;width:2.5rem;border-radius:.125rem;overflow:hidden}.shows-filter-item-image-img{object-fit:contain;object-position:center;max-height:100%;max-width:100%;margin-left:auto;margin-right:auto}.shows-filter-item-image-placeholder{display:flex;background-color:#e5e7eb;height:100%;width:100%;animation:shows-filter-pulse 2s cubic-bezier(.4,0,.6,1) infinite}.shows-filter-item-title{font-size:.875rem;font-weight:600;color:#6b7280}.shows-filter-item-count{font-size:11px;color:#6b7280}.shows-filter-item-actions{font-size:.875rem;font-weight:700;color:#6b7280}@keyframes shows-filter-pulse{0%,to{opacity:1}50%{opacity:.5}}\n"], dependencies: [{ kind: "component", type: AppButtonComponent, selector: "app-button", inputs: ["disabled", "loading", "type", "variant", "text", "size", "loadingText", "icon"], outputs: ["clicked"] }, { kind: "ngmodule", type: CommonModule }] });
4833
4890
  }
4834
4891
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ShowsFilterComponent, decorators: [{
4835
4892
  type: Component,
4836
- args: [{ selector: 'shows-filter', standalone: true, imports: [AppButtonComponent, CommonModule], template: "<div class=\"flex flex-col gap-2 w-full\">\n @if (shows().length > 0) {\n <p class=\"text-[11px] font-semibold tracking-[0.25em] text-neutral-500 uppercase\">\n Filtrar por evento\n </p>\n }\n\n @if (loadingData()) {\n @for (i of [1, 2, 3]; track $index) {\n <div\n class=\"h-15 border border-neutral-200 dark:border-gray-500/10 bg-neutral-100 dark:bg-gray-500/[0.03] rounded-xl animate-pulse w-full\"\n ></div>\n }\n }\n\n @for (show of shows(); track $index) {\n <div\n class=\"flex items-center justify-between border-gray-500/10 bg-gray-500/[0.02] rounded-xl border px-3 py-3 w-full\"\n [class.glow-red]=\"isActive(show.id)\"\n >\n <div class=\"flex items-center gap-3\">\n <span class=\"h-10 w-10 rounded-sm overflow-hidden\">\n @if (show.images.length > 0) {\n <img\n [src]=\"show.images[0].full_url\"\n class=\"object-contain object-center max-h-full max-w-full mx-auto\"\n />\n } @else {\n <span class=\"flex bg-gray-200 h-full w-full animate-pulse\"></span>\n }\n </span>\n\n <div>\n <div class=\"text-sm font-semibold text-gray-500\">{{ show.title }}</div>\n @if (show.performances_quantity && show.performances_quantity > 0) {\n <div class=\"text-[11px] text-neutral-500\">\n {{ show.performances_quantity }} funciones\n </div>\n }\n </div>\n </div>\n\n <div class=\"text-sm font-bold text-gray-500\">\n @if (isActive(show.id)) {\n <app-button\n variant=\"terciary\"\n icon=\"ri-close-line\"\n size=\"xs\"\n (clicked)=\"onFilter(show)\"\n />\n } @else {\n <app-button variant=\"primary\" text=\"Filtrar\" size=\"xs\" (clicked)=\"onFilter(show)\" />\n }\n </div>\n </div>\n }\n</div>\n" }]
4893
+ args: [{ selector: 'shows-filter', standalone: true, imports: [AppButtonComponent, CommonModule], template: "<div class=\"shows-filter\">\n @if (shows().length > 0) {\n <p class=\"shows-filter-heading\">Filtrar por evento</p>\n }\n\n @if (loadingData()) {\n @for (i of [1, 2, 3]; track $index) {\n <div class=\"shows-filter-skeleton\"></div>\n }\n }\n\n @for (show of shows(); track $index) {\n <div class=\"shows-filter-item\" [class.shows-filter-item--active]=\"isActive(show.id)\">\n <div class=\"shows-filter-item-info\">\n <span class=\"shows-filter-item-image\">\n @if (show.images.length > 0) {\n <img [src]=\"show.images[0].full_url\" class=\"shows-filter-item-image-img\" />\n } @else {\n <span class=\"shows-filter-item-image-placeholder\"></span>\n }\n </span>\n\n <div>\n <div class=\"shows-filter-item-title\">{{ show.title }}</div>\n @if (show.performances_quantity && show.performances_quantity > 0) {\n <div class=\"shows-filter-item-count\">\n {{ show.performances_quantity }} funciones\n </div>\n }\n </div>\n </div>\n\n <div class=\"shows-filter-item-actions\">\n @if (isActive(show.id)) {\n <app-button\n variant=\"tertiary\"\n icon=\"ri-close-line\"\n size=\"xs\"\n (clicked)=\"onFilter(show)\"\n />\n } @else {\n <app-button variant=\"primary\" text=\"Filtrar\" size=\"xs\" (clicked)=\"onFilter(show)\" />\n }\n </div>\n </div>\n }\n</div>\n", styles: [".shows-filter{display:flex;flex-direction:column;gap:.5rem;width:100%}.shows-filter-heading{font-size:11px;font-weight:600;letter-spacing:.25em;color:#6b7280;text-transform:uppercase}.shows-filter-skeleton{height:3.75rem;width:100%;border-radius:.75rem;border:1px solid #e5e7eb;background-color:#f3f4f6;animation:shows-filter-pulse 2s cubic-bezier(.4,0,.6,1) infinite}@media(prefers-color-scheme:dark){.shows-filter-skeleton{border-color:#6b72801a;background-color:#6b728008}}.shows-filter-item{display:flex;align-items:center;justify-content:space-between;border-radius:.75rem;border:1px solid rgba(107,114,128,.1);background-color:#6b728005;padding:.75rem;width:100%}.shows-filter-item--active{box-shadow:0 0 0 1px #ef444480,0 0 16px #ef444459}.shows-filter-item-info{display:flex;align-items:center;gap:.75rem}.shows-filter-item-image{height:2.5rem;width:2.5rem;border-radius:.125rem;overflow:hidden}.shows-filter-item-image-img{object-fit:contain;object-position:center;max-height:100%;max-width:100%;margin-left:auto;margin-right:auto}.shows-filter-item-image-placeholder{display:flex;background-color:#e5e7eb;height:100%;width:100%;animation:shows-filter-pulse 2s cubic-bezier(.4,0,.6,1) infinite}.shows-filter-item-title{font-size:.875rem;font-weight:600;color:#6b7280}.shows-filter-item-count{font-size:11px;color:#6b7280}.shows-filter-item-actions{font-size:.875rem;font-weight:700;color:#6b7280}@keyframes shows-filter-pulse{0%,to{opacity:1}50%{opacity:.5}}\n"] }]
4837
4894
  }], ctorParameters: () => [{ type: undefined, decorators: [{
4838
4895
  type: Inject,
4839
4896
  args: [PLATFORM_ID]
@@ -4842,11 +4899,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
4842
4899
  class ZonePriceItemComponent {
4843
4900
  zone;
4844
4901
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ZonePriceItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4845
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.25", type: ZonePriceItemComponent, isStandalone: true, selector: "zone-price-item", inputs: { zone: "zone" }, ngImport: i0, template: "<div\n class=\"flex items-center justify-between rounded-xl border border-white/10 bg-white/[0.02] px-4 py-3\"\n>\n <div class=\"flex items-center gap-3\">\n <span class=\"h-3 w-3 rounded-sm {{ zone.colorClass }}\"></span>\n <div>\n <div class=\"text-sm font-semibold text-white\">{{ zone.name }}</div>\n <div class=\"text-[11px] text-neutral-500\">{{ zone.seatsAvailable }} sillas disponibles</div>\n </div>\n </div>\n <div class=\"text-sm font-bold text-white\">{{ zone.price }}</div>\n</div>\n" });
4902
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.25", type: ZonePriceItemComponent, isStandalone: true, selector: "zone-price-item", inputs: { zone: "zone" }, ngImport: i0, template: "<div class=\"zone-price-item\">\n <div class=\"zone-price-item-info\">\n <span class=\"zone-price-item-swatch {{ zone.colorClass }}\"></span>\n <div>\n <div class=\"zone-price-item-name\">{{ zone.name }}</div>\n <div class=\"zone-price-item-seats\">{{ zone.seatsAvailable }} sillas disponibles</div>\n </div>\n </div>\n <div class=\"zone-price-item-price\">{{ zone.price }}</div>\n</div>\n", styles: [".zone-price-item{display:flex;align-items:center;justify-content:space-between;border-radius:.75rem;border:1px solid rgba(255,255,255,.1);background-color:#ffffff05;padding:.75rem 1rem}.zone-price-item-info{display:flex;align-items:center;gap:.75rem}.zone-price-item-swatch{height:.75rem;width:.75rem;border-radius:.125rem}.zone-price-item-name{font-size:.875rem;font-weight:600;color:#fff}.zone-price-item-seats{font-size:11px;color:#6b7280}.zone-price-item-price{font-size:.875rem;font-weight:700;color:#fff}\n"] });
4846
4903
  }
4847
4904
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ZonePriceItemComponent, decorators: [{
4848
4905
  type: Component,
4849
- args: [{ selector: 'zone-price-item', standalone: true, template: "<div\n class=\"flex items-center justify-between rounded-xl border border-white/10 bg-white/[0.02] px-4 py-3\"\n>\n <div class=\"flex items-center gap-3\">\n <span class=\"h-3 w-3 rounded-sm {{ zone.colorClass }}\"></span>\n <div>\n <div class=\"text-sm font-semibold text-white\">{{ zone.name }}</div>\n <div class=\"text-[11px] text-neutral-500\">{{ zone.seatsAvailable }} sillas disponibles</div>\n </div>\n </div>\n <div class=\"text-sm font-bold text-white\">{{ zone.price }}</div>\n</div>\n" }]
4906
+ args: [{ selector: 'zone-price-item', standalone: true, template: "<div class=\"zone-price-item\">\n <div class=\"zone-price-item-info\">\n <span class=\"zone-price-item-swatch {{ zone.colorClass }}\"></span>\n <div>\n <div class=\"zone-price-item-name\">{{ zone.name }}</div>\n <div class=\"zone-price-item-seats\">{{ zone.seatsAvailable }} sillas disponibles</div>\n </div>\n </div>\n <div class=\"zone-price-item-price\">{{ zone.price }}</div>\n</div>\n", styles: [".zone-price-item{display:flex;align-items:center;justify-content:space-between;border-radius:.75rem;border:1px solid rgba(255,255,255,.1);background-color:#ffffff05;padding:.75rem 1rem}.zone-price-item-info{display:flex;align-items:center;gap:.75rem}.zone-price-item-swatch{height:.75rem;width:.75rem;border-radius:.125rem}.zone-price-item-name{font-size:.875rem;font-weight:600;color:#fff}.zone-price-item-seats{font-size:11px;color:#6b7280}.zone-price-item-price{font-size:.875rem;font-weight:700;color:#fff}\n"] }]
4850
4907
  }], propDecorators: { zone: [{
4851
4908
  type: Input,
4852
4909
  args: [{ required: true }]
@@ -4855,11 +4912,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
4855
4912
  class ZonePriceListComponent {
4856
4913
  zones;
4857
4914
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ZonePriceListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4858
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: ZonePriceListComponent, isStandalone: true, selector: "zone-price-list", inputs: { zones: "zones" }, ngImport: i0, template: "<p class=\"text-[11px] font-semibold tracking-[0.25em] text-neutral-400\">ZONAS Y PRECIOS</p>\n\n<div class=\"mt-4 flex flex-col gap-2 w-full\">\n @for (zone of zones; track $index) {\n <zone-price-item [zone]=\"zone\" />\n }\n</div>\n", dependencies: [{ kind: "component", type: ZonePriceItemComponent, selector: "zone-price-item", inputs: ["zone"] }] });
4915
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: ZonePriceListComponent, isStandalone: true, selector: "zone-price-list", inputs: { zones: "zones" }, ngImport: i0, template: "<p class=\"zone-price-list-title\">ZONAS Y PRECIOS</p>\n\n<div class=\"zone-price-list\">\n @for (zone of zones; track $index) {\n <zone-price-item [zone]=\"zone\" />\n }\n</div>\n", styles: [".zone-price-list-title{font-size:11px;font-weight:600;letter-spacing:.25em;color:#9ca3af}.zone-price-list{margin-top:1rem;display:flex;flex-direction:column;gap:.5rem;width:100%}\n"], dependencies: [{ kind: "component", type: ZonePriceItemComponent, selector: "zone-price-item", inputs: ["zone"] }] });
4859
4916
  }
4860
4917
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ZonePriceListComponent, decorators: [{
4861
4918
  type: Component,
4862
- args: [{ selector: 'zone-price-list', standalone: true, imports: [ZonePriceItemComponent], template: "<p class=\"text-[11px] font-semibold tracking-[0.25em] text-neutral-400\">ZONAS Y PRECIOS</p>\n\n<div class=\"mt-4 flex flex-col gap-2 w-full\">\n @for (zone of zones; track $index) {\n <zone-price-item [zone]=\"zone\" />\n }\n</div>\n" }]
4919
+ args: [{ selector: 'zone-price-list', standalone: true, imports: [ZonePriceItemComponent], template: "<p class=\"zone-price-list-title\">ZONAS Y PRECIOS</p>\n\n<div class=\"zone-price-list\">\n @for (zone of zones; track $index) {\n <zone-price-item [zone]=\"zone\" />\n }\n</div>\n", styles: [".zone-price-list-title{font-size:11px;font-weight:600;letter-spacing:.25em;color:#9ca3af}.zone-price-list{margin-top:1rem;display:flex;flex-direction:column;gap:.5rem;width:100%}\n"] }]
4863
4920
  }], propDecorators: { zones: [{
4864
4921
  type: Input,
4865
4922
  args: [{ required: true }]
@@ -4871,5 +4928,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
4871
4928
  * Generated bundle index. Do not edit.
4872
4929
  */
4873
4930
 
4874
- export { ADMIN_API_ROUTES, ALERT_BASE_CLASSES, ALERT_COLOR_CLASSES, ALERT_ICONS, ALERT_SIZE_CLASSES, AdminSelectComponent, AdminService, ApiService, AppAlertComponent, AppButtonComponent, AppLinkButtonComponent, AppModalComponent, AsyncSelectComponent, AuditInformationComponent, BASE_BUTTON_CLASSES, BASE_INPUT_CLASSES, BUTTON_SIZES_CLASSES, BUTTON_VARIANT_CLASSES, CITY_API_ENDPOINTS, COUNTRY_API_ENDPOINTS, CUSTOMERS_API_ROUTES, ChangePasswordFormComponent, ChangePasswordFormService, CitiesService, CitySelectComponent, ColorPickerComponent, CorporateBondStatus, CountrySelectComponent, CountryService, CouponApplicability, CouponDiscountType, CustomerSelectComponent, CustomerService, DateInputComponent, DateService, DaySelectorGridComponent, DeleteConfirmationComponent, DeleteConfirmationService, DynamicTableComponent, ERROR_INPUT_CLASSES, EndDateGreaterThanStartValidator, FORM_ERROR_MESSAGES, FileType, FileUploadComponent, FileUploadPreviewComponent, FormEditorComponent, FormInputComponent, FormSelectComponent, FormTextareaComponent, LanguageSwitcherComponent, LoadingModalService, LoadingmModalComponent, MinTodayValidator, MustMatchValidator, OrderItemType, OrderStatus, PERFORMANCES_API_ROUTES, PRICE_ZONES_API_ROUTES, PRODUCTS_API_ROUTES, PerformanceCardComponent, PerformanceCardListComponent, PerformanceMultiSelectComponent, PerformanceSelectComponent, PerformanceService, PerformanceStatus, PerformanceStepperComponent, PerformanceTicketStatus, PerformancesListEventsService, PriceZoneEventService, PriceZoneFormModalService, PriceZoneSelectComponent, PriceZoneService, ProductMultiSelectComponent, ProductSelectComponent, ProductService, RoomMapElementOrientation, RoomMapElementType, SHOWS_API_ROUTES, STATE_API_ENDPOINTS, ShowMultiSelectComponent, ShowSelectComponent, ShowService, ShowsFilterComponent, StateSelectComponent, StatesService, TICKERA_COMPONENTS_CONFIG, ToastService, ToggleSwitchComponent, VENUES_API_ROUTES, ZonePriceItemComponent, ZonePriceListComponent, authInterceptor, formatCitiesResponseToSelect, getCustomerFullname, parseJsonToFormDataAdvanced, provideTickeraComponents, transformImageToFile };
4931
+ export { ADMIN_API_ROUTES, ALERT_ICONS, AdminSelectComponent, AdminService, ApiService, AppAlertComponent, AppButtonComponent, AppLinkButtonComponent, AppModalComponent, AsyncSelectComponent, AuditInformationComponent, BASE_BUTTON_CLASSES, BASE_INPUT_CLASSES, BUTTON_SIZES_CLASSES, BUTTON_VARIANT_CLASSES, CITY_API_ENDPOINTS, COUNTRY_API_ENDPOINTS, CUSTOMERS_API_ROUTES, ChangePasswordFormComponent, ChangePasswordFormService, CitiesService, CitySelectComponent, ColorPickerComponent, CorporateBondStatus, CountrySelectComponent, CountryService, CouponApplicability, CouponDiscountType, CustomerSelectComponent, CustomerService, DateInputComponent, DateService, DaySelectorGridComponent, DeleteConfirmationComponent, DeleteConfirmationService, DynamicTableComponent, ERROR_INPUT_CLASSES, EndDateGreaterThanStartValidator, FORM_ERROR_MESSAGES, FileType, FileUploadComponent, FileUploadPreviewComponent, FormEditorComponent, FormInputComponent, FormSelectComponent, FormTextareaComponent, LanguageSwitcherComponent, LoadingModalService, LoadingmModalComponent, MinTodayValidator, MustMatchValidator, OrderItemType, OrderStatus, PERFORMANCES_API_ROUTES, PRICE_ZONES_API_ROUTES, PRODUCTS_API_ROUTES, PerformanceCardComponent, PerformanceCardListComponent, PerformanceMultiSelectComponent, PerformanceSelectComponent, PerformanceService, PerformanceStatus, PerformanceStepperComponent, PerformanceTicketStatus, PerformancesListEventsService, PriceZoneEventService, PriceZoneFormModalService, PriceZoneSelectComponent, PriceZoneService, ProductMultiSelectComponent, ProductSelectComponent, ProductService, RoomMapElementOrientation, RoomMapElementType, SHOWS_API_ROUTES, STATE_API_ENDPOINTS, ShowMultiSelectComponent, ShowSelectComponent, ShowService, ShowsFilterComponent, StateSelectComponent, StatesService, TICKERA_COMPONENTS_CONFIG, TickeraTranslocoLoader, ToastService, ToggleSwitchComponent, VENUES_API_ROUTES, ZonePriceItemComponent, ZonePriceListComponent, authInterceptor, formatCitiesResponseToSelect, getBrowserLanguage, getCustomerFullname, getStoredLanguage, parseJsonToFormDataAdvanced, provideTickeraComponents, resolveLanguage, setStoredLanguage, transformImageToFile };
4875
4932
  //# sourceMappingURL=tickera-angular-components.mjs.map