@posiwise/user-module 0.0.145 → 0.0.147

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.
@@ -16,9 +16,9 @@ import * as i6$3 from '@posiwise/pipes';
16
16
  import { PipesModule } from '@posiwise/pipes';
17
17
  import * as i5 from '@posiwise/shared-components';
18
18
  import { SharedComponentsModule } from '@posiwise/shared-components';
19
- import * as i6$5 from 'ngx-captcha';
19
+ import * as i6$4 from 'ngx-captcha';
20
20
  import { NgxCaptchaModule } from 'ngx-captcha';
21
- import * as i11 from 'ngx-ui-switch';
21
+ import * as i11$1 from 'ngx-ui-switch';
22
22
  import { UiSwitchModule } from 'ngx-ui-switch';
23
23
  import * as i2$2 from 'primeng/accordion';
24
24
  import { AccordionModule } from 'primeng/accordion';
@@ -31,12 +31,14 @@ import { InputTextModule } from 'primeng/inputtext';
31
31
  import { MultiSelectModule } from 'primeng/multiselect';
32
32
  import * as i4$1 from 'primeng/progressspinner';
33
33
  import { ProgressSpinnerModule } from 'primeng/progressspinner';
34
- import * as i6$6 from 'primeng/rating';
34
+ import * as i6$5 from 'primeng/rating';
35
35
  import { RatingModule } from 'primeng/rating';
36
36
  import * as i6$2 from 'primeng/select';
37
37
  import { SelectModule } from 'primeng/select';
38
38
  import * as i8$1 from 'primeng/selectbutton';
39
39
  import { SelectButtonModule } from 'primeng/selectbutton';
40
+ import * as i11 from 'primeng/tooltip';
41
+ import { TooltipModule } from 'primeng/tooltip';
40
42
  import { Loader } from '@googlemaps/js-api-loader';
41
43
  import * as i1$1 from '@ng-bootstrap/ng-bootstrap';
42
44
  import { NgbModalModule, NgbDatepickerModule } from '@ng-bootstrap/ng-bootstrap';
@@ -55,7 +57,6 @@ import * as i8 from '@jsverse/transloco';
55
57
  import cloneDeep from 'lodash/cloneDeep';
56
58
  import sortBy from 'lodash/sortBy';
57
59
  import { distinct, mergeMap } from 'rxjs/operators';
58
- import * as i6$4 from 'primeng/tooltip';
59
60
  import { GetUser, getUser } from '@posiwise/app-store';
60
61
  import * as i4$2 from '@ngrx/store';
61
62
  import * as i5$1 from '@angular/cdk/clipboard';
@@ -473,7 +474,7 @@ class AccountDetailsComponent extends AppBaseComponent {
473
474
  });
474
475
  }
475
476
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AccountDetailsComponent, deps: [{ token: i2.UntypedFormBuilder }, { token: i1$1.NgbModal }, { token: i1$2.AuthService }, { token: i1$2.GeoService }, { token: i1$2.ProfileService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
476
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: AccountDetailsComponent, isStandalone: false, selector: "pw-account-details", viewQueries: [{ propertyName: "placesRef", first: true, predicate: ["ngxPlaces"], descendants: true }, { propertyName: "passwordRef", first: true, predicate: ["password"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"w-100 text-center\">\n @if (!isLoaded) {\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n }\n</div>\n<div class=\"row d-flex flex-row\">\n <div class=\"col-md-8 order-md-first order-sm-last\">\n <section id=\"email-section\">\n <div class=\"row\">\n <div class=\"col-sm-12 col-md-8 col-lg-8\">\n <h2>{{ 'User.Account.RegisteredEmail' | transloco }}</h2>\n <!-- Email Form -->\n <section id=\"email-form\">\n <form [formGroup]=\"emailForm\"\n (ngSubmit)=\"onEmailFormSubmit()\">\n <!-- Email Address -->\n <div class=\"mt-0\">\n <span id=\"account-primary-email-label\" class=\"me-3 pw-label-style\">{{ 'User.Account.PrimaryEmail' | transloco }}:\n </span>\n <strong>{{ validatedEmail }}</strong>\n <div class=\"mt-1\">\n @if (!toggleEmail) {\n <a class=\"btn btn-raised btn-outline-primary\"\n aria-label=\"Navigate to Target\"\n (click)=\"shouldUserChangeEmail()\">\n {{ 'User.Account.ChangeEmail' | transloco }}</a>\n }\n @if (toggleEmail) {\n <div class=\"row\">\n <div class=\"clearfix\"></div>\n <div class=\"col-12 mb-3\">\n @if (!passwordVerified) {\n <input type=\"password\"\n class=\"form-control\"\n id=\"account-email-current-password\"\n name=\"currentPassword\"\n #password\n placeholder=\"Current Password\"\n autocomplete=\"current-password\"\n (keyup)=\"checkValidity()\" />\n }\n @if (passwordVerified) {\n <input type=\"text\"\n class=\"form-control\"\n id=\"account-new-email\"\n name=\"newEmail\"\n placeholder=\"New Email\"\n autocomplete=\"email\"\n formControlName=\"email\" />\n }\n </div>\n <div class=\"col-12\">\n @if (toggleEmail) {\n <a\n class=\"btn btn-raised btn-outline-default my-2 me-2\"\n aria-label=\"Navigate to Target\"\n (click)=\"onToggleEmail()\">{{ 'Button.Cancel' | transloco }}</a>\n }\n @if (!passwordVerified) {\n <button class=\"btn btn-raised btn-primary\"\n type=\"submit\"\n [buttonBusy]=\"validatePasswordBusyButton\"\n (click)=\"validatePassword()\"\n [disabled]=\"isCurrentPasswordValid\">\n {{ 'User.Account.Validate' | transloco }}\n </button>\n }\n @if (passwordVerified) {\n <button type=\"submit\"\n class=\"btn btn-raised btn-primary\"\n [buttonBusy]=\"emailBusyButton\"\n >\n {{\n 'User.Account.SendVerification' | transloco\n }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n </div>\n <section id=\"slug\"\n class=\"mb-2 mt-3\">\n <div>\n <span class=\"me-3 pw-label-style\" id=\"account-nickname-label\">{{ 'User.Account.NickName' | transloco }}:\n </span>\n <strong>{{ slug }}</strong>\n <div>\n @if (!toggleNickName) {\n <a class=\"btn btn-raised btn-outline-primary me-2\"\n aria-label=\"Navigate to Target\"\n (click)=\"toggleNickName = true\">\n {{ 'User.Account.ChangeNickname' | transloco }}</a>\n }\n @if (toggleNickName) {\n <div class=\"mb-3\">\n <input type=\"text\"\n id=\"account-nickname\"\n name=\"nickname\"\n class=\"form-control slug-input\"\n aria-labelledby=\"account-nickname-label\"\n [(ngModel)]=\"slug\"\n [ngModelOptions]=\"{ standalone: true }\" />\n </div>\n <div>\n <button type=\"button\"\n class=\"btn btn-raised btn-outline-default\"\n (click)=\"toggleNickName = false\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"button\"\n class=\"btn btn-raised btn-primary ms-2\"\n [buttonBusy]=\"slugBusyButton\"\n [disabled]=\"slug?.length < 2\"\n (click)=\"onUpdateSlug()\">\n {{ 'User.Account.UpdateNickname' | transloco }}\n </button>\n </div>\n }\n </div>\n </div>\n </section>\n </form>\n </section>\n </div>\n </div>\n <section id=\"password-change\"\n class=\"mt-1\">\n <form [formGroup]=\"passwordForm\"\n (ngSubmit)=\"onPasswordFormSubmit()\">\n <div class=\"row\">\n <div class=\"col-sm-12 col-md-8 col-lg-8 mt-4\">\n <h2>{{ 'User.Account.ChangePassword' | transloco }}</h2>\n </div>\n @if (!user?.has_password) {\n <div class=\"text-danger mx-3 my-2\">\n <div>\n You don't have a password set, click on\n <em>{{ 'User.Account.ChangePassword' | transloco }}</em>.\n </div>\n <div>{{ 'User.Profile.PictureMessage' | transloco }}</div>\n </div>\n }\n @if (user?.has_password) {\n <div class=\"col-sm-12 col-md-8 col-lg-8\"\n >\n @if (togglePassword) {\n <div class=\"mb-3\">\n <label for=\"account-current-password\">{{ 'User.Account.CurrentPassword' | transloco }}</label>\n <input type=\"password\"\n id=\"account-current-password\"\n class=\"form-control\"\n formControlName=\"currentPassword\"\n autocomplete=\"current-password\" name=\"input_currentPassword_4\"/>\n @if (\n !passwordForm.get('currentPassword').valid &&\n (passwordForm.get('currentPassword').dirty ||\n passwordForm.get('currentPassword').touched)\n ) {\n <small class=\"form-text text-muted danger\"\n >\n {{ 'User.Account.Required' | transloco }}\n </small>\n }\n </div>\n <div class=\"mb-3\">\n <label for=\"account-new-password\">{{ 'User.Account.NewPassword' | transloco }}</label>\n <input type=\"password\"\n id=\"account-new-password\"\n class=\"form-control\"\n formControlName=\"newPassword\"\n autocomplete=\"new-password\" name=\"input_newPassword_5\"/>\n @if (\n !passwordForm.get('newPassword').valid &&\n (passwordForm.get('newPassword').dirty ||\n passwordForm.get('newPassword').touched)\n ) {\n <small class=\"form-text text-muted danger\"\n >{{ 'User.Account.Validation.StrongPassword' | transloco }}\n </small>\n }\n </div>\n <div class=\"mb-3\">\n <label for=\"account-confirm-password\">{{\n 'User.Account.ConfirmPassword' | transloco\n }}</label>\n <input type=\"password\"\n id=\"account-confirm-password\"\n class=\"form-control\"\n formControlName=\"confirmPassword\"\n autocomplete=\"new-password\" name=\"input_confirmPassword_6\"/>\n @if (\n passwordForm.get('confirmPassword').touched &&\n passwordForm.get('confirmPassword').errors\n ?.MatchPassword\n ) {\n <div class=\"text-danger\"\n >\n {{ 'User.Account.Validation.PasswordsMatch' | transloco }}\n </div>\n }\n </div>\n <div class=\"mb-3\">\n @if (togglePassword) {\n <a class=\"btn btn-raised btn-outline-default\"\n aria-label=\"Navigate to Target\"\n data-bs-target=\"\"\n (click)=\"onTogglePassword()\">\n {{ 'Button.Cancel' | transloco }}</a>\n }\n <button class=\"btn btn-raised btn-primary ms-2\"\n [buttonBusy]=\"passwordBusyButton\"\n [disabled]=\"!passwordForm.valid\">\n {{ 'User.Account.UpdatePassword' | transloco }}\n </button>\n </div>\n }\n <div>\n @if (!togglePassword) {\n <a class=\"btn btn-raised btn-outline-primary\"\n aria-label=\"Navigate to Target\"\n data-bs-target=\"\"\n (click)=\"togglePassword = !togglePassword\">\n {{ 'User.Account.ChangePassword' | transloco }}</a>\n }\n </div>\n </div>\n }\n @if (!user?.has_password) {\n <div class=\"col-sm-12 col-md-8 col-lg-8\"\n >\n <a class=\"btn btn-raised btn-primary me-2\"\n aria-label=\"Navigate to Target\"\n data-bs-target=\"\"\n (click)=\"sendMailToResetPassword()\">\n {{ 'User.Account.ChangePassword' | transloco }}</a>\n </div>\n }\n </div>\n </form>\n </section>\n @if (user?.api_keys?.api_hits_max > 0) {\n <section id=\"api-credentials\"\n class=\"mt-4\">\n <div class=\"row\">\n <div class=\"col-12\">\n <h3>{{ 'User.Subscriptions.APICredentials.Title' | transloco }}</h3>\n <p>\n {{ 'User.Subscriptions.APICredentials.Description' | transloco }}\n </p>\n </div>\n <div class=\"col-12 col-md-6\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"account-api-token\">{{ 'User.Account.APIUserToken' | transloco }}</label>\n <div class=\"input-group\">\n <input type=\"text\"\n id=\"account-api-token\"\n name=\"api_token\"\n class=\"form-control\"\n [value]=\"showApiToken ? user?.api_keys?.api_user_token || ('User.Subscriptions.APICredentials.NoTokenAvailable' | transloco) : '*************************'\"\n readonly />\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"toggleApiTokenVisibility()\">\n {{ showApiToken ? ('User.Subscriptions.APICredentials.Hide' | transloco) : ('User.Subscriptions.APICredentials.View' | transloco) }}\n </button>\n </div>\n </div>\n </div>\n <div class=\"col-12 col-md-6\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"account-api-client-id\">{{ 'User.Account.APIUserId' | transloco }}</label>\n <div class=\"input-group\">\n <input type=\"text\"\n id=\"account-api-client-id\"\n name=\"api_client_id\"\n class=\"form-control\"\n [value]=\"showApiClientId ? user?.api_keys?.api_user_id || ('User.Subscriptions.APICredentials.NoClientIdAvailable' | transloco) : '*************************'\"\n readonly />\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"toggleApiClientIdVisibility()\">\n {{ showApiClientId ? ('User.Subscriptions.APICredentials.Hide' | transloco) : ('User.Subscriptions.APICredentials.View' | transloco) }}\n </button>\n </div>\n </div>\n </div>\n <div class=\"col-12 mt-3\">\n <div class=\"d-flex align-items-center gap-3\">\n <button type=\"button\"\n class=\"btn btn-warning\"\n (click)=\"refreshApiTokens()\"\n [disabled]=\"refreshingTokens\">\n <i class=\"fas fa-sync-alt me-2\" [class.fa-spin]=\"refreshingTokens\"></i>\n {{ refreshingTokens ? ('User.Subscriptions.APICredentials.Refreshing' | transloco) : ('User.Subscriptions.APICredentials.RefreshTokens' | transloco) }}\n </button>\n <div class=\"d-flex align-items-center gap-2\">\n @if (user?.api_keys?.api_hits !== null) {\n <span class=\"text-muted\">{{ 'User.Subscriptions.APICredentials.ApiHits' | transloco }}:</span>\n <span class=\"fw-bold\">{{ user.api_keys.api_hits | number }}</span>\n }\n @if (user?.api_keys?.api_hits_max !== null) {\n <span class=\"text-muted\">{{ 'User.Subscriptions.APICredentials.ApiHitsMax' | transloco }}:</span>\n <span class=\"fw-bold\">{{ user.api_keys.api_hits_max | number }}</span>\n }\n <!-- Show utilization percentage when both values exist -->\n @if (user?.api_keys?.api_hits !== null && user?.api_keys?.api_hits_max !== null && user?.api_keys?.api_hits_max > 0) {\n <span class=\"text-muted ms-2\">(</span>\n <span class=\"fw-bold\" [ngClass]=\"{\n 'text-success': (user.api_keys.api_hits / user.api_keys.api_hits_max) <= 0.8,\n 'text-warning': (user.api_keys.api_hits / user.api_keys.api_hits_max) > 0.8 && (user.api_keys.api_hits / user.api_keys.api_hits_max) <= 0.9,\n 'text-danger': (user.api_keys.api_hits / user.api_keys.api_hits_max) > 0.9\n }\">\n {{ (user.api_keys.api_hits / user.api_keys.api_hits_max * 100) | number:'1.0-0' }}% consumed\n </span>\n <span class=\"text-muted\">)</span>\n }\n </div>\n </div>\n </div>\n </div>\n </section>\n }\n </section>\n </div>\n <!-- Avatar -->\n <div class=\"mt-4 mt-sm-0 col-md-4 text-center order-md-last order-sm-first\">\n <h2>{{ 'User.Profile.Avatar' | transloco }}</h2>\n <div class=\"text-center mt-1\">\n <div class=\"image-container\">\n <img [src]=\"image\"\n width=\"150\"\n height=\"150\"\n class=\"image rounded-circle\"\n alt=\"User Male\"\n (error)=\"handleImageError($event, 'assets/img/icons/male.png')\" />\n <div class=\"overlay\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\">\n <div class=\"overlay-text\">{{ 'User.Profile.Change' | transloco }}</div>\n </div>\n </div>\n <h4 class=\"mt-2\">{{ user?.first_name }} {{ user?.last_name }}</h4>\n <a aria-label=\"Navigate to Target\"\n class=\"d-inline-block mb-2\"\n (click)=\"openModal(content)\">\n {{ 'User.Profile.EditAvatar' | transloco }}</a>\n <br />\n </div>\n </div>\n</div>\n<br />\n<section id=\"user-profile\"\n class=\"mt-2\">\n <div class=\"row\">\n <div class=\"col-12\">\n <form [formGroup]=\"profileForm\"\n (ngSubmit)=\"onProfileFormSubmit()\">\n <h2>{{ 'User.Profile.UserProfile' | transloco }}</h2>\n <div class=\"row mt-3\">\n <div class=\"col-sm-12 col-md-6 col-lg-6\">\n <pw-input-container label=\"First Name\"\n name=\"first_name\"\n controlId=\"account-first_name\"\n errorMsg=\"Please enter first Name\">\n <input type=\"text\"\n id=\"account-first_name\"\n class=\"form-control\"\n formControlName=\"first_name\"\n autocomplete=\"given-name\" name=\"input_first_name_9\"/>\n </pw-input-container>\n <pw-input-container label=\"Preferred name\"\n name=\"preferred_name\"\n controlId=\"account-preferred_name\"\n errorMsg=\"Please enter preferred Name\">\n <input type=\"text\"\n id=\"account-preferred_name\"\n class=\"form-control\"\n formControlName=\"preferred_name\"\n autocomplete=\"username\" name=\"input_preferred_name_10\"/>\n </pw-input-container>\n @if (countries$ | async; as countries) {\n <pw-input-container label=\"Country\"\n name=\"country\"\n controlId=\"account-country\"\n [useAriaLabelledbyOnly]=\"true\"\n errorMsg=\"Please select a country\">\n <p-select\n [attr.aria-labelledby]=\"'account-country-label'\"\n [options]=\"countries\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"country\"\n (onChange)=\"getRegion($event.value)\"\n placeholder=\"{{ 'User.Profile.SelectCountry' | transloco }}\">\n </p-select>\n </pw-input-container>\n }\n <pw-input-container label=\"Province\"\n name=\"province\"\n controlId=\"account-province\"\n errorMsg=\"Please enter province\">\n <input type=\"text\"\n id=\"account-province\"\n class=\"form-control\"\n formControlName=\"province\"\n autocomplete=\"postal-code\" name=\"input_province_11\"/>\n </pw-input-container>\n <pw-input-container label=\"Website Url\"\n name=\"website_url\"\n controlId=\"account-website_url\"\n errorMsg=\"Please enter Website\">\n <input type=\"text\"\n id=\"account-website_url\"\n class=\"form-control\"\n formControlName=\"website_url\"\n autocomplete=\"url\" name=\"input_website_url_12\"/>\n </pw-input-container>\n </div>\n <div class=\"col-sm-12 col-md-6 col-lg-6\">\n <pw-input-container label=\"Last Name\"\n name=\"last_name\"\n controlId=\"account-last_name\"\n errorMsg=\"Please enter last Name\">\n <input type=\"text\"\n id=\"account-last_name\"\n class=\"form-control\"\n formControlName=\"last_name\"\n autocomplete=\"family-name\" name=\"input_last_name_13\"/>\n </pw-input-container>\n <pw-input-container label=\"Date of Birth\"\n name=\"dob\"\n controlId=\"account-dob\"\n errorMsg=\"Please enter date of birth\">\n <div class=\"input-group\">\n <input class=\"form-control\"\n id=\"account-dob\"\n name=\"dob\"\n placeholder=\"dd-mmm-yyyy\"\n formControlName=\"dob\"\n ngbDatepicker\n #d=\"ngbDatepicker\"\n [minDate]=\"{ day: 1, month: 1, year: 1950 }\"\n [maxDate]=\"{ day: 31, month: 12, year: 2018 }\" />\n <div class=\"input-group-append\">\n <button class=\"btn btn-primary\"\n type=\"button\"\n id=\"account-dob-trigger\"\n aria-label=\"Open date picker for date of birth\"\n (click)=\"d.toggle()\">\n <i class=\"fa fa-calendar\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </pw-input-container>\n <pw-input-container label=\"State\"\n name=\"state\"\n controlId=\"account-state\"\n [useAriaLabelledbyOnly]=\"true\"\n errorMsg=\"Please select a state\">\n <p-select\n [attr.aria-labelledby]=\"'account-state-label'\"\n [options]=\"states\"\n [(ngModel)]=\"selectedState\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"state\"\n [placeholder]=\"'User.Profile.SelectState' | transloco\">\n </p-select>\n\n </pw-input-container>\n <!-- Location -->\n <pw-input-container label=\"Location\"\n name=\"location\"\n controlId=\"account-location\"\n [useAriaLabelledbyOnly]=\"true\">\n <input ngx-gp-autocomplete\n id=\"account-location\"\n name=\"location\"\n class=\"form-control\"\n [attr.aria-labelledby]=\"'account-location-label'\"\n #places=\"ngx-places\"\n formControlName=\"location\"\n (onAddressChange)=\"handleAddressChange($event)\" />\n </pw-input-container>\n <pw-input-container label=\"Phone Number\"\n name=\"phone_number\"\n controlId=\"account-phone_number\"\n errorMsg=\"Please enter phone number\">\n <input type=\"text\"\n id=\"account-phone_number\"\n class=\"form-control\"\n formControlName=\"phone_number\"\n autocomplete=\"tel\" name=\"input_phone_number_16\"/>\n </pw-input-container>\n </div>\n <div class=\"col-12 text-end\">\n <div class=\"mb-3\">\n <button class=\"btn btn-raised btn-primary\" [buttonBusy]=\"profileBusyButton\">\n {{ 'Button.Save' | transloco }}\n </button>\n </div>\n </div>\n </div>\n </form>\n </div>\n </div>\n</section>\n<ng-template #content\n let-modal>\n <div class=\"card m-0\">\n <div class=\"card-content\">\n <div class=\"card-title\">\n <h3 class=\"modal-title\">{{ 'User.Profile.ProfilePicture' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"card-header\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n aspectRatio=\"auto\"\n (imageSelectionEvent)=\"onImageSelection($event)\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [".overlay{left:50%;opacity:0;position:absolute;text-align:center;top:50%;transform:translate(-50%,-50%);transition:.5s ease}.image-container{position:relative}.image-container:hover .image{opacity:.3}.image-container:hover .overlay{opacity:0}.overlay-text{background:#f0efef80;border-radius:50%;color:#000;font-size:16px;height:150px;line-height:150px;text-align:center;vertical-align:middle;width:150px}@media screen and (max-width:767px){.card-body{padding:20px!important}}\n"], dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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: "directive", type: i6$1.NgxGpAutocompleteDirective, selector: "[ngx-gp-autocomplete]", inputs: ["options"], outputs: ["onAddressChange"], exportAs: ["ngx-places"] }, { kind: "component", type: i6$2.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i9.ProfileImageCropperComponent, selector: "pw-image-cropper", inputs: ["aspectRatio", "dynamicData"], outputs: ["imageSelectionEvent", "closeEvent", "fileChangeEvent"] }, { kind: "component", type: i5.InputContainerComponent, selector: "pw-input-container", inputs: ["name", "controlId", "useAriaLabelledbyOnly", "label", "labelClass", "tooltipPosition", "required", "errorMsg", "isReadOnly", "showTooltip", "tooltipText", "showTriangle", "afterLabel", "showAfterLabel", "showTriangleText", "isLeftTooltip"] }, { kind: "directive", type: i1$1.NgbInputDatepicker, selector: "input[ngbDatepicker]", inputs: ["autoClose", "contentTemplate", "datepickerClass", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "minDate", "maxDate", "navigation", "outsideDays", "placement", "popperOptions", "restoreFocus", "showWeekNumbers", "startDate", "container", "positionTarget", "weekdays", "disabled"], outputs: ["dateSelect", "navigate", "closed"], exportAs: ["ngbDatepicker"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.DecimalPipe, name: "number" }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
477
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: AccountDetailsComponent, isStandalone: false, selector: "pw-account-details", viewQueries: [{ propertyName: "placesRef", first: true, predicate: ["ngxPlaces"], descendants: true }, { propertyName: "passwordRef", first: true, predicate: ["password"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"w-100 text-center\">\n @if (!isLoaded) {\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n }\n</div>\n<div class=\"row gx-3 mb-3\">\n <div class=\"col-md-4\">\n <section class=\"card p-4 h-100 d-flex flex-column\">\n <h2>{{ 'User.Profile.Avatar' | transloco }}</h2>\n <div class=\"text-center d-flex flex-column justify-content-center flex-grow-1 mt-1\">\n <div class=\"image-container\">\n <img [src]=\"image\"\n width=\"150\"\n height=\"150\"\n class=\"image rounded-circle\"\n alt=\"User Male\"\n (error)=\"handleImageError($event, 'assets/img/icons/male.png')\" />\n <div class=\"overlay\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\">\n <div class=\"overlay-text\">{{ 'User.Profile.Change' | transloco }}</div>\n </div>\n </div>\n <h4 class=\"mt-2\">{{ user?.first_name }} {{ user?.last_name }}</h4>\n <a aria-label=\"Navigate to Target\"\n class=\"d-inline-block mb-2\"\n (click)=\"openModal(content)\">\n {{ 'User.Profile.EditAvatar' | transloco }}</a>\n </div>\n </section>\n </div>\n <div class=\"col-md-8\">\n <section id=\"user-profile\"\n class=\"card p-4 overflow-visible h-100\">\n <form [formGroup]=\"profileForm\"\n (ngSubmit)=\"onProfileFormSubmit()\">\n <h2>{{ 'User.Profile.UserProfile' | transloco }}</h2>\n <div class=\"row mt-3\">\n <div class=\"col-sm-12 col-md-6 col-lg-6\">\n <pw-input-container label=\"First Name\"\n name=\"first_name\"\n controlId=\"account-first_name\"\n errorMsg=\"Please enter first Name\">\n <input type=\"text\"\n id=\"account-first_name\"\n class=\"form-control\"\n formControlName=\"first_name\"\n autocomplete=\"given-name\" name=\"input_first_name_9\"/>\n </pw-input-container>\n <pw-input-container label=\"Preferred name\"\n name=\"preferred_name\"\n controlId=\"account-preferred_name\"\n errorMsg=\"Please enter preferred Name\">\n <input type=\"text\"\n id=\"account-preferred_name\"\n class=\"form-control\"\n formControlName=\"preferred_name\"\n autocomplete=\"username\" name=\"input_preferred_name_10\"/>\n </pw-input-container>\n @if (countries$ | async; as countries) {\n <pw-input-container label=\"Country\"\n name=\"country\"\n controlId=\"account-country\"\n [useAriaLabelledbyOnly]=\"true\"\n errorMsg=\"Please select a country\">\n <p-select\n [attr.aria-labelledby]=\"'account-country-label'\"\n [options]=\"countries\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"country\"\n (onChange)=\"getRegion($event.value)\"\n placeholder=\"{{ 'User.Profile.SelectCountry' | transloco }}\">\n </p-select>\n </pw-input-container>\n }\n <pw-input-container label=\"Province\"\n name=\"province\"\n controlId=\"account-province\"\n errorMsg=\"Please enter province\">\n <input type=\"text\"\n id=\"account-province\"\n class=\"form-control\"\n formControlName=\"province\"\n autocomplete=\"postal-code\" name=\"input_province_11\"/>\n </pw-input-container>\n <pw-input-container label=\"Website Url\"\n name=\"website_url\"\n controlId=\"account-website_url\"\n errorMsg=\"Please enter Website\">\n <input type=\"text\"\n id=\"account-website_url\"\n class=\"form-control\"\n formControlName=\"website_url\"\n autocomplete=\"url\" name=\"input_website_url_12\"/>\n </pw-input-container>\n </div>\n <div class=\"col-sm-12 col-md-6 col-lg-6\">\n <pw-input-container label=\"Last Name\"\n name=\"last_name\"\n controlId=\"account-last_name\"\n errorMsg=\"Please enter last Name\">\n <input type=\"text\"\n id=\"account-last_name\"\n class=\"form-control\"\n formControlName=\"last_name\"\n autocomplete=\"family-name\" name=\"input_last_name_13\"/>\n </pw-input-container>\n <pw-input-container label=\"Date of Birth\"\n name=\"dob\"\n controlId=\"account-dob\"\n errorMsg=\"Please enter date of birth\">\n <div class=\"input-group\">\n <input class=\"form-control\"\n id=\"account-dob\"\n name=\"dob\"\n placeholder=\"dd-mmm-yyyy\"\n formControlName=\"dob\"\n ngbDatepicker\n #d=\"ngbDatepicker\"\n [minDate]=\"{ day: 1, month: 1, year: 1950 }\"\n [maxDate]=\"{ day: 31, month: 12, year: 2018 }\" />\n <button class=\"btn btn-primary\"\n type=\"button\"\n id=\"account-dob-trigger\"\n aria-label=\"Open date picker for date of birth\"\n (click)=\"d.toggle()\">\n <i class=\"fa fa-calendar\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </pw-input-container>\n <pw-input-container label=\"State\"\n name=\"state\"\n controlId=\"account-state\"\n [useAriaLabelledbyOnly]=\"true\"\n errorMsg=\"Please select a state\">\n <p-select\n [attr.aria-labelledby]=\"'account-state-label'\"\n [options]=\"states\"\n [(ngModel)]=\"selectedState\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"state\"\n [placeholder]=\"'User.Profile.SelectState' | transloco\">\n </p-select>\n </pw-input-container>\n <pw-input-container label=\"Location\"\n name=\"location\"\n controlId=\"account-location\"\n [useAriaLabelledbyOnly]=\"true\">\n <input ngx-gp-autocomplete\n id=\"account-location\"\n name=\"location\"\n class=\"form-control\"\n [attr.aria-labelledby]=\"'account-location-label'\"\n #places=\"ngx-places\"\n formControlName=\"location\"\n (onAddressChange)=\"handleAddressChange($event)\" />\n </pw-input-container>\n <pw-input-container label=\"Phone Number\"\n name=\"phone_number\"\n controlId=\"account-phone_number\"\n errorMsg=\"Please enter phone number\">\n <input type=\"text\"\n id=\"account-phone_number\"\n class=\"form-control\"\n formControlName=\"phone_number\"\n autocomplete=\"tel\" name=\"input_phone_number_16\"/>\n </pw-input-container>\n </div>\n <div class=\"col-12 text-end\">\n <div class=\"mb-3\">\n <button class=\"btn btn-raised btn-primary\" [buttonBusy]=\"profileBusyButton\">\n {{ 'Button.Save' | transloco }}\n </button>\n </div>\n </div>\n </div>\n </form>\n </section>\n </div>\n</div>\n<div class=\"row gx-3 mb-3\">\n <div class=\"col-md-6\">\n <section id=\"email-section\"\n class=\"card p-4 h-100\">\n <div class=\"row\">\n <div class=\"col-12\">\n <h2>{{ 'User.Account.RegisteredEmail' | transloco }}</h2>\n <section id=\"email-form\">\n <form [formGroup]=\"emailForm\"\n (ngSubmit)=\"onEmailFormSubmit()\">\n <!-- Email Address -->\n <div class=\"mt-0\">\n <span id=\"account-primary-email-label\" class=\"me-3 pw-label-style\">{{ 'User.Account.PrimaryEmail' | transloco }}:\n </span>\n <strong>{{ validatedEmail }}</strong>\n <div class=\"mt-1\">\n @if (!toggleEmail) {\n <a class=\"btn btn-raised btn-outline-primary\"\n aria-label=\"Navigate to Target\"\n (click)=\"shouldUserChangeEmail()\">\n {{ 'User.Account.ChangeEmail' | transloco }}</a>\n }\n @if (toggleEmail) {\n <div class=\"row\">\n <div class=\"clearfix\"></div>\n <div class=\"col-12 mb-3\">\n @if (!passwordVerified) {\n <input type=\"password\"\n class=\"form-control\"\n id=\"account-email-current-password\"\n name=\"currentPassword\"\n #password\n placeholder=\"Current Password\"\n autocomplete=\"current-password\"\n (keyup)=\"checkValidity()\" />\n }\n @if (passwordVerified) {\n <input type=\"text\"\n class=\"form-control\"\n id=\"account-new-email\"\n name=\"newEmail\"\n placeholder=\"New Email\"\n autocomplete=\"email\"\n formControlName=\"email\" />\n }\n </div>\n <div class=\"col-12\">\n @if (toggleEmail) {\n <a\n class=\"btn btn-raised btn-outline-default my-2 me-2\"\n aria-label=\"Navigate to Target\"\n (click)=\"onToggleEmail()\">{{ 'Button.Cancel' | transloco }}</a>\n }\n @if (!passwordVerified) {\n <button class=\"btn btn-raised btn-primary\"\n type=\"submit\"\n [buttonBusy]=\"validatePasswordBusyButton\"\n (click)=\"validatePassword()\"\n [disabled]=\"isCurrentPasswordValid\">\n {{ 'User.Account.Validate' | transloco }}\n </button>\n }\n @if (passwordVerified) {\n <button type=\"submit\"\n class=\"btn btn-raised btn-primary\"\n [buttonBusy]=\"emailBusyButton\"\n >\n {{\n 'User.Account.SendVerification' | transloco\n }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n </div>\n <section id=\"slug\"\n class=\"mb-2 mt-3\">\n <div>\n <span class=\"me-3 pw-label-style\" id=\"account-nickname-label\">{{ 'User.Account.NickName' | transloco }}:</span>\n <span class=\"tooltip-wrap me-3\" [pTooltip]=\"'User.Account.HandleTooltip' | transloco\" [appendTo]=\"'body'\" tooltipPosition=\"top\"><i class=\"far fa-info-circle text-muted\"></i></span>\n <strong>{{ slug }}</strong>\n <div class=\"mt-1\">\n @if (!toggleNickName) {\n <a class=\"btn btn-raised btn-outline-primary me-2\"\n aria-label=\"Navigate to Target\"\n (click)=\"toggleNickName = true\">\n {{ 'User.Account.ChangeNickname' | transloco }}</a>\n }\n @if (toggleNickName) {\n <div class=\"mb-3\">\n <input type=\"text\"\n id=\"account-nickname\"\n name=\"nickname\"\n class=\"form-control slug-input\"\n aria-labelledby=\"account-nickname-label\"\n [(ngModel)]=\"slug\"\n [ngModelOptions]=\"{ standalone: true }\" />\n </div>\n <div>\n <button type=\"button\"\n class=\"btn btn-raised btn-outline-default\"\n (click)=\"toggleNickName = false\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"button\"\n class=\"btn btn-raised btn-primary ms-2\"\n [buttonBusy]=\"slugBusyButton\"\n [disabled]=\"slug?.length < 2\"\n (click)=\"onUpdateSlug()\">\n {{ 'User.Account.UpdateNickname' | transloco }}\n </button>\n </div>\n }\n </div>\n </div>\n </section>\n </form>\n </section>\n </div>\n </div>\n </section>\n </div>\n <div class=\"col-md-6\">\n <section id=\"password-change\"\n class=\"card p-4 h-100\">\n <form [formGroup]=\"passwordForm\"\n (ngSubmit)=\"onPasswordFormSubmit()\">\n <div class=\"row\">\n <div class=\"col-12\">\n <h2>{{ 'User.Account.ChangePassword' | transloco }}</h2>\n </div>\n @if (!user?.has_password) {\n <div class=\"text-danger mx-3 my-2\">\n <div>\n You don't have a password set, click on\n <em>{{ 'User.Account.ChangePassword' | transloco }}</em>.\n </div>\n <div>{{ 'User.Profile.PictureMessage' | transloco }}</div>\n </div>\n }\n @if (user?.has_password) {\n <div class=\"col-12\"\n >\n @if (togglePassword) {\n <div class=\"mb-3\">\n <label for=\"account-current-password\">{{ 'User.Account.CurrentPassword' | transloco }}</label>\n <input type=\"password\"\n id=\"account-current-password\"\n class=\"form-control\"\n formControlName=\"currentPassword\"\n autocomplete=\"current-password\" name=\"input_currentPassword_4\"/>\n @if (\n !passwordForm.get('currentPassword').valid &&\n (passwordForm.get('currentPassword').dirty ||\n passwordForm.get('currentPassword').touched)\n ) {\n <small class=\"form-text text-muted danger\"\n >\n {{ 'User.Account.Required' | transloco }}\n </small>\n }\n </div>\n <div class=\"mb-3\">\n <label for=\"account-new-password\">{{ 'User.Account.NewPassword' | transloco }}</label>\n <input type=\"password\"\n id=\"account-new-password\"\n class=\"form-control\"\n formControlName=\"newPassword\"\n autocomplete=\"new-password\" name=\"input_newPassword_5\"/>\n @if (\n !passwordForm.get('newPassword').valid &&\n (passwordForm.get('newPassword').dirty ||\n passwordForm.get('newPassword').touched)\n ) {\n <small class=\"form-text text-muted danger\"\n >{{ 'User.Account.Validation.StrongPassword' | transloco }}\n </small>\n }\n </div>\n <div class=\"mb-3\">\n <label for=\"account-confirm-password\">{{\n 'User.Account.ConfirmPassword' | transloco\n }}</label>\n <input type=\"password\"\n id=\"account-confirm-password\"\n class=\"form-control\"\n formControlName=\"confirmPassword\"\n autocomplete=\"new-password\" name=\"input_confirmPassword_6\"/>\n @if (\n passwordForm.get('confirmPassword').touched &&\n passwordForm.get('confirmPassword').errors\n ?.MatchPassword\n ) {\n <div class=\"text-danger\"\n >\n {{ 'User.Account.Validation.PasswordsMatch' | transloco }}\n </div>\n }\n </div>\n <div class=\"mb-3\">\n @if (togglePassword) {\n <a class=\"btn btn-raised btn-outline-default\"\n aria-label=\"Navigate to Target\"\n data-bs-target=\"\"\n (click)=\"onTogglePassword()\">\n {{ 'Button.Cancel' | transloco }}</a>\n }\n <button class=\"btn btn-raised btn-primary ms-2\"\n [buttonBusy]=\"passwordBusyButton\"\n [disabled]=\"!passwordForm.valid\">\n {{ 'User.Account.UpdatePassword' | transloco }}\n </button>\n </div>\n }\n <div>\n @if (!togglePassword) {\n <a class=\"btn btn-raised btn-outline-primary\"\n aria-label=\"Navigate to Target\"\n data-bs-target=\"\"\n (click)=\"togglePassword = !togglePassword\">\n {{ 'User.Account.ChangePassword' | transloco }}</a>\n }\n </div>\n </div>\n }\n @if (!user?.has_password) {\n <div class=\"col-12\"\n >\n <a class=\"btn btn-raised btn-primary me-2\"\n aria-label=\"Navigate to Target\"\n data-bs-target=\"\"\n (click)=\"sendMailToResetPassword()\">\n {{ 'User.Account.ChangePassword' | transloco }}</a>\n </div>\n }\n </div>\n </form>\n </section>\n </div>\n @if (user?.api_keys?.api_hits_max > 0) {\n <div class=\"col-12 mt-3\">\n <section id=\"api-credentials\"\n class=\"card p-4 h-auto\">\n <div class=\"row\">\n <div class=\"col-12\">\n <h2>{{ 'User.Subscriptions.APICredentials.Title' | transloco }}</h2>\n <p>\n {{ 'User.Subscriptions.APICredentials.Description' | transloco }}\n </p>\n <!-- pb (not mb): .card .mb-3:last-child is margin-reset in this component's scss -->\n <p class=\"text-muted small mb-0 pb-3\">\n <i class=\"fas fa-info-circle me-1\"></i>\n {{ 'User.Subscriptions.APICredentials.SubscriptionClientIdNote' | transloco }}\n </p>\n </div>\n <div class=\"col-12 col-md-6\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"account-api-token\">{{ 'User.Account.APIUserToken' | transloco }}</label>\n <div class=\"input-group\">\n <input type=\"text\"\n id=\"account-api-token\"\n name=\"api_token\"\n class=\"form-control\"\n [value]=\"showApiToken ? user?.api_keys?.api_user_token || ('User.Subscriptions.APICredentials.NoTokenAvailable' | transloco) : '*************************'\"\n readonly />\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"toggleApiTokenVisibility()\">\n {{ showApiToken ? ('User.Subscriptions.APICredentials.Hide' | transloco) : ('User.Subscriptions.APICredentials.View' | transloco) }}\n </button>\n </div>\n </div>\n </div>\n <div class=\"col-12 col-md-6\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"account-api-client-id\">{{ 'User.Account.APIUserId' | transloco }}</label>\n <div class=\"input-group\">\n <input type=\"text\"\n id=\"account-api-client-id\"\n name=\"api_client_id\"\n class=\"form-control\"\n [value]=\"showApiClientId ? user?.api_keys?.api_user_id || ('User.Subscriptions.APICredentials.NoClientIdAvailable' | transloco) : '*************************'\"\n readonly />\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"toggleApiClientIdVisibility()\">\n {{ showApiClientId ? ('User.Subscriptions.APICredentials.Hide' | transloco) : ('User.Subscriptions.APICredentials.View' | transloco) }}\n </button>\n </div>\n </div>\n </div>\n <div class=\"col-12 mt-3\">\n <div class=\"d-flex align-items-center gap-3\">\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"refreshApiTokens()\"\n [disabled]=\"refreshingTokens\">\n <i class=\"fas fa-sync-alt me-2\" [class.fa-spin]=\"refreshingTokens\"></i>\n {{ refreshingTokens ? ('User.Subscriptions.APICredentials.Refreshing' | transloco) : ('User.Subscriptions.APICredentials.RefreshTokens' | transloco) }}\n </button>\n <div class=\"d-flex align-items-center gap-2\">\n @if (user?.api_keys?.api_hits !== null) {\n <span class=\"text-muted\">{{ 'User.Subscriptions.APICredentials.ApiHits' | transloco }}:</span>\n <span class=\"fw-bold\">{{ user.api_keys.api_hits | number }}</span>\n }\n @if (user?.api_keys?.api_hits_max !== null) {\n <span class=\"text-muted\">{{ 'User.Subscriptions.APICredentials.ApiHitsMax' | transloco }}:</span>\n <span class=\"fw-bold\">{{ user.api_keys.api_hits_max | number }}</span>\n }\n <!-- Show utilization percentage when both values exist -->\n @if (user?.api_keys?.api_hits !== null && user?.api_keys?.api_hits_max !== null && user?.api_keys?.api_hits_max > 0) {\n <span class=\"text-muted ms-2\">(</span>\n <span class=\"fw-bold\" [ngClass]=\"{\n 'text-success': (user.api_keys.api_hits / user.api_keys.api_hits_max) <= 0.8,\n 'text-warning': (user.api_keys.api_hits / user.api_keys.api_hits_max) > 0.8 && (user.api_keys.api_hits / user.api_keys.api_hits_max) <= 0.9,\n 'text-danger': (user.api_keys.api_hits / user.api_keys.api_hits_max) > 0.9\n }\">\n {{ (user.api_keys.api_hits / user.api_keys.api_hits_max * 100) | number:'1.0-0' }}% consumed\n </span>\n <span class=\"text-muted\">)</span>\n }\n </div>\n </div>\n </div>\n </div>\n </section>\n </div>\n }\n</div>\n<ng-template #content\n let-modal>\n <div class=\"card m-0\">\n <div class=\"card-content\">\n <div class=\"card-title\">\n <h3 class=\"modal-title\">{{ 'User.Profile.ProfilePicture' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n </button>\n </div>\n <div class=\"card-header\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n aspectRatio=\"auto\"\n (imageSelectionEvent)=\"onImageSelection($event)\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [".card .mb-2:last-child,.card .mb-3:last-child{margin-bottom:0!important}.overlay{left:50%;opacity:0;position:absolute;text-align:center;top:50%;transform:translate(-50%,-50%);transition:.5s ease}.image-container{position:relative}.image-container:hover .image{opacity:.3}.image-container:hover .overlay{opacity:0}.overlay-text{background:#f0efef80;border-radius:50%;color:#000;font-size:16px;height:150px;line-height:150px;text-align:center;vertical-align:middle;width:150px}@media screen and (max-width:767px){.card-body{padding:20px!important}}\n"], dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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: "directive", type: i6$1.NgxGpAutocompleteDirective, selector: "[ngx-gp-autocomplete]", inputs: ["options"], outputs: ["onAddressChange"], exportAs: ["ngx-places"] }, { kind: "component", type: i6$2.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i9.ProfileImageCropperComponent, selector: "pw-image-cropper", inputs: ["aspectRatio", "dynamicData"], outputs: ["imageSelectionEvent", "closeEvent", "fileChangeEvent"] }, { kind: "component", type: i5.InputContainerComponent, selector: "pw-input-container", inputs: ["name", "controlId", "useAriaLabelledbyOnly", "label", "labelClass", "tooltipPosition", "required", "errorMsg", "isReadOnly", "showTooltip", "tooltipText", "showTriangle", "afterLabel", "showAfterLabel", "showTriangleText", "isLeftTooltip"] }, { kind: "directive", type: i11.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "directive", type: i1$1.NgbInputDatepicker, selector: "input[ngbDatepicker]", inputs: ["autoClose", "contentTemplate", "datepickerClass", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "minDate", "maxDate", "navigation", "outsideDays", "placement", "popperOptions", "restoreFocus", "showWeekNumbers", "startDate", "container", "positionTarget", "weekdays", "disabled"], outputs: ["dateSelect", "navigate", "closed"], exportAs: ["ngbDatepicker"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.DecimalPipe, name: "number" }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
477
478
  }
478
479
  __decorate([
479
480
  ValidateForm('profileForm'),
@@ -483,7 +484,7 @@ __decorate([
483
484
  ], AccountDetailsComponent.prototype, "onProfileFormSubmit", null);
484
485
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AccountDetailsComponent, decorators: [{
485
486
  type: Component,
486
- args: [{ selector: 'pw-account-details', standalone: false, template: "<div class=\"w-100 text-center\">\n @if (!isLoaded) {\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n }\n</div>\n<div class=\"row d-flex flex-row\">\n <div class=\"col-md-8 order-md-first order-sm-last\">\n <section id=\"email-section\">\n <div class=\"row\">\n <div class=\"col-sm-12 col-md-8 col-lg-8\">\n <h2>{{ 'User.Account.RegisteredEmail' | transloco }}</h2>\n <!-- Email Form -->\n <section id=\"email-form\">\n <form [formGroup]=\"emailForm\"\n (ngSubmit)=\"onEmailFormSubmit()\">\n <!-- Email Address -->\n <div class=\"mt-0\">\n <span id=\"account-primary-email-label\" class=\"me-3 pw-label-style\">{{ 'User.Account.PrimaryEmail' | transloco }}:\n </span>\n <strong>{{ validatedEmail }}</strong>\n <div class=\"mt-1\">\n @if (!toggleEmail) {\n <a class=\"btn btn-raised btn-outline-primary\"\n aria-label=\"Navigate to Target\"\n (click)=\"shouldUserChangeEmail()\">\n {{ 'User.Account.ChangeEmail' | transloco }}</a>\n }\n @if (toggleEmail) {\n <div class=\"row\">\n <div class=\"clearfix\"></div>\n <div class=\"col-12 mb-3\">\n @if (!passwordVerified) {\n <input type=\"password\"\n class=\"form-control\"\n id=\"account-email-current-password\"\n name=\"currentPassword\"\n #password\n placeholder=\"Current Password\"\n autocomplete=\"current-password\"\n (keyup)=\"checkValidity()\" />\n }\n @if (passwordVerified) {\n <input type=\"text\"\n class=\"form-control\"\n id=\"account-new-email\"\n name=\"newEmail\"\n placeholder=\"New Email\"\n autocomplete=\"email\"\n formControlName=\"email\" />\n }\n </div>\n <div class=\"col-12\">\n @if (toggleEmail) {\n <a\n class=\"btn btn-raised btn-outline-default my-2 me-2\"\n aria-label=\"Navigate to Target\"\n (click)=\"onToggleEmail()\">{{ 'Button.Cancel' | transloco }}</a>\n }\n @if (!passwordVerified) {\n <button class=\"btn btn-raised btn-primary\"\n type=\"submit\"\n [buttonBusy]=\"validatePasswordBusyButton\"\n (click)=\"validatePassword()\"\n [disabled]=\"isCurrentPasswordValid\">\n {{ 'User.Account.Validate' | transloco }}\n </button>\n }\n @if (passwordVerified) {\n <button type=\"submit\"\n class=\"btn btn-raised btn-primary\"\n [buttonBusy]=\"emailBusyButton\"\n >\n {{\n 'User.Account.SendVerification' | transloco\n }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n </div>\n <section id=\"slug\"\n class=\"mb-2 mt-3\">\n <div>\n <span class=\"me-3 pw-label-style\" id=\"account-nickname-label\">{{ 'User.Account.NickName' | transloco }}:\n </span>\n <strong>{{ slug }}</strong>\n <div>\n @if (!toggleNickName) {\n <a class=\"btn btn-raised btn-outline-primary me-2\"\n aria-label=\"Navigate to Target\"\n (click)=\"toggleNickName = true\">\n {{ 'User.Account.ChangeNickname' | transloco }}</a>\n }\n @if (toggleNickName) {\n <div class=\"mb-3\">\n <input type=\"text\"\n id=\"account-nickname\"\n name=\"nickname\"\n class=\"form-control slug-input\"\n aria-labelledby=\"account-nickname-label\"\n [(ngModel)]=\"slug\"\n [ngModelOptions]=\"{ standalone: true }\" />\n </div>\n <div>\n <button type=\"button\"\n class=\"btn btn-raised btn-outline-default\"\n (click)=\"toggleNickName = false\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"button\"\n class=\"btn btn-raised btn-primary ms-2\"\n [buttonBusy]=\"slugBusyButton\"\n [disabled]=\"slug?.length < 2\"\n (click)=\"onUpdateSlug()\">\n {{ 'User.Account.UpdateNickname' | transloco }}\n </button>\n </div>\n }\n </div>\n </div>\n </section>\n </form>\n </section>\n </div>\n </div>\n <section id=\"password-change\"\n class=\"mt-1\">\n <form [formGroup]=\"passwordForm\"\n (ngSubmit)=\"onPasswordFormSubmit()\">\n <div class=\"row\">\n <div class=\"col-sm-12 col-md-8 col-lg-8 mt-4\">\n <h2>{{ 'User.Account.ChangePassword' | transloco }}</h2>\n </div>\n @if (!user?.has_password) {\n <div class=\"text-danger mx-3 my-2\">\n <div>\n You don't have a password set, click on\n <em>{{ 'User.Account.ChangePassword' | transloco }}</em>.\n </div>\n <div>{{ 'User.Profile.PictureMessage' | transloco }}</div>\n </div>\n }\n @if (user?.has_password) {\n <div class=\"col-sm-12 col-md-8 col-lg-8\"\n >\n @if (togglePassword) {\n <div class=\"mb-3\">\n <label for=\"account-current-password\">{{ 'User.Account.CurrentPassword' | transloco }}</label>\n <input type=\"password\"\n id=\"account-current-password\"\n class=\"form-control\"\n formControlName=\"currentPassword\"\n autocomplete=\"current-password\" name=\"input_currentPassword_4\"/>\n @if (\n !passwordForm.get('currentPassword').valid &&\n (passwordForm.get('currentPassword').dirty ||\n passwordForm.get('currentPassword').touched)\n ) {\n <small class=\"form-text text-muted danger\"\n >\n {{ 'User.Account.Required' | transloco }}\n </small>\n }\n </div>\n <div class=\"mb-3\">\n <label for=\"account-new-password\">{{ 'User.Account.NewPassword' | transloco }}</label>\n <input type=\"password\"\n id=\"account-new-password\"\n class=\"form-control\"\n formControlName=\"newPassword\"\n autocomplete=\"new-password\" name=\"input_newPassword_5\"/>\n @if (\n !passwordForm.get('newPassword').valid &&\n (passwordForm.get('newPassword').dirty ||\n passwordForm.get('newPassword').touched)\n ) {\n <small class=\"form-text text-muted danger\"\n >{{ 'User.Account.Validation.StrongPassword' | transloco }}\n </small>\n }\n </div>\n <div class=\"mb-3\">\n <label for=\"account-confirm-password\">{{\n 'User.Account.ConfirmPassword' | transloco\n }}</label>\n <input type=\"password\"\n id=\"account-confirm-password\"\n class=\"form-control\"\n formControlName=\"confirmPassword\"\n autocomplete=\"new-password\" name=\"input_confirmPassword_6\"/>\n @if (\n passwordForm.get('confirmPassword').touched &&\n passwordForm.get('confirmPassword').errors\n ?.MatchPassword\n ) {\n <div class=\"text-danger\"\n >\n {{ 'User.Account.Validation.PasswordsMatch' | transloco }}\n </div>\n }\n </div>\n <div class=\"mb-3\">\n @if (togglePassword) {\n <a class=\"btn btn-raised btn-outline-default\"\n aria-label=\"Navigate to Target\"\n data-bs-target=\"\"\n (click)=\"onTogglePassword()\">\n {{ 'Button.Cancel' | transloco }}</a>\n }\n <button class=\"btn btn-raised btn-primary ms-2\"\n [buttonBusy]=\"passwordBusyButton\"\n [disabled]=\"!passwordForm.valid\">\n {{ 'User.Account.UpdatePassword' | transloco }}\n </button>\n </div>\n }\n <div>\n @if (!togglePassword) {\n <a class=\"btn btn-raised btn-outline-primary\"\n aria-label=\"Navigate to Target\"\n data-bs-target=\"\"\n (click)=\"togglePassword = !togglePassword\">\n {{ 'User.Account.ChangePassword' | transloco }}</a>\n }\n </div>\n </div>\n }\n @if (!user?.has_password) {\n <div class=\"col-sm-12 col-md-8 col-lg-8\"\n >\n <a class=\"btn btn-raised btn-primary me-2\"\n aria-label=\"Navigate to Target\"\n data-bs-target=\"\"\n (click)=\"sendMailToResetPassword()\">\n {{ 'User.Account.ChangePassword' | transloco }}</a>\n </div>\n }\n </div>\n </form>\n </section>\n @if (user?.api_keys?.api_hits_max > 0) {\n <section id=\"api-credentials\"\n class=\"mt-4\">\n <div class=\"row\">\n <div class=\"col-12\">\n <h3>{{ 'User.Subscriptions.APICredentials.Title' | transloco }}</h3>\n <p>\n {{ 'User.Subscriptions.APICredentials.Description' | transloco }}\n </p>\n </div>\n <div class=\"col-12 col-md-6\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"account-api-token\">{{ 'User.Account.APIUserToken' | transloco }}</label>\n <div class=\"input-group\">\n <input type=\"text\"\n id=\"account-api-token\"\n name=\"api_token\"\n class=\"form-control\"\n [value]=\"showApiToken ? user?.api_keys?.api_user_token || ('User.Subscriptions.APICredentials.NoTokenAvailable' | transloco) : '*************************'\"\n readonly />\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"toggleApiTokenVisibility()\">\n {{ showApiToken ? ('User.Subscriptions.APICredentials.Hide' | transloco) : ('User.Subscriptions.APICredentials.View' | transloco) }}\n </button>\n </div>\n </div>\n </div>\n <div class=\"col-12 col-md-6\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"account-api-client-id\">{{ 'User.Account.APIUserId' | transloco }}</label>\n <div class=\"input-group\">\n <input type=\"text\"\n id=\"account-api-client-id\"\n name=\"api_client_id\"\n class=\"form-control\"\n [value]=\"showApiClientId ? user?.api_keys?.api_user_id || ('User.Subscriptions.APICredentials.NoClientIdAvailable' | transloco) : '*************************'\"\n readonly />\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"toggleApiClientIdVisibility()\">\n {{ showApiClientId ? ('User.Subscriptions.APICredentials.Hide' | transloco) : ('User.Subscriptions.APICredentials.View' | transloco) }}\n </button>\n </div>\n </div>\n </div>\n <div class=\"col-12 mt-3\">\n <div class=\"d-flex align-items-center gap-3\">\n <button type=\"button\"\n class=\"btn btn-warning\"\n (click)=\"refreshApiTokens()\"\n [disabled]=\"refreshingTokens\">\n <i class=\"fas fa-sync-alt me-2\" [class.fa-spin]=\"refreshingTokens\"></i>\n {{ refreshingTokens ? ('User.Subscriptions.APICredentials.Refreshing' | transloco) : ('User.Subscriptions.APICredentials.RefreshTokens' | transloco) }}\n </button>\n <div class=\"d-flex align-items-center gap-2\">\n @if (user?.api_keys?.api_hits !== null) {\n <span class=\"text-muted\">{{ 'User.Subscriptions.APICredentials.ApiHits' | transloco }}:</span>\n <span class=\"fw-bold\">{{ user.api_keys.api_hits | number }}</span>\n }\n @if (user?.api_keys?.api_hits_max !== null) {\n <span class=\"text-muted\">{{ 'User.Subscriptions.APICredentials.ApiHitsMax' | transloco }}:</span>\n <span class=\"fw-bold\">{{ user.api_keys.api_hits_max | number }}</span>\n }\n <!-- Show utilization percentage when both values exist -->\n @if (user?.api_keys?.api_hits !== null && user?.api_keys?.api_hits_max !== null && user?.api_keys?.api_hits_max > 0) {\n <span class=\"text-muted ms-2\">(</span>\n <span class=\"fw-bold\" [ngClass]=\"{\n 'text-success': (user.api_keys.api_hits / user.api_keys.api_hits_max) <= 0.8,\n 'text-warning': (user.api_keys.api_hits / user.api_keys.api_hits_max) > 0.8 && (user.api_keys.api_hits / user.api_keys.api_hits_max) <= 0.9,\n 'text-danger': (user.api_keys.api_hits / user.api_keys.api_hits_max) > 0.9\n }\">\n {{ (user.api_keys.api_hits / user.api_keys.api_hits_max * 100) | number:'1.0-0' }}% consumed\n </span>\n <span class=\"text-muted\">)</span>\n }\n </div>\n </div>\n </div>\n </div>\n </section>\n }\n </section>\n </div>\n <!-- Avatar -->\n <div class=\"mt-4 mt-sm-0 col-md-4 text-center order-md-last order-sm-first\">\n <h2>{{ 'User.Profile.Avatar' | transloco }}</h2>\n <div class=\"text-center mt-1\">\n <div class=\"image-container\">\n <img [src]=\"image\"\n width=\"150\"\n height=\"150\"\n class=\"image rounded-circle\"\n alt=\"User Male\"\n (error)=\"handleImageError($event, 'assets/img/icons/male.png')\" />\n <div class=\"overlay\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\">\n <div class=\"overlay-text\">{{ 'User.Profile.Change' | transloco }}</div>\n </div>\n </div>\n <h4 class=\"mt-2\">{{ user?.first_name }} {{ user?.last_name }}</h4>\n <a aria-label=\"Navigate to Target\"\n class=\"d-inline-block mb-2\"\n (click)=\"openModal(content)\">\n {{ 'User.Profile.EditAvatar' | transloco }}</a>\n <br />\n </div>\n </div>\n</div>\n<br />\n<section id=\"user-profile\"\n class=\"mt-2\">\n <div class=\"row\">\n <div class=\"col-12\">\n <form [formGroup]=\"profileForm\"\n (ngSubmit)=\"onProfileFormSubmit()\">\n <h2>{{ 'User.Profile.UserProfile' | transloco }}</h2>\n <div class=\"row mt-3\">\n <div class=\"col-sm-12 col-md-6 col-lg-6\">\n <pw-input-container label=\"First Name\"\n name=\"first_name\"\n controlId=\"account-first_name\"\n errorMsg=\"Please enter first Name\">\n <input type=\"text\"\n id=\"account-first_name\"\n class=\"form-control\"\n formControlName=\"first_name\"\n autocomplete=\"given-name\" name=\"input_first_name_9\"/>\n </pw-input-container>\n <pw-input-container label=\"Preferred name\"\n name=\"preferred_name\"\n controlId=\"account-preferred_name\"\n errorMsg=\"Please enter preferred Name\">\n <input type=\"text\"\n id=\"account-preferred_name\"\n class=\"form-control\"\n formControlName=\"preferred_name\"\n autocomplete=\"username\" name=\"input_preferred_name_10\"/>\n </pw-input-container>\n @if (countries$ | async; as countries) {\n <pw-input-container label=\"Country\"\n name=\"country\"\n controlId=\"account-country\"\n [useAriaLabelledbyOnly]=\"true\"\n errorMsg=\"Please select a country\">\n <p-select\n [attr.aria-labelledby]=\"'account-country-label'\"\n [options]=\"countries\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"country\"\n (onChange)=\"getRegion($event.value)\"\n placeholder=\"{{ 'User.Profile.SelectCountry' | transloco }}\">\n </p-select>\n </pw-input-container>\n }\n <pw-input-container label=\"Province\"\n name=\"province\"\n controlId=\"account-province\"\n errorMsg=\"Please enter province\">\n <input type=\"text\"\n id=\"account-province\"\n class=\"form-control\"\n formControlName=\"province\"\n autocomplete=\"postal-code\" name=\"input_province_11\"/>\n </pw-input-container>\n <pw-input-container label=\"Website Url\"\n name=\"website_url\"\n controlId=\"account-website_url\"\n errorMsg=\"Please enter Website\">\n <input type=\"text\"\n id=\"account-website_url\"\n class=\"form-control\"\n formControlName=\"website_url\"\n autocomplete=\"url\" name=\"input_website_url_12\"/>\n </pw-input-container>\n </div>\n <div class=\"col-sm-12 col-md-6 col-lg-6\">\n <pw-input-container label=\"Last Name\"\n name=\"last_name\"\n controlId=\"account-last_name\"\n errorMsg=\"Please enter last Name\">\n <input type=\"text\"\n id=\"account-last_name\"\n class=\"form-control\"\n formControlName=\"last_name\"\n autocomplete=\"family-name\" name=\"input_last_name_13\"/>\n </pw-input-container>\n <pw-input-container label=\"Date of Birth\"\n name=\"dob\"\n controlId=\"account-dob\"\n errorMsg=\"Please enter date of birth\">\n <div class=\"input-group\">\n <input class=\"form-control\"\n id=\"account-dob\"\n name=\"dob\"\n placeholder=\"dd-mmm-yyyy\"\n formControlName=\"dob\"\n ngbDatepicker\n #d=\"ngbDatepicker\"\n [minDate]=\"{ day: 1, month: 1, year: 1950 }\"\n [maxDate]=\"{ day: 31, month: 12, year: 2018 }\" />\n <div class=\"input-group-append\">\n <button class=\"btn btn-primary\"\n type=\"button\"\n id=\"account-dob-trigger\"\n aria-label=\"Open date picker for date of birth\"\n (click)=\"d.toggle()\">\n <i class=\"fa fa-calendar\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </pw-input-container>\n <pw-input-container label=\"State\"\n name=\"state\"\n controlId=\"account-state\"\n [useAriaLabelledbyOnly]=\"true\"\n errorMsg=\"Please select a state\">\n <p-select\n [attr.aria-labelledby]=\"'account-state-label'\"\n [options]=\"states\"\n [(ngModel)]=\"selectedState\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"state\"\n [placeholder]=\"'User.Profile.SelectState' | transloco\">\n </p-select>\n\n </pw-input-container>\n <!-- Location -->\n <pw-input-container label=\"Location\"\n name=\"location\"\n controlId=\"account-location\"\n [useAriaLabelledbyOnly]=\"true\">\n <input ngx-gp-autocomplete\n id=\"account-location\"\n name=\"location\"\n class=\"form-control\"\n [attr.aria-labelledby]=\"'account-location-label'\"\n #places=\"ngx-places\"\n formControlName=\"location\"\n (onAddressChange)=\"handleAddressChange($event)\" />\n </pw-input-container>\n <pw-input-container label=\"Phone Number\"\n name=\"phone_number\"\n controlId=\"account-phone_number\"\n errorMsg=\"Please enter phone number\">\n <input type=\"text\"\n id=\"account-phone_number\"\n class=\"form-control\"\n formControlName=\"phone_number\"\n autocomplete=\"tel\" name=\"input_phone_number_16\"/>\n </pw-input-container>\n </div>\n <div class=\"col-12 text-end\">\n <div class=\"mb-3\">\n <button class=\"btn btn-raised btn-primary\" [buttonBusy]=\"profileBusyButton\">\n {{ 'Button.Save' | transloco }}\n </button>\n </div>\n </div>\n </div>\n </form>\n </div>\n </div>\n</section>\n<ng-template #content\n let-modal>\n <div class=\"card m-0\">\n <div class=\"card-content\">\n <div class=\"card-title\">\n <h3 class=\"modal-title\">{{ 'User.Profile.ProfilePicture' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"card-header\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n aspectRatio=\"auto\"\n (imageSelectionEvent)=\"onImageSelection($event)\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [".overlay{left:50%;opacity:0;position:absolute;text-align:center;top:50%;transform:translate(-50%,-50%);transition:.5s ease}.image-container{position:relative}.image-container:hover .image{opacity:.3}.image-container:hover .overlay{opacity:0}.overlay-text{background:#f0efef80;border-radius:50%;color:#000;font-size:16px;height:150px;line-height:150px;text-align:center;vertical-align:middle;width:150px}@media screen and (max-width:767px){.card-body{padding:20px!important}}\n"] }]
487
+ args: [{ selector: 'pw-account-details', standalone: false, template: "<div class=\"w-100 text-center\">\n @if (!isLoaded) {\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n }\n</div>\n<div class=\"row gx-3 mb-3\">\n <div class=\"col-md-4\">\n <section class=\"card p-4 h-100 d-flex flex-column\">\n <h2>{{ 'User.Profile.Avatar' | transloco }}</h2>\n <div class=\"text-center d-flex flex-column justify-content-center flex-grow-1 mt-1\">\n <div class=\"image-container\">\n <img [src]=\"image\"\n width=\"150\"\n height=\"150\"\n class=\"image rounded-circle\"\n alt=\"User Male\"\n (error)=\"handleImageError($event, 'assets/img/icons/male.png')\" />\n <div class=\"overlay\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\">\n <div class=\"overlay-text\">{{ 'User.Profile.Change' | transloco }}</div>\n </div>\n </div>\n <h4 class=\"mt-2\">{{ user?.first_name }} {{ user?.last_name }}</h4>\n <a aria-label=\"Navigate to Target\"\n class=\"d-inline-block mb-2\"\n (click)=\"openModal(content)\">\n {{ 'User.Profile.EditAvatar' | transloco }}</a>\n </div>\n </section>\n </div>\n <div class=\"col-md-8\">\n <section id=\"user-profile\"\n class=\"card p-4 overflow-visible h-100\">\n <form [formGroup]=\"profileForm\"\n (ngSubmit)=\"onProfileFormSubmit()\">\n <h2>{{ 'User.Profile.UserProfile' | transloco }}</h2>\n <div class=\"row mt-3\">\n <div class=\"col-sm-12 col-md-6 col-lg-6\">\n <pw-input-container label=\"First Name\"\n name=\"first_name\"\n controlId=\"account-first_name\"\n errorMsg=\"Please enter first Name\">\n <input type=\"text\"\n id=\"account-first_name\"\n class=\"form-control\"\n formControlName=\"first_name\"\n autocomplete=\"given-name\" name=\"input_first_name_9\"/>\n </pw-input-container>\n <pw-input-container label=\"Preferred name\"\n name=\"preferred_name\"\n controlId=\"account-preferred_name\"\n errorMsg=\"Please enter preferred Name\">\n <input type=\"text\"\n id=\"account-preferred_name\"\n class=\"form-control\"\n formControlName=\"preferred_name\"\n autocomplete=\"username\" name=\"input_preferred_name_10\"/>\n </pw-input-container>\n @if (countries$ | async; as countries) {\n <pw-input-container label=\"Country\"\n name=\"country\"\n controlId=\"account-country\"\n [useAriaLabelledbyOnly]=\"true\"\n errorMsg=\"Please select a country\">\n <p-select\n [attr.aria-labelledby]=\"'account-country-label'\"\n [options]=\"countries\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"country\"\n (onChange)=\"getRegion($event.value)\"\n placeholder=\"{{ 'User.Profile.SelectCountry' | transloco }}\">\n </p-select>\n </pw-input-container>\n }\n <pw-input-container label=\"Province\"\n name=\"province\"\n controlId=\"account-province\"\n errorMsg=\"Please enter province\">\n <input type=\"text\"\n id=\"account-province\"\n class=\"form-control\"\n formControlName=\"province\"\n autocomplete=\"postal-code\" name=\"input_province_11\"/>\n </pw-input-container>\n <pw-input-container label=\"Website Url\"\n name=\"website_url\"\n controlId=\"account-website_url\"\n errorMsg=\"Please enter Website\">\n <input type=\"text\"\n id=\"account-website_url\"\n class=\"form-control\"\n formControlName=\"website_url\"\n autocomplete=\"url\" name=\"input_website_url_12\"/>\n </pw-input-container>\n </div>\n <div class=\"col-sm-12 col-md-6 col-lg-6\">\n <pw-input-container label=\"Last Name\"\n name=\"last_name\"\n controlId=\"account-last_name\"\n errorMsg=\"Please enter last Name\">\n <input type=\"text\"\n id=\"account-last_name\"\n class=\"form-control\"\n formControlName=\"last_name\"\n autocomplete=\"family-name\" name=\"input_last_name_13\"/>\n </pw-input-container>\n <pw-input-container label=\"Date of Birth\"\n name=\"dob\"\n controlId=\"account-dob\"\n errorMsg=\"Please enter date of birth\">\n <div class=\"input-group\">\n <input class=\"form-control\"\n id=\"account-dob\"\n name=\"dob\"\n placeholder=\"dd-mmm-yyyy\"\n formControlName=\"dob\"\n ngbDatepicker\n #d=\"ngbDatepicker\"\n [minDate]=\"{ day: 1, month: 1, year: 1950 }\"\n [maxDate]=\"{ day: 31, month: 12, year: 2018 }\" />\n <button class=\"btn btn-primary\"\n type=\"button\"\n id=\"account-dob-trigger\"\n aria-label=\"Open date picker for date of birth\"\n (click)=\"d.toggle()\">\n <i class=\"fa fa-calendar\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </pw-input-container>\n <pw-input-container label=\"State\"\n name=\"state\"\n controlId=\"account-state\"\n [useAriaLabelledbyOnly]=\"true\"\n errorMsg=\"Please select a state\">\n <p-select\n [attr.aria-labelledby]=\"'account-state-label'\"\n [options]=\"states\"\n [(ngModel)]=\"selectedState\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"state\"\n [placeholder]=\"'User.Profile.SelectState' | transloco\">\n </p-select>\n </pw-input-container>\n <pw-input-container label=\"Location\"\n name=\"location\"\n controlId=\"account-location\"\n [useAriaLabelledbyOnly]=\"true\">\n <input ngx-gp-autocomplete\n id=\"account-location\"\n name=\"location\"\n class=\"form-control\"\n [attr.aria-labelledby]=\"'account-location-label'\"\n #places=\"ngx-places\"\n formControlName=\"location\"\n (onAddressChange)=\"handleAddressChange($event)\" />\n </pw-input-container>\n <pw-input-container label=\"Phone Number\"\n name=\"phone_number\"\n controlId=\"account-phone_number\"\n errorMsg=\"Please enter phone number\">\n <input type=\"text\"\n id=\"account-phone_number\"\n class=\"form-control\"\n formControlName=\"phone_number\"\n autocomplete=\"tel\" name=\"input_phone_number_16\"/>\n </pw-input-container>\n </div>\n <div class=\"col-12 text-end\">\n <div class=\"mb-3\">\n <button class=\"btn btn-raised btn-primary\" [buttonBusy]=\"profileBusyButton\">\n {{ 'Button.Save' | transloco }}\n </button>\n </div>\n </div>\n </div>\n </form>\n </section>\n </div>\n</div>\n<div class=\"row gx-3 mb-3\">\n <div class=\"col-md-6\">\n <section id=\"email-section\"\n class=\"card p-4 h-100\">\n <div class=\"row\">\n <div class=\"col-12\">\n <h2>{{ 'User.Account.RegisteredEmail' | transloco }}</h2>\n <section id=\"email-form\">\n <form [formGroup]=\"emailForm\"\n (ngSubmit)=\"onEmailFormSubmit()\">\n <!-- Email Address -->\n <div class=\"mt-0\">\n <span id=\"account-primary-email-label\" class=\"me-3 pw-label-style\">{{ 'User.Account.PrimaryEmail' | transloco }}:\n </span>\n <strong>{{ validatedEmail }}</strong>\n <div class=\"mt-1\">\n @if (!toggleEmail) {\n <a class=\"btn btn-raised btn-outline-primary\"\n aria-label=\"Navigate to Target\"\n (click)=\"shouldUserChangeEmail()\">\n {{ 'User.Account.ChangeEmail' | transloco }}</a>\n }\n @if (toggleEmail) {\n <div class=\"row\">\n <div class=\"clearfix\"></div>\n <div class=\"col-12 mb-3\">\n @if (!passwordVerified) {\n <input type=\"password\"\n class=\"form-control\"\n id=\"account-email-current-password\"\n name=\"currentPassword\"\n #password\n placeholder=\"Current Password\"\n autocomplete=\"current-password\"\n (keyup)=\"checkValidity()\" />\n }\n @if (passwordVerified) {\n <input type=\"text\"\n class=\"form-control\"\n id=\"account-new-email\"\n name=\"newEmail\"\n placeholder=\"New Email\"\n autocomplete=\"email\"\n formControlName=\"email\" />\n }\n </div>\n <div class=\"col-12\">\n @if (toggleEmail) {\n <a\n class=\"btn btn-raised btn-outline-default my-2 me-2\"\n aria-label=\"Navigate to Target\"\n (click)=\"onToggleEmail()\">{{ 'Button.Cancel' | transloco }}</a>\n }\n @if (!passwordVerified) {\n <button class=\"btn btn-raised btn-primary\"\n type=\"submit\"\n [buttonBusy]=\"validatePasswordBusyButton\"\n (click)=\"validatePassword()\"\n [disabled]=\"isCurrentPasswordValid\">\n {{ 'User.Account.Validate' | transloco }}\n </button>\n }\n @if (passwordVerified) {\n <button type=\"submit\"\n class=\"btn btn-raised btn-primary\"\n [buttonBusy]=\"emailBusyButton\"\n >\n {{\n 'User.Account.SendVerification' | transloco\n }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n </div>\n <section id=\"slug\"\n class=\"mb-2 mt-3\">\n <div>\n <span class=\"me-3 pw-label-style\" id=\"account-nickname-label\">{{ 'User.Account.NickName' | transloco }}:</span>\n <span class=\"tooltip-wrap me-3\" [pTooltip]=\"'User.Account.HandleTooltip' | transloco\" [appendTo]=\"'body'\" tooltipPosition=\"top\"><i class=\"far fa-info-circle text-muted\"></i></span>\n <strong>{{ slug }}</strong>\n <div class=\"mt-1\">\n @if (!toggleNickName) {\n <a class=\"btn btn-raised btn-outline-primary me-2\"\n aria-label=\"Navigate to Target\"\n (click)=\"toggleNickName = true\">\n {{ 'User.Account.ChangeNickname' | transloco }}</a>\n }\n @if (toggleNickName) {\n <div class=\"mb-3\">\n <input type=\"text\"\n id=\"account-nickname\"\n name=\"nickname\"\n class=\"form-control slug-input\"\n aria-labelledby=\"account-nickname-label\"\n [(ngModel)]=\"slug\"\n [ngModelOptions]=\"{ standalone: true }\" />\n </div>\n <div>\n <button type=\"button\"\n class=\"btn btn-raised btn-outline-default\"\n (click)=\"toggleNickName = false\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"button\"\n class=\"btn btn-raised btn-primary ms-2\"\n [buttonBusy]=\"slugBusyButton\"\n [disabled]=\"slug?.length < 2\"\n (click)=\"onUpdateSlug()\">\n {{ 'User.Account.UpdateNickname' | transloco }}\n </button>\n </div>\n }\n </div>\n </div>\n </section>\n </form>\n </section>\n </div>\n </div>\n </section>\n </div>\n <div class=\"col-md-6\">\n <section id=\"password-change\"\n class=\"card p-4 h-100\">\n <form [formGroup]=\"passwordForm\"\n (ngSubmit)=\"onPasswordFormSubmit()\">\n <div class=\"row\">\n <div class=\"col-12\">\n <h2>{{ 'User.Account.ChangePassword' | transloco }}</h2>\n </div>\n @if (!user?.has_password) {\n <div class=\"text-danger mx-3 my-2\">\n <div>\n You don't have a password set, click on\n <em>{{ 'User.Account.ChangePassword' | transloco }}</em>.\n </div>\n <div>{{ 'User.Profile.PictureMessage' | transloco }}</div>\n </div>\n }\n @if (user?.has_password) {\n <div class=\"col-12\"\n >\n @if (togglePassword) {\n <div class=\"mb-3\">\n <label for=\"account-current-password\">{{ 'User.Account.CurrentPassword' | transloco }}</label>\n <input type=\"password\"\n id=\"account-current-password\"\n class=\"form-control\"\n formControlName=\"currentPassword\"\n autocomplete=\"current-password\" name=\"input_currentPassword_4\"/>\n @if (\n !passwordForm.get('currentPassword').valid &&\n (passwordForm.get('currentPassword').dirty ||\n passwordForm.get('currentPassword').touched)\n ) {\n <small class=\"form-text text-muted danger\"\n >\n {{ 'User.Account.Required' | transloco }}\n </small>\n }\n </div>\n <div class=\"mb-3\">\n <label for=\"account-new-password\">{{ 'User.Account.NewPassword' | transloco }}</label>\n <input type=\"password\"\n id=\"account-new-password\"\n class=\"form-control\"\n formControlName=\"newPassword\"\n autocomplete=\"new-password\" name=\"input_newPassword_5\"/>\n @if (\n !passwordForm.get('newPassword').valid &&\n (passwordForm.get('newPassword').dirty ||\n passwordForm.get('newPassword').touched)\n ) {\n <small class=\"form-text text-muted danger\"\n >{{ 'User.Account.Validation.StrongPassword' | transloco }}\n </small>\n }\n </div>\n <div class=\"mb-3\">\n <label for=\"account-confirm-password\">{{\n 'User.Account.ConfirmPassword' | transloco\n }}</label>\n <input type=\"password\"\n id=\"account-confirm-password\"\n class=\"form-control\"\n formControlName=\"confirmPassword\"\n autocomplete=\"new-password\" name=\"input_confirmPassword_6\"/>\n @if (\n passwordForm.get('confirmPassword').touched &&\n passwordForm.get('confirmPassword').errors\n ?.MatchPassword\n ) {\n <div class=\"text-danger\"\n >\n {{ 'User.Account.Validation.PasswordsMatch' | transloco }}\n </div>\n }\n </div>\n <div class=\"mb-3\">\n @if (togglePassword) {\n <a class=\"btn btn-raised btn-outline-default\"\n aria-label=\"Navigate to Target\"\n data-bs-target=\"\"\n (click)=\"onTogglePassword()\">\n {{ 'Button.Cancel' | transloco }}</a>\n }\n <button class=\"btn btn-raised btn-primary ms-2\"\n [buttonBusy]=\"passwordBusyButton\"\n [disabled]=\"!passwordForm.valid\">\n {{ 'User.Account.UpdatePassword' | transloco }}\n </button>\n </div>\n }\n <div>\n @if (!togglePassword) {\n <a class=\"btn btn-raised btn-outline-primary\"\n aria-label=\"Navigate to Target\"\n data-bs-target=\"\"\n (click)=\"togglePassword = !togglePassword\">\n {{ 'User.Account.ChangePassword' | transloco }}</a>\n }\n </div>\n </div>\n }\n @if (!user?.has_password) {\n <div class=\"col-12\"\n >\n <a class=\"btn btn-raised btn-primary me-2\"\n aria-label=\"Navigate to Target\"\n data-bs-target=\"\"\n (click)=\"sendMailToResetPassword()\">\n {{ 'User.Account.ChangePassword' | transloco }}</a>\n </div>\n }\n </div>\n </form>\n </section>\n </div>\n @if (user?.api_keys?.api_hits_max > 0) {\n <div class=\"col-12 mt-3\">\n <section id=\"api-credentials\"\n class=\"card p-4 h-auto\">\n <div class=\"row\">\n <div class=\"col-12\">\n <h2>{{ 'User.Subscriptions.APICredentials.Title' | transloco }}</h2>\n <p>\n {{ 'User.Subscriptions.APICredentials.Description' | transloco }}\n </p>\n <!-- pb (not mb): .card .mb-3:last-child is margin-reset in this component's scss -->\n <p class=\"text-muted small mb-0 pb-3\">\n <i class=\"fas fa-info-circle me-1\"></i>\n {{ 'User.Subscriptions.APICredentials.SubscriptionClientIdNote' | transloco }}\n </p>\n </div>\n <div class=\"col-12 col-md-6\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"account-api-token\">{{ 'User.Account.APIUserToken' | transloco }}</label>\n <div class=\"input-group\">\n <input type=\"text\"\n id=\"account-api-token\"\n name=\"api_token\"\n class=\"form-control\"\n [value]=\"showApiToken ? user?.api_keys?.api_user_token || ('User.Subscriptions.APICredentials.NoTokenAvailable' | transloco) : '*************************'\"\n readonly />\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"toggleApiTokenVisibility()\">\n {{ showApiToken ? ('User.Subscriptions.APICredentials.Hide' | transloco) : ('User.Subscriptions.APICredentials.View' | transloco) }}\n </button>\n </div>\n </div>\n </div>\n <div class=\"col-12 col-md-6\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"account-api-client-id\">{{ 'User.Account.APIUserId' | transloco }}</label>\n <div class=\"input-group\">\n <input type=\"text\"\n id=\"account-api-client-id\"\n name=\"api_client_id\"\n class=\"form-control\"\n [value]=\"showApiClientId ? user?.api_keys?.api_user_id || ('User.Subscriptions.APICredentials.NoClientIdAvailable' | transloco) : '*************************'\"\n readonly />\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"toggleApiClientIdVisibility()\">\n {{ showApiClientId ? ('User.Subscriptions.APICredentials.Hide' | transloco) : ('User.Subscriptions.APICredentials.View' | transloco) }}\n </button>\n </div>\n </div>\n </div>\n <div class=\"col-12 mt-3\">\n <div class=\"d-flex align-items-center gap-3\">\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"refreshApiTokens()\"\n [disabled]=\"refreshingTokens\">\n <i class=\"fas fa-sync-alt me-2\" [class.fa-spin]=\"refreshingTokens\"></i>\n {{ refreshingTokens ? ('User.Subscriptions.APICredentials.Refreshing' | transloco) : ('User.Subscriptions.APICredentials.RefreshTokens' | transloco) }}\n </button>\n <div class=\"d-flex align-items-center gap-2\">\n @if (user?.api_keys?.api_hits !== null) {\n <span class=\"text-muted\">{{ 'User.Subscriptions.APICredentials.ApiHits' | transloco }}:</span>\n <span class=\"fw-bold\">{{ user.api_keys.api_hits | number }}</span>\n }\n @if (user?.api_keys?.api_hits_max !== null) {\n <span class=\"text-muted\">{{ 'User.Subscriptions.APICredentials.ApiHitsMax' | transloco }}:</span>\n <span class=\"fw-bold\">{{ user.api_keys.api_hits_max | number }}</span>\n }\n <!-- Show utilization percentage when both values exist -->\n @if (user?.api_keys?.api_hits !== null && user?.api_keys?.api_hits_max !== null && user?.api_keys?.api_hits_max > 0) {\n <span class=\"text-muted ms-2\">(</span>\n <span class=\"fw-bold\" [ngClass]=\"{\n 'text-success': (user.api_keys.api_hits / user.api_keys.api_hits_max) <= 0.8,\n 'text-warning': (user.api_keys.api_hits / user.api_keys.api_hits_max) > 0.8 && (user.api_keys.api_hits / user.api_keys.api_hits_max) <= 0.9,\n 'text-danger': (user.api_keys.api_hits / user.api_keys.api_hits_max) > 0.9\n }\">\n {{ (user.api_keys.api_hits / user.api_keys.api_hits_max * 100) | number:'1.0-0' }}% consumed\n </span>\n <span class=\"text-muted\">)</span>\n }\n </div>\n </div>\n </div>\n </div>\n </section>\n </div>\n }\n</div>\n<ng-template #content\n let-modal>\n <div class=\"card m-0\">\n <div class=\"card-content\">\n <div class=\"card-title\">\n <h3 class=\"modal-title\">{{ 'User.Profile.ProfilePicture' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n </button>\n </div>\n <div class=\"card-header\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n aspectRatio=\"auto\"\n (imageSelectionEvent)=\"onImageSelection($event)\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [".card .mb-2:last-child,.card .mb-3:last-child{margin-bottom:0!important}.overlay{left:50%;opacity:0;position:absolute;text-align:center;top:50%;transform:translate(-50%,-50%);transition:.5s ease}.image-container{position:relative}.image-container:hover .image{opacity:.3}.image-container:hover .overlay{opacity:0}.overlay-text{background:#f0efef80;border-radius:50%;color:#000;font-size:16px;height:150px;line-height:150px;text-align:center;vertical-align:middle;width:150px}@media screen and (max-width:767px){.card-body{padding:20px!important}}\n"] }]
487
488
  }], ctorParameters: () => [{ type: i2.UntypedFormBuilder }, { type: i1$1.NgbModal }, { type: i1$2.AuthService }, { type: i1$2.GeoService }, { type: i1$2.ProfileService }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }], propDecorators: { placesRef: [{
488
489
  type: ViewChild,
489
490
  args: ['ngxPlaces']
@@ -564,11 +565,11 @@ class AddSubscriptionComponent extends AppBaseComponent {
564
565
  super.ngOnDestroy();
565
566
  }
566
567
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AddSubscriptionComponent, deps: [{ token: i1$2.ProductService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
567
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: AddSubscriptionComponent, isStandalone: false, selector: "pw-add-subscription", usesInheritance: true, ngImport: i0, template: "@if (isLoaded && !selectedProduct) {\n <div\n class=\"mt-4\">\n <a aria-label=\"Navigate to Target\"\n [routerLink]=\"['/account/subscriptions']\"\n class=\"previous float-start\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i>\n </a>\n <div class=\"d-flex flex-wrap justify-content-center\">\n @for (item of subscribedPermissionKeys; track item; let i = $index) {\n <div class=\"toggle\"\n >\n <input type=\"radio\"\n name=\"sizeBy\"\n value=\"option{{ i + 1 }}\"\n id=\"option{{ i + 1 }}\"\n (change)=\"onChangeCategory(item)\"\n [checked]=\"i === 0\" />\n <label for=\"option{{ i + 1 }}\">{{ item }}</label>\n </div>\n }\n </div>\n <ul class=\"row animated fadeIn d-flex\">\n @for (product of availableProducts; track trackByProduct($index, product)) {\n <li\n class=\"col-sm-12 col-md-6 col-xl-4 my-3 mt-sm-2\">\n <div class=\"card\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <h4 class=\"text-bold-500 primary mb-3\">{{ product.name }}</h4>\n @if (product.price_per_unit) {\n @if (product?.purchased_units) {\n <h5\n class=\"my-3 branding-color-1\">\n Currently {{ product.currency | currencySymbol\n }}{{\n (\n (product.purchased_units * product.price_per_unit) /\n 100\n ) | number:'1.2-2'\n }}&nbsp;/&nbsp;{{ product.billing_frequency }}\n </h5>\n }\n <h5 class=\"my-3\">\n Min\n {{product.min_units &gt; 1 ? (product.min_units + ' Seats'): (product.min_units + ' Seat')}}\n - {{ product.currency | currencySymbol\n }}{{\n ((product.min_units * product.price_per_unit) / 100) | number:'1.2-2'\n }}&nbsp;/&nbsp;{{ product.billing_frequency }}\n </h5>\n <h5 class=\"d-inline-block text-bold-600 mb-2\">\n {{ product.currency | currencySymbol\n }}{{ (product.price_per_unit / 100) | number:'1.2-2' }}&nbsp;/&nbsp;{{\n product.billing_frequency\n }}&nbsp;/&nbsp;seat\n </h5>\n } @else {\n <div class=\"d-inline-block text-bold-600 mb-2\">Free</div>\n }\n <p class=\"mb-2\"\n [innerHTML]=\"product?.description\"></p>\n </div>\n <div class=\"card-footer px-3\">\n @if (\n !product.is_subscribed &&\n !product.trial_subscription &&\n product.stripe_plan_id\n ) {\n <a aria-label=\"Navigate to Target\"\n (click)=\"onSelection(product)\"\n class=\"card-btn btn btn-raised me-1 btn-primary btn-sm\">\n {{ 'User.Subscriptions.Subscribe' | transloco }}\n </a>\n }\n @if (\n !product.is_subscribed &&\n product.trial_subscription &&\n product.stripe_plan_id\n ) {\n <div class=\"mt-3\"\n >\n <a aria-label=\"Navigate to Target\"\n (click)=\"onSelection(product)\"\n class=\"card-btn btn btn-raised me-1 btn-primary btn-sm\">\n {{ 'Button.Upgrade' | transloco }}\n </a>\n <span class=\"badge bg-secondary position-absolute trial-badge\">{{ 'User.Subscriptions.Trial' | transloco }}\n </span>\n </div>\n }\n @if (\n product.is_subscribed &&\n !product.trial_subscription &&\n !product.is_deleted\n ) {\n <span\n class=\"card-btn badge bg-default text-white\">\n {{ 'User.Subscriptions.Subscribed' | transloco }}\n </span>\n }\n @if (\n product.is_subscribed &&\n product.trial_subscription &&\n product.price_per_unit === 0 &&\n !product.is_deleted &&\n !product.stripe_plan_id\n ) {\n <span\n class=\"card-btn badge bg-default text-white\">\n Free\n </span>\n }\n @if (product.is_deleted) {\n <span\n class=\"card-btn badge bg-default text-white\">\n {{ 'User.Subscriptions.UnsubscribedButActive' | transloco }}\n </span>\n }\n </div>\n </div>\n </div>\n </li>\n }\n </ul>\n <div class=\"row\">\n <div class=\"col-12\">\n @if (availableProducts && availableProducts.length === 0) {\n <pw-no-data [withImage]=\"true\" message=\"No products available under this category.\"\n >\n </pw-no-data>\n }\n </div>\n </div>\n </div>\n}\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.card .card-body{position:relative}.card .card-body .bottom-text{bottom:15px;left:20px;position:absolute}.card .card-body .card-btn{bottom:15px;position:absolute}.card.shadow-md{height:100%}.card .primary{text-transform:uppercase}.trial-badge{bottom:15px;left:20px}.toggle{align-items:stretch;box-sizing:border-box;display:flex;flex-flow:row nowrap;font-size:0;justify-content:flex-start;margin:0}.toggle input{height:0;left:-9999px;position:absolute;width:0}.toggle input+label{background-color:#fff;border:solid 1px rgb(221,221,221);box-shadow:0 0 #fff0;box-sizing:border-box;display:inline-block;font-size:1rem;font-weight:600;line-height:140%;margin:0;padding:.75rem 2rem;position:relative;text-align:center;transition:border-color .15s ease-out,color .25s ease-out,background-color .15s ease-out,box-shadow .15s ease-out}.toggle input:hover+label{border-color:#213140}.toggle input:checked+label{background-color:var(--tabs_bg);border-color:var(--tabs_bg);box-shadow:0 0 10px #66b3fb80;color:var(--tabs_text);z-index:1}.shadow-md{height:100%;padding-bottom:50px!important}.fadeIn{animation-name:fadeIn}.animated{animation-duration:2s;animation-fill-mode:both}.card-btn{bottom:15px;position:absolute;right:20px}.card-footer{height:60px}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@media(max-width:800px){.toggle{justify-content:center}.toggle input+label{align-items:center;display:flex;flex:0 0 70%;justify-content:center;padding:.75rem .25rem}}.branding-color-1{color:var(--first)!important}\n"], dependencies: [{ kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i5.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i6.DecimalPipe, name: "number" }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i6$3.CurrencySymbolPipe, name: "currencySymbol" }] }); }
568
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: AddSubscriptionComponent, isStandalone: false, selector: "pw-add-subscription", usesInheritance: true, ngImport: i0, template: "@if (isLoaded && !selectedProduct) {\n <div\n class=\"mt-4\">\n <div class=\"d-flex align-items-start category-tabs-row\">\n <a aria-label=\"Navigate to Target\"\n [routerLink]=\"['/account/subscriptions']\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i>\n </a>\n <div class=\"d-flex category-tabs\">\n @for (item of subscribedPermissionKeys; track item; let i = $index) {\n <div class=\"toggle\"\n >\n <input type=\"radio\"\n name=\"sizeBy\"\n value=\"option{{ i + 1 }}\"\n id=\"option{{ i + 1 }}\"\n (change)=\"onChangeCategory(item)\"\n [checked]=\"i === 0\" />\n <label for=\"option{{ i + 1 }}\">{{ item }}</label>\n </div>\n }\n </div>\n </div>\n <ul class=\"row animated fadeIn d-flex\">\n @for (product of availableProducts; track trackByProduct($index, product)) {\n <li\n class=\"col-sm-12 col-md-6 col-xl-4 my-3 mt-sm-2\">\n <div class=\"card\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <h4 class=\"text-bold-500 primary mb-3\">{{ product.name }}</h4>\n @if (product.price_per_unit) {\n @if (product?.purchased_units) {\n <h5\n class=\"my-3 branding-color-1\">\n Currently {{ product.currency | currencySymbol\n }}{{\n (\n (product.purchased_units * product.price_per_unit) /\n 100\n ) | number:'1.2-2'\n }}&nbsp;/&nbsp;{{ product.billing_frequency }}\n </h5>\n }\n <h5 class=\"my-3\">\n Min\n {{product.min_units &gt; 1 ? (product.min_units + ' Seats'): (product.min_units + ' Seat')}}\n - {{ product.currency | currencySymbol\n }}{{\n ((product.min_units * product.price_per_unit) / 100) | number:'1.2-2'\n }}&nbsp;/&nbsp;{{ product.billing_frequency }}\n </h5>\n <h5 class=\"d-inline-block text-bold-600 mb-2\">\n {{ product.currency | currencySymbol\n }}{{ (product.price_per_unit / 100) | number:'1.2-2' }}&nbsp;/&nbsp;{{\n product.billing_frequency\n }}&nbsp;/&nbsp;seat\n </h5>\n } @else {\n <div class=\"d-inline-block text-bold-600 mb-2\">Free</div>\n }\n <p class=\"mb-2\"\n [innerHTML]=\"product?.description\"></p>\n </div>\n <div class=\"card-footer px-3\">\n @if (\n !product.is_subscribed &&\n !product.trial_subscription &&\n product.stripe_plan_id\n ) {\n <a aria-label=\"Navigate to Target\"\n (click)=\"onSelection(product)\"\n class=\"card-btn btn btn-raised me-1 btn-primary btn-sm\">\n {{ 'User.Subscriptions.Subscribe' | transloco }}\n </a>\n }\n @if (\n !product.is_subscribed &&\n product.trial_subscription &&\n product.stripe_plan_id\n ) {\n <div class=\"mt-3\"\n >\n <a aria-label=\"Navigate to Target\"\n (click)=\"onSelection(product)\"\n class=\"card-btn btn btn-raised me-1 btn-primary btn-sm\">\n {{ 'Button.Upgrade' | transloco }}\n </a>\n <span class=\"badge bg-secondary position-absolute trial-badge\">{{ 'User.Subscriptions.Trial' | transloco }}\n </span>\n </div>\n }\n @if (\n product.is_subscribed &&\n !product.trial_subscription &&\n !product.is_deleted\n ) {\n <span\n class=\"card-btn badge bg-default text-white\">\n {{ 'User.Subscriptions.Subscribed' | transloco }}\n </span>\n }\n @if (\n product.is_subscribed &&\n product.trial_subscription &&\n product.price_per_unit === 0 &&\n !product.is_deleted &&\n !product.stripe_plan_id\n ) {\n <span\n class=\"card-btn badge bg-default text-white\">\n Free\n </span>\n }\n @if (product.is_deleted) {\n <span\n class=\"card-btn badge bg-default text-white\">\n {{ 'User.Subscriptions.UnsubscribedButActive' | transloco }}\n </span>\n }\n </div>\n </div>\n </div>\n </li>\n }\n </ul>\n <div class=\"row\">\n <div class=\"col-12\">\n @if (availableProducts && availableProducts.length === 0) {\n <pw-no-data [withImage]=\"true\" message=\"No products available under this category.\"\n >\n </pw-no-data>\n }\n </div>\n </div>\n </div>\n}\n", styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.card .card-body{position:relative}.card .card-body .bottom-text{bottom:15px;left:20px;position:absolute}.card .card-body .card-btn{bottom:15px;position:absolute}.card.shadow-md{height:100%}.card .primary{text-transform:uppercase}.trial-badge{bottom:15px;left:20px}.category-tabs{flex-wrap:nowrap;justify-content:safe center;max-width:100%;min-width:0;overflow-x:auto;scrollbar-width:thin}.category-tabs .toggle{flex:0 0 auto}.category-tabs .toggle input+label{white-space:nowrap}.category-tabs-row .previous i{top:0}.toggle{align-items:stretch;box-sizing:border-box;display:flex;flex-flow:row nowrap;font-size:0;justify-content:flex-start;margin:0}.toggle input{height:0;left:-9999px;position:absolute;width:0}.toggle input+label{background-color:#fff;border:solid 1px rgb(221,221,221);box-shadow:0 0 #fff0;box-sizing:border-box;display:inline-block;font-size:1rem;font-weight:600;line-height:140%;margin:0;padding:.75rem 2rem;position:relative;text-align:center;transition:border-color .15s ease-out,color .25s ease-out,background-color .15s ease-out,box-shadow .15s ease-out}.toggle input:hover+label{border-color:#213140}.toggle input:checked+label{background-color:var(--tabs_bg);border-color:var(--tabs_bg);box-shadow:0 0 10px #66b3fb80;color:var(--tabs_text);z-index:1}.toggle:first-of-type input+label{border-radius:4px 0 0 4px}.toggle:last-of-type input+label{border-radius:0 4px 4px 0}.toggle:first-of-type:last-of-type input+label{border-radius:4px}.shadow-md{height:100%;padding-bottom:50px!important}.fadeIn{animation-name:fadeIn}.animated{animation-duration:2s;animation-fill-mode:both}.card-btn{bottom:15px;position:absolute;right:20px}.card-footer{height:60px}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@media(max-width:800px){.toggle input+label{padding:.75rem 1rem}}.branding-color-1{color:var(--first)!important}\n"], dependencies: [{ kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i5.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i6.DecimalPipe, name: "number" }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i6$3.CurrencySymbolPipe, name: "currencySymbol" }] }); }
568
569
  }
569
570
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AddSubscriptionComponent, decorators: [{
570
571
  type: Component,
571
- args: [{ selector: 'pw-add-subscription', standalone: false, template: "@if (isLoaded && !selectedProduct) {\n <div\n class=\"mt-4\">\n <a aria-label=\"Navigate to Target\"\n [routerLink]=\"['/account/subscriptions']\"\n class=\"previous float-start\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i>\n </a>\n <div class=\"d-flex flex-wrap justify-content-center\">\n @for (item of subscribedPermissionKeys; track item; let i = $index) {\n <div class=\"toggle\"\n >\n <input type=\"radio\"\n name=\"sizeBy\"\n value=\"option{{ i + 1 }}\"\n id=\"option{{ i + 1 }}\"\n (change)=\"onChangeCategory(item)\"\n [checked]=\"i === 0\" />\n <label for=\"option{{ i + 1 }}\">{{ item }}</label>\n </div>\n }\n </div>\n <ul class=\"row animated fadeIn d-flex\">\n @for (product of availableProducts; track trackByProduct($index, product)) {\n <li\n class=\"col-sm-12 col-md-6 col-xl-4 my-3 mt-sm-2\">\n <div class=\"card\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <h4 class=\"text-bold-500 primary mb-3\">{{ product.name }}</h4>\n @if (product.price_per_unit) {\n @if (product?.purchased_units) {\n <h5\n class=\"my-3 branding-color-1\">\n Currently {{ product.currency | currencySymbol\n }}{{\n (\n (product.purchased_units * product.price_per_unit) /\n 100\n ) | number:'1.2-2'\n }}&nbsp;/&nbsp;{{ product.billing_frequency }}\n </h5>\n }\n <h5 class=\"my-3\">\n Min\n {{product.min_units &gt; 1 ? (product.min_units + ' Seats'): (product.min_units + ' Seat')}}\n - {{ product.currency | currencySymbol\n }}{{\n ((product.min_units * product.price_per_unit) / 100) | number:'1.2-2'\n }}&nbsp;/&nbsp;{{ product.billing_frequency }}\n </h5>\n <h5 class=\"d-inline-block text-bold-600 mb-2\">\n {{ product.currency | currencySymbol\n }}{{ (product.price_per_unit / 100) | number:'1.2-2' }}&nbsp;/&nbsp;{{\n product.billing_frequency\n }}&nbsp;/&nbsp;seat\n </h5>\n } @else {\n <div class=\"d-inline-block text-bold-600 mb-2\">Free</div>\n }\n <p class=\"mb-2\"\n [innerHTML]=\"product?.description\"></p>\n </div>\n <div class=\"card-footer px-3\">\n @if (\n !product.is_subscribed &&\n !product.trial_subscription &&\n product.stripe_plan_id\n ) {\n <a aria-label=\"Navigate to Target\"\n (click)=\"onSelection(product)\"\n class=\"card-btn btn btn-raised me-1 btn-primary btn-sm\">\n {{ 'User.Subscriptions.Subscribe' | transloco }}\n </a>\n }\n @if (\n !product.is_subscribed &&\n product.trial_subscription &&\n product.stripe_plan_id\n ) {\n <div class=\"mt-3\"\n >\n <a aria-label=\"Navigate to Target\"\n (click)=\"onSelection(product)\"\n class=\"card-btn btn btn-raised me-1 btn-primary btn-sm\">\n {{ 'Button.Upgrade' | transloco }}\n </a>\n <span class=\"badge bg-secondary position-absolute trial-badge\">{{ 'User.Subscriptions.Trial' | transloco }}\n </span>\n </div>\n }\n @if (\n product.is_subscribed &&\n !product.trial_subscription &&\n !product.is_deleted\n ) {\n <span\n class=\"card-btn badge bg-default text-white\">\n {{ 'User.Subscriptions.Subscribed' | transloco }}\n </span>\n }\n @if (\n product.is_subscribed &&\n product.trial_subscription &&\n product.price_per_unit === 0 &&\n !product.is_deleted &&\n !product.stripe_plan_id\n ) {\n <span\n class=\"card-btn badge bg-default text-white\">\n Free\n </span>\n }\n @if (product.is_deleted) {\n <span\n class=\"card-btn badge bg-default text-white\">\n {{ 'User.Subscriptions.UnsubscribedButActive' | transloco }}\n </span>\n }\n </div>\n </div>\n </div>\n </li>\n }\n </ul>\n <div class=\"row\">\n <div class=\"col-12\">\n @if (availableProducts && availableProducts.length === 0) {\n <pw-no-data [withImage]=\"true\" message=\"No products available under this category.\"\n >\n </pw-no-data>\n }\n </div>\n </div>\n </div>\n}\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.card .card-body{position:relative}.card .card-body .bottom-text{bottom:15px;left:20px;position:absolute}.card .card-body .card-btn{bottom:15px;position:absolute}.card.shadow-md{height:100%}.card .primary{text-transform:uppercase}.trial-badge{bottom:15px;left:20px}.toggle{align-items:stretch;box-sizing:border-box;display:flex;flex-flow:row nowrap;font-size:0;justify-content:flex-start;margin:0}.toggle input{height:0;left:-9999px;position:absolute;width:0}.toggle input+label{background-color:#fff;border:solid 1px rgb(221,221,221);box-shadow:0 0 #fff0;box-sizing:border-box;display:inline-block;font-size:1rem;font-weight:600;line-height:140%;margin:0;padding:.75rem 2rem;position:relative;text-align:center;transition:border-color .15s ease-out,color .25s ease-out,background-color .15s ease-out,box-shadow .15s ease-out}.toggle input:hover+label{border-color:#213140}.toggle input:checked+label{background-color:var(--tabs_bg);border-color:var(--tabs_bg);box-shadow:0 0 10px #66b3fb80;color:var(--tabs_text);z-index:1}.shadow-md{height:100%;padding-bottom:50px!important}.fadeIn{animation-name:fadeIn}.animated{animation-duration:2s;animation-fill-mode:both}.card-btn{bottom:15px;position:absolute;right:20px}.card-footer{height:60px}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@media(max-width:800px){.toggle{justify-content:center}.toggle input+label{align-items:center;display:flex;flex:0 0 70%;justify-content:center;padding:.75rem .25rem}}.branding-color-1{color:var(--first)!important}\n"] }]
572
+ args: [{ selector: 'pw-add-subscription', standalone: false, template: "@if (isLoaded && !selectedProduct) {\n <div\n class=\"mt-4\">\n <div class=\"d-flex align-items-start category-tabs-row\">\n <a aria-label=\"Navigate to Target\"\n [routerLink]=\"['/account/subscriptions']\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i>\n </a>\n <div class=\"d-flex category-tabs\">\n @for (item of subscribedPermissionKeys; track item; let i = $index) {\n <div class=\"toggle\"\n >\n <input type=\"radio\"\n name=\"sizeBy\"\n value=\"option{{ i + 1 }}\"\n id=\"option{{ i + 1 }}\"\n (change)=\"onChangeCategory(item)\"\n [checked]=\"i === 0\" />\n <label for=\"option{{ i + 1 }}\">{{ item }}</label>\n </div>\n }\n </div>\n </div>\n <ul class=\"row animated fadeIn d-flex\">\n @for (product of availableProducts; track trackByProduct($index, product)) {\n <li\n class=\"col-sm-12 col-md-6 col-xl-4 my-3 mt-sm-2\">\n <div class=\"card\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <h4 class=\"text-bold-500 primary mb-3\">{{ product.name }}</h4>\n @if (product.price_per_unit) {\n @if (product?.purchased_units) {\n <h5\n class=\"my-3 branding-color-1\">\n Currently {{ product.currency | currencySymbol\n }}{{\n (\n (product.purchased_units * product.price_per_unit) /\n 100\n ) | number:'1.2-2'\n }}&nbsp;/&nbsp;{{ product.billing_frequency }}\n </h5>\n }\n <h5 class=\"my-3\">\n Min\n {{product.min_units &gt; 1 ? (product.min_units + ' Seats'): (product.min_units + ' Seat')}}\n - {{ product.currency | currencySymbol\n }}{{\n ((product.min_units * product.price_per_unit) / 100) | number:'1.2-2'\n }}&nbsp;/&nbsp;{{ product.billing_frequency }}\n </h5>\n <h5 class=\"d-inline-block text-bold-600 mb-2\">\n {{ product.currency | currencySymbol\n }}{{ (product.price_per_unit / 100) | number:'1.2-2' }}&nbsp;/&nbsp;{{\n product.billing_frequency\n }}&nbsp;/&nbsp;seat\n </h5>\n } @else {\n <div class=\"d-inline-block text-bold-600 mb-2\">Free</div>\n }\n <p class=\"mb-2\"\n [innerHTML]=\"product?.description\"></p>\n </div>\n <div class=\"card-footer px-3\">\n @if (\n !product.is_subscribed &&\n !product.trial_subscription &&\n product.stripe_plan_id\n ) {\n <a aria-label=\"Navigate to Target\"\n (click)=\"onSelection(product)\"\n class=\"card-btn btn btn-raised me-1 btn-primary btn-sm\">\n {{ 'User.Subscriptions.Subscribe' | transloco }}\n </a>\n }\n @if (\n !product.is_subscribed &&\n product.trial_subscription &&\n product.stripe_plan_id\n ) {\n <div class=\"mt-3\"\n >\n <a aria-label=\"Navigate to Target\"\n (click)=\"onSelection(product)\"\n class=\"card-btn btn btn-raised me-1 btn-primary btn-sm\">\n {{ 'Button.Upgrade' | transloco }}\n </a>\n <span class=\"badge bg-secondary position-absolute trial-badge\">{{ 'User.Subscriptions.Trial' | transloco }}\n </span>\n </div>\n }\n @if (\n product.is_subscribed &&\n !product.trial_subscription &&\n !product.is_deleted\n ) {\n <span\n class=\"card-btn badge bg-default text-white\">\n {{ 'User.Subscriptions.Subscribed' | transloco }}\n </span>\n }\n @if (\n product.is_subscribed &&\n product.trial_subscription &&\n product.price_per_unit === 0 &&\n !product.is_deleted &&\n !product.stripe_plan_id\n ) {\n <span\n class=\"card-btn badge bg-default text-white\">\n Free\n </span>\n }\n @if (product.is_deleted) {\n <span\n class=\"card-btn badge bg-default text-white\">\n {{ 'User.Subscriptions.UnsubscribedButActive' | transloco }}\n </span>\n }\n </div>\n </div>\n </div>\n </li>\n }\n </ul>\n <div class=\"row\">\n <div class=\"col-12\">\n @if (availableProducts && availableProducts.length === 0) {\n <pw-no-data [withImage]=\"true\" message=\"No products available under this category.\"\n >\n </pw-no-data>\n }\n </div>\n </div>\n </div>\n}\n", styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.card .card-body{position:relative}.card .card-body .bottom-text{bottom:15px;left:20px;position:absolute}.card .card-body .card-btn{bottom:15px;position:absolute}.card.shadow-md{height:100%}.card .primary{text-transform:uppercase}.trial-badge{bottom:15px;left:20px}.category-tabs{flex-wrap:nowrap;justify-content:safe center;max-width:100%;min-width:0;overflow-x:auto;scrollbar-width:thin}.category-tabs .toggle{flex:0 0 auto}.category-tabs .toggle input+label{white-space:nowrap}.category-tabs-row .previous i{top:0}.toggle{align-items:stretch;box-sizing:border-box;display:flex;flex-flow:row nowrap;font-size:0;justify-content:flex-start;margin:0}.toggle input{height:0;left:-9999px;position:absolute;width:0}.toggle input+label{background-color:#fff;border:solid 1px rgb(221,221,221);box-shadow:0 0 #fff0;box-sizing:border-box;display:inline-block;font-size:1rem;font-weight:600;line-height:140%;margin:0;padding:.75rem 2rem;position:relative;text-align:center;transition:border-color .15s ease-out,color .25s ease-out,background-color .15s ease-out,box-shadow .15s ease-out}.toggle input:hover+label{border-color:#213140}.toggle input:checked+label{background-color:var(--tabs_bg);border-color:var(--tabs_bg);box-shadow:0 0 10px #66b3fb80;color:var(--tabs_text);z-index:1}.toggle:first-of-type input+label{border-radius:4px 0 0 4px}.toggle:last-of-type input+label{border-radius:0 4px 4px 0}.toggle:first-of-type:last-of-type input+label{border-radius:4px}.shadow-md{height:100%;padding-bottom:50px!important}.fadeIn{animation-name:fadeIn}.animated{animation-duration:2s;animation-fill-mode:both}.card-btn{bottom:15px;position:absolute;right:20px}.card-footer{height:60px}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@media(max-width:800px){.toggle input+label{padding:.75rem 1rem}}.branding-color-1{color:var(--first)!important}\n"] }]
572
573
  }], ctorParameters: () => [{ type: i1$2.ProductService }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }] });
573
574
 
574
575
  /**
@@ -708,7 +709,7 @@ class SubscriptionCredentialComponent extends AppBaseComponent {
708
709
  const isValid = this.form.value.credentials.every((_x, i) => this.credentialsGroup.controls[i].valid === true);
709
710
  if (isValid) {
710
711
  this.form.value.credentials.forEach(credential => {
711
- if (credential?.value) {
712
+ if (credential?.value && !String(credential.value).startsWith('***')) {
712
713
  const data = {
713
714
  subscription_id: this.subscriptionId,
714
715
  credential_id: credential.credential_id,
@@ -1028,7 +1029,7 @@ class UpdatePaymentDetailsComponent extends AppBaseComponent {
1028
1029
  this.cdr.markForCheck();
1029
1030
  }
1030
1031
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UpdatePaymentDetailsComponent, deps: [{ token: i2.UntypedFormBuilder }, { token: i1$2.ScriptLoaderService }, { token: i1$2.ProductService }, { token: i1$2.SubscriptionService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1031
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: UpdatePaymentDetailsComponent, isStandalone: false, selector: "pw-update-payment-details", viewQueries: [{ propertyName: "braintreeContainer", first: true, predicate: ["braintreeContainer"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"container-fluid\">\n <div class=\"card-block\">\n <div class=\"row\">\n <div class=\"col-lg-12 ps-0\">\n <a aria-label=\"Navigate to Target\"\n (click)=\"back()\"\n class=\"previous float-start\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h4 class=\"form-section my-3\">\n <i class=\"ft-edit\" aria-hidden=\"true\"></i>\n {{ 'User.Payments.UpdateTitle' | transloco }}\n </h4>\n </div>\n </div>\n\n <div class=\"row g-3 mt-1\">\n <!-- Primary payment method (Stripe) -->\n <div class=\"col-12 col-lg-6\">\n <div class=\"card payment-left p-3 h-100\">\n <div class=\"card-body\">\n <h5 class=\"section-title\">{{ 'User.Payments.Primary.Title' | transloco }}</h5>\n <p class=\"text-muted\">{{ 'User.Payments.Primary.Description' | transloco }}</p>\n\n @if (errorMsg) {\n <div class=\"alert alert-danger\">{{ errorMsg }}</div>\n }\n @if (!isChangePayment && cardDetails) {\n <pw-saved-card-details [data]=\"cardDetails\"\n (changeEvent)=\"onChange($event)\">\n </pw-saved-card-details>\n }\n\n @if (loading) {\n <div class=\"text-center\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n\n @if ((!cardDetails && !loading) || isChangePayment) {\n <form [formGroup]=\"form\" (ngSubmit)=\"onSave()\">\n <h4 class=\"title\">{{ 'User.Payments.Primary.NewCard' | transloco }}</h4>\n <div class=\"row\">\n <div class=\"col-md-9\">\n <div class=\"mb-3\">\n <label for=\"update-payment-card_number\">{{ 'User.Payments.CardNumber' | transloco }}</label>\n <input type=\"text\"\n id=\"update-payment-card_number\"\n class=\"form-control\"\n formControlName=\"card_number\"\n [placeholder]=\"'User.Payments.CardNumber' | transloco\"\n name=\"card_number\" />\n @if (form.get('card_number').touched && form.get('card_number').errors?.required) {\n <div class=\"danger\"><span>{{ 'User.Payments.Errors.CardNumberRequired' | transloco }}</span></div>\n }\n </div>\n </div>\n <div class=\"col-md-3\">\n <div class=\"mb-3\">\n <label for=\"update-payment-cvc\">{{ 'User.Payments.Cvc' | transloco }}</label>\n <input type=\"text\"\n id=\"update-payment-cvc\"\n class=\"form-control\"\n formControlName=\"cvc\"\n [placeholder]=\"'User.Payments.Cvc' | transloco\"\n name=\"cvc\" />\n @if (form.get('cvc').touched && form.get('cvc').errors?.required) {\n <div class=\"danger\"><span>{{ 'User.Payments.Errors.CvcRequired' | transloco }}</span></div>\n }\n </div>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-md-6\">\n <div class=\"mb-3\">\n <span class=\"sr-only\" id=\"update-payment-exp_month-label\" class=\"pw-label-style\">{{ 'User.Payments.ExpMonth' | transloco }}</span>\n <p-select\n [attr.aria-labelledby]=\"'update-payment-exp_month-label'\"\n [options]=\"months\"\n [appendTo]=\"'body'\"\n formControlName=\"exp_month\"\n [placeholder]=\"'User.Payments.ExpMonth' | transloco\"\n optionValue=\"value\"\n optionLabel=\"value\">\n </p-select>\n @if (form.get('exp_month').touched && form.get('exp_month').errors?.required) {\n <div class=\"danger\"><span>{{ 'User.Payments.Errors.ExpMonthRequired' | transloco }}</span></div>\n }\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"mb-3\">\n <span class=\"sr-only\" id=\"update-payment-exp_year-label\">{{ 'User.Payments.ExpYear' | transloco }}</span>\n <p-select\n [attr.aria-labelledby]=\"'update-payment-exp_year-label'\"\n [options]=\"years\"\n formControlName=\"exp_year\"\n [placeholder]=\"'User.Payments.ExpYear' | transloco\"\n optionValue=\"value\"\n [appendTo]=\"'body'\"\n optionLabel=\"value\">\n </p-select>\n @if (form.get('exp_year')?.touched && form.get('exp_year')?.errors?.['required']) {\n <div class=\"danger\"><span>{{ 'User.Payments.Errors.ExpYearRequired' | transloco }}</span></div>\n }\n </div>\n </div>\n <div class=\"col-12 text-center mt-4\">\n <img src=\"/assets/img/icons/powered_by_stripe_v2.png\"\n class=\"payment-provider\"\n alt=\"\" />\n </div>\n <div class=\"col-12 mt-4 text-end\">\n <button type=\"button\"\n (click)=\"cancel()\"\n class=\"btn btn-outline-default me-2\">\n {{ 'User.Payments.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n class=\"btn btn-primary\"\n [buttonBusy]=\"busy\">\n {{ 'User.Payments.Submit' | transloco }}\n </button>\n </div>\n </div>\n </form>\n }\n </div>\n </div>\n </div>\n\n <!-- Secondary payment method (Braintree) -->\n <div class=\"col-12 col-lg-6\">\n <div class=\"card payment-right p-3 h-100\">\n <div class=\"card-body\">\n <h5 class=\"section-title\">{{ 'User.Payments.Secondary.Title' | transloco }}</h5>\n <p class=\"alert alert-info\" [pTooltip]=\"'User.Payments.Secondary.Tooltip' | transloco\" tooltipPosition=\"top\" appendTo=\"body\">\n {{ 'User.Payments.Secondary.Callout' | transloco }}\n </p>\n\n @if (loading) {\n <div class=\"text-center\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n\n @if (secondaryCard && !showBraintreeForm) {\n <pw-saved-card-details [data]=\"secondaryCard\"\n (changeEvent)=\"startBraintreeFlow()\">\n </pw-saved-card-details>\n }\n\n @if (!secondaryCard && !showBraintreeForm && !loading) {\n <button type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"startBraintreeFlow()\">\n {{ 'User.Payments.Secondary.AddCta' | transloco }}\n </button>\n }\n\n @if (showBraintreeForm) {\n <div #braintreeContainer class=\"braintree-dropin-container mt-3\"></div>\n <div class=\"col-12 mt-4 text-end\">\n <button type=\"button\"\n (click)=\"cancelBraintreeFlow()\"\n class=\"btn btn-outline-default me-2\">\n {{ 'User.Payments.Cancel' | transloco }}\n </button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n [buttonBusy]=\"braintreeBusy\"\n (click)=\"submitBraintree()\">\n {{ 'User.Payments.Submit' | transloco }}\n </button>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n\n </div>\n</div>\n", styles: [".card-block .payment-left,.card-block .payment-right{border:1px solid rgb(204,204,204)}.card-block .payment-left h4,.card-block .payment-right h4{border-bottom:1px solid rgb(0,0,0);font-size:1rem;font-weight:600;margin:0 0 20px;padding:0 0 5px;text-transform:uppercase}.payment-provider{width:30%}@media(max-width:800px){.payment-provider{width:60%}}\n"], dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { 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: i6$2.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i6$4.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: SavedCardDetailsComponent, selector: "pw-saved-card-details", inputs: ["data", "isChangePayment", "showNewCard"], outputs: ["changeEvent"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
1032
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: UpdatePaymentDetailsComponent, isStandalone: false, selector: "pw-update-payment-details", viewQueries: [{ propertyName: "braintreeContainer", first: true, predicate: ["braintreeContainer"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"container-fluid\">\n <div class=\"card-block\">\n <div class=\"row\">\n <div class=\"col-lg-12 ps-0\">\n <a aria-label=\"Navigate to Target\"\n (click)=\"back()\"\n class=\"previous float-start\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h4 class=\"form-section my-3\">\n <i class=\"ft-edit\" aria-hidden=\"true\"></i>\n {{ 'User.Payments.UpdateTitle' | transloco }}\n </h4>\n </div>\n </div>\n\n <div class=\"row g-3 mt-1\">\n <!-- Primary payment method (Stripe) -->\n <div class=\"col-12 col-lg-6\">\n <div class=\"card payment-left p-3 h-100\">\n <div class=\"card-body\">\n <h5 class=\"section-title\">{{ 'User.Payments.Primary.Title' | transloco }}</h5>\n <p class=\"text-muted\">{{ 'User.Payments.Primary.Description' | transloco }}</p>\n\n @if (errorMsg) {\n <div class=\"alert alert-danger\">{{ errorMsg }}</div>\n }\n @if (!isChangePayment && cardDetails) {\n <pw-saved-card-details [data]=\"cardDetails\"\n (changeEvent)=\"onChange($event)\">\n </pw-saved-card-details>\n }\n\n @if (loading) {\n <div class=\"text-center\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n\n @if ((!cardDetails && !loading) || isChangePayment) {\n <form [formGroup]=\"form\" (ngSubmit)=\"onSave()\">\n <h4 class=\"title\">{{ 'User.Payments.Primary.NewCard' | transloco }}</h4>\n <div class=\"row\">\n <div class=\"col-md-9\">\n <div class=\"mb-3\">\n <label for=\"update-payment-card_number\">{{ 'User.Payments.CardNumber' | transloco }}</label>\n <input type=\"text\"\n id=\"update-payment-card_number\"\n class=\"form-control\"\n formControlName=\"card_number\"\n [placeholder]=\"'User.Payments.CardNumber' | transloco\"\n name=\"card_number\" />\n @if (form.get('card_number').touched && form.get('card_number').errors?.required) {\n <div class=\"danger\"><span>{{ 'User.Payments.Errors.CardNumberRequired' | transloco }}</span></div>\n }\n </div>\n </div>\n <div class=\"col-md-3\">\n <div class=\"mb-3\">\n <label for=\"update-payment-cvc\">{{ 'User.Payments.Cvc' | transloco }}</label>\n <input type=\"text\"\n id=\"update-payment-cvc\"\n class=\"form-control\"\n formControlName=\"cvc\"\n [placeholder]=\"'User.Payments.Cvc' | transloco\"\n name=\"cvc\" />\n @if (form.get('cvc').touched && form.get('cvc').errors?.required) {\n <div class=\"danger\"><span>{{ 'User.Payments.Errors.CvcRequired' | transloco }}</span></div>\n }\n </div>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-md-6\">\n <div class=\"mb-3\">\n <span class=\"sr-only\" id=\"update-payment-exp_month-label\" class=\"pw-label-style\">{{ 'User.Payments.ExpMonth' | transloco }}</span>\n <p-select\n [attr.aria-labelledby]=\"'update-payment-exp_month-label'\"\n [options]=\"months\"\n [appendTo]=\"'body'\"\n formControlName=\"exp_month\"\n [placeholder]=\"'User.Payments.ExpMonth' | transloco\"\n optionValue=\"value\"\n optionLabel=\"value\">\n </p-select>\n @if (form.get('exp_month').touched && form.get('exp_month').errors?.required) {\n <div class=\"danger\"><span>{{ 'User.Payments.Errors.ExpMonthRequired' | transloco }}</span></div>\n }\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"mb-3\">\n <span class=\"sr-only\" id=\"update-payment-exp_year-label\">{{ 'User.Payments.ExpYear' | transloco }}</span>\n <p-select\n [attr.aria-labelledby]=\"'update-payment-exp_year-label'\"\n [options]=\"years\"\n formControlName=\"exp_year\"\n [placeholder]=\"'User.Payments.ExpYear' | transloco\"\n optionValue=\"value\"\n [appendTo]=\"'body'\"\n optionLabel=\"value\">\n </p-select>\n @if (form.get('exp_year')?.touched && form.get('exp_year')?.errors?.['required']) {\n <div class=\"danger\"><span>{{ 'User.Payments.Errors.ExpYearRequired' | transloco }}</span></div>\n }\n </div>\n </div>\n <div class=\"col-12 text-center mt-4\">\n <img src=\"/assets/img/icons/powered_by_stripe_v2.png\"\n class=\"payment-provider\"\n alt=\"\" />\n </div>\n <div class=\"col-12 mt-4 text-end\">\n <button type=\"button\"\n (click)=\"cancel()\"\n class=\"btn btn-outline-default me-2\">\n {{ 'User.Payments.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n class=\"btn btn-primary\"\n [buttonBusy]=\"busy\">\n {{ 'User.Payments.Submit' | transloco }}\n </button>\n </div>\n </div>\n </form>\n }\n </div>\n </div>\n </div>\n\n <!-- Secondary payment method (Braintree) -->\n <div class=\"col-12 col-lg-6\">\n <div class=\"card payment-right p-3 h-100\">\n <div class=\"card-body\">\n <h5 class=\"section-title\">{{ 'User.Payments.Secondary.Title' | transloco }}</h5>\n <p class=\"alert alert-info\" [pTooltip]=\"'User.Payments.Secondary.Tooltip' | transloco\" tooltipPosition=\"top\" appendTo=\"body\">\n {{ 'User.Payments.Secondary.Callout' | transloco }}\n </p>\n\n @if (loading) {\n <div class=\"text-center\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n\n @if (secondaryCard && !showBraintreeForm) {\n <pw-saved-card-details [data]=\"secondaryCard\"\n (changeEvent)=\"startBraintreeFlow()\">\n </pw-saved-card-details>\n }\n\n @if (!secondaryCard && !showBraintreeForm && !loading) {\n <button type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"startBraintreeFlow()\">\n {{ 'User.Payments.Secondary.AddCta' | transloco }}\n </button>\n }\n\n @if (showBraintreeForm) {\n <div #braintreeContainer class=\"braintree-dropin-container mt-3\"></div>\n <div class=\"col-12 mt-4 text-end\">\n <button type=\"button\"\n (click)=\"cancelBraintreeFlow()\"\n class=\"btn btn-outline-default me-2\">\n {{ 'User.Payments.Cancel' | transloco }}\n </button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n [buttonBusy]=\"braintreeBusy\"\n (click)=\"submitBraintree()\">\n {{ 'User.Payments.Submit' | transloco }}\n </button>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n\n </div>\n</div>\n", styles: [".card-block .payment-left,.card-block .payment-right{border:1px solid rgb(204,204,204)}.card-block .payment-left h4,.card-block .payment-right h4{border-bottom:1px solid rgb(0,0,0);font-size:1rem;font-weight:600;margin:0 0 20px;padding:0 0 5px;text-transform:uppercase}.payment-provider{width:30%}@media(max-width:800px){.payment-provider{width:60%}}\n"], dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { 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: i6$2.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i11.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: SavedCardDetailsComponent, selector: "pw-saved-card-details", inputs: ["data", "isChangePayment", "showNewCard"], outputs: ["changeEvent"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
1032
1033
  }
1033
1034
  __decorate([
1034
1035
  ValidateForm('form'),
@@ -1344,6 +1345,8 @@ class UserSubscriptionDetailsComponent extends AppBaseComponent {
1344
1345
  this.cdr = cdr;
1345
1346
  this.busyButton = false;
1346
1347
  this.units = 1;
1348
+ this.fullLogoBroken = false;
1349
+ this.squaredLogoBroken = false;
1347
1350
  this.showApiToken = false;
1348
1351
  this.showApiClientId = false;
1349
1352
  this.refreshingTokens = false;
@@ -1375,6 +1378,8 @@ class UserSubscriptionDetailsComponent extends AppBaseComponent {
1375
1378
  this.subscription = response;
1376
1379
  this.fullLogo = this.subscription?.full_logo.url;
1377
1380
  this.squaredLogo = this.subscription?.squared_logo?.url;
1381
+ this.fullLogoBroken = false;
1382
+ this.squaredLogoBroken = false;
1378
1383
  this.form.patchValue(this.subscription);
1379
1384
  this.units = this.subscription?.products[0]?.purchased_units;
1380
1385
  this.form.patchValue({
@@ -1438,14 +1443,6 @@ class UserSubscriptionDetailsComponent extends AppBaseComponent {
1438
1443
  openModal(content) {
1439
1444
  this.modalService.open(content, { centered: true, windowClass: 'modal-holder' });
1440
1445
  }
1441
- onImgError(event, fallbackSrc) {
1442
- const img = event.target;
1443
- if (!img)
1444
- return;
1445
- if (img.src && img.src.endsWith(fallbackSrc))
1446
- return;
1447
- img.src = fallbackSrc;
1448
- }
1449
1446
  onImageSelection(event) {
1450
1447
  const blob = this.dataURLtoBlob(event);
1451
1448
  const filename = `${`${this.slug.toLocaleLowerCase()}_${Date.parse(new Date().toString())}`}.png`;
@@ -1453,6 +1450,7 @@ class UserSubscriptionDetailsComponent extends AppBaseComponent {
1453
1450
  this.subscriptionService.addFullLogo(this.subscriptionId, file).subscribe(res => {
1454
1451
  this.modalService.dismissAll();
1455
1452
  this.fullLogo = res?.full_logo?.url;
1453
+ this.fullLogoBroken = false;
1456
1454
  this.cdr.markForCheck();
1457
1455
  });
1458
1456
  }
@@ -1463,6 +1461,7 @@ class UserSubscriptionDetailsComponent extends AppBaseComponent {
1463
1461
  this.subscriptionService.addSquaredLogo(this.subscriptionId, file).subscribe(res => {
1464
1462
  this.modalService.dismissAll();
1465
1463
  this.squaredLogo = res?.squared_logo?.url;
1464
+ this.squaredLogoBroken = false;
1466
1465
  this.cdr.markForCheck();
1467
1466
  });
1468
1467
  }
@@ -1588,7 +1587,7 @@ class UserSubscriptionDetailsComponent extends AppBaseComponent {
1588
1587
  this.allowUpdate = false;
1589
1588
  }
1590
1589
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserSubscriptionDetailsComponent, deps: [{ token: i2.UntypedFormBuilder }, { token: i1$2.GeoService }, { token: i1$1.NgbModal }, { token: i1$2.SubscriptionService }, { token: i4$2.Store }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1591
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: UserSubscriptionDetailsComponent, isStandalone: false, selector: "ng-component", viewQueries: [{ propertyName: "modal", first: true, predicate: ["modal"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<!-- edit Subscription details page -->\n<div class=\"row\">\n <div class=\"col-12\">\n <h3 class=\"my-3\">{{ subscription?.organisation || subscription?.contact_name }}</h3>\n </div>\n</div>\n\n@if (subscription) {\n <div class=\"row\"\n >\n <div class=\"col-md-6\">\n <div class=\"text-center mt-5\">\n <div class=\"image-container\">\n <h4 class=\"mb-2\">Full Logo\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'User.Subscriptions.Tooltip.FullLogo'|transloco\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"'top'\">\n <i class=\"fas fa-info-circle\"></i>\n </span>\n </h4>\n <img [src]=\"fullLogo\"\n alt=\"full logo\"\n width=\"100%\"\n class=\"image full-logo\"\n height=\"100%\"\n role=\"presentation\"\n (error)=\"onImgError($event, 'assets/img/icons/dummy-logo.jpg')\" />\n <div class=\"overlay mt-2\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\">\n <div class=\"overlay-text\">\n <a aria-label=\"Navigate to Target\">{{ 'User.Profile.Change' | transloco }}</a>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"text-center mt-5\">\n <div class=\"image-container\">\n <h4 class=\"mb-2\">Squared Logo\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'User.Subscriptions.Tooltip.SquaredLogo'|transloco\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"'top'\">\n <i class=\"fas fa-info-circle\"></i>\n </span>\n </h4>\n <img [src]=\"squaredLogo\"\n alt=\"Squared Presentation\"\n width=\"150\"\n class=\"squared_logo\"\n [height]=\"'150'\"\n role=\"presentation\"\n (error)=\"onImgError($event, 'assets/img/icons/dummy-icon.jpg')\" />\n <div class=\"overlay mt-2\"\n (keydown.enter)=\"openModal(squaredLogoContent)\"\n (click)=\"openModal(squaredLogoContent)\">\n <div class=\"overlay-text\">\n <a aria-label=\"Navigate to Target\">{{ 'User.Profile.Change' | transloco }}</a>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n}\n<div class=\"row\">\n <div class=\"col-12\">\n @if (subscription?.trial_subscription && subscription?.calculated_price) {\n <small\n class=\"text-danger\">Upgrade to be able to update your purchased seats</small>\n }\n </div>\n</div>\n<div class=\"row btns-row align-items-center\">\n @if (subscription) {\n <div class=\"col-md-3 col-8\"\n >\n <label for=\"user-subscription-seats\" class=\"visually-hidden\">{{ 'User.Subscriptions.Tooltip.Seats' | transloco }}</label>\n <pw-number-picker [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Seats'|transloco\"\n inputId=\"user-subscription-seats\"\n name=\"number-picker\"\n [(value)]=\"units\"\n [min]=\"subscription?.min_units||subscription?.products[0].min_units\"\n [max]=\"subscription?.products[0].max_units\"\n step=\"1\"\n postfix=\"seats\"\n placeholder=\"Total Licences\"\n [inputReadOnly]=\"subscription?.products[0].trial_subscription\"\n [showUpButton]=\"!subscription?.products[0].trial_subscription\"\n [showDownButton]=\"!subscription?.products[0].trial_subscription\"\n size=\"small\"\n pickStartAfter=\"500\"\n pickTimer=\"100\"\n [arrowKeys]=\"true\"\n (minReached)=\"onMinReached($event)\"\n (maxReached)=\"onMaxReached($event)\"\n (valueChange)=\"onUnitChange($event)\">\n </pw-number-picker>\n </div>\n }\n\n @if (subscription) {\n <div class=\"col-md-3 col-4 p-1\"\n >\n @if (!subscription?.products[0].trial_subscription && allowUpdate) {\n <button class=\"btn btn-primary\"\n (click)=\"updateUnits()\">\n {{ 'User.Subscriptions.UpdateUnits' | transloco }}\n </button>\n } @else {\n <div>\n @if (subscription?.products[0].trial_subscription) {\n <small class=\"danger\"\n >Update seats is available only to paid subscriptions</small>\n }\n </div>\n }\n </div>\n }\n\n @if (hasUnitChanged) {\n <div class=\"col-12 col-md-6\"\n >\n <table class=\"table table-borderless table-sm\"\n aria-describedby=\"Product details\">\n <thead>\n <tr>\n <th scope=\"true\">Product</th>\n <th scope=\"true\">Price per seat <span>({{subscription?.products[0]?.currency|currencySymbol}})</span></th>\n <th scope=\"true\">Seats</th>\n </tr>\n </thead>\n <tbody>\n @for (product of subscription.products; track trackByProduct($index, product)) {\n <tr>\n <td>{{ product.name }}</td>\n <td>{{ product.price_per_unit / 100 }}</td>\n <td>{{ units }}</td>\n </tr>\n }\n </tbody>\n </table>\n <p>\n If you proceed, the new cost for your subscription will be\n <strong>{{ totalAmount()| currency: subscription?.products[0]?.currency:'symbol-narrow'}}</strong>\n </p>\n </div>\n }\n</div>\n@if (subscription) {\n <form [formGroup]=\"form\"\n (ngSubmit)=\"onSaveDetails()\"\n class=\"row mt-4\"\n >\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.ContactName' | transloco\"\n class=\"col-md-6\"\n label=\"Contact Name\"\n name=\"contact_name\"\n controlId=\"user-subscription-contact_name\"\n errorMsg=\"Please enter Contact Name\">\n <input type=\"text\"\n id=\"user-subscription-contact_name\"\n class=\"form-control\"\n formControlName=\"contact_name\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.ContactEmail' | transloco\"\n class=\"col-md-6\"\n label=\"Contact Email\"\n name=\"contact_email\"\n controlId=\"user-subscription-contact_email\"\n errorMsg=\"Please enter Contact Email\">\n <input type=\"text\"\n id=\"user-subscription-contact_email\"\n class=\"form-control\"\n formControlName=\"contact_email\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Organization' | transloco\"\n class=\"col-md-6\"\n label=\"Organisation\"\n name=\"organisation\"\n controlId=\"user-subscription-organisation\"\n errorMsg=\"Please enter organisation\">\n <input type=\"text\"\n id=\"user-subscription-organisation\"\n class=\"form-control\"\n formControlName=\"organisation\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Phone' | transloco\"\n class=\"col-md-6\"\n label=\"Contact Tel\"\n name=\"contact_tel\"\n controlId=\"user-subscription-contact_tel\"\n errorMsg=\"Please enter Contact Telephone Number\">\n <input type=\"text\"\n id=\"user-subscription-contact_tel\"\n class=\"form-control\"\n formControlName=\"contact_tel\" />\n </pw-input-container>\n @if (countries$ | async; as countries) {\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Country' | transloco\"\n class=\"col-md-6\"\n label=\"Country\"\n name=\"country_code\"\n controlId=\"user-subscription-country_code\"\n [useAriaLabelledbyOnly]=\"true\"\n [isLeftTooltip]=\"true\"\n errorMsg=\"Please select a country\">\n <p-select\n [attr.aria-labelledby]=\"'user-subscription-country_code-label'\"\n [options]=\"countries\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"country_code\"\n placeholder=\"Select Country\">\n </p-select>\n </pw-input-container>\n }\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Address' | transloco\"\n class=\"col-md-6\"\n label=\"Address\"\n name=\"address\"\n controlId=\"user-subscription-address\"\n [useAriaLabelledbyOnly]=\"true\"\n errorMsg=\"Please enter address\">\n <input ngx-gp-autocomplete\n id=\"user-subscription-address\"\n name=\"address\"\n class=\"form-control\"\n [attr.aria-labelledby]=\"'user-subscription-address-label'\"\n #places=\"ngx-places\"\n formControlName=\"address\"\n (onAddressChange)=\"handleAddressChange($event)\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.VatNumber' | transloco\"\n class=\"col-md-6\"\n label=\"GST/VAT Number\"\n name=\"tax_id\"\n controlId=\"user-subscription-tax_id\"\n errorMsg=\"Please enter GST/VAT Number\">\n <input type=\"text\"\n id=\"user-subscription-tax_id\"\n class=\"form-control\"\n formControlName=\"tax_id\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.CompanyUrl' | transloco\"\n class=\"col-md-6\"\n label=\"Company URL\"\n name=\"company_url\"\n controlId=\"user-subscription-company_url\"\n errorMsg=\"Please enter company url\">\n <input type=\"text\"\n id=\"user-subscription-company_url\"\n class=\"form-control\"\n formControlName=\"company_url\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.InvoiceRecipientEmails' | transloco\"\n class=\"col-md-6\"\n label=\"Invoice Recipient Emails\"\n name=\"invoice_recipient_emails\"\n controlId=\"user-subscription-invoice_recipient_emails\"\n errorMsg=\"Please enter valid email addresses separated by commas\">\n <input type=\"text\"\n id=\"user-subscription-invoice_recipient_emails\"\n class=\"form-control\"\n formControlName=\"invoice_recipient_emails\"\n placeholder=\"email1@example.com,email2@example.com\" />\n </pw-input-container>\n <ng-container *rbacAllow=\"'SubscriptionSuperAdmin'\">\n <div class=\"col-12\">\n <h3>Social Media</h3>\n <p>\n Any of the social media handles that you set here will appear in the footer of emails going out to your child subscriptions.\n </p>\n </div>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.FacebookHandle' | transloco\"\n class=\"col-md-6\"\n label=\"Facebook handle\"\n name=\"facebook_handle\"\n controlId=\"user-subscription-facebook_handle\"\n errorMsg=\"Please enter facebook id\">\n <input type=\"text\"\n id=\"user-subscription-facebook_handle\"\n class=\"form-control\"\n formControlName=\"facebook_handle\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.TwitterHandle' | transloco\"\n class=\"col-md-6\"\n label=\"Twitter handle\"\n name=\"twitter_handle\"\n controlId=\"user-subscription-twitter_handle\"\n errorMsg=\"Please enter twitter id\">\n <input type=\"text\"\n id=\"user-subscription-twitter_handle\"\n class=\"form-control\"\n formControlName=\"twitter_handle\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.LinkedinHandle' | transloco\"\n class=\"col-md-6\"\n label=\"Linkedin handle\"\n name=\"linkedin_handle\"\n controlId=\"user-subscription-linkedin_handle\"\n errorMsg=\"Please enter linkedin id\">\n <input type=\"text\"\n id=\"user-subscription-linkedin_handle\"\n class=\"form-control\"\n formControlName=\"linkedin_handle\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.RedditHandle' | transloco\"\n class=\"col-md-6\"\n label=\"Reddit handle\"\n name=\"reddit_handle\"\n controlId=\"user-subscription-reddit_handle\"\n errorMsg=\"Please enter reddit id\">\n <input type=\"text\"\n id=\"user-subscription-reddit_handle\"\n class=\"form-control\"\n formControlName=\"reddit_handle\" />\n </pw-input-container>\n </ng-container>\n @if (subscription?.api_hits_max > 0) {\n <div class=\"col-12\">\n <h3>{{ 'User.Subscriptions.APICredentials.Title' | transloco }}</h3>\n <p>\n Manage your {{appConfig?.company?.name}} API credentials. These tokens are used to authenticate API requests.\n </p>\n </div>\n <div class=\"col-md-6\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"user-subscription-api-token\">{{ 'User.Subscriptions.APICredentials.AccessToken' | transloco }}</label>\n <div class=\"input-group\">\n <input type=\"text\"\n id=\"user-subscription-api-token\"\n name=\"api_token\"\n class=\"form-control\"\n [value]=\"showApiToken ? subscription?.api_access_token || ('User.Subscriptions.APICredentials.NoTokenAvailable' | transloco) : '*************************'\"\n readonly />\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"toggleApiTokenVisibility()\">\n {{ showApiToken ? ('User.Subscriptions.APICredentials.Hide' | transloco) : ('User.Subscriptions.APICredentials.View' | transloco) }}\n </button>\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"user-subscription-api-client-id\">{{ 'User.Subscriptions.APICredentials.ClientId' | transloco }}</label>\n <div class=\"input-group\">\n <input type=\"text\"\n id=\"user-subscription-api-client-id\"\n name=\"api_client_id\"\n class=\"form-control\"\n [value]=\"showApiClientId ? subscription?.api_client_id || ('User.Subscriptions.APICredentials.NoClientIdAvailable' | transloco) : '*************************'\"\n readonly />\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"toggleApiClientIdVisibility()\">\n {{ showApiClientId ? ('User.Subscriptions.APICredentials.Hide' | transloco) : ('User.Subscriptions.APICredentials.View' | transloco) }}\n </button>\n </div>\n </div>\n </div>\n <div class=\"col-12 mt-3\">\n <div class=\"d-flex align-items-center gap-3\">\n <button type=\"button\"\n class=\"btn btn-warning\"\n (click)=\"refreshApiTokens()\"\n [disabled]=\"refreshingTokens\">\n <i class=\"fas fa-sync-alt me-2\" [class.fa-spin]=\"refreshingTokens\"></i>\n {{ refreshingTokens ? ('User.Subscriptions.APICredentials.Refreshing' | transloco) : ('User.Subscriptions.APICredentials.RefreshTokens' | transloco) }}\n </button>\n <div class=\"d-flex align-items-center gap-2\">\n @if (subscription?.api_hits !== null) {\n <span class=\"text-muted\">{{ 'User.Subscriptions.APICredentials.ApiHits' | transloco }}:</span>\n <span class=\"fw-bold\">{{ subscription.api_hits | number }}</span>\n }\n @if (subscription?.api_hits_max !== null) {\n <span class=\"text-muted\">{{ 'User.Subscriptions.APICredentials.ApiHitsMax' | transloco }}:</span>\n <span class=\"fw-bold\">{{ subscription.api_hits_max | number }}</span>\n }\n <!-- Show utilization percentage when both values exist -->\n @if (subscription?.api_hits !== null || subscription?.api_hits_max !== null) {\n <span class=\"text-muted ms-2\">(</span>\n <span class=\"fw-bold\" [ngClass]=\"{\n 'text-success': (subscription.api_hits / subscription.api_hits_max) <= 0.8,\n 'text-warning': (subscription.api_hits / subscription.api_hits_max) > 0.8 && (subscription.api_hits / subscription.api_hits_max) <= 0.9,\n 'text-danger': (subscription.api_hits / subscription.api_hits_max) > 0.9\n }\">\n {{ (subscription.api_hits / subscription.api_hits_max * 100) | number:'1.0-0' }}% consumed\n </span>\n <span class=\"text-muted\">)</span>\n }\n </div>\n </div>\n </div>\n }\n <div class=\"col-12 mt-5\">\n <h3>Security</h3>\n <p>\n While we'll add more security options in the future, please start by enforcing 2FA for all your subscription members.\n </p>\n </div>\n <div class=\"col-12 col-sm-3\">\n <pw-input-container label=\"Enforce 2FA\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Enforce2fa' | transloco\"\n name=\"enforce_2fa\"\n controlId=\"user-subscription-enforce_2fa\"\n [useAriaLabelledbyOnly]=\"true\">\n <ui-switch formControlName=\"enforce_2fa\"\n name=\"enforce_2fa\"\n [attr.aria-labelledby]=\"'user-subscription-enforce_2fa-label'\"> </ui-switch>\n </pw-input-container>\n </div>\n <div class=\"mb-3 col-12 text-end mt-3\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n routerLink=\"/account/subscriptions\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button name=\"submit\"\n type=\"submit\"\n [buttonBusy]=\"busyButton\"\n class=\"btn btn-primary\">\n {{ 'Button.Submit' | transloco }}\n </button>\n </div>\n </form>\n}\n\n<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h3 class=\"modal-title mb-0 p-0\">{{ 'User.Subscriptions.FullLogo' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n (imageSelectionEvent)=\"onImageSelection($event)\"\n aspectRatio=\"fullLogo\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n</ng-template>\n<ng-template #squaredLogoContent\n let-modal>\n <div class=\"modal-header\">\n <h3 class=\"modal-title mb-0 p-0\">{{ 'User.Subscriptions.SquaredLogo' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n (imageSelectionEvent)=\"uploadSquaredLogo($event)\"\n aspectRatio=\"auto\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n</ng-template>\n<pw-password-validation #modal\n(successEvent)=\"onPasswordValidation($event)\"> </pw-password-validation>\n", styles: [".sub-header{color:gray;font-size:20px;font-weight:600}.full-logo{object-fit:cover;width:280px}@media only screen and (max-width:767px){.btns-row .btn-primary{font-size:.8rem;margin-top:5px;padding:.375rem .5rem}}\n"], dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { kind: "directive", type: i4.RbacAllowDirective, selector: "[rbacAllow]", inputs: ["rbacAllow"] }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { 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: "directive", type: i6$1.NgxGpAutocompleteDirective, selector: "[ngx-gp-autocomplete]", inputs: ["options"], outputs: ["onAddressChange"], exportAs: ["ngx-places"] }, { kind: "component", type: i5.PasswordValidationComponent, selector: "pw-password-validation", inputs: ["confirmMessage"], outputs: ["successEvent"] }, { kind: "component", type: i6$2.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i11.UiSwitchComponent, selector: "ui-switch", inputs: ["size", "color", "switchOffColor", "switchColor", "defaultBgColor", "defaultBoColor", "checkedLabel", "uncheckedLabel", "checkedTextColor", "uncheckedTextColor", "beforeChange", "ariaLabel", "checked", "disabled", "reverse", "loading"], outputs: ["change", "changeEvent", "valueChange"] }, { kind: "component", type: i5.NumberPickerComponent, selector: "pw-number-picker", inputs: ["min", "showTooltip", "tooltipText", "max", "step", "value", "pickStartAfter", "pickTimer", "prefix", "postfix", "placeholder", "buttonsOrientation", "size", "customClass", "mouseWheel", "arrowKeys", "inputReadOnly", "showUpButton", "showDownButton", "inputId"], outputs: ["valueChange", "minReached", "maxReached", "pickStarted", "pickStopped", "pickUpStarted", "pickUpStopped", "pickDownStarted", "pickDownStopped"] }, { kind: "component", type: i9.ProfileImageCropperComponent, selector: "pw-image-cropper", inputs: ["aspectRatio", "dynamicData"], outputs: ["imageSelectionEvent", "closeEvent", "fileChangeEvent"] }, { kind: "component", type: i5.InputContainerComponent, selector: "pw-input-container", inputs: ["name", "controlId", "useAriaLabelledbyOnly", "label", "labelClass", "tooltipPosition", "required", "errorMsg", "isReadOnly", "showTooltip", "tooltipText", "showTriangle", "afterLabel", "showAfterLabel", "showTriangleText", "isLeftTooltip"] }, { kind: "directive", type: i6$4.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.DecimalPipe, name: "number" }, { kind: "pipe", type: i6.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i6$3.CurrencySymbolPipe, name: "currencySymbol" }] }); }
1590
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: UserSubscriptionDetailsComponent, isStandalone: false, selector: "ng-component", viewQueries: [{ propertyName: "modal", first: true, predicate: ["modal"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<!-- edit Subscription details page -->\n<div class=\"row\">\n <div class=\"col-12\">\n <h3 class=\"my-3\">{{ subscription?.organisation || subscription?.contact_name }}</h3>\n </div>\n</div>\n\n@if (subscription) {\n <form [formGroup]=\"form\"\n (ngSubmit)=\"onSaveDetails()\"\n class=\"row mt-4\"\n >\n <!-- 1. Contact details -->\n <div class=\"col-12\">\n <h3>Contact details</h3>\n </div>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.ContactName' | transloco\"\n class=\"col-md-6\"\n label=\"Contact Name\"\n name=\"contact_name\"\n controlId=\"user-subscription-contact_name\"\n errorMsg=\"Please enter Contact Name\">\n <input type=\"text\"\n id=\"user-subscription-contact_name\"\n class=\"form-control\"\n formControlName=\"contact_name\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.ContactEmail' | transloco\"\n class=\"col-md-6\"\n label=\"Contact Email\"\n name=\"contact_email\"\n controlId=\"user-subscription-contact_email\"\n errorMsg=\"Please enter Contact Email\">\n <input type=\"text\"\n id=\"user-subscription-contact_email\"\n class=\"form-control\"\n formControlName=\"contact_email\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Organization' | transloco\"\n class=\"col-md-6\"\n label=\"Organisation\"\n name=\"organisation\"\n controlId=\"user-subscription-organisation\"\n errorMsg=\"Please enter organisation\">\n <input type=\"text\"\n id=\"user-subscription-organisation\"\n class=\"form-control\"\n formControlName=\"organisation\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Phone' | transloco\"\n class=\"col-md-6\"\n label=\"Contact Tel\"\n name=\"contact_tel\"\n controlId=\"user-subscription-contact_tel\"\n errorMsg=\"Please enter Contact Telephone Number\">\n <input type=\"text\"\n id=\"user-subscription-contact_tel\"\n class=\"form-control\"\n formControlName=\"contact_tel\" />\n </pw-input-container>\n @if (countries$ | async; as countries) {\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Country' | transloco\"\n class=\"col-md-6\"\n label=\"Country\"\n name=\"country_code\"\n controlId=\"user-subscription-country_code\"\n [useAriaLabelledbyOnly]=\"true\"\n [isLeftTooltip]=\"true\"\n errorMsg=\"Please select a country\">\n <p-select\n [attr.aria-labelledby]=\"'user-subscription-country_code-label'\"\n [options]=\"countries\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"country_code\"\n placeholder=\"Select Country\">\n </p-select>\n </pw-input-container>\n }\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Address' | transloco\"\n class=\"col-md-6\"\n label=\"Address\"\n name=\"address\"\n controlId=\"user-subscription-address\"\n [useAriaLabelledbyOnly]=\"true\"\n errorMsg=\"Please enter address\">\n <input ngx-gp-autocomplete\n id=\"user-subscription-address\"\n name=\"address\"\n class=\"form-control\"\n [attr.aria-labelledby]=\"'user-subscription-address-label'\"\n #places=\"ngx-places\"\n formControlName=\"address\"\n (onAddressChange)=\"handleAddressChange($event)\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.VatNumber' | transloco\"\n class=\"col-md-6\"\n label=\"GST/VAT Number\"\n name=\"tax_id\"\n controlId=\"user-subscription-tax_id\"\n errorMsg=\"Please enter GST/VAT Number\">\n <input type=\"text\"\n id=\"user-subscription-tax_id\"\n class=\"form-control\"\n formControlName=\"tax_id\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.CompanyUrl' | transloco\"\n class=\"col-md-6\"\n label=\"Company URL\"\n name=\"company_url\"\n controlId=\"user-subscription-company_url\"\n errorMsg=\"Please enter company url\">\n <input type=\"text\"\n id=\"user-subscription-company_url\"\n class=\"form-control\"\n formControlName=\"company_url\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.InvoiceRecipientEmails' | transloco\"\n class=\"col-md-6\"\n label=\"Invoice Recipient Emails\"\n name=\"invoice_recipient_emails\"\n controlId=\"user-subscription-invoice_recipient_emails\"\n errorMsg=\"Please enter valid email addresses separated by commas\">\n <input type=\"text\"\n id=\"user-subscription-invoice_recipient_emails\"\n class=\"form-control\"\n formControlName=\"invoice_recipient_emails\"\n placeholder=\"email1@example.com,email2@example.com\" />\n </pw-input-container>\n\n <!-- 2. Branding / Logos -->\n <div class=\"col-12\">\n <div class=\"row branding-section\">\n <div class=\"col-12\">\n <h3>Branding</h3>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-md-6\">\n <div class=\"text-center mt-5\">\n <div class=\"image-container\">\n <h4 class=\"mb-2\">{{ 'User.Subscriptions.FullLogo' | transloco }}\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'User.Subscriptions.Tooltip.FullLogo'|transloco\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"'top'\">\n <i class=\"far fa-info-circle text-muted\"></i>\n </span>\n </h4>\n @if (fullLogo && !fullLogo.includes('no_image_uploaded') && !fullLogoBroken) {\n <img [src]=\"fullLogo\"\n alt=\"full logo\"\n class=\"image full-logo\"\n role=\"presentation\"\n (error)=\"fullLogoBroken = true\" />\n <div class=\"overlay mt-2\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\">\n <div class=\"overlay-text\">\n <a aria-label=\"Navigate to Target\">{{ 'User.Profile.Change' | transloco }}</a>\n </div>\n </div>\n } @else {\n <div class=\"logo-dropzone full-dropzone\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Upload full logo\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\">\n <i class=\"fas fa-upload\"></i>\n <span class=\"dropzone-title\">Upload a logo</span>\n <span class=\"dropzone-hint\">PNG or JPG</span>\n </div>\n }\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"text-center mt-5\">\n <div class=\"image-container\">\n <h4 class=\"mb-2\">Squared Logo\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'User.Subscriptions.Tooltip.SquaredLogo'|transloco\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"'top'\">\n <i class=\"far fa-info-circle text-muted\"></i>\n </span>\n </h4>\n @if (squaredLogo && !squaredLogo.includes('no_image_uploaded') && !squaredLogoBroken) {\n <img [src]=\"squaredLogo\"\n alt=\"Squared Presentation\"\n class=\"squared_logo\"\n role=\"presentation\"\n (error)=\"squaredLogoBroken = true\" />\n <div class=\"overlay mt-2\"\n (keydown.enter)=\"openModal(squaredLogoContent)\"\n (click)=\"openModal(squaredLogoContent)\">\n <div class=\"overlay-text\">\n <a aria-label=\"Navigate to Target\">{{ 'User.Profile.Change' | transloco }}</a>\n </div>\n </div>\n } @else {\n <div class=\"logo-dropzone squared-dropzone\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Upload squared logo\"\n (keydown.enter)=\"openModal(squaredLogoContent)\"\n (click)=\"openModal(squaredLogoContent)\">\n <i class=\"fas fa-upload\"></i>\n <span class=\"dropzone-title\">Upload a logo</span>\n <span class=\"dropzone-hint\">PNG or JPG</span>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- 3. Social Media -->\n <ng-container *rbacAllow=\"'SubscriptionSuperAdmin'\">\n <div class=\"col-12\">\n <h3>Social Media</h3>\n <p>\n Any of the social media handles that you set here will appear in the footer of emails going out to your child subscriptions.\n </p>\n </div>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.FacebookHandle' | transloco\"\n class=\"col-md-6\"\n label=\"Facebook handle\"\n name=\"facebook_handle\"\n controlId=\"user-subscription-facebook_handle\"\n errorMsg=\"Please enter facebook id\">\n <input type=\"text\"\n id=\"user-subscription-facebook_handle\"\n class=\"form-control\"\n formControlName=\"facebook_handle\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.TwitterHandle' | transloco\"\n class=\"col-md-6\"\n label=\"Twitter handle\"\n name=\"twitter_handle\"\n controlId=\"user-subscription-twitter_handle\"\n errorMsg=\"Please enter twitter id\">\n <input type=\"text\"\n id=\"user-subscription-twitter_handle\"\n class=\"form-control\"\n formControlName=\"twitter_handle\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.LinkedinHandle' | transloco\"\n class=\"col-md-6\"\n label=\"Linkedin handle\"\n name=\"linkedin_handle\"\n controlId=\"user-subscription-linkedin_handle\"\n errorMsg=\"Please enter linkedin id\">\n <input type=\"text\"\n id=\"user-subscription-linkedin_handle\"\n class=\"form-control\"\n formControlName=\"linkedin_handle\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.RedditHandle' | transloco\"\n class=\"col-md-6\"\n label=\"Reddit handle\"\n name=\"reddit_handle\"\n controlId=\"user-subscription-reddit_handle\"\n errorMsg=\"Please enter reddit id\">\n <input type=\"text\"\n id=\"user-subscription-reddit_handle\"\n class=\"form-control\"\n formControlName=\"reddit_handle\" />\n </pw-input-container>\n </ng-container>\n\n <!-- 4. Seats -->\n <div class=\"col-12\">\n <div class=\"row seats-section\">\n <div class=\"col-12\">\n <h3>Seats</h3>\n <p>Changing the number of seats updates your subscription cost.</p>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n @if (subscription?.trial_subscription && subscription?.calculated_price) {\n <small\n class=\"text-danger\">Upgrade to be able to update your purchased seats</small>\n }\n </div>\n </div>\n <div class=\"row btns-row align-items-center\">\n @if (subscription) {\n <div class=\"col-md-3 col-8\"\n >\n <label for=\"user-subscription-seats\" class=\"visually-hidden\">{{ 'User.Subscriptions.Tooltip.Seats' | transloco }}</label>\n <pw-number-picker [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Seats'|transloco\"\n inputId=\"user-subscription-seats\"\n name=\"number-picker\"\n [(value)]=\"units\"\n [min]=\"subscription?.min_units||subscription?.products[0].min_units\"\n [max]=\"subscription?.products[0].max_units\"\n step=\"1\"\n postfix=\"seats\"\n placeholder=\"Total Licences\"\n [inputReadOnly]=\"subscription?.products[0].trial_subscription\"\n [showUpButton]=\"!subscription?.products[0].trial_subscription\"\n [showDownButton]=\"!subscription?.products[0].trial_subscription\"\n size=\"small\"\n pickStartAfter=\"500\"\n pickTimer=\"100\"\n [arrowKeys]=\"true\"\n (minReached)=\"onMinReached($event)\"\n (maxReached)=\"onMaxReached($event)\"\n (valueChange)=\"onUnitChange($event)\">\n </pw-number-picker>\n </div>\n }\n\n @if (subscription) {\n <div class=\"col-md-3 col-4 p-1\"\n >\n @if (!subscription?.products[0].trial_subscription && allowUpdate) {\n <button type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"updateUnits()\">\n {{ 'User.Subscriptions.UpdateUnits' | transloco }}\n </button>\n } @else {\n <div>\n @if (subscription?.products[0].trial_subscription) {\n <small class=\"text-muted\"\n >Update seats is available only to paid subscriptions</small>\n }\n </div>\n }\n </div>\n }\n\n @if (hasUnitChanged) {\n <div class=\"col-12 col-md-6\"\n >\n <table class=\"table table-borderless table-sm\"\n aria-describedby=\"Product details\">\n <thead>\n <tr>\n <th scope=\"true\">Product</th>\n <th scope=\"true\">Price per seat <span>({{subscription?.products[0]?.currency|currencySymbol}})</span></th>\n <th scope=\"true\">Seats</th>\n </tr>\n </thead>\n <tbody>\n @for (product of subscription.products; track trackByProduct($index, product)) {\n <tr>\n <td>{{ product.name }}</td>\n <td>{{ product.price_per_unit / 100 }}</td>\n <td>{{ units }}</td>\n </tr>\n }\n </tbody>\n </table>\n <p>\n If you proceed, the new cost for your subscription will be\n <strong>{{ totalAmount()| currency: subscription?.products[0]?.currency:'symbol-narrow'}}</strong>\n </p>\n </div>\n }\n </div>\n </div>\n\n <!-- 5. API & MCP Credentials -->\n @if (subscription?.api_hits_max > 0) {\n <div class=\"col-12\">\n <h3>{{ 'User.Subscriptions.APICredentials.Title' | transloco }}</h3>\n <p>\n These credentials authenticate both REST API and MCP (Model Context Protocol) requests, and must be used together with the user tokens defined on your Account page.\n </p>\n </div>\n <div class=\"col-md-6\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"user-subscription-api-token\">\n {{ 'User.Subscriptions.APICredentials.AccessToken' | transloco }}\n <span class=\"tooltip-wrap ms-1\"\n pTooltip=\"The subscription token has been discontinued in favour of the user token defined on your Account page.\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"'top'\">\n <i class=\"far fa-info-circle text-muted\"></i>\n </span>\n </label>\n <div class=\"input-group\">\n <input type=\"text\"\n id=\"user-subscription-api-token\"\n name=\"api_token\"\n class=\"form-control\"\n [value]=\"showApiToken ? subscription?.api_access_token || ('User.Subscriptions.APICredentials.NoTokenAvailable' | transloco) : '*************************'\"\n readonly />\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"toggleApiTokenVisibility()\">\n {{ showApiToken ? ('User.Subscriptions.APICredentials.Hide' | transloco) : ('User.Subscriptions.APICredentials.View' | transloco) }}\n </button>\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"user-subscription-api-client-id\">{{ 'User.Subscriptions.APICredentials.ClientId' | transloco }}</label>\n <div class=\"input-group\">\n <input type=\"text\"\n id=\"user-subscription-api-client-id\"\n name=\"api_client_id\"\n class=\"form-control\"\n [value]=\"showApiClientId ? subscription?.api_client_id || ('User.Subscriptions.APICredentials.NoClientIdAvailable' | transloco) : '*************************'\"\n readonly />\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"toggleApiClientIdVisibility()\">\n {{ showApiClientId ? ('User.Subscriptions.APICredentials.Hide' | transloco) : ('User.Subscriptions.APICredentials.View' | transloco) }}\n </button>\n </div>\n </div>\n </div>\n <div class=\"col-12 mt-3\">\n <div class=\"d-flex align-items-center gap-3\">\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"refreshApiTokens()\"\n [disabled]=\"refreshingTokens\">\n <i class=\"fas fa-sync-alt me-2\" [class.fa-spin]=\"refreshingTokens\"></i>\n {{ refreshingTokens ? ('User.Subscriptions.APICredentials.Refreshing' | transloco) : ('User.Subscriptions.APICredentials.RefreshTokens' | transloco) }}\n </button>\n <div class=\"d-flex align-items-center gap-2\">\n @if (subscription?.api_hits !== null) {\n <span class=\"text-muted\">{{ 'User.Subscriptions.APICredentials.ApiHits' | transloco }}:</span>\n <span class=\"fw-bold\">{{ subscription.api_hits | number }}</span>\n }\n @if (subscription?.api_hits_max !== null) {\n <span class=\"text-muted\">{{ 'User.Subscriptions.APICredentials.ApiHitsMax' | transloco }}:</span>\n <span class=\"fw-bold\">{{ subscription.api_hits_max | number }}</span>\n }\n <!-- Show utilization percentage when both values exist -->\n @if (subscription?.api_hits !== null || subscription?.api_hits_max !== null) {\n <span class=\"text-muted ms-2\">(</span>\n <span class=\"fw-bold\" [ngClass]=\"{\n 'text-success': (subscription.api_hits / subscription.api_hits_max) <= 0.8,\n 'text-warning': (subscription.api_hits / subscription.api_hits_max) > 0.8 && (subscription.api_hits / subscription.api_hits_max) <= 0.9,\n 'text-danger': (subscription.api_hits / subscription.api_hits_max) > 0.9\n }\">\n {{ (subscription.api_hits / subscription.api_hits_max * 100) | number:'1.0-0' }}% consumed\n </span>\n <span class=\"text-muted\">)</span>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- 6. Security -->\n <div class=\"col-12 mt-5\">\n <h3>Security</h3>\n <p>\n While we'll add more security options in the future, please start by enforcing 2FA for all your subscription members.\n </p>\n </div>\n <div class=\"col-12 col-sm-3\">\n <pw-input-container label=\"Enforce 2FA\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Enforce2fa' | transloco\"\n name=\"enforce_2fa\"\n controlId=\"user-subscription-enforce_2fa\"\n [useAriaLabelledbyOnly]=\"true\">\n <ui-switch formControlName=\"enforce_2fa\"\n name=\"enforce_2fa\"\n [attr.aria-labelledby]=\"'user-subscription-enforce_2fa-label'\"> </ui-switch>\n </pw-input-container>\n </div>\n <div class=\"mb-3 col-12 text-end mt-3\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n routerLink=\"/account/subscriptions\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button name=\"submit\"\n type=\"submit\"\n [buttonBusy]=\"busyButton\"\n class=\"btn btn-primary\">\n {{ 'Button.Submit' | transloco }}\n </button>\n </div>\n </form>\n}\n\n<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h3 class=\"modal-title mb-0 p-0\">{{ 'User.Subscriptions.FullLogo' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n (imageSelectionEvent)=\"onImageSelection($event)\"\n aspectRatio=\"fullLogo\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n</ng-template>\n<ng-template #squaredLogoContent\n let-modal>\n <div class=\"modal-header\">\n <h3 class=\"modal-title mb-0 p-0\">{{ 'User.Subscriptions.SquaredLogo' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n (imageSelectionEvent)=\"uploadSquaredLogo($event)\"\n aspectRatio=\"auto\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n</ng-template>\n<pw-password-validation #modal\n(successEvent)=\"onPasswordValidation($event)\"> </pw-password-validation>\n", styles: [":host{display:block}:host>.row:first-of-type h3{color:var(--titles, #222);font-size:24px;font-weight:700;letter-spacing:-.01em;line-height:1.18}:host form .col-12>h3,:host .seats-section>.col-12>h3,:host .branding-section>.col-12>h3{border-top:1px solid #e2e5ea;color:var(--titles, #222);display:block;font-size:18px;font-weight:600;margin-top:32px;padding-top:24px}:host form>.col-12:first-child>h3{border-top:0;margin-top:0;padding-top:0}:host form .col-12>p,:host .seats-section>.col-12>p{color:#5a6473;font-size:15px;margin-bottom:16px}:host .row .text-center.mt-5{margin-top:16px!important;text-align:left!important}:host .image-container>h4{color:var(--titles, #222);font-size:14px;font-weight:600}:host .full-logo,:host .squared_logo{background:#f7f8fa;border:1px solid #e2e5ea;border-radius:8px;object-fit:contain;padding:12px}:host .full-logo{height:120px;width:280px}:host .squared_logo{height:150px;width:150px}:host .overlay{cursor:pointer;margin-top:8px}:host .overlay-text a{color:var(--first, #1769e1);cursor:pointer;font-weight:600}:host .overlay-text a:hover{text-decoration:underline}.sub-header{color:gray;font-size:20px;font-weight:600}@media only screen and (max-width:767px){.btns-row>[class*=col-]{flex:0 0 100%;max-width:100%}.btns-row .btn-primary{font-size:.8rem;margin-top:5px;padding:.375rem .5rem}}\n"], dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { kind: "directive", type: i4.RbacAllowDirective, selector: "[rbacAllow]", inputs: ["rbacAllow"] }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { 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: "directive", type: i6$1.NgxGpAutocompleteDirective, selector: "[ngx-gp-autocomplete]", inputs: ["options"], outputs: ["onAddressChange"], exportAs: ["ngx-places"] }, { kind: "component", type: i5.PasswordValidationComponent, selector: "pw-password-validation", inputs: ["confirmMessage"], outputs: ["successEvent"] }, { kind: "component", type: i6$2.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i11$1.UiSwitchComponent, selector: "ui-switch", inputs: ["size", "color", "switchOffColor", "switchColor", "defaultBgColor", "defaultBoColor", "checkedLabel", "uncheckedLabel", "checkedTextColor", "uncheckedTextColor", "beforeChange", "ariaLabel", "checked", "disabled", "reverse", "loading"], outputs: ["change", "changeEvent", "valueChange"] }, { kind: "component", type: i5.NumberPickerComponent, selector: "pw-number-picker", inputs: ["min", "showTooltip", "tooltipText", "max", "step", "value", "pickStartAfter", "pickTimer", "prefix", "postfix", "placeholder", "buttonsOrientation", "size", "customClass", "mouseWheel", "arrowKeys", "inputReadOnly", "showUpButton", "showDownButton", "inputId"], outputs: ["valueChange", "minReached", "maxReached", "pickStarted", "pickStopped", "pickUpStarted", "pickUpStopped", "pickDownStarted", "pickDownStopped"] }, { kind: "component", type: i9.ProfileImageCropperComponent, selector: "pw-image-cropper", inputs: ["aspectRatio", "dynamicData"], outputs: ["imageSelectionEvent", "closeEvent", "fileChangeEvent"] }, { kind: "component", type: i5.InputContainerComponent, selector: "pw-input-container", inputs: ["name", "controlId", "useAriaLabelledbyOnly", "label", "labelClass", "tooltipPosition", "required", "errorMsg", "isReadOnly", "showTooltip", "tooltipText", "showTriangle", "afterLabel", "showAfterLabel", "showTriangleText", "isLeftTooltip"] }, { kind: "directive", type: i11.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.DecimalPipe, name: "number" }, { kind: "pipe", type: i6.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i6$3.CurrencySymbolPipe, name: "currencySymbol" }] }); }
1592
1591
  }
1593
1592
  __decorate([
1594
1593
  ValidateForm('form'),
@@ -1598,7 +1597,7 @@ __decorate([
1598
1597
  ], UserSubscriptionDetailsComponent.prototype, "onSaveDetails", null);
1599
1598
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserSubscriptionDetailsComponent, decorators: [{
1600
1599
  type: Component,
1601
- args: [{ standalone: false, template: "<!-- edit Subscription details page -->\n<div class=\"row\">\n <div class=\"col-12\">\n <h3 class=\"my-3\">{{ subscription?.organisation || subscription?.contact_name }}</h3>\n </div>\n</div>\n\n@if (subscription) {\n <div class=\"row\"\n >\n <div class=\"col-md-6\">\n <div class=\"text-center mt-5\">\n <div class=\"image-container\">\n <h4 class=\"mb-2\">Full Logo\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'User.Subscriptions.Tooltip.FullLogo'|transloco\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"'top'\">\n <i class=\"fas fa-info-circle\"></i>\n </span>\n </h4>\n <img [src]=\"fullLogo\"\n alt=\"full logo\"\n width=\"100%\"\n class=\"image full-logo\"\n height=\"100%\"\n role=\"presentation\"\n (error)=\"onImgError($event, 'assets/img/icons/dummy-logo.jpg')\" />\n <div class=\"overlay mt-2\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\">\n <div class=\"overlay-text\">\n <a aria-label=\"Navigate to Target\">{{ 'User.Profile.Change' | transloco }}</a>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"text-center mt-5\">\n <div class=\"image-container\">\n <h4 class=\"mb-2\">Squared Logo\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'User.Subscriptions.Tooltip.SquaredLogo'|transloco\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"'top'\">\n <i class=\"fas fa-info-circle\"></i>\n </span>\n </h4>\n <img [src]=\"squaredLogo\"\n alt=\"Squared Presentation\"\n width=\"150\"\n class=\"squared_logo\"\n [height]=\"'150'\"\n role=\"presentation\"\n (error)=\"onImgError($event, 'assets/img/icons/dummy-icon.jpg')\" />\n <div class=\"overlay mt-2\"\n (keydown.enter)=\"openModal(squaredLogoContent)\"\n (click)=\"openModal(squaredLogoContent)\">\n <div class=\"overlay-text\">\n <a aria-label=\"Navigate to Target\">{{ 'User.Profile.Change' | transloco }}</a>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n}\n<div class=\"row\">\n <div class=\"col-12\">\n @if (subscription?.trial_subscription && subscription?.calculated_price) {\n <small\n class=\"text-danger\">Upgrade to be able to update your purchased seats</small>\n }\n </div>\n</div>\n<div class=\"row btns-row align-items-center\">\n @if (subscription) {\n <div class=\"col-md-3 col-8\"\n >\n <label for=\"user-subscription-seats\" class=\"visually-hidden\">{{ 'User.Subscriptions.Tooltip.Seats' | transloco }}</label>\n <pw-number-picker [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Seats'|transloco\"\n inputId=\"user-subscription-seats\"\n name=\"number-picker\"\n [(value)]=\"units\"\n [min]=\"subscription?.min_units||subscription?.products[0].min_units\"\n [max]=\"subscription?.products[0].max_units\"\n step=\"1\"\n postfix=\"seats\"\n placeholder=\"Total Licences\"\n [inputReadOnly]=\"subscription?.products[0].trial_subscription\"\n [showUpButton]=\"!subscription?.products[0].trial_subscription\"\n [showDownButton]=\"!subscription?.products[0].trial_subscription\"\n size=\"small\"\n pickStartAfter=\"500\"\n pickTimer=\"100\"\n [arrowKeys]=\"true\"\n (minReached)=\"onMinReached($event)\"\n (maxReached)=\"onMaxReached($event)\"\n (valueChange)=\"onUnitChange($event)\">\n </pw-number-picker>\n </div>\n }\n\n @if (subscription) {\n <div class=\"col-md-3 col-4 p-1\"\n >\n @if (!subscription?.products[0].trial_subscription && allowUpdate) {\n <button class=\"btn btn-primary\"\n (click)=\"updateUnits()\">\n {{ 'User.Subscriptions.UpdateUnits' | transloco }}\n </button>\n } @else {\n <div>\n @if (subscription?.products[0].trial_subscription) {\n <small class=\"danger\"\n >Update seats is available only to paid subscriptions</small>\n }\n </div>\n }\n </div>\n }\n\n @if (hasUnitChanged) {\n <div class=\"col-12 col-md-6\"\n >\n <table class=\"table table-borderless table-sm\"\n aria-describedby=\"Product details\">\n <thead>\n <tr>\n <th scope=\"true\">Product</th>\n <th scope=\"true\">Price per seat <span>({{subscription?.products[0]?.currency|currencySymbol}})</span></th>\n <th scope=\"true\">Seats</th>\n </tr>\n </thead>\n <tbody>\n @for (product of subscription.products; track trackByProduct($index, product)) {\n <tr>\n <td>{{ product.name }}</td>\n <td>{{ product.price_per_unit / 100 }}</td>\n <td>{{ units }}</td>\n </tr>\n }\n </tbody>\n </table>\n <p>\n If you proceed, the new cost for your subscription will be\n <strong>{{ totalAmount()| currency: subscription?.products[0]?.currency:'symbol-narrow'}}</strong>\n </p>\n </div>\n }\n</div>\n@if (subscription) {\n <form [formGroup]=\"form\"\n (ngSubmit)=\"onSaveDetails()\"\n class=\"row mt-4\"\n >\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.ContactName' | transloco\"\n class=\"col-md-6\"\n label=\"Contact Name\"\n name=\"contact_name\"\n controlId=\"user-subscription-contact_name\"\n errorMsg=\"Please enter Contact Name\">\n <input type=\"text\"\n id=\"user-subscription-contact_name\"\n class=\"form-control\"\n formControlName=\"contact_name\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.ContactEmail' | transloco\"\n class=\"col-md-6\"\n label=\"Contact Email\"\n name=\"contact_email\"\n controlId=\"user-subscription-contact_email\"\n errorMsg=\"Please enter Contact Email\">\n <input type=\"text\"\n id=\"user-subscription-contact_email\"\n class=\"form-control\"\n formControlName=\"contact_email\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Organization' | transloco\"\n class=\"col-md-6\"\n label=\"Organisation\"\n name=\"organisation\"\n controlId=\"user-subscription-organisation\"\n errorMsg=\"Please enter organisation\">\n <input type=\"text\"\n id=\"user-subscription-organisation\"\n class=\"form-control\"\n formControlName=\"organisation\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Phone' | transloco\"\n class=\"col-md-6\"\n label=\"Contact Tel\"\n name=\"contact_tel\"\n controlId=\"user-subscription-contact_tel\"\n errorMsg=\"Please enter Contact Telephone Number\">\n <input type=\"text\"\n id=\"user-subscription-contact_tel\"\n class=\"form-control\"\n formControlName=\"contact_tel\" />\n </pw-input-container>\n @if (countries$ | async; as countries) {\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Country' | transloco\"\n class=\"col-md-6\"\n label=\"Country\"\n name=\"country_code\"\n controlId=\"user-subscription-country_code\"\n [useAriaLabelledbyOnly]=\"true\"\n [isLeftTooltip]=\"true\"\n errorMsg=\"Please select a country\">\n <p-select\n [attr.aria-labelledby]=\"'user-subscription-country_code-label'\"\n [options]=\"countries\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"country_code\"\n placeholder=\"Select Country\">\n </p-select>\n </pw-input-container>\n }\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Address' | transloco\"\n class=\"col-md-6\"\n label=\"Address\"\n name=\"address\"\n controlId=\"user-subscription-address\"\n [useAriaLabelledbyOnly]=\"true\"\n errorMsg=\"Please enter address\">\n <input ngx-gp-autocomplete\n id=\"user-subscription-address\"\n name=\"address\"\n class=\"form-control\"\n [attr.aria-labelledby]=\"'user-subscription-address-label'\"\n #places=\"ngx-places\"\n formControlName=\"address\"\n (onAddressChange)=\"handleAddressChange($event)\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.VatNumber' | transloco\"\n class=\"col-md-6\"\n label=\"GST/VAT Number\"\n name=\"tax_id\"\n controlId=\"user-subscription-tax_id\"\n errorMsg=\"Please enter GST/VAT Number\">\n <input type=\"text\"\n id=\"user-subscription-tax_id\"\n class=\"form-control\"\n formControlName=\"tax_id\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.CompanyUrl' | transloco\"\n class=\"col-md-6\"\n label=\"Company URL\"\n name=\"company_url\"\n controlId=\"user-subscription-company_url\"\n errorMsg=\"Please enter company url\">\n <input type=\"text\"\n id=\"user-subscription-company_url\"\n class=\"form-control\"\n formControlName=\"company_url\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.InvoiceRecipientEmails' | transloco\"\n class=\"col-md-6\"\n label=\"Invoice Recipient Emails\"\n name=\"invoice_recipient_emails\"\n controlId=\"user-subscription-invoice_recipient_emails\"\n errorMsg=\"Please enter valid email addresses separated by commas\">\n <input type=\"text\"\n id=\"user-subscription-invoice_recipient_emails\"\n class=\"form-control\"\n formControlName=\"invoice_recipient_emails\"\n placeholder=\"email1@example.com,email2@example.com\" />\n </pw-input-container>\n <ng-container *rbacAllow=\"'SubscriptionSuperAdmin'\">\n <div class=\"col-12\">\n <h3>Social Media</h3>\n <p>\n Any of the social media handles that you set here will appear in the footer of emails going out to your child subscriptions.\n </p>\n </div>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.FacebookHandle' | transloco\"\n class=\"col-md-6\"\n label=\"Facebook handle\"\n name=\"facebook_handle\"\n controlId=\"user-subscription-facebook_handle\"\n errorMsg=\"Please enter facebook id\">\n <input type=\"text\"\n id=\"user-subscription-facebook_handle\"\n class=\"form-control\"\n formControlName=\"facebook_handle\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.TwitterHandle' | transloco\"\n class=\"col-md-6\"\n label=\"Twitter handle\"\n name=\"twitter_handle\"\n controlId=\"user-subscription-twitter_handle\"\n errorMsg=\"Please enter twitter id\">\n <input type=\"text\"\n id=\"user-subscription-twitter_handle\"\n class=\"form-control\"\n formControlName=\"twitter_handle\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.LinkedinHandle' | transloco\"\n class=\"col-md-6\"\n label=\"Linkedin handle\"\n name=\"linkedin_handle\"\n controlId=\"user-subscription-linkedin_handle\"\n errorMsg=\"Please enter linkedin id\">\n <input type=\"text\"\n id=\"user-subscription-linkedin_handle\"\n class=\"form-control\"\n formControlName=\"linkedin_handle\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.RedditHandle' | transloco\"\n class=\"col-md-6\"\n label=\"Reddit handle\"\n name=\"reddit_handle\"\n controlId=\"user-subscription-reddit_handle\"\n errorMsg=\"Please enter reddit id\">\n <input type=\"text\"\n id=\"user-subscription-reddit_handle\"\n class=\"form-control\"\n formControlName=\"reddit_handle\" />\n </pw-input-container>\n </ng-container>\n @if (subscription?.api_hits_max > 0) {\n <div class=\"col-12\">\n <h3>{{ 'User.Subscriptions.APICredentials.Title' | transloco }}</h3>\n <p>\n Manage your {{appConfig?.company?.name}} API credentials. These tokens are used to authenticate API requests.\n </p>\n </div>\n <div class=\"col-md-6\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"user-subscription-api-token\">{{ 'User.Subscriptions.APICredentials.AccessToken' | transloco }}</label>\n <div class=\"input-group\">\n <input type=\"text\"\n id=\"user-subscription-api-token\"\n name=\"api_token\"\n class=\"form-control\"\n [value]=\"showApiToken ? subscription?.api_access_token || ('User.Subscriptions.APICredentials.NoTokenAvailable' | transloco) : '*************************'\"\n readonly />\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"toggleApiTokenVisibility()\">\n {{ showApiToken ? ('User.Subscriptions.APICredentials.Hide' | transloco) : ('User.Subscriptions.APICredentials.View' | transloco) }}\n </button>\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"user-subscription-api-client-id\">{{ 'User.Subscriptions.APICredentials.ClientId' | transloco }}</label>\n <div class=\"input-group\">\n <input type=\"text\"\n id=\"user-subscription-api-client-id\"\n name=\"api_client_id\"\n class=\"form-control\"\n [value]=\"showApiClientId ? subscription?.api_client_id || ('User.Subscriptions.APICredentials.NoClientIdAvailable' | transloco) : '*************************'\"\n readonly />\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"toggleApiClientIdVisibility()\">\n {{ showApiClientId ? ('User.Subscriptions.APICredentials.Hide' | transloco) : ('User.Subscriptions.APICredentials.View' | transloco) }}\n </button>\n </div>\n </div>\n </div>\n <div class=\"col-12 mt-3\">\n <div class=\"d-flex align-items-center gap-3\">\n <button type=\"button\"\n class=\"btn btn-warning\"\n (click)=\"refreshApiTokens()\"\n [disabled]=\"refreshingTokens\">\n <i class=\"fas fa-sync-alt me-2\" [class.fa-spin]=\"refreshingTokens\"></i>\n {{ refreshingTokens ? ('User.Subscriptions.APICredentials.Refreshing' | transloco) : ('User.Subscriptions.APICredentials.RefreshTokens' | transloco) }}\n </button>\n <div class=\"d-flex align-items-center gap-2\">\n @if (subscription?.api_hits !== null) {\n <span class=\"text-muted\">{{ 'User.Subscriptions.APICredentials.ApiHits' | transloco }}:</span>\n <span class=\"fw-bold\">{{ subscription.api_hits | number }}</span>\n }\n @if (subscription?.api_hits_max !== null) {\n <span class=\"text-muted\">{{ 'User.Subscriptions.APICredentials.ApiHitsMax' | transloco }}:</span>\n <span class=\"fw-bold\">{{ subscription.api_hits_max | number }}</span>\n }\n <!-- Show utilization percentage when both values exist -->\n @if (subscription?.api_hits !== null || subscription?.api_hits_max !== null) {\n <span class=\"text-muted ms-2\">(</span>\n <span class=\"fw-bold\" [ngClass]=\"{\n 'text-success': (subscription.api_hits / subscription.api_hits_max) <= 0.8,\n 'text-warning': (subscription.api_hits / subscription.api_hits_max) > 0.8 && (subscription.api_hits / subscription.api_hits_max) <= 0.9,\n 'text-danger': (subscription.api_hits / subscription.api_hits_max) > 0.9\n }\">\n {{ (subscription.api_hits / subscription.api_hits_max * 100) | number:'1.0-0' }}% consumed\n </span>\n <span class=\"text-muted\">)</span>\n }\n </div>\n </div>\n </div>\n }\n <div class=\"col-12 mt-5\">\n <h3>Security</h3>\n <p>\n While we'll add more security options in the future, please start by enforcing 2FA for all your subscription members.\n </p>\n </div>\n <div class=\"col-12 col-sm-3\">\n <pw-input-container label=\"Enforce 2FA\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Enforce2fa' | transloco\"\n name=\"enforce_2fa\"\n controlId=\"user-subscription-enforce_2fa\"\n [useAriaLabelledbyOnly]=\"true\">\n <ui-switch formControlName=\"enforce_2fa\"\n name=\"enforce_2fa\"\n [attr.aria-labelledby]=\"'user-subscription-enforce_2fa-label'\"> </ui-switch>\n </pw-input-container>\n </div>\n <div class=\"mb-3 col-12 text-end mt-3\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n routerLink=\"/account/subscriptions\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button name=\"submit\"\n type=\"submit\"\n [buttonBusy]=\"busyButton\"\n class=\"btn btn-primary\">\n {{ 'Button.Submit' | transloco }}\n </button>\n </div>\n </form>\n}\n\n<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h3 class=\"modal-title mb-0 p-0\">{{ 'User.Subscriptions.FullLogo' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n (imageSelectionEvent)=\"onImageSelection($event)\"\n aspectRatio=\"fullLogo\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n</ng-template>\n<ng-template #squaredLogoContent\n let-modal>\n <div class=\"modal-header\">\n <h3 class=\"modal-title mb-0 p-0\">{{ 'User.Subscriptions.SquaredLogo' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n (imageSelectionEvent)=\"uploadSquaredLogo($event)\"\n aspectRatio=\"auto\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n</ng-template>\n<pw-password-validation #modal\n(successEvent)=\"onPasswordValidation($event)\"> </pw-password-validation>\n", styles: [".sub-header{color:gray;font-size:20px;font-weight:600}.full-logo{object-fit:cover;width:280px}@media only screen and (max-width:767px){.btns-row .btn-primary{font-size:.8rem;margin-top:5px;padding:.375rem .5rem}}\n"] }]
1600
+ args: [{ standalone: false, template: "<!-- edit Subscription details page -->\n<div class=\"row\">\n <div class=\"col-12\">\n <h3 class=\"my-3\">{{ subscription?.organisation || subscription?.contact_name }}</h3>\n </div>\n</div>\n\n@if (subscription) {\n <form [formGroup]=\"form\"\n (ngSubmit)=\"onSaveDetails()\"\n class=\"row mt-4\"\n >\n <!-- 1. Contact details -->\n <div class=\"col-12\">\n <h3>Contact details</h3>\n </div>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.ContactName' | transloco\"\n class=\"col-md-6\"\n label=\"Contact Name\"\n name=\"contact_name\"\n controlId=\"user-subscription-contact_name\"\n errorMsg=\"Please enter Contact Name\">\n <input type=\"text\"\n id=\"user-subscription-contact_name\"\n class=\"form-control\"\n formControlName=\"contact_name\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.ContactEmail' | transloco\"\n class=\"col-md-6\"\n label=\"Contact Email\"\n name=\"contact_email\"\n controlId=\"user-subscription-contact_email\"\n errorMsg=\"Please enter Contact Email\">\n <input type=\"text\"\n id=\"user-subscription-contact_email\"\n class=\"form-control\"\n formControlName=\"contact_email\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Organization' | transloco\"\n class=\"col-md-6\"\n label=\"Organisation\"\n name=\"organisation\"\n controlId=\"user-subscription-organisation\"\n errorMsg=\"Please enter organisation\">\n <input type=\"text\"\n id=\"user-subscription-organisation\"\n class=\"form-control\"\n formControlName=\"organisation\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Phone' | transloco\"\n class=\"col-md-6\"\n label=\"Contact Tel\"\n name=\"contact_tel\"\n controlId=\"user-subscription-contact_tel\"\n errorMsg=\"Please enter Contact Telephone Number\">\n <input type=\"text\"\n id=\"user-subscription-contact_tel\"\n class=\"form-control\"\n formControlName=\"contact_tel\" />\n </pw-input-container>\n @if (countries$ | async; as countries) {\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Country' | transloco\"\n class=\"col-md-6\"\n label=\"Country\"\n name=\"country_code\"\n controlId=\"user-subscription-country_code\"\n [useAriaLabelledbyOnly]=\"true\"\n [isLeftTooltip]=\"true\"\n errorMsg=\"Please select a country\">\n <p-select\n [attr.aria-labelledby]=\"'user-subscription-country_code-label'\"\n [options]=\"countries\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"country_code\"\n placeholder=\"Select Country\">\n </p-select>\n </pw-input-container>\n }\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Address' | transloco\"\n class=\"col-md-6\"\n label=\"Address\"\n name=\"address\"\n controlId=\"user-subscription-address\"\n [useAriaLabelledbyOnly]=\"true\"\n errorMsg=\"Please enter address\">\n <input ngx-gp-autocomplete\n id=\"user-subscription-address\"\n name=\"address\"\n class=\"form-control\"\n [attr.aria-labelledby]=\"'user-subscription-address-label'\"\n #places=\"ngx-places\"\n formControlName=\"address\"\n (onAddressChange)=\"handleAddressChange($event)\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.VatNumber' | transloco\"\n class=\"col-md-6\"\n label=\"GST/VAT Number\"\n name=\"tax_id\"\n controlId=\"user-subscription-tax_id\"\n errorMsg=\"Please enter GST/VAT Number\">\n <input type=\"text\"\n id=\"user-subscription-tax_id\"\n class=\"form-control\"\n formControlName=\"tax_id\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.CompanyUrl' | transloco\"\n class=\"col-md-6\"\n label=\"Company URL\"\n name=\"company_url\"\n controlId=\"user-subscription-company_url\"\n errorMsg=\"Please enter company url\">\n <input type=\"text\"\n id=\"user-subscription-company_url\"\n class=\"form-control\"\n formControlName=\"company_url\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.InvoiceRecipientEmails' | transloco\"\n class=\"col-md-6\"\n label=\"Invoice Recipient Emails\"\n name=\"invoice_recipient_emails\"\n controlId=\"user-subscription-invoice_recipient_emails\"\n errorMsg=\"Please enter valid email addresses separated by commas\">\n <input type=\"text\"\n id=\"user-subscription-invoice_recipient_emails\"\n class=\"form-control\"\n formControlName=\"invoice_recipient_emails\"\n placeholder=\"email1@example.com,email2@example.com\" />\n </pw-input-container>\n\n <!-- 2. Branding / Logos -->\n <div class=\"col-12\">\n <div class=\"row branding-section\">\n <div class=\"col-12\">\n <h3>Branding</h3>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-md-6\">\n <div class=\"text-center mt-5\">\n <div class=\"image-container\">\n <h4 class=\"mb-2\">{{ 'User.Subscriptions.FullLogo' | transloco }}\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'User.Subscriptions.Tooltip.FullLogo'|transloco\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"'top'\">\n <i class=\"far fa-info-circle text-muted\"></i>\n </span>\n </h4>\n @if (fullLogo && !fullLogo.includes('no_image_uploaded') && !fullLogoBroken) {\n <img [src]=\"fullLogo\"\n alt=\"full logo\"\n class=\"image full-logo\"\n role=\"presentation\"\n (error)=\"fullLogoBroken = true\" />\n <div class=\"overlay mt-2\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\">\n <div class=\"overlay-text\">\n <a aria-label=\"Navigate to Target\">{{ 'User.Profile.Change' | transloco }}</a>\n </div>\n </div>\n } @else {\n <div class=\"logo-dropzone full-dropzone\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Upload full logo\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\">\n <i class=\"fas fa-upload\"></i>\n <span class=\"dropzone-title\">Upload a logo</span>\n <span class=\"dropzone-hint\">PNG or JPG</span>\n </div>\n }\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"text-center mt-5\">\n <div class=\"image-container\">\n <h4 class=\"mb-2\">Squared Logo\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'User.Subscriptions.Tooltip.SquaredLogo'|transloco\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"'top'\">\n <i class=\"far fa-info-circle text-muted\"></i>\n </span>\n </h4>\n @if (squaredLogo && !squaredLogo.includes('no_image_uploaded') && !squaredLogoBroken) {\n <img [src]=\"squaredLogo\"\n alt=\"Squared Presentation\"\n class=\"squared_logo\"\n role=\"presentation\"\n (error)=\"squaredLogoBroken = true\" />\n <div class=\"overlay mt-2\"\n (keydown.enter)=\"openModal(squaredLogoContent)\"\n (click)=\"openModal(squaredLogoContent)\">\n <div class=\"overlay-text\">\n <a aria-label=\"Navigate to Target\">{{ 'User.Profile.Change' | transloco }}</a>\n </div>\n </div>\n } @else {\n <div class=\"logo-dropzone squared-dropzone\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Upload squared logo\"\n (keydown.enter)=\"openModal(squaredLogoContent)\"\n (click)=\"openModal(squaredLogoContent)\">\n <i class=\"fas fa-upload\"></i>\n <span class=\"dropzone-title\">Upload a logo</span>\n <span class=\"dropzone-hint\">PNG or JPG</span>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- 3. Social Media -->\n <ng-container *rbacAllow=\"'SubscriptionSuperAdmin'\">\n <div class=\"col-12\">\n <h3>Social Media</h3>\n <p>\n Any of the social media handles that you set here will appear in the footer of emails going out to your child subscriptions.\n </p>\n </div>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.FacebookHandle' | transloco\"\n class=\"col-md-6\"\n label=\"Facebook handle\"\n name=\"facebook_handle\"\n controlId=\"user-subscription-facebook_handle\"\n errorMsg=\"Please enter facebook id\">\n <input type=\"text\"\n id=\"user-subscription-facebook_handle\"\n class=\"form-control\"\n formControlName=\"facebook_handle\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.TwitterHandle' | transloco\"\n class=\"col-md-6\"\n label=\"Twitter handle\"\n name=\"twitter_handle\"\n controlId=\"user-subscription-twitter_handle\"\n errorMsg=\"Please enter twitter id\">\n <input type=\"text\"\n id=\"user-subscription-twitter_handle\"\n class=\"form-control\"\n formControlName=\"twitter_handle\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.LinkedinHandle' | transloco\"\n class=\"col-md-6\"\n label=\"Linkedin handle\"\n name=\"linkedin_handle\"\n controlId=\"user-subscription-linkedin_handle\"\n errorMsg=\"Please enter linkedin id\">\n <input type=\"text\"\n id=\"user-subscription-linkedin_handle\"\n class=\"form-control\"\n formControlName=\"linkedin_handle\" />\n </pw-input-container>\n <pw-input-container [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.RedditHandle' | transloco\"\n class=\"col-md-6\"\n label=\"Reddit handle\"\n name=\"reddit_handle\"\n controlId=\"user-subscription-reddit_handle\"\n errorMsg=\"Please enter reddit id\">\n <input type=\"text\"\n id=\"user-subscription-reddit_handle\"\n class=\"form-control\"\n formControlName=\"reddit_handle\" />\n </pw-input-container>\n </ng-container>\n\n <!-- 4. Seats -->\n <div class=\"col-12\">\n <div class=\"row seats-section\">\n <div class=\"col-12\">\n <h3>Seats</h3>\n <p>Changing the number of seats updates your subscription cost.</p>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n @if (subscription?.trial_subscription && subscription?.calculated_price) {\n <small\n class=\"text-danger\">Upgrade to be able to update your purchased seats</small>\n }\n </div>\n </div>\n <div class=\"row btns-row align-items-center\">\n @if (subscription) {\n <div class=\"col-md-3 col-8\"\n >\n <label for=\"user-subscription-seats\" class=\"visually-hidden\">{{ 'User.Subscriptions.Tooltip.Seats' | transloco }}</label>\n <pw-number-picker [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Seats'|transloco\"\n inputId=\"user-subscription-seats\"\n name=\"number-picker\"\n [(value)]=\"units\"\n [min]=\"subscription?.min_units||subscription?.products[0].min_units\"\n [max]=\"subscription?.products[0].max_units\"\n step=\"1\"\n postfix=\"seats\"\n placeholder=\"Total Licences\"\n [inputReadOnly]=\"subscription?.products[0].trial_subscription\"\n [showUpButton]=\"!subscription?.products[0].trial_subscription\"\n [showDownButton]=\"!subscription?.products[0].trial_subscription\"\n size=\"small\"\n pickStartAfter=\"500\"\n pickTimer=\"100\"\n [arrowKeys]=\"true\"\n (minReached)=\"onMinReached($event)\"\n (maxReached)=\"onMaxReached($event)\"\n (valueChange)=\"onUnitChange($event)\">\n </pw-number-picker>\n </div>\n }\n\n @if (subscription) {\n <div class=\"col-md-3 col-4 p-1\"\n >\n @if (!subscription?.products[0].trial_subscription && allowUpdate) {\n <button type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"updateUnits()\">\n {{ 'User.Subscriptions.UpdateUnits' | transloco }}\n </button>\n } @else {\n <div>\n @if (subscription?.products[0].trial_subscription) {\n <small class=\"text-muted\"\n >Update seats is available only to paid subscriptions</small>\n }\n </div>\n }\n </div>\n }\n\n @if (hasUnitChanged) {\n <div class=\"col-12 col-md-6\"\n >\n <table class=\"table table-borderless table-sm\"\n aria-describedby=\"Product details\">\n <thead>\n <tr>\n <th scope=\"true\">Product</th>\n <th scope=\"true\">Price per seat <span>({{subscription?.products[0]?.currency|currencySymbol}})</span></th>\n <th scope=\"true\">Seats</th>\n </tr>\n </thead>\n <tbody>\n @for (product of subscription.products; track trackByProduct($index, product)) {\n <tr>\n <td>{{ product.name }}</td>\n <td>{{ product.price_per_unit / 100 }}</td>\n <td>{{ units }}</td>\n </tr>\n }\n </tbody>\n </table>\n <p>\n If you proceed, the new cost for your subscription will be\n <strong>{{ totalAmount()| currency: subscription?.products[0]?.currency:'symbol-narrow'}}</strong>\n </p>\n </div>\n }\n </div>\n </div>\n\n <!-- 5. API & MCP Credentials -->\n @if (subscription?.api_hits_max > 0) {\n <div class=\"col-12\">\n <h3>{{ 'User.Subscriptions.APICredentials.Title' | transloco }}</h3>\n <p>\n These credentials authenticate both REST API and MCP (Model Context Protocol) requests, and must be used together with the user tokens defined on your Account page.\n </p>\n </div>\n <div class=\"col-md-6\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"user-subscription-api-token\">\n {{ 'User.Subscriptions.APICredentials.AccessToken' | transloco }}\n <span class=\"tooltip-wrap ms-1\"\n pTooltip=\"The subscription token has been discontinued in favour of the user token defined on your Account page.\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"'top'\">\n <i class=\"far fa-info-circle text-muted\"></i>\n </span>\n </label>\n <div class=\"input-group\">\n <input type=\"text\"\n id=\"user-subscription-api-token\"\n name=\"api_token\"\n class=\"form-control\"\n [value]=\"showApiToken ? subscription?.api_access_token || ('User.Subscriptions.APICredentials.NoTokenAvailable' | transloco) : '*************************'\"\n readonly />\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"toggleApiTokenVisibility()\">\n {{ showApiToken ? ('User.Subscriptions.APICredentials.Hide' | transloco) : ('User.Subscriptions.APICredentials.View' | transloco) }}\n </button>\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"form-group\">\n <label class=\"form-label\" for=\"user-subscription-api-client-id\">{{ 'User.Subscriptions.APICredentials.ClientId' | transloco }}</label>\n <div class=\"input-group\">\n <input type=\"text\"\n id=\"user-subscription-api-client-id\"\n name=\"api_client_id\"\n class=\"form-control\"\n [value]=\"showApiClientId ? subscription?.api_client_id || ('User.Subscriptions.APICredentials.NoClientIdAvailable' | transloco) : '*************************'\"\n readonly />\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"toggleApiClientIdVisibility()\">\n {{ showApiClientId ? ('User.Subscriptions.APICredentials.Hide' | transloco) : ('User.Subscriptions.APICredentials.View' | transloco) }}\n </button>\n </div>\n </div>\n </div>\n <div class=\"col-12 mt-3\">\n <div class=\"d-flex align-items-center gap-3\">\n <button type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"refreshApiTokens()\"\n [disabled]=\"refreshingTokens\">\n <i class=\"fas fa-sync-alt me-2\" [class.fa-spin]=\"refreshingTokens\"></i>\n {{ refreshingTokens ? ('User.Subscriptions.APICredentials.Refreshing' | transloco) : ('User.Subscriptions.APICredentials.RefreshTokens' | transloco) }}\n </button>\n <div class=\"d-flex align-items-center gap-2\">\n @if (subscription?.api_hits !== null) {\n <span class=\"text-muted\">{{ 'User.Subscriptions.APICredentials.ApiHits' | transloco }}:</span>\n <span class=\"fw-bold\">{{ subscription.api_hits | number }}</span>\n }\n @if (subscription?.api_hits_max !== null) {\n <span class=\"text-muted\">{{ 'User.Subscriptions.APICredentials.ApiHitsMax' | transloco }}:</span>\n <span class=\"fw-bold\">{{ subscription.api_hits_max | number }}</span>\n }\n <!-- Show utilization percentage when both values exist -->\n @if (subscription?.api_hits !== null || subscription?.api_hits_max !== null) {\n <span class=\"text-muted ms-2\">(</span>\n <span class=\"fw-bold\" [ngClass]=\"{\n 'text-success': (subscription.api_hits / subscription.api_hits_max) <= 0.8,\n 'text-warning': (subscription.api_hits / subscription.api_hits_max) > 0.8 && (subscription.api_hits / subscription.api_hits_max) <= 0.9,\n 'text-danger': (subscription.api_hits / subscription.api_hits_max) > 0.9\n }\">\n {{ (subscription.api_hits / subscription.api_hits_max * 100) | number:'1.0-0' }}% consumed\n </span>\n <span class=\"text-muted\">)</span>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- 6. Security -->\n <div class=\"col-12 mt-5\">\n <h3>Security</h3>\n <p>\n While we'll add more security options in the future, please start by enforcing 2FA for all your subscription members.\n </p>\n </div>\n <div class=\"col-12 col-sm-3\">\n <pw-input-container label=\"Enforce 2FA\"\n [showTooltip]=\"true\"\n [tooltipText]=\"'User.Subscriptions.Tooltip.Enforce2fa' | transloco\"\n name=\"enforce_2fa\"\n controlId=\"user-subscription-enforce_2fa\"\n [useAriaLabelledbyOnly]=\"true\">\n <ui-switch formControlName=\"enforce_2fa\"\n name=\"enforce_2fa\"\n [attr.aria-labelledby]=\"'user-subscription-enforce_2fa-label'\"> </ui-switch>\n </pw-input-container>\n </div>\n <div class=\"mb-3 col-12 text-end mt-3\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n routerLink=\"/account/subscriptions\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button name=\"submit\"\n type=\"submit\"\n [buttonBusy]=\"busyButton\"\n class=\"btn btn-primary\">\n {{ 'Button.Submit' | transloco }}\n </button>\n </div>\n </form>\n}\n\n<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h3 class=\"modal-title mb-0 p-0\">{{ 'User.Subscriptions.FullLogo' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n (imageSelectionEvent)=\"onImageSelection($event)\"\n aspectRatio=\"fullLogo\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n</ng-template>\n<ng-template #squaredLogoContent\n let-modal>\n <div class=\"modal-header\">\n <h3 class=\"modal-title mb-0 p-0\">{{ 'User.Subscriptions.SquaredLogo' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n (imageSelectionEvent)=\"uploadSquaredLogo($event)\"\n aspectRatio=\"auto\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n</ng-template>\n<pw-password-validation #modal\n(successEvent)=\"onPasswordValidation($event)\"> </pw-password-validation>\n", styles: [":host{display:block}:host>.row:first-of-type h3{color:var(--titles, #222);font-size:24px;font-weight:700;letter-spacing:-.01em;line-height:1.18}:host form .col-12>h3,:host .seats-section>.col-12>h3,:host .branding-section>.col-12>h3{border-top:1px solid #e2e5ea;color:var(--titles, #222);display:block;font-size:18px;font-weight:600;margin-top:32px;padding-top:24px}:host form>.col-12:first-child>h3{border-top:0;margin-top:0;padding-top:0}:host form .col-12>p,:host .seats-section>.col-12>p{color:#5a6473;font-size:15px;margin-bottom:16px}:host .row .text-center.mt-5{margin-top:16px!important;text-align:left!important}:host .image-container>h4{color:var(--titles, #222);font-size:14px;font-weight:600}:host .full-logo,:host .squared_logo{background:#f7f8fa;border:1px solid #e2e5ea;border-radius:8px;object-fit:contain;padding:12px}:host .full-logo{height:120px;width:280px}:host .squared_logo{height:150px;width:150px}:host .overlay{cursor:pointer;margin-top:8px}:host .overlay-text a{color:var(--first, #1769e1);cursor:pointer;font-weight:600}:host .overlay-text a:hover{text-decoration:underline}.sub-header{color:gray;font-size:20px;font-weight:600}@media only screen and (max-width:767px){.btns-row>[class*=col-]{flex:0 0 100%;max-width:100%}.btns-row .btn-primary{font-size:.8rem;margin-top:5px;padding:.375rem .5rem}}\n"] }]
1602
1601
  }], ctorParameters: () => [{ type: i2.UntypedFormBuilder }, { type: i1$2.GeoService }, { type: i1$1.NgbModal }, { type: i1$2.SubscriptionService }, { type: i4$2.Store }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }], propDecorators: { modal: [{
1603
1602
  type: ViewChild,
1604
1603
  args: ['modal', { static: true }]
@@ -1683,9 +1682,11 @@ class UserSubscriptionListComponent extends AppBaseComponent {
1683
1682
  this.cdr.markForCheck();
1684
1683
  });
1685
1684
  }
1686
- updateApiKey(item) {
1687
- this.subscriptionService.updateSubscriptionAPIKey(item.id).subscribe(response => {
1688
- item.api_access_token = response;
1685
+ updateApiKey(subscription, product) {
1686
+ this.subscriptionService
1687
+ .updateSubscriptionAPIKey(subscription.id, product.id)
1688
+ .subscribe(response => {
1689
+ product.api_access_token = response;
1689
1690
  this.toast.success(this.translation.translate('User.Subscriptions.UpdatedKey'));
1690
1691
  this.getSubscribedProduct();
1691
1692
  this.cdr.markForCheck();
@@ -1805,11 +1806,11 @@ class UserSubscriptionListComponent extends AppBaseComponent {
1805
1806
  super.ngOnDestroy();
1806
1807
  }
1807
1808
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserSubscriptionListComponent, deps: [{ token: i1$2.SubscriptionService }, { token: i2$1.AdminService }, { token: i1$1.NgbModal }, { token: i4$2.Store }, { token: i5$1.Clipboard }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1808
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: UserSubscriptionListComponent, isStandalone: false, selector: "pw-user-subscriptions-list", viewQueries: [{ propertyName: "menu", first: true, predicate: ["menuItems"], descendants: true }, { propertyName: "changeSubscriptionRef", first: true, predicate: AddSubscriptionComponent, descendants: true }, { propertyName: "passwordValidationModalForAccountDelete", first: true, predicate: ["passwordValidationModalForAccountDelete"], descendants: true }, { propertyName: "passwordValidationModalForKey", first: true, predicate: ["passwordValidationModalForKey"], descendants: true }, { propertyName: "passwordValidationForUnsubscribe", first: true, predicate: ["passwordValidationForUnsubscribe"], descendants: true }, { propertyName: "cancelSubscriptionModal", first: true, predicate: ["cancelSubscriptionModal"], descendants: true }], usesInheritance: true, ngImport: i0, template: "@if (!showTos) {\n <!-- Subscriptions Tab Content -->\n @if (!editing && !isAddNew) {\n <div class=\"row\"\n >\n <div class=\"col-12\">\n <h2>Your Subscriptions</h2>\n <p class=\"float-start\">You'll find in this section the summary of your subscriptions.</p>\n <div class=\"text-end\">\n <!-- Delete Account -->\n <button type=\"button\"\n class=\"btn btn-sm btn-outline-danger px-3 mt-2 me-2 me-sm-2\"\n (click)=\"showModalForAccountDeletion()\"\n [pTooltip]=\"'User.Account.Tooltip.DeleteAccount' | transloco\"\n tooltipPosition=\"bottom\">\n {{ 'User.Account.DeleteAccount' | transloco }}\n </button>\n </div>\n </div>\n </div>\n }\n <!-- Subscribed Product Cards -->\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (\n !editing && !isAddNew && !isUpdatePayment && isLoaded && subscribedSubscriptions.length\n ) {\n <div class=\"row\"\n >\n @for (subscription of subscribedSubscriptions; track trackBySubscription($index, subscription)) {\n <div class=\"col-12 col-md-6 my-4\"\n >\n <div class=\"subscription-details mb-4\">\n <div class=\"float-start\">\n <div>\n <strong>Organisation:</strong>\n {{\n subscription.organisation\n ? subscription.organisation\n : subscription.contact_name\n }}\n </div>\n <div>\n <strong>{{ 'User.Subscriptions.TotalPriceExclTax' | transloco }}:</strong>\n @if (subscription.calculated_price) {\n {{\n subscription.calculated_price / 100\n | currency: subscription.products[0]?.currency:'symbol-narrow'\n }}\n {{ subscription.products[0].trial_subscription ? '(After Trial)' : '' }}\n } @else {\n Free\n }\n </div>\n <div>\n <strong>{{ 'User.Subscriptions.TotalPurchasedSeats' | transloco }}:</strong>\n {{ subscription.purchased_units }}\n </div>\n <div>\n <div>\n <strong>{{ 'User.Subscriptions.SeatsInUse' | transloco }}:</strong>\n {{ subscription.units_in_use || 1 }}\n </div>\n </div>\n </div>\n <!-- Products list -->\n @for (\n product of subscription.products; track trackByProduct($index,\n product); let first = $first) {\n <div>\n @if (first) {\n <!-- Edit -->\n @if (\n !product.deleted &&\n (subscription.is_subscription_owner ||\n subscription.is_subscription_admin) &&\n !product.dependency_products?.length\n ) {\n <div\n class=\"float-end m-2 m-sm-2\">\n <a class=\"btn btn-outline-primary btn-sm mx-1\"\n aria-label=\"Navigate to Target\"\n [routerLink]=\"['../subscriptions', subscription.id]\">\n {{ 'Button.Edit' | transloco }}\n </a>\n @if (\n !product.expired &&\n !product.deleted &&\n !product.trial_subscription\n ) {\n <button [routerLink]=\"['../subscriptions', subscription.id, 'credential']\"\n class=\"btn btn-dark btn-sm float-end mx-1\">\n {{ 'User.Subscriptions.Credentials' | transloco }}\n </button>\n }\n <!-- Update Card Details -->\n @if (!isUpdatePayment && subscription.stripe_customer_id) {\n <a class=\"btn btn-sm btn-outline-primary mx-1 me-sm-2\"\n [routerLink]=\"[\n '../subscriptions',\n subscription.id,\n 'product',\n product.id,\n 'update-payment'\n ]\">\n <i class=\"fa fa-edit\" aria-hidden=\"true\"></i>\n {{ 'User.Subscriptions.UpdateCardDetails' | transloco }}</a>\n }\n </div>\n }\n <!-- Add New Subscription -->\n @if (\n !product.deleted &&\n (subscription.is_subscription_owner ||\n subscription.is_subscription_admin) &&\n !product.dependency_products?.length\n ) {\n <div class=\"float-end m-2 m-sm-2\"\n >\n <button class=\"btn btn-sm btn-primary\"\n [routerLink]=\"'/account/subscriptions/add-new'\"\n [queryParams]=\"{ subscription_id: subscription.id }\"\n [pTooltip]=\"\n 'User.Subscriptions.Tooltip.ManageAllProducts' | transloco\n \"\n tooltipPosition=\"bottom\">\n <i class=\"fa fa-plus-circle\"></i>\n {{ 'User.Subscriptions.SeeAllProducts' | transloco }}\n </button>\n </div>\n }\n }\n <div class=\"card subscription-products-cards\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <div>\n <h4 class=\"mb-3 text-bold-500 primary\">{{ product?.name }}</h4>\n <!-- Frequency -->\n <div>\n <div>\n <strong class=\"d-inline-block w-50\">{{\n 'User.Subscriptions.Frequency' | transloco\n }}:</strong>\n {{ product?.billing_frequency | uppercase }}\n </div>\n </div>\n <!-- Expiration -->\n <div [ngClass]=\"{ 'text-danger': product.expired }\">\n <strong class=\"d-inline-block w-50\">{{\n product.expired ? 'Expired' : 'Expiry Date'\n }}:</strong>\n {{ product.expires_at | dateFormat }}\n </div>\n <!-- Estimated Price -->\n <div [ngClass]=\"{ 'text-danger': product.expired }\">\n <strong class=\"d-inline-block w-50\">{{\n 'User.Subscriptions.PriceExclTax' | transloco\n }}:</strong>\n {{ product.currency }}\n {{ (product.calculated_price / 100) | number:'1.2-2' }}\n </div>\n <!-- API Key -->\n @if (\n (product.stripe_plan_id && product.max_hits > 0) ||\n product.max_hits_trial > 0\n ) {\n <div class=\"d-inline\">\n <strong class=\"d-inline-block w-50\">{{\n 'User.Subscriptions.ApiKey' | transloco\n }}:</strong>\n <code class=\"d-inline me-2\">{{ product.masked }}</code>\n </div>\n <div class=\"float-end\">\n <!-- Show Access Key -->\n <button class=\"btn\"\n ngbTooltip=\"Show Access Key\"\n (click)=\"showKey(product)\">\n <i class=\"fas fa-eye\" aria-hidden=\"true\"></i>\n </button>\n <!-- Copy To Clipboard -->\n <button class=\"btn\"\n ngbTooltip=\"Copy Key\">\n <i\n class=\"fal fa-copy\"\n aria-hidden=\"true\"\n (click)=\"\n onClipboardCopy(product.api_access_token)\n \"\n (keydown.enter)=\"onClipboardCopy(product.api_access_token)\"\n ></i>\n </button>\n <!-- Update API Key -->\n @if (!product.expired && !product.deleted) {\n <button class=\"btn\"\n ngbTooltip=\"Change Key\"\n (click)=\"updateApiKey(product)\">\n <i class=\"fal fa-sync-alt\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n }\n <div class=\"clearfix\"></div>\n </div>\n </div>\n <div class=\"card-footer px-3\">\n <div class=\"float-start\">\n @if (product.deleted && !product.expired) {\n <div>\n <i class=\"fa fa-info-circle me-2\" aria-hidden=\"true\"></i>{{ 'User.Subscriptions.OutdatedMessage' | transloco }}\n </div>\n }\n <div>\n @if (product.deleted) {\n <span\n class=\"badge bg-danger me-2\">Deleted</span>\n }\n @if (\n product.trial_subscription &&\n product.calculated_price\n ) {\n <span class=\"badge bg-warning me-2\"\n >\n Trial</span>\n }\n @if (product?.pause_collection && objectKeys(product?.pause_collection)?.length) {\n <span class=\"badge bg-grey me-2\"\n [pTooltip]=\"'User.Subscriptions.Tooltip.PausedCollection'|transloco\"\n tooltipPosition=\"top\">\n Paused collection\n </span>\n }\n @if (!product.calculated_price) {\n <span class=\"badge bg-success me-2\"\n >\n Free\n </span>\n }\n </div>\n </div>\n @if (\n subscription.is_subscription_owner ||\n subscription.is_subscription_admin\n ) {\n <!-- Unsubscribe -->\n @if (\n subscription?.stripe_customer_id&&\n !product?.deleted &&\n !product?.trial_subscription\n ) {\n <button class=\"btn btn-outline-danger btn-sm float-end me-2\"\n (click)=\"attemptUnsubscribe(subscription, product.id)\">\n {{ 'User.Subscriptions.Unsubscribe' | transloco }}\n </button>\n }\n @if (product?.product_privacy_service_id) {\n <button class=\"badge bg-dark me-2 float-end\"\n (click)=\"showPrivacyAndTos(product)\">\n {{\n 'User.Subscriptions.PrivacyAndTermsOfService'\n | transloco\n }}\n </button>\n }\n @if (product.stripe_plan_id && product.active) {\n <!-- Upgrade -->\n @if (product.trial_subscription && !product.deleted) {\n <button class=\"btn btn-primary btn-sm me-2 float-end\"\n (click)=\"attemptUpgrade(subscription, product)\">\n {{ 'Button.Upgrade' | transloco }}\n </button>\n }\n <!-- Subscribe -->\n @if (subscription.expired && product.stripe_plan_id) {\n <button class=\"btn btn-primary btn-sm float-start\"\n [routerLink]=\"'/account/subscriptions/add-new'\">\n {{ 'User.Subscriptions.Subscribe' | transloco }}\n </button>\n }\n }\n }\n @if (!product?.deleted && !subscription.is_subscription_owner) {\n <div>\n <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i> Invited to\n use this product\n @if (subscription.is_subscription_admin) {\n <span\n class=\"fw-bold\">as an admin</span>\n }\n </div>\n }\n </div>\n </div>\n </div>\n @if (subscription.products.length === 0) {\n <div>\n <div class=\"card\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <p class=\"text-center\">\n No product available for this subscription\n </p>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n @if (!editing && !isAddNew && !isUpdatePayment) {\n <div class=\"col-12\"\n >\n @if (subscribedSubscriptions.length === 0) {\n <pw-no-data [withImage]=\"true\" message=\"You don't have any subscription.\"\n >\n </pw-no-data>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n <!--\n Add New Subscription\n -->\n <!-- <ng-template [ngIf]=\"isAddNew && !isUpdatePayment\">\n <pw-subscription-details></pw-subscription-details>\n</ng-template> -->\n<!--\nValidate Password For Account Delete\n-->\n<pw-password-validation #passwordValidationModalForAccountDelete\n (successEvent)=\"deleteUser($event)\">\n <div class=\"row\">\n <div class=\"col-12\">\n <p>{{ 'User.Account.Message.ActionCanNotUndone' | transloco }}</p>\n <p>{{ 'User.Account.Message.ConfirmPassword' | transloco }}</p>\n </div>\n </div>\n</pw-password-validation>\n<!--\nValidate Password For Display Key\n-->\n<pw-password-validation #passwordValidationModalForKey\n (successEvent)=\"displayApiKey()\">\n</pw-password-validation>\n<!--\nValidate Password For Unsubscribe\n-->\n<pw-password-validation #passwordValidationForUnsubscribe\n (successEvent)=\"onValidatePassword($event)\">\n <div class=\"row\">\n <div class=\"col-12\">\n <p>{{ 'User.Account.Message.ActionCanNotUndone' | transloco }}</p>\n <p>{{ 'User.Account.Message.ConfirmPassword' | transloco }}</p>\n </div>\n </div>\n</pw-password-validation>\n<!--\nCancel Subscription Modal\n-->\n<ng-template #cancelSubscriptionModal let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\">{{ 'User.Subscriptions.CancelSubscription.Title' | transloco }}</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss(); reasonToCancel = '';\">\n </button>\n </div>\n <div class=\"modal-body\">\n <p>{{ 'User.Subscriptions.CancelSubscription.Message' | transloco }}</p>\n <div class=\"mb-3\">\n <label for=\"reasonToCancel\" class=\"form-label\">\n {{ 'User.Subscriptions.CancelSubscription.ReasonLabel' | transloco }} <span class=\"text-danger\">*</span>\n </label>\n <textarea\n id=\"reasonToCancel\"\n class=\"form-control\"\n rows=\"4\"\n [(ngModel)]=\"reasonToCancel\"\n [ngClass]=\"{'is-invalid': reasonToCancel && reasonToCancel.trim() === ''}\"\n placeholder=\"{{ 'User.Subscriptions.CancelSubscription.ReasonPlaceholder' | transloco }}\"></textarea>\n @if (reasonToCancel && reasonToCancel.trim() === '') {\n <div class=\"invalid-feedback\">\n {{ 'User.Subscriptions.Validation.ReasonRequired' | transloco }}\n </div>\n }\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.dismiss(); reasonToCancel = '';\">\n {{ 'User.Subscriptions.CancelSubscription.KeepItForNow' | transloco }}\n </button>\n <button type=\"button\"\n class=\"btn btn-danger\"\n [disabled]=\"!reasonToCancel || reasonToCancel.trim() === ''\"\n (click)=\"onConfirmCancel(); modal.close()\">\n {{ 'User.Subscriptions.CancelSubscription.ConfirmButton' | transloco }}\n </button>\n </div>\n</ng-template>\n}\n\n@if (showTos) {\n <pw-privacy-and-tos [productId]=\"productId\"></pw-privacy-and-tos>\n}\n\n<router-outlet></router-outlet>\n", styles: [".btn-list{bottom:24px;left:0;padding:0 38px;right:0}.shadow-md{padding-bottom:70px!important}.bg-dark{border:0}.subscription-products-cards{padding-bottom:0!important}.subscription-products-cards .card-footer{position:static!important}\n"], dependencies: [{ kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { 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: "component", type: i5.PasswordValidationComponent, selector: "pw-password-validation", inputs: ["confirmMessage"], outputs: ["successEvent"] }, { kind: "directive", type: i1$1.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i5.PrivacyAndTosComponent, selector: "pw-privacy-and-tos", inputs: ["productId"] }, { kind: "component", type: i5.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "directive", type: i6$4.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "pipe", type: i6.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: i6.DecimalPipe, name: "number" }, { kind: "pipe", type: i6.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i6$3.DateFormatPipe, name: "dateFormat" }] }); }
1809
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: UserSubscriptionListComponent, isStandalone: false, selector: "pw-user-subscriptions-list", viewQueries: [{ propertyName: "menu", first: true, predicate: ["menuItems"], descendants: true }, { propertyName: "changeSubscriptionRef", first: true, predicate: AddSubscriptionComponent, descendants: true }, { propertyName: "passwordValidationModalForAccountDelete", first: true, predicate: ["passwordValidationModalForAccountDelete"], descendants: true }, { propertyName: "passwordValidationModalForKey", first: true, predicate: ["passwordValidationModalForKey"], descendants: true }, { propertyName: "passwordValidationForUnsubscribe", first: true, predicate: ["passwordValidationForUnsubscribe"], descendants: true }, { propertyName: "cancelSubscriptionModal", first: true, predicate: ["cancelSubscriptionModal"], descendants: true }], usesInheritance: true, ngImport: i0, template: "@if (!showTos) {\n <!-- Subscriptions Tab Content -->\n @if (!editing && !isAddNew) {\n <div class=\"row\">\n <div class=\"col-12\">\n <h2>Your Subscriptions</h2>\n <p>You'll find in this section the summary of your subscriptions.</p>\n </div>\n </div>\n }\n <!-- Subscribed Product Cards -->\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (\n !editing && !isAddNew && !isUpdatePayment && isLoaded && subscribedSubscriptions.length\n ) {\n <div class=\"row\"\n >\n @for (subscription of subscribedSubscriptions; track trackBySubscription($index, subscription)) {\n <div class=\"col-12 col-md-6 my-3\"\n >\n <div class=\"subscription-details mb-4\">\n <div class=\"subscription-summary d-flex flex-wrap justify-content-between align-items-start gap-2 mb-3\">\n <div class=\"subscription-summary__info\">\n <div>\n <strong>Organisation:</strong>\n {{ subscription.organisation ? subscription.organisation : subscription.contact_name }}\n </div>\n <div>\n <strong>{{ 'User.Subscriptions.TotalPriceExclTax' | transloco }}:</strong>\n @if (subscription.calculated_price) {\n {{ subscription.products[0]?.currency }} {{ subscription.calculated_price / 100 | number:'1.2-2' }}\n {{ subscription.products[0].trial_subscription ? '(After Trial)' : '' }}\n } @else {\n Free\n }\n </div>\n <div>\n <strong>{{ 'User.Subscriptions.SeatsInUse' | transloco }}:</strong>\n {{ subscription.units_in_use || 1 }} / {{ subscription.purchased_units }}\n @if (subscription.purchased_units) {\n <span class=\"seats-usage\"\n [style.--seats-pct]=\"(subscription.units_in_use || 1) / subscription.purchased_units\"></span>\n }\n </div>\n </div>\n <!-- Subscription-level actions (a subscription may hold multiple products) -->\n @if (\n (subscription.is_subscription_owner || subscription.is_subscription_admin) &&\n subscription.products?.length &&\n !subscription.products[0].deleted &&\n !subscription.products[0].dependency_products?.length\n ) {\n <div class=\"subscription-summary__actions d-flex flex-wrap align-items-center gap-2\">\n <a class=\"btn btn-outline-primary btn-sm\"\n aria-label=\"Navigate to Target\"\n [routerLink]=\"['../subscriptions', subscription.id]\">\n {{ 'Button.Edit' | transloco }}\n </a>\n @if (!subscription.products[0].expired && !subscription.products[0].trial_subscription) {\n <button [routerLink]=\"['../subscriptions', subscription.id, 'credential']\"\n class=\"btn btn-outline-secondary btn-sm\">\n {{ 'User.Subscriptions.Credentials' | transloco }}\n </button>\n }\n @if (!isUpdatePayment && subscription.stripe_customer_id) {\n <a class=\"btn btn-sm btn-outline-primary\"\n [routerLink]=\"['../subscriptions', subscription.id, 'product', subscription.products[0].id, 'update-payment']\">\n <i class=\"fa fa-edit me-1\" aria-hidden=\"true\"></i>{{ 'User.Subscriptions.UpdateCardDetails' | transloco }}</a>\n }\n <button class=\"btn btn-sm btn-outline-primary\"\n [routerLink]=\"'/account/subscriptions/add-new'\"\n [queryParams]=\"{ subscription_id: subscription.id }\"\n [pTooltip]=\"'User.Subscriptions.Tooltip.ManageAllProducts' | transloco\"\n tooltipPosition=\"bottom\">\n <i class=\"fa fa-plus me-1\"></i>{{ 'User.Subscriptions.SeeAllProducts' | transloco }}\n </button>\n </div>\n }\n </div>\n <!-- Products list -->\n @for (\n product of subscription.products; track trackByProduct($index,\n product); let first = $first) {\n <div class=\"mb-3\">\n <div class=\"card subscription-products-cards\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <div>\n <h4 class=\"mb-3 text-bold-500 primary\">{{ product?.name }}</h4>\n <!-- Frequency -->\n <div>\n <div>\n <strong class=\"d-inline-block w-50\">{{\n 'User.Subscriptions.Frequency' | transloco\n }}:</strong>\n {{ product?.billing_frequency | uppercase }}\n </div>\n </div>\n <!-- Expiration -->\n <div [ngClass]=\"{ 'text-danger': product.expired }\">\n <strong class=\"d-inline-block w-50\">{{\n product.expired ? 'Expired' : 'Expiry Date'\n }}:</strong>\n {{ product.expires_at | dateFormat }}\n </div>\n <!-- Estimated Price -->\n <div [ngClass]=\"{ 'text-danger': product.expired }\">\n <strong class=\"d-inline-block w-50\">{{\n 'User.Subscriptions.PriceExclTax' | transloco\n }}:</strong>\n {{ product.currency }}\n {{ (product.calculated_price / 100) | number:'1.2-2' }}\n </div>\n <!-- Product API Key (Alpha-only) -->\n <ng-container *rbacAllow=\"'Pages.Alpha'\">\n @if (\n (product.stripe_plan_id && product.max_hits > 0) ||\n product.max_hits_trial > 0\n ) {\n <div class=\"d-flex align-items-center\">\n <strong class=\"d-inline-block w-50\">\n {{ 'User.Subscriptions.ApiKey' | transloco }}:\n <i class=\"far fa-info-circle ms-1 text-muted\"\n aria-hidden=\"true\"\n [ngbTooltip]=\"'User.Subscriptions.ApiKey.NotUsedHint' | transloco\"></i>\n </strong>\n <code class=\"text-truncate me-2\">{{ product.masked }}</code>\n <span class=\"ms-auto d-flex align-items-center flex-shrink-0\">\n <!-- Show Access Key -->\n <button class=\"btn\"\n ngbTooltip=\"Show Access Key\"\n (click)=\"showKey(product)\">\n <i class=\"fas fa-eye\" aria-hidden=\"true\"></i>\n </button>\n <!-- Copy To Clipboard -->\n <button class=\"btn\"\n ngbTooltip=\"Copy Key\">\n <i class=\"fal fa-copy\"\n aria-hidden=\"true\"\n (click)=\"onClipboardCopy(product.api_access_token)\"\n (keydown.enter)=\"onClipboardCopy(product.api_access_token)\"></i>\n </button>\n <!-- Update API Key -->\n @if (!product.expired && !product.deleted) {\n <button class=\"btn\"\n ngbTooltip=\"Change Key\"\n (click)=\"updateApiKey(subscription, product)\">\n <i class=\"fal fa-sync-alt\" aria-hidden=\"true\"></i>\n </button>\n }\n </span>\n </div>\n }\n </ng-container>\n </div>\n </div>\n <div class=\"card-footer px-3 d-flex flex-column gap-2\">\n <div class=\"footer-status d-flex flex-wrap align-items-center gap-2\">\n @if (product.deleted && !product.expired) {\n <span class=\"footer-note\">\n <i class=\"fa fa-info-circle me-2\" aria-hidden=\"true\"></i>{{ 'User.Subscriptions.OutdatedMessage' | transloco }}\n </span>\n }\n @if (product.deleted) {\n <span class=\"badge bg-danger\">Deleted</span>\n }\n @if (\n product.trial_subscription &&\n product.calculated_price\n ) {\n <span class=\"badge bg-warning\">Trial</span>\n }\n @if (product?.pause_collection && objectKeys(product?.pause_collection)?.length) {\n <span class=\"badge bg-grey\"\n [pTooltip]=\"'User.Subscriptions.Tooltip.PausedCollection'|transloco\"\n tooltipPosition=\"top\">\n Paused collection\n </span>\n }\n @if (!product.calculated_price) {\n <span class=\"badge bg-success\">Free</span>\n }\n @if (!product?.deleted && !subscription.is_subscription_owner) {\n <span class=\"footer-note\">\n <i class=\"fa fa-info-circle me-2\" aria-hidden=\"true\"></i>Invited to use this product\n @if (subscription.is_subscription_admin) {\n <span class=\"badge bg-role-admin ms-1\">as an admin</span>\n }\n </span>\n }\n </div>\n @if (\n subscription.is_subscription_owner ||\n subscription.is_subscription_admin\n ) {\n <div class=\"footer-actions d-flex flex-wrap align-items-center justify-content-end gap-2\">\n <!-- Unsubscribe -->\n @if (\n subscription?.stripe_customer_id &&\n !product?.deleted &&\n !product?.trial_subscription\n ) {\n <button class=\"btn btn-outline-danger btn-sm\"\n (click)=\"attemptUnsubscribe(subscription, product.id)\">\n {{ 'User.Subscriptions.Unsubscribe' | transloco }}\n </button>\n }\n @if (product.stripe_plan_id && product.active) {\n <!-- Upgrade (single primary CTA) -->\n @if (product.trial_subscription && !product.deleted) {\n <button class=\"btn btn-primary btn-sm\"\n (click)=\"attemptUpgrade(subscription, product)\">\n {{ 'Button.Upgrade' | transloco }}\n </button>\n }\n <!-- Subscribe -->\n @if (subscription.expired && product.stripe_plan_id) {\n <button class=\"btn btn-primary btn-sm\"\n [routerLink]=\"'/account/subscriptions/add-new'\">\n {{ 'User.Subscriptions.Subscribe' | transloco }}\n </button>\n }\n }\n <!-- Privacy & Terms of Service (quiet link, not a button) -->\n @if (product?.product_privacy_service_id) {\n <button class=\"btn btn-link btn-sm p-0 footer-tos-link\"\n (click)=\"showPrivacyAndTos(product)\">\n {{\n 'User.Subscriptions.PrivacyAndTermsOfService'\n | transloco\n }}\n </button>\n }\n </div>\n }\n </div>\n </div>\n </div>\n @if (subscription.products.length === 0) {\n <div>\n <div class=\"card\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <p class=\"text-center\">\n No product available for this subscription\n </p>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n @if (!editing && !isAddNew && !isUpdatePayment) {\n <div class=\"col-12\"\n >\n @if (subscribedSubscriptions.length === 0) {\n <pw-no-data [withImage]=\"true\" message=\"You don't have any subscription.\"\n >\n </pw-no-data>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n <!-- Danger zone (demoted account deletion) -->\n @if (!editing && !isAddNew && !isUpdatePayment && isLoaded) {\n <div class=\"row\">\n <div class=\"col-12\">\n <div class=\"danger-zone mt-4\">\n <button type=\"button\"\n class=\"btn btn-sm btn-outline-danger danger-zone__action\"\n (click)=\"showModalForAccountDeletion()\"\n [pTooltip]=\"'User.Account.Tooltip.DeleteAccount' | transloco\"\n tooltipPosition=\"top\">\n {{ 'User.Account.DeleteAccount' | transloco }}\n </button>\n </div>\n </div>\n </div>\n }\n <!--\n Add New Subscription\n -->\n <!-- <ng-template [ngIf]=\"isAddNew && !isUpdatePayment\">\n <pw-subscription-details></pw-subscription-details>\n</ng-template> -->\n<!--\nValidate Password For Account Delete\n-->\n<pw-password-validation #passwordValidationModalForAccountDelete\n (successEvent)=\"deleteUser($event)\">\n <div class=\"row\">\n <div class=\"col-12\">\n <p>{{ 'User.Account.Message.ActionCanNotUndone' | transloco }}</p>\n <p>{{ 'User.Account.Message.ConfirmPassword' | transloco }}</p>\n </div>\n </div>\n</pw-password-validation>\n<!--\nValidate Password For Display Key\n-->\n<pw-password-validation #passwordValidationModalForKey\n (successEvent)=\"displayApiKey()\">\n</pw-password-validation>\n<!--\nValidate Password For Unsubscribe\n-->\n<pw-password-validation #passwordValidationForUnsubscribe\n (successEvent)=\"onValidatePassword($event)\">\n <div class=\"row\">\n <div class=\"col-12\">\n <p>{{ 'User.Account.Message.ActionCanNotUndone' | transloco }}</p>\n <p>{{ 'User.Account.Message.ConfirmPassword' | transloco }}</p>\n </div>\n </div>\n</pw-password-validation>\n<!--\nCancel Subscription Modal\n-->\n<ng-template #cancelSubscriptionModal let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\">{{ 'User.Subscriptions.CancelSubscription.Title' | transloco }}</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss(); reasonToCancel = '';\">\n </button>\n </div>\n <div class=\"modal-body\">\n <p>{{ 'User.Subscriptions.CancelSubscription.Message' | transloco }}</p>\n <div class=\"mb-3\">\n <label for=\"reasonToCancel\" class=\"form-label\">\n {{ 'User.Subscriptions.CancelSubscription.ReasonLabel' | transloco }} <span class=\"text-danger\">*</span>\n </label>\n <textarea\n id=\"reasonToCancel\"\n class=\"form-control\"\n rows=\"4\"\n [(ngModel)]=\"reasonToCancel\"\n [ngClass]=\"{'is-invalid': reasonToCancel && reasonToCancel.trim() === ''}\"\n placeholder=\"{{ 'User.Subscriptions.CancelSubscription.ReasonPlaceholder' | transloco }}\"></textarea>\n @if (reasonToCancel && reasonToCancel.trim() === '') {\n <div class=\"invalid-feedback\">\n {{ 'User.Subscriptions.Validation.ReasonRequired' | transloco }}\n </div>\n }\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.dismiss(); reasonToCancel = '';\">\n {{ 'User.Subscriptions.CancelSubscription.KeepItForNow' | transloco }}\n </button>\n <button type=\"button\"\n class=\"btn btn-danger\"\n [disabled]=\"!reasonToCancel || reasonToCancel.trim() === ''\"\n (click)=\"onConfirmCancel(); modal.close()\">\n {{ 'User.Subscriptions.CancelSubscription.ConfirmButton' | transloco }}\n </button>\n </div>\n</ng-template>\n}\n\n@if (showTos) {\n <pw-privacy-and-tos [productId]=\"productId\"></pw-privacy-and-tos>\n}\n\n<router-outlet></router-outlet>\n", styles: [".btn-list{bottom:24px;left:0;padding:0 38px;right:0}.shadow-md{padding-bottom:70px!important}.bg-dark{border:0}.subscription-details{background:#fff;border:1px solid #e2e5ea;border-radius:12px;padding:16px 16px 6px;font-size:14px;font-variant-numeric:tabular-nums}.subscription-summary{border-bottom:1px solid #eef0f3;padding-bottom:12px}.seats-usage{display:inline-block;width:120px;height:6px;margin-left:8px;border-radius:999px;vertical-align:middle;overflow:hidden;background:linear-gradient(#5a6473,#5a6473) left/calc(var(--seats-pct, 0) * 100%) 100% no-repeat,#e2e5ea}.subscription-products-cards{padding-bottom:0!important}.subscription-products-cards .card-footer{position:static!important}.subscription-products-cards.card{background:#f7f8fa;border:1px solid #eef0f3;border-radius:8px;box-shadow:none!important;font-size:14px}.card-footer{background:transparent;border-top:1px solid #eef0f3}.card-footer .footer-note{color:#5a6473;font-size:.875rem}.card-footer .footer-tos-link{color:#5a6473;font-weight:500;text-decoration:underline}.card-footer .footer-tos-link:hover{color:var(--first)}.badge{font-weight:600;border-radius:4px}.badge.bg-success{background-color:#e6f4ec!important;color:#0f6b3a!important}.badge.bg-danger{background-color:#fbeae8!important;color:#c0392b!important}.badge.bg-warning{background-color:#fbf1e3!important;color:#8a5a00!important}.badge.bg-grey,.badge.bg-role-admin{background-color:#eef0f3!important;color:#5a6473!important}code{color:var(--text);min-width:0}.danger-zone{border-top:1px solid #e2e5ea;padding-top:16px;text-align:right}\n"], dependencies: [{ kind: "directive", type: i4.RbacAllowDirective, selector: "[rbacAllow]", inputs: ["rbacAllow"] }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { 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: "component", type: i5.PasswordValidationComponent, selector: "pw-password-validation", inputs: ["confirmMessage"], outputs: ["successEvent"] }, { kind: "directive", type: i1$1.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i5.PrivacyAndTosComponent, selector: "pw-privacy-and-tos", inputs: ["productId"] }, { kind: "component", type: i5.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "directive", type: i11.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "pipe", type: i6.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: i6.DecimalPipe, name: "number" }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i6$3.DateFormatPipe, name: "dateFormat" }] }); }
1809
1810
  }
1810
1811
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserSubscriptionListComponent, decorators: [{
1811
1812
  type: Component,
1812
- args: [{ selector: 'pw-user-subscriptions-list', standalone: false, template: "@if (!showTos) {\n <!-- Subscriptions Tab Content -->\n @if (!editing && !isAddNew) {\n <div class=\"row\"\n >\n <div class=\"col-12\">\n <h2>Your Subscriptions</h2>\n <p class=\"float-start\">You'll find in this section the summary of your subscriptions.</p>\n <div class=\"text-end\">\n <!-- Delete Account -->\n <button type=\"button\"\n class=\"btn btn-sm btn-outline-danger px-3 mt-2 me-2 me-sm-2\"\n (click)=\"showModalForAccountDeletion()\"\n [pTooltip]=\"'User.Account.Tooltip.DeleteAccount' | transloco\"\n tooltipPosition=\"bottom\">\n {{ 'User.Account.DeleteAccount' | transloco }}\n </button>\n </div>\n </div>\n </div>\n }\n <!-- Subscribed Product Cards -->\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (\n !editing && !isAddNew && !isUpdatePayment && isLoaded && subscribedSubscriptions.length\n ) {\n <div class=\"row\"\n >\n @for (subscription of subscribedSubscriptions; track trackBySubscription($index, subscription)) {\n <div class=\"col-12 col-md-6 my-4\"\n >\n <div class=\"subscription-details mb-4\">\n <div class=\"float-start\">\n <div>\n <strong>Organisation:</strong>\n {{\n subscription.organisation\n ? subscription.organisation\n : subscription.contact_name\n }}\n </div>\n <div>\n <strong>{{ 'User.Subscriptions.TotalPriceExclTax' | transloco }}:</strong>\n @if (subscription.calculated_price) {\n {{\n subscription.calculated_price / 100\n | currency: subscription.products[0]?.currency:'symbol-narrow'\n }}\n {{ subscription.products[0].trial_subscription ? '(After Trial)' : '' }}\n } @else {\n Free\n }\n </div>\n <div>\n <strong>{{ 'User.Subscriptions.TotalPurchasedSeats' | transloco }}:</strong>\n {{ subscription.purchased_units }}\n </div>\n <div>\n <div>\n <strong>{{ 'User.Subscriptions.SeatsInUse' | transloco }}:</strong>\n {{ subscription.units_in_use || 1 }}\n </div>\n </div>\n </div>\n <!-- Products list -->\n @for (\n product of subscription.products; track trackByProduct($index,\n product); let first = $first) {\n <div>\n @if (first) {\n <!-- Edit -->\n @if (\n !product.deleted &&\n (subscription.is_subscription_owner ||\n subscription.is_subscription_admin) &&\n !product.dependency_products?.length\n ) {\n <div\n class=\"float-end m-2 m-sm-2\">\n <a class=\"btn btn-outline-primary btn-sm mx-1\"\n aria-label=\"Navigate to Target\"\n [routerLink]=\"['../subscriptions', subscription.id]\">\n {{ 'Button.Edit' | transloco }}\n </a>\n @if (\n !product.expired &&\n !product.deleted &&\n !product.trial_subscription\n ) {\n <button [routerLink]=\"['../subscriptions', subscription.id, 'credential']\"\n class=\"btn btn-dark btn-sm float-end mx-1\">\n {{ 'User.Subscriptions.Credentials' | transloco }}\n </button>\n }\n <!-- Update Card Details -->\n @if (!isUpdatePayment && subscription.stripe_customer_id) {\n <a class=\"btn btn-sm btn-outline-primary mx-1 me-sm-2\"\n [routerLink]=\"[\n '../subscriptions',\n subscription.id,\n 'product',\n product.id,\n 'update-payment'\n ]\">\n <i class=\"fa fa-edit\" aria-hidden=\"true\"></i>\n {{ 'User.Subscriptions.UpdateCardDetails' | transloco }}</a>\n }\n </div>\n }\n <!-- Add New Subscription -->\n @if (\n !product.deleted &&\n (subscription.is_subscription_owner ||\n subscription.is_subscription_admin) &&\n !product.dependency_products?.length\n ) {\n <div class=\"float-end m-2 m-sm-2\"\n >\n <button class=\"btn btn-sm btn-primary\"\n [routerLink]=\"'/account/subscriptions/add-new'\"\n [queryParams]=\"{ subscription_id: subscription.id }\"\n [pTooltip]=\"\n 'User.Subscriptions.Tooltip.ManageAllProducts' | transloco\n \"\n tooltipPosition=\"bottom\">\n <i class=\"fa fa-plus-circle\"></i>\n {{ 'User.Subscriptions.SeeAllProducts' | transloco }}\n </button>\n </div>\n }\n }\n <div class=\"card subscription-products-cards\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <div>\n <h4 class=\"mb-3 text-bold-500 primary\">{{ product?.name }}</h4>\n <!-- Frequency -->\n <div>\n <div>\n <strong class=\"d-inline-block w-50\">{{\n 'User.Subscriptions.Frequency' | transloco\n }}:</strong>\n {{ product?.billing_frequency | uppercase }}\n </div>\n </div>\n <!-- Expiration -->\n <div [ngClass]=\"{ 'text-danger': product.expired }\">\n <strong class=\"d-inline-block w-50\">{{\n product.expired ? 'Expired' : 'Expiry Date'\n }}:</strong>\n {{ product.expires_at | dateFormat }}\n </div>\n <!-- Estimated Price -->\n <div [ngClass]=\"{ 'text-danger': product.expired }\">\n <strong class=\"d-inline-block w-50\">{{\n 'User.Subscriptions.PriceExclTax' | transloco\n }}:</strong>\n {{ product.currency }}\n {{ (product.calculated_price / 100) | number:'1.2-2' }}\n </div>\n <!-- API Key -->\n @if (\n (product.stripe_plan_id && product.max_hits > 0) ||\n product.max_hits_trial > 0\n ) {\n <div class=\"d-inline\">\n <strong class=\"d-inline-block w-50\">{{\n 'User.Subscriptions.ApiKey' | transloco\n }}:</strong>\n <code class=\"d-inline me-2\">{{ product.masked }}</code>\n </div>\n <div class=\"float-end\">\n <!-- Show Access Key -->\n <button class=\"btn\"\n ngbTooltip=\"Show Access Key\"\n (click)=\"showKey(product)\">\n <i class=\"fas fa-eye\" aria-hidden=\"true\"></i>\n </button>\n <!-- Copy To Clipboard -->\n <button class=\"btn\"\n ngbTooltip=\"Copy Key\">\n <i\n class=\"fal fa-copy\"\n aria-hidden=\"true\"\n (click)=\"\n onClipboardCopy(product.api_access_token)\n \"\n (keydown.enter)=\"onClipboardCopy(product.api_access_token)\"\n ></i>\n </button>\n <!-- Update API Key -->\n @if (!product.expired && !product.deleted) {\n <button class=\"btn\"\n ngbTooltip=\"Change Key\"\n (click)=\"updateApiKey(product)\">\n <i class=\"fal fa-sync-alt\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n }\n <div class=\"clearfix\"></div>\n </div>\n </div>\n <div class=\"card-footer px-3\">\n <div class=\"float-start\">\n @if (product.deleted && !product.expired) {\n <div>\n <i class=\"fa fa-info-circle me-2\" aria-hidden=\"true\"></i>{{ 'User.Subscriptions.OutdatedMessage' | transloco }}\n </div>\n }\n <div>\n @if (product.deleted) {\n <span\n class=\"badge bg-danger me-2\">Deleted</span>\n }\n @if (\n product.trial_subscription &&\n product.calculated_price\n ) {\n <span class=\"badge bg-warning me-2\"\n >\n Trial</span>\n }\n @if (product?.pause_collection && objectKeys(product?.pause_collection)?.length) {\n <span class=\"badge bg-grey me-2\"\n [pTooltip]=\"'User.Subscriptions.Tooltip.PausedCollection'|transloco\"\n tooltipPosition=\"top\">\n Paused collection\n </span>\n }\n @if (!product.calculated_price) {\n <span class=\"badge bg-success me-2\"\n >\n Free\n </span>\n }\n </div>\n </div>\n @if (\n subscription.is_subscription_owner ||\n subscription.is_subscription_admin\n ) {\n <!-- Unsubscribe -->\n @if (\n subscription?.stripe_customer_id&&\n !product?.deleted &&\n !product?.trial_subscription\n ) {\n <button class=\"btn btn-outline-danger btn-sm float-end me-2\"\n (click)=\"attemptUnsubscribe(subscription, product.id)\">\n {{ 'User.Subscriptions.Unsubscribe' | transloco }}\n </button>\n }\n @if (product?.product_privacy_service_id) {\n <button class=\"badge bg-dark me-2 float-end\"\n (click)=\"showPrivacyAndTos(product)\">\n {{\n 'User.Subscriptions.PrivacyAndTermsOfService'\n | transloco\n }}\n </button>\n }\n @if (product.stripe_plan_id && product.active) {\n <!-- Upgrade -->\n @if (product.trial_subscription && !product.deleted) {\n <button class=\"btn btn-primary btn-sm me-2 float-end\"\n (click)=\"attemptUpgrade(subscription, product)\">\n {{ 'Button.Upgrade' | transloco }}\n </button>\n }\n <!-- Subscribe -->\n @if (subscription.expired && product.stripe_plan_id) {\n <button class=\"btn btn-primary btn-sm float-start\"\n [routerLink]=\"'/account/subscriptions/add-new'\">\n {{ 'User.Subscriptions.Subscribe' | transloco }}\n </button>\n }\n }\n }\n @if (!product?.deleted && !subscription.is_subscription_owner) {\n <div>\n <i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i> Invited to\n use this product\n @if (subscription.is_subscription_admin) {\n <span\n class=\"fw-bold\">as an admin</span>\n }\n </div>\n }\n </div>\n </div>\n </div>\n @if (subscription.products.length === 0) {\n <div>\n <div class=\"card\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <p class=\"text-center\">\n No product available for this subscription\n </p>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n @if (!editing && !isAddNew && !isUpdatePayment) {\n <div class=\"col-12\"\n >\n @if (subscribedSubscriptions.length === 0) {\n <pw-no-data [withImage]=\"true\" message=\"You don't have any subscription.\"\n >\n </pw-no-data>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n <!--\n Add New Subscription\n -->\n <!-- <ng-template [ngIf]=\"isAddNew && !isUpdatePayment\">\n <pw-subscription-details></pw-subscription-details>\n</ng-template> -->\n<!--\nValidate Password For Account Delete\n-->\n<pw-password-validation #passwordValidationModalForAccountDelete\n (successEvent)=\"deleteUser($event)\">\n <div class=\"row\">\n <div class=\"col-12\">\n <p>{{ 'User.Account.Message.ActionCanNotUndone' | transloco }}</p>\n <p>{{ 'User.Account.Message.ConfirmPassword' | transloco }}</p>\n </div>\n </div>\n</pw-password-validation>\n<!--\nValidate Password For Display Key\n-->\n<pw-password-validation #passwordValidationModalForKey\n (successEvent)=\"displayApiKey()\">\n</pw-password-validation>\n<!--\nValidate Password For Unsubscribe\n-->\n<pw-password-validation #passwordValidationForUnsubscribe\n (successEvent)=\"onValidatePassword($event)\">\n <div class=\"row\">\n <div class=\"col-12\">\n <p>{{ 'User.Account.Message.ActionCanNotUndone' | transloco }}</p>\n <p>{{ 'User.Account.Message.ConfirmPassword' | transloco }}</p>\n </div>\n </div>\n</pw-password-validation>\n<!--\nCancel Subscription Modal\n-->\n<ng-template #cancelSubscriptionModal let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\">{{ 'User.Subscriptions.CancelSubscription.Title' | transloco }}</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss(); reasonToCancel = '';\">\n </button>\n </div>\n <div class=\"modal-body\">\n <p>{{ 'User.Subscriptions.CancelSubscription.Message' | transloco }}</p>\n <div class=\"mb-3\">\n <label for=\"reasonToCancel\" class=\"form-label\">\n {{ 'User.Subscriptions.CancelSubscription.ReasonLabel' | transloco }} <span class=\"text-danger\">*</span>\n </label>\n <textarea\n id=\"reasonToCancel\"\n class=\"form-control\"\n rows=\"4\"\n [(ngModel)]=\"reasonToCancel\"\n [ngClass]=\"{'is-invalid': reasonToCancel && reasonToCancel.trim() === ''}\"\n placeholder=\"{{ 'User.Subscriptions.CancelSubscription.ReasonPlaceholder' | transloco }}\"></textarea>\n @if (reasonToCancel && reasonToCancel.trim() === '') {\n <div class=\"invalid-feedback\">\n {{ 'User.Subscriptions.Validation.ReasonRequired' | transloco }}\n </div>\n }\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.dismiss(); reasonToCancel = '';\">\n {{ 'User.Subscriptions.CancelSubscription.KeepItForNow' | transloco }}\n </button>\n <button type=\"button\"\n class=\"btn btn-danger\"\n [disabled]=\"!reasonToCancel || reasonToCancel.trim() === ''\"\n (click)=\"onConfirmCancel(); modal.close()\">\n {{ 'User.Subscriptions.CancelSubscription.ConfirmButton' | transloco }}\n </button>\n </div>\n</ng-template>\n}\n\n@if (showTos) {\n <pw-privacy-and-tos [productId]=\"productId\"></pw-privacy-and-tos>\n}\n\n<router-outlet></router-outlet>\n", styles: [".btn-list{bottom:24px;left:0;padding:0 38px;right:0}.shadow-md{padding-bottom:70px!important}.bg-dark{border:0}.subscription-products-cards{padding-bottom:0!important}.subscription-products-cards .card-footer{position:static!important}\n"] }]
1813
+ args: [{ selector: 'pw-user-subscriptions-list', standalone: false, template: "@if (!showTos) {\n <!-- Subscriptions Tab Content -->\n @if (!editing && !isAddNew) {\n <div class=\"row\">\n <div class=\"col-12\">\n <h2>Your Subscriptions</h2>\n <p>You'll find in this section the summary of your subscriptions.</p>\n </div>\n </div>\n }\n <!-- Subscribed Product Cards -->\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (\n !editing && !isAddNew && !isUpdatePayment && isLoaded && subscribedSubscriptions.length\n ) {\n <div class=\"row\"\n >\n @for (subscription of subscribedSubscriptions; track trackBySubscription($index, subscription)) {\n <div class=\"col-12 col-md-6 my-3\"\n >\n <div class=\"subscription-details mb-4\">\n <div class=\"subscription-summary d-flex flex-wrap justify-content-between align-items-start gap-2 mb-3\">\n <div class=\"subscription-summary__info\">\n <div>\n <strong>Organisation:</strong>\n {{ subscription.organisation ? subscription.organisation : subscription.contact_name }}\n </div>\n <div>\n <strong>{{ 'User.Subscriptions.TotalPriceExclTax' | transloco }}:</strong>\n @if (subscription.calculated_price) {\n {{ subscription.products[0]?.currency }} {{ subscription.calculated_price / 100 | number:'1.2-2' }}\n {{ subscription.products[0].trial_subscription ? '(After Trial)' : '' }}\n } @else {\n Free\n }\n </div>\n <div>\n <strong>{{ 'User.Subscriptions.SeatsInUse' | transloco }}:</strong>\n {{ subscription.units_in_use || 1 }} / {{ subscription.purchased_units }}\n @if (subscription.purchased_units) {\n <span class=\"seats-usage\"\n [style.--seats-pct]=\"(subscription.units_in_use || 1) / subscription.purchased_units\"></span>\n }\n </div>\n </div>\n <!-- Subscription-level actions (a subscription may hold multiple products) -->\n @if (\n (subscription.is_subscription_owner || subscription.is_subscription_admin) &&\n subscription.products?.length &&\n !subscription.products[0].deleted &&\n !subscription.products[0].dependency_products?.length\n ) {\n <div class=\"subscription-summary__actions d-flex flex-wrap align-items-center gap-2\">\n <a class=\"btn btn-outline-primary btn-sm\"\n aria-label=\"Navigate to Target\"\n [routerLink]=\"['../subscriptions', subscription.id]\">\n {{ 'Button.Edit' | transloco }}\n </a>\n @if (!subscription.products[0].expired && !subscription.products[0].trial_subscription) {\n <button [routerLink]=\"['../subscriptions', subscription.id, 'credential']\"\n class=\"btn btn-outline-secondary btn-sm\">\n {{ 'User.Subscriptions.Credentials' | transloco }}\n </button>\n }\n @if (!isUpdatePayment && subscription.stripe_customer_id) {\n <a class=\"btn btn-sm btn-outline-primary\"\n [routerLink]=\"['../subscriptions', subscription.id, 'product', subscription.products[0].id, 'update-payment']\">\n <i class=\"fa fa-edit me-1\" aria-hidden=\"true\"></i>{{ 'User.Subscriptions.UpdateCardDetails' | transloco }}</a>\n }\n <button class=\"btn btn-sm btn-outline-primary\"\n [routerLink]=\"'/account/subscriptions/add-new'\"\n [queryParams]=\"{ subscription_id: subscription.id }\"\n [pTooltip]=\"'User.Subscriptions.Tooltip.ManageAllProducts' | transloco\"\n tooltipPosition=\"bottom\">\n <i class=\"fa fa-plus me-1\"></i>{{ 'User.Subscriptions.SeeAllProducts' | transloco }}\n </button>\n </div>\n }\n </div>\n <!-- Products list -->\n @for (\n product of subscription.products; track trackByProduct($index,\n product); let first = $first) {\n <div class=\"mb-3\">\n <div class=\"card subscription-products-cards\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <div>\n <h4 class=\"mb-3 text-bold-500 primary\">{{ product?.name }}</h4>\n <!-- Frequency -->\n <div>\n <div>\n <strong class=\"d-inline-block w-50\">{{\n 'User.Subscriptions.Frequency' | transloco\n }}:</strong>\n {{ product?.billing_frequency | uppercase }}\n </div>\n </div>\n <!-- Expiration -->\n <div [ngClass]=\"{ 'text-danger': product.expired }\">\n <strong class=\"d-inline-block w-50\">{{\n product.expired ? 'Expired' : 'Expiry Date'\n }}:</strong>\n {{ product.expires_at | dateFormat }}\n </div>\n <!-- Estimated Price -->\n <div [ngClass]=\"{ 'text-danger': product.expired }\">\n <strong class=\"d-inline-block w-50\">{{\n 'User.Subscriptions.PriceExclTax' | transloco\n }}:</strong>\n {{ product.currency }}\n {{ (product.calculated_price / 100) | number:'1.2-2' }}\n </div>\n <!-- Product API Key (Alpha-only) -->\n <ng-container *rbacAllow=\"'Pages.Alpha'\">\n @if (\n (product.stripe_plan_id && product.max_hits > 0) ||\n product.max_hits_trial > 0\n ) {\n <div class=\"d-flex align-items-center\">\n <strong class=\"d-inline-block w-50\">\n {{ 'User.Subscriptions.ApiKey' | transloco }}:\n <i class=\"far fa-info-circle ms-1 text-muted\"\n aria-hidden=\"true\"\n [ngbTooltip]=\"'User.Subscriptions.ApiKey.NotUsedHint' | transloco\"></i>\n </strong>\n <code class=\"text-truncate me-2\">{{ product.masked }}</code>\n <span class=\"ms-auto d-flex align-items-center flex-shrink-0\">\n <!-- Show Access Key -->\n <button class=\"btn\"\n ngbTooltip=\"Show Access Key\"\n (click)=\"showKey(product)\">\n <i class=\"fas fa-eye\" aria-hidden=\"true\"></i>\n </button>\n <!-- Copy To Clipboard -->\n <button class=\"btn\"\n ngbTooltip=\"Copy Key\">\n <i class=\"fal fa-copy\"\n aria-hidden=\"true\"\n (click)=\"onClipboardCopy(product.api_access_token)\"\n (keydown.enter)=\"onClipboardCopy(product.api_access_token)\"></i>\n </button>\n <!-- Update API Key -->\n @if (!product.expired && !product.deleted) {\n <button class=\"btn\"\n ngbTooltip=\"Change Key\"\n (click)=\"updateApiKey(subscription, product)\">\n <i class=\"fal fa-sync-alt\" aria-hidden=\"true\"></i>\n </button>\n }\n </span>\n </div>\n }\n </ng-container>\n </div>\n </div>\n <div class=\"card-footer px-3 d-flex flex-column gap-2\">\n <div class=\"footer-status d-flex flex-wrap align-items-center gap-2\">\n @if (product.deleted && !product.expired) {\n <span class=\"footer-note\">\n <i class=\"fa fa-info-circle me-2\" aria-hidden=\"true\"></i>{{ 'User.Subscriptions.OutdatedMessage' | transloco }}\n </span>\n }\n @if (product.deleted) {\n <span class=\"badge bg-danger\">Deleted</span>\n }\n @if (\n product.trial_subscription &&\n product.calculated_price\n ) {\n <span class=\"badge bg-warning\">Trial</span>\n }\n @if (product?.pause_collection && objectKeys(product?.pause_collection)?.length) {\n <span class=\"badge bg-grey\"\n [pTooltip]=\"'User.Subscriptions.Tooltip.PausedCollection'|transloco\"\n tooltipPosition=\"top\">\n Paused collection\n </span>\n }\n @if (!product.calculated_price) {\n <span class=\"badge bg-success\">Free</span>\n }\n @if (!product?.deleted && !subscription.is_subscription_owner) {\n <span class=\"footer-note\">\n <i class=\"fa fa-info-circle me-2\" aria-hidden=\"true\"></i>Invited to use this product\n @if (subscription.is_subscription_admin) {\n <span class=\"badge bg-role-admin ms-1\">as an admin</span>\n }\n </span>\n }\n </div>\n @if (\n subscription.is_subscription_owner ||\n subscription.is_subscription_admin\n ) {\n <div class=\"footer-actions d-flex flex-wrap align-items-center justify-content-end gap-2\">\n <!-- Unsubscribe -->\n @if (\n subscription?.stripe_customer_id &&\n !product?.deleted &&\n !product?.trial_subscription\n ) {\n <button class=\"btn btn-outline-danger btn-sm\"\n (click)=\"attemptUnsubscribe(subscription, product.id)\">\n {{ 'User.Subscriptions.Unsubscribe' | transloco }}\n </button>\n }\n @if (product.stripe_plan_id && product.active) {\n <!-- Upgrade (single primary CTA) -->\n @if (product.trial_subscription && !product.deleted) {\n <button class=\"btn btn-primary btn-sm\"\n (click)=\"attemptUpgrade(subscription, product)\">\n {{ 'Button.Upgrade' | transloco }}\n </button>\n }\n <!-- Subscribe -->\n @if (subscription.expired && product.stripe_plan_id) {\n <button class=\"btn btn-primary btn-sm\"\n [routerLink]=\"'/account/subscriptions/add-new'\">\n {{ 'User.Subscriptions.Subscribe' | transloco }}\n </button>\n }\n }\n <!-- Privacy & Terms of Service (quiet link, not a button) -->\n @if (product?.product_privacy_service_id) {\n <button class=\"btn btn-link btn-sm p-0 footer-tos-link\"\n (click)=\"showPrivacyAndTos(product)\">\n {{\n 'User.Subscriptions.PrivacyAndTermsOfService'\n | transloco\n }}\n </button>\n }\n </div>\n }\n </div>\n </div>\n </div>\n @if (subscription.products.length === 0) {\n <div>\n <div class=\"card\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <p class=\"text-center\">\n No product available for this subscription\n </p>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n @if (!editing && !isAddNew && !isUpdatePayment) {\n <div class=\"col-12\"\n >\n @if (subscribedSubscriptions.length === 0) {\n <pw-no-data [withImage]=\"true\" message=\"You don't have any subscription.\"\n >\n </pw-no-data>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n <!-- Danger zone (demoted account deletion) -->\n @if (!editing && !isAddNew && !isUpdatePayment && isLoaded) {\n <div class=\"row\">\n <div class=\"col-12\">\n <div class=\"danger-zone mt-4\">\n <button type=\"button\"\n class=\"btn btn-sm btn-outline-danger danger-zone__action\"\n (click)=\"showModalForAccountDeletion()\"\n [pTooltip]=\"'User.Account.Tooltip.DeleteAccount' | transloco\"\n tooltipPosition=\"top\">\n {{ 'User.Account.DeleteAccount' | transloco }}\n </button>\n </div>\n </div>\n </div>\n }\n <!--\n Add New Subscription\n -->\n <!-- <ng-template [ngIf]=\"isAddNew && !isUpdatePayment\">\n <pw-subscription-details></pw-subscription-details>\n</ng-template> -->\n<!--\nValidate Password For Account Delete\n-->\n<pw-password-validation #passwordValidationModalForAccountDelete\n (successEvent)=\"deleteUser($event)\">\n <div class=\"row\">\n <div class=\"col-12\">\n <p>{{ 'User.Account.Message.ActionCanNotUndone' | transloco }}</p>\n <p>{{ 'User.Account.Message.ConfirmPassword' | transloco }}</p>\n </div>\n </div>\n</pw-password-validation>\n<!--\nValidate Password For Display Key\n-->\n<pw-password-validation #passwordValidationModalForKey\n (successEvent)=\"displayApiKey()\">\n</pw-password-validation>\n<!--\nValidate Password For Unsubscribe\n-->\n<pw-password-validation #passwordValidationForUnsubscribe\n (successEvent)=\"onValidatePassword($event)\">\n <div class=\"row\">\n <div class=\"col-12\">\n <p>{{ 'User.Account.Message.ActionCanNotUndone' | transloco }}</p>\n <p>{{ 'User.Account.Message.ConfirmPassword' | transloco }}</p>\n </div>\n </div>\n</pw-password-validation>\n<!--\nCancel Subscription Modal\n-->\n<ng-template #cancelSubscriptionModal let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\">{{ 'User.Subscriptions.CancelSubscription.Title' | transloco }}</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss(); reasonToCancel = '';\">\n </button>\n </div>\n <div class=\"modal-body\">\n <p>{{ 'User.Subscriptions.CancelSubscription.Message' | transloco }}</p>\n <div class=\"mb-3\">\n <label for=\"reasonToCancel\" class=\"form-label\">\n {{ 'User.Subscriptions.CancelSubscription.ReasonLabel' | transloco }} <span class=\"text-danger\">*</span>\n </label>\n <textarea\n id=\"reasonToCancel\"\n class=\"form-control\"\n rows=\"4\"\n [(ngModel)]=\"reasonToCancel\"\n [ngClass]=\"{'is-invalid': reasonToCancel && reasonToCancel.trim() === ''}\"\n placeholder=\"{{ 'User.Subscriptions.CancelSubscription.ReasonPlaceholder' | transloco }}\"></textarea>\n @if (reasonToCancel && reasonToCancel.trim() === '') {\n <div class=\"invalid-feedback\">\n {{ 'User.Subscriptions.Validation.ReasonRequired' | transloco }}\n </div>\n }\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.dismiss(); reasonToCancel = '';\">\n {{ 'User.Subscriptions.CancelSubscription.KeepItForNow' | transloco }}\n </button>\n <button type=\"button\"\n class=\"btn btn-danger\"\n [disabled]=\"!reasonToCancel || reasonToCancel.trim() === ''\"\n (click)=\"onConfirmCancel(); modal.close()\">\n {{ 'User.Subscriptions.CancelSubscription.ConfirmButton' | transloco }}\n </button>\n </div>\n</ng-template>\n}\n\n@if (showTos) {\n <pw-privacy-and-tos [productId]=\"productId\"></pw-privacy-and-tos>\n}\n\n<router-outlet></router-outlet>\n", styles: [".btn-list{bottom:24px;left:0;padding:0 38px;right:0}.shadow-md{padding-bottom:70px!important}.bg-dark{border:0}.subscription-details{background:#fff;border:1px solid #e2e5ea;border-radius:12px;padding:16px 16px 6px;font-size:14px;font-variant-numeric:tabular-nums}.subscription-summary{border-bottom:1px solid #eef0f3;padding-bottom:12px}.seats-usage{display:inline-block;width:120px;height:6px;margin-left:8px;border-radius:999px;vertical-align:middle;overflow:hidden;background:linear-gradient(#5a6473,#5a6473) left/calc(var(--seats-pct, 0) * 100%) 100% no-repeat,#e2e5ea}.subscription-products-cards{padding-bottom:0!important}.subscription-products-cards .card-footer{position:static!important}.subscription-products-cards.card{background:#f7f8fa;border:1px solid #eef0f3;border-radius:8px;box-shadow:none!important;font-size:14px}.card-footer{background:transparent;border-top:1px solid #eef0f3}.card-footer .footer-note{color:#5a6473;font-size:.875rem}.card-footer .footer-tos-link{color:#5a6473;font-weight:500;text-decoration:underline}.card-footer .footer-tos-link:hover{color:var(--first)}.badge{font-weight:600;border-radius:4px}.badge.bg-success{background-color:#e6f4ec!important;color:#0f6b3a!important}.badge.bg-danger{background-color:#fbeae8!important;color:#c0392b!important}.badge.bg-warning{background-color:#fbf1e3!important;color:#8a5a00!important}.badge.bg-grey,.badge.bg-role-admin{background-color:#eef0f3!important;color:#5a6473!important}code{color:var(--text);min-width:0}.danger-zone{border-top:1px solid #e2e5ea;padding-top:16px;text-align:right}\n"] }]
1813
1814
  }], ctorParameters: () => [{ type: i1$2.SubscriptionService }, { type: i2$1.AdminService }, { type: i1$1.NgbModal }, { type: i4$2.Store }, { type: i5$1.Clipboard }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }], propDecorators: { menu: [{
1814
1815
  type: ViewChild,
1815
1816
  args: ['menuItems', { static: false }]
@@ -1887,11 +1888,11 @@ class UserInvoiceComponent extends AppBaseComponent {
1887
1888
  }
1888
1889
  }
1889
1890
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserInvoiceComponent, deps: [{ token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1890
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: UserInvoiceComponent, isStandalone: false, selector: "pw-user-invoice", usesInheritance: true, ngImport: i0, template: "<div class=\"row\" [class.custom-disable-wrapper]=\"buttonBusy\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-center\">\n <h2 class=\"card-title p-0 float-start\">Your Invoices</h2>\n </div>\n</div>\n\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\">\n <p-progressSpinner strokeWidth=\"2\"></p-progressSpinner>\n </div>\n}\n<div class=\"row primeng-datatable-container mt-0\" [class.custom-disable-wrapper]=\"buttonBusy\" [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <div class=\"col-12 px-0\">\n <p-table #tt\n [value]=\"invoices\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [lazy]=\"true\"\n [totalRecords]=\"totalRecords\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n >\n <ng-template pTemplate=\"caption\">\n <div class=\"search-filter justify-content-end\">\n <div class=\"text-end\">\n <label for=\"user-invoice-search\" class=\"visually-hidden\">Search Invoices</label>\n <i class=\"fa fa-search mt-2 me-2\" aria-hidden=\"true\"></i>\n <input id=\"user-invoice-search\"\n name=\"user-invoice-search\"\n [(ngModel)]=\"searchText\"\n (input)=\"tt.filterGlobal($event.target.value, 'contains')\"\n type=\"text\"\n pInputText\n size=\"50\"\n placeholder=\"Search Invoices...\"\n data-cy=\"incident-search\"\n class=\"wd-90\">\n </div>\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"col\" pSortableColumn=\"date\">Invoice Date <p-sortIcon field=\"date\"></p-sortIcon></th>\n <th scope=\"col\" pSortableColumn=\"frequency\">Frequency <p-sortIcon field=\"frequency\"></p-sortIcon></th>\n <th scope=\"col\" pSortableColumn=\"seatsPurchased\">Seats Purchased <p-sortIcon field=\"seatsPurchased\"></p-sortIcon></th>\n <th scope=\"col\" pSortableColumn=\"subtotal\">Subtotal <p-sortIcon field=\"subtotal\"></p-sortIcon></th>\n <th scope=\"col\" pSortableColumn=\"total\">Total (incl. tax) <p-sortIcon field=\"total\"></p-sortIcon></th>\n <th scope=\"col\">Action</th>\n </tr>\n </ng-template>\n\n <ng-template pTemplate=\"body\" let-invoice>\n <tr>\n <td>{{ invoice.date | date:'dd-MMM-yyyy' }}</td>\n <td>\n <span class=\"badge\"\n [appDynamicBadge]=\"{\n itemsArray: invoiceFrequency,\n item: invoice.product.billing_frequency\n }\"\n color=\"blue-grey\">{{ invoice.product.billing_frequency }}</span>\n </td>\n <td>{{ invoice?.subscription_product?.purchased_units }}</td>\n <td>{{ (invoice.subtotal_in_cents / 100) | currency:invoice?.product?.currency }}</td>\n <td class=\"td-total\">{{ (invoice.total_in_cents / 100) | currency:invoice?.product?.currency }}</td>\n <td>\n @if (invoice?.file?.url) {\n <a class=\"btn btn-sm btn-primary\" [attr.href]=\"invoice.file.url\" target=\"_blank\" title=\"Download\">\n <i class=\"fa fa-download\">&nbsp;Download</i>\n </a>\n } @else {\n <a class=\"btn btn-sm btn-primary\" [attr.href]=\"invoice?.stripe_invoice_pdf\" target=\"_blank\" title=\"Download\">\n <i class=\"fa fa-download\">&nbsp;Download</i>\n </a>\n }\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n\n @if (totalRecords !== 0) {\n <span class=\"total-records-count\">Total: {{ totalRecords }}</span>\n }\n\n </div>\n</div>\n@if (totalRecordsUnFiltered === 0 && isLoaded) {\n <pw-no-data [withImage]=\"true\" message=\"You don't have any invoice yet.\">\n </pw-no-data>\n}\n\n", styles: [".page-heading{background:#fcfcfc;border-bottom:1px solid rgba(0,0,0,.1);position:relative;width:100%}.page-heading:after{clear:both;content:\"\";display:table}.page-heading .page-heading__container{padding:15px 20px;position:relative}.page-heading .page-heading__container .title{color:#242437;font-size:15px;font-weight:500;line-height:20px;margin:3px 0 0;overflow:hidden;padding:0;text-overflow:ellipsis;width:95%}.card .card-container{position:absolute;right:20px;top:25px;z-index:1}.td-total{font-weight:700}.card-inner-container{background:#0000000d;border:1px dashed rgba(0,0,0,.1);border-radius:3px;margin-bottom:20px;padding:20px}.invoice-text{display:flex;font-size:13px;justify-content:space-between;margin:10px 0}.invoice-template{min-height:calc(100vh - 190px)}\n"], dependencies: [{ kind: "directive", type: i1$3.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: i4.DynamicBadgeDirective, selector: "[appDynamicBadge]", inputs: ["appDynamicBadge", "color", "colorByName", "dataName"] }, { 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: "component", type: i4$3.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i5$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i4$3.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "component", type: i4$3.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i5.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i6.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i6.DatePipe, name: "date" }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
1891
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: UserInvoiceComponent, isStandalone: false, selector: "pw-user-invoice", usesInheritance: true, ngImport: i0, template: "<div class=\"row\" [class.custom-disable-wrapper]=\"buttonBusy\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-center\">\n <h2 class=\"card-title p-0 float-start\">Your Invoices</h2>\n </div>\n</div>\n\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\">\n <p-progressSpinner strokeWidth=\"2\"></p-progressSpinner>\n </div>\n}\n<div class=\"row primeng-datatable-container actions-collapsed mt-0\" [class.custom-disable-wrapper]=\"buttonBusy\" [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <div class=\"col-12 px-0\">\n <p-table #tt\n [value]=\"invoices\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [lazy]=\"true\"\n [totalRecords]=\"totalRecords\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n >\n <ng-template pTemplate=\"caption\">\n <div class=\"search-filter justify-content-end\">\n <div class=\"text-end\">\n <label for=\"user-invoice-search\" class=\"visually-hidden\">Search Invoices</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input id=\"user-invoice-search\"\n name=\"user-invoice-search\"\n [(ngModel)]=\"searchText\"\n (input)=\"tt.filterGlobal($event.target.value, 'contains')\"\n type=\"text\"\n pInputText\n placeholder=\"Search Invoices...\"\n data-cy=\"incident-search\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"col\" pSortableColumn=\"date\">Invoice Date <p-sortIcon field=\"date\"></p-sortIcon></th>\n <th scope=\"col\" pSortableColumn=\"frequency\">Frequency <p-sortIcon field=\"frequency\"></p-sortIcon></th>\n <th scope=\"col\" pSortableColumn=\"seatsPurchased\">Seats Purchased <p-sortIcon field=\"seatsPurchased\"></p-sortIcon></th>\n <th scope=\"col\" pSortableColumn=\"subtotal\">Subtotal <p-sortIcon field=\"subtotal\"></p-sortIcon></th>\n <th scope=\"col\" pSortableColumn=\"total\">Total (incl. tax) <p-sortIcon field=\"total\"></p-sortIcon></th>\n <th scope=\"col\">Action</th>\n </tr>\n </ng-template>\n\n <ng-template pTemplate=\"body\" let-invoice>\n <tr>\n <td>{{ invoice.date | date:'dd-MMM-yyyy' }}</td>\n <td>\n <span class=\"badge\"\n [appDynamicBadge]=\"{\n itemsArray: invoiceFrequency,\n item: invoice.product.billing_frequency\n }\"\n color=\"blue-grey\">{{ invoice.product.billing_frequency }}</span>\n </td>\n <td>{{ invoice?.subscription_product?.purchased_units }}</td>\n <td>{{ (invoice.subtotal_in_cents / 100) | currency:invoice?.product?.currency }}</td>\n <td class=\"td-total\">{{ (invoice.total_in_cents / 100) | currency:invoice?.product?.currency }}</td>\n <td>\n @if (invoice?.file?.url) {\n <a class=\"btn btn-sm btn-primary\" [attr.href]=\"invoice.file.url\" target=\"_blank\" title=\"Download\">\n <i class=\"fa fa-download\">&nbsp;Download</i>\n </a>\n } @else {\n <a class=\"btn btn-sm btn-primary\" [attr.href]=\"invoice?.stripe_invoice_pdf\" target=\"_blank\" title=\"Download\">\n <i class=\"fa fa-download\">&nbsp;Download</i>\n </a>\n }\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n\n </div>\n</div>\n@if (totalRecordsUnFiltered === 0 && isLoaded) {\n <pw-no-data [withImage]=\"true\" message=\"You don't have any invoice yet.\">\n </pw-no-data>\n}\n\n", styles: [".page-heading{background:#fcfcfc;border-bottom:1px solid rgba(0,0,0,.1);position:relative;width:100%}.page-heading:after{clear:both;content:\"\";display:table}.page-heading .page-heading__container{padding:15px 20px;position:relative}.page-heading .page-heading__container .title{color:#242437;font-size:15px;font-weight:500;line-height:20px;margin:3px 0 0;overflow:hidden;padding:0;text-overflow:ellipsis;width:95%}.card .card-container{position:absolute;right:20px;top:25px;z-index:1}.td-total{font-weight:700}.card-inner-container{background:#0000000d;border:1px dashed rgba(0,0,0,.1);border-radius:3px;margin-bottom:20px;padding:20px}.invoice-text{display:flex;font-size:13px;justify-content:space-between;margin:10px 0}.invoice-template{min-height:calc(100vh - 190px)}\n"], dependencies: [{ kind: "directive", type: i1$3.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: i4.DynamicBadgeDirective, selector: "[appDynamicBadge]", inputs: ["appDynamicBadge", "color", "colorByName", "dataName"] }, { 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: "component", type: i4$3.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i5$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i4$3.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "component", type: i4$3.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i5.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "component", type: i5.RecordsSummaryComponent, selector: "pw-records-summary", inputs: ["showing", "total"] }, { kind: "pipe", type: i6.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i6.DatePipe, name: "date" }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
1891
1892
  }
1892
1893
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserInvoiceComponent, decorators: [{
1893
1894
  type: Component,
1894
- args: [{ selector: 'pw-user-invoice', standalone: false, template: "<div class=\"row\" [class.custom-disable-wrapper]=\"buttonBusy\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-center\">\n <h2 class=\"card-title p-0 float-start\">Your Invoices</h2>\n </div>\n</div>\n\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\">\n <p-progressSpinner strokeWidth=\"2\"></p-progressSpinner>\n </div>\n}\n<div class=\"row primeng-datatable-container mt-0\" [class.custom-disable-wrapper]=\"buttonBusy\" [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <div class=\"col-12 px-0\">\n <p-table #tt\n [value]=\"invoices\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [lazy]=\"true\"\n [totalRecords]=\"totalRecords\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n >\n <ng-template pTemplate=\"caption\">\n <div class=\"search-filter justify-content-end\">\n <div class=\"text-end\">\n <label for=\"user-invoice-search\" class=\"visually-hidden\">Search Invoices</label>\n <i class=\"fa fa-search mt-2 me-2\" aria-hidden=\"true\"></i>\n <input id=\"user-invoice-search\"\n name=\"user-invoice-search\"\n [(ngModel)]=\"searchText\"\n (input)=\"tt.filterGlobal($event.target.value, 'contains')\"\n type=\"text\"\n pInputText\n size=\"50\"\n placeholder=\"Search Invoices...\"\n data-cy=\"incident-search\"\n class=\"wd-90\">\n </div>\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"col\" pSortableColumn=\"date\">Invoice Date <p-sortIcon field=\"date\"></p-sortIcon></th>\n <th scope=\"col\" pSortableColumn=\"frequency\">Frequency <p-sortIcon field=\"frequency\"></p-sortIcon></th>\n <th scope=\"col\" pSortableColumn=\"seatsPurchased\">Seats Purchased <p-sortIcon field=\"seatsPurchased\"></p-sortIcon></th>\n <th scope=\"col\" pSortableColumn=\"subtotal\">Subtotal <p-sortIcon field=\"subtotal\"></p-sortIcon></th>\n <th scope=\"col\" pSortableColumn=\"total\">Total (incl. tax) <p-sortIcon field=\"total\"></p-sortIcon></th>\n <th scope=\"col\">Action</th>\n </tr>\n </ng-template>\n\n <ng-template pTemplate=\"body\" let-invoice>\n <tr>\n <td>{{ invoice.date | date:'dd-MMM-yyyy' }}</td>\n <td>\n <span class=\"badge\"\n [appDynamicBadge]=\"{\n itemsArray: invoiceFrequency,\n item: invoice.product.billing_frequency\n }\"\n color=\"blue-grey\">{{ invoice.product.billing_frequency }}</span>\n </td>\n <td>{{ invoice?.subscription_product?.purchased_units }}</td>\n <td>{{ (invoice.subtotal_in_cents / 100) | currency:invoice?.product?.currency }}</td>\n <td class=\"td-total\">{{ (invoice.total_in_cents / 100) | currency:invoice?.product?.currency }}</td>\n <td>\n @if (invoice?.file?.url) {\n <a class=\"btn btn-sm btn-primary\" [attr.href]=\"invoice.file.url\" target=\"_blank\" title=\"Download\">\n <i class=\"fa fa-download\">&nbsp;Download</i>\n </a>\n } @else {\n <a class=\"btn btn-sm btn-primary\" [attr.href]=\"invoice?.stripe_invoice_pdf\" target=\"_blank\" title=\"Download\">\n <i class=\"fa fa-download\">&nbsp;Download</i>\n </a>\n }\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n\n @if (totalRecords !== 0) {\n <span class=\"total-records-count\">Total: {{ totalRecords }}</span>\n }\n\n </div>\n</div>\n@if (totalRecordsUnFiltered === 0 && isLoaded) {\n <pw-no-data [withImage]=\"true\" message=\"You don't have any invoice yet.\">\n </pw-no-data>\n}\n\n", styles: [".page-heading{background:#fcfcfc;border-bottom:1px solid rgba(0,0,0,.1);position:relative;width:100%}.page-heading:after{clear:both;content:\"\";display:table}.page-heading .page-heading__container{padding:15px 20px;position:relative}.page-heading .page-heading__container .title{color:#242437;font-size:15px;font-weight:500;line-height:20px;margin:3px 0 0;overflow:hidden;padding:0;text-overflow:ellipsis;width:95%}.card .card-container{position:absolute;right:20px;top:25px;z-index:1}.td-total{font-weight:700}.card-inner-container{background:#0000000d;border:1px dashed rgba(0,0,0,.1);border-radius:3px;margin-bottom:20px;padding:20px}.invoice-text{display:flex;font-size:13px;justify-content:space-between;margin:10px 0}.invoice-template{min-height:calc(100vh - 190px)}\n"] }]
1895
+ args: [{ selector: 'pw-user-invoice', standalone: false, template: "<div class=\"row\" [class.custom-disable-wrapper]=\"buttonBusy\">\n <div class=\"col-12 d-flex flex-wrap justify-content-between align-items-center\">\n <h2 class=\"card-title p-0 float-start\">Your Invoices</h2>\n </div>\n</div>\n\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\">\n <p-progressSpinner strokeWidth=\"2\"></p-progressSpinner>\n </div>\n}\n<div class=\"row primeng-datatable-container actions-collapsed mt-0\" [class.custom-disable-wrapper]=\"buttonBusy\" [class.hideTable]=\"totalRecordsUnFiltered === 0\">\n <div class=\"col-12 px-0\">\n <p-table #tt\n [value]=\"invoices\"\n [paginator]=\"totalRecords !== 0\"\n [rows]=\"PAGE_SIZE\"\n [lazy]=\"true\"\n [totalRecords]=\"totalRecords\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n >\n <ng-template pTemplate=\"caption\">\n <div class=\"search-filter justify-content-end\">\n <div class=\"text-end\">\n <label for=\"user-invoice-search\" class=\"visually-hidden\">Search Invoices</label>\n <p-iconfield iconPosition=\"left\">\n <p-inputicon><i class=\"fa fa-search\" aria-hidden=\"true\"></i></p-inputicon>\n <input id=\"user-invoice-search\"\n name=\"user-invoice-search\"\n [(ngModel)]=\"searchText\"\n (input)=\"tt.filterGlobal($event.target.value, 'contains')\"\n type=\"text\"\n pInputText\n placeholder=\"Search Invoices...\"\n data-cy=\"incident-search\" />\n </p-iconfield>\n </div>\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"col\" pSortableColumn=\"date\">Invoice Date <p-sortIcon field=\"date\"></p-sortIcon></th>\n <th scope=\"col\" pSortableColumn=\"frequency\">Frequency <p-sortIcon field=\"frequency\"></p-sortIcon></th>\n <th scope=\"col\" pSortableColumn=\"seatsPurchased\">Seats Purchased <p-sortIcon field=\"seatsPurchased\"></p-sortIcon></th>\n <th scope=\"col\" pSortableColumn=\"subtotal\">Subtotal <p-sortIcon field=\"subtotal\"></p-sortIcon></th>\n <th scope=\"col\" pSortableColumn=\"total\">Total (incl. tax) <p-sortIcon field=\"total\"></p-sortIcon></th>\n <th scope=\"col\">Action</th>\n </tr>\n </ng-template>\n\n <ng-template pTemplate=\"body\" let-invoice>\n <tr>\n <td>{{ invoice.date | date:'dd-MMM-yyyy' }}</td>\n <td>\n <span class=\"badge\"\n [appDynamicBadge]=\"{\n itemsArray: invoiceFrequency,\n item: invoice.product.billing_frequency\n }\"\n color=\"blue-grey\">{{ invoice.product.billing_frequency }}</span>\n </td>\n <td>{{ invoice?.subscription_product?.purchased_units }}</td>\n <td>{{ (invoice.subtotal_in_cents / 100) | currency:invoice?.product?.currency }}</td>\n <td class=\"td-total\">{{ (invoice.total_in_cents / 100) | currency:invoice?.product?.currency }}</td>\n <td>\n @if (invoice?.file?.url) {\n <a class=\"btn btn-sm btn-primary\" [attr.href]=\"invoice.file.url\" target=\"_blank\" title=\"Download\">\n <i class=\"fa fa-download\">&nbsp;Download</i>\n </a>\n } @else {\n <a class=\"btn btn-sm btn-primary\" [attr.href]=\"invoice?.stripe_invoice_pdf\" target=\"_blank\" title=\"Download\">\n <i class=\"fa fa-download\">&nbsp;Download</i>\n </a>\n }\n </td>\n </tr>\n </ng-template>\n </p-table>\n @if (totalRecords === 0 && totalRecordsUnFiltered !== 0) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Search.NoDataMessage' | transloco\" [description]=\"'Search.NoDataDescription' | transloco\" >\n </pw-no-data>\n </div>\n }\n\n @if (totalRecords !== 0) {\n <pw-records-summary [showing]=\"tt?.value?.length ?? 0\" [total]=\"totalRecords\" />\n }\n\n </div>\n</div>\n@if (totalRecordsUnFiltered === 0 && isLoaded) {\n <pw-no-data [withImage]=\"true\" message=\"You don't have any invoice yet.\">\n </pw-no-data>\n}\n\n", styles: [".page-heading{background:#fcfcfc;border-bottom:1px solid rgba(0,0,0,.1);position:relative;width:100%}.page-heading:after{clear:both;content:\"\";display:table}.page-heading .page-heading__container{padding:15px 20px;position:relative}.page-heading .page-heading__container .title{color:#242437;font-size:15px;font-weight:500;line-height:20px;margin:3px 0 0;overflow:hidden;padding:0;text-overflow:ellipsis;width:95%}.card .card-container{position:absolute;right:20px;top:25px;z-index:1}.td-total{font-weight:700}.card-inner-container{background:#0000000d;border:1px dashed rgba(0,0,0,.1);border-radius:3px;margin-bottom:20px;padding:20px}.invoice-text{display:flex;font-size:13px;justify-content:space-between;margin:10px 0}.invoice-template{min-height:calc(100vh - 190px)}\n"] }]
1895
1896
  }], ctorParameters: () => [{ type: i0.Injector }, { type: i0.ChangeDetectorRef }] });
1896
1897
 
1897
1898
  class CommunicationTabComponent extends AppBaseComponent {
@@ -1966,11 +1967,11 @@ class CommunicationTabComponent extends AppBaseComponent {
1966
1967
  // });
1967
1968
  }
1968
1969
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: CommunicationTabComponent, deps: [{ token: i1$2.CommonService }, { token: i1$2.ProfileService }, { token: i4$2.Store }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1969
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: CommunicationTabComponent, isStandalone: false, selector: "pw-communication-tab", usesInheritance: true, ngImport: i0, template: "<div class=\"row\">\n <div class=\"col-12\">\n <h2>Communication preferences</h2>\n\n <p>\n Although sometimes we do need to communicate with you - for example if you contact\n Support, or if we need to send you a receipt or invoice - we make a clear distinction\n between transactional and non-transactional communications.\n </p>\n\n <p>\n You will always receive the transactional communications but you can decide to opt out\n from all the not transactional ones. To do so, you\u2019ll just need to turn the switch off\n in the list of available communication provided below.\n </p>\n </div>\n\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n</div>\n\n@if (isLoaded) {\n <div class=\"row mt-4 pt-1\"\n >\n <div class=\"col-md-6 col-sm-6\">\n @for (item of subscriptions; track item; let idx = $index) {\n @if (item.visible || item.enabled) {\n <div class=\"mb-3\"\n >\n <div class=\"row\">\n <div class=\"col-md-10 col-sm-6\">\n <span class=\"pw-label-style\" [id]=\"'communication-tab-' + idx\">{{ item.name }}</span>\n </div>\n <div class=\"col-md-2 col-sm-6\">\n <ui-switch [checked]=\"item.enabled\"\n [attr.aria-labelledby]=\"'communication-tab-' + idx\"\n checkedLabel=\"on\"\n uncheckedLabel=\"off\"\n (valueChange)=\"onValueChange(item, $event)\">\n </ui-switch>\n </div>\n </div>\n </div>\n }\n }\n </div>\n </div>\n}\n\n\n@if (subscriptions.length === 0 && isLoaded) {\n <pw-no-data [withImage]=\"true\" message=\"You don't have any communication preferences yet.\">\n </pw-no-data>\n}\n", styles: ["label{font-size:15px!important}\n"], dependencies: [{ kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i11.UiSwitchComponent, selector: "ui-switch", inputs: ["size", "color", "switchOffColor", "switchColor", "defaultBgColor", "defaultBoColor", "checkedLabel", "uncheckedLabel", "checkedTextColor", "uncheckedTextColor", "beforeChange", "ariaLabel", "checked", "disabled", "reverse", "loading"], outputs: ["change", "changeEvent", "valueChange"] }, { kind: "component", type: i5.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }] }); }
1970
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: CommunicationTabComponent, isStandalone: false, selector: "pw-communication-tab", usesInheritance: true, ngImport: i0, template: "<div class=\"communication-settings\">\n <h2>{{ 'User.Settings.Communications.Title' | transloco }}</h2>\n\n <p class=\"settings-intro\">{{ 'User.Settings.Communications.Intro1' | transloco }}</p>\n <p class=\"settings-intro\">{{ 'User.Settings.Communications.Intro2' | transloco }}</p>\n\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n\n @if (isLoaded && subscriptions.length > 0) {\n <ul class=\"pref-list\">\n @for (item of subscriptions; track item; let idx = $index) {\n @if (item.visible || item.enabled) {\n <li class=\"pref-row\">\n <span class=\"pref-name\" [id]=\"'communication-tab-' + idx\">{{ item.name }}</span>\n <ui-switch [checked]=\"item.enabled\"\n [attr.aria-labelledby]=\"'communication-tab-' + idx\"\n (valueChange)=\"onValueChange(item, $event)\">\n </ui-switch>\n </li>\n }\n }\n </ul>\n }\n\n @if (isLoaded && subscriptions.length === 0) {\n <pw-no-data [withImage]=\"true\"\n [message]=\"'User.Settings.Communications.NoDataMessage' | transloco\">\n </pw-no-data>\n }\n</div>\n", styles: [":host{display:block}.communication-settings{max-width:800px}.settings-intro{color:#5a6473;font-size:14px;line-height:1.55;margin-bottom:.75rem}.pref-list{list-style:none;margin:1.75rem 0 0;padding:0;border-top:1px solid #e2e5ea}.pref-row{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:12px 4px;border-bottom:1px solid #e2e5ea}.pref-name{flex:1 1 auto;min-width:0;color:var(--text, #222);font-size:14px;font-weight:500;line-height:1.4}\n"], dependencies: [{ kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i11$1.UiSwitchComponent, selector: "ui-switch", inputs: ["size", "color", "switchOffColor", "switchColor", "defaultBgColor", "defaultBoColor", "checkedLabel", "uncheckedLabel", "checkedTextColor", "uncheckedTextColor", "beforeChange", "ariaLabel", "checked", "disabled", "reverse", "loading"], outputs: ["change", "changeEvent", "valueChange"] }, { kind: "component", type: i5.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
1970
1971
  }
1971
1972
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: CommunicationTabComponent, decorators: [{
1972
1973
  type: Component,
1973
- args: [{ selector: 'pw-communication-tab', standalone: false, template: "<div class=\"row\">\n <div class=\"col-12\">\n <h2>Communication preferences</h2>\n\n <p>\n Although sometimes we do need to communicate with you - for example if you contact\n Support, or if we need to send you a receipt or invoice - we make a clear distinction\n between transactional and non-transactional communications.\n </p>\n\n <p>\n You will always receive the transactional communications but you can decide to opt out\n from all the not transactional ones. To do so, you\u2019ll just need to turn the switch off\n in the list of available communication provided below.\n </p>\n </div>\n\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n</div>\n\n@if (isLoaded) {\n <div class=\"row mt-4 pt-1\"\n >\n <div class=\"col-md-6 col-sm-6\">\n @for (item of subscriptions; track item; let idx = $index) {\n @if (item.visible || item.enabled) {\n <div class=\"mb-3\"\n >\n <div class=\"row\">\n <div class=\"col-md-10 col-sm-6\">\n <span class=\"pw-label-style\" [id]=\"'communication-tab-' + idx\">{{ item.name }}</span>\n </div>\n <div class=\"col-md-2 col-sm-6\">\n <ui-switch [checked]=\"item.enabled\"\n [attr.aria-labelledby]=\"'communication-tab-' + idx\"\n checkedLabel=\"on\"\n uncheckedLabel=\"off\"\n (valueChange)=\"onValueChange(item, $event)\">\n </ui-switch>\n </div>\n </div>\n </div>\n }\n }\n </div>\n </div>\n}\n\n\n@if (subscriptions.length === 0 && isLoaded) {\n <pw-no-data [withImage]=\"true\" message=\"You don't have any communication preferences yet.\">\n </pw-no-data>\n}\n", styles: ["label{font-size:15px!important}\n"] }]
1974
+ args: [{ selector: 'pw-communication-tab', standalone: false, template: "<div class=\"communication-settings\">\n <h2>{{ 'User.Settings.Communications.Title' | transloco }}</h2>\n\n <p class=\"settings-intro\">{{ 'User.Settings.Communications.Intro1' | transloco }}</p>\n <p class=\"settings-intro\">{{ 'User.Settings.Communications.Intro2' | transloco }}</p>\n\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\">\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n\n @if (isLoaded && subscriptions.length > 0) {\n <ul class=\"pref-list\">\n @for (item of subscriptions; track item; let idx = $index) {\n @if (item.visible || item.enabled) {\n <li class=\"pref-row\">\n <span class=\"pref-name\" [id]=\"'communication-tab-' + idx\">{{ item.name }}</span>\n <ui-switch [checked]=\"item.enabled\"\n [attr.aria-labelledby]=\"'communication-tab-' + idx\"\n (valueChange)=\"onValueChange(item, $event)\">\n </ui-switch>\n </li>\n }\n }\n </ul>\n }\n\n @if (isLoaded && subscriptions.length === 0) {\n <pw-no-data [withImage]=\"true\"\n [message]=\"'User.Settings.Communications.NoDataMessage' | transloco\">\n </pw-no-data>\n }\n</div>\n", styles: [":host{display:block}.communication-settings{max-width:800px}.settings-intro{color:#5a6473;font-size:14px;line-height:1.55;margin-bottom:.75rem}.pref-list{list-style:none;margin:1.75rem 0 0;padding:0;border-top:1px solid #e2e5ea}.pref-row{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:12px 4px;border-bottom:1px solid #e2e5ea}.pref-name{flex:1 1 auto;min-width:0;color:var(--text, #222);font-size:14px;font-weight:500;line-height:1.4}\n"] }]
1974
1975
  }], ctorParameters: () => [{ type: i1$2.CommonService }, { type: i1$2.ProfileService }, { type: i4$2.Store }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }] });
1975
1976
 
1976
1977
  class OthersTabComponent extends AppBaseComponent {
@@ -2035,11 +2036,11 @@ class OthersTabComponent extends AppBaseComponent {
2035
2036
  super.ngOnDestroy();
2036
2037
  }
2037
2038
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: OthersTabComponent, deps: [{ token: i1$2.CommonService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
2038
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: OthersTabComponent, isStandalone: false, selector: "pw-others-tab", usesInheritance: true, ngImport: i0, template: "<div class=\"row\">\n <div class=\"col-12\">\n <h2>Other</h2>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n}\n@if (isLoaded && globalConfigs?.length) {\n <div class=\"row mt-4 pt-1\"\n >\n <div class=\"col-md-6 col-sm-6\">\n @for (item of globalConfigs; track item; let idx = $index) {\n <div class=\"mb-3\">\n <div class=\"row\">\n <div class=\"col-md-10 col-sm-6\">\n <span class=\"pw-label-style\" [id]=\"'others-tab-' + idx\"> {{ item?.name }} </span>\n </div>\n <div class=\"col-md-2 col-sm-6\">\n <ui-switch [checked]=\"item.value === 'true'\"\n [attr.aria-labelledby]=\"'others-tab-' + idx\"\n checkedLabel=\"on\"\n uncheckedLabel=\"off\"\n (valueChange)=\"onValueChange(item, $event)\">\n </ui-switch>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n}\n\n@if (isLoaded && !globalConfigs?.length) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'User.OtherSettings.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n", dependencies: [{ kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i11.UiSwitchComponent, selector: "ui-switch", inputs: ["size", "color", "switchOffColor", "switchColor", "defaultBgColor", "defaultBoColor", "checkedLabel", "uncheckedLabel", "checkedTextColor", "uncheckedTextColor", "beforeChange", "ariaLabel", "checked", "disabled", "reverse", "loading"], outputs: ["change", "changeEvent", "valueChange"] }, { kind: "component", type: i5.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
2039
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: OthersTabComponent, isStandalone: false, selector: "pw-others-tab", usesInheritance: true, ngImport: i0, template: "<div class=\"row\">\n <div class=\"col-12\">\n <h2>Other</h2>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n}\n@if (isLoaded && globalConfigs?.length) {\n <div class=\"row mt-4 pt-1\"\n >\n <div class=\"col-md-6 col-sm-6\">\n @for (item of globalConfigs; track item; let idx = $index) {\n <div class=\"mb-3\">\n <div class=\"row\">\n <div class=\"col-md-10 col-sm-6\">\n <span class=\"pw-label-style\" [id]=\"'others-tab-' + idx\"> {{ item?.name }} </span>\n </div>\n <div class=\"col-md-2 col-sm-6\">\n <ui-switch [checked]=\"item.value === 'true'\"\n [attr.aria-labelledby]=\"'others-tab-' + idx\"\n (valueChange)=\"onValueChange(item, $event)\">\n </ui-switch>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n}\n\n@if (isLoaded && !globalConfigs?.length) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'User.OtherSettings.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n", dependencies: [{ kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i11$1.UiSwitchComponent, selector: "ui-switch", inputs: ["size", "color", "switchOffColor", "switchColor", "defaultBgColor", "defaultBoColor", "checkedLabel", "uncheckedLabel", "checkedTextColor", "uncheckedTextColor", "beforeChange", "ariaLabel", "checked", "disabled", "reverse", "loading"], outputs: ["change", "changeEvent", "valueChange"] }, { kind: "component", type: i5.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
2039
2040
  }
2040
2041
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: OthersTabComponent, decorators: [{
2041
2042
  type: Component,
2042
- args: [{ selector: 'pw-others-tab', standalone: false, template: "<div class=\"row\">\n <div class=\"col-12\">\n <h2>Other</h2>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n}\n@if (isLoaded && globalConfigs?.length) {\n <div class=\"row mt-4 pt-1\"\n >\n <div class=\"col-md-6 col-sm-6\">\n @for (item of globalConfigs; track item; let idx = $index) {\n <div class=\"mb-3\">\n <div class=\"row\">\n <div class=\"col-md-10 col-sm-6\">\n <span class=\"pw-label-style\" [id]=\"'others-tab-' + idx\"> {{ item?.name }} </span>\n </div>\n <div class=\"col-md-2 col-sm-6\">\n <ui-switch [checked]=\"item.value === 'true'\"\n [attr.aria-labelledby]=\"'others-tab-' + idx\"\n checkedLabel=\"on\"\n uncheckedLabel=\"off\"\n (valueChange)=\"onValueChange(item, $event)\">\n </ui-switch>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n}\n\n@if (isLoaded && !globalConfigs?.length) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'User.OtherSettings.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n" }]
2043
+ args: [{ selector: 'pw-others-tab', standalone: false, template: "<div class=\"row\">\n <div class=\"col-12\">\n <h2>Other</h2>\n </div>\n</div>\n@if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n}\n@if (isLoaded && globalConfigs?.length) {\n <div class=\"row mt-4 pt-1\"\n >\n <div class=\"col-md-6 col-sm-6\">\n @for (item of globalConfigs; track item; let idx = $index) {\n <div class=\"mb-3\">\n <div class=\"row\">\n <div class=\"col-md-10 col-sm-6\">\n <span class=\"pw-label-style\" [id]=\"'others-tab-' + idx\"> {{ item?.name }} </span>\n </div>\n <div class=\"col-md-2 col-sm-6\">\n <ui-switch [checked]=\"item.value === 'true'\"\n [attr.aria-labelledby]=\"'others-tab-' + idx\"\n (valueChange)=\"onValueChange(item, $event)\">\n </ui-switch>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n}\n\n@if (isLoaded && !globalConfigs?.length) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'User.OtherSettings.NoDataMessage' | transloco\"> </pw-no-data>\n </div>\n}\n" }]
2043
2044
  }], ctorParameters: () => [{ type: i1$2.CommonService }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }] });
2044
2045
 
2045
2046
  class SecurityTabComponent extends AppBaseComponent {
@@ -2173,11 +2174,11 @@ class SecurityTabComponent extends AppBaseComponent {
2173
2174
  }
2174
2175
  }
2175
2176
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SecurityTabComponent, deps: [{ token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
2176
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: SecurityTabComponent, isStandalone: false, selector: "pw-security-tab", viewQueries: [{ propertyName: "passwordRef", first: true, predicate: ["password"], descendants: true }, { propertyName: "verificationCode", first: true, predicate: ["verificationCode"], descendants: true }, { propertyName: "ssoPasswordRef", first: true, predicate: ["ssoPassword"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"row\">\n <div class=\"col-12\">\n <h2>Security settings</h2>\n </div>\n</div>\n<p-accordion>\n <p-accordion-panel value=\"0\">\n <p-accordion-header>Two Factor Authentication (2FA)</p-accordion-header>\n <p-accordion-content>\n <div class=\"row mt-2\">\n <div class=\"col-12\">\n <div class=\"d-flex\">\n <p class=\"small text-muted\"> Add an extra layer of security to your user account by asking to verify their\n identity when they enter a username and password </p>\n </div>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n <!-- Disable 2FA -->\n @if (user?.enable_two_factor_authenticator) {\n <button class=\"btn btn-danger\" (click)=\"show2FA = true\"> Disable\n </button>\n }\n <!-- Enable 2FA -->\n @if (!user?.enable_two_factor_authenticator) {\n <button class=\"btn btn-primary\"\n [disabled]=\"created2faDetails?.code\" (click)=\"show2FA = true\"> Enable </button>\n }\n </div>\n </div>\n @if (show2FA) {\n <div class=\"row\">\n <div class=\"col-12 col-md-6 col-lg-4 mt-2\">\n <div class=\"mb-3\">\n @if (!passwordVerified) {\n <input type=\"password\" class=\"form-control\" #password placeholder=\"Current Password\"\n (keyup)=\"checkValidity()\" id=\"input_current_password_800\" name=\"input_current_password_800\" />\n }\n </div>\n </div>\n @if (created2faDetails?.code) {\n <div class=\"col-12\">\n <p class=\"small\"> Scan the QR code below or use secret manually with the Google authenticator app on your mobile\n device, after that fill in the field below with the code generated in the app </p>\n <img [src]=\"created2faDetails?.qr_uri\" alt=\"loading QR code...\" class=\"qr-code img-thumbnail img-responsive\" />\n <strong> Secret Key: {{ created2faDetails?.code }}</strong>\n <p class=\"small\">Auth Type: Time Based OTP</p>\n </div>\n }\n </div>\n }\n @if (show2FA) {\n <div class=\"row\">\n <div class=\"col-4\">\n <div class=\"mb-3 mt-2\">\n @if (passwordVerified) {\n <input type=\"text\" #verificationCode class=\"form-control\"\n placeholder=\"Provide passcode from authenticator app\" id=\"input_provide_passcode_from_authenticator_app_800\" name=\"input_provide_passcode_from_authenticator_app_800\" />\n }\n </div>\n </div>\n @if (show2FA) {\n <div class=\"col-12\">\n <div class=\"d-flex mt-2\">\n <button class=\"btn btn-raised btn-outline-default me-2\" (click)=\"reset()\"> Cancel </button>\n @if (!passwordVerified) {\n <button class=\"btn btn-raised btn-primary\" (click)=\"validatePassword()\"\n [disabled]=\"isCurrentPasswordValid\"> Validate </button>\n }\n @if (passwordVerified) {\n <button class=\"btn btn-raised btn-primary\" (click)=\"verify2FA()\"> Confirm </button>\n }\n </div>\n </div>\n }\n </div>\n }\n </p-accordion-content>\n </p-accordion-panel>\n</p-accordion>\n<p-accordion>\n <p-accordion-panel value=\"0\">\n <p-accordion-header>Single Sign On (SSO) - AWS Cognito</p-accordion-header>\n <p-accordion-content>\n <div class=\"row mt-2\">\n <div class=\"col-12\">\n <p class=\"small text-muted\"> {{ user?.cognito_sso_activated ? 'You have already activated AWS Cognito SSO, if you click on \u2018Resend activation email\u2018 you\u2018ll receive an email with instructions to reset your SSO\n password.' : 'Once you click \u2018Enable\u2019, you\u2019ll receive an email with instructions to activate your AWS Cognito\n SSO. This will enable you to access all our systems using a single password.' }} </p>\n </div>\n </div>\n <!-- Enable or Resend Button -->\n @if (!showSSOSection) {\n <div class=\"row\">\n <div class=\"col-12\">\n <button class=\"btn btn-primary\" (click)=\"showSSOSection = true\"> {{ user?.cognito_sso_activated ? 'Resend\n activation email' : 'Enable' }} </button>\n </div>\n </div>\n }\n <!-- Password Validation -->\n @if (showSSOSection) {\n <div class=\"row\">\n @if (!ssoPasswordVerified) {\n <div class=\"col-12 col-md-6 col-lg-4 mt-2\">\n <div class=\"mb-3\">\n <input type=\"password\" class=\"form-control\" #ssoPassword placeholder=\"Current Password\"\n (keyup)=\"checkSSOPasswordValidity()\" id=\"input_current_password_801\" name=\"input_current_password_801\" />\n </div>\n </div>\n }\n <div class=\"col-12\">\n <div class=\"d-flex mt-2\">\n <button class=\"btn btn-raised btn-outline-default me-2\" (click)=\"resetSSO()\"> Cancel </button>\n @if (!ssoPasswordVerified) {\n <button class=\"btn btn-raised btn-primary\" (click)=\"validateSSOPassword()\"\n [disabled]=\"isSSOPasswordInvalid\"> Validate </button>\n }\n @if (ssoPasswordVerified) {\n <button class=\"btn btn-primary\" (click)=\"triggerSSO()\"> Confirm </button>\n }\n </div>\n </div>\n </div>\n }\n </p-accordion-content>\n </p-accordion-panel>\n</p-accordion>\n", styles: [".qr-code{margin:10px;max-width:200px}.text-muted{font-size:15px!important}\n"], dependencies: [{ kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { kind: "component", type: i2$2.Accordion, selector: "p-accordion", inputs: ["value", "multiple", "styleClass", "expandIcon", "collapseIcon", "selectOnFocus", "transitionOptions", "motionOptions"], outputs: ["valueChange", "onClose", "onOpen"] }, { kind: "component", type: i2$2.AccordionPanel, selector: "p-accordion-panel, p-accordionpanel", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: i2$2.AccordionHeader, selector: "p-accordion-header, p-accordionheader" }, { kind: "component", type: i2$2.AccordionContent, selector: "p-accordion-content, p-accordioncontent" }] }); }
2177
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: SecurityTabComponent, isStandalone: false, selector: "pw-security-tab", viewQueries: [{ propertyName: "passwordRef", first: true, predicate: ["password"], descendants: true }, { propertyName: "verificationCode", first: true, predicate: ["verificationCode"], descendants: true }, { propertyName: "ssoPasswordRef", first: true, predicate: ["ssoPassword"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"row\">\n <div class=\"col-12\">\n <h2>Security settings</h2>\n </div>\n</div>\n<p-accordion>\n <p-accordion-panel value=\"0\">\n <p-accordion-header>Two Factor Authentication (2FA)</p-accordion-header>\n <p-accordion-content>\n <div class=\"row mt-2\">\n <div class=\"col-12\">\n <div class=\"d-flex\">\n <p class=\"small text-muted\"> Add an extra layer of security to your user account by asking to verify their\n identity when they enter a username and password </p>\n </div>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n <!-- Disable 2FA -->\n @if (user?.enable_two_factor_authenticator) {\n <button class=\"btn btn-danger\" (click)=\"show2FA = true\"> Disable\n </button>\n }\n <!-- Enable 2FA -->\n @if (!user?.enable_two_factor_authenticator) {\n <button class=\"btn btn-primary\"\n [disabled]=\"created2faDetails?.code\" (click)=\"show2FA = true\"> Enable </button>\n }\n </div>\n </div>\n @if (show2FA) {\n <div class=\"row\">\n <div class=\"col-12 col-md-6 col-lg-4 mt-2\">\n <div class=\"mb-3\">\n @if (!passwordVerified) {\n <input type=\"password\" class=\"form-control\" #password placeholder=\"Current Password\"\n (keyup)=\"checkValidity()\" id=\"input_current_password_800\" name=\"input_current_password_800\" />\n }\n </div>\n </div>\n @if (created2faDetails?.code) {\n <div class=\"col-12\">\n <p class=\"small\"> Scan the QR code below or use secret manually with the Google authenticator app on your mobile\n device, after that fill in the field below with the code generated in the app </p>\n <img [src]=\"created2faDetails?.qr_uri\" alt=\"loading QR code...\" class=\"qr-code img-thumbnail img-responsive\" />\n <strong> Secret Key: {{ created2faDetails?.code }}</strong>\n <p class=\"small\">Auth Type: Time Based OTP</p>\n </div>\n }\n </div>\n }\n @if (show2FA) {\n <div class=\"row\">\n <div class=\"col-4\">\n <div class=\"mb-3 mt-2\">\n @if (passwordVerified) {\n <input type=\"text\" #verificationCode class=\"form-control\"\n placeholder=\"Provide passcode from authenticator app\" id=\"input_provide_passcode_from_authenticator_app_800\" name=\"input_provide_passcode_from_authenticator_app_800\" />\n }\n </div>\n </div>\n @if (show2FA) {\n <div class=\"col-12\">\n <div class=\"d-flex mt-2\">\n <button class=\"btn btn-raised btn-outline-default me-2\" (click)=\"reset()\"> Cancel </button>\n @if (!passwordVerified) {\n <button class=\"btn btn-raised btn-primary\" (click)=\"validatePassword()\"\n [disabled]=\"isCurrentPasswordValid\"> Validate </button>\n }\n @if (passwordVerified) {\n <button class=\"btn btn-raised btn-primary\" (click)=\"verify2FA()\"> Confirm </button>\n }\n </div>\n </div>\n }\n </div>\n }\n </p-accordion-content>\n </p-accordion-panel>\n <p-accordion-panel value=\"1\">\n <p-accordion-header>Single Sign On (SSO) - AWS Cognito</p-accordion-header>\n <p-accordion-content>\n <div class=\"row mt-2\">\n <div class=\"col-12\">\n <p class=\"small text-muted\"> {{ user?.cognito_sso_activated ? 'You have already activated AWS Cognito SSO, if you click on \u2018Resend activation email\u2018 you\u2018ll receive an email with instructions to reset your SSO\n password.' : 'Once you click \u2018Enable\u2019, you\u2019ll receive an email with instructions to activate your AWS Cognito\n SSO. This will enable you to access all our systems using a single password.' }} </p>\n </div>\n </div>\n <!-- Enable or Resend Button -->\n @if (!showSSOSection) {\n <div class=\"row\">\n <div class=\"col-12\">\n <button class=\"btn btn-primary\" (click)=\"showSSOSection = true\"> {{ user?.cognito_sso_activated ? 'Resend\n activation email' : 'Enable' }} </button>\n </div>\n </div>\n }\n <!-- Password Validation -->\n @if (showSSOSection) {\n <div class=\"row\">\n @if (!ssoPasswordVerified) {\n <div class=\"col-12 col-md-6 col-lg-4 mt-2\">\n <div class=\"mb-3\">\n <input type=\"password\" class=\"form-control\" #ssoPassword placeholder=\"Current Password\"\n (keyup)=\"checkSSOPasswordValidity()\" id=\"input_current_password_801\" name=\"input_current_password_801\" />\n </div>\n </div>\n }\n <div class=\"col-12\">\n <div class=\"d-flex mt-2\">\n <button class=\"btn btn-raised btn-outline-default me-2\" (click)=\"resetSSO()\"> Cancel </button>\n @if (!ssoPasswordVerified) {\n <button class=\"btn btn-raised btn-primary\" (click)=\"validateSSOPassword()\"\n [disabled]=\"isSSOPasswordInvalid\"> Validate </button>\n }\n @if (ssoPasswordVerified) {\n <button class=\"btn btn-primary\" (click)=\"triggerSSO()\"> Confirm </button>\n }\n </div>\n </div>\n </div>\n }\n </p-accordion-content>\n </p-accordion-panel>\n</p-accordion>\n", styles: [".qr-code{margin:10px;max-width:200px}.text-muted{font-size:15px!important}\n"], dependencies: [{ kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { kind: "component", type: i2$2.Accordion, selector: "p-accordion", inputs: ["value", "multiple", "styleClass", "expandIcon", "collapseIcon", "selectOnFocus", "transitionOptions", "motionOptions"], outputs: ["valueChange", "onClose", "onOpen"] }, { kind: "component", type: i2$2.AccordionPanel, selector: "p-accordion-panel, p-accordionpanel", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: i2$2.AccordionHeader, selector: "p-accordion-header, p-accordionheader" }, { kind: "component", type: i2$2.AccordionContent, selector: "p-accordion-content, p-accordioncontent" }] }); }
2177
2178
  }
2178
2179
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SecurityTabComponent, decorators: [{
2179
2180
  type: Component,
2180
- args: [{ selector: 'pw-security-tab', standalone: false, template: "<div class=\"row\">\n <div class=\"col-12\">\n <h2>Security settings</h2>\n </div>\n</div>\n<p-accordion>\n <p-accordion-panel value=\"0\">\n <p-accordion-header>Two Factor Authentication (2FA)</p-accordion-header>\n <p-accordion-content>\n <div class=\"row mt-2\">\n <div class=\"col-12\">\n <div class=\"d-flex\">\n <p class=\"small text-muted\"> Add an extra layer of security to your user account by asking to verify their\n identity when they enter a username and password </p>\n </div>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n <!-- Disable 2FA -->\n @if (user?.enable_two_factor_authenticator) {\n <button class=\"btn btn-danger\" (click)=\"show2FA = true\"> Disable\n </button>\n }\n <!-- Enable 2FA -->\n @if (!user?.enable_two_factor_authenticator) {\n <button class=\"btn btn-primary\"\n [disabled]=\"created2faDetails?.code\" (click)=\"show2FA = true\"> Enable </button>\n }\n </div>\n </div>\n @if (show2FA) {\n <div class=\"row\">\n <div class=\"col-12 col-md-6 col-lg-4 mt-2\">\n <div class=\"mb-3\">\n @if (!passwordVerified) {\n <input type=\"password\" class=\"form-control\" #password placeholder=\"Current Password\"\n (keyup)=\"checkValidity()\" id=\"input_current_password_800\" name=\"input_current_password_800\" />\n }\n </div>\n </div>\n @if (created2faDetails?.code) {\n <div class=\"col-12\">\n <p class=\"small\"> Scan the QR code below or use secret manually with the Google authenticator app on your mobile\n device, after that fill in the field below with the code generated in the app </p>\n <img [src]=\"created2faDetails?.qr_uri\" alt=\"loading QR code...\" class=\"qr-code img-thumbnail img-responsive\" />\n <strong> Secret Key: {{ created2faDetails?.code }}</strong>\n <p class=\"small\">Auth Type: Time Based OTP</p>\n </div>\n }\n </div>\n }\n @if (show2FA) {\n <div class=\"row\">\n <div class=\"col-4\">\n <div class=\"mb-3 mt-2\">\n @if (passwordVerified) {\n <input type=\"text\" #verificationCode class=\"form-control\"\n placeholder=\"Provide passcode from authenticator app\" id=\"input_provide_passcode_from_authenticator_app_800\" name=\"input_provide_passcode_from_authenticator_app_800\" />\n }\n </div>\n </div>\n @if (show2FA) {\n <div class=\"col-12\">\n <div class=\"d-flex mt-2\">\n <button class=\"btn btn-raised btn-outline-default me-2\" (click)=\"reset()\"> Cancel </button>\n @if (!passwordVerified) {\n <button class=\"btn btn-raised btn-primary\" (click)=\"validatePassword()\"\n [disabled]=\"isCurrentPasswordValid\"> Validate </button>\n }\n @if (passwordVerified) {\n <button class=\"btn btn-raised btn-primary\" (click)=\"verify2FA()\"> Confirm </button>\n }\n </div>\n </div>\n }\n </div>\n }\n </p-accordion-content>\n </p-accordion-panel>\n</p-accordion>\n<p-accordion>\n <p-accordion-panel value=\"0\">\n <p-accordion-header>Single Sign On (SSO) - AWS Cognito</p-accordion-header>\n <p-accordion-content>\n <div class=\"row mt-2\">\n <div class=\"col-12\">\n <p class=\"small text-muted\"> {{ user?.cognito_sso_activated ? 'You have already activated AWS Cognito SSO, if you click on \u2018Resend activation email\u2018 you\u2018ll receive an email with instructions to reset your SSO\n password.' : 'Once you click \u2018Enable\u2019, you\u2019ll receive an email with instructions to activate your AWS Cognito\n SSO. This will enable you to access all our systems using a single password.' }} </p>\n </div>\n </div>\n <!-- Enable or Resend Button -->\n @if (!showSSOSection) {\n <div class=\"row\">\n <div class=\"col-12\">\n <button class=\"btn btn-primary\" (click)=\"showSSOSection = true\"> {{ user?.cognito_sso_activated ? 'Resend\n activation email' : 'Enable' }} </button>\n </div>\n </div>\n }\n <!-- Password Validation -->\n @if (showSSOSection) {\n <div class=\"row\">\n @if (!ssoPasswordVerified) {\n <div class=\"col-12 col-md-6 col-lg-4 mt-2\">\n <div class=\"mb-3\">\n <input type=\"password\" class=\"form-control\" #ssoPassword placeholder=\"Current Password\"\n (keyup)=\"checkSSOPasswordValidity()\" id=\"input_current_password_801\" name=\"input_current_password_801\" />\n </div>\n </div>\n }\n <div class=\"col-12\">\n <div class=\"d-flex mt-2\">\n <button class=\"btn btn-raised btn-outline-default me-2\" (click)=\"resetSSO()\"> Cancel </button>\n @if (!ssoPasswordVerified) {\n <button class=\"btn btn-raised btn-primary\" (click)=\"validateSSOPassword()\"\n [disabled]=\"isSSOPasswordInvalid\"> Validate </button>\n }\n @if (ssoPasswordVerified) {\n <button class=\"btn btn-primary\" (click)=\"triggerSSO()\"> Confirm </button>\n }\n </div>\n </div>\n </div>\n }\n </p-accordion-content>\n </p-accordion-panel>\n</p-accordion>\n", styles: [".qr-code{margin:10px;max-width:200px}.text-muted{font-size:15px!important}\n"] }]
2181
+ args: [{ selector: 'pw-security-tab', standalone: false, template: "<div class=\"row\">\n <div class=\"col-12\">\n <h2>Security settings</h2>\n </div>\n</div>\n<p-accordion>\n <p-accordion-panel value=\"0\">\n <p-accordion-header>Two Factor Authentication (2FA)</p-accordion-header>\n <p-accordion-content>\n <div class=\"row mt-2\">\n <div class=\"col-12\">\n <div class=\"d-flex\">\n <p class=\"small text-muted\"> Add an extra layer of security to your user account by asking to verify their\n identity when they enter a username and password </p>\n </div>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n <!-- Disable 2FA -->\n @if (user?.enable_two_factor_authenticator) {\n <button class=\"btn btn-danger\" (click)=\"show2FA = true\"> Disable\n </button>\n }\n <!-- Enable 2FA -->\n @if (!user?.enable_two_factor_authenticator) {\n <button class=\"btn btn-primary\"\n [disabled]=\"created2faDetails?.code\" (click)=\"show2FA = true\"> Enable </button>\n }\n </div>\n </div>\n @if (show2FA) {\n <div class=\"row\">\n <div class=\"col-12 col-md-6 col-lg-4 mt-2\">\n <div class=\"mb-3\">\n @if (!passwordVerified) {\n <input type=\"password\" class=\"form-control\" #password placeholder=\"Current Password\"\n (keyup)=\"checkValidity()\" id=\"input_current_password_800\" name=\"input_current_password_800\" />\n }\n </div>\n </div>\n @if (created2faDetails?.code) {\n <div class=\"col-12\">\n <p class=\"small\"> Scan the QR code below or use secret manually with the Google authenticator app on your mobile\n device, after that fill in the field below with the code generated in the app </p>\n <img [src]=\"created2faDetails?.qr_uri\" alt=\"loading QR code...\" class=\"qr-code img-thumbnail img-responsive\" />\n <strong> Secret Key: {{ created2faDetails?.code }}</strong>\n <p class=\"small\">Auth Type: Time Based OTP</p>\n </div>\n }\n </div>\n }\n @if (show2FA) {\n <div class=\"row\">\n <div class=\"col-4\">\n <div class=\"mb-3 mt-2\">\n @if (passwordVerified) {\n <input type=\"text\" #verificationCode class=\"form-control\"\n placeholder=\"Provide passcode from authenticator app\" id=\"input_provide_passcode_from_authenticator_app_800\" name=\"input_provide_passcode_from_authenticator_app_800\" />\n }\n </div>\n </div>\n @if (show2FA) {\n <div class=\"col-12\">\n <div class=\"d-flex mt-2\">\n <button class=\"btn btn-raised btn-outline-default me-2\" (click)=\"reset()\"> Cancel </button>\n @if (!passwordVerified) {\n <button class=\"btn btn-raised btn-primary\" (click)=\"validatePassword()\"\n [disabled]=\"isCurrentPasswordValid\"> Validate </button>\n }\n @if (passwordVerified) {\n <button class=\"btn btn-raised btn-primary\" (click)=\"verify2FA()\"> Confirm </button>\n }\n </div>\n </div>\n }\n </div>\n }\n </p-accordion-content>\n </p-accordion-panel>\n <p-accordion-panel value=\"1\">\n <p-accordion-header>Single Sign On (SSO) - AWS Cognito</p-accordion-header>\n <p-accordion-content>\n <div class=\"row mt-2\">\n <div class=\"col-12\">\n <p class=\"small text-muted\"> {{ user?.cognito_sso_activated ? 'You have already activated AWS Cognito SSO, if you click on \u2018Resend activation email\u2018 you\u2018ll receive an email with instructions to reset your SSO\n password.' : 'Once you click \u2018Enable\u2019, you\u2019ll receive an email with instructions to activate your AWS Cognito\n SSO. This will enable you to access all our systems using a single password.' }} </p>\n </div>\n </div>\n <!-- Enable or Resend Button -->\n @if (!showSSOSection) {\n <div class=\"row\">\n <div class=\"col-12\">\n <button class=\"btn btn-primary\" (click)=\"showSSOSection = true\"> {{ user?.cognito_sso_activated ? 'Resend\n activation email' : 'Enable' }} </button>\n </div>\n </div>\n }\n <!-- Password Validation -->\n @if (showSSOSection) {\n <div class=\"row\">\n @if (!ssoPasswordVerified) {\n <div class=\"col-12 col-md-6 col-lg-4 mt-2\">\n <div class=\"mb-3\">\n <input type=\"password\" class=\"form-control\" #ssoPassword placeholder=\"Current Password\"\n (keyup)=\"checkSSOPasswordValidity()\" id=\"input_current_password_801\" name=\"input_current_password_801\" />\n </div>\n </div>\n }\n <div class=\"col-12\">\n <div class=\"d-flex mt-2\">\n <button class=\"btn btn-raised btn-outline-default me-2\" (click)=\"resetSSO()\"> Cancel </button>\n @if (!ssoPasswordVerified) {\n <button class=\"btn btn-raised btn-primary\" (click)=\"validateSSOPassword()\"\n [disabled]=\"isSSOPasswordInvalid\"> Validate </button>\n }\n @if (ssoPasswordVerified) {\n <button class=\"btn btn-primary\" (click)=\"triggerSSO()\"> Confirm </button>\n }\n </div>\n </div>\n </div>\n }\n </p-accordion-content>\n </p-accordion-panel>\n</p-accordion>\n", styles: [".qr-code{margin:10px;max-width:200px}.text-muted{font-size:15px!important}\n"] }]
2181
2182
  }], ctorParameters: () => [{ type: i0.Injector }, { type: i0.ChangeDetectorRef }], propDecorators: { passwordRef: [{
2182
2183
  type: ViewChild,
2183
2184
  args: ['password', { static: false }]
@@ -2257,11 +2258,11 @@ class SupportComponent extends AppBaseComponent {
2257
2258
  });
2258
2259
  }
2259
2260
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SupportComponent, deps: [{ token: i0.Injector }, { token: i1$2.CommonService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
2260
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: SupportComponent, isStandalone: false, selector: "pw-support", usesInheritance: true, ngImport: i0, template: "<div class=\"row m-3\">\n <div class=\"col-12 mb-3\">\n <div\n class=\"col-12 d-flex flex-wrap justify-content-between align-items-center mt-4\">\n <h2 class=\"card-title p-0 float-start\">Support Center</h2>\n <a routerLink=\"/support-details/add\"\n aria-label=\"Navigate to Target\"\n class=\"btn btn-sm btn-outline-primary float-end\"\n tabindex=\"0\"\n (keydown)=\"$event.key === 'Enter' && $event.target.click()\"\n aria-expanded=\"false\">\n <i class=\"fa fa-plus-circle\"\n aria-hidden=\"true\"></i>\n Create new support request\n </a>\n </div>\n </div>\n <div class=\"col-12 my-3\">\n <h3>Previous support requests</h3>\n <p>Please note that responses to your support requests are sent directly to your email. You can simply reply to those\n emails for further assistance.</p>\n </div>\n @if (isLoading) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n <div class=\"col-12 mb-3\">\n <p-accordion>\n @for (item of supports; track item; let i = $index) {\n <p-accordion-panel [value]=\"i\">\n <p-accordion-header>{{ item?.created_at | dateFormat }} ({{ item?.user_name }}) {{ item?.title }}</p-accordion-header>\n <p-accordion-content>\n <p>{{ item?.description }}</p>\n <a [href]=\"item?.attachment?.version_200x200?.url\"\n target=\"_blank\">\n @if (item?.attachment?.version_200x200?.url) {\n <img alt=\"version_200x200\"\n [src]=\"item?.attachment?.version_200x200?.url\"\n class=\"img-fluid\" />\n }</a>\n </p-accordion-content>\n </p-accordion-panel>\n }\n </p-accordion>\n </div>\n @if (!supports?.length && isLoaded) {\n <div class=\"col-12\"\n >\n <pw-no-data [withImage]=\"true\" message=\"No support requests found\"> </pw-no-data>\n </div>\n }\n </div>\n", styles: [".contact-support{font-size:24px;font-weight:600}\n"], dependencies: [{ kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i5.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "component", type: i2$2.Accordion, selector: "p-accordion", inputs: ["value", "multiple", "styleClass", "expandIcon", "collapseIcon", "selectOnFocus", "transitionOptions", "motionOptions"], outputs: ["valueChange", "onClose", "onOpen"] }, { kind: "component", type: i2$2.AccordionPanel, selector: "p-accordion-panel, p-accordionpanel", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: i2$2.AccordionHeader, selector: "p-accordion-header, p-accordionheader" }, { kind: "component", type: i2$2.AccordionContent, selector: "p-accordion-content, p-accordioncontent" }, { kind: "pipe", type: i6$3.DateFormatPipe, name: "dateFormat" }] }); }
2261
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: SupportComponent, isStandalone: false, selector: "pw-support", usesInheritance: true, ngImport: i0, template: "<div class=\"row m-3\">\n <div class=\"col-12 mb-3\">\n <div\n class=\"col-12 d-flex flex-wrap justify-content-between align-items-center mt-4\">\n <h2 class=\"card-title p-0 float-start\">Support Center</h2>\n <a routerLink=\"/support-details/add\"\n aria-label=\"Navigate to Target\"\n class=\"btn btn-sm btn-outline-primary float-end\"\n tabindex=\"0\"\n (keydown)=\"$event.key === 'Enter' && $event.target.click()\"\n aria-expanded=\"false\">\n <i class=\"fa fa-plus-circle\"\n aria-hidden=\"true\"></i>\n Create new support request\n </a>\n </div>\n </div>\n <div class=\"col-12 my-3\">\n <h3>Previous support requests</h3>\n <p>Please note that responses to your support requests are sent directly to your email. You can simply reply to those\n emails for further assistance.</p>\n </div>\n @if (isLoading) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (supports?.length) {\n <div class=\"col-12 mb-3\">\n <p-accordion>\n @for (item of supports; track item; let i = $index) {\n <p-accordion-panel [value]=\"i\">\n <p-accordion-header>{{ item?.created_at | dateFormat }} ({{ item?.user_name }}) {{ item?.title }}</p-accordion-header>\n <p-accordion-content>\n <p>{{ item?.description }}</p>\n <a [href]=\"item?.attachment?.version_200x200?.url\"\n target=\"_blank\">\n @if (item?.attachment?.version_200x200?.url) {\n <img alt=\"version_200x200\"\n [src]=\"item?.attachment?.version_200x200?.url\"\n class=\"img-fluid\" />\n }</a>\n </p-accordion-content>\n </p-accordion-panel>\n }\n </p-accordion>\n </div>\n }\n @if (!supports?.length && isLoaded) {\n <div class=\"col-12\"\n >\n <pw-no-data [withImage]=\"true\" message=\"No support requests found\"> </pw-no-data>\n </div>\n }\n </div>\n", styles: [".contact-support{font-size:24px;font-weight:600}\n"], dependencies: [{ kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i5.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "component", type: i2$2.Accordion, selector: "p-accordion", inputs: ["value", "multiple", "styleClass", "expandIcon", "collapseIcon", "selectOnFocus", "transitionOptions", "motionOptions"], outputs: ["valueChange", "onClose", "onOpen"] }, { kind: "component", type: i2$2.AccordionPanel, selector: "p-accordion-panel, p-accordionpanel", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: i2$2.AccordionHeader, selector: "p-accordion-header, p-accordionheader" }, { kind: "component", type: i2$2.AccordionContent, selector: "p-accordion-content, p-accordioncontent" }, { kind: "pipe", type: i6$3.DateFormatPipe, name: "dateFormat" }] }); }
2261
2262
  }
2262
2263
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SupportComponent, decorators: [{
2263
2264
  type: Component,
2264
- args: [{ selector: 'pw-support', standalone: false, template: "<div class=\"row m-3\">\n <div class=\"col-12 mb-3\">\n <div\n class=\"col-12 d-flex flex-wrap justify-content-between align-items-center mt-4\">\n <h2 class=\"card-title p-0 float-start\">Support Center</h2>\n <a routerLink=\"/support-details/add\"\n aria-label=\"Navigate to Target\"\n class=\"btn btn-sm btn-outline-primary float-end\"\n tabindex=\"0\"\n (keydown)=\"$event.key === 'Enter' && $event.target.click()\"\n aria-expanded=\"false\">\n <i class=\"fa fa-plus-circle\"\n aria-hidden=\"true\"></i>\n Create new support request\n </a>\n </div>\n </div>\n <div class=\"col-12 my-3\">\n <h3>Previous support requests</h3>\n <p>Please note that responses to your support requests are sent directly to your email. You can simply reply to those\n emails for further assistance.</p>\n </div>\n @if (isLoading) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n <div class=\"col-12 mb-3\">\n <p-accordion>\n @for (item of supports; track item; let i = $index) {\n <p-accordion-panel [value]=\"i\">\n <p-accordion-header>{{ item?.created_at | dateFormat }} ({{ item?.user_name }}) {{ item?.title }}</p-accordion-header>\n <p-accordion-content>\n <p>{{ item?.description }}</p>\n <a [href]=\"item?.attachment?.version_200x200?.url\"\n target=\"_blank\">\n @if (item?.attachment?.version_200x200?.url) {\n <img alt=\"version_200x200\"\n [src]=\"item?.attachment?.version_200x200?.url\"\n class=\"img-fluid\" />\n }</a>\n </p-accordion-content>\n </p-accordion-panel>\n }\n </p-accordion>\n </div>\n @if (!supports?.length && isLoaded) {\n <div class=\"col-12\"\n >\n <pw-no-data [withImage]=\"true\" message=\"No support requests found\"> </pw-no-data>\n </div>\n }\n </div>\n", styles: [".contact-support{font-size:24px;font-weight:600}\n"] }]
2265
+ args: [{ selector: 'pw-support', standalone: false, template: "<div class=\"row m-3\">\n <div class=\"col-12 mb-3\">\n <div\n class=\"col-12 d-flex flex-wrap justify-content-between align-items-center mt-4\">\n <h2 class=\"card-title p-0 float-start\">Support Center</h2>\n <a routerLink=\"/support-details/add\"\n aria-label=\"Navigate to Target\"\n class=\"btn btn-sm btn-outline-primary float-end\"\n tabindex=\"0\"\n (keydown)=\"$event.key === 'Enter' && $event.target.click()\"\n aria-expanded=\"false\">\n <i class=\"fa fa-plus-circle\"\n aria-hidden=\"true\"></i>\n Create new support request\n </a>\n </div>\n </div>\n <div class=\"col-12 my-3\">\n <h3>Previous support requests</h3>\n <p>Please note that responses to your support requests are sent directly to your email. You can simply reply to those\n emails for further assistance.</p>\n </div>\n @if (isLoading) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (supports?.length) {\n <div class=\"col-12 mb-3\">\n <p-accordion>\n @for (item of supports; track item; let i = $index) {\n <p-accordion-panel [value]=\"i\">\n <p-accordion-header>{{ item?.created_at | dateFormat }} ({{ item?.user_name }}) {{ item?.title }}</p-accordion-header>\n <p-accordion-content>\n <p>{{ item?.description }}</p>\n <a [href]=\"item?.attachment?.version_200x200?.url\"\n target=\"_blank\">\n @if (item?.attachment?.version_200x200?.url) {\n <img alt=\"version_200x200\"\n [src]=\"item?.attachment?.version_200x200?.url\"\n class=\"img-fluid\" />\n }</a>\n </p-accordion-content>\n </p-accordion-panel>\n }\n </p-accordion>\n </div>\n }\n @if (!supports?.length && isLoaded) {\n <div class=\"col-12\"\n >\n <pw-no-data [withImage]=\"true\" message=\"No support requests found\"> </pw-no-data>\n </div>\n }\n </div>\n", styles: [".contact-support{font-size:24px;font-weight:600}\n"] }]
2265
2266
  }], ctorParameters: () => [{ type: i0.Injector }, { type: i1$2.CommonService }, { type: i0.ChangeDetectorRef }] });
2266
2267
 
2267
2268
  class SupportDetailsComponent extends AppBaseComponent {
@@ -2356,7 +2357,7 @@ class SupportDetailsComponent extends AppBaseComponent {
2356
2357
  HelperService.onUploadError(event, this.toast);
2357
2358
  }
2358
2359
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SupportDetailsComponent, deps: [{ token: i0.Injector }, { token: i1$2.CommonService }, { token: i1$2.AuthService }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
2359
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: SupportDetailsComponent, isStandalone: false, selector: "pw-support-details", usesInheritance: true, ngImport: i0, template: "<div class=\"container-fluid pw-tab overflow-hidden\">\n <div class=\"dashboard\">\n <div class=\"dashboard-body\">\n <div class=\"me-auto col-xs-6 mt-4\">\n <a aria-label=\"Navigate to Target\" (click)=\"back()\" class=\"previous\"><i\n class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h3 class=\"mt-3\">{{ 'Label.NewSupport' | transloco }}</h3>\n </div>\n <div class=\"p-2 m-1 mt-3\">\n <form [formGroup]=\"form\"\n (ngSubmit)=\"onSave()\">\n <div class=\"row\">\n <div class=\"col-12\">\n <pw-input-container controlId=\"support-details-title\"\n label=\"title\"\n name=\"title\"\n errorMsg=\"Title is required\">\n <input type=\"text\"\n id=\"support-details-title\"\n class=\"form-control\"\n formControlName=\"title\" />\n </pw-input-container>\n </div>\n <div class=\"col-12 col-sm-12\">\n <pw-input-container controlId=\"support-details-description\"\n label=\"Description\"\n errorMsg=\"description is required\"\n name=\"description\">\n <textarea rows=\"3\"\n id=\"support-details-description\"\n type=\"text\"\n class=\"form-control\"\n formControlName=\"description\"></textarea>\n </pw-input-container>\n </div>\n <div class=\"col-12 col-md-6\">\n <h4 class=\"mt-4\">You can add a picture here</h4>\n <div class=\"mb-3 file-upload-support-details\">\n <span id=\"support-details-file-label\" class=\"pw-label-style\">Upload Picture</span>\n <p-fileUpload #forms\n [attr.aria-labelledby]=\"'support-details-file-label'\"\n name=\"myfile[]\"\n [customUpload]=\"true\"\n [showUploadButton]=\"false\"\n accept=\"image/*\"\n [disabled]=\"uploadedFiles && uploadedFiles.length > 0\"\n (onSelect)=\"onSelect($event)\"\n (onRemove)=\"onRemove($event)\"\n (onError)=\"onUploadError($event)\">\n @if (uploadedFiles?.length) {\n <ng-template pTemplate=\"content\"\n >\n @if (!filesUploaded && (!uploadedFiles || uploadedFiles.length === 0)) {\n <div class=\"drag-drop-text\">\n <p>You can drag and drop your file here</p>\n </div>\n }\n </ng-template>\n }\n </p-fileUpload>\n </div>\n </div>\n @if (isLoading) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n <div class=\"col-12 text-end mt-3\">\n @if (isSubmitClicked) {\n <div class=\"support-details-captcha\">\n <ngx-recaptcha2 [ngModelOptions]=\"{ standalone: true }\"\n [siteKey]=\"siteKey\"\n size=\"normal\"\n [(ngModel)]=\"recaptcha\"\n (success)=\"handleSuccess($event)\">\n </ngx-recaptcha2>\n </div>\n }\n @if (!isSubmitClicked) {\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"back()\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n class=\"btn btn-primary\" [disabled]=\"invalidFile\">\n {{ 'Button.Submit' | transloco }}\n </button>\n }\n </div>\n </div>\n </form>\n </div>\n </div>\n </div>\n</div>\n", styles: ["::ng-deep .file-upload-support-details .p-fileupload .p-fileupload-content{padding:4rem 1rem}::ng-deep .file-upload-support-details .p-fileupload-content .p-fileupload-files .p-fileupload-row>:first-child{display:none}.support-details-captcha{text-align:-webkit-right}.drag-drop-text{padding:20px;border:2px dashed #ccc;text-align:center;color:#aaa;margin-top:10px}::ng-deep .file-upload-support-details .p-fileupload .p-fileupload-content{padding:1rem}::ng-deep .file-upload-support-details .p-fileupload-content .p-fileupload-files .p-fileupload-row>:first-child{display:flex}\n"], dependencies: [{ 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: "directive", type: i5$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i5.InputContainerComponent, selector: "pw-input-container", inputs: ["name", "controlId", "useAriaLabelledbyOnly", "label", "labelClass", "tooltipPosition", "required", "errorMsg", "isReadOnly", "showTooltip", "tooltipText", "showTriangle", "afterLabel", "showAfterLabel", "showTriangleText", "isLeftTooltip"] }, { kind: "component", type: i6$5.ReCaptcha2Component, selector: "ngx-recaptcha2", inputs: ["theme", "size"] }, { kind: "component", type: i7.FileUpload, selector: "p-fileupload, p-fileUpload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "uploadStyleClass", "cancelStyleClass", "removeStyleClass", "chooseStyleClass", "chooseButtonProps", "uploadButtonProps", "cancelButtonProps", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler", "onImageError", "onRemoveUploadedFile"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
2360
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: SupportDetailsComponent, isStandalone: false, selector: "pw-support-details", usesInheritance: true, ngImport: i0, template: "<div class=\"container-fluid pw-tab overflow-hidden\">\n <div class=\"dashboard\">\n <div class=\"dashboard-body\">\n <div class=\"me-auto col-xs-6 mt-4\">\n <a aria-label=\"Navigate to Target\" (click)=\"back()\" class=\"previous\"><i\n class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h3 class=\"mt-3\">{{ 'Label.NewSupport' | transloco }}</h3>\n </div>\n <div class=\"p-2 m-1 mt-3\">\n <form [formGroup]=\"form\"\n (ngSubmit)=\"onSave()\">\n <div class=\"row\">\n <div class=\"col-12\">\n <pw-input-container controlId=\"support-details-title\"\n label=\"title\"\n name=\"title\"\n errorMsg=\"Title is required\">\n <input type=\"text\"\n id=\"support-details-title\"\n class=\"form-control\"\n [placeholder]=\"'Support.Placeholder.Title' | transloco\"\n formControlName=\"title\" />\n </pw-input-container>\n </div>\n <div class=\"col-12\">\n <pw-input-container controlId=\"support-details-description\"\n label=\"Description\"\n errorMsg=\"description is required\"\n name=\"description\">\n <textarea rows=\"3\"\n id=\"support-details-description\"\n type=\"text\"\n class=\"form-control\"\n [placeholder]=\"'Support.Placeholder.Description' | transloco\"\n formControlName=\"description\"></textarea>\n </pw-input-container>\n </div>\n <div class=\"col-12\">\n <div class=\"mb-3 file-upload-support-details\">\n <span id=\"support-details-file-label\" class=\"pw-label-style\">Upload Picture</span>\n <p-fileUpload #forms\n [attr.aria-labelledby]=\"'support-details-file-label'\"\n name=\"myfile[]\"\n [customUpload]=\"true\"\n [showUploadButton]=\"false\"\n accept=\"image/*\"\n [disabled]=\"uploadedFiles && uploadedFiles.length > 0\"\n (onSelect)=\"onSelect($event)\"\n (onRemove)=\"onRemove($event)\"\n (onError)=\"onUploadError($event)\">\n <ng-template pTemplate=\"content\">\n @if (!uploadedFiles?.length) {\n <div class=\"drag-drop-text\">\n <p>You can drag and drop your file here</p>\n </div>\n }\n </ng-template>\n </p-fileUpload>\n </div>\n </div>\n @if (isLoading) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n <div class=\"col-12 text-end mt-3\">\n @if (isSubmitClicked) {\n <div class=\"support-details-captcha\">\n <ngx-recaptcha2 [ngModelOptions]=\"{ standalone: true }\"\n [siteKey]=\"siteKey\"\n size=\"normal\"\n [(ngModel)]=\"recaptcha\"\n (success)=\"handleSuccess($event)\">\n </ngx-recaptcha2>\n </div>\n }\n @if (!isSubmitClicked) {\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"back()\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n class=\"btn btn-primary\" [disabled]=\"invalidFile\">\n {{ 'Button.Submit' | transloco }}\n </button>\n }\n </div>\n </div>\n </form>\n </div>\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";::ng-deep .file-upload-support-details .p-fileupload .p-fileupload-content{padding:4rem 1rem}::ng-deep .file-upload-support-details .p-fileupload-content .p-fileupload-files .p-fileupload-row>:first-child{display:none}.support-details-captcha{text-align:-webkit-right}:host .pw-label-style{display:block;height:18px;line-height:18px;margin-bottom:8px}.drag-drop-text{padding:20px;border:2px dashed #ccc;text-align:center;color:#aaa;margin-top:10px}::ng-deep .file-upload-support-details .p-fileupload .p-fileupload-content{padding:1rem}::ng-deep .file-upload-support-details .p-fileupload-content .p-fileupload-files .p-fileupload-row>:first-child{display:flex}\n"], dependencies: [{ 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: "directive", type: i5$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i5.InputContainerComponent, selector: "pw-input-container", inputs: ["name", "controlId", "useAriaLabelledbyOnly", "label", "labelClass", "tooltipPosition", "required", "errorMsg", "isReadOnly", "showTooltip", "tooltipText", "showTriangle", "afterLabel", "showAfterLabel", "showTriangleText", "isLeftTooltip"] }, { kind: "component", type: i6$4.ReCaptcha2Component, selector: "ngx-recaptcha2", inputs: ["theme", "size"] }, { kind: "component", type: i7.FileUpload, selector: "p-fileupload, p-fileUpload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "uploadStyleClass", "cancelStyleClass", "removeStyleClass", "chooseStyleClass", "chooseButtonProps", "uploadButtonProps", "cancelButtonProps", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler", "onImageError", "onRemoveUploadedFile"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
2360
2361
  }
2361
2362
  __decorate([
2362
2363
  ValidateForm('form'),
@@ -2366,7 +2367,7 @@ __decorate([
2366
2367
  ], SupportDetailsComponent.prototype, "onSave", null);
2367
2368
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SupportDetailsComponent, decorators: [{
2368
2369
  type: Component,
2369
- args: [{ selector: 'pw-support-details', standalone: false, template: "<div class=\"container-fluid pw-tab overflow-hidden\">\n <div class=\"dashboard\">\n <div class=\"dashboard-body\">\n <div class=\"me-auto col-xs-6 mt-4\">\n <a aria-label=\"Navigate to Target\" (click)=\"back()\" class=\"previous\"><i\n class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h3 class=\"mt-3\">{{ 'Label.NewSupport' | transloco }}</h3>\n </div>\n <div class=\"p-2 m-1 mt-3\">\n <form [formGroup]=\"form\"\n (ngSubmit)=\"onSave()\">\n <div class=\"row\">\n <div class=\"col-12\">\n <pw-input-container controlId=\"support-details-title\"\n label=\"title\"\n name=\"title\"\n errorMsg=\"Title is required\">\n <input type=\"text\"\n id=\"support-details-title\"\n class=\"form-control\"\n formControlName=\"title\" />\n </pw-input-container>\n </div>\n <div class=\"col-12 col-sm-12\">\n <pw-input-container controlId=\"support-details-description\"\n label=\"Description\"\n errorMsg=\"description is required\"\n name=\"description\">\n <textarea rows=\"3\"\n id=\"support-details-description\"\n type=\"text\"\n class=\"form-control\"\n formControlName=\"description\"></textarea>\n </pw-input-container>\n </div>\n <div class=\"col-12 col-md-6\">\n <h4 class=\"mt-4\">You can add a picture here</h4>\n <div class=\"mb-3 file-upload-support-details\">\n <span id=\"support-details-file-label\" class=\"pw-label-style\">Upload Picture</span>\n <p-fileUpload #forms\n [attr.aria-labelledby]=\"'support-details-file-label'\"\n name=\"myfile[]\"\n [customUpload]=\"true\"\n [showUploadButton]=\"false\"\n accept=\"image/*\"\n [disabled]=\"uploadedFiles && uploadedFiles.length > 0\"\n (onSelect)=\"onSelect($event)\"\n (onRemove)=\"onRemove($event)\"\n (onError)=\"onUploadError($event)\">\n @if (uploadedFiles?.length) {\n <ng-template pTemplate=\"content\"\n >\n @if (!filesUploaded && (!uploadedFiles || uploadedFiles.length === 0)) {\n <div class=\"drag-drop-text\">\n <p>You can drag and drop your file here</p>\n </div>\n }\n </ng-template>\n }\n </p-fileUpload>\n </div>\n </div>\n @if (isLoading) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n <div class=\"col-12 text-end mt-3\">\n @if (isSubmitClicked) {\n <div class=\"support-details-captcha\">\n <ngx-recaptcha2 [ngModelOptions]=\"{ standalone: true }\"\n [siteKey]=\"siteKey\"\n size=\"normal\"\n [(ngModel)]=\"recaptcha\"\n (success)=\"handleSuccess($event)\">\n </ngx-recaptcha2>\n </div>\n }\n @if (!isSubmitClicked) {\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"back()\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n class=\"btn btn-primary\" [disabled]=\"invalidFile\">\n {{ 'Button.Submit' | transloco }}\n </button>\n }\n </div>\n </div>\n </form>\n </div>\n </div>\n </div>\n</div>\n", styles: ["::ng-deep .file-upload-support-details .p-fileupload .p-fileupload-content{padding:4rem 1rem}::ng-deep .file-upload-support-details .p-fileupload-content .p-fileupload-files .p-fileupload-row>:first-child{display:none}.support-details-captcha{text-align:-webkit-right}.drag-drop-text{padding:20px;border:2px dashed #ccc;text-align:center;color:#aaa;margin-top:10px}::ng-deep .file-upload-support-details .p-fileupload .p-fileupload-content{padding:1rem}::ng-deep .file-upload-support-details .p-fileupload-content .p-fileupload-files .p-fileupload-row>:first-child{display:flex}\n"] }]
2370
+ args: [{ selector: 'pw-support-details', standalone: false, template: "<div class=\"container-fluid pw-tab overflow-hidden\">\n <div class=\"dashboard\">\n <div class=\"dashboard-body\">\n <div class=\"me-auto col-xs-6 mt-4\">\n <a aria-label=\"Navigate to Target\" (click)=\"back()\" class=\"previous\"><i\n class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h3 class=\"mt-3\">{{ 'Label.NewSupport' | transloco }}</h3>\n </div>\n <div class=\"p-2 m-1 mt-3\">\n <form [formGroup]=\"form\"\n (ngSubmit)=\"onSave()\">\n <div class=\"row\">\n <div class=\"col-12\">\n <pw-input-container controlId=\"support-details-title\"\n label=\"title\"\n name=\"title\"\n errorMsg=\"Title is required\">\n <input type=\"text\"\n id=\"support-details-title\"\n class=\"form-control\"\n [placeholder]=\"'Support.Placeholder.Title' | transloco\"\n formControlName=\"title\" />\n </pw-input-container>\n </div>\n <div class=\"col-12\">\n <pw-input-container controlId=\"support-details-description\"\n label=\"Description\"\n errorMsg=\"description is required\"\n name=\"description\">\n <textarea rows=\"3\"\n id=\"support-details-description\"\n type=\"text\"\n class=\"form-control\"\n [placeholder]=\"'Support.Placeholder.Description' | transloco\"\n formControlName=\"description\"></textarea>\n </pw-input-container>\n </div>\n <div class=\"col-12\">\n <div class=\"mb-3 file-upload-support-details\">\n <span id=\"support-details-file-label\" class=\"pw-label-style\">Upload Picture</span>\n <p-fileUpload #forms\n [attr.aria-labelledby]=\"'support-details-file-label'\"\n name=\"myfile[]\"\n [customUpload]=\"true\"\n [showUploadButton]=\"false\"\n accept=\"image/*\"\n [disabled]=\"uploadedFiles && uploadedFiles.length > 0\"\n (onSelect)=\"onSelect($event)\"\n (onRemove)=\"onRemove($event)\"\n (onError)=\"onUploadError($event)\">\n <ng-template pTemplate=\"content\">\n @if (!uploadedFiles?.length) {\n <div class=\"drag-drop-text\">\n <p>You can drag and drop your file here</p>\n </div>\n }\n </ng-template>\n </p-fileUpload>\n </div>\n </div>\n @if (isLoading) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n <div class=\"col-12 text-end mt-3\">\n @if (isSubmitClicked) {\n <div class=\"support-details-captcha\">\n <ngx-recaptcha2 [ngModelOptions]=\"{ standalone: true }\"\n [siteKey]=\"siteKey\"\n size=\"normal\"\n [(ngModel)]=\"recaptcha\"\n (success)=\"handleSuccess($event)\">\n </ngx-recaptcha2>\n </div>\n }\n @if (!isSubmitClicked) {\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"back()\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n class=\"btn btn-primary\" [disabled]=\"invalidFile\">\n {{ 'Button.Submit' | transloco }}\n </button>\n }\n </div>\n </div>\n </form>\n </div>\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";::ng-deep .file-upload-support-details .p-fileupload .p-fileupload-content{padding:4rem 1rem}::ng-deep .file-upload-support-details .p-fileupload-content .p-fileupload-files .p-fileupload-row>:first-child{display:none}.support-details-captcha{text-align:-webkit-right}:host .pw-label-style{display:block;height:18px;line-height:18px;margin-bottom:8px}.drag-drop-text{padding:20px;border:2px dashed #ccc;text-align:center;color:#aaa;margin-top:10px}::ng-deep .file-upload-support-details .p-fileupload .p-fileupload-content{padding:1rem}::ng-deep .file-upload-support-details .p-fileupload-content .p-fileupload-files .p-fileupload-row>:first-child{display:flex}\n"] }]
2370
2371
  }], ctorParameters: () => [{ type: i0.Injector }, { type: i1$2.CommonService }, { type: i1$2.AuthService }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { onSave: [] } });
2371
2372
 
2372
2373
  class EditPortfoliosComponent {
@@ -2456,11 +2457,11 @@ class EditPortfoliosComponent {
2456
2457
  HelperService.onUploadError(event);
2457
2458
  }
2458
2459
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EditPortfoliosComponent, deps: [{ token: i1$1.NgbModal }, { token: i1$2.ProfileService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
2459
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: EditPortfoliosComponent, isStandalone: false, selector: "pw-edit-portfolios", inputs: { id: "id", slug: "slug" }, outputs: { successEvent: "successEvent" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }, { propertyName: "uploader", first: true, predicate: ["form"], descendants: true }], ngImport: i0, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">Add/Edit Portfolio Item</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n Add a cover image or a downloadable file for your portfolio item\n <p-fileUpload #form\n name=\"myfile[]\"\n [customUpload]=\"true\"\n [showUploadButton]=\"false\"\n accept=\"\"\n [disabled]=\"uploadedFiles && uploadedFiles.length > 0\"\n (onSelect)=\"onSelect($event)\"\n (onRemove)=\"onRemove($event)\"\n (onError)=\"onUploadError($event)\">\n @if (uploadedFiles?.length) {\n <ng-template pTemplate=\"content\"\n >\n @if (!filesUploaded && (!uploadedFiles || uploadedFiles.length === 0)) {\n <div class=\"drag-drop-text\">\n <p>You can drag and drop your file here</p>\n </div>\n }\n </ng-template>\n }\n </p-fileUpload>\n <div class=\"ui-fileupload-content ui-widget-content ui-corner-bottom\">\n <div class=\"ui-fileupload-files\">\n <div class=\"\">\n <h5>Uploaded Pictures</h5>\n @for (image of projectPictures; track trackByImage($index, image)) {\n <div\n class=\"ui-fileupload-row d-inline-block\">\n <div>\n <img [src]=\"image?.picture?.version_50x50?.url\"\n alt=\"\"\n width=\"50\" />\n </div>\n <div class=\"pt-1 ps-1\">\n <button icon=\"pi pi-times\"\n type=\"button\"\n (click)=\"deleteProjectPicture(image.id)\"\n class=\"ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only\">\n <span class=\"ui-button-icon-left ui-clickable pi pi-times\"></span>\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.close()\">\n Cancel\n </button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n [buttonBusy]=\"busy\"\n (click)=\"onSave(form)\">\n Save\n </button>\n </div>\n</ng-template>\n", styles: [".drag-drop-text{padding:20px;border:2px dashed #ccc;text-align:center;color:#aaa;margin-top:10px}\n"], dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { kind: "directive", type: i5$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i7.FileUpload, selector: "p-fileupload, p-fileUpload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "uploadStyleClass", "cancelStyleClass", "removeStyleClass", "chooseStyleClass", "chooseButtonProps", "uploadButtonProps", "cancelButtonProps", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler", "onImageError", "onRemoveUploadedFile"] }] }); }
2460
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: EditPortfoliosComponent, isStandalone: false, selector: "pw-edit-portfolios", inputs: { id: "id", slug: "slug" }, outputs: { successEvent: "successEvent" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }, { propertyName: "uploader", first: true, predicate: ["form"], descendants: true }], ngImport: i0, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">Add/Edit Portfolio Item</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n Add a cover image or a downloadable file for your portfolio item\n <p-fileUpload #form\n name=\"myfile[]\"\n [customUpload]=\"true\"\n [showUploadButton]=\"false\"\n accept=\"\"\n [disabled]=\"uploadedFiles && uploadedFiles.length > 0\"\n (onSelect)=\"onSelect($event)\"\n (onRemove)=\"onRemove($event)\"\n (onError)=\"onUploadError($event)\">\n <ng-template pTemplate=\"content\">\n @if (!uploadedFiles?.length) {\n <div class=\"drag-drop-text\">\n <p>You can drag and drop your file here</p>\n </div>\n }\n </ng-template>\n </p-fileUpload>\n <div class=\"ui-fileupload-content ui-widget-content ui-corner-bottom\">\n <div class=\"ui-fileupload-files\">\n <div class=\"\">\n <h5>Uploaded Pictures</h5>\n @for (image of projectPictures; track trackByImage($index, image)) {\n <div\n class=\"ui-fileupload-row d-inline-block\">\n <div>\n <img [src]=\"image?.picture?.version_50x50?.url\"\n alt=\"\"\n width=\"50\" />\n </div>\n <div class=\"pt-1 ps-1\">\n <button icon=\"pi pi-times\"\n type=\"button\"\n (click)=\"deleteProjectPicture(image.id)\"\n class=\"ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only\">\n <span class=\"ui-button-icon-left ui-clickable pi pi-times\"></span>\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.close()\">\n Cancel\n </button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n [buttonBusy]=\"busy\"\n (click)=\"onSave(form)\">\n Save\n </button>\n </div>\n</ng-template>\n", styles: [".drag-drop-text{padding:20px;border:2px dashed #ccc;text-align:center;color:#aaa;margin-top:10px}\n"], dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { kind: "directive", type: i5$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i7.FileUpload, selector: "p-fileupload, p-fileUpload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "uploadStyleClass", "cancelStyleClass", "removeStyleClass", "chooseStyleClass", "chooseButtonProps", "uploadButtonProps", "cancelButtonProps", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler", "onImageError", "onRemoveUploadedFile"] }] }); }
2460
2461
  }
2461
2462
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EditPortfoliosComponent, decorators: [{
2462
2463
  type: Component,
2463
- args: [{ selector: 'pw-edit-portfolios', standalone: false, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">Add/Edit Portfolio Item</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n Add a cover image or a downloadable file for your portfolio item\n <p-fileUpload #form\n name=\"myfile[]\"\n [customUpload]=\"true\"\n [showUploadButton]=\"false\"\n accept=\"\"\n [disabled]=\"uploadedFiles && uploadedFiles.length > 0\"\n (onSelect)=\"onSelect($event)\"\n (onRemove)=\"onRemove($event)\"\n (onError)=\"onUploadError($event)\">\n @if (uploadedFiles?.length) {\n <ng-template pTemplate=\"content\"\n >\n @if (!filesUploaded && (!uploadedFiles || uploadedFiles.length === 0)) {\n <div class=\"drag-drop-text\">\n <p>You can drag and drop your file here</p>\n </div>\n }\n </ng-template>\n }\n </p-fileUpload>\n <div class=\"ui-fileupload-content ui-widget-content ui-corner-bottom\">\n <div class=\"ui-fileupload-files\">\n <div class=\"\">\n <h5>Uploaded Pictures</h5>\n @for (image of projectPictures; track trackByImage($index, image)) {\n <div\n class=\"ui-fileupload-row d-inline-block\">\n <div>\n <img [src]=\"image?.picture?.version_50x50?.url\"\n alt=\"\"\n width=\"50\" />\n </div>\n <div class=\"pt-1 ps-1\">\n <button icon=\"pi pi-times\"\n type=\"button\"\n (click)=\"deleteProjectPicture(image.id)\"\n class=\"ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only\">\n <span class=\"ui-button-icon-left ui-clickable pi pi-times\"></span>\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.close()\">\n Cancel\n </button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n [buttonBusy]=\"busy\"\n (click)=\"onSave(form)\">\n Save\n </button>\n </div>\n</ng-template>\n", styles: [".drag-drop-text{padding:20px;border:2px dashed #ccc;text-align:center;color:#aaa;margin-top:10px}\n"] }]
2464
+ args: [{ selector: 'pw-edit-portfolios', standalone: false, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">Add/Edit Portfolio Item</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n Add a cover image or a downloadable file for your portfolio item\n <p-fileUpload #form\n name=\"myfile[]\"\n [customUpload]=\"true\"\n [showUploadButton]=\"false\"\n accept=\"\"\n [disabled]=\"uploadedFiles && uploadedFiles.length > 0\"\n (onSelect)=\"onSelect($event)\"\n (onRemove)=\"onRemove($event)\"\n (onError)=\"onUploadError($event)\">\n <ng-template pTemplate=\"content\">\n @if (!uploadedFiles?.length) {\n <div class=\"drag-drop-text\">\n <p>You can drag and drop your file here</p>\n </div>\n }\n </ng-template>\n </p-fileUpload>\n <div class=\"ui-fileupload-content ui-widget-content ui-corner-bottom\">\n <div class=\"ui-fileupload-files\">\n <div class=\"\">\n <h5>Uploaded Pictures</h5>\n @for (image of projectPictures; track trackByImage($index, image)) {\n <div\n class=\"ui-fileupload-row d-inline-block\">\n <div>\n <img [src]=\"image?.picture?.version_50x50?.url\"\n alt=\"\"\n width=\"50\" />\n </div>\n <div class=\"pt-1 ps-1\">\n <button icon=\"pi pi-times\"\n type=\"button\"\n (click)=\"deleteProjectPicture(image.id)\"\n class=\"ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only\">\n <span class=\"ui-button-icon-left ui-clickable pi pi-times\"></span>\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.close()\">\n Cancel\n </button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n [buttonBusy]=\"busy\"\n (click)=\"onSave(form)\">\n Save\n </button>\n </div>\n</ng-template>\n", styles: [".drag-drop-text{padding:20px;border:2px dashed #ccc;text-align:center;color:#aaa;margin-top:10px}\n"] }]
2464
2465
  }], ctorParameters: () => [{ type: i1$1.NgbModal }, { type: i1$2.ProfileService }, { type: i0.ChangeDetectorRef }], propDecorators: { content: [{
2465
2466
  type: ViewChild,
2466
2467
  args: ['content', { static: true }]
@@ -2594,7 +2595,7 @@ class EditProjectModalComponent extends AppBaseComponent {
2594
2595
  });
2595
2596
  }
2596
2597
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EditProjectModalComponent, deps: [{ token: i1$1.NgbModal }, { token: i2.UntypedFormBuilder }, { token: i1$2.ProfileService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
2597
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: EditProjectModalComponent, isStandalone: false, selector: "pw-edit-project-modal", outputs: { cancelEvent: "cancelEvent", saveEvent: "saveEvent" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">{{ title }}</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <form [formGroup]=\"form\">\n <div class=\"row p-2\">\n <!-- Title -->\n <pw-input-container class=\"col-12\"\n controlId=\"edit-project-title\"\n label=\"Title\"\n name=\"title\"\n errorMsg=\"This field is required.\">\n <input type=\"text\"\n id=\"edit-project-title\"\n class=\"form-control\"\n formControlName=\"title\"\n [ngClass]=\"{ 'is-invalid': submitted && f.title.errors }\" />\n </pw-input-container>\n <!-- Client Name -->\n <pw-input-container class=\"col-12\"\n controlId=\"edit-project-client_name\"\n label=\"Client Name\"\n name=\"client_name\"\n errorMsg=\"This field is required.\">\n <input type=\"text\"\n id=\"edit-project-client_name\"\n class=\"form-control\"\n formControlName=\"client_name\"\n [ngClass]=\"{ 'is-invalid': submitted && f.client_name.errors }\" />\n </pw-input-container>\n <!-- Project Start Year -->\n <pw-input-container class=\"col-4\"\n controlId=\"edit-project-start_year\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Start\"\n name=\"start_year\"\n errorMsg=\"YYYY format date is required\">\n <p-select\n [attr.aria-labelledby]=\"'edit-project-start_year-label'\"\n (onShow)=\"getStartYear()\"\n formControlName=\"start_year\"\n [options]=\"startYears\"\n [placeholder]=\"'Select Start Year'\"\n (onChange)=\"getEndYears($event.value)\"\n [ngClass]=\"{ 'is-invalid': submitted && f.start_year.errors }\">\n </p-select>\n </pw-input-container>\n <!-- Project End Year -->\n <pw-input-container class=\"col-4\"\n controlId=\"edit-project-end_year\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"End\"\n name=\"end_year\"\n errorMsg=\"YYYY format date is required\">\n <p-select\n [attr.aria-labelledby]=\"'edit-project-end_year-label'\"\n formControlName=\"end_year\"\n [options]=\"endYears\"\n [placeholder]=\"'Select End Year'\"\n (onChange)=\"getEndYears($event.value)\"\n [ngClass]=\"{ 'is-invalid': submitted && f.end_year.errors }\">\n </p-select>\n </pw-input-container>\n <!-- Total Weeks Worked -->\n <pw-input-container class=\"col-4\"\n controlId=\"edit-project-length\"\n label=\"Weeks worked\"\n name=\"length\"\n errorMsg=\"This field is required. (0-5000)\">\n <input type=\"number\"\n id=\"edit-project-length\"\n formControlName=\"length\"\n class=\"form-control\"\n placeholder=\"weeks\"\n [ngClass]=\"{ 'is-invalid': submitted && f.length.errors }\" />\n </pw-input-container>\n <!-- Description -->\n <pw-input-container class=\"col-12\"\n controlId=\"edit-project-description\"\n label=\"Description\"\n name=\"description\"\n errorMsg=\"This field is required.\">\n <textarea type=\"text\"\n id=\"edit-project-description\"\n class=\"form-control\"\n formControlName=\"description\"\n required\n [ngClass]=\"{ 'is-invalid': submitted && f.description.errors }\"></textarea>\n </pw-input-container>\n </div>\n </form>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.close()\">\n Cancel\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\"\n (click)=\"onSaveDetail()\">Save</button>\n </div>\n</ng-template>\n", styles: [".ng-valid.is-invalid{background-image:none;border-color:inherit}\n"], dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { 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.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { 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: i6$2.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i5.InputContainerComponent, selector: "pw-input-container", inputs: ["name", "controlId", "useAriaLabelledbyOnly", "label", "labelClass", "tooltipPosition", "required", "errorMsg", "isReadOnly", "showTooltip", "tooltipText", "showTriangle", "afterLabel", "showAfterLabel", "showTriangleText", "isLeftTooltip"] }] }); }
2598
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: EditProjectModalComponent, isStandalone: false, selector: "pw-edit-project-modal", outputs: { cancelEvent: "cancelEvent", saveEvent: "saveEvent" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">{{ title }}</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <form [formGroup]=\"form\">\n <div class=\"row p-2\">\n <!-- Title -->\n <pw-input-container class=\"col-12\"\n controlId=\"edit-project-title\"\n label=\"Title\"\n name=\"title\"\n errorMsg=\"This field is required.\">\n <input type=\"text\"\n id=\"edit-project-title\"\n class=\"form-control\"\n formControlName=\"title\"\n [placeholder]=\"'User.Profile.Projects.Placeholder.Title' | transloco\"\n [ngClass]=\"{ 'is-invalid': submitted && f.title.errors }\" />\n </pw-input-container>\n <!-- Client Name -->\n <pw-input-container class=\"col-12\"\n controlId=\"edit-project-client_name\"\n label=\"Client Name\"\n name=\"client_name\"\n errorMsg=\"This field is required.\">\n <input type=\"text\"\n id=\"edit-project-client_name\"\n class=\"form-control\"\n formControlName=\"client_name\"\n [placeholder]=\"'User.Profile.Projects.Placeholder.ClientName' | transloco\"\n [ngClass]=\"{ 'is-invalid': submitted && f.client_name.errors }\" />\n </pw-input-container>\n <!-- Project Start Year -->\n <pw-input-container class=\"col-12 col-md-4\"\n controlId=\"edit-project-start_year\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Start\"\n name=\"start_year\"\n errorMsg=\"YYYY format date is required\">\n <p-select\n [attr.aria-labelledby]=\"'edit-project-start_year-label'\"\n (onShow)=\"getStartYear()\"\n formControlName=\"start_year\"\n [options]=\"startYears\"\n [placeholder]=\"'User.Profile.Projects.Placeholder.StartYear' | transloco\"\n (onChange)=\"getEndYears($event.value)\"\n [ngClass]=\"{ 'is-invalid': submitted && f.start_year.errors }\">\n </p-select>\n </pw-input-container>\n <!-- Project End Year -->\n <pw-input-container class=\"col-12 col-md-4\"\n controlId=\"edit-project-end_year\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"End\"\n name=\"end_year\"\n errorMsg=\"YYYY format date is required\">\n <p-select\n [attr.aria-labelledby]=\"'edit-project-end_year-label'\"\n formControlName=\"end_year\"\n [options]=\"endYears\"\n [placeholder]=\"'User.Profile.Projects.Placeholder.EndYear' | transloco\"\n (onChange)=\"getEndYears($event.value)\"\n [ngClass]=\"{ 'is-invalid': submitted && f.end_year.errors }\">\n </p-select>\n </pw-input-container>\n <!-- Total Weeks Worked -->\n <pw-input-container class=\"col-12 col-md-4\"\n controlId=\"edit-project-length\"\n label=\"Weeks worked\"\n name=\"length\"\n errorMsg=\"This field is required. (0-5000)\">\n <input type=\"number\"\n id=\"edit-project-length\"\n formControlName=\"length\"\n class=\"form-control\"\n [ngClass]=\"{ 'is-invalid': submitted && f.length.errors }\" />\n </pw-input-container>\n <!-- Description -->\n <pw-input-container class=\"col-12\"\n controlId=\"edit-project-description\"\n label=\"Description\"\n name=\"description\"\n errorMsg=\"This field is required.\">\n <textarea type=\"text\"\n id=\"edit-project-description\"\n class=\"form-control\"\n formControlName=\"description\"\n required\n [placeholder]=\"'User.Profile.Projects.Placeholder.Description' | transloco\"\n [ngClass]=\"{ 'is-invalid': submitted && f.description.errors }\"></textarea>\n </pw-input-container>\n </div>\n </form>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.close()\">\n Cancel\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\"\n (click)=\"onSaveDetail()\">Save</button>\n </div>\n</ng-template>\n", styles: [".ng-valid.is-invalid{background-image:none;border-color:inherit}\n"], dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { 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.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { 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: i6$2.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i5.InputContainerComponent, selector: "pw-input-container", inputs: ["name", "controlId", "useAriaLabelledbyOnly", "label", "labelClass", "tooltipPosition", "required", "errorMsg", "isReadOnly", "showTooltip", "tooltipText", "showTriangle", "afterLabel", "showAfterLabel", "showTriangleText", "isLeftTooltip"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
2598
2599
  }
2599
2600
  __decorate([
2600
2601
  ValidateForm('form'),
@@ -2604,7 +2605,7 @@ __decorate([
2604
2605
  ], EditProjectModalComponent.prototype, "onSaveDetail", null);
2605
2606
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EditProjectModalComponent, decorators: [{
2606
2607
  type: Component,
2607
- args: [{ selector: 'pw-edit-project-modal', standalone: false, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">{{ title }}</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <form [formGroup]=\"form\">\n <div class=\"row p-2\">\n <!-- Title -->\n <pw-input-container class=\"col-12\"\n controlId=\"edit-project-title\"\n label=\"Title\"\n name=\"title\"\n errorMsg=\"This field is required.\">\n <input type=\"text\"\n id=\"edit-project-title\"\n class=\"form-control\"\n formControlName=\"title\"\n [ngClass]=\"{ 'is-invalid': submitted && f.title.errors }\" />\n </pw-input-container>\n <!-- Client Name -->\n <pw-input-container class=\"col-12\"\n controlId=\"edit-project-client_name\"\n label=\"Client Name\"\n name=\"client_name\"\n errorMsg=\"This field is required.\">\n <input type=\"text\"\n id=\"edit-project-client_name\"\n class=\"form-control\"\n formControlName=\"client_name\"\n [ngClass]=\"{ 'is-invalid': submitted && f.client_name.errors }\" />\n </pw-input-container>\n <!-- Project Start Year -->\n <pw-input-container class=\"col-4\"\n controlId=\"edit-project-start_year\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Start\"\n name=\"start_year\"\n errorMsg=\"YYYY format date is required\">\n <p-select\n [attr.aria-labelledby]=\"'edit-project-start_year-label'\"\n (onShow)=\"getStartYear()\"\n formControlName=\"start_year\"\n [options]=\"startYears\"\n [placeholder]=\"'Select Start Year'\"\n (onChange)=\"getEndYears($event.value)\"\n [ngClass]=\"{ 'is-invalid': submitted && f.start_year.errors }\">\n </p-select>\n </pw-input-container>\n <!-- Project End Year -->\n <pw-input-container class=\"col-4\"\n controlId=\"edit-project-end_year\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"End\"\n name=\"end_year\"\n errorMsg=\"YYYY format date is required\">\n <p-select\n [attr.aria-labelledby]=\"'edit-project-end_year-label'\"\n formControlName=\"end_year\"\n [options]=\"endYears\"\n [placeholder]=\"'Select End Year'\"\n (onChange)=\"getEndYears($event.value)\"\n [ngClass]=\"{ 'is-invalid': submitted && f.end_year.errors }\">\n </p-select>\n </pw-input-container>\n <!-- Total Weeks Worked -->\n <pw-input-container class=\"col-4\"\n controlId=\"edit-project-length\"\n label=\"Weeks worked\"\n name=\"length\"\n errorMsg=\"This field is required. (0-5000)\">\n <input type=\"number\"\n id=\"edit-project-length\"\n formControlName=\"length\"\n class=\"form-control\"\n placeholder=\"weeks\"\n [ngClass]=\"{ 'is-invalid': submitted && f.length.errors }\" />\n </pw-input-container>\n <!-- Description -->\n <pw-input-container class=\"col-12\"\n controlId=\"edit-project-description\"\n label=\"Description\"\n name=\"description\"\n errorMsg=\"This field is required.\">\n <textarea type=\"text\"\n id=\"edit-project-description\"\n class=\"form-control\"\n formControlName=\"description\"\n required\n [ngClass]=\"{ 'is-invalid': submitted && f.description.errors }\"></textarea>\n </pw-input-container>\n </div>\n </form>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.close()\">\n Cancel\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\"\n (click)=\"onSaveDetail()\">Save</button>\n </div>\n</ng-template>\n", styles: [".ng-valid.is-invalid{background-image:none;border-color:inherit}\n"] }]
2608
+ args: [{ selector: 'pw-edit-project-modal', standalone: false, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">{{ title }}</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <form [formGroup]=\"form\">\n <div class=\"row p-2\">\n <!-- Title -->\n <pw-input-container class=\"col-12\"\n controlId=\"edit-project-title\"\n label=\"Title\"\n name=\"title\"\n errorMsg=\"This field is required.\">\n <input type=\"text\"\n id=\"edit-project-title\"\n class=\"form-control\"\n formControlName=\"title\"\n [placeholder]=\"'User.Profile.Projects.Placeholder.Title' | transloco\"\n [ngClass]=\"{ 'is-invalid': submitted && f.title.errors }\" />\n </pw-input-container>\n <!-- Client Name -->\n <pw-input-container class=\"col-12\"\n controlId=\"edit-project-client_name\"\n label=\"Client Name\"\n name=\"client_name\"\n errorMsg=\"This field is required.\">\n <input type=\"text\"\n id=\"edit-project-client_name\"\n class=\"form-control\"\n formControlName=\"client_name\"\n [placeholder]=\"'User.Profile.Projects.Placeholder.ClientName' | transloco\"\n [ngClass]=\"{ 'is-invalid': submitted && f.client_name.errors }\" />\n </pw-input-container>\n <!-- Project Start Year -->\n <pw-input-container class=\"col-12 col-md-4\"\n controlId=\"edit-project-start_year\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Start\"\n name=\"start_year\"\n errorMsg=\"YYYY format date is required\">\n <p-select\n [attr.aria-labelledby]=\"'edit-project-start_year-label'\"\n (onShow)=\"getStartYear()\"\n formControlName=\"start_year\"\n [options]=\"startYears\"\n [placeholder]=\"'User.Profile.Projects.Placeholder.StartYear' | transloco\"\n (onChange)=\"getEndYears($event.value)\"\n [ngClass]=\"{ 'is-invalid': submitted && f.start_year.errors }\">\n </p-select>\n </pw-input-container>\n <!-- Project End Year -->\n <pw-input-container class=\"col-12 col-md-4\"\n controlId=\"edit-project-end_year\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"End\"\n name=\"end_year\"\n errorMsg=\"YYYY format date is required\">\n <p-select\n [attr.aria-labelledby]=\"'edit-project-end_year-label'\"\n formControlName=\"end_year\"\n [options]=\"endYears\"\n [placeholder]=\"'User.Profile.Projects.Placeholder.EndYear' | transloco\"\n (onChange)=\"getEndYears($event.value)\"\n [ngClass]=\"{ 'is-invalid': submitted && f.end_year.errors }\">\n </p-select>\n </pw-input-container>\n <!-- Total Weeks Worked -->\n <pw-input-container class=\"col-12 col-md-4\"\n controlId=\"edit-project-length\"\n label=\"Weeks worked\"\n name=\"length\"\n errorMsg=\"This field is required. (0-5000)\">\n <input type=\"number\"\n id=\"edit-project-length\"\n formControlName=\"length\"\n class=\"form-control\"\n [ngClass]=\"{ 'is-invalid': submitted && f.length.errors }\" />\n </pw-input-container>\n <!-- Description -->\n <pw-input-container class=\"col-12\"\n controlId=\"edit-project-description\"\n label=\"Description\"\n name=\"description\"\n errorMsg=\"This field is required.\">\n <textarea type=\"text\"\n id=\"edit-project-description\"\n class=\"form-control\"\n formControlName=\"description\"\n required\n [placeholder]=\"'User.Profile.Projects.Placeholder.Description' | transloco\"\n [ngClass]=\"{ 'is-invalid': submitted && f.description.errors }\"></textarea>\n </pw-input-container>\n </div>\n </form>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.close()\">\n Cancel\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\"\n (click)=\"onSaveDetail()\">Save</button>\n </div>\n</ng-template>\n", styles: [".ng-valid.is-invalid{background-image:none;border-color:inherit}\n"] }]
2608
2609
  }], ctorParameters: () => [{ type: i1$1.NgbModal }, { type: i2.UntypedFormBuilder }, { type: i1$2.ProfileService }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }], propDecorators: { content: [{
2609
2610
  type: ViewChild,
2610
2611
  args: ['content', { static: true }]
@@ -2702,7 +2703,7 @@ class EditQualificationsModalComponent extends AppBaseComponent {
2702
2703
  });
2703
2704
  }
2704
2705
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EditQualificationsModalComponent, deps: [{ token: i1$1.NgbModal }, { token: i2.UntypedFormBuilder }, { token: i1$2.QualificationService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
2705
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: EditQualificationsModalComponent, isStandalone: false, selector: "pw-edit-qualifications-modal", outputs: { saveEvent: "saveEvent" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">{{ title }}</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <form [formGroup]=\"form\">\n <div class=\"row p-2\">\n <pw-input-container class=\"col-12\"\n controlId=\"edit-qualifications-school\"\n label=\"School\"\n name=\"school\"\n errorMsg=\"This field is required.\">\n <input type=\"text\"\n id=\"edit-qualifications-school\"\n class=\"form-control\"\n formControlName=\"school\" />\n </pw-input-container>\n\n <pw-input-container class=\"col-6\"\n controlId=\"edit-qualifications-started_on\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Dates Attended\"\n name=\"started_on\"\n errorMsg=\"This field is required.\">\n <div class=\"ui-fluid\">\n <p-datepicker inputId=\"edit-qualifications-started_on\" formControlName=\"started_on\"\n [attr.aria-labelledby]=\"'edit-qualifications-started_on-label'\"\n [monthNavigator]=\"true\"\n [yearNavigator]=\"true\"\n yearRange=\"1950:2020\"\n (onSelect)=\"onDateChange()\"\n [showIcon]=\"true\"\n dateFormat=\"yy-mm-dd\">\n </p-datepicker>\n </div>\n </pw-input-container>\n\n <pw-input-container class=\"col-6\"\n controlId=\"edit-qualifications-ended_on\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Dates Completed\"\n name=\"ended_on\"\n errorMsg=\"This field is required.\">\n <div class=\"ui-fluid\">\n <p-datepicker inputId=\"edit-qualifications-ended_on\" formControlName=\"ended_on\"\n [attr.aria-labelledby]=\"'edit-qualifications-ended_on-label'\"\n [monthNavigator]=\"true\"\n [yearNavigator]=\"true\"\n [showIcon]=\"true\"\n (onSelect)=\"onDateChange()\"\n [minDate]=\"minToDate\"\n dateFormat=\"yy-mm-dd\"\n yearRange=\"1950:2025\"></p-datepicker>\n </div>\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-qualifications-points\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Degree\"\n name=\"points\"\n errorMsg=\"This field is required.\">\n <p-select inputId=\"edit-qualifications-points\"\n [options]=\"qualifications\"\n [attr.aria-labelledby]=\"'edit-qualifications-points-label'\"\n placeholder=\"Select\"\n formControlName=\"points\"></p-select>\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-qualifications-course\"\n label=\"Course\"\n name=\"course\"\n errorMsg=\"This field is required.\">\n <input type=\"text\"\n id=\"edit-qualifications-course\"\n class=\"form-control\"\n formControlName=\"course\" />\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-qualifications-description\"\n label=\"Description\"\n name=\"description\">\n <textarea type=\"text\"\n id=\"edit-qualifications-description\"\n class=\"form-control\"\n formControlName=\"description\"></textarea>\n </pw-input-container>\n </div>\n </form>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.close()\">\n Cancel\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\"\n (click)=\"onSaveDetail()\">Save</button>\n </div>\n</ng-template>\n\n<i\n class=\"fa fa-lg pi pi-plus-circle float-end mt-2 pt-1 pt-md-0 profile-icons\"\n data-cy=\"add-qualification\"\n (keydown.enter)=\"onOpen()\"\n aria-label=\"Add Qualification\"\n (click)=\"onOpen()\"\n aria-hidden=\"true\"\n></i>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.btn-add{cursor:pointer;font-size:24px}.profile-icons{color:var(--first)}\n"], dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { 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: i6$2.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i5.InputContainerComponent, selector: "pw-input-container", inputs: ["name", "controlId", "useAriaLabelledbyOnly", "label", "labelClass", "tooltipPosition", "required", "errorMsg", "isReadOnly", "showTooltip", "tooltipText", "showTriangle", "afterLabel", "showAfterLabel", "showTriangleText", "isLeftTooltip"] }, { kind: "component", type: i7$1.DatePicker, selector: "p-datePicker, p-datepicker, p-date-picker", inputs: ["iconDisplay", "styleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "readonlyInput", "shortYearCutoff", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "minDate", "maxDate", "disabledDates", "disabledDays", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "view", "defaultDate", "appendTo", "motionOptions"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }] }); }
2706
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: EditQualificationsModalComponent, isStandalone: false, selector: "pw-edit-qualifications-modal", outputs: { saveEvent: "saveEvent" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">{{ title }}</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <form [formGroup]=\"form\">\n <div class=\"row p-2\">\n <pw-input-container class=\"col-12\"\n controlId=\"edit-qualifications-school\"\n label=\"School\"\n name=\"school\"\n errorMsg=\"This field is required.\">\n <input type=\"text\"\n id=\"edit-qualifications-school\"\n class=\"form-control\"\n [placeholder]=\"'User.Profile.Qualifications.Placeholder.School' | transloco\"\n formControlName=\"school\" />\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-qualifications-started_on\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Dates Attended\"\n name=\"started_on\"\n errorMsg=\"This field is required.\">\n <div class=\"ui-fluid\">\n <p-datepicker inputId=\"edit-qualifications-started_on\" formControlName=\"started_on\"\n [attr.aria-labelledby]=\"'edit-qualifications-started_on-label'\"\n [monthNavigator]=\"true\"\n [yearNavigator]=\"true\"\n yearRange=\"1950:2020\"\n (onSelect)=\"onDateChange()\"\n [showIcon]=\"true\"\n placeholder=\"yyyy-mm-dd\"\n dateFormat=\"yy-mm-dd\">\n </p-datepicker>\n </div>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-qualifications-ended_on\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Dates Completed\"\n name=\"ended_on\"\n errorMsg=\"This field is required.\">\n <div class=\"ui-fluid\">\n <p-datepicker inputId=\"edit-qualifications-ended_on\" formControlName=\"ended_on\"\n [attr.aria-labelledby]=\"'edit-qualifications-ended_on-label'\"\n [monthNavigator]=\"true\"\n [yearNavigator]=\"true\"\n [showIcon]=\"true\"\n (onSelect)=\"onDateChange()\"\n [minDate]=\"minToDate\"\n placeholder=\"yyyy-mm-dd\"\n dateFormat=\"yy-mm-dd\"\n yearRange=\"1950:2025\"></p-datepicker>\n </div>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-qualifications-points\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Degree\"\n name=\"points\"\n errorMsg=\"This field is required.\">\n <p-select inputId=\"edit-qualifications-points\"\n [options]=\"qualifications\"\n [attr.aria-labelledby]=\"'edit-qualifications-points-label'\"\n [placeholder]=\"'User.Profile.Qualifications.Placeholder.Degree' | transloco\"\n formControlName=\"points\"></p-select>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-qualifications-course\"\n label=\"Course\"\n name=\"course\"\n errorMsg=\"This field is required.\">\n <input type=\"text\"\n id=\"edit-qualifications-course\"\n class=\"form-control\"\n [placeholder]=\"'User.Profile.Qualifications.Placeholder.Course' | transloco\"\n formControlName=\"course\" />\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-qualifications-description\"\n label=\"Description\"\n name=\"description\">\n <textarea type=\"text\"\n id=\"edit-qualifications-description\"\n class=\"form-control\"\n [placeholder]=\"'User.Profile.Qualifications.Placeholder.Description' | transloco\"\n formControlName=\"description\"></textarea>\n </pw-input-container>\n </div>\n </form>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.close()\">\n Cancel\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\"\n (click)=\"onSaveDetail()\">Save</button>\n </div>\n</ng-template>\n\n<i\n class=\"fa fa-lg pi pi-plus-circle float-end mt-2 pt-1 pt-md-0 profile-icons\"\n data-cy=\"add-qualification\"\n (keydown.enter)=\"onOpen()\"\n aria-label=\"Add Qualification\"\n (click)=\"onOpen()\"\n aria-hidden=\"true\"\n></i>\n", styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.btn-add{cursor:pointer;font-size:24px}.profile-icons{color:var(--first)}\n"], dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { 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: i6$2.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i5.InputContainerComponent, selector: "pw-input-container", inputs: ["name", "controlId", "useAriaLabelledbyOnly", "label", "labelClass", "tooltipPosition", "required", "errorMsg", "isReadOnly", "showTooltip", "tooltipText", "showTriangle", "afterLabel", "showAfterLabel", "showTriangleText", "isLeftTooltip"] }, { kind: "component", type: i7$1.DatePicker, selector: "p-datePicker, p-datepicker, p-date-picker", inputs: ["iconDisplay", "styleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "readonlyInput", "shortYearCutoff", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "minDate", "maxDate", "disabledDates", "disabledDays", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "view", "defaultDate", "appendTo", "motionOptions"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
2706
2707
  }
2707
2708
  __decorate([
2708
2709
  ValidateForm('form'),
@@ -2712,7 +2713,7 @@ __decorate([
2712
2713
  ], EditQualificationsModalComponent.prototype, "onSaveDetail", null);
2713
2714
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EditQualificationsModalComponent, decorators: [{
2714
2715
  type: Component,
2715
- args: [{ selector: 'pw-edit-qualifications-modal', standalone: false, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">{{ title }}</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <form [formGroup]=\"form\">\n <div class=\"row p-2\">\n <pw-input-container class=\"col-12\"\n controlId=\"edit-qualifications-school\"\n label=\"School\"\n name=\"school\"\n errorMsg=\"This field is required.\">\n <input type=\"text\"\n id=\"edit-qualifications-school\"\n class=\"form-control\"\n formControlName=\"school\" />\n </pw-input-container>\n\n <pw-input-container class=\"col-6\"\n controlId=\"edit-qualifications-started_on\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Dates Attended\"\n name=\"started_on\"\n errorMsg=\"This field is required.\">\n <div class=\"ui-fluid\">\n <p-datepicker inputId=\"edit-qualifications-started_on\" formControlName=\"started_on\"\n [attr.aria-labelledby]=\"'edit-qualifications-started_on-label'\"\n [monthNavigator]=\"true\"\n [yearNavigator]=\"true\"\n yearRange=\"1950:2020\"\n (onSelect)=\"onDateChange()\"\n [showIcon]=\"true\"\n dateFormat=\"yy-mm-dd\">\n </p-datepicker>\n </div>\n </pw-input-container>\n\n <pw-input-container class=\"col-6\"\n controlId=\"edit-qualifications-ended_on\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Dates Completed\"\n name=\"ended_on\"\n errorMsg=\"This field is required.\">\n <div class=\"ui-fluid\">\n <p-datepicker inputId=\"edit-qualifications-ended_on\" formControlName=\"ended_on\"\n [attr.aria-labelledby]=\"'edit-qualifications-ended_on-label'\"\n [monthNavigator]=\"true\"\n [yearNavigator]=\"true\"\n [showIcon]=\"true\"\n (onSelect)=\"onDateChange()\"\n [minDate]=\"minToDate\"\n dateFormat=\"yy-mm-dd\"\n yearRange=\"1950:2025\"></p-datepicker>\n </div>\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-qualifications-points\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Degree\"\n name=\"points\"\n errorMsg=\"This field is required.\">\n <p-select inputId=\"edit-qualifications-points\"\n [options]=\"qualifications\"\n [attr.aria-labelledby]=\"'edit-qualifications-points-label'\"\n placeholder=\"Select\"\n formControlName=\"points\"></p-select>\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-qualifications-course\"\n label=\"Course\"\n name=\"course\"\n errorMsg=\"This field is required.\">\n <input type=\"text\"\n id=\"edit-qualifications-course\"\n class=\"form-control\"\n formControlName=\"course\" />\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-qualifications-description\"\n label=\"Description\"\n name=\"description\">\n <textarea type=\"text\"\n id=\"edit-qualifications-description\"\n class=\"form-control\"\n formControlName=\"description\"></textarea>\n </pw-input-container>\n </div>\n </form>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.close()\">\n Cancel\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\"\n (click)=\"onSaveDetail()\">Save</button>\n </div>\n</ng-template>\n\n<i\n class=\"fa fa-lg pi pi-plus-circle float-end mt-2 pt-1 pt-md-0 profile-icons\"\n data-cy=\"add-qualification\"\n (keydown.enter)=\"onOpen()\"\n aria-label=\"Add Qualification\"\n (click)=\"onOpen()\"\n aria-hidden=\"true\"\n></i>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.btn-add{cursor:pointer;font-size:24px}.profile-icons{color:var(--first)}\n"] }]
2716
+ args: [{ selector: 'pw-edit-qualifications-modal', standalone: false, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">{{ title }}</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <form [formGroup]=\"form\">\n <div class=\"row p-2\">\n <pw-input-container class=\"col-12\"\n controlId=\"edit-qualifications-school\"\n label=\"School\"\n name=\"school\"\n errorMsg=\"This field is required.\">\n <input type=\"text\"\n id=\"edit-qualifications-school\"\n class=\"form-control\"\n [placeholder]=\"'User.Profile.Qualifications.Placeholder.School' | transloco\"\n formControlName=\"school\" />\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-qualifications-started_on\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Dates Attended\"\n name=\"started_on\"\n errorMsg=\"This field is required.\">\n <div class=\"ui-fluid\">\n <p-datepicker inputId=\"edit-qualifications-started_on\" formControlName=\"started_on\"\n [attr.aria-labelledby]=\"'edit-qualifications-started_on-label'\"\n [monthNavigator]=\"true\"\n [yearNavigator]=\"true\"\n yearRange=\"1950:2020\"\n (onSelect)=\"onDateChange()\"\n [showIcon]=\"true\"\n placeholder=\"yyyy-mm-dd\"\n dateFormat=\"yy-mm-dd\">\n </p-datepicker>\n </div>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-qualifications-ended_on\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Dates Completed\"\n name=\"ended_on\"\n errorMsg=\"This field is required.\">\n <div class=\"ui-fluid\">\n <p-datepicker inputId=\"edit-qualifications-ended_on\" formControlName=\"ended_on\"\n [attr.aria-labelledby]=\"'edit-qualifications-ended_on-label'\"\n [monthNavigator]=\"true\"\n [yearNavigator]=\"true\"\n [showIcon]=\"true\"\n (onSelect)=\"onDateChange()\"\n [minDate]=\"minToDate\"\n placeholder=\"yyyy-mm-dd\"\n dateFormat=\"yy-mm-dd\"\n yearRange=\"1950:2025\"></p-datepicker>\n </div>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-qualifications-points\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Degree\"\n name=\"points\"\n errorMsg=\"This field is required.\">\n <p-select inputId=\"edit-qualifications-points\"\n [options]=\"qualifications\"\n [attr.aria-labelledby]=\"'edit-qualifications-points-label'\"\n [placeholder]=\"'User.Profile.Qualifications.Placeholder.Degree' | transloco\"\n formControlName=\"points\"></p-select>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-qualifications-course\"\n label=\"Course\"\n name=\"course\"\n errorMsg=\"This field is required.\">\n <input type=\"text\"\n id=\"edit-qualifications-course\"\n class=\"form-control\"\n [placeholder]=\"'User.Profile.Qualifications.Placeholder.Course' | transloco\"\n formControlName=\"course\" />\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-qualifications-description\"\n label=\"Description\"\n name=\"description\">\n <textarea type=\"text\"\n id=\"edit-qualifications-description\"\n class=\"form-control\"\n [placeholder]=\"'User.Profile.Qualifications.Placeholder.Description' | transloco\"\n formControlName=\"description\"></textarea>\n </pw-input-container>\n </div>\n </form>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.close()\">\n Cancel\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\"\n (click)=\"onSaveDetail()\">Save</button>\n </div>\n</ng-template>\n\n<i\n class=\"fa fa-lg pi pi-plus-circle float-end mt-2 pt-1 pt-md-0 profile-icons\"\n data-cy=\"add-qualification\"\n (keydown.enter)=\"onOpen()\"\n aria-label=\"Add Qualification\"\n (click)=\"onOpen()\"\n aria-hidden=\"true\"\n></i>\n", styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.btn-add{cursor:pointer;font-size:24px}.profile-icons{color:var(--first)}\n"] }]
2716
2717
  }], ctorParameters: () => [{ type: i1$1.NgbModal }, { type: i2.UntypedFormBuilder }, { type: i1$2.QualificationService }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }], propDecorators: { saveEvent: [{
2717
2718
  type: Output
2718
2719
  }], content: [{
@@ -2770,7 +2771,7 @@ class EditRecommendationModalComponent {
2770
2771
  });
2771
2772
  }
2772
2773
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EditRecommendationModalComponent, deps: [{ token: i1$1.NgbModal }, { token: i2.UntypedFormBuilder }, { token: i1$2.ProfileService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
2773
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: EditRecommendationModalComponent, isStandalone: false, selector: "pw-edit-recommendation-modal", inputs: { user: "user" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], ngImport: i0, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">{{ title }}</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <form [formGroup]=\"form\">\n <div class=\"row p-2\">\n <pw-input-container class=\"col-12 col-md-4\"\n controlId=\"edit-recommendation-quality\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Quality\"\n name=\"quality\"\n errorMsg=\"This field is required.\">\n <p-rating formControlName=\"quality\"\n [attr.aria-labelledby]=\"'edit-recommendation-quality-label'\"\n [cancel]=\"false\"></p-rating>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-4\"\n controlId=\"edit-recommendation-communication\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Communication\"\n name=\"communication\"\n errorMsg=\"This field is required.\">\n <p-rating formControlName=\"communication\"\n [attr.aria-labelledby]=\"'edit-recommendation-communication-label'\"\n [cancel]=\"false\"></p-rating>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-4\"\n controlId=\"edit-recommendation-time\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Time\"\n name=\"time\"\n errorMsg=\"This field is required.\">\n <p-rating formControlName=\"time\"\n [attr.aria-labelledby]=\"'edit-recommendation-time-label'\"\n [cancel]=\"false\"></p-rating>\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-recommendation-description\"\n label=\"Description\"\n name=\"description\"\n errorMsg=\"This field is required.\">\n <textarea type=\"text\"\n id=\"edit-recommendation-description\"\n class=\"form-control\"\n formControlName=\"description\"></textarea>\n </pw-input-container>\n </div>\n </form>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.close()\">\n Cancel\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\"\n (click)=\"onSaveDetail()\">Save</button>\n </div>\n</ng-template>\n\n<!-- <i class=\"fal fa-plus-circle fa-2x btn-link float-end btn-add\" (click)=\"onOpen()\" aria-hidden=\"true\"></i> -->\n", dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { 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: i5.InputContainerComponent, selector: "pw-input-container", inputs: ["name", "controlId", "useAriaLabelledbyOnly", "label", "labelClass", "tooltipPosition", "required", "errorMsg", "isReadOnly", "showTooltip", "tooltipText", "showTriangle", "afterLabel", "showAfterLabel", "showTriangleText", "isLeftTooltip"] }, { kind: "component", type: i6$6.Rating, selector: "p-rating", inputs: ["readonly", "stars", "iconOnClass", "iconOnStyle", "iconOffClass", "iconOffStyle", "autofocus"], outputs: ["onRate", "onFocus", "onBlur"] }] }); }
2774
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: EditRecommendationModalComponent, isStandalone: false, selector: "pw-edit-recommendation-modal", inputs: { user: "user" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], ngImport: i0, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">{{ title }}</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <form [formGroup]=\"form\">\n <div class=\"row p-2\">\n <pw-input-container class=\"col-12 col-md-4\"\n controlId=\"edit-recommendation-quality\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Quality\"\n name=\"quality\"\n errorMsg=\"This field is required.\">\n <p-rating formControlName=\"quality\"\n [attr.aria-labelledby]=\"'edit-recommendation-quality-label'\"\n [cancel]=\"false\"></p-rating>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-4\"\n controlId=\"edit-recommendation-communication\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Communication\"\n name=\"communication\"\n errorMsg=\"This field is required.\">\n <p-rating formControlName=\"communication\"\n [attr.aria-labelledby]=\"'edit-recommendation-communication-label'\"\n [cancel]=\"false\"></p-rating>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-4\"\n controlId=\"edit-recommendation-time\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Time\"\n name=\"time\"\n errorMsg=\"This field is required.\">\n <p-rating formControlName=\"time\"\n [attr.aria-labelledby]=\"'edit-recommendation-time-label'\"\n [cancel]=\"false\"></p-rating>\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-recommendation-description\"\n label=\"Description\"\n name=\"description\"\n errorMsg=\"This field is required.\">\n <textarea type=\"text\"\n id=\"edit-recommendation-description\"\n class=\"form-control\"\n formControlName=\"description\"></textarea>\n </pw-input-container>\n </div>\n </form>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"modal.close()\">\n Cancel\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\"\n (click)=\"onSaveDetail()\">Save</button>\n </div>\n</ng-template>\n\n<!-- <i class=\"fal fa-plus-circle fa-2x btn-link float-end btn-add\" (click)=\"onOpen()\" aria-hidden=\"true\"></i> -->\n", dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { 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: i5.InputContainerComponent, selector: "pw-input-container", inputs: ["name", "controlId", "useAriaLabelledbyOnly", "label", "labelClass", "tooltipPosition", "required", "errorMsg", "isReadOnly", "showTooltip", "tooltipText", "showTriangle", "afterLabel", "showAfterLabel", "showTriangleText", "isLeftTooltip"] }, { kind: "component", type: i6$5.Rating, selector: "p-rating", inputs: ["readonly", "stars", "iconOnClass", "iconOnStyle", "iconOffClass", "iconOffStyle", "autofocus"], outputs: ["onRate", "onFocus", "onBlur"] }] }); }
2774
2775
  }
2775
2776
  __decorate([
2776
2777
  ValidateForm('form'),
@@ -2873,11 +2874,11 @@ class EditSkillsModalComponent extends AppBaseComponent {
2873
2874
  });
2874
2875
  }
2875
2876
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EditSkillsModalComponent, deps: [{ token: i1$1.NgbModal }, { token: i1$2.TagService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
2876
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: EditSkillsModalComponent, isStandalone: false, selector: "pw-edit-skills-modal", inputs: { userId: "userId", slug: "slug", entityType: "entityType", entityEntity: "entityEntity" }, outputs: { saveEvent: "saveEvent" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">My Skills</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <div class=\"ui-fluid skills-modal skills-dropdown\">\n <p-autoComplete [(ngModel)]=\"selectedSkills\"\n [suggestions]=\"searchSkills\"\n dataKey=\"id\"\n optionLabel=\"name\"\n (completeMethod)=\"search($event)\"\n styleClass=\"w-100\"\n [minLength]=\"1\"\n [maxlength]=\"10\"\n placeholder=\"Skills\"\n [dropdown]=\"true\"\n [multiple]=\"true\"></p-autoComplete>\n\n <small class=\"p-2\">Select up to 10 skills.</small>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"close(modal)\">Cancel</button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"saveUserSkills()\">Save</button>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "component", type: i4$4.AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "minQueryLength", "delay", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "addOnTab", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "addOnBlur", "separator", "appendTo", "motionOptions"], outputs: ["completeMethod", "onSelect", "onUnselect", "onAdd", "onFocus", "onBlur", "onDropdownClick", "onClear", "onInputKeydown", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
2877
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: EditSkillsModalComponent, isStandalone: false, selector: "pw-edit-skills-modal", inputs: { userId: "userId", slug: "slug", entityType: "entityType", entityEntity: "entityEntity" }, outputs: { saveEvent: "saveEvent" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">My Skills</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <div class=\"ui-fluid skills-modal skills-dropdown\">\n <p-autoComplete appendTo=\"body\" [(ngModel)]=\"selectedSkills\"\n [suggestions]=\"searchSkills\"\n dataKey=\"id\"\n optionLabel=\"name\"\n (completeMethod)=\"search($event)\"\n styleClass=\"w-100\"\n [minLength]=\"1\"\n [maxlength]=\"10\"\n placeholder=\"Skills\"\n [dropdown]=\"true\"\n [multiple]=\"true\"></p-autoComplete>\n\n <small class=\"p-2\">Select up to 10 skills.</small>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"close(modal)\">Cancel</button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"saveUserSkills()\">Save</button>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "component", type: i4$4.AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "minQueryLength", "delay", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "addOnTab", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "addOnBlur", "separator", "appendTo", "motionOptions"], outputs: ["completeMethod", "onSelect", "onUnselect", "onAdd", "onFocus", "onBlur", "onDropdownClick", "onClear", "onInputKeydown", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
2877
2878
  }
2878
2879
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EditSkillsModalComponent, decorators: [{
2879
2880
  type: Component,
2880
- args: [{ selector: 'pw-edit-skills-modal', standalone: false, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">My Skills</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <div class=\"ui-fluid skills-modal skills-dropdown\">\n <p-autoComplete [(ngModel)]=\"selectedSkills\"\n [suggestions]=\"searchSkills\"\n dataKey=\"id\"\n optionLabel=\"name\"\n (completeMethod)=\"search($event)\"\n styleClass=\"w-100\"\n [minLength]=\"1\"\n [maxlength]=\"10\"\n placeholder=\"Skills\"\n [dropdown]=\"true\"\n [multiple]=\"true\"></p-autoComplete>\n\n <small class=\"p-2\">Select up to 10 skills.</small>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"close(modal)\">Cancel</button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"saveUserSkills()\">Save</button>\n </div>\n</ng-template>\n" }]
2881
+ args: [{ selector: 'pw-edit-skills-modal', standalone: false, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">My Skills</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <div class=\"ui-fluid skills-modal skills-dropdown\">\n <p-autoComplete appendTo=\"body\" [(ngModel)]=\"selectedSkills\"\n [suggestions]=\"searchSkills\"\n dataKey=\"id\"\n optionLabel=\"name\"\n (completeMethod)=\"search($event)\"\n styleClass=\"w-100\"\n [minLength]=\"1\"\n [maxlength]=\"10\"\n placeholder=\"Skills\"\n [dropdown]=\"true\"\n [multiple]=\"true\"></p-autoComplete>\n\n <small class=\"p-2\">Select up to 10 skills.</small>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"close(modal)\">Cancel</button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"saveUserSkills()\">Save</button>\n </div>\n</ng-template>\n" }]
2881
2882
  }], ctorParameters: () => [{ type: i1$1.NgbModal }, { type: i1$2.TagService }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }], propDecorators: { content: [{
2882
2883
  type: ViewChild,
2883
2884
  args: ['content', { static: true }]
@@ -3009,12 +3010,8 @@ class EditUserProfileModalComponent extends AppBaseComponent {
3009
3010
  });
3010
3011
  }
3011
3012
  ngOnInit() {
3012
- this.geoService.getCountries().subscribe(() => {
3013
- this.countries$ = this.geoService
3014
- .getCountries()
3015
- .pipe(map((countries) => [{ name: 'Select Country', code: null }, ...countries]));
3016
- this.cdr.markForCheck();
3017
- });
3013
+ this.countries$ = this.geoService.getCountries();
3014
+ this.cdr.markForCheck();
3018
3015
  this.getValues();
3019
3016
  }
3020
3017
  getValues() {
@@ -3059,7 +3056,7 @@ class EditUserProfileModalComponent extends AppBaseComponent {
3059
3056
  getRegion(countryId) {
3060
3057
  if (countryId) {
3061
3058
  this.geoService.getRegions(countryId).subscribe(response => {
3062
- this.states = [{ code: 0, name: 'Select State' }, ...response];
3059
+ this.states = response;
3063
3060
  this.cdr.markForCheck();
3064
3061
  });
3065
3062
  }
@@ -3088,7 +3085,7 @@ class EditUserProfileModalComponent extends AppBaseComponent {
3088
3085
  });
3089
3086
  }
3090
3087
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EditUserProfileModalComponent, deps: [{ token: i1$1.NgbModal }, { token: i2.UntypedFormBuilder }, { token: i1$2.ProfileService }, { token: i1$2.GeoService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
3091
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: EditUserProfileModalComponent, isStandalone: false, selector: "pw-edit-user-profile-modal", inputs: { slug: "slug", user: "user" }, outputs: { saveEvent: "saveEvent" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }, { propertyName: "placesRef", first: true, predicate: ["ngxPlaces"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">Edit Intro</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <form [formGroup]=\"form\"\n (ngSubmit)=\"onSaveDetail()\">\n <div class=\"row\">\n <pw-input-container class=\"col-6\"\n controlId=\"edit-intro-first-name\"\n label=\"First Name\"\n name=\"first_name\"\n errorMsg=\"Please enter first Name\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"first_name\"\n id=\"edit-intro-first-name\"\n autocomplete=\"given-name\" name=\"input_first_name_1\"/>\n </pw-input-container>\n\n <pw-input-container class=\"col-6\"\n controlId=\"edit-intro-last-name\"\n label=\"Last Name\"\n name=\"last_name\"\n errorMsg=\"Please enter last Name\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"last_name\"\n id=\"edit-intro-last-name\"\n autocomplete=\"family-name\" name=\"input_last_name_2\"/>\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-intro-headline\"\n label=\"Headline\"\n name=\"headline\"\n errorMsg=\"Please enter headline\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"headline\"\n id=\"edit-intro-headline\" name=\"input_headline_3\"/>\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-intro-description\"\n label=\"About me\"\n name=\"description\"\n errorMsg=\"Please enter description\">\n <textarea class=\"form-control\"\n id=\"edit-intro-description\"\n name=\"description\"\n formControlName=\"description\"></textarea>\n </pw-input-container>\n\n <pw-input-container class=\"col-6\"\n controlId=\"edit-intro-gender\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Gender\"\n name=\"gender\"\n errorMsg=\"Please enter Gender\">\n <p-selectButton [options]=\"[\n { label: 'Male', value: 'M' },\n { label: 'Female', value: 'F' }\n ]\"\n [attr.aria-labelledby]=\"'edit-intro-gender-label'\"\n formControlName=\"gender\"></p-selectButton>\n </pw-input-container>\n\n <pw-input-container class=\"col-6\"\n controlId=\"edit-intro-dob\"\n label=\"Date of Birth\"\n name=\"dob\"\n errorMsg=\"Please enter date of birth\">\n <div class=\"input-group\">\n <input class=\"form-control\"\n id=\"edit-intro-dob\"\n name=\"dob\"\n placeholder=\"yyyy-mm-dd\"\n formControlName=\"dob\"\n ngbDatepicker\n #d=\"ngbDatepicker\"\n [minDate]=\"{ year: 1950, month: 1, day: 1 }\"\n [maxDate]=\"{ year: 2018, month: 12, day: 31 }\"\n autocomplete=\"off\" />\n <div class=\"input-group-append\">\n <button class=\"btn btn-primary\"\n type=\"button\"\n aria-label=\"Open date picker\"\n (click)=\"d.toggle()\">\n <i class=\"fa fa-calendar\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </pw-input-container>\n\n <pw-input-container class=\"col-6\"\n controlId=\"edit-intro-phone\"\n label=\"Phone\"\n name=\"phone_number\"\n errorMsg=\"Please enter phone\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"phone_number\"\n id=\"edit-intro-phone\"\n name=\"phone_number\"\n autocomplete=\"tel\" />\n </pw-input-container>\n\n <pw-input-container class=\"col-6\"\n controlId=\"edit-intro-postcode\"\n label=\"Postcode\"\n name=\"postcode\"\n errorMsg=\"Please enter postcode\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"postcode\"\n id=\"edit-intro-postcode\"\n autocomplete=\"postal-code\" name=\"input_postcode_6\"/>\n </pw-input-container>\n\n @if (countries$ | async; as countries) {\n <pw-input-container class=\"col-12 col-sm-6\"\n controlId=\"edit-intro-country\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Country\"\n name=\"country\"\n errorMsg=\"Please select a country\">\n <p-select\n [attr.aria-labelledby]=\"'edit-intro-country-label'\"\n [options]=\"countries\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"country\"\n (onChange)=\"getRegion($event.value)\"\n placeholder=\"{{ 'User.Profile.SelectCountry' | transloco }}\">\n </p-select>\n </pw-input-container>\n }\n\n <pw-input-container class=\"col-12 col-sm-6\"\n controlId=\"edit-intro-state\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"State\"\n name=\"state\"\n errorMsg=\"Please select a state\">\n <p-select\n [attr.aria-labelledby]=\"'edit-intro-state-label'\"\n [options]=\"states\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"state\"\n [placeholder]=\"'User.Profile.SelectState' | transloco\">\n </p-select>\n </pw-input-container>\n\n <!-- Location -->\n <pw-input-container label=\"Location\"\n class=\"col-12 col-md-6\"\n controlId=\"edit-intro-location\"\n [useAriaLabelledbyOnly]=\"true\"\n name=\"location\">\n <input ngx-gp-autocomplete\n id=\"edit-intro-location\"\n name=\"location\"\n class=\"form-control\"\n #places=\"ngx-places\"\n formControlName=\"location\"\n [attr.aria-labelledby]=\"'edit-intro-location-label'\"\n (onAddressChange)=\"handleAddressChange($event)\" />\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-sm-6\"\n controlId=\"edit-intro-website\"\n label=\"Website\"\n name=\"website_url\"\n errorMsg=\"Please enter Website\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"website_url\"\n id=\"edit-intro-website\"\n autocomplete=\"url\" name=\"input_website_url_8\"/>\n </pw-input-container>\n </div>\n <div class=\"modal-footer\">\n <input type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"modal.close()\"\n value=\"Cancel\" id=\"input_field_9\" name=\"input_field_9\"/>\n <input type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\"\n value=\"Save Changes\" id=\"input_field_10\" name=\"input_field_10\"/>\n </div>\n </form>\n </div>\n</ng-template>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}::ng-deep .p-selectbutton .p-button{margin-right:1rem}::ng-deep body .p-selectbutton .p-button.p-highlight{background-color:var(--first)!important}\n"], dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { 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: "directive", type: i6$1.NgxGpAutocompleteDirective, selector: "[ngx-gp-autocomplete]", inputs: ["options"], outputs: ["onAddressChange"], exportAs: ["ngx-places"] }, { kind: "component", type: i6$2.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i5.InputContainerComponent, selector: "pw-input-container", inputs: ["name", "controlId", "useAriaLabelledbyOnly", "label", "labelClass", "tooltipPosition", "required", "errorMsg", "isReadOnly", "showTooltip", "tooltipText", "showTriangle", "afterLabel", "showAfterLabel", "showTriangleText", "isLeftTooltip"] }, { kind: "component", type: i8$1.SelectButton, selector: "p-selectButton, p-selectbutton, p-select-button", inputs: ["options", "optionLabel", "optionValue", "optionDisabled", "unselectable", "tabindex", "multiple", "allowEmpty", "styleClass", "ariaLabelledBy", "dataKey", "autofocus", "size", "fluid"], outputs: ["onOptionClick", "onChange"] }, { kind: "directive", type: i1$1.NgbInputDatepicker, selector: "input[ngbDatepicker]", inputs: ["autoClose", "contentTemplate", "datepickerClass", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "minDate", "maxDate", "navigation", "outsideDays", "placement", "popperOptions", "restoreFocus", "showWeekNumbers", "startDate", "container", "positionTarget", "weekdays", "disabled"], outputs: ["dateSelect", "navigate", "closed"], exportAs: ["ngbDatepicker"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
3088
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: EditUserProfileModalComponent, isStandalone: false, selector: "pw-edit-user-profile-modal", inputs: { slug: "slug", user: "user" }, outputs: { saveEvent: "saveEvent" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }, { propertyName: "placesRef", first: true, predicate: ["ngxPlaces"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">Edit Intro</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <form [formGroup]=\"form\"\n (ngSubmit)=\"onSaveDetail()\">\n <div class=\"row\">\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-first-name\"\n label=\"First Name\"\n name=\"first_name\"\n errorMsg=\"Please enter first Name\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"first_name\"\n id=\"edit-intro-first-name\"\n [placeholder]=\"'User.Profile.Intro.Placeholder.FirstName' | transloco\"\n autocomplete=\"given-name\" name=\"input_first_name_1\"/>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-last-name\"\n label=\"Last Name\"\n name=\"last_name\"\n errorMsg=\"Please enter last Name\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"last_name\"\n id=\"edit-intro-last-name\"\n [placeholder]=\"'User.Profile.Intro.Placeholder.LastName' | transloco\"\n autocomplete=\"family-name\" name=\"input_last_name_2\"/>\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-intro-headline\"\n label=\"Headline\"\n name=\"headline\"\n errorMsg=\"Please enter headline\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"headline\"\n id=\"edit-intro-headline\"\n [placeholder]=\"'User.Profile.Intro.Placeholder.Headline' | transloco\" name=\"input_headline_3\"/>\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-intro-description\"\n label=\"About me\"\n name=\"description\"\n errorMsg=\"Please enter description\">\n <textarea class=\"form-control\"\n id=\"edit-intro-description\"\n name=\"description\"\n [placeholder]=\"'User.Profile.Intro.Placeholder.Description' | transloco\"\n formControlName=\"description\"></textarea>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-gender\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Gender\"\n name=\"gender\"\n errorMsg=\"Please enter Gender\">\n <p-selectButton [options]=\"[\n { label: 'Male', value: 'M' },\n { label: 'Female', value: 'F' }\n ]\"\n [attr.aria-labelledby]=\"'edit-intro-gender-label'\"\n formControlName=\"gender\"></p-selectButton>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-dob\"\n label=\"Date of Birth\"\n name=\"dob\"\n errorMsg=\"Please enter date of birth\">\n <div class=\"input-group\">\n <input class=\"form-control\"\n id=\"edit-intro-dob\"\n name=\"dob\"\n placeholder=\"yyyy-mm-dd\"\n formControlName=\"dob\"\n ngbDatepicker\n #d=\"ngbDatepicker\"\n [minDate]=\"{ year: 1950, month: 1, day: 1 }\"\n [maxDate]=\"{ year: 2018, month: 12, day: 31 }\"\n autocomplete=\"off\" />\n <button class=\"btn btn-primary\"\n type=\"button\"\n aria-label=\"Open date picker\"\n (click)=\"d.toggle()\">\n <i class=\"fa fa-calendar\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-phone\"\n label=\"Phone\"\n name=\"phone_number\"\n errorMsg=\"Please enter phone\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"phone_number\"\n id=\"edit-intro-phone\"\n name=\"phone_number\"\n [placeholder]=\"'User.Profile.Intro.Placeholder.Phone' | transloco\"\n autocomplete=\"tel\" />\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-postcode\"\n label=\"Postcode\"\n name=\"postcode\"\n errorMsg=\"Please enter postcode\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"postcode\"\n id=\"edit-intro-postcode\"\n [placeholder]=\"'User.Profile.Intro.Placeholder.Postcode' | transloco\"\n autocomplete=\"postal-code\" name=\"input_postcode_6\"/>\n </pw-input-container>\n\n @if (countries$ | async; as countries) {\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-country\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Country\"\n name=\"country\"\n errorMsg=\"Please select a country\">\n <p-select\n [attr.aria-labelledby]=\"'edit-intro-country-label'\"\n [options]=\"countries\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"country\"\n (onChange)=\"getRegion($event.value)\"\n [placeholder]=\"'User.Profile.SelectCountry' | transloco\">\n </p-select>\n </pw-input-container>\n }\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-state\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"State\"\n name=\"state\"\n errorMsg=\"Please select a state\">\n <p-select\n [attr.aria-labelledby]=\"'edit-intro-state-label'\"\n [options]=\"states\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"state\"\n [placeholder]=\"'User.Profile.SelectState' | transloco\">\n </p-select>\n </pw-input-container>\n\n <!-- Location -->\n <pw-input-container label=\"Location\"\n class=\"col-12 col-md-6\"\n controlId=\"edit-intro-location\"\n [useAriaLabelledbyOnly]=\"true\"\n name=\"location\">\n <input ngx-gp-autocomplete\n id=\"edit-intro-location\"\n name=\"location\"\n class=\"form-control\"\n #places=\"ngx-places\"\n formControlName=\"location\"\n [placeholder]=\"'User.Profile.Intro.Placeholder.Location' | transloco\"\n [attr.aria-labelledby]=\"'edit-intro-location-label'\"\n (onAddressChange)=\"handleAddressChange($event)\" />\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-website\"\n label=\"Website\"\n name=\"website_url\"\n errorMsg=\"Please enter Website\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"website_url\"\n id=\"edit-intro-website\"\n [placeholder]=\"'User.Profile.Intro.Placeholder.Website' | transloco\"\n autocomplete=\"url\" name=\"input_website_url_8\"/>\n </pw-input-container>\n </div>\n <div class=\"modal-footer\">\n <input type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"modal.close()\"\n value=\"Cancel\" id=\"input_field_9\" name=\"input_field_9\"/>\n <input type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\"\n value=\"Save Changes\" id=\"input_field_10\" name=\"input_field_10\"/>\n </div>\n </form>\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}::ng-deep .p-selectbutton .p-button{margin-right:1rem}::ng-deep body .p-selectbutton .p-button.p-highlight{background-color:var(--first)!important}\n"], dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { 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: "directive", type: i6$1.NgxGpAutocompleteDirective, selector: "[ngx-gp-autocomplete]", inputs: ["options"], outputs: ["onAddressChange"], exportAs: ["ngx-places"] }, { kind: "component", type: i6$2.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i5.InputContainerComponent, selector: "pw-input-container", inputs: ["name", "controlId", "useAriaLabelledbyOnly", "label", "labelClass", "tooltipPosition", "required", "errorMsg", "isReadOnly", "showTooltip", "tooltipText", "showTriangle", "afterLabel", "showAfterLabel", "showTriangleText", "isLeftTooltip"] }, { kind: "component", type: i8$1.SelectButton, selector: "p-selectButton, p-selectbutton, p-select-button", inputs: ["options", "optionLabel", "optionValue", "optionDisabled", "unselectable", "tabindex", "multiple", "allowEmpty", "styleClass", "ariaLabelledBy", "dataKey", "autofocus", "size", "fluid"], outputs: ["onOptionClick", "onChange"] }, { kind: "directive", type: i1$1.NgbInputDatepicker, selector: "input[ngbDatepicker]", inputs: ["autoClose", "contentTemplate", "datepickerClass", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "minDate", "maxDate", "navigation", "outsideDays", "placement", "popperOptions", "restoreFocus", "showWeekNumbers", "startDate", "container", "positionTarget", "weekdays", "disabled"], outputs: ["dateSelect", "navigate", "closed"], exportAs: ["ngbDatepicker"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
3092
3089
  }
3093
3090
  __decorate([
3094
3091
  ValidateForm('form'),
@@ -3098,7 +3095,7 @@ __decorate([
3098
3095
  ], EditUserProfileModalComponent.prototype, "save", null);
3099
3096
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EditUserProfileModalComponent, decorators: [{
3100
3097
  type: Component,
3101
- args: [{ selector: 'pw-edit-user-profile-modal', standalone: false, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">Edit Intro</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <form [formGroup]=\"form\"\n (ngSubmit)=\"onSaveDetail()\">\n <div class=\"row\">\n <pw-input-container class=\"col-6\"\n controlId=\"edit-intro-first-name\"\n label=\"First Name\"\n name=\"first_name\"\n errorMsg=\"Please enter first Name\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"first_name\"\n id=\"edit-intro-first-name\"\n autocomplete=\"given-name\" name=\"input_first_name_1\"/>\n </pw-input-container>\n\n <pw-input-container class=\"col-6\"\n controlId=\"edit-intro-last-name\"\n label=\"Last Name\"\n name=\"last_name\"\n errorMsg=\"Please enter last Name\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"last_name\"\n id=\"edit-intro-last-name\"\n autocomplete=\"family-name\" name=\"input_last_name_2\"/>\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-intro-headline\"\n label=\"Headline\"\n name=\"headline\"\n errorMsg=\"Please enter headline\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"headline\"\n id=\"edit-intro-headline\" name=\"input_headline_3\"/>\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-intro-description\"\n label=\"About me\"\n name=\"description\"\n errorMsg=\"Please enter description\">\n <textarea class=\"form-control\"\n id=\"edit-intro-description\"\n name=\"description\"\n formControlName=\"description\"></textarea>\n </pw-input-container>\n\n <pw-input-container class=\"col-6\"\n controlId=\"edit-intro-gender\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Gender\"\n name=\"gender\"\n errorMsg=\"Please enter Gender\">\n <p-selectButton [options]=\"[\n { label: 'Male', value: 'M' },\n { label: 'Female', value: 'F' }\n ]\"\n [attr.aria-labelledby]=\"'edit-intro-gender-label'\"\n formControlName=\"gender\"></p-selectButton>\n </pw-input-container>\n\n <pw-input-container class=\"col-6\"\n controlId=\"edit-intro-dob\"\n label=\"Date of Birth\"\n name=\"dob\"\n errorMsg=\"Please enter date of birth\">\n <div class=\"input-group\">\n <input class=\"form-control\"\n id=\"edit-intro-dob\"\n name=\"dob\"\n placeholder=\"yyyy-mm-dd\"\n formControlName=\"dob\"\n ngbDatepicker\n #d=\"ngbDatepicker\"\n [minDate]=\"{ year: 1950, month: 1, day: 1 }\"\n [maxDate]=\"{ year: 2018, month: 12, day: 31 }\"\n autocomplete=\"off\" />\n <div class=\"input-group-append\">\n <button class=\"btn btn-primary\"\n type=\"button\"\n aria-label=\"Open date picker\"\n (click)=\"d.toggle()\">\n <i class=\"fa fa-calendar\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </pw-input-container>\n\n <pw-input-container class=\"col-6\"\n controlId=\"edit-intro-phone\"\n label=\"Phone\"\n name=\"phone_number\"\n errorMsg=\"Please enter phone\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"phone_number\"\n id=\"edit-intro-phone\"\n name=\"phone_number\"\n autocomplete=\"tel\" />\n </pw-input-container>\n\n <pw-input-container class=\"col-6\"\n controlId=\"edit-intro-postcode\"\n label=\"Postcode\"\n name=\"postcode\"\n errorMsg=\"Please enter postcode\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"postcode\"\n id=\"edit-intro-postcode\"\n autocomplete=\"postal-code\" name=\"input_postcode_6\"/>\n </pw-input-container>\n\n @if (countries$ | async; as countries) {\n <pw-input-container class=\"col-12 col-sm-6\"\n controlId=\"edit-intro-country\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Country\"\n name=\"country\"\n errorMsg=\"Please select a country\">\n <p-select\n [attr.aria-labelledby]=\"'edit-intro-country-label'\"\n [options]=\"countries\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"country\"\n (onChange)=\"getRegion($event.value)\"\n placeholder=\"{{ 'User.Profile.SelectCountry' | transloco }}\">\n </p-select>\n </pw-input-container>\n }\n\n <pw-input-container class=\"col-12 col-sm-6\"\n controlId=\"edit-intro-state\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"State\"\n name=\"state\"\n errorMsg=\"Please select a state\">\n <p-select\n [attr.aria-labelledby]=\"'edit-intro-state-label'\"\n [options]=\"states\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"state\"\n [placeholder]=\"'User.Profile.SelectState' | transloco\">\n </p-select>\n </pw-input-container>\n\n <!-- Location -->\n <pw-input-container label=\"Location\"\n class=\"col-12 col-md-6\"\n controlId=\"edit-intro-location\"\n [useAriaLabelledbyOnly]=\"true\"\n name=\"location\">\n <input ngx-gp-autocomplete\n id=\"edit-intro-location\"\n name=\"location\"\n class=\"form-control\"\n #places=\"ngx-places\"\n formControlName=\"location\"\n [attr.aria-labelledby]=\"'edit-intro-location-label'\"\n (onAddressChange)=\"handleAddressChange($event)\" />\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-sm-6\"\n controlId=\"edit-intro-website\"\n label=\"Website\"\n name=\"website_url\"\n errorMsg=\"Please enter Website\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"website_url\"\n id=\"edit-intro-website\"\n autocomplete=\"url\" name=\"input_website_url_8\"/>\n </pw-input-container>\n </div>\n <div class=\"modal-footer\">\n <input type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"modal.close()\"\n value=\"Cancel\" id=\"input_field_9\" name=\"input_field_9\"/>\n <input type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\"\n value=\"Save Changes\" id=\"input_field_10\" name=\"input_field_10\"/>\n </div>\n </form>\n </div>\n</ng-template>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}::ng-deep .p-selectbutton .p-button{margin-right:1rem}::ng-deep body .p-selectbutton .p-button.p-highlight{background-color:var(--first)!important}\n"] }]
3098
+ args: [{ selector: 'pw-edit-user-profile-modal', standalone: false, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">Edit Intro</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <form [formGroup]=\"form\"\n (ngSubmit)=\"onSaveDetail()\">\n <div class=\"row\">\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-first-name\"\n label=\"First Name\"\n name=\"first_name\"\n errorMsg=\"Please enter first Name\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"first_name\"\n id=\"edit-intro-first-name\"\n [placeholder]=\"'User.Profile.Intro.Placeholder.FirstName' | transloco\"\n autocomplete=\"given-name\" name=\"input_first_name_1\"/>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-last-name\"\n label=\"Last Name\"\n name=\"last_name\"\n errorMsg=\"Please enter last Name\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"last_name\"\n id=\"edit-intro-last-name\"\n [placeholder]=\"'User.Profile.Intro.Placeholder.LastName' | transloco\"\n autocomplete=\"family-name\" name=\"input_last_name_2\"/>\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-intro-headline\"\n label=\"Headline\"\n name=\"headline\"\n errorMsg=\"Please enter headline\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"headline\"\n id=\"edit-intro-headline\"\n [placeholder]=\"'User.Profile.Intro.Placeholder.Headline' | transloco\" name=\"input_headline_3\"/>\n </pw-input-container>\n\n <pw-input-container class=\"col-12\"\n controlId=\"edit-intro-description\"\n label=\"About me\"\n name=\"description\"\n errorMsg=\"Please enter description\">\n <textarea class=\"form-control\"\n id=\"edit-intro-description\"\n name=\"description\"\n [placeholder]=\"'User.Profile.Intro.Placeholder.Description' | transloco\"\n formControlName=\"description\"></textarea>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-gender\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Gender\"\n name=\"gender\"\n errorMsg=\"Please enter Gender\">\n <p-selectButton [options]=\"[\n { label: 'Male', value: 'M' },\n { label: 'Female', value: 'F' }\n ]\"\n [attr.aria-labelledby]=\"'edit-intro-gender-label'\"\n formControlName=\"gender\"></p-selectButton>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-dob\"\n label=\"Date of Birth\"\n name=\"dob\"\n errorMsg=\"Please enter date of birth\">\n <div class=\"input-group\">\n <input class=\"form-control\"\n id=\"edit-intro-dob\"\n name=\"dob\"\n placeholder=\"yyyy-mm-dd\"\n formControlName=\"dob\"\n ngbDatepicker\n #d=\"ngbDatepicker\"\n [minDate]=\"{ year: 1950, month: 1, day: 1 }\"\n [maxDate]=\"{ year: 2018, month: 12, day: 31 }\"\n autocomplete=\"off\" />\n <button class=\"btn btn-primary\"\n type=\"button\"\n aria-label=\"Open date picker\"\n (click)=\"d.toggle()\">\n <i class=\"fa fa-calendar\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-phone\"\n label=\"Phone\"\n name=\"phone_number\"\n errorMsg=\"Please enter phone\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"phone_number\"\n id=\"edit-intro-phone\"\n name=\"phone_number\"\n [placeholder]=\"'User.Profile.Intro.Placeholder.Phone' | transloco\"\n autocomplete=\"tel\" />\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-postcode\"\n label=\"Postcode\"\n name=\"postcode\"\n errorMsg=\"Please enter postcode\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"postcode\"\n id=\"edit-intro-postcode\"\n [placeholder]=\"'User.Profile.Intro.Placeholder.Postcode' | transloco\"\n autocomplete=\"postal-code\" name=\"input_postcode_6\"/>\n </pw-input-container>\n\n @if (countries$ | async; as countries) {\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-country\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"Country\"\n name=\"country\"\n errorMsg=\"Please select a country\">\n <p-select\n [attr.aria-labelledby]=\"'edit-intro-country-label'\"\n [options]=\"countries\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"country\"\n (onChange)=\"getRegion($event.value)\"\n [placeholder]=\"'User.Profile.SelectCountry' | transloco\">\n </p-select>\n </pw-input-container>\n }\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-state\"\n [useAriaLabelledbyOnly]=\"true\"\n label=\"State\"\n name=\"state\"\n errorMsg=\"Please select a state\">\n <p-select\n [attr.aria-labelledby]=\"'edit-intro-state-label'\"\n [options]=\"states\"\n optionLabel=\"name\"\n optionValue=\"code\"\n formControlName=\"state\"\n [placeholder]=\"'User.Profile.SelectState' | transloco\">\n </p-select>\n </pw-input-container>\n\n <!-- Location -->\n <pw-input-container label=\"Location\"\n class=\"col-12 col-md-6\"\n controlId=\"edit-intro-location\"\n [useAriaLabelledbyOnly]=\"true\"\n name=\"location\">\n <input ngx-gp-autocomplete\n id=\"edit-intro-location\"\n name=\"location\"\n class=\"form-control\"\n #places=\"ngx-places\"\n formControlName=\"location\"\n [placeholder]=\"'User.Profile.Intro.Placeholder.Location' | transloco\"\n [attr.aria-labelledby]=\"'edit-intro-location-label'\"\n (onAddressChange)=\"handleAddressChange($event)\" />\n </pw-input-container>\n\n <pw-input-container class=\"col-12 col-md-6\"\n controlId=\"edit-intro-website\"\n label=\"Website\"\n name=\"website_url\"\n errorMsg=\"Please enter Website\">\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"website_url\"\n id=\"edit-intro-website\"\n [placeholder]=\"'User.Profile.Intro.Placeholder.Website' | transloco\"\n autocomplete=\"url\" name=\"input_website_url_8\"/>\n </pw-input-container>\n </div>\n <div class=\"modal-footer\">\n <input type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"modal.close()\"\n value=\"Cancel\" id=\"input_field_9\" name=\"input_field_9\"/>\n <input type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\"\n value=\"Save Changes\" id=\"input_field_10\" name=\"input_field_10\"/>\n </div>\n </form>\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}::ng-deep .p-selectbutton .p-button{margin-right:1rem}::ng-deep body .p-selectbutton .p-button.p-highlight{background-color:var(--first)!important}\n"] }]
3102
3099
  }], ctorParameters: () => [{ type: i1$1.NgbModal }, { type: i2.UntypedFormBuilder }, { type: i1$2.ProfileService }, { type: i1$2.GeoService }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }], propDecorators: { content: [{
3103
3100
  type: ViewChild,
3104
3101
  args: ['content', { static: true }]
@@ -3221,11 +3218,11 @@ class UserAboutComponent extends AppBaseComponent {
3221
3218
  }
3222
3219
  }
3223
3220
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserAboutComponent, deps: [{ token: i1$2.ProfileService }, { token: i1$2.QualificationService }, { token: i1$2.TagService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
3224
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: UserAboutComponent, isStandalone: false, selector: "pw-user-about", inputs: { user: "user", isEdit: "isEdit" }, outputs: { saveEvent: "saveEvent" }, viewQueries: [{ propertyName: "modal", first: true, predicate: EditUserProfileModalComponent, descendants: true }, { propertyName: "qualificationModal", first: true, predicate: EditQualificationsModalComponent, descendants: true }, { propertyName: "skillsModal", first: true, predicate: EditSkillsModalComponent, descendants: true }, { propertyName: "socialModal", first: true, predicate: EditSocialLinksComponent, descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"row\">\n <div class=\"col-sm-12 mt-2\">\n <div data-cy=\"personal-info\">\n <h2 class=\"\">Personal Information</h2>\n @if (user && isEdit) {\n <i\n class=\"profile-icons fa fa-lg fa-user-edit float-end mt-3 pt-1 pt-md-0\"\n (click)=\"onProfileOpen()\"\n (keydown.enter)=\"onProfileOpen()\"\n aria-label=\"Open Profile\"\n aria-hidden=\"true\"\n ></i>\n <pw-edit-user-profile-modal [user]=\"user\"\n (saveEvent)=\"onProfileSaved($event)\"\n [slug]=\"user?.slug\">\n </pw-edit-user-profile-modal>\n }\n </div>\n <div>\n <div class=\"my-3\">\n <span class=\"profile-label\">About Me:</span>\n <span class=\"display-block overflow-hidden\">{{ user_profile?.description || 'No description has been added yet.' }}\n </span>\n </div>\n <hr />\n <div class=\"row mt-0 my-0\">\n <div class=\"col-6 col-sm-6 col-lg-4\">\n <ul class=\"no-list-style personal-info\">\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"icon-present font-small-3\" aria-hidden=\"true\"></i>\n Birthday:</span>\n <span class=\"display-block overflow-hidden pt-2\">{{\n user_profile?.dob | dateFormat\n }}</span>\n </li>\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-globe font-small-3\" aria-hidden=\"true\"></i> Lives\n in:</span>\n <span class=\"display-block overflow-hidden pt-2\">{{\n user_profile?.country\n }}</span>\n </li>\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-monitor font-small-3\" aria-hidden=\"true\"></i>\n Website:</span>\n <a class=\"display-block overflow-hidden pt-2\">{{\n user_profile?.website_url\n }}</a>\n </li>\n </ul>\n </div>\n <div class=\"col-6 col-sm-6 col-lg-4\">\n <ul class=\"no-list-style personal-info\">\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-user font-small-3\" aria-hidden=\"true\"></i>\n Gender:</span>\n <span class=\"display-block overflow-hidden pt-2\">\n {{\n user_profile?.gender === 'M'\n ? 'Male'\n : user_profile?.gender === 'F'\n ? 'Female'\n : ''\n }}\n </span>\n </li>\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-mail font-small-3\" aria-hidden=\"true\"></i>\n Email:</span>\n <a class=\"display-block overflow-hidden pt-2\">{{ user?.email }}</a>\n </li>\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-smartphone font-small-3\" aria-hidden=\"true\"></i> Phone\n Number:</span>\n <span class=\"display-block overflow-hidden pt-2\">{{\n user_profile?.phone_number\n }}</span>\n</li>\n</ul>\n</div>\n<div class=\"col-6 col-md-6 col-lg-4\">\n <ul class=\"no-list-style personal-info\">\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-book font-small-3\" aria-hidden=\"true\"></i>\n Joined:</span>\n <span class=\"display-block overflow-hidden pt-2\">{{\n user?.joined_at | dateFormat\n }}</span>\n </li>\n</ul>\n</div>\n</div>\n</div>\n<hr />\n<div data-cy=\"skills-info\"\n class=\"mt-4\">\n <h2 class=\"\">Skills</h2>\n @if (isEdit) {\n <div class=\"float-end\"\n >\n <i\n class=\"profile-icons fa fa-lg fa-edit float-end mt-3 pt-1 pt-md-0\"\n (click)=\"openSkills()\"\n (keydown.enter)=\"openSkills()\"\n aria-label=\"Open Skills\"\n aria-hidden=\"true\"\n ></i>\n <pw-edit-skills-modal [userId]=\"user?.id\"\n [slug]=\"user?.slug\"\n (saveEvent)=\"getUserDetails()\">\n </pw-edit-skills-modal>\n </div>\n }\n <div class=\"row\">\n <div class=\"col-12\">\n @if (selectedSkills?.length === 0) {\n <div class=\"mb-4\"\n >\n {{\n isEdit\n ? \"You haven't selected any skills yet. Please add some.\"\n : 'No skills added.'\n }}\n </div>\n }\n </div>\n </div>\n</div>\n<div class=\"ui-fluid\">\n @for (skill of selectedSkills; track skill) {\n <span class=\"\"\n >\n <span class=\"my-2 me-3\">{{ skill.category_name }}</span>\n @for (item of skill.tags; track item) {\n <span\n class=\"badge bg-success me-2 mb-2\">{{ item.name }}\n </span>\n }\n <br />\n </span>\n }\n</div>\n<hr />\n<div data-cy=\"educational-info\">\n <div class=\"\">\n <h2 class=\"\">Educational Information</h2>\n @if (isEdit) {\n <div class=\"float-end\"\n >\n <pw-edit-qualifications-modal (saveEvent)=\"getUserDetails()\">\n </pw-edit-qualifications-modal>\n </div>\n }\n </div>\n <div class=\"row\">\n @for (item of qualifications; track trackByQualification($index, item)) {\n <div class=\"col-lg-6 col-12 mb-4\"\n [ngClass]=\"{ editable: isEdit }\"\n >\n <div class=\"mb-2\">\n <div class=\"float-start\">\n <h4>{{ item?.school }}</h4>\n <ul class=\"no-list-style\">\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-clock font-small-3\" aria-hidden=\"true\"></i>\n Period:</span>\n <span class=\"display-block overflow-hidden pt-2\">\n {{ item?.started_on }} - {{ item?.ended_on }}\n </span>\n </li>\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-feather font-small-3\" aria-hidden=\"true\"></i>\n Degree:</span>\n <span class=\"display-block overflow-hidden pt-2\">\n {{ item?.degree }}\n </span>\n </li>\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-octagon font-small-3\" aria-hidden=\"true\"></i>\n Course:</span>\n <span class=\"display-block overflow-hidden pt-2\">\n {{ item?.course }}\n </span>\n </li>\n </ul>\n </div>\n @if (isEdit) {\n <div class=\"float-end action\"\n >\n <span class=\"fa-stack\">\n <i\n class=\"fa fa-lg fa-edit fa-stack-1x me-3 profile-icons\"\n title=\"Edit\"\n (keydown.enter)=\"editQualification(item)\"\n aria-label=\"Edit Qualification\"\n (click)=\"editQualification(item)\"\n aria-hidden=\"true\"\n ></i>\n </span>\n <span class=\"fa-stack\">\n <i\n class=\"fa fa-lg fa-trash fa-stack-1x delete-icon\"\n data-cy=\"delete-qualification\"\n title=\"Delete\"\n aria-label=\"Delete Qualification\"\n (keydown.enter)=\"deleteQualification(item)\"\n (click)=\"deleteQualification(item)\"\n aria-hidden=\"true\"\n ></i>\n </span>\n </div>\n }\n </div>\n</div>\n}\n@if (qualifications && qualifications.length === 0) {\n <div class=\"col-lg-6 col-12 mb-4\"\n >\n {{\n isEdit\n ? ' No qualification yet. Please add some.'\n : 'No qualifications added.'\n }}\n </div>\n}\n</div>\n</div>\n<hr />\n<!-- External Portfolio -->\n<div data-cy=\"portfolio-info\"\n class=\"mt-4\">\n <div class=\"\">\n <h2 class=\"\">External Portfolio</h2>\n @if (isEdit) {\n <i\n class=\"fa fa-lg fa-edit profile-icons float-end mt-3 pt-1 pt-md-0\"\n (click)=\"onOpenSocial()\"\n aria-label=\"Edit external portfolio\"\n (keydown)=\"($event.key === 'Enter' ? onOpenSocial() : null)\"\n title=\"Edit External Portfolio\"\n ></i>\n }\n </div>\n <div class=\"row\">\n <div class=\"col-md-6 col-12 mb-4\">\n @if (userLinks) {\n <div>\n @for (link of objectKeys(userLinks); track link) {\n @if (userLinks[link]) {\n <a target=\"_blank\"\n rel=\"noopener noreferrer\"\n [href]=\"userLinks[link]\"\n >\n <img src=\"assets/img/icons/social/{{ link }}.svg\"\n class=\"me-2\"\n width=\"40\"\n alt=\"\" />\n </a>\n }\n }\n </div>\n }\n <div class=\"row\">\n @if (user) {\n <pw-edit-social-links [userId]=\"user.id\"\n [links]=\"userLinks\"\n (saveEvent)=\"onSaveUserLinks()\">\n </pw-edit-social-links>\n }\n @if (!noUserLinks) {\n <div class=\"col-12 mb-4\"\n >\n {{\n isEdit\n ? 'No external portfolio yet. Please add some.'\n : 'No portfolio added.'\n }}\n </div>\n }\n </div>\n </div>\n </div>\n</div>\n</div>\n</div>\n@if (loading) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n}\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.edu-card .action{display:none}.edu-card:hover .action{display:block}.profile-label{color:var(--first);font-weight:700;margin-right:15px}.profile-icons{color:var(--first)}.personal-info{margin-left:6%}@media only screen and (max-width:1024px){#about{font-size:.7rem}}\n"], dependencies: [{ kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: EditQualificationsModalComponent, selector: "pw-edit-qualifications-modal", outputs: ["saveEvent"] }, { kind: "component", type: EditSkillsModalComponent, selector: "pw-edit-skills-modal", inputs: ["userId", "slug", "entityType", "entityEntity"], outputs: ["saveEvent"] }, { kind: "component", type: EditSocialLinksComponent, selector: "pw-edit-social-links", inputs: ["links", "userId"], outputs: ["saveEvent"] }, { kind: "component", type: EditUserProfileModalComponent, selector: "pw-edit-user-profile-modal", inputs: ["slug", "user"], outputs: ["saveEvent"] }, { kind: "pipe", type: i6$3.DateFormatPipe, name: "dateFormat" }] }); }
3221
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: UserAboutComponent, isStandalone: false, selector: "pw-user-about", inputs: { user: "user", isEdit: "isEdit" }, outputs: { saveEvent: "saveEvent" }, viewQueries: [{ propertyName: "modal", first: true, predicate: EditUserProfileModalComponent, descendants: true }, { propertyName: "qualificationModal", first: true, predicate: EditQualificationsModalComponent, descendants: true }, { propertyName: "skillsModal", first: true, predicate: EditSkillsModalComponent, descendants: true }, { propertyName: "socialModal", first: true, predicate: EditSocialLinksComponent, descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"about\">\n <!-- Personal Information -->\n <section class=\"about-section\" data-cy=\"personal-info\">\n <header class=\"about-section__head\">\n <span class=\"about-section__icon\"><i class=\"fa fa-user\" aria-hidden=\"true\"></i></span>\n <h2 class=\"about-section__title\">{{ 'User.Profile.About.PersonalInfo' | transloco }}</h2>\n @if (user && isEdit) {\n <button type=\"button\" class=\"about-section__edit\" (click)=\"onProfileOpen()\" [attr.aria-label]=\"'User.Profile.About.EditPersonalInfo' | transloco\">\n <i class=\"fa fa-pen\" aria-hidden=\"true\"></i>\n </button>\n }\n </header>\n <div class=\"about-bio\">\n <span class=\"about-field__label\">{{ 'User.Profile.About.AboutMe' | transloco }}</span>\n <p class=\"about-bio__text\" [class.is-empty]=\"!user_profile?.description\">\n {{ user_profile?.description || ('User.Profile.About.NoDescription' | transloco) }}\n </p>\n </div>\n <dl class=\"about-grid\">\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.Birthday' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!user_profile?.dob\">{{ (user_profile?.dob | dateFormat) || '\u2014' }}</dd>\n </div>\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.LivesIn' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!user_profile?.country\">{{ user_profile?.country || '\u2014' }}</dd>\n </div>\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.Gender' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!user_profile?.gender\">\n {{\n user_profile?.gender === 'M'\n ? ('User.Profile.About.Male' | transloco)\n : user_profile?.gender === 'F'\n ? ('User.Profile.About.Female' | transloco)\n : '\u2014'\n }}\n </dd>\n </div>\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.Email' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!user?.email\">\n @if (user?.email) {\n <a class=\"about-field__link\" [href]=\"'mailto:' + user.email\">{{ user.email }}</a>\n } @else {\n \u2014\n }\n </dd>\n </div>\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.PhoneNumber' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!user_profile?.phone_number\">{{ user_profile?.phone_number || '\u2014' }}</dd>\n </div>\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.Website' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!user_profile?.website_url\">\n @if (user_profile?.website_url) {\n <a class=\"about-field__link\" target=\"_blank\" rel=\"noopener noreferrer\" [href]=\"user_profile.website_url\">{{ user_profile.website_url }}</a>\n } @else {\n \u2014\n }\n </dd>\n </div>\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.Joined' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!user?.joined_at\">{{ (user?.joined_at | dateFormat) || '\u2014' }}</dd>\n </div>\n </dl>\n @if (user && isEdit) {\n <pw-edit-user-profile-modal [user]=\"user\" (saveEvent)=\"onProfileSaved($event)\" [slug]=\"user?.slug\"></pw-edit-user-profile-modal>\n }\n </section>\n\n <!-- Skills -->\n <section class=\"about-section\" data-cy=\"skills-info\">\n <header class=\"about-section__head\">\n <span class=\"about-section__icon\"><i class=\"fa fa-bolt\" aria-hidden=\"true\"></i></span>\n <h2 class=\"about-section__title\">{{ 'User.Profile.About.Skills' | transloco }}</h2>\n @if (isEdit) {\n <button type=\"button\" class=\"about-section__edit\" (click)=\"openSkills()\" [attr.aria-label]=\"'User.Profile.About.EditSkills' | transloco\">\n <i class=\"fa fa-pen\" aria-hidden=\"true\"></i>\n </button>\n }\n </header>\n @if (selectedSkills?.length) {\n <div class=\"about-skills\">\n @for (skill of selectedSkills; track skill) {\n <div class=\"about-skills__group\">\n <span class=\"about-skills__category\">{{ skill.category_name }}</span>\n <div class=\"about-tags\">\n @for (item of skill.tags; track item) {\n <span class=\"about-tag\">{{ item.name }}</span>\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <p class=\"about-empty\">{{ (isEdit ? 'User.Profile.About.NoSkillsEdit' : 'User.Profile.About.NoSkills') | transloco }}</p>\n }\n @if (isEdit) {\n <pw-edit-skills-modal [userId]=\"user?.id\" [slug]=\"user?.slug\" (saveEvent)=\"getUserDetails()\"></pw-edit-skills-modal>\n }\n </section>\n\n <!-- Educational Information -->\n <section class=\"about-section\" data-cy=\"educational-info\">\n <header class=\"about-section__head\">\n <span class=\"about-section__icon\"><i class=\"fa fa-graduation-cap\" aria-hidden=\"true\"></i></span>\n <h2 class=\"about-section__title\">{{ 'User.Profile.About.Education' | transloco }}</h2>\n @if (isEdit) {\n <button type=\"button\" class=\"about-section__edit\" (click)=\"qualificationModal.onOpen()\" [attr.aria-label]=\"'User.Profile.About.AddEducation' | transloco\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n </button>\n }\n </header>\n @if (qualifications?.length) {\n <div class=\"about-edu\">\n @for (item of qualifications; track trackByQualification($index, item)) {\n <article class=\"about-edu__item\">\n <div class=\"about-edu__main\">\n <h4 class=\"about-edu__school\">{{ item?.school }}</h4>\n <dl class=\"about-grid about-grid--compact\">\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.Period' | transloco }}</dt>\n <dd class=\"about-field__value\">{{ item?.started_on }} \u2013 {{ item?.ended_on }}</dd>\n </div>\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.Degree' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!item?.degree\">{{ item?.degree || '\u2014' }}</dd>\n </div>\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.Course' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!item?.course\">{{ item?.course || '\u2014' }}</dd>\n </div>\n </dl>\n </div>\n @if (isEdit) {\n <div class=\"about-edu__actions\">\n <button type=\"button\" class=\"about-icon-btn\" [attr.aria-label]=\"'User.Profile.About.EditEducation' | transloco\" (click)=\"editQualification(item)\">\n <i class=\"fa fa-pen\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"about-icon-btn about-icon-btn--danger\" data-cy=\"delete-qualification\" [attr.aria-label]=\"'User.Profile.About.DeleteEducation' | transloco\" (click)=\"deleteQualification(item)\">\n <i class=\"fa fa-trash\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n </article>\n }\n </div>\n } @else {\n <p class=\"about-empty\">{{ 'User.Profile.About.NoEducation' | transloco }}</p>\n }\n @if (isEdit) {\n <pw-edit-qualifications-modal (saveEvent)=\"getUserDetails()\"></pw-edit-qualifications-modal>\n }\n </section>\n\n <!-- External Portfolio -->\n <section class=\"about-section\" data-cy=\"portfolio-info\">\n <header class=\"about-section__head\">\n <span class=\"about-section__icon\"><i class=\"fa fa-link\" aria-hidden=\"true\"></i></span>\n <h2 class=\"about-section__title\">{{ 'User.Profile.About.Portfolio' | transloco }}</h2>\n @if (isEdit) {\n <button type=\"button\" class=\"about-section__edit\" (click)=\"onOpenSocial()\" [attr.aria-label]=\"'User.Profile.About.EditPortfolio' | transloco\">\n <i class=\"fa fa-pen\" aria-hidden=\"true\"></i>\n </button>\n }\n </header>\n @if (noUserLinks) {\n <div class=\"about-social\">\n @for (link of objectKeys(userLinks); track link) {\n @if (userLinks[link]) {\n <a class=\"about-social__link\" target=\"_blank\" rel=\"noopener noreferrer\" [href]=\"userLinks[link]\" [attr.aria-label]=\"link\">\n <img src=\"assets/img/icons/social/{{ link }}.svg\" width=\"32\" height=\"32\" [alt]=\"link\" />\n </a>\n }\n }\n </div>\n } @else {\n <p class=\"about-empty\">{{ 'User.Profile.About.NoPortfolio' | transloco }}</p>\n }\n @if (user && isEdit) {\n <pw-edit-social-links [userId]=\"user.id\" [links]=\"userLinks\" (saveEvent)=\"onSaveUserLinks()\"></pw-edit-social-links>\n }\n </section>\n\n @if (loading) {\n <div class=\"w-100 text-center p-3\"><p-progressSpinner strokeWidth=\"2\"></p-progressSpinner></div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.about{display:flex;flex-direction:column;gap:16px}.about-section{background:#fff;border:1px solid #e2e5ea;border-radius:8px;padding:20px 24px;float:none}.about-section ::ng-deep .pi-plus-circle{display:none}.about-section__head{display:flex;align-items:center;margin-bottom:18px;float:none}.about-section__icon{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;margin-right:12px;border-radius:8px;background:#f7f8fa;color:#5a6473;font-size:.95rem;flex-shrink:0}.about-section__title{margin:0!important;padding:0!important}.about-section__edit{margin-left:auto}.about-field__label,.about-skills__category{margin:0;font-size:1rem;font-weight:600;letter-spacing:.03em;text-transform:uppercase;color:#7c8696}.about-section__edit,.about-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:1px solid #e2e5ea;border-radius:7px;background:#fff;color:#5a6473;font-size:.9rem;cursor:pointer;transition:all .12s ease-out}.about-section__edit:hover,.about-icon-btn:hover{background:#f7f8fa;color:#1a1d21;border-color:#cfd4dc}.about-empty{margin:0;color:#7c8696;font-size:1.2rem}.about-bio{margin-bottom:22px}.about-bio__text{margin:6px 0 0;color:#1a1d21;font-size:1.25rem;line-height:1.55}.about-bio__text.is-empty{color:#7c8696;font-size:1.2rem}.about-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:20px 28px;margin:0}.about-grid--compact{gap:14px 24px}.about-field{display:flex;flex-direction:column;gap:5px;min-width:0}.about-field__value{margin:0;font-size:1.15rem;color:#1a1d21;word-break:break-word}.about-field__value.is-empty{color:#cfd4dc}.about-field__link{color:var(--first);text-decoration:none}.about-field__link:hover{text-decoration:underline}.about-skills{display:flex;flex-direction:column;gap:16px}.about-skills__group{display:flex;flex-direction:column;gap:8px}.about-tags{display:flex;flex-wrap:wrap;gap:8px}.about-tag{display:inline-flex;align-items:center;padding:5px 13px;border:1px solid #e2e5ea;border-radius:9999px;background:#eef0f3;color:#3d4654;font-size:1.05rem;font-weight:500;line-height:1.4}.about-edu{display:flex;flex-direction:column;gap:14px}.about-edu__item{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:16px;border:1px solid #e2e5ea;border-radius:8px;background:#f7f8fa}.about-edu__main{min-width:0;flex:1}.about-edu__school{margin:0 0 12px}.about-edu__actions{display:flex;gap:6px;flex-shrink:0}.about-icon-btn--danger:hover{color:#c0392b;border-color:#c0392b}.about-social{display:flex;flex-wrap:wrap;gap:14px}.about-social__link{display:inline-flex}\n"], dependencies: [{ kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: EditQualificationsModalComponent, selector: "pw-edit-qualifications-modal", outputs: ["saveEvent"] }, { kind: "component", type: EditSkillsModalComponent, selector: "pw-edit-skills-modal", inputs: ["userId", "slug", "entityType", "entityEntity"], outputs: ["saveEvent"] }, { kind: "component", type: EditSocialLinksComponent, selector: "pw-edit-social-links", inputs: ["links", "userId"], outputs: ["saveEvent"] }, { kind: "component", type: EditUserProfileModalComponent, selector: "pw-edit-user-profile-modal", inputs: ["slug", "user"], outputs: ["saveEvent"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i6$3.DateFormatPipe, name: "dateFormat" }] }); }
3225
3222
  }
3226
3223
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserAboutComponent, decorators: [{
3227
3224
  type: Component,
3228
- args: [{ selector: 'pw-user-about', standalone: false, template: "<div class=\"row\">\n <div class=\"col-sm-12 mt-2\">\n <div data-cy=\"personal-info\">\n <h2 class=\"\">Personal Information</h2>\n @if (user && isEdit) {\n <i\n class=\"profile-icons fa fa-lg fa-user-edit float-end mt-3 pt-1 pt-md-0\"\n (click)=\"onProfileOpen()\"\n (keydown.enter)=\"onProfileOpen()\"\n aria-label=\"Open Profile\"\n aria-hidden=\"true\"\n ></i>\n <pw-edit-user-profile-modal [user]=\"user\"\n (saveEvent)=\"onProfileSaved($event)\"\n [slug]=\"user?.slug\">\n </pw-edit-user-profile-modal>\n }\n </div>\n <div>\n <div class=\"my-3\">\n <span class=\"profile-label\">About Me:</span>\n <span class=\"display-block overflow-hidden\">{{ user_profile?.description || 'No description has been added yet.' }}\n </span>\n </div>\n <hr />\n <div class=\"row mt-0 my-0\">\n <div class=\"col-6 col-sm-6 col-lg-4\">\n <ul class=\"no-list-style personal-info\">\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"icon-present font-small-3\" aria-hidden=\"true\"></i>\n Birthday:</span>\n <span class=\"display-block overflow-hidden pt-2\">{{\n user_profile?.dob | dateFormat\n }}</span>\n </li>\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-globe font-small-3\" aria-hidden=\"true\"></i> Lives\n in:</span>\n <span class=\"display-block overflow-hidden pt-2\">{{\n user_profile?.country\n }}</span>\n </li>\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-monitor font-small-3\" aria-hidden=\"true\"></i>\n Website:</span>\n <a class=\"display-block overflow-hidden pt-2\">{{\n user_profile?.website_url\n }}</a>\n </li>\n </ul>\n </div>\n <div class=\"col-6 col-sm-6 col-lg-4\">\n <ul class=\"no-list-style personal-info\">\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-user font-small-3\" aria-hidden=\"true\"></i>\n Gender:</span>\n <span class=\"display-block overflow-hidden pt-2\">\n {{\n user_profile?.gender === 'M'\n ? 'Male'\n : user_profile?.gender === 'F'\n ? 'Female'\n : ''\n }}\n </span>\n </li>\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-mail font-small-3\" aria-hidden=\"true\"></i>\n Email:</span>\n <a class=\"display-block overflow-hidden pt-2\">{{ user?.email }}</a>\n </li>\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-smartphone font-small-3\" aria-hidden=\"true\"></i> Phone\n Number:</span>\n <span class=\"display-block overflow-hidden pt-2\">{{\n user_profile?.phone_number\n }}</span>\n</li>\n</ul>\n</div>\n<div class=\"col-6 col-md-6 col-lg-4\">\n <ul class=\"no-list-style personal-info\">\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-book font-small-3\" aria-hidden=\"true\"></i>\n Joined:</span>\n <span class=\"display-block overflow-hidden pt-2\">{{\n user?.joined_at | dateFormat\n }}</span>\n </li>\n</ul>\n</div>\n</div>\n</div>\n<hr />\n<div data-cy=\"skills-info\"\n class=\"mt-4\">\n <h2 class=\"\">Skills</h2>\n @if (isEdit) {\n <div class=\"float-end\"\n >\n <i\n class=\"profile-icons fa fa-lg fa-edit float-end mt-3 pt-1 pt-md-0\"\n (click)=\"openSkills()\"\n (keydown.enter)=\"openSkills()\"\n aria-label=\"Open Skills\"\n aria-hidden=\"true\"\n ></i>\n <pw-edit-skills-modal [userId]=\"user?.id\"\n [slug]=\"user?.slug\"\n (saveEvent)=\"getUserDetails()\">\n </pw-edit-skills-modal>\n </div>\n }\n <div class=\"row\">\n <div class=\"col-12\">\n @if (selectedSkills?.length === 0) {\n <div class=\"mb-4\"\n >\n {{\n isEdit\n ? \"You haven't selected any skills yet. Please add some.\"\n : 'No skills added.'\n }}\n </div>\n }\n </div>\n </div>\n</div>\n<div class=\"ui-fluid\">\n @for (skill of selectedSkills; track skill) {\n <span class=\"\"\n >\n <span class=\"my-2 me-3\">{{ skill.category_name }}</span>\n @for (item of skill.tags; track item) {\n <span\n class=\"badge bg-success me-2 mb-2\">{{ item.name }}\n </span>\n }\n <br />\n </span>\n }\n</div>\n<hr />\n<div data-cy=\"educational-info\">\n <div class=\"\">\n <h2 class=\"\">Educational Information</h2>\n @if (isEdit) {\n <div class=\"float-end\"\n >\n <pw-edit-qualifications-modal (saveEvent)=\"getUserDetails()\">\n </pw-edit-qualifications-modal>\n </div>\n }\n </div>\n <div class=\"row\">\n @for (item of qualifications; track trackByQualification($index, item)) {\n <div class=\"col-lg-6 col-12 mb-4\"\n [ngClass]=\"{ editable: isEdit }\"\n >\n <div class=\"mb-2\">\n <div class=\"float-start\">\n <h4>{{ item?.school }}</h4>\n <ul class=\"no-list-style\">\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-clock font-small-3\" aria-hidden=\"true\"></i>\n Period:</span>\n <span class=\"display-block overflow-hidden pt-2\">\n {{ item?.started_on }} - {{ item?.ended_on }}\n </span>\n </li>\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-feather font-small-3\" aria-hidden=\"true\"></i>\n Degree:</span>\n <span class=\"display-block overflow-hidden pt-2\">\n {{ item?.degree }}\n </span>\n </li>\n <li class=\"mb-4\">\n <span class=\"profile-label\"><i class=\"ft-octagon font-small-3\" aria-hidden=\"true\"></i>\n Course:</span>\n <span class=\"display-block overflow-hidden pt-2\">\n {{ item?.course }}\n </span>\n </li>\n </ul>\n </div>\n @if (isEdit) {\n <div class=\"float-end action\"\n >\n <span class=\"fa-stack\">\n <i\n class=\"fa fa-lg fa-edit fa-stack-1x me-3 profile-icons\"\n title=\"Edit\"\n (keydown.enter)=\"editQualification(item)\"\n aria-label=\"Edit Qualification\"\n (click)=\"editQualification(item)\"\n aria-hidden=\"true\"\n ></i>\n </span>\n <span class=\"fa-stack\">\n <i\n class=\"fa fa-lg fa-trash fa-stack-1x delete-icon\"\n data-cy=\"delete-qualification\"\n title=\"Delete\"\n aria-label=\"Delete Qualification\"\n (keydown.enter)=\"deleteQualification(item)\"\n (click)=\"deleteQualification(item)\"\n aria-hidden=\"true\"\n ></i>\n </span>\n </div>\n }\n </div>\n</div>\n}\n@if (qualifications && qualifications.length === 0) {\n <div class=\"col-lg-6 col-12 mb-4\"\n >\n {{\n isEdit\n ? ' No qualification yet. Please add some.'\n : 'No qualifications added.'\n }}\n </div>\n}\n</div>\n</div>\n<hr />\n<!-- External Portfolio -->\n<div data-cy=\"portfolio-info\"\n class=\"mt-4\">\n <div class=\"\">\n <h2 class=\"\">External Portfolio</h2>\n @if (isEdit) {\n <i\n class=\"fa fa-lg fa-edit profile-icons float-end mt-3 pt-1 pt-md-0\"\n (click)=\"onOpenSocial()\"\n aria-label=\"Edit external portfolio\"\n (keydown)=\"($event.key === 'Enter' ? onOpenSocial() : null)\"\n title=\"Edit External Portfolio\"\n ></i>\n }\n </div>\n <div class=\"row\">\n <div class=\"col-md-6 col-12 mb-4\">\n @if (userLinks) {\n <div>\n @for (link of objectKeys(userLinks); track link) {\n @if (userLinks[link]) {\n <a target=\"_blank\"\n rel=\"noopener noreferrer\"\n [href]=\"userLinks[link]\"\n >\n <img src=\"assets/img/icons/social/{{ link }}.svg\"\n class=\"me-2\"\n width=\"40\"\n alt=\"\" />\n </a>\n }\n }\n </div>\n }\n <div class=\"row\">\n @if (user) {\n <pw-edit-social-links [userId]=\"user.id\"\n [links]=\"userLinks\"\n (saveEvent)=\"onSaveUserLinks()\">\n </pw-edit-social-links>\n }\n @if (!noUserLinks) {\n <div class=\"col-12 mb-4\"\n >\n {{\n isEdit\n ? 'No external portfolio yet. Please add some.'\n : 'No portfolio added.'\n }}\n </div>\n }\n </div>\n </div>\n </div>\n</div>\n</div>\n</div>\n@if (loading) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n}\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.edu-card .action{display:none}.edu-card:hover .action{display:block}.profile-label{color:var(--first);font-weight:700;margin-right:15px}.profile-icons{color:var(--first)}.personal-info{margin-left:6%}@media only screen and (max-width:1024px){#about{font-size:.7rem}}\n"] }]
3225
+ args: [{ selector: 'pw-user-about', standalone: false, template: "<div class=\"about\">\n <!-- Personal Information -->\n <section class=\"about-section\" data-cy=\"personal-info\">\n <header class=\"about-section__head\">\n <span class=\"about-section__icon\"><i class=\"fa fa-user\" aria-hidden=\"true\"></i></span>\n <h2 class=\"about-section__title\">{{ 'User.Profile.About.PersonalInfo' | transloco }}</h2>\n @if (user && isEdit) {\n <button type=\"button\" class=\"about-section__edit\" (click)=\"onProfileOpen()\" [attr.aria-label]=\"'User.Profile.About.EditPersonalInfo' | transloco\">\n <i class=\"fa fa-pen\" aria-hidden=\"true\"></i>\n </button>\n }\n </header>\n <div class=\"about-bio\">\n <span class=\"about-field__label\">{{ 'User.Profile.About.AboutMe' | transloco }}</span>\n <p class=\"about-bio__text\" [class.is-empty]=\"!user_profile?.description\">\n {{ user_profile?.description || ('User.Profile.About.NoDescription' | transloco) }}\n </p>\n </div>\n <dl class=\"about-grid\">\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.Birthday' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!user_profile?.dob\">{{ (user_profile?.dob | dateFormat) || '\u2014' }}</dd>\n </div>\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.LivesIn' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!user_profile?.country\">{{ user_profile?.country || '\u2014' }}</dd>\n </div>\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.Gender' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!user_profile?.gender\">\n {{\n user_profile?.gender === 'M'\n ? ('User.Profile.About.Male' | transloco)\n : user_profile?.gender === 'F'\n ? ('User.Profile.About.Female' | transloco)\n : '\u2014'\n }}\n </dd>\n </div>\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.Email' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!user?.email\">\n @if (user?.email) {\n <a class=\"about-field__link\" [href]=\"'mailto:' + user.email\">{{ user.email }}</a>\n } @else {\n \u2014\n }\n </dd>\n </div>\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.PhoneNumber' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!user_profile?.phone_number\">{{ user_profile?.phone_number || '\u2014' }}</dd>\n </div>\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.Website' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!user_profile?.website_url\">\n @if (user_profile?.website_url) {\n <a class=\"about-field__link\" target=\"_blank\" rel=\"noopener noreferrer\" [href]=\"user_profile.website_url\">{{ user_profile.website_url }}</a>\n } @else {\n \u2014\n }\n </dd>\n </div>\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.Joined' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!user?.joined_at\">{{ (user?.joined_at | dateFormat) || '\u2014' }}</dd>\n </div>\n </dl>\n @if (user && isEdit) {\n <pw-edit-user-profile-modal [user]=\"user\" (saveEvent)=\"onProfileSaved($event)\" [slug]=\"user?.slug\"></pw-edit-user-profile-modal>\n }\n </section>\n\n <!-- Skills -->\n <section class=\"about-section\" data-cy=\"skills-info\">\n <header class=\"about-section__head\">\n <span class=\"about-section__icon\"><i class=\"fa fa-bolt\" aria-hidden=\"true\"></i></span>\n <h2 class=\"about-section__title\">{{ 'User.Profile.About.Skills' | transloco }}</h2>\n @if (isEdit) {\n <button type=\"button\" class=\"about-section__edit\" (click)=\"openSkills()\" [attr.aria-label]=\"'User.Profile.About.EditSkills' | transloco\">\n <i class=\"fa fa-pen\" aria-hidden=\"true\"></i>\n </button>\n }\n </header>\n @if (selectedSkills?.length) {\n <div class=\"about-skills\">\n @for (skill of selectedSkills; track skill) {\n <div class=\"about-skills__group\">\n <span class=\"about-skills__category\">{{ skill.category_name }}</span>\n <div class=\"about-tags\">\n @for (item of skill.tags; track item) {\n <span class=\"about-tag\">{{ item.name }}</span>\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <p class=\"about-empty\">{{ (isEdit ? 'User.Profile.About.NoSkillsEdit' : 'User.Profile.About.NoSkills') | transloco }}</p>\n }\n @if (isEdit) {\n <pw-edit-skills-modal [userId]=\"user?.id\" [slug]=\"user?.slug\" (saveEvent)=\"getUserDetails()\"></pw-edit-skills-modal>\n }\n </section>\n\n <!-- Educational Information -->\n <section class=\"about-section\" data-cy=\"educational-info\">\n <header class=\"about-section__head\">\n <span class=\"about-section__icon\"><i class=\"fa fa-graduation-cap\" aria-hidden=\"true\"></i></span>\n <h2 class=\"about-section__title\">{{ 'User.Profile.About.Education' | transloco }}</h2>\n @if (isEdit) {\n <button type=\"button\" class=\"about-section__edit\" (click)=\"qualificationModal.onOpen()\" [attr.aria-label]=\"'User.Profile.About.AddEducation' | transloco\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n </button>\n }\n </header>\n @if (qualifications?.length) {\n <div class=\"about-edu\">\n @for (item of qualifications; track trackByQualification($index, item)) {\n <article class=\"about-edu__item\">\n <div class=\"about-edu__main\">\n <h4 class=\"about-edu__school\">{{ item?.school }}</h4>\n <dl class=\"about-grid about-grid--compact\">\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.Period' | transloco }}</dt>\n <dd class=\"about-field__value\">{{ item?.started_on }} \u2013 {{ item?.ended_on }}</dd>\n </div>\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.Degree' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!item?.degree\">{{ item?.degree || '\u2014' }}</dd>\n </div>\n <div class=\"about-field\">\n <dt class=\"about-field__label\">{{ 'User.Profile.About.Course' | transloco }}</dt>\n <dd class=\"about-field__value\" [class.is-empty]=\"!item?.course\">{{ item?.course || '\u2014' }}</dd>\n </div>\n </dl>\n </div>\n @if (isEdit) {\n <div class=\"about-edu__actions\">\n <button type=\"button\" class=\"about-icon-btn\" [attr.aria-label]=\"'User.Profile.About.EditEducation' | transloco\" (click)=\"editQualification(item)\">\n <i class=\"fa fa-pen\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"about-icon-btn about-icon-btn--danger\" data-cy=\"delete-qualification\" [attr.aria-label]=\"'User.Profile.About.DeleteEducation' | transloco\" (click)=\"deleteQualification(item)\">\n <i class=\"fa fa-trash\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n </article>\n }\n </div>\n } @else {\n <p class=\"about-empty\">{{ 'User.Profile.About.NoEducation' | transloco }}</p>\n }\n @if (isEdit) {\n <pw-edit-qualifications-modal (saveEvent)=\"getUserDetails()\"></pw-edit-qualifications-modal>\n }\n </section>\n\n <!-- External Portfolio -->\n <section class=\"about-section\" data-cy=\"portfolio-info\">\n <header class=\"about-section__head\">\n <span class=\"about-section__icon\"><i class=\"fa fa-link\" aria-hidden=\"true\"></i></span>\n <h2 class=\"about-section__title\">{{ 'User.Profile.About.Portfolio' | transloco }}</h2>\n @if (isEdit) {\n <button type=\"button\" class=\"about-section__edit\" (click)=\"onOpenSocial()\" [attr.aria-label]=\"'User.Profile.About.EditPortfolio' | transloco\">\n <i class=\"fa fa-pen\" aria-hidden=\"true\"></i>\n </button>\n }\n </header>\n @if (noUserLinks) {\n <div class=\"about-social\">\n @for (link of objectKeys(userLinks); track link) {\n @if (userLinks[link]) {\n <a class=\"about-social__link\" target=\"_blank\" rel=\"noopener noreferrer\" [href]=\"userLinks[link]\" [attr.aria-label]=\"link\">\n <img src=\"assets/img/icons/social/{{ link }}.svg\" width=\"32\" height=\"32\" [alt]=\"link\" />\n </a>\n }\n }\n </div>\n } @else {\n <p class=\"about-empty\">{{ 'User.Profile.About.NoPortfolio' | transloco }}</p>\n }\n @if (user && isEdit) {\n <pw-edit-social-links [userId]=\"user.id\" [links]=\"userLinks\" (saveEvent)=\"onSaveUserLinks()\"></pw-edit-social-links>\n }\n </section>\n\n @if (loading) {\n <div class=\"w-100 text-center p-3\"><p-progressSpinner strokeWidth=\"2\"></p-progressSpinner></div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.about{display:flex;flex-direction:column;gap:16px}.about-section{background:#fff;border:1px solid #e2e5ea;border-radius:8px;padding:20px 24px;float:none}.about-section ::ng-deep .pi-plus-circle{display:none}.about-section__head{display:flex;align-items:center;margin-bottom:18px;float:none}.about-section__icon{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;margin-right:12px;border-radius:8px;background:#f7f8fa;color:#5a6473;font-size:.95rem;flex-shrink:0}.about-section__title{margin:0!important;padding:0!important}.about-section__edit{margin-left:auto}.about-field__label,.about-skills__category{margin:0;font-size:1rem;font-weight:600;letter-spacing:.03em;text-transform:uppercase;color:#7c8696}.about-section__edit,.about-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:1px solid #e2e5ea;border-radius:7px;background:#fff;color:#5a6473;font-size:.9rem;cursor:pointer;transition:all .12s ease-out}.about-section__edit:hover,.about-icon-btn:hover{background:#f7f8fa;color:#1a1d21;border-color:#cfd4dc}.about-empty{margin:0;color:#7c8696;font-size:1.2rem}.about-bio{margin-bottom:22px}.about-bio__text{margin:6px 0 0;color:#1a1d21;font-size:1.25rem;line-height:1.55}.about-bio__text.is-empty{color:#7c8696;font-size:1.2rem}.about-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:20px 28px;margin:0}.about-grid--compact{gap:14px 24px}.about-field{display:flex;flex-direction:column;gap:5px;min-width:0}.about-field__value{margin:0;font-size:1.15rem;color:#1a1d21;word-break:break-word}.about-field__value.is-empty{color:#cfd4dc}.about-field__link{color:var(--first);text-decoration:none}.about-field__link:hover{text-decoration:underline}.about-skills{display:flex;flex-direction:column;gap:16px}.about-skills__group{display:flex;flex-direction:column;gap:8px}.about-tags{display:flex;flex-wrap:wrap;gap:8px}.about-tag{display:inline-flex;align-items:center;padding:5px 13px;border:1px solid #e2e5ea;border-radius:9999px;background:#eef0f3;color:#3d4654;font-size:1.05rem;font-weight:500;line-height:1.4}.about-edu{display:flex;flex-direction:column;gap:14px}.about-edu__item{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:16px;border:1px solid #e2e5ea;border-radius:8px;background:#f7f8fa}.about-edu__main{min-width:0;flex:1}.about-edu__school{margin:0 0 12px}.about-edu__actions{display:flex;gap:6px;flex-shrink:0}.about-icon-btn--danger:hover{color:#c0392b;border-color:#c0392b}.about-social{display:flex;flex-wrap:wrap;gap:14px}.about-social__link{display:inline-flex}\n"] }]
3229
3226
  }], ctorParameters: () => [{ type: i1$2.ProfileService }, { type: i1$2.QualificationService }, { type: i1$2.TagService }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }], propDecorators: { user: [{
3230
3227
  type: Input
3231
3228
  }], isEdit: [{
@@ -3368,11 +3365,11 @@ class UserProjectsComponent extends AppBaseComponent {
3368
3365
  });
3369
3366
  }
3370
3367
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserProjectsComponent, deps: [{ token: i1$2.ProfileService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
3371
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: UserProjectsComponent, isStandalone: false, selector: "pw-user-projects", inputs: { user: "user", isEdit: "isEdit", slug: "slug" }, viewQueries: [{ propertyName: "projectModal", first: true, predicate: EditProjectModalComponent, descendants: true, static: true }, { propertyName: "skillModal", first: true, predicate: EditSkillsModalComponent, descendants: true }, { propertyName: "recommendationModal", first: true, predicate: EditRecommendationModalComponent, descendants: true, static: true }, { propertyName: "portfolios", first: true, predicate: EditPortfoliosComponent, descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"row\">\n <div class=\"col-sm-12 mt-2\">\n <h2>User's Projects</h2>\n @if (isEdit) {\n <div class=\"row\"\n >\n <div class=\"col-12\">\n <div class=\"content-header\">\n <button class=\"btn btn-primary float-end\"\n (click)=\"onEditProject(null)\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> {{'Create Project' | transloco}}\n </button>\n </div>\n </div>\n </div>\n }\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (projects?.length) {\n <div id=\"timeline\"\n class=\"timeline-center timeline-wrapper\"\n >\n <ul class=\"timeline\">\n <li class=\"timeline-line\"></li>\n </ul>\n <ul class=\"timeline\">\n <li class=\"timeline-line\"></li>\n @for (\n project of projects; track trackByProject(i,\n project); let i = $index; let odd = $odd; let even = $even) {\n <li class=\"timeline-item\"\n [ngClass]=\"{ 'mt-5': odd }\"\n >\n <div class=\"timeline-badge\">\n <span class=\"bg-red bg-lighten-1\"\n data-bs-toggle=\"tooltip\"\n data-placement=\"right\"\n title=\"Portfolio project work\">\n <span class=\"timeline-year\"> {{ project.start_year }} </span>\n </span>\n </div>\n <div class=\"timeline-card card shadow rounded border-grey border-lighten-2 pb-0\">\n <div class=\"card-header\">\n <h4 class=\"mb-0 card-title\">\n <a>{{ project.title }}</a>\n </h4>\n <div class=\"card-subtitle text-muted mt-0\">\n <span class=\"font-small-3\">\n {{ project.start_year }} - {{ project.end_year }}</span>\n </div>\n </div>\n <div class=\"card-body project-card\">\n @if (project.project_pictures?.length) {\n <i\n class=\"fal fa-times\"\n (click)=\"deletePicture(project)\"\n (keydown.enter)=\"deletePicture(project)\"\n aria-hidden=\"true\"\n ></i>\n <img class=\"img-fluid project-picture\"\n [src]=\"project.project_pictures[0].picture.url\"\n alt=\"Project Cover\" />\n }\n <div class=\"card-body\">\n <div class=\"\">\n <p class=\"card-text\">{{ project.description }}</p>\n <div class=\"list-inline mb-1\">\n <!-- Skills -->\n @if (project.tags?.length) {\n <div>\n <div class=\"my-2\">\n <i class=\"fa fa-user-tag\" aria-hidden=\"true\"></i>\n Skills\n </div>\n @for (tag of project.tags; track tag) {\n <span class=\"badge bg-success me-2\">{{\n tag.name\n }}</span>\n }\n </div>\n }\n @if (project.project_recommendations?.length) {\n <div class=\"mt-2\"\n >\n <div class=\"my-2\">\n <i\n class=\"fa fa-clipboard-check me-2\"\n aria-hidden=\"true\"\n ></i>\n Recommendations\n </div>\n @for (\n recommendation of project.project_recommendations\n ; track\n recommendation) {\n <section class=\"mb-2\"\n >\n <div class=\"me-2\">\n Client: {{ recommendation?.client_name }}\n </div>\n <div class=\"me-2\">\n Message: {{ recommendation?.description }}\n </div>\n <div class=\"row recommendation\">\n <div class=\"col-4\">\n <span>Communication</span>\n <p-rating [(ngModel)]=\"\n recommendation.communication\n \"\n [cancel]=\"false\"\n [readonly]=\"true\">\n </p-rating>\n </div>\n <div class=\"col-4\">\n <span>Quality</span>\n <p-rating [(ngModel)]=\"recommendation.quality\"\n [cancel]=\"false\"\n [readonly]=\"true\">\n </p-rating>\n </div>\n <div class=\"col-4\">\n <span>Time</span>\n <p-rating [(ngModel)]=\"recommendation.time\"\n [cancel]=\"false\"\n [readonly]=\"true\">\n </p-rating>\n </div>\n </div>\n </section>\n }\n </div>\n }\n @if (isEdit) {\n <div class=\"text-end mt-3 d-flex justify-content-end project-actions\"\n >\n <!-- Project Edit -->\n <span class=\"btn btn-link pb-0 actions\"\n (keydown.enter)=\"onEditProject(project)\"\n (click)=\"onEditProject(project)\">\n Edit\n </span>\n <button class=\"btn btn-link pb-0 actions\"\n (click)=\"openSkills(project)\">\n Skills\n </button>\n <pw-edit-skills-modal [userId]=\"user?.id\"\n entityEntity=\"Project\"\n entityType=\"skills\"\n (saveEvent)=\"onSkillsSave()\"\n [slug]=\"project?.slug\">\n </pw-edit-skills-modal>\n <!-- Portfolios -->\n <button class=\"btn btn-link pb-0 actions\"\n (click)=\"openPortfolios(project.id)\">\n Photos\n </button>\n <pw-edit-portfolios [slug]=\"user?.slug\"\n [id]=\"project.id\"\n (successEvent)=\"getProjects()\">\n </pw-edit-portfolios>\n <span class=\"btn btn-link pb-0 delete-project actions\"\n (keydown.enter)=\"onDeleteProject(project)\"\n (click)=\"onDeleteProject(project)\">\n Delete\n </span>\n </div>\n }\n <!-- Recommendation -->\n @if (!isEdit) {\n <span class=\"pe-1 mt-3\"\n (click)=\"editRecommendation(project)\"\n (keydown.enter)=\"editRecommendation(project)\"\n >\n <a class=\"primary\"><span class=\"fa fa-commenting-o\"></span> Endorse\n </a></span>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n </li>\n }\n </ul>\n </div>\n }\n @if (projects?.length === 0 && isLoaded) {\n<pw-no-data [withImage]=\"true\" [message]=\"\n isEdit\n ? ('User.Profile.Projects.NoProjects' | transloco)\n : ('User.Profile.Projects.NoUserProjects' | transloco)\n \"\n >\n </pw-no-data>\n }\n </div>\n</div>\n<pw-edit-project-modal (saveEvent)=\"onSaveProject($event)\"></pw-edit-project-modal>\n<pw-edit-recommendation-modal [user]=\"user\"></pw-edit-recommendation-modal>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.project-card{position:relative}.project-card i.fa-times{color:#fff;display:none;font-size:20px;position:absolute;right:39px;top:14px}.project-card:hover i.fa-times{display:inline}.timeline-card.card{min-height:auto}.timeline-card.card .card-header{padding:1.5rem 1.5rem 0}.timeline-card.card .card-body.project-card{padding:0 20px 1rem}.timeline-card.card .card-body.project-card .card-body{padding:20px 0 0}@media only screen and (max-width:767px){.timeline-center{margin-top:30px}.timeline-center .project-actions .btn{padding:.375rem .5rem}}.actions{color:var(--first)!important}\n"], dependencies: [{ kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i5.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "component", type: i6$6.Rating, selector: "p-rating", inputs: ["readonly", "stars", "iconOnClass", "iconOnStyle", "iconOffClass", "iconOffStyle", "autofocus"], outputs: ["onRate", "onFocus", "onBlur"] }, { kind: "component", type: EditPortfoliosComponent, selector: "pw-edit-portfolios", inputs: ["id", "slug"], outputs: ["successEvent"] }, { kind: "component", type: EditProjectModalComponent, selector: "pw-edit-project-modal", outputs: ["cancelEvent", "saveEvent"] }, { kind: "component", type: EditRecommendationModalComponent, selector: "pw-edit-recommendation-modal", inputs: ["user"] }, { kind: "component", type: EditSkillsModalComponent, selector: "pw-edit-skills-modal", inputs: ["userId", "slug", "entityType", "entityEntity"], outputs: ["saveEvent"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
3368
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: UserProjectsComponent, isStandalone: false, selector: "pw-user-projects", inputs: { user: "user", isEdit: "isEdit", slug: "slug" }, viewQueries: [{ propertyName: "projectModal", first: true, predicate: EditProjectModalComponent, descendants: true, static: true }, { propertyName: "skillModal", first: true, predicate: EditSkillsModalComponent, descendants: true }, { propertyName: "recommendationModal", first: true, predicate: EditRecommendationModalComponent, descendants: true, static: true }, { propertyName: "portfolios", first: true, predicate: EditPortfoliosComponent, descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"row\">\n <div class=\"col-sm-12 mt-2\">\n <h2>User's Projects</h2>\n @if (isEdit) {\n <div class=\"row\"\n >\n <div class=\"col-12\">\n <div class=\"content-header\">\n <button class=\"btn btn-primary float-end\"\n (click)=\"onEditProject(null)\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> {{'Create Project' | transloco}}\n </button>\n </div>\n </div>\n </div>\n }\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (projects?.length) {\n <div id=\"timeline\"\n class=\"timeline-center timeline-wrapper\"\n >\n <ul class=\"timeline\">\n <li class=\"timeline-line\"></li>\n </ul>\n <ul class=\"timeline\">\n <li class=\"timeline-line\"></li>\n @for (\n project of projects; track trackByProject(i,\n project); let i = $index; let odd = $odd; let even = $even) {\n <li class=\"timeline-item\"\n [ngClass]=\"{ 'mt-5': odd }\"\n >\n <div class=\"timeline-badge\">\n <span class=\"bg-red bg-lighten-1\"\n data-bs-toggle=\"tooltip\"\n data-placement=\"right\"\n title=\"Portfolio project work\">\n <span class=\"timeline-year\"> {{ project.start_year }} </span>\n </span>\n </div>\n <div class=\"timeline-card card pb-0\">\n <div class=\"card-header\">\n <h4 class=\"mb-0 card-title\">\n <a>{{ project.title }}</a>\n </h4>\n <div class=\"card-subtitle text-muted mt-0\">\n <span class=\"font-small-3\">\n {{ project.start_year }} - {{ project.end_year }}</span>\n </div>\n </div>\n <div class=\"card-body project-card\">\n @if (project.project_pictures?.length) {\n <i\n class=\"fal fa-times\"\n (click)=\"deletePicture(project)\"\n (keydown.enter)=\"deletePicture(project)\"\n aria-hidden=\"true\"\n ></i>\n <img class=\"img-fluid project-picture\"\n [src]=\"project.project_pictures[0].picture.url\"\n alt=\"Project Cover\" />\n }\n <div class=\"card-body\">\n <div class=\"\">\n <p class=\"card-text\">{{ project.description }}</p>\n <div class=\"list-inline mb-1\">\n <!-- Skills -->\n @if (project.tags?.length) {\n <div>\n <div class=\"my-2\">\n <i class=\"fa fa-user-tag\" aria-hidden=\"true\"></i>\n Skills\n </div>\n @for (tag of project.tags; track tag) {\n <span class=\"badge bg-success me-2\">{{\n tag.name\n }}</span>\n }\n </div>\n }\n @if (project.project_recommendations?.length) {\n <div class=\"mt-2\"\n >\n <div class=\"my-2\">\n <i\n class=\"fa fa-clipboard-check me-2\"\n aria-hidden=\"true\"\n ></i>\n Recommendations\n </div>\n @for (\n recommendation of project.project_recommendations\n ; track\n recommendation) {\n <section class=\"mb-2\"\n >\n <div class=\"me-2\">\n Client: {{ recommendation?.client_name }}\n </div>\n <div class=\"me-2\">\n Message: {{ recommendation?.description }}\n </div>\n <div class=\"row recommendation\">\n <div class=\"col-4\">\n <span>Communication</span>\n <p-rating [(ngModel)]=\"\n recommendation.communication\n \"\n [cancel]=\"false\"\n [readonly]=\"true\">\n </p-rating>\n </div>\n <div class=\"col-4\">\n <span>Quality</span>\n <p-rating [(ngModel)]=\"recommendation.quality\"\n [cancel]=\"false\"\n [readonly]=\"true\">\n </p-rating>\n </div>\n <div class=\"col-4\">\n <span>Time</span>\n <p-rating [(ngModel)]=\"recommendation.time\"\n [cancel]=\"false\"\n [readonly]=\"true\">\n </p-rating>\n </div>\n </div>\n </section>\n }\n </div>\n }\n @if (isEdit) {\n <div class=\"text-end mt-3 d-flex justify-content-end project-actions\"\n >\n <!-- Project Edit -->\n <span class=\"btn btn-link pb-0 actions\"\n (keydown.enter)=\"onEditProject(project)\"\n (click)=\"onEditProject(project)\">\n Edit\n </span>\n <button class=\"btn btn-link pb-0 actions\"\n (click)=\"openSkills(project)\">\n Skills\n </button>\n <pw-edit-skills-modal [userId]=\"user?.id\"\n entityEntity=\"Project\"\n entityType=\"skills\"\n (saveEvent)=\"onSkillsSave()\"\n [slug]=\"project?.slug\">\n </pw-edit-skills-modal>\n <!-- Portfolios -->\n <button class=\"btn btn-link pb-0 actions\"\n (click)=\"openPortfolios(project.id)\">\n Photos\n </button>\n <pw-edit-portfolios [slug]=\"user?.slug\"\n [id]=\"project.id\"\n (successEvent)=\"getProjects()\">\n </pw-edit-portfolios>\n <span class=\"btn btn-link pb-0 delete-project actions\"\n (keydown.enter)=\"onDeleteProject(project)\"\n (click)=\"onDeleteProject(project)\">\n Delete\n </span>\n </div>\n }\n <!-- Recommendation -->\n @if (!isEdit) {\n <span class=\"pe-1 mt-3\"\n (click)=\"editRecommendation(project)\"\n (keydown.enter)=\"editRecommendation(project)\"\n >\n <a class=\"primary\"><span class=\"fa fa-commenting-o\"></span> Endorse\n </a></span>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n </li>\n }\n </ul>\n </div>\n }\n @if (projects?.length === 0 && isLoaded) {\n<pw-no-data [withImage]=\"true\" [message]=\"\n isEdit\n ? ('User.Profile.Projects.NoProjects' | transloco)\n : ('User.Profile.Projects.NoUserProjects' | transloco)\n \"\n >\n </pw-no-data>\n }\n </div>\n</div>\n<pw-edit-project-modal (saveEvent)=\"onSaveProject($event)\"></pw-edit-project-modal>\n<pw-edit-recommendation-modal [user]=\"user\"></pw-edit-recommendation-modal>\n", styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.project-card{position:relative}.project-card i.fa-times{color:#fff;display:none;font-size:20px;position:absolute;right:39px;top:14px}.project-card:hover i.fa-times{display:inline}.timeline-card.card{min-height:auto;border:1px solid #e2e5ea;border-radius:10px;box-shadow:0 1px 2px #1018280f}.timeline-card.card .card-header{padding:14px 16px 6px}.timeline-card.card .badge.bg-success{border-radius:9999px;background-color:#e7f5ee!important;color:#1f7a47!important;border:1px solid #c9e9d6;font-weight:600}.timeline-card.card .card-body.project-card{padding:0 20px 1rem}.timeline-card.card .card-body.project-card .card-body{padding:20px 0 0}@media only screen and (max-width:767px){.timeline-center{margin-top:30px}.timeline-center .project-actions .btn{padding:.375rem .5rem}}.actions{color:var(--first)!important}.timeline-badge .bg-red.bg-lighten-1{background-color:#eef0f3!important}.timeline-badge .bg-red.bg-lighten-1 .timeline-year{color:#3d4654}\n"], dependencies: [{ kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i5.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "component", type: i6$5.Rating, selector: "p-rating", inputs: ["readonly", "stars", "iconOnClass", "iconOnStyle", "iconOffClass", "iconOffStyle", "autofocus"], outputs: ["onRate", "onFocus", "onBlur"] }, { kind: "component", type: EditPortfoliosComponent, selector: "pw-edit-portfolios", inputs: ["id", "slug"], outputs: ["successEvent"] }, { kind: "component", type: EditProjectModalComponent, selector: "pw-edit-project-modal", outputs: ["cancelEvent", "saveEvent"] }, { kind: "component", type: EditRecommendationModalComponent, selector: "pw-edit-recommendation-modal", inputs: ["user"] }, { kind: "component", type: EditSkillsModalComponent, selector: "pw-edit-skills-modal", inputs: ["userId", "slug", "entityType", "entityEntity"], outputs: ["saveEvent"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
3372
3369
  }
3373
3370
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserProjectsComponent, decorators: [{
3374
3371
  type: Component,
3375
- args: [{ selector: 'pw-user-projects', standalone: false, template: "<div class=\"row\">\n <div class=\"col-sm-12 mt-2\">\n <h2>User's Projects</h2>\n @if (isEdit) {\n <div class=\"row\"\n >\n <div class=\"col-12\">\n <div class=\"content-header\">\n <button class=\"btn btn-primary float-end\"\n (click)=\"onEditProject(null)\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> {{'Create Project' | transloco}}\n </button>\n </div>\n </div>\n </div>\n }\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (projects?.length) {\n <div id=\"timeline\"\n class=\"timeline-center timeline-wrapper\"\n >\n <ul class=\"timeline\">\n <li class=\"timeline-line\"></li>\n </ul>\n <ul class=\"timeline\">\n <li class=\"timeline-line\"></li>\n @for (\n project of projects; track trackByProject(i,\n project); let i = $index; let odd = $odd; let even = $even) {\n <li class=\"timeline-item\"\n [ngClass]=\"{ 'mt-5': odd }\"\n >\n <div class=\"timeline-badge\">\n <span class=\"bg-red bg-lighten-1\"\n data-bs-toggle=\"tooltip\"\n data-placement=\"right\"\n title=\"Portfolio project work\">\n <span class=\"timeline-year\"> {{ project.start_year }} </span>\n </span>\n </div>\n <div class=\"timeline-card card shadow rounded border-grey border-lighten-2 pb-0\">\n <div class=\"card-header\">\n <h4 class=\"mb-0 card-title\">\n <a>{{ project.title }}</a>\n </h4>\n <div class=\"card-subtitle text-muted mt-0\">\n <span class=\"font-small-3\">\n {{ project.start_year }} - {{ project.end_year }}</span>\n </div>\n </div>\n <div class=\"card-body project-card\">\n @if (project.project_pictures?.length) {\n <i\n class=\"fal fa-times\"\n (click)=\"deletePicture(project)\"\n (keydown.enter)=\"deletePicture(project)\"\n aria-hidden=\"true\"\n ></i>\n <img class=\"img-fluid project-picture\"\n [src]=\"project.project_pictures[0].picture.url\"\n alt=\"Project Cover\" />\n }\n <div class=\"card-body\">\n <div class=\"\">\n <p class=\"card-text\">{{ project.description }}</p>\n <div class=\"list-inline mb-1\">\n <!-- Skills -->\n @if (project.tags?.length) {\n <div>\n <div class=\"my-2\">\n <i class=\"fa fa-user-tag\" aria-hidden=\"true\"></i>\n Skills\n </div>\n @for (tag of project.tags; track tag) {\n <span class=\"badge bg-success me-2\">{{\n tag.name\n }}</span>\n }\n </div>\n }\n @if (project.project_recommendations?.length) {\n <div class=\"mt-2\"\n >\n <div class=\"my-2\">\n <i\n class=\"fa fa-clipboard-check me-2\"\n aria-hidden=\"true\"\n ></i>\n Recommendations\n </div>\n @for (\n recommendation of project.project_recommendations\n ; track\n recommendation) {\n <section class=\"mb-2\"\n >\n <div class=\"me-2\">\n Client: {{ recommendation?.client_name }}\n </div>\n <div class=\"me-2\">\n Message: {{ recommendation?.description }}\n </div>\n <div class=\"row recommendation\">\n <div class=\"col-4\">\n <span>Communication</span>\n <p-rating [(ngModel)]=\"\n recommendation.communication\n \"\n [cancel]=\"false\"\n [readonly]=\"true\">\n </p-rating>\n </div>\n <div class=\"col-4\">\n <span>Quality</span>\n <p-rating [(ngModel)]=\"recommendation.quality\"\n [cancel]=\"false\"\n [readonly]=\"true\">\n </p-rating>\n </div>\n <div class=\"col-4\">\n <span>Time</span>\n <p-rating [(ngModel)]=\"recommendation.time\"\n [cancel]=\"false\"\n [readonly]=\"true\">\n </p-rating>\n </div>\n </div>\n </section>\n }\n </div>\n }\n @if (isEdit) {\n <div class=\"text-end mt-3 d-flex justify-content-end project-actions\"\n >\n <!-- Project Edit -->\n <span class=\"btn btn-link pb-0 actions\"\n (keydown.enter)=\"onEditProject(project)\"\n (click)=\"onEditProject(project)\">\n Edit\n </span>\n <button class=\"btn btn-link pb-0 actions\"\n (click)=\"openSkills(project)\">\n Skills\n </button>\n <pw-edit-skills-modal [userId]=\"user?.id\"\n entityEntity=\"Project\"\n entityType=\"skills\"\n (saveEvent)=\"onSkillsSave()\"\n [slug]=\"project?.slug\">\n </pw-edit-skills-modal>\n <!-- Portfolios -->\n <button class=\"btn btn-link pb-0 actions\"\n (click)=\"openPortfolios(project.id)\">\n Photos\n </button>\n <pw-edit-portfolios [slug]=\"user?.slug\"\n [id]=\"project.id\"\n (successEvent)=\"getProjects()\">\n </pw-edit-portfolios>\n <span class=\"btn btn-link pb-0 delete-project actions\"\n (keydown.enter)=\"onDeleteProject(project)\"\n (click)=\"onDeleteProject(project)\">\n Delete\n </span>\n </div>\n }\n <!-- Recommendation -->\n @if (!isEdit) {\n <span class=\"pe-1 mt-3\"\n (click)=\"editRecommendation(project)\"\n (keydown.enter)=\"editRecommendation(project)\"\n >\n <a class=\"primary\"><span class=\"fa fa-commenting-o\"></span> Endorse\n </a></span>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n </li>\n }\n </ul>\n </div>\n }\n @if (projects?.length === 0 && isLoaded) {\n<pw-no-data [withImage]=\"true\" [message]=\"\n isEdit\n ? ('User.Profile.Projects.NoProjects' | transloco)\n : ('User.Profile.Projects.NoUserProjects' | transloco)\n \"\n >\n </pw-no-data>\n }\n </div>\n</div>\n<pw-edit-project-modal (saveEvent)=\"onSaveProject($event)\"></pw-edit-project-modal>\n<pw-edit-recommendation-modal [user]=\"user\"></pw-edit-recommendation-modal>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.project-card{position:relative}.project-card i.fa-times{color:#fff;display:none;font-size:20px;position:absolute;right:39px;top:14px}.project-card:hover i.fa-times{display:inline}.timeline-card.card{min-height:auto}.timeline-card.card .card-header{padding:1.5rem 1.5rem 0}.timeline-card.card .card-body.project-card{padding:0 20px 1rem}.timeline-card.card .card-body.project-card .card-body{padding:20px 0 0}@media only screen and (max-width:767px){.timeline-center{margin-top:30px}.timeline-center .project-actions .btn{padding:.375rem .5rem}}.actions{color:var(--first)!important}\n"] }]
3372
+ args: [{ selector: 'pw-user-projects', standalone: false, template: "<div class=\"row\">\n <div class=\"col-sm-12 mt-2\">\n <h2>User's Projects</h2>\n @if (isEdit) {\n <div class=\"row\"\n >\n <div class=\"col-12\">\n <div class=\"content-header\">\n <button class=\"btn btn-primary float-end\"\n (click)=\"onEditProject(null)\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> {{'Create Project' | transloco}}\n </button>\n </div>\n </div>\n </div>\n }\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (projects?.length) {\n <div id=\"timeline\"\n class=\"timeline-center timeline-wrapper\"\n >\n <ul class=\"timeline\">\n <li class=\"timeline-line\"></li>\n </ul>\n <ul class=\"timeline\">\n <li class=\"timeline-line\"></li>\n @for (\n project of projects; track trackByProject(i,\n project); let i = $index; let odd = $odd; let even = $even) {\n <li class=\"timeline-item\"\n [ngClass]=\"{ 'mt-5': odd }\"\n >\n <div class=\"timeline-badge\">\n <span class=\"bg-red bg-lighten-1\"\n data-bs-toggle=\"tooltip\"\n data-placement=\"right\"\n title=\"Portfolio project work\">\n <span class=\"timeline-year\"> {{ project.start_year }} </span>\n </span>\n </div>\n <div class=\"timeline-card card pb-0\">\n <div class=\"card-header\">\n <h4 class=\"mb-0 card-title\">\n <a>{{ project.title }}</a>\n </h4>\n <div class=\"card-subtitle text-muted mt-0\">\n <span class=\"font-small-3\">\n {{ project.start_year }} - {{ project.end_year }}</span>\n </div>\n </div>\n <div class=\"card-body project-card\">\n @if (project.project_pictures?.length) {\n <i\n class=\"fal fa-times\"\n (click)=\"deletePicture(project)\"\n (keydown.enter)=\"deletePicture(project)\"\n aria-hidden=\"true\"\n ></i>\n <img class=\"img-fluid project-picture\"\n [src]=\"project.project_pictures[0].picture.url\"\n alt=\"Project Cover\" />\n }\n <div class=\"card-body\">\n <div class=\"\">\n <p class=\"card-text\">{{ project.description }}</p>\n <div class=\"list-inline mb-1\">\n <!-- Skills -->\n @if (project.tags?.length) {\n <div>\n <div class=\"my-2\">\n <i class=\"fa fa-user-tag\" aria-hidden=\"true\"></i>\n Skills\n </div>\n @for (tag of project.tags; track tag) {\n <span class=\"badge bg-success me-2\">{{\n tag.name\n }}</span>\n }\n </div>\n }\n @if (project.project_recommendations?.length) {\n <div class=\"mt-2\"\n >\n <div class=\"my-2\">\n <i\n class=\"fa fa-clipboard-check me-2\"\n aria-hidden=\"true\"\n ></i>\n Recommendations\n </div>\n @for (\n recommendation of project.project_recommendations\n ; track\n recommendation) {\n <section class=\"mb-2\"\n >\n <div class=\"me-2\">\n Client: {{ recommendation?.client_name }}\n </div>\n <div class=\"me-2\">\n Message: {{ recommendation?.description }}\n </div>\n <div class=\"row recommendation\">\n <div class=\"col-4\">\n <span>Communication</span>\n <p-rating [(ngModel)]=\"\n recommendation.communication\n \"\n [cancel]=\"false\"\n [readonly]=\"true\">\n </p-rating>\n </div>\n <div class=\"col-4\">\n <span>Quality</span>\n <p-rating [(ngModel)]=\"recommendation.quality\"\n [cancel]=\"false\"\n [readonly]=\"true\">\n </p-rating>\n </div>\n <div class=\"col-4\">\n <span>Time</span>\n <p-rating [(ngModel)]=\"recommendation.time\"\n [cancel]=\"false\"\n [readonly]=\"true\">\n </p-rating>\n </div>\n </div>\n </section>\n }\n </div>\n }\n @if (isEdit) {\n <div class=\"text-end mt-3 d-flex justify-content-end project-actions\"\n >\n <!-- Project Edit -->\n <span class=\"btn btn-link pb-0 actions\"\n (keydown.enter)=\"onEditProject(project)\"\n (click)=\"onEditProject(project)\">\n Edit\n </span>\n <button class=\"btn btn-link pb-0 actions\"\n (click)=\"openSkills(project)\">\n Skills\n </button>\n <pw-edit-skills-modal [userId]=\"user?.id\"\n entityEntity=\"Project\"\n entityType=\"skills\"\n (saveEvent)=\"onSkillsSave()\"\n [slug]=\"project?.slug\">\n </pw-edit-skills-modal>\n <!-- Portfolios -->\n <button class=\"btn btn-link pb-0 actions\"\n (click)=\"openPortfolios(project.id)\">\n Photos\n </button>\n <pw-edit-portfolios [slug]=\"user?.slug\"\n [id]=\"project.id\"\n (successEvent)=\"getProjects()\">\n </pw-edit-portfolios>\n <span class=\"btn btn-link pb-0 delete-project actions\"\n (keydown.enter)=\"onDeleteProject(project)\"\n (click)=\"onDeleteProject(project)\">\n Delete\n </span>\n </div>\n }\n <!-- Recommendation -->\n @if (!isEdit) {\n <span class=\"pe-1 mt-3\"\n (click)=\"editRecommendation(project)\"\n (keydown.enter)=\"editRecommendation(project)\"\n >\n <a class=\"primary\"><span class=\"fa fa-commenting-o\"></span> Endorse\n </a></span>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n </li>\n }\n </ul>\n </div>\n }\n @if (projects?.length === 0 && isLoaded) {\n<pw-no-data [withImage]=\"true\" [message]=\"\n isEdit\n ? ('User.Profile.Projects.NoProjects' | transloco)\n : ('User.Profile.Projects.NoUserProjects' | transloco)\n \"\n >\n </pw-no-data>\n }\n </div>\n</div>\n<pw-edit-project-modal (saveEvent)=\"onSaveProject($event)\"></pw-edit-project-modal>\n<pw-edit-recommendation-modal [user]=\"user\"></pw-edit-recommendation-modal>\n", styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.project-card{position:relative}.project-card i.fa-times{color:#fff;display:none;font-size:20px;position:absolute;right:39px;top:14px}.project-card:hover i.fa-times{display:inline}.timeline-card.card{min-height:auto;border:1px solid #e2e5ea;border-radius:10px;box-shadow:0 1px 2px #1018280f}.timeline-card.card .card-header{padding:14px 16px 6px}.timeline-card.card .badge.bg-success{border-radius:9999px;background-color:#e7f5ee!important;color:#1f7a47!important;border:1px solid #c9e9d6;font-weight:600}.timeline-card.card .card-body.project-card{padding:0 20px 1rem}.timeline-card.card .card-body.project-card .card-body{padding:20px 0 0}@media only screen and (max-width:767px){.timeline-center{margin-top:30px}.timeline-center .project-actions .btn{padding:.375rem .5rem}}.actions{color:var(--first)!important}.timeline-badge .bg-red.bg-lighten-1{background-color:#eef0f3!important}.timeline-badge .bg-red.bg-lighten-1 .timeline-year{color:#3d4654}\n"] }]
3376
3373
  }], ctorParameters: () => [{ type: i1$2.ProfileService }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }], propDecorators: { user: [{
3377
3374
  type: Input
3378
3375
  }], isEdit: [{
@@ -3586,11 +3583,11 @@ class UserProfilePageComponent extends AppBaseComponent {
3586
3583
  super.ngOnDestroy();
3587
3584
  }
3588
3585
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserProfilePageComponent, deps: [{ token: i0.Injector }, { token: i1$2.ProfileService }, { token: i1$1.NgbModal }, { token: i1$2.ScriptLoaderService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
3589
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: UserProfilePageComponent, isStandalone: false, selector: "pw-user-profile-page", usesInheritance: true, ngImport: i0, template: "<!-- User Profile Starts -->\n<!-- Basic User Details Starts -->\n@if (user) {\n <section id=\"user-profile\"\n >\n <div class=\"row\">\n <div class=\"col-12\">\n <div class=\"dashboard\">\n <div class=\"media row py-3 align-items-center\">\n <div class=\"col-3 col-sm-2\">\n <div class=\"align-self-center halfway-fab text-center\">\n <!-- User Avatar -->\n <a class=\"profile-image\">\n <img [src]=\"image\"\n width=\"100\"\n height=\"100\"\n class=\"rounded-circle img-border width-100\"\n alt=\"User Male\"\n (error)=\"handleImageError($event, 'assets/img/icons/male.png')\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\" />\n @if (allowEdit) {\n <div class=\"ms-4 ps-3 ms-sm-0 ps-sm-0 overlay\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\"\n >\n <div class=\"overlay-text\">\n <!-- Change Profile Pic -->\n <a aria-label=\"Navigate to Target\">\n {{ 'User.Profile.Change' | transloco }}\n </a>\n </div>\n </div>\n }\n </a>\n </div>\n </div>\n <div class=\"col-9 col-sm-5\">\n <div class=\"align-self-start halfway-fab ps-3 pt-2\">\n <div>\n @if (user?.last_name) {\n <strong class=\"font-medium-2 text-uppercase\"\n >\n {{\n user?.first_name\n ? user?.first_name + ' ' + user?.last_name\n : 'Update Profile'\n }}\n </strong>\n }\n @if (!user?.last_name) {\n <strong class=\"font-medium-2 text-uppercase\"\n >\n {{ user?.first_name ? user?.first_name : 'Update Profile' }}\n </strong>\n }\n <p class=\"font-small-4\">{{ userProfile?.headline }}</p>\n </div>\n </div>\n </div>\n <div class=\"col-12 col-sm-5\">\n @if (!allowEdit) {\n <div class=\"profile-cover-buttons\"\n >\n <div class=\"d-flex halfway-fab align-self-end\">\n <div class=\"text-end d-none d-sm-none d-md-none d-lg-block\">\n <button type=\"button\"\n (click)=\"followUser()\"\n class=\"btn btn-outline-primary btn-raised me-2\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n {{ isFollowing ? 'Following' : 'Follow' }}\n </button>\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-3\"\n (click)=\"sendMessageSlug()\">\n <i class=\"fa fa-mail-bulk\" aria-hidden=\"true\"></i> Message\n </button>\n </div>\n <div class=\"text-end d-block d-sm-block d-md-block d-lg-none\">\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-2\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-3\">\n <i class=\"fa fa-mail-bulk\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n </section>\n}\n<!-- Basic User Details Ends -->\n<section>\n <div class=\"container-fluid pw-tab overflow-hidden\">\n <p-tabs [value]=\"activeTabValue\" (valueChange)=\"onTabChange($event)\">\n <p-tablist>\n @for (item of items; track item) {\n <p-tab [value]=\"item.id\">\n @if (item.icon) {\n <i [class]=\"item.icon\" aria-hidden=\"true\"></i>\n }\n <span>{{ item.label }}</span>\n </p-tab>\n }\n </p-tablist>\n </p-tabs>\n <div class=\"dashboard\">\n <div class=\"dashboard-body\">\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (user && activeItem.id === 'about') {\n <pw-user-about [user]=\"user\"\n [isEdit]=\"allowEdit\"\n (saveEvent)=\"getUserBySlug()\">\n </pw-user-about>\n }\n @if (activeItem.id === 'projects') {\n <pw-user-projects [user]=\"user\"\n [slug]=\"slug\"\n [isEdit]=\"allowEdit\"></pw-user-projects>\n }\n @if (activeItem.id === 'portfolio') {\n <pw-portfolios [user]=\"user\"\n [isEdit]=\"allowEdit\"></pw-portfolios>\n }\n </div>\n </div>\n </div>\n</section>\n<ng-template #content\n let-modal>\n <div class=\"card m-0\">\n <div class=\"card-content\">\n <div class=\"card-title\">\n <h3 class=\"modal-title\">{{ 'User.Profile.ProfilePicture' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"card-header\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n aspectRatio=\"auto\"\n [userAvatar]=\"image\"\n (imageSelectionEvent)=\"onImageSelection($event)\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.card-body{padding:10px!important}.py-3{padding-top:4rem!important;padding-bottom:0rem!important}.overlay-text{margin-left:-19px;margin-top:5px;text-align:center}::ng-deep .pw-tab .p-tabs .p-tab.p-highlight,::ng-deep .pw-tab .p-tabs .p-tab[aria-selected=true]{background-color:#1769e1!important;box-shadow:none!important;color:#fff!important}::ng-deep .pw-tab .p-tabs .p-tab.p-highlight:hover,::ng-deep .pw-tab .p-tabs .p-tab[aria-selected=true]:hover{background-color:#1769e1!important;color:#fff!important}\n"], dependencies: [{ kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { kind: "component", type: i4$5.Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: i4$5.TabList, selector: "p-tablist" }, { kind: "component", type: i4$5.Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i9.ProfileImageCropperComponent, selector: "pw-image-cropper", inputs: ["aspectRatio", "dynamicData"], outputs: ["imageSelectionEvent", "closeEvent", "fileChangeEvent"] }, { kind: "component", type: UserAboutComponent, selector: "pw-user-about", inputs: ["user", "isEdit"], outputs: ["saveEvent"] }, { kind: "component", type: PortfoliosComponent, selector: "pw-portfolios", inputs: ["user", "isEdit"] }, { kind: "component", type: UserProjectsComponent, selector: "pw-user-projects", inputs: ["user", "isEdit", "slug"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
3586
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: UserProfilePageComponent, isStandalone: false, selector: "pw-user-profile-page", usesInheritance: true, ngImport: i0, template: "<!-- User Profile Starts -->\n<!-- Basic User Details Starts -->\n@if (user) {\n <section id=\"user-profile\"\n >\n <div class=\"row\">\n <div class=\"col-12\">\n <div class=\"dashboard\">\n <div class=\"media row py-3 align-items-center\">\n <div class=\"col-3 col-sm-2\">\n <div class=\"align-self-center halfway-fab text-center\">\n <!-- User Avatar -->\n <a class=\"profile-image\">\n <img [src]=\"image\"\n width=\"100\"\n height=\"100\"\n class=\"rounded-circle img-border width-100\"\n alt=\"User Male\"\n (error)=\"handleImageError($event, 'assets/img/icons/male.png')\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\" />\n @if (allowEdit) {\n <div class=\"overlay\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\"\n >\n <div class=\"overlay-text\">\n <!-- Change Profile Pic -->\n <a aria-label=\"Navigate to Target\">\n {{ 'User.Profile.Change' | transloco }}\n </a>\n </div>\n </div>\n }\n </a>\n </div>\n </div>\n <div class=\"col-9 col-sm-5\">\n <div class=\"align-self-start halfway-fab ps-3 pt-2\">\n <div>\n @if (user?.last_name) {\n <strong class=\"font-medium-2 text-uppercase\"\n >\n {{\n user?.first_name\n ? user?.first_name + ' ' + user?.last_name\n : 'Update Profile'\n }}\n </strong>\n }\n @if (!user?.last_name) {\n <strong class=\"font-medium-2 text-uppercase\"\n >\n {{ user?.first_name ? user?.first_name : 'Update Profile' }}\n </strong>\n }\n <p class=\"font-small-4\">{{ userProfile?.headline }}</p>\n </div>\n </div>\n </div>\n <div class=\"col-12 col-sm-5\">\n @if (!allowEdit) {\n <div class=\"profile-cover-buttons\"\n >\n <div class=\"d-flex halfway-fab align-self-end\">\n <div class=\"text-end d-none d-sm-none d-md-none d-lg-block\">\n <button type=\"button\"\n (click)=\"followUser()\"\n class=\"btn btn-outline-primary btn-raised me-2\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n {{ isFollowing ? 'Following' : 'Follow' }}\n </button>\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-3\"\n (click)=\"sendMessageSlug()\">\n <i class=\"fa fa-mail-bulk\" aria-hidden=\"true\"></i> Message\n </button>\n </div>\n <div class=\"text-end d-block d-sm-block d-md-block d-lg-none\">\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-2\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-3\">\n <i class=\"fa fa-mail-bulk\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n </section>\n}\n<!-- Basic User Details Ends -->\n<section>\n <div class=\"container-fluid pw-tab overflow-hidden\">\n <p-tabs [value]=\"activeTabValue\" (valueChange)=\"onTabChange($event)\">\n <p-tablist>\n @for (item of items; track item) {\n <p-tab [value]=\"item.id\">\n @if (item.icon) {\n <i [class]=\"item.icon\" aria-hidden=\"true\"></i>\n }\n <span>{{ item.label }}</span>\n </p-tab>\n }\n </p-tablist>\n </p-tabs>\n <div class=\"dashboard\">\n <div class=\"dashboard-body\">\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (user && activeItem.id === 'about') {\n <pw-user-about [user]=\"user\"\n [isEdit]=\"allowEdit\"\n (saveEvent)=\"getUserBySlug()\">\n </pw-user-about>\n }\n @if (activeItem.id === 'projects') {\n <pw-user-projects [user]=\"user\"\n [slug]=\"slug\"\n [isEdit]=\"allowEdit\"></pw-user-projects>\n }\n @if (activeItem.id === 'portfolio') {\n <pw-portfolios [user]=\"user\"\n [isEdit]=\"allowEdit\"></pw-portfolios>\n }\n </div>\n </div>\n </div>\n</section>\n<ng-template #content\n let-modal>\n <div class=\"card m-0\">\n <div class=\"card-content\">\n <div class=\"card-title\">\n <h3 class=\"modal-title\">{{ 'User.Profile.ProfilePicture' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"card-header\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n aspectRatio=\"auto\"\n [userAvatar]=\"image\"\n (imageSelectionEvent)=\"onImageSelection($event)\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.card-body{padding:10px!important}.py-3{padding-top:4rem!important;padding-bottom:0rem!important}.overlay-text{margin-top:5px;text-align:center}.profile-image img.rounded-circle{max-width:100%;height:auto;box-sizing:border-box}::ng-deep .pw-tab .p-tabs .p-tab.p-highlight,::ng-deep .pw-tab .p-tabs .p-tab[aria-selected=true]{background-color:#1769e1!important;box-shadow:none!important;color:#fff!important}::ng-deep .pw-tab .p-tabs .p-tab.p-highlight:hover,::ng-deep .pw-tab .p-tabs .p-tab[aria-selected=true]:hover{background-color:#1769e1!important;color:#fff!important}\n"], dependencies: [{ kind: "directive", type: i4.LazyImgDirective, selector: "img" }, { kind: "component", type: i4$5.Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: i4$5.TabList, selector: "p-tablist" }, { kind: "component", type: i4$5.Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i9.ProfileImageCropperComponent, selector: "pw-image-cropper", inputs: ["aspectRatio", "dynamicData"], outputs: ["imageSelectionEvent", "closeEvent", "fileChangeEvent"] }, { kind: "component", type: UserAboutComponent, selector: "pw-user-about", inputs: ["user", "isEdit"], outputs: ["saveEvent"] }, { kind: "component", type: PortfoliosComponent, selector: "pw-portfolios", inputs: ["user", "isEdit"] }, { kind: "component", type: UserProjectsComponent, selector: "pw-user-projects", inputs: ["user", "isEdit", "slug"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
3590
3587
  }
3591
3588
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserProfilePageComponent, decorators: [{
3592
3589
  type: Component,
3593
- args: [{ selector: 'pw-user-profile-page', standalone: false, template: "<!-- User Profile Starts -->\n<!-- Basic User Details Starts -->\n@if (user) {\n <section id=\"user-profile\"\n >\n <div class=\"row\">\n <div class=\"col-12\">\n <div class=\"dashboard\">\n <div class=\"media row py-3 align-items-center\">\n <div class=\"col-3 col-sm-2\">\n <div class=\"align-self-center halfway-fab text-center\">\n <!-- User Avatar -->\n <a class=\"profile-image\">\n <img [src]=\"image\"\n width=\"100\"\n height=\"100\"\n class=\"rounded-circle img-border width-100\"\n alt=\"User Male\"\n (error)=\"handleImageError($event, 'assets/img/icons/male.png')\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\" />\n @if (allowEdit) {\n <div class=\"ms-4 ps-3 ms-sm-0 ps-sm-0 overlay\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\"\n >\n <div class=\"overlay-text\">\n <!-- Change Profile Pic -->\n <a aria-label=\"Navigate to Target\">\n {{ 'User.Profile.Change' | transloco }}\n </a>\n </div>\n </div>\n }\n </a>\n </div>\n </div>\n <div class=\"col-9 col-sm-5\">\n <div class=\"align-self-start halfway-fab ps-3 pt-2\">\n <div>\n @if (user?.last_name) {\n <strong class=\"font-medium-2 text-uppercase\"\n >\n {{\n user?.first_name\n ? user?.first_name + ' ' + user?.last_name\n : 'Update Profile'\n }}\n </strong>\n }\n @if (!user?.last_name) {\n <strong class=\"font-medium-2 text-uppercase\"\n >\n {{ user?.first_name ? user?.first_name : 'Update Profile' }}\n </strong>\n }\n <p class=\"font-small-4\">{{ userProfile?.headline }}</p>\n </div>\n </div>\n </div>\n <div class=\"col-12 col-sm-5\">\n @if (!allowEdit) {\n <div class=\"profile-cover-buttons\"\n >\n <div class=\"d-flex halfway-fab align-self-end\">\n <div class=\"text-end d-none d-sm-none d-md-none d-lg-block\">\n <button type=\"button\"\n (click)=\"followUser()\"\n class=\"btn btn-outline-primary btn-raised me-2\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n {{ isFollowing ? 'Following' : 'Follow' }}\n </button>\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-3\"\n (click)=\"sendMessageSlug()\">\n <i class=\"fa fa-mail-bulk\" aria-hidden=\"true\"></i> Message\n </button>\n </div>\n <div class=\"text-end d-block d-sm-block d-md-block d-lg-none\">\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-2\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-3\">\n <i class=\"fa fa-mail-bulk\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n </section>\n}\n<!-- Basic User Details Ends -->\n<section>\n <div class=\"container-fluid pw-tab overflow-hidden\">\n <p-tabs [value]=\"activeTabValue\" (valueChange)=\"onTabChange($event)\">\n <p-tablist>\n @for (item of items; track item) {\n <p-tab [value]=\"item.id\">\n @if (item.icon) {\n <i [class]=\"item.icon\" aria-hidden=\"true\"></i>\n }\n <span>{{ item.label }}</span>\n </p-tab>\n }\n </p-tablist>\n </p-tabs>\n <div class=\"dashboard\">\n <div class=\"dashboard-body\">\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (user && activeItem.id === 'about') {\n <pw-user-about [user]=\"user\"\n [isEdit]=\"allowEdit\"\n (saveEvent)=\"getUserBySlug()\">\n </pw-user-about>\n }\n @if (activeItem.id === 'projects') {\n <pw-user-projects [user]=\"user\"\n [slug]=\"slug\"\n [isEdit]=\"allowEdit\"></pw-user-projects>\n }\n @if (activeItem.id === 'portfolio') {\n <pw-portfolios [user]=\"user\"\n [isEdit]=\"allowEdit\"></pw-portfolios>\n }\n </div>\n </div>\n </div>\n</section>\n<ng-template #content\n let-modal>\n <div class=\"card m-0\">\n <div class=\"card-content\">\n <div class=\"card-title\">\n <h3 class=\"modal-title\">{{ 'User.Profile.ProfilePicture' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"card-header\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n aspectRatio=\"auto\"\n [userAvatar]=\"image\"\n (imageSelectionEvent)=\"onImageSelection($event)\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.card-body{padding:10px!important}.py-3{padding-top:4rem!important;padding-bottom:0rem!important}.overlay-text{margin-left:-19px;margin-top:5px;text-align:center}::ng-deep .pw-tab .p-tabs .p-tab.p-highlight,::ng-deep .pw-tab .p-tabs .p-tab[aria-selected=true]{background-color:#1769e1!important;box-shadow:none!important;color:#fff!important}::ng-deep .pw-tab .p-tabs .p-tab.p-highlight:hover,::ng-deep .pw-tab .p-tabs .p-tab[aria-selected=true]:hover{background-color:#1769e1!important;color:#fff!important}\n"] }]
3590
+ args: [{ selector: 'pw-user-profile-page', standalone: false, template: "<!-- User Profile Starts -->\n<!-- Basic User Details Starts -->\n@if (user) {\n <section id=\"user-profile\"\n >\n <div class=\"row\">\n <div class=\"col-12\">\n <div class=\"dashboard\">\n <div class=\"media row py-3 align-items-center\">\n <div class=\"col-3 col-sm-2\">\n <div class=\"align-self-center halfway-fab text-center\">\n <!-- User Avatar -->\n <a class=\"profile-image\">\n <img [src]=\"image\"\n width=\"100\"\n height=\"100\"\n class=\"rounded-circle img-border width-100\"\n alt=\"User Male\"\n (error)=\"handleImageError($event, 'assets/img/icons/male.png')\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\" />\n @if (allowEdit) {\n <div class=\"overlay\"\n (keydown.enter)=\"openModal(content)\"\n (click)=\"openModal(content)\"\n >\n <div class=\"overlay-text\">\n <!-- Change Profile Pic -->\n <a aria-label=\"Navigate to Target\">\n {{ 'User.Profile.Change' | transloco }}\n </a>\n </div>\n </div>\n }\n </a>\n </div>\n </div>\n <div class=\"col-9 col-sm-5\">\n <div class=\"align-self-start halfway-fab ps-3 pt-2\">\n <div>\n @if (user?.last_name) {\n <strong class=\"font-medium-2 text-uppercase\"\n >\n {{\n user?.first_name\n ? user?.first_name + ' ' + user?.last_name\n : 'Update Profile'\n }}\n </strong>\n }\n @if (!user?.last_name) {\n <strong class=\"font-medium-2 text-uppercase\"\n >\n {{ user?.first_name ? user?.first_name : 'Update Profile' }}\n </strong>\n }\n <p class=\"font-small-4\">{{ userProfile?.headline }}</p>\n </div>\n </div>\n </div>\n <div class=\"col-12 col-sm-5\">\n @if (!allowEdit) {\n <div class=\"profile-cover-buttons\"\n >\n <div class=\"d-flex halfway-fab align-self-end\">\n <div class=\"text-end d-none d-sm-none d-md-none d-lg-block\">\n <button type=\"button\"\n (click)=\"followUser()\"\n class=\"btn btn-outline-primary btn-raised me-2\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n {{ isFollowing ? 'Following' : 'Follow' }}\n </button>\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-3\"\n (click)=\"sendMessageSlug()\">\n <i class=\"fa fa-mail-bulk\" aria-hidden=\"true\"></i> Message\n </button>\n </div>\n <div class=\"text-end d-block d-sm-block d-md-block d-lg-none\">\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-2\">\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\"\n class=\"btn btn-primary btn-raised me-3\">\n <i class=\"fa fa-mail-bulk\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n </section>\n}\n<!-- Basic User Details Ends -->\n<section>\n <div class=\"container-fluid pw-tab overflow-hidden\">\n <p-tabs [value]=\"activeTabValue\" (valueChange)=\"onTabChange($event)\">\n <p-tablist>\n @for (item of items; track item) {\n <p-tab [value]=\"item.id\">\n @if (item.icon) {\n <i [class]=\"item.icon\" aria-hidden=\"true\"></i>\n }\n <span>{{ item.label }}</span>\n </p-tab>\n }\n </p-tablist>\n </p-tabs>\n <div class=\"dashboard\">\n <div class=\"dashboard-body\">\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (user && activeItem.id === 'about') {\n <pw-user-about [user]=\"user\"\n [isEdit]=\"allowEdit\"\n (saveEvent)=\"getUserBySlug()\">\n </pw-user-about>\n }\n @if (activeItem.id === 'projects') {\n <pw-user-projects [user]=\"user\"\n [slug]=\"slug\"\n [isEdit]=\"allowEdit\"></pw-user-projects>\n }\n @if (activeItem.id === 'portfolio') {\n <pw-portfolios [user]=\"user\"\n [isEdit]=\"allowEdit\"></pw-portfolios>\n }\n </div>\n </div>\n </div>\n</section>\n<ng-template #content\n let-modal>\n <div class=\"card m-0\">\n <div class=\"card-content\">\n <div class=\"card-title\">\n <h3 class=\"modal-title\">{{ 'User.Profile.ProfilePicture' | transloco }}</h3>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"card-header\">\n <small> {{ 'User.Profile.PictureMessage' | transloco }}</small>\n <pw-image-cropper #profile\n aspectRatio=\"auto\"\n [userAvatar]=\"image\"\n (imageSelectionEvent)=\"onImageSelection($event)\"\n (closeEvent)=\"onClose()\">\n </pw-image-cropper>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.card-body{padding:10px!important}.py-3{padding-top:4rem!important;padding-bottom:0rem!important}.overlay-text{margin-top:5px;text-align:center}.profile-image img.rounded-circle{max-width:100%;height:auto;box-sizing:border-box}::ng-deep .pw-tab .p-tabs .p-tab.p-highlight,::ng-deep .pw-tab .p-tabs .p-tab[aria-selected=true]{background-color:#1769e1!important;box-shadow:none!important;color:#fff!important}::ng-deep .pw-tab .p-tabs .p-tab.p-highlight:hover,::ng-deep .pw-tab .p-tabs .p-tab[aria-selected=true]:hover{background-color:#1769e1!important;color:#fff!important}\n"] }]
3594
3591
  }], ctorParameters: () => [{ type: i0.Injector }, { type: i1$2.ProfileService }, { type: i1$1.NgbModal }, { type: i1$2.ScriptLoaderService }, { type: i0.ChangeDetectorRef }] });
3595
3592
 
3596
3593
  const primeNgModules = [
@@ -3601,7 +3598,8 @@ const primeNgModules = [
3601
3598
  FileUploadModule,
3602
3599
  SelectModule,
3603
3600
  RatingModule,
3604
- SelectButtonModule
3601
+ SelectButtonModule,
3602
+ TooltipModule
3605
3603
  ];
3606
3604
  const ngbModule = [NgbModalModule, NgbDatepickerModule];
3607
3605
  class UserModuleModule {
@@ -3650,7 +3648,8 @@ class UserModuleModule {
3650
3648
  FileUploadModule,
3651
3649
  SelectModule,
3652
3650
  RatingModule,
3653
- SelectButtonModule, NgbModalModule, NgbDatepickerModule], exports: [AccountComponent,
3651
+ SelectButtonModule,
3652
+ TooltipModule, NgbModalModule, NgbDatepickerModule], exports: [AccountComponent,
3654
3653
  AccountDetailsComponent,
3655
3654
  AddSubscriptionComponent,
3656
3655
  SavedCardDetailsComponent,