@acontplus/ng-auth 2.1.0 → 2.1.2

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.
@@ -14,11 +14,13 @@ import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
14
14
  import { MatCard, MatCardHeader, MatCardTitle, MatCardContent, MatCardFooter } from '@angular/material/card';
15
15
  import { MatLabel, MatFormField } from '@angular/material/form-field';
16
16
  import { MatInput } from '@angular/material/input';
17
- import { MatIcon } from '@angular/material/icon';
17
+ import { MatIconRegistry, MatIcon } from '@angular/material/icon';
18
18
  import { MatButton, MatAnchor } from '@angular/material/button';
19
19
  import { MatCheckbox } from '@angular/material/checkbox';
20
20
  import { MatDivider } from '@angular/material/divider';
21
+ import { DomSanitizer } from '@angular/platform-browser';
21
22
  import { LoggingService } from '@acontplus/ng-infrastructure';
23
+ import { DEFAULT_ICONS } from '@acontplus/ui-kit';
22
24
  import * as i1$1 from '@angular/material/progress-spinner';
23
25
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
24
26
 
@@ -97,9 +99,7 @@ class AuthHttpRepository extends AuthRepository {
97
99
  params['domain'] = config.domain;
98
100
  if (config?.redirectUri)
99
101
  params['redirectUri'] = config.redirectUri;
100
- const queryString = Object.keys(params).length > 0
101
- ? '?' + new URLSearchParams(params).toString()
102
- : '';
102
+ const queryString = Object.keys(params).length > 0 ? '?' + new URLSearchParams(params).toString() : '';
103
103
  return this.http.get(`${this.URL}social/${provider}/url${queryString}`);
104
104
  }
105
105
  socialLogin(request) {
@@ -1055,6 +1055,8 @@ class Login {
1055
1055
  fb = inject(FormBuilder);
1056
1056
  authState = inject(AuthState);
1057
1057
  loggingService = inject(LoggingService);
1058
+ iconRegistry = inject(MatIconRegistry);
1059
+ sanitizer = inject(DomSanitizer);
1058
1060
  // Angular 20+ signals
1059
1061
  isLoginMode = signal(true, ...(ngDevMode ? [{ debugName: "isLoginMode" }] : []));
1060
1062
  isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
@@ -1064,6 +1066,8 @@ class Login {
1064
1066
  signinForm;
1065
1067
  signupForm;
1066
1068
  constructor() {
1069
+ // Register social login icons
1070
+ this.registerSocialIcons();
1067
1071
  this.signinForm = this.fb.group({
1068
1072
  email: ['', [Validators.required, Validators.email]],
1069
1073
  password: ['', Validators.required],
@@ -1075,6 +1079,15 @@ class Login {
1075
1079
  password: ['', [Validators.required, Validators.minLength(6)]],
1076
1080
  });
1077
1081
  }
1082
+ registerSocialIcons() {
1083
+ const socialIconNames = ['google', 'microsoft', 'github', 'facebook', 'apple', 'linkedin'];
1084
+ socialIconNames.forEach((name) => {
1085
+ const icon = DEFAULT_ICONS.find((i) => i.name === name);
1086
+ if (icon) {
1087
+ this.iconRegistry.addSvgIconLiteral(name, this.sanitizer.bypassSecurityTrustHtml(icon.data));
1088
+ }
1089
+ });
1090
+ }
1078
1091
  ngOnInit() {
1079
1092
  // Handle rememberMe control based on showRememberMe input
1080
1093
  if (!this.showRememberMe()) {
@@ -1192,7 +1205,7 @@ class Login {
1192
1205
  this.loginWithProvider(provider);
1193
1206
  }
1194
1207
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: Login, deps: [], target: i0.ɵɵFactoryTarget.Component });
1195
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: Login, isStandalone: true, selector: "acp-login", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, showRegisterButton: { classPropertyName: "showRegisterButton", publicName: "showRegisterButton", isSignal: true, isRequired: false, transformFunction: null }, showRememberMe: { classPropertyName: "showRememberMe", publicName: "showRememberMe", isSignal: true, isRequired: false, transformFunction: null }, enableDomainDiscovery: { classPropertyName: "enableDomainDiscovery", publicName: "enableDomainDiscovery", isSignal: true, isRequired: false, transformFunction: null }, showSocialLogin: { classPropertyName: "showSocialLogin", publicName: "showSocialLogin", isSignal: true, isRequired: false, transformFunction: null }, additionalSigninControls: { classPropertyName: "additionalSigninControls", publicName: "additionalSigninControls", isSignal: true, isRequired: false, transformFunction: null }, additionalSignupControls: { classPropertyName: "additionalSignupControls", publicName: "additionalSignupControls", isSignal: true, isRequired: false, transformFunction: null }, additionalSigninFields: { classPropertyName: "additionalSigninFields", publicName: "additionalSigninFields", isSignal: true, isRequired: false, transformFunction: null }, additionalSignupFields: { classPropertyName: "additionalSignupFields", publicName: "additionalSignupFields", isSignal: true, isRequired: false, transformFunction: null }, footerContent: { classPropertyName: "footerContent", publicName: "footerContent", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mat-card class=\"mat-elevation-z8 p-4 rounded\">\n <mat-card-header>\n <mat-card-title class=\"text-center\">{{ title() }}</mat-card-title>\n </mat-card-header>\n <mat-card-content>\n @if (isLoginMode()) {\n <form [formGroup]=\"signinForm\" (ngSubmit)=\"signIn()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Usuario</mat-label>\n <input matInput type=\"text\" placeholder=\"Ingrese su usuario\" formControlName=\"email\" />\n </mat-form-field>\n\n <!-- Show discovery message if OAuth is required -->\n @if (enableDomainDiscovery() && discoveryResult() && discoveryResult()!.requiresOAuth) {\n <div class=\"discovery-message\">\n @if (discoveryResult()!.provider) {\n <p>\n <mat-icon>info</mat-icon>\n Su organizaci\u00F3n utiliza {{ discoveryResult()!.provider }} para la autenticaci\u00F3n\n </p>\n @if (!discoveryResult()!.allowPasswordLogin) {\n <p class=\"warning\">Por favor, use el bot\u00F3n de inicio de sesi\u00F3n corporativo</p>\n }\n }\n </div>\n }\n\n <!-- Password field - only show if allowed -->\n @if (showPasswordLogin()) {\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"current-password\"\n />\n </mat-form-field>\n\n <!-- Remember Me checkbox - conditional -->\n @if (showRememberMe()) {\n <div class=\"d-flex align-items-center mt-2\">\n <mat-checkbox formControlName=\"rememberMe\"> Recordarme </mat-checkbox>\n </div>\n }\n\n <!-- Additional signin fields -->\n <ng-container *ngTemplateOutlet=\"additionalSigninFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signinForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Ingresando...\n } @else {\n <ng-container>Ingresar <mat-icon>login</mat-icon></ng-container>\n }\n </button>\n </div>\n }\n\n <!-- OAuth/SSO Login Buttons -->\n @if (enableDomainDiscovery() && discoveryResult() && discoveryResult()!.requiresOAuth && discoveryResult()!.provider) {\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"accent\"\n type=\"button\"\n (click)=\"loginWithProvider()\"\n class=\"w-100 oauth-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon>business</mat-icon>\n Iniciar sesi\u00F3n con {{ discoveryResult()!.provider }}\n </button>\n </div>\n }\n\n <!-- Social Login Divider -->\n @if (showSocialLogin() && showPasswordLogin()) {\n <mat-divider class=\"my-3\"></mat-divider>\n <p class=\"text-center text-muted\">O continuar con</p>\n }\n\n <!-- Social Login Buttons -->\n @if (showSocialLogin() && !discoveryResult()?.requiresOAuth) {\n <div class=\"social-login-buttons\">\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('google')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"google\"></mat-icon>\n Google\n </button>\n\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('microsoft')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"microsoft\"></mat-icon>\n Microsoft\n </button>\n\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('github')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"github\"></mat-icon>\n GitHub\n </button>\n </div>\n }\n\n <div class=\"text-center mt-2\">\n @if (showRegisterButton()) {\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFNo tienes cuenta? Reg\u00EDstrate\n </button>\n }\n </div>\n </form>\n } @else {\n <form [formGroup]=\"signupForm\" (ngSubmit)=\"registerUser()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Nombre</mat-label>\n <input\n matInput\n type=\"text\"\n placeholder=\"Ingrese su nombre\"\n formControlName=\"displayName\"\n />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Email</mat-label>\n <input matInput type=\"email\" placeholder=\"Ingrese su email\" formControlName=\"email\" />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"new-password\"\n />\n </mat-form-field>\n\n <!-- Additional signup fields -->\n <ng-container *ngTemplateOutlet=\"additionalSignupFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signupForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Registrando...\n } @else {\n <ng-container>Registrarse <mat-icon>person_add</mat-icon></ng-container>\n }\n </button>\n </div>\n\n <div class=\"text-center mt-2\">\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFYa tienes cuenta? Inicia sesi\u00F3n\n </button>\n </div>\n </form>\n }\n @if (errorMessage()) {\n <div class=\"alert alert-danger mt-3\" role=\"alert\">{{ errorMessage() }}</div>\n }\n </mat-card-content>\n @if (hasFooterContent()) {\n <mat-card-footer>\n <ng-container *ngTemplateOutlet=\"footerContent()\"></ng-container>\n </mat-card-footer>\n }\n</mat-card>\n", styles: [":host{display:flex;justify-content:center;align-items:center;min-height:100vh;width:100%;padding:16px;box-sizing:border-box}:host mat-card{width:100%;max-width:400px;border-radius:12px;box-shadow:0 8px 32px #0000001a}:host mat-card-header{text-align:center;margin-bottom:20px}:host mat-card-title{font-size:24px;font-weight:600;color:var(--mat-sys-primary, #6750a4)}:host mat-form-field{width:100%}:host mat-button{border-radius:8px}:host .w-100{width:100%}:host .d-flex{display:flex}:host .flex-column{flex-direction:column}:host .gap-3{gap:12px}:host .justify-content-center{justify-content:center}:host .discovery-message{padding:12px;background-color:#e3f2fd;border-radius:8px;margin-bottom:16px}:host .discovery-message p{margin:4px 0;display:flex;align-items:center;gap:8px;font-size:14px;color:#1565c0}:host .discovery-message p mat-icon{font-size:18px;width:18px;height:18px}:host .discovery-message p.warning{color:#f57c00;font-weight:500}:host .oauth-button{background-color:var(--mat-sys-secondary-container, #e8def8);color:var(--mat-sys-on-secondary-container, #1d192b);font-weight:500}:host .oauth-button mat-icon{margin-right:8px}:host .oauth-button:hover:not([disabled]){background-color:var(--mat-sys-secondary, #625b71);color:var(--mat-sys-on-secondary, #ffffff)}:host .social-login-buttons{display:flex;flex-direction:column;gap:12px;margin-top:16px}:host .social-button{display:flex;align-items:center;justify-content:center;gap:12px;padding:12px 24px;font-weight:500;border:1.5px solid var(--mat-sys-outline, #79747e);transition:all .2s ease}:host .social-button mat-icon{width:20px;height:20px;font-size:20px}:host .social-button:hover:not([disabled]){background-color:var(--mat-sys-surface-variant, #e7e0ec);border-color:var(--mat-sys-primary, #6750a4)}:host .social-button[disabled]{opacity:.5;cursor:not-allowed}:host .text-muted{color:var(--mat-sys-outline, #79747e);font-size:14px;margin:8px 0}:host mat-divider{margin:16px 0}:host .align-items-center{align-items:center}:host .mt-3{margin-top:12px}:host .mt-2{margin-top:8px}:host .text-center{text-align:center}:host .p-4{padding:16px}:host .rounded{border-radius:12px}:host .m-t-10{margin-top:10px}:host .alert-danger{background-color:var(--mat-sys-error-container, #ffdad6);border-color:var(--mat-sys-error, #ba1a1a);color:var(--mat-sys-on-error-container, #410002);padding:12px;border-radius:4px;border:1px solid transparent}:host .row{display:flex;flex-wrap:wrap;margin:0 -15px}:host .col-xs-12,:host .col-sm-12,:host .col-md-12{flex:0 0 100%;max-width:100%;padding:0 15px}:host .social{display:flex;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatCardFooter, selector: "mat-card-footer" }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
1208
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: Login, isStandalone: true, selector: "acp-login", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, showRegisterButton: { classPropertyName: "showRegisterButton", publicName: "showRegisterButton", isSignal: true, isRequired: false, transformFunction: null }, showRememberMe: { classPropertyName: "showRememberMe", publicName: "showRememberMe", isSignal: true, isRequired: false, transformFunction: null }, enableDomainDiscovery: { classPropertyName: "enableDomainDiscovery", publicName: "enableDomainDiscovery", isSignal: true, isRequired: false, transformFunction: null }, showSocialLogin: { classPropertyName: "showSocialLogin", publicName: "showSocialLogin", isSignal: true, isRequired: false, transformFunction: null }, additionalSigninControls: { classPropertyName: "additionalSigninControls", publicName: "additionalSigninControls", isSignal: true, isRequired: false, transformFunction: null }, additionalSignupControls: { classPropertyName: "additionalSignupControls", publicName: "additionalSignupControls", isSignal: true, isRequired: false, transformFunction: null }, additionalSigninFields: { classPropertyName: "additionalSigninFields", publicName: "additionalSigninFields", isSignal: true, isRequired: false, transformFunction: null }, additionalSignupFields: { classPropertyName: "additionalSignupFields", publicName: "additionalSignupFields", isSignal: true, isRequired: false, transformFunction: null }, footerContent: { classPropertyName: "footerContent", publicName: "footerContent", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mat-card class=\"mat-elevation-z8 p-4 rounded\">\n <mat-card-header>\n <mat-card-title class=\"text-center\">{{ title() }}</mat-card-title>\n </mat-card-header>\n <mat-card-content>\n @if (isLoginMode()) {\n <form [formGroup]=\"signinForm\" (ngSubmit)=\"signIn()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Usuario</mat-label>\n <input matInput type=\"text\" placeholder=\"Ingrese su usuario\" formControlName=\"email\" />\n </mat-form-field>\n\n <!-- Show discovery message if OAuth is required -->\n @if (enableDomainDiscovery() && discoveryResult() && discoveryResult()!.requiresOAuth) {\n <div class=\"discovery-message\">\n @if (discoveryResult()!.provider) {\n <p>\n <mat-icon>info</mat-icon>\n Su organizaci\u00F3n utiliza {{ discoveryResult()!.provider }} para la autenticaci\u00F3n\n </p>\n @if (!discoveryResult()!.allowPasswordLogin) {\n <p class=\"warning\">Por favor, use el bot\u00F3n de inicio de sesi\u00F3n corporativo</p>\n }\n }\n </div>\n }\n\n <!-- Password field - only show if allowed -->\n @if (showPasswordLogin()) {\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"current-password\"\n />\n </mat-form-field>\n\n <!-- Remember Me checkbox - conditional -->\n @if (showRememberMe()) {\n <div class=\"d-flex align-items-center mt-2\">\n <mat-checkbox formControlName=\"rememberMe\"> Recordarme </mat-checkbox>\n </div>\n }\n\n <!-- Additional signin fields -->\n <ng-container *ngTemplateOutlet=\"additionalSigninFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signinForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Ingresando...\n } @else {\n <ng-container>Ingresar <mat-icon>login</mat-icon></ng-container>\n }\n </button>\n </div>\n }\n\n <!-- OAuth/SSO Login Buttons -->\n @if (\n enableDomainDiscovery() &&\n discoveryResult() &&\n discoveryResult()!.requiresOAuth &&\n discoveryResult()!.provider\n ) {\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"accent\"\n type=\"button\"\n (click)=\"loginWithProvider()\"\n class=\"w-100 oauth-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon>business</mat-icon>\n Iniciar sesi\u00F3n con {{ discoveryResult()!.provider }}\n </button>\n </div>\n }\n\n <!-- Social Login Divider -->\n @if (showSocialLogin() && showPasswordLogin()) {\n <mat-divider class=\"my-3\"></mat-divider>\n <p class=\"text-center text-muted\">O continuar con</p>\n }\n\n <!-- Social Login Buttons -->\n @if (showSocialLogin() && !discoveryResult()?.requiresOAuth) {\n <div class=\"social-login-buttons\">\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('google')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"google\"></mat-icon>\n Google\n </button>\n\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('microsoft')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"microsoft\"></mat-icon>\n Microsoft\n </button>\n\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('github')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"github\"></mat-icon>\n GitHub\n </button>\n </div>\n }\n\n <div class=\"text-center mt-2\">\n @if (showRegisterButton()) {\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFNo tienes cuenta? Reg\u00EDstrate\n </button>\n }\n </div>\n </form>\n } @else {\n <form [formGroup]=\"signupForm\" (ngSubmit)=\"registerUser()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Nombre</mat-label>\n <input\n matInput\n type=\"text\"\n placeholder=\"Ingrese su nombre\"\n formControlName=\"displayName\"\n />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Email</mat-label>\n <input matInput type=\"email\" placeholder=\"Ingrese su email\" formControlName=\"email\" />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"new-password\"\n />\n </mat-form-field>\n\n <!-- Additional signup fields -->\n <ng-container *ngTemplateOutlet=\"additionalSignupFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signupForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Registrando...\n } @else {\n <ng-container>Registrarse <mat-icon>person_add</mat-icon></ng-container>\n }\n </button>\n </div>\n\n <div class=\"text-center mt-2\">\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFYa tienes cuenta? Inicia sesi\u00F3n\n </button>\n </div>\n </form>\n }\n @if (errorMessage()) {\n <div class=\"alert alert-danger mt-3\" role=\"alert\">{{ errorMessage() }}</div>\n }\n </mat-card-content>\n @if (hasFooterContent()) {\n <mat-card-footer>\n <ng-container *ngTemplateOutlet=\"footerContent()\"></ng-container>\n </mat-card-footer>\n }\n</mat-card>\n", styles: [":host{display:flex;justify-content:center;align-items:center;min-height:100vh;width:100%;padding:16px;box-sizing:border-box}:host mat-card{width:100%;max-width:400px;border-radius:12px;box-shadow:0 8px 32px #0000001a}:host mat-card-header{text-align:center;margin-bottom:20px}:host mat-card-title{font-size:24px;font-weight:600;color:var(--mat-sys-primary, #6750a4)}:host mat-form-field{width:100%}:host mat-button{border-radius:8px}:host .w-100{width:100%}:host .d-flex{display:flex}:host .flex-column{flex-direction:column}:host .gap-3{gap:12px}:host .justify-content-center{justify-content:center}:host .discovery-message{padding:12px;background-color:#e3f2fd;border-radius:8px;margin-bottom:16px}:host .discovery-message p{margin:4px 0;display:flex;align-items:center;gap:8px;font-size:14px;color:#1565c0}:host .discovery-message p mat-icon{font-size:18px;width:18px;height:18px}:host .discovery-message p.warning{color:#f57c00;font-weight:500}:host .oauth-button{background-color:var(--mat-sys-secondary-container, #e8def8);color:var(--mat-sys-on-secondary-container, #1d192b);font-weight:500}:host .oauth-button mat-icon{margin-right:8px}:host .oauth-button:hover:not([disabled]){background-color:var(--mat-sys-secondary, #625b71);color:var(--mat-sys-on-secondary, #ffffff)}:host .social-login-buttons{display:flex;flex-direction:column;gap:12px;margin-top:16px}:host .social-button{display:flex;align-items:center;justify-content:center;gap:12px;padding:12px 24px;font-weight:500;border:1.5px solid var(--mat-sys-outline, #79747e);transition:all .2s ease}:host .social-button mat-icon{width:20px;height:20px;font-size:20px}:host .social-button:hover:not([disabled]){background-color:var(--mat-sys-surface-variant, #e7e0ec);border-color:var(--mat-sys-primary, #6750a4)}:host .social-button[disabled]{opacity:.5;cursor:not-allowed}:host .text-muted{color:var(--mat-sys-outline, #79747e);font-size:14px;margin:8px 0}:host mat-divider{margin:16px 0}:host .align-items-center{align-items:center}:host .mt-3{margin-top:12px}:host .mt-2{margin-top:8px}:host .text-center{text-align:center}:host .p-4{padding:16px}:host .rounded{border-radius:12px}:host .m-t-10{margin-top:10px}:host .alert-danger{background-color:var(--mat-sys-error-container, #ffdad6);border-color:var(--mat-sys-error, #ba1a1a);color:var(--mat-sys-on-error-container, #410002);padding:12px;border-radius:4px;border:1px solid transparent}:host .row{display:flex;flex-wrap:wrap;margin:0 -15px}:host .col-xs-12,:host .col-sm-12,:host .col-md-12{flex:0 0 100%;max-width:100%;padding:0 15px}:host .social{display:flex;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatCardFooter, selector: "mat-card-footer" }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
1196
1209
  }
1197
1210
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: Login, decorators: [{
1198
1211
  type: Component,
@@ -1212,7 +1225,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
1212
1225
  MatAnchor,
1213
1226
  MatCheckbox,
1214
1227
  MatDivider,
1215
- ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<mat-card class=\"mat-elevation-z8 p-4 rounded\">\n <mat-card-header>\n <mat-card-title class=\"text-center\">{{ title() }}</mat-card-title>\n </mat-card-header>\n <mat-card-content>\n @if (isLoginMode()) {\n <form [formGroup]=\"signinForm\" (ngSubmit)=\"signIn()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Usuario</mat-label>\n <input matInput type=\"text\" placeholder=\"Ingrese su usuario\" formControlName=\"email\" />\n </mat-form-field>\n\n <!-- Show discovery message if OAuth is required -->\n @if (enableDomainDiscovery() && discoveryResult() && discoveryResult()!.requiresOAuth) {\n <div class=\"discovery-message\">\n @if (discoveryResult()!.provider) {\n <p>\n <mat-icon>info</mat-icon>\n Su organizaci\u00F3n utiliza {{ discoveryResult()!.provider }} para la autenticaci\u00F3n\n </p>\n @if (!discoveryResult()!.allowPasswordLogin) {\n <p class=\"warning\">Por favor, use el bot\u00F3n de inicio de sesi\u00F3n corporativo</p>\n }\n }\n </div>\n }\n\n <!-- Password field - only show if allowed -->\n @if (showPasswordLogin()) {\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"current-password\"\n />\n </mat-form-field>\n\n <!-- Remember Me checkbox - conditional -->\n @if (showRememberMe()) {\n <div class=\"d-flex align-items-center mt-2\">\n <mat-checkbox formControlName=\"rememberMe\"> Recordarme </mat-checkbox>\n </div>\n }\n\n <!-- Additional signin fields -->\n <ng-container *ngTemplateOutlet=\"additionalSigninFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signinForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Ingresando...\n } @else {\n <ng-container>Ingresar <mat-icon>login</mat-icon></ng-container>\n }\n </button>\n </div>\n }\n\n <!-- OAuth/SSO Login Buttons -->\n @if (enableDomainDiscovery() && discoveryResult() && discoveryResult()!.requiresOAuth && discoveryResult()!.provider) {\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"accent\"\n type=\"button\"\n (click)=\"loginWithProvider()\"\n class=\"w-100 oauth-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon>business</mat-icon>\n Iniciar sesi\u00F3n con {{ discoveryResult()!.provider }}\n </button>\n </div>\n }\n\n <!-- Social Login Divider -->\n @if (showSocialLogin() && showPasswordLogin()) {\n <mat-divider class=\"my-3\"></mat-divider>\n <p class=\"text-center text-muted\">O continuar con</p>\n }\n\n <!-- Social Login Buttons -->\n @if (showSocialLogin() && !discoveryResult()?.requiresOAuth) {\n <div class=\"social-login-buttons\">\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('google')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"google\"></mat-icon>\n Google\n </button>\n\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('microsoft')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"microsoft\"></mat-icon>\n Microsoft\n </button>\n\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('github')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"github\"></mat-icon>\n GitHub\n </button>\n </div>\n }\n\n <div class=\"text-center mt-2\">\n @if (showRegisterButton()) {\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFNo tienes cuenta? Reg\u00EDstrate\n </button>\n }\n </div>\n </form>\n } @else {\n <form [formGroup]=\"signupForm\" (ngSubmit)=\"registerUser()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Nombre</mat-label>\n <input\n matInput\n type=\"text\"\n placeholder=\"Ingrese su nombre\"\n formControlName=\"displayName\"\n />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Email</mat-label>\n <input matInput type=\"email\" placeholder=\"Ingrese su email\" formControlName=\"email\" />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"new-password\"\n />\n </mat-form-field>\n\n <!-- Additional signup fields -->\n <ng-container *ngTemplateOutlet=\"additionalSignupFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signupForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Registrando...\n } @else {\n <ng-container>Registrarse <mat-icon>person_add</mat-icon></ng-container>\n }\n </button>\n </div>\n\n <div class=\"text-center mt-2\">\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFYa tienes cuenta? Inicia sesi\u00F3n\n </button>\n </div>\n </form>\n }\n @if (errorMessage()) {\n <div class=\"alert alert-danger mt-3\" role=\"alert\">{{ errorMessage() }}</div>\n }\n </mat-card-content>\n @if (hasFooterContent()) {\n <mat-card-footer>\n <ng-container *ngTemplateOutlet=\"footerContent()\"></ng-container>\n </mat-card-footer>\n }\n</mat-card>\n", styles: [":host{display:flex;justify-content:center;align-items:center;min-height:100vh;width:100%;padding:16px;box-sizing:border-box}:host mat-card{width:100%;max-width:400px;border-radius:12px;box-shadow:0 8px 32px #0000001a}:host mat-card-header{text-align:center;margin-bottom:20px}:host mat-card-title{font-size:24px;font-weight:600;color:var(--mat-sys-primary, #6750a4)}:host mat-form-field{width:100%}:host mat-button{border-radius:8px}:host .w-100{width:100%}:host .d-flex{display:flex}:host .flex-column{flex-direction:column}:host .gap-3{gap:12px}:host .justify-content-center{justify-content:center}:host .discovery-message{padding:12px;background-color:#e3f2fd;border-radius:8px;margin-bottom:16px}:host .discovery-message p{margin:4px 0;display:flex;align-items:center;gap:8px;font-size:14px;color:#1565c0}:host .discovery-message p mat-icon{font-size:18px;width:18px;height:18px}:host .discovery-message p.warning{color:#f57c00;font-weight:500}:host .oauth-button{background-color:var(--mat-sys-secondary-container, #e8def8);color:var(--mat-sys-on-secondary-container, #1d192b);font-weight:500}:host .oauth-button mat-icon{margin-right:8px}:host .oauth-button:hover:not([disabled]){background-color:var(--mat-sys-secondary, #625b71);color:var(--mat-sys-on-secondary, #ffffff)}:host .social-login-buttons{display:flex;flex-direction:column;gap:12px;margin-top:16px}:host .social-button{display:flex;align-items:center;justify-content:center;gap:12px;padding:12px 24px;font-weight:500;border:1.5px solid var(--mat-sys-outline, #79747e);transition:all .2s ease}:host .social-button mat-icon{width:20px;height:20px;font-size:20px}:host .social-button:hover:not([disabled]){background-color:var(--mat-sys-surface-variant, #e7e0ec);border-color:var(--mat-sys-primary, #6750a4)}:host .social-button[disabled]{opacity:.5;cursor:not-allowed}:host .text-muted{color:var(--mat-sys-outline, #79747e);font-size:14px;margin:8px 0}:host mat-divider{margin:16px 0}:host .align-items-center{align-items:center}:host .mt-3{margin-top:12px}:host .mt-2{margin-top:8px}:host .text-center{text-align:center}:host .p-4{padding:16px}:host .rounded{border-radius:12px}:host .m-t-10{margin-top:10px}:host .alert-danger{background-color:var(--mat-sys-error-container, #ffdad6);border-color:var(--mat-sys-error, #ba1a1a);color:var(--mat-sys-on-error-container, #410002);padding:12px;border-radius:4px;border:1px solid transparent}:host .row{display:flex;flex-wrap:wrap;margin:0 -15px}:host .col-xs-12,:host .col-sm-12,:host .col-md-12{flex:0 0 100%;max-width:100%;padding:0 15px}:host .social{display:flex;justify-content:center}\n"] }]
1228
+ ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<mat-card class=\"mat-elevation-z8 p-4 rounded\">\n <mat-card-header>\n <mat-card-title class=\"text-center\">{{ title() }}</mat-card-title>\n </mat-card-header>\n <mat-card-content>\n @if (isLoginMode()) {\n <form [formGroup]=\"signinForm\" (ngSubmit)=\"signIn()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Usuario</mat-label>\n <input matInput type=\"text\" placeholder=\"Ingrese su usuario\" formControlName=\"email\" />\n </mat-form-field>\n\n <!-- Show discovery message if OAuth is required -->\n @if (enableDomainDiscovery() && discoveryResult() && discoveryResult()!.requiresOAuth) {\n <div class=\"discovery-message\">\n @if (discoveryResult()!.provider) {\n <p>\n <mat-icon>info</mat-icon>\n Su organizaci\u00F3n utiliza {{ discoveryResult()!.provider }} para la autenticaci\u00F3n\n </p>\n @if (!discoveryResult()!.allowPasswordLogin) {\n <p class=\"warning\">Por favor, use el bot\u00F3n de inicio de sesi\u00F3n corporativo</p>\n }\n }\n </div>\n }\n\n <!-- Password field - only show if allowed -->\n @if (showPasswordLogin()) {\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"current-password\"\n />\n </mat-form-field>\n\n <!-- Remember Me checkbox - conditional -->\n @if (showRememberMe()) {\n <div class=\"d-flex align-items-center mt-2\">\n <mat-checkbox formControlName=\"rememberMe\"> Recordarme </mat-checkbox>\n </div>\n }\n\n <!-- Additional signin fields -->\n <ng-container *ngTemplateOutlet=\"additionalSigninFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signinForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Ingresando...\n } @else {\n <ng-container>Ingresar <mat-icon>login</mat-icon></ng-container>\n }\n </button>\n </div>\n }\n\n <!-- OAuth/SSO Login Buttons -->\n @if (\n enableDomainDiscovery() &&\n discoveryResult() &&\n discoveryResult()!.requiresOAuth &&\n discoveryResult()!.provider\n ) {\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"accent\"\n type=\"button\"\n (click)=\"loginWithProvider()\"\n class=\"w-100 oauth-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon>business</mat-icon>\n Iniciar sesi\u00F3n con {{ discoveryResult()!.provider }}\n </button>\n </div>\n }\n\n <!-- Social Login Divider -->\n @if (showSocialLogin() && showPasswordLogin()) {\n <mat-divider class=\"my-3\"></mat-divider>\n <p class=\"text-center text-muted\">O continuar con</p>\n }\n\n <!-- Social Login Buttons -->\n @if (showSocialLogin() && !discoveryResult()?.requiresOAuth) {\n <div class=\"social-login-buttons\">\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('google')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"google\"></mat-icon>\n Google\n </button>\n\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('microsoft')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"microsoft\"></mat-icon>\n Microsoft\n </button>\n\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"socialLogin('github')\"\n class=\"w-100 social-button\"\n [disabled]=\"isLoading()\"\n >\n <mat-icon svgIcon=\"github\"></mat-icon>\n GitHub\n </button>\n </div>\n }\n\n <div class=\"text-center mt-2\">\n @if (showRegisterButton()) {\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFNo tienes cuenta? Reg\u00EDstrate\n </button>\n }\n </div>\n </form>\n } @else {\n <form [formGroup]=\"signupForm\" (ngSubmit)=\"registerUser()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Nombre</mat-label>\n <input\n matInput\n type=\"text\"\n placeholder=\"Ingrese su nombre\"\n formControlName=\"displayName\"\n />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Email</mat-label>\n <input matInput type=\"email\" placeholder=\"Ingrese su email\" formControlName=\"email\" />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"new-password\"\n />\n </mat-form-field>\n\n <!-- Additional signup fields -->\n <ng-container *ngTemplateOutlet=\"additionalSignupFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signupForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Registrando...\n } @else {\n <ng-container>Registrarse <mat-icon>person_add</mat-icon></ng-container>\n }\n </button>\n </div>\n\n <div class=\"text-center mt-2\">\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFYa tienes cuenta? Inicia sesi\u00F3n\n </button>\n </div>\n </form>\n }\n @if (errorMessage()) {\n <div class=\"alert alert-danger mt-3\" role=\"alert\">{{ errorMessage() }}</div>\n }\n </mat-card-content>\n @if (hasFooterContent()) {\n <mat-card-footer>\n <ng-container *ngTemplateOutlet=\"footerContent()\"></ng-container>\n </mat-card-footer>\n }\n</mat-card>\n", styles: [":host{display:flex;justify-content:center;align-items:center;min-height:100vh;width:100%;padding:16px;box-sizing:border-box}:host mat-card{width:100%;max-width:400px;border-radius:12px;box-shadow:0 8px 32px #0000001a}:host mat-card-header{text-align:center;margin-bottom:20px}:host mat-card-title{font-size:24px;font-weight:600;color:var(--mat-sys-primary, #6750a4)}:host mat-form-field{width:100%}:host mat-button{border-radius:8px}:host .w-100{width:100%}:host .d-flex{display:flex}:host .flex-column{flex-direction:column}:host .gap-3{gap:12px}:host .justify-content-center{justify-content:center}:host .discovery-message{padding:12px;background-color:#e3f2fd;border-radius:8px;margin-bottom:16px}:host .discovery-message p{margin:4px 0;display:flex;align-items:center;gap:8px;font-size:14px;color:#1565c0}:host .discovery-message p mat-icon{font-size:18px;width:18px;height:18px}:host .discovery-message p.warning{color:#f57c00;font-weight:500}:host .oauth-button{background-color:var(--mat-sys-secondary-container, #e8def8);color:var(--mat-sys-on-secondary-container, #1d192b);font-weight:500}:host .oauth-button mat-icon{margin-right:8px}:host .oauth-button:hover:not([disabled]){background-color:var(--mat-sys-secondary, #625b71);color:var(--mat-sys-on-secondary, #ffffff)}:host .social-login-buttons{display:flex;flex-direction:column;gap:12px;margin-top:16px}:host .social-button{display:flex;align-items:center;justify-content:center;gap:12px;padding:12px 24px;font-weight:500;border:1.5px solid var(--mat-sys-outline, #79747e);transition:all .2s ease}:host .social-button mat-icon{width:20px;height:20px;font-size:20px}:host .social-button:hover:not([disabled]){background-color:var(--mat-sys-surface-variant, #e7e0ec);border-color:var(--mat-sys-primary, #6750a4)}:host .social-button[disabled]{opacity:.5;cursor:not-allowed}:host .text-muted{color:var(--mat-sys-outline, #79747e);font-size:14px;margin:8px 0}:host mat-divider{margin:16px 0}:host .align-items-center{align-items:center}:host .mt-3{margin-top:12px}:host .mt-2{margin-top:8px}:host .text-center{text-align:center}:host .p-4{padding:16px}:host .rounded{border-radius:12px}:host .m-t-10{margin-top:10px}:host .alert-danger{background-color:var(--mat-sys-error-container, #ffdad6);border-color:var(--mat-sys-error, #ba1a1a);color:var(--mat-sys-on-error-container, #410002);padding:12px;border-radius:4px;border:1px solid transparent}:host .row{display:flex;flex-wrap:wrap;margin:0 -15px}:host .col-xs-12,:host .col-sm-12,:host .col-md-12{flex:0 0 100%;max-width:100%;padding:0 15px}:host .social{display:flex;justify-content:center}\n"] }]
1216
1229
  }], ctorParameters: () => [], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], showRegisterButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRegisterButton", required: false }] }], showRememberMe: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRememberMe", required: false }] }], enableDomainDiscovery: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableDomainDiscovery", required: false }] }], showSocialLogin: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSocialLogin", required: false }] }], additionalSigninControls: [{ type: i0.Input, args: [{ isSignal: true, alias: "additionalSigninControls", required: false }] }], additionalSignupControls: [{ type: i0.Input, args: [{ isSignal: true, alias: "additionalSignupControls", required: false }] }], additionalSigninFields: [{ type: i0.Input, args: [{ isSignal: true, alias: "additionalSigninFields", required: false }] }], additionalSignupFields: [{ type: i0.Input, args: [{ isSignal: true, alias: "additionalSignupFields", required: false }] }], footerContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "footerContent", required: false }] }] } });
1217
1230
 
1218
1231
  // src/lib/presentation/components/index.ts
@@ -1317,11 +1330,11 @@ class OAuthCallbackComponent {
1317
1330
  </div>
1318
1331
  }
1319
1332
  </div>
1320
- `, isInline: true, styles: [".oauth-callback-container{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;padding:2rem;text-align:center}mat-spinner{margin-bottom:1.5rem}p{font-size:1rem;color:#666;margin:0}.error-message{max-width:400px}.error-message h2{color:#d32f2f;margin-bottom:1rem}.error-message p{color:#666;margin-bottom:2rem}.error-message button{padding:.75rem 2rem;background-color:#1976d2;color:#fff;border:none;border-radius:4px;font-size:1rem;cursor:pointer;transition:background-color .2s}.error-message button:hover{background-color:#1565c0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i1$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] });
1333
+ `, isInline: true, styles: [".oauth-callback-container{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;padding:2rem;text-align:center}mat-spinner{margin-bottom:1.5rem}p{font-size:1rem;color:#666;margin:0}.error-message{max-width:400px}.error-message h2{color:#d32f2f;margin-bottom:1rem}.error-message p{color:#666;margin-bottom:2rem}.error-message button{padding:.75rem 2rem;background-color:#1976d2;color:#fff;border:none;border-radius:4px;font-size:1rem;cursor:pointer;transition:background-color .2s}.error-message button:hover{background-color:#1565c0}\n"], dependencies: [{ kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i1$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] });
1321
1334
  }
1322
1335
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: OAuthCallbackComponent, decorators: [{
1323
1336
  type: Component,
1324
- args: [{ selector: 'acp-oauth-callback', standalone: true, imports: [CommonModule, MatProgressSpinnerModule], template: `
1337
+ args: [{ selector: 'acp-oauth-callback', standalone: true, imports: [MatProgressSpinnerModule], template: `
1325
1338
  <div class="oauth-callback-container">
1326
1339
  @if (loading) {
1327
1340
  <mat-spinner diameter="48"></mat-spinner>