@posiwise/user-module 0.0.142 → 0.0.144
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$
|
|
19
|
+
import * as i6$5 from 'ngx-captcha';
|
|
20
20
|
import { NgxCaptchaModule } from 'ngx-captcha';
|
|
21
|
-
import * as i11
|
|
21
|
+
import * as i11 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,11 +31,11 @@ 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$
|
|
34
|
+
import * as i6$6 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
|
-
import * as i8 from 'primeng/selectbutton';
|
|
38
|
+
import * as i8$1 from 'primeng/selectbutton';
|
|
39
39
|
import { SelectButtonModule } from 'primeng/selectbutton';
|
|
40
40
|
import { Loader } from '@googlemaps/js-api-loader';
|
|
41
41
|
import * as i1$1 from '@ng-bootstrap/ng-bootstrap';
|
|
@@ -51,13 +51,13 @@ import { ValidateForm, clearQueryParams, appendQueryParam } from '@posiwise/util
|
|
|
51
51
|
import { StatusCodes } from 'http-status-codes';
|
|
52
52
|
import { map, from, forkJoin, interval } from 'rxjs';
|
|
53
53
|
import swal from 'sweetalert2';
|
|
54
|
-
import * as
|
|
54
|
+
import * as i8 from '@jsverse/transloco';
|
|
55
55
|
import cloneDeep from 'lodash/cloneDeep';
|
|
56
56
|
import sortBy from 'lodash/sortBy';
|
|
57
57
|
import { distinct, mergeMap } from 'rxjs/operators';
|
|
58
|
+
import * as i6$4 from 'primeng/tooltip';
|
|
58
59
|
import { GetUser, getUser } from '@posiwise/app-store';
|
|
59
60
|
import * as i4$2 from '@ngrx/store';
|
|
60
|
-
import * as i13 from 'primeng/tooltip';
|
|
61
61
|
import * as i5$1 from '@angular/cdk/clipboard';
|
|
62
62
|
import { HttpParams } from '@angular/common/http';
|
|
63
63
|
import * as i2$1 from '@posiwise/admin-module-utils';
|
|
@@ -473,7 +473,7 @@ class AccountDetailsComponent extends AppBaseComponent {
|
|
|
473
473
|
});
|
|
474
474
|
}
|
|
475
475
|
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.Subscriptions.APICredentials.AccessToken' | 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.Subscriptions.APICredentials.ClientId' | 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: i11.TranslocoPipe, name: "transloco" }] }); }
|
|
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.Subscriptions.APICredentials.AccessToken' | 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.Subscriptions.APICredentials.ClientId' | 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
477
|
}
|
|
478
478
|
__decorate([
|
|
479
479
|
ValidateForm('profileForm'),
|
|
@@ -564,7 +564,7 @@ class AddSubscriptionComponent extends AppBaseComponent {
|
|
|
564
564
|
super.ngOnDestroy();
|
|
565
565
|
}
|
|
566
566
|
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 }} / {{ product.billing_frequency }}\n </h5>\n }\n <h5 class=\"my-3\">\n Min\n {{product.min_units > 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 }} / {{ 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' }} / {{\n product.billing_frequency\n }} / 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:
|
|
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 }} / {{ product.billing_frequency }}\n </h5>\n }\n <h5 class=\"my-3\">\n Min\n {{product.min_units > 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 }} / {{ 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' }} / {{\n product.billing_frequency\n }} / 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
568
|
}
|
|
569
569
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AddSubscriptionComponent, decorators: [{
|
|
570
570
|
type: Component,
|
|
@@ -787,7 +787,7 @@ class SubscriptionCredentialComponent extends AppBaseComponent {
|
|
|
787
787
|
super.ngOnDestroy();
|
|
788
788
|
}
|
|
789
789
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SubscriptionCredentialComponent, deps: [{ token: i2.UntypedFormBuilder }, { token: i1$2.SubscriptionService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
790
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: SubscriptionCredentialComponent, isStandalone: false, selector: "pw-subscription-credential", viewQueries: [{ propertyName: "passwordValidationModalForRevealCredential", first: true, predicate: ["passwordValidationModalForRevealCredential"], descendants: true }, { propertyName: "passwordValidationModalForEditCredential", first: true, predicate: ["passwordValidationModalForEditCredential"], descendants: true }, { propertyName: "passwordValidationModalForAddCredential", first: true, predicate: ["passwordValidationModalForAddCredential"], descendants: true }], usesInheritance: true, ngImport: i0, template: "@if (showForm) {\n <div class=\"row\"\n >\n <div class=\"col-12 d-flex\">\n <a aria-label=\"Navigate to Target\"\n (click)=\"onCancel()\"\n (keydown.enter)=\"onCancel()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h3 class=\"m-subheader__title m-subheader__title--separator\">\n <span>{{ data.length ? 'Edit' : 'Create new' }} Credential</span>\n </h3>\n </div>\n </div>\n }\n @if (showForm) {\n <div class=\"container-fluid pw-tab\">\n <div class=\"p-2 mt-3\">\n <form>\n <div class=\"row mb-3\">\n @if (!isEdit && showForm) {\n <div class=\"col-12 col-md-4\"\n >\n <div class=\"mb-3\">\n <span id=\"subscription-credential-select-label\" class=\"pw-label-style\">Credential <span class=\"text-danger required-icon\">*</span> </span>\n <p-select\n [attr.aria-labelledby]=\"'subscription-credential-select-label'\"\n [options]=\"uniqueCredential\"\n [placeholder]=\"'Select credential'\"\n optionLabel=\"name\"\n optionValue=\"name\"\n (onChange)=\"selectedOption($event)\">\n </p-select>\n </div>\n </div>\n }\n @if (credentialsSelect?.length) {\n <div class=\"col-12 col-md-4\"\n >\n <div class=\"card pb-2 pt-2 overflow-visible\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <form [formGroup]=\"form\"\n novalidate\n (ngSubmit)=\"saveCredentials()\">\n <div formArrayName=\"credentials\">\n @for (\n credential of credentialsGroup.controls; track\n credential; let i = $index) {\n <div>\n <div [formGroupName]=\"i\">\n <div class=\"mb-3\">\n <pw-input-container label=\"{{\n credential.get('field').value\n }}\"\n [class.info-circle]=\"\n credential.get('description').value\n \"\n name=\"value\"\n errorMsg=\"Please enter value\">\n @if (\n credential.get('description')\n .value\n ) {\n <span\n class=\"tooltiptext gradient-custom-branding\">{{\n credential.get('description')\n .value\n }}</span>\n }\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"value\"\n [ngClass]=\"{\n 'is-invalid':\n submitted &&\n credential.get('value')\n .invalid\n }\" id=\"input_value_1\" name=\"input_value_1\"/>\n </pw-input-container>\n </div>\n </div>\n </div>\n }\n </div>\n <div class=\"text-end mt-3\">\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\">\n {{ 'Button.Submit' | transloco }}\n </button>\n </div>\n </form>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n <div class=\"row\">\n <div class=\"col-12 text-end mt-3\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"onCancel()\"\n (keydown.enter)=\"onCancel()\" >\n {{ 'Button.Back' | transloco }}\n </button>\n </div>\n </div>\n </form>\n </div>\n </div>\n }\n\n @if (!showForm) {\n <div class=\"row\">\n <div class=\"col-12 d-flex\">\n <a aria-label=\"Navigate to Target\"\n (click)=\"back()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h2 class=\"mt-3\">Credentials</h2>\n </div>\n <div class=\"col-12 col-md-12 text-end\">\n <button class=\"btn btn-sm btn-outline-primary\"\n (click)=\"openCredentialsForAdd()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> {{ 'Add Credential' }}\n </button>\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 <div class=\"row my-4\">\n @for (credential of credentials; track credential) {\n <div class=\"col-12 col-md-6 col-xl-4 mt-3 credential-cards\"\n >\n <div class=\"card\">\n <h2 class=\"credential-field mt-3\">{{ credential.credential_name }}</h2>\n @for (subscriptionCredential of credential.credentials; track subscriptionCredential) {\n <div class=\"card-content\"\n >\n <div class=\"card-header\">\n <div>\n <strong class=\"d-block\">{{ subscriptionCredential.field }}:</strong>\n <input class=\"credential-value\"\n [type]=\"\n credentialName === credential.credential_name\n ? 'text'\n : 'password'\n \"\n readonly\n #input\n [value]=\"subscriptionCredential?.value\" id=\"input_text_5520\" name=\"input_text_5520\" />\n </div>\n </div>\n <div class=\"card-footer\">\n <div class=\"float-end px-2\">\n @if (credentialName !== credential.credential_name) {\n <button class=\"btn btn-outline-primary me-2\"\n (click)=\"revealCredentials(credential)\">\n {{\n 'User.Subscriptions.SubscriptionCredentials.RevealCredential'\n | transloco\n }}\n </button>\n }\n @if (credentialName === credential.credential_name) {\n <button class=\"btn btn-outline-primary me-2\"\n (click)=\"hideCredentials()\">\n {{\n 'User.Subscriptions.SubscriptionCredentials.HideCredential'\n | transloco\n }}\n </button>\n }\n <a class=\"me-2 my-1\"\n aria-label=\"Edit Credential\"\n (click)=\"openCredentialsForEdit(credential.credential_name)\"><i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i></a>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n </div>\n @if (allSubscriptionCredentials?.length === 0 && isLoaded) {\n <div\n class=\"clearboth\">\n <pw-no-data [withImage]=\"true\" [message]=\"'User.Subscriptions.SubscriptionCredentials.NoDataMessage' | transloco\">\n </pw-no-data>\n </div>\n }\n }\n <!-- password validation modal for reveal Credential -->\n <pw-password-validation #passwordValidationModalForRevealCredential\n (successEvent)=\"showCredentials()\">\n </pw-password-validation>\n <!-- password validation modal for Edit Credential -->\n <pw-password-validation #passwordValidationModalForEditCredential\n (successEvent)=\"editCredentials()\">\n </pw-password-validation>\n <!-- password validation modal for Add Credential -->\n <pw-password-validation #passwordValidationModalForAddCredential\n (successEvent)=\"showEditForm()\">\n </pw-password-validation>\n", styles: [".credential-field{text-align:center}.card .card-header{padding:0 24px}.credentials-field{border:0}.credential-value{border:0;width:100%}.overflow-visible{overflow:visible}\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.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: i2.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i2.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { 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: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { 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: i5.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i11.TranslocoPipe, name: "transloco" }] }); }
|
|
790
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: SubscriptionCredentialComponent, isStandalone: false, selector: "pw-subscription-credential", viewQueries: [{ propertyName: "passwordValidationModalForRevealCredential", first: true, predicate: ["passwordValidationModalForRevealCredential"], descendants: true }, { propertyName: "passwordValidationModalForEditCredential", first: true, predicate: ["passwordValidationModalForEditCredential"], descendants: true }, { propertyName: "passwordValidationModalForAddCredential", first: true, predicate: ["passwordValidationModalForAddCredential"], descendants: true }], usesInheritance: true, ngImport: i0, template: "@if (showForm) {\n <div class=\"row\"\n >\n <div class=\"col-12 d-flex\">\n <a aria-label=\"Navigate to Target\"\n (click)=\"onCancel()\"\n (keydown.enter)=\"onCancel()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h3 class=\"m-subheader__title m-subheader__title--separator\">\n <span>{{ data.length ? 'Edit' : 'Create new' }} Credential</span>\n </h3>\n </div>\n </div>\n }\n @if (showForm) {\n <div class=\"container-fluid pw-tab\">\n <div class=\"p-2 mt-3\">\n <form>\n <div class=\"row mb-3\">\n @if (!isEdit && showForm) {\n <div class=\"col-12 col-md-4\"\n >\n <div class=\"mb-3\">\n <span id=\"subscription-credential-select-label\" class=\"pw-label-style\">Credential <span class=\"text-danger required-icon\">*</span> </span>\n <p-select\n [attr.aria-labelledby]=\"'subscription-credential-select-label'\"\n [options]=\"uniqueCredential\"\n [placeholder]=\"'Select credential'\"\n optionLabel=\"name\"\n optionValue=\"name\"\n (onChange)=\"selectedOption($event)\">\n </p-select>\n </div>\n </div>\n }\n @if (credentialsSelect?.length) {\n <div class=\"col-12 col-md-4\"\n >\n <div class=\"card pb-2 pt-2 overflow-visible\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <form [formGroup]=\"form\"\n novalidate\n (ngSubmit)=\"saveCredentials()\">\n <div formArrayName=\"credentials\">\n @for (\n credential of credentialsGroup.controls; track\n credential; let i = $index) {\n <div>\n <div [formGroupName]=\"i\">\n <div class=\"mb-3\">\n <pw-input-container label=\"{{\n credential.get('field').value\n }}\"\n [class.info-circle]=\"\n credential.get('description').value\n \"\n name=\"value\"\n errorMsg=\"Please enter value\">\n @if (\n credential.get('description')\n .value\n ) {\n <span\n class=\"tooltiptext gradient-custom-branding\">{{\n credential.get('description')\n .value\n }}</span>\n }\n <input type=\"text\"\n class=\"form-control\"\n formControlName=\"value\"\n [ngClass]=\"{\n 'is-invalid':\n submitted &&\n credential.get('value')\n .invalid\n }\" id=\"input_value_1\" name=\"input_value_1\"/>\n </pw-input-container>\n </div>\n </div>\n </div>\n }\n </div>\n <div class=\"text-end mt-3\">\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\">\n {{ 'Button.Submit' | transloco }}\n </button>\n </div>\n </form>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n <div class=\"row\">\n <div class=\"col-12 text-end mt-3\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"onCancel()\"\n (keydown.enter)=\"onCancel()\" >\n {{ 'Button.Back' | transloco }}\n </button>\n </div>\n </div>\n </form>\n </div>\n </div>\n }\n\n @if (!showForm) {\n <div class=\"row\">\n <div class=\"col-12 d-flex\">\n <a aria-label=\"Navigate to Target\"\n (click)=\"back()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h2 class=\"mt-3\">Credentials</h2>\n </div>\n <div class=\"col-12 col-md-12 text-end\">\n <button class=\"btn btn-sm btn-outline-primary\"\n (click)=\"openCredentialsForAdd()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> {{ 'Add Credential' }}\n </button>\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 <div class=\"row my-4\">\n @for (credential of credentials; track credential) {\n <div class=\"col-12 col-md-6 col-xl-4 mt-3 credential-cards\"\n >\n <div class=\"card\">\n <h2 class=\"credential-field mt-3\">{{ credential.credential_name }}</h2>\n @for (subscriptionCredential of credential.credentials; track subscriptionCredential) {\n <div class=\"card-content\"\n >\n <div class=\"card-header\">\n <div>\n <strong class=\"d-block\">{{ subscriptionCredential.field }}:</strong>\n <input class=\"credential-value\"\n [type]=\"\n credentialName === credential.credential_name\n ? 'text'\n : 'password'\n \"\n readonly\n #input\n [value]=\"subscriptionCredential?.value\" id=\"input_text_5520\" name=\"input_text_5520\" />\n </div>\n </div>\n <div class=\"card-footer\">\n <div class=\"float-end px-2\">\n @if (credentialName !== credential.credential_name) {\n <button class=\"btn btn-outline-primary me-2\"\n (click)=\"revealCredentials(credential)\">\n {{\n 'User.Subscriptions.SubscriptionCredentials.RevealCredential'\n | transloco\n }}\n </button>\n }\n @if (credentialName === credential.credential_name) {\n <button class=\"btn btn-outline-primary me-2\"\n (click)=\"hideCredentials()\">\n {{\n 'User.Subscriptions.SubscriptionCredentials.HideCredential'\n | transloco\n }}\n </button>\n }\n <a class=\"me-2 my-1\"\n aria-label=\"Edit Credential\"\n (click)=\"openCredentialsForEdit(credential.credential_name)\"><i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i></a>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n </div>\n @if (allSubscriptionCredentials?.length === 0 && isLoaded) {\n <div\n class=\"clearboth\">\n <pw-no-data [withImage]=\"true\" [message]=\"'User.Subscriptions.SubscriptionCredentials.NoDataMessage' | transloco\">\n </pw-no-data>\n </div>\n }\n }\n <!-- password validation modal for reveal Credential -->\n <pw-password-validation #passwordValidationModalForRevealCredential\n (successEvent)=\"showCredentials()\">\n </pw-password-validation>\n <!-- password validation modal for Edit Credential -->\n <pw-password-validation #passwordValidationModalForEditCredential\n (successEvent)=\"editCredentials()\">\n </pw-password-validation>\n <!-- password validation modal for Add Credential -->\n <pw-password-validation #passwordValidationModalForAddCredential\n (successEvent)=\"showEditForm()\">\n </pw-password-validation>\n", styles: [".credential-field{text-align:center}.card .card-header{padding:0 24px}.credentials-field{border:0}.credential-value{border:0;width:100%}.overflow-visible{overflow:visible}\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.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: i2.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i2.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { 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: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { 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: i5.NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
|
|
791
791
|
}
|
|
792
792
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SubscriptionCredentialComponent, decorators: [{
|
|
793
793
|
type: Component,
|
|
@@ -803,6 +803,72 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
|
|
|
803
803
|
args: ['passwordValidationModalForAddCredential', { static: false }]
|
|
804
804
|
}] } });
|
|
805
805
|
|
|
806
|
+
/**
|
|
807
|
+
* Thin wrapper around the Braintree Web Drop-in script.
|
|
808
|
+
* Mounts a Drop-in instance into a host DOM element and resolves the
|
|
809
|
+
* payment_method_nonce on submit. Loaded as a CDN script (mirrors the Stripe
|
|
810
|
+
* pattern in the same component) — see UpdatePaymentDetailsComponent.
|
|
811
|
+
*/
|
|
812
|
+
const DROPIN_CDN_URL = 'https://js.braintreegateway.com/web/dropin/1.43.0/js/dropin.min.js';
|
|
813
|
+
class BraintreeDropinHelper {
|
|
814
|
+
constructor() {
|
|
815
|
+
this.dropinInstance = null;
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Loads the Drop-in script into <head> if not already present, then mounts
|
|
819
|
+
* a Drop-in instance bound to clientToken into the host element.
|
|
820
|
+
*/
|
|
821
|
+
async mount(host, clientToken) {
|
|
822
|
+
await this.ensureScriptLoaded();
|
|
823
|
+
await this.teardown();
|
|
824
|
+
this.dropinInstance = await braintree.dropin.create({
|
|
825
|
+
authorization: clientToken,
|
|
826
|
+
container: host
|
|
827
|
+
});
|
|
828
|
+
}
|
|
829
|
+
async requestNonce() {
|
|
830
|
+
if (!this.dropinInstance) {
|
|
831
|
+
throw new Error('braintree_dropin_not_mounted');
|
|
832
|
+
}
|
|
833
|
+
const result = await this.dropinInstance.requestPaymentMethod();
|
|
834
|
+
return result.nonce;
|
|
835
|
+
}
|
|
836
|
+
async teardown() {
|
|
837
|
+
if (!this.dropinInstance) {
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
try {
|
|
841
|
+
await this.dropinInstance.teardown();
|
|
842
|
+
}
|
|
843
|
+
finally {
|
|
844
|
+
this.dropinInstance = null;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
ensureScriptLoaded() {
|
|
848
|
+
if (typeof window === 'undefined') {
|
|
849
|
+
return Promise.resolve();
|
|
850
|
+
}
|
|
851
|
+
if (window.braintree) {
|
|
852
|
+
return Promise.resolve();
|
|
853
|
+
}
|
|
854
|
+
const existing = document.querySelector(`script[src="${DROPIN_CDN_URL}"]`);
|
|
855
|
+
if (existing) {
|
|
856
|
+
return new Promise((resolve, reject) => {
|
|
857
|
+
existing.addEventListener('load', () => resolve(), { once: true });
|
|
858
|
+
existing.addEventListener('error', () => reject(new Error('braintree_script_load_failed')), { once: true });
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
return new Promise((resolve, reject) => {
|
|
862
|
+
const script = document.createElement('script');
|
|
863
|
+
script.src = DROPIN_CDN_URL;
|
|
864
|
+
script.async = true;
|
|
865
|
+
script.addEventListener('load', () => resolve(), { once: true });
|
|
866
|
+
script.addEventListener('error', () => reject(new Error('braintree_script_load_failed')), { once: true });
|
|
867
|
+
document.head.appendChild(script);
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
|
|
806
872
|
class UpdatePaymentDetailsComponent extends AppBaseComponent {
|
|
807
873
|
constructor(fb, scriptLoader, productService, subscriptionService, injector, cdr) {
|
|
808
874
|
super(injector);
|
|
@@ -813,11 +879,16 @@ class UpdatePaymentDetailsComponent extends AppBaseComponent {
|
|
|
813
879
|
this.cdr = cdr;
|
|
814
880
|
this.years = [];
|
|
815
881
|
this.months = [];
|
|
882
|
+
this.cardDetails = null;
|
|
883
|
+
this.secondaryCard = null;
|
|
884
|
+
this.showBraintreeForm = false;
|
|
885
|
+
this.braintreeBusy = false;
|
|
816
886
|
this.loading = true;
|
|
887
|
+
this.braintreeHelper = new BraintreeDropinHelper();
|
|
817
888
|
this.route.params.subscribe(response => {
|
|
818
889
|
this.subscriptionId = Number(response['subscriptionId']);
|
|
819
890
|
this.productId = Number(response['productId']);
|
|
820
|
-
this.
|
|
891
|
+
this.refreshPaymentMethods();
|
|
821
892
|
this.cdr.markForCheck();
|
|
822
893
|
});
|
|
823
894
|
this.form = this.fb.group({
|
|
@@ -832,15 +903,21 @@ class UpdatePaymentDetailsComponent extends AppBaseComponent {
|
|
|
832
903
|
this.years = HelperService.getYears();
|
|
833
904
|
this.months = HelperService.getMonths();
|
|
834
905
|
}
|
|
835
|
-
|
|
906
|
+
ngOnDestroy() {
|
|
907
|
+
super.ngOnDestroy();
|
|
908
|
+
this.braintreeHelper.teardown();
|
|
909
|
+
}
|
|
910
|
+
refreshPaymentMethods() {
|
|
836
911
|
forkJoin({
|
|
837
|
-
|
|
912
|
+
paymentMethods: this.subscriptionService.getPaymentMethods(this.subscriptionId),
|
|
838
913
|
product: this.productService.getProductById(this.productId)
|
|
839
914
|
})
|
|
840
915
|
.subscribe(response => {
|
|
841
916
|
this.stripePublishKey = response.product.stripe_publishable_key;
|
|
842
|
-
if (response.
|
|
843
|
-
|
|
917
|
+
if (response.paymentMethods.status === StatusCodes.OK) {
|
|
918
|
+
const data = response.paymentMethods.data || {};
|
|
919
|
+
this.cardDetails = data.primary || null;
|
|
920
|
+
this.secondaryCard = data.secondary || null;
|
|
844
921
|
}
|
|
845
922
|
this.cdr.markForCheck();
|
|
846
923
|
})
|
|
@@ -862,32 +939,30 @@ class UpdatePaymentDetailsComponent extends AppBaseComponent {
|
|
|
862
939
|
exp_year: this.form.value.exp_year
|
|
863
940
|
};
|
|
864
941
|
Stripe.setPublishableKey(this.stripePublishKey);
|
|
865
|
-
Stripe.card.createToken(cardDetails, (status, res) =>
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
})
|
|
886
|
-
.add(() => {
|
|
887
|
-
this.busy = false;
|
|
888
|
-
this.cdr.markForCheck();
|
|
889
|
-
});
|
|
942
|
+
Stripe.card.createToken(cardDetails, (status, res) => this.onStripeToken(status, res));
|
|
943
|
+
}
|
|
944
|
+
onStripeToken(status, res) {
|
|
945
|
+
if (status !== 200) {
|
|
946
|
+
this.toast.error(res?.error?.message);
|
|
947
|
+
this.busy = false;
|
|
948
|
+
this.cdr.markForCheck();
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
951
|
+
this.subscriptionService
|
|
952
|
+
.updateCardDetails(this.form.value, this.subscriptionId)
|
|
953
|
+
.subscribe({
|
|
954
|
+
next: response => {
|
|
955
|
+
if (response.error) {
|
|
956
|
+
this.toast.error(response.error.errors[0].message);
|
|
957
|
+
}
|
|
958
|
+
else if (response.status === StatusCodes.CREATED) {
|
|
959
|
+
this.toast.success(response.message);
|
|
960
|
+
}
|
|
961
|
+
this.cancel();
|
|
890
962
|
}
|
|
963
|
+
})
|
|
964
|
+
.add(() => {
|
|
965
|
+
this.busy = false;
|
|
891
966
|
this.cdr.markForCheck();
|
|
892
967
|
});
|
|
893
968
|
}
|
|
@@ -897,8 +972,63 @@ class UpdatePaymentDetailsComponent extends AppBaseComponent {
|
|
|
897
972
|
onChange(value) {
|
|
898
973
|
this.isChangePayment = value;
|
|
899
974
|
}
|
|
975
|
+
async startBraintreeFlow() {
|
|
976
|
+
this.showBraintreeForm = true;
|
|
977
|
+
this.cdr.markForCheck();
|
|
978
|
+
try {
|
|
979
|
+
const tokenResponse = await this.subscriptionService
|
|
980
|
+
.getBraintreeClientToken(this.subscriptionId)
|
|
981
|
+
.toPromise();
|
|
982
|
+
const clientToken = tokenResponse?.data?.client_token;
|
|
983
|
+
await this.braintreeHelper.mount(this.braintreeContainer.nativeElement, clientToken);
|
|
984
|
+
}
|
|
985
|
+
catch {
|
|
986
|
+
this.toast.error('PAYMENTS.BRAINTREE.SCRIPT_FAILED');
|
|
987
|
+
this.showBraintreeForm = false;
|
|
988
|
+
}
|
|
989
|
+
finally {
|
|
990
|
+
this.cdr.markForCheck();
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
async submitBraintree() {
|
|
994
|
+
this.braintreeBusy = true;
|
|
995
|
+
try {
|
|
996
|
+
const nonce = await this.braintreeHelper.requestNonce();
|
|
997
|
+
this.subscriptionService
|
|
998
|
+
.registerBraintreePaymentMethod(this.subscriptionId, nonce)
|
|
999
|
+
.subscribe({
|
|
1000
|
+
next: response => {
|
|
1001
|
+
if (response?.status === StatusCodes.CREATED) {
|
|
1002
|
+
this.toast.success(response.message);
|
|
1003
|
+
// Refresh the user payload so payment_methods_status is re-evaluated
|
|
1004
|
+
// and the secondary-payment modal in UserService stops firing.
|
|
1005
|
+
this.userService.getUserInfo().subscribe();
|
|
1006
|
+
this.showBraintreeForm = false;
|
|
1007
|
+
this.refreshPaymentMethods();
|
|
1008
|
+
}
|
|
1009
|
+
else if (response?.error) {
|
|
1010
|
+
this.toast.error(response.error.errors?.[0]?.message);
|
|
1011
|
+
}
|
|
1012
|
+
this.cdr.markForCheck();
|
|
1013
|
+
}
|
|
1014
|
+
})
|
|
1015
|
+
.add(() => {
|
|
1016
|
+
this.braintreeBusy = false;
|
|
1017
|
+
this.cdr.markForCheck();
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
1020
|
+
catch {
|
|
1021
|
+
this.braintreeBusy = false;
|
|
1022
|
+
this.toast.error('PAYMENTS.BRAINTREE.NONCE_FAILED');
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
cancelBraintreeFlow() {
|
|
1026
|
+
this.braintreeHelper.teardown();
|
|
1027
|
+
this.showBraintreeForm = false;
|
|
1028
|
+
this.cdr.markForCheck();
|
|
1029
|
+
}
|
|
900
1030
|
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 }); }
|
|
901
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: UpdatePaymentDetailsComponent, isStandalone: false, selector: "pw-update-payment-details", 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 Update Card Details\n </h4>\n </div>\n <div class=\"col-12 col-lg-6 mt-3 payment-left p-3 card\">\n <div class=\"card-body\">\n @if (errorMsg) {\n <div class=\"alert alert-danger\"\n >{{ 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\"\n (ngSubmit)=\"onSave()\">\n <h4 class=\"title\">New card?</h4>\n <div class=\"row\">\n <div class=\"col-md-9\">\n <div class=\"mb-3\">\n <label for=\"update-payment-card_number\">Card Number</label>\n <input type=\"text\"\n id=\"update-payment-card_number\"\n class=\"form-control\"\n formControlName=\"card_number\"\n placeholder=\"Card Number\"\n name=\"card_number\" />\n @if (\n form.get('card_number').touched &&\n form.get('card_number').errors?.required\n ) {\n <div class=\"danger\"\n >\n <span> Please enter card number. </span>\n </div>\n }\n </div>\n </div>\n <div class=\"col-md-3\">\n <div class=\"mb-3\">\n <label for=\"update-payment-cvc\">CVC</label>\n <input type=\"text\"\n id=\"update-payment-cvc\"\n class=\"form-control\"\n formControlName=\"cvc\"\n placeholder=\"CVC\"\n name=\"cvc\" />\n @if (\n form.get('cvc').touched &&\n form.get('cvc').errors?.required\n ) {\n <div class=\"danger\"\n >\n <span> Please enter cvc number. </span>\n </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\">Exp. Month</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]=\"'Exp. Month'\"\n optionValue=\"value\"\n optionLabel=\"value\">\n </p-select>\n @if (\n form.get('exp_month').touched &&\n form.get('exp_month').errors?.required\n ) {\n <div class=\"danger\"\n >\n <span> Please enter expiry month. </span>\n </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\">Exp. Year</span>\n <p-select\n [attr.aria-labelledby]=\"'update-payment-exp_year-label'\"\n [options]=\"years\"\n formControlName=\"exp_year\"\n [placeholder]=\"'Exp. Year'\"\n optionValue=\"value\"\n [appendTo]=\"'body'\"\n optionLabel=\"value\">\n </p-select>\n @if (\n form.get('exp_year')?.touched &&\n form.get('exp_year')?.errors?.['required']\n ) {\n <div class=\"danger\"\n >\n <span> Please enter expiry year. </span>\n </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 Cancel\n </button>\n <button type=\"submit\"\n class=\"btn btn-primary\"\n [buttonBusy]=\"busy\">\n Submit\n </button>\n </div>\n </div>\n </form>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n", styles: [".card-block .payment-left{border:1px solid rgb(204,204,204);height:100%}.card-block .payment-left 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%}}.card{width:50%}\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: "component", type: SavedCardDetailsComponent, selector: "pw-saved-card-details", inputs: ["data", "isChangePayment", "showNewCard"], outputs: ["changeEvent"] }] }); }
|
|
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" }] }); }
|
|
902
1032
|
}
|
|
903
1033
|
__decorate([
|
|
904
1034
|
ValidateForm('form'),
|
|
@@ -908,8 +1038,11 @@ __decorate([
|
|
|
908
1038
|
], UpdatePaymentDetailsComponent.prototype, "onSave", null);
|
|
909
1039
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UpdatePaymentDetailsComponent, decorators: [{
|
|
910
1040
|
type: Component,
|
|
911
|
-
args: [{ selector: 'pw-update-payment-details', standalone: false, 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
|
|
912
|
-
}], ctorParameters: () => [{ type: i2.UntypedFormBuilder }, { type: i1$2.ScriptLoaderService }, { type: i1$2.ProductService }, { type: i1$2.SubscriptionService }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }], propDecorators: {
|
|
1041
|
+
args: [{ selector: 'pw-update-payment-details', standalone: false, 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"] }]
|
|
1042
|
+
}], ctorParameters: () => [{ type: i2.UntypedFormBuilder }, { type: i1$2.ScriptLoaderService }, { type: i1$2.ProductService }, { type: i1$2.SubscriptionService }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }], propDecorators: { braintreeContainer: [{
|
|
1043
|
+
type: ViewChild,
|
|
1044
|
+
args: ['braintreeContainer']
|
|
1045
|
+
}], onSave: [] } });
|
|
913
1046
|
|
|
914
1047
|
class UpgradeSubscriptionComponent extends AppBaseComponent {
|
|
915
1048
|
get totalAmount() {
|
|
@@ -1180,7 +1313,7 @@ class UpgradeSubscriptionComponent extends AppBaseComponent {
|
|
|
1180
1313
|
super.ngOnDestroy();
|
|
1181
1314
|
}
|
|
1182
1315
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UpgradeSubscriptionComponent, deps: [{ token: i0.Injector }, { token: i1$2.ProductService }, { token: i2.UntypedFormBuilder }, { token: i1$1.NgbModal }, { token: i1$2.SubscriptionService }, { token: i4$2.Store }, { token: i1$2.ScriptLoaderService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1183
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: UpgradeSubscriptionComponent, isStandalone: false, selector: "pw-upgrade-subscription", viewQueries: [{ propertyName: "passwordValidationModal", first: true, predicate: ["passwordValidationModal"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<h4 class=\"form-section m-3\">\n <i class=\"ft-check-circle\" aria-hidden=\"true\"></i> {{ 'Button.Payment' | transloco }}\n</h4>\n<div class=\"card-block\">\n <!-- Show Payment Page when there is user.has_stripe_account===false -->\n <ng-container>\n <form class=\"form\"\n (ngSubmit)=\"attemptPurchase()\"\n [formGroup]=\"form\">\n <div class=\"row\">\n <div class=\"col-md-6\">\n <div class=\"form-body p-3 payment-left card pb-0\">\n <div class=\"card-body\">\n @if (product?.max_units > 1) {\n <div class=\"row\"\n >\n <div class=\"col-12\">\n <div class=\"mb-3\">\n <h4 class=\"title\">\n {{ 'User.Subscriptions.LicensesRequired' | transloco }}\n </h4>\n <div class=\"row btns-row\">\n <div class=\"col-md-4 col-8\">\n <pw-number-picker name=\"number-picker\"\n [(value)]=\"units\"\n [min]=\"subscription.min_units || product.min_units\"\n [max]=\"product.max_units\"\n step=\"1\"\n postfix=\"Units\"\n placeholder=\"Total Licenses\"\n [inputReadOnly]=\"false\"\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 </div>\n <div class=\"text-center\">\n <small class=\"form-text text-muted danger\">\n {{ unitError }}\n </small>\n </div>\n </div>\n <p>\n If you proceed, your credit card will be charged\n <strong>{{ product.currency }}\n {{ totalAmount | number:'1.2-2' }}</strong>\n </p>\n </div>\n </div>\n }\n <!-- Shows Saved Card: Shows when user has card details and not trying to update the card details -->\n @if (cardDetails) {\n <pw-saved-card-details [data]=\"cardDetails\"\n (changeEvent)=\"showNewCard = $event\"\n [showNewCard]=\"showNewCard\">\n </pw-saved-card-details>\n }\n <!-- Add New Payment Starts, opens up when user doesn't have stripe account or tries to change the\n card details -->\n @if ((user && !cardDetails) || (cardDetails && showNewCard)) {\n <h4 class=\"title\">\n {{ 'User.Subscriptions.NewCard' | transloco }}?\n </h4>\n <div class=\"row\">\n <div class=\"col-md-9\">\n <div class=\"mb-3\">\n <label for=\"upgrade-subscription-card_number\">{{\n 'User.Subscriptions.CardNumber' | transloco\n }}</label>\n <input type=\"text\"\n id=\"upgrade-subscription-card_number\"\n class=\"form-control\"\n formControlName=\"card_number\"\n placeholder=\"Card Number\"\n name=\"card_number\" />\n @if (\n form.get('card_number').touched &&\n form.get('card_number').errors?.required\n ) {\n <div class=\"danger\"\n >\n <span> Please enter card number. </span>\n </div>\n }\n </div>\n </div>\n <div class=\"col-md-3\">\n <div class=\"mb-3\">\n <label for=\"upgrade-subscription-cvc\">{{\n 'User.Subscriptions.CVC' | transloco\n }}</label>\n <input type=\"text\"\n id=\"upgrade-subscription-cvc\"\n class=\"form-control\"\n formControlName=\"cvc\"\n placeholder=\"CVC\"\n name=\"cvc\" />\n @if (\n form.get('cvc').touched &&\n form.get('cvc').errors?.required\n ) {\n <div class=\"danger\"\n >\n <span> Please enter cvc. </span>\n </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 pw-label-style\" id=\"upgrade-subscription-exp_month-label\">Exp. Month</span>\n <p-select\n [attr.aria-labelledby]=\"'upgrade-subscription-exp_month-label'\"\n [options]=\"months\"\n formControlName=\"exp_month\"\n [placeholder]=\"'Exp. Month'\"\n optionValue=\"value\"\n [appendTo]=\"'body'\"\n optionLabel=\"value\">\n </p-select>\n @if (\n form.get('exp_month').touched &&\n form.get('exp_month').errors?.required\n ) {\n <div class=\"danger\"\n >\n <span> Please enter expiry month. </span>\n </div>\n }\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"mb-3\">\n <span class=\"sr-only\" id=\"upgrade-subscription-exp_year-label\">Exp. Year</span>\n <p-select\n [attr.aria-labelledby]=\"'upgrade-subscription-exp_year-label'\"\n [options]=\"years\"\n formControlName=\"exp_year\"\n [placeholder]=\"'Exp. Year'\"\n [appendTo]=\"'body'\"\n optionValue=\"value\"\n optionLabel=\"value\">\n </p-select>\n @if (\n form.get('exp_year').touched &&\n form.get('exp_year').errors?.required\n ) {\n <div class=\"danger\"\n >\n <span> Please enter expiry year. </span>\n </div>\n }\n </div>\n </div>\n @if (cardDetails) {\n <div class=\"col-12 mt-2\"\n >\n <a aria-label=\"Navigate to Target\"\n (click)=\"showNewCard = false; onDiscardToggle()\">Disregard and pay with current registered card</a>\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n <!-- Purchase Summary -->\n @if (product) {\n <div class=\"col-md-6\"\n >\n <div class=\"purchase-summary card p-3 payment-right\">\n <div class=\"card-body\">\n <h4 class=\"title\">{{ 'Label.PurchaseSummary' | transloco }}</h4>\n <div class=\"summary-row d-flex mb-2\">\n <div class=\"summary-left\">{{ 'Label.Plan' | transloco }}:</div>\n <div class=\"summary-right\">{{ product.name }}</div>\n </div>\n <div class=\"summary-row d-flex mb-2\">\n <div class=\"summary-left\">{{ 'Label.Price' | transloco }}:</div>\n <div class=\"summary-right\">\n {{ product.currency }}\n {{ (product.price_per_unit / 100) | number:'1.2-2' }}\n </div>\n </div>\n <div class=\"summary-row d-flex mb-2\">\n <div class=\"summary-left\">{{ 'Label.Seats' | transloco }}:</div>\n <div class=\"summary-right\">{{ form.get('units').value }}</div>\n </div>\n <div class=\"summary-row d-flex mb-2\">\n <div class=\"summary-left\">{{ 'Label.Total' | transloco }}:</div>\n <div class=\"summary-right\">\n {{ product.currency }} {{ totalAmount | number:'1.2-2' }}\n </div>\n </div>\n <div class=\"summary-row d-flex mb-2\">\n <div class=\"summary-left\">\n {{ 'Label.Recurrency' | transloco }}:\n </div>\n <div class=\"summary-right\">{{ product.billing_frequency }}</div>\n </div>\n </div>\n <div class=\"text-center\">\n <hr />\n <p>\n By subscribing you acknowledge and accept our terms of service and\n privacy policy\n </p>\n </div>\n </div>\n </div>\n }\n </div>\n <div class=\"row\">\n <div class=\"col-12 text-center mt-3\">\n <img src=\"/assets/img/icons/powered_by_stripe_v2.png\"\n class=\"payment-provider\"\n alt=\"\" />\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n <div class=\"form-actions text-end\">\n <button type=\"button\"\n class=\"btn btn-raised btn-outline-default me-1\"\n [disabled]=\"isPurchaseAttempted\"\n routerLink=\"/account/subscriptions\">\n <i class=\"ft-x\" aria-hidden=\"true\"></i>{{ 'Button.Back' | transloco }}\n </button>\n <button type=\"submit\"\n class=\"btn btn-raised btn-primary\"\n [disabled]=\"isPurchaseAttempted\"\n [buttonBusy]=\"busy\">\n <i class=\"ft-check\" aria-hidden=\"true\"></i>\n {{ 'Button.Purchase' | transloco }}\n </button>\n </div>\n </div>\n </div>\n </form>\n </ng-container>\n</div>\n\n<pw-password-validation #passwordValidationModal\n (successEvent)=\"onValidatePassword($event)\">\n <div class=\"row\">\n <div class=\"col-12\">\n <p>\n If you proceed, your credit card will be charged\n @if (totalAmount) {\n <strong>{{ product.currency }} {{ totalAmount | number:'1.2-2' }}</strong>\n }\n </p>\n </div>\n </div>\n</pw-password-validation>\n", styles: [".payment-left,.payment-right{border:1px solid rgb(204,204,204);height:100%}.payment-left h4,.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-left .summary-row.total,.payment-right .summary-row.total{padding:10px 0 0 10px}.payment-left .summary-row .summary-left,.payment-right .summary-row .summary-left{font-weight:600}.payment-provider{width:20%}@media(max-width:800px){.payment-provider{width:60%}}.summary-left{-webkit-box-flex:1;color:#555;flex-grow:1;-ms-flex-positive:1;font-weight:200;text-align:left}.summary-left.plan{color:#c93f00;font-size:14px;margin:5px 0}.summary-right{-webkit-box-flex:1;-webkit-box-pack:end;color:#000;flex-grow:1;-ms-flex-pack:end;-ms-flex-positive:1;justify-content:flex-end;text-align:right}\n"], dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { 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: "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.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: 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: SavedCardDetailsComponent, selector: "pw-saved-card-details", inputs: ["data", "isChangePayment", "showNewCard"], outputs: ["changeEvent"] }, { kind: "pipe", type: i6.DecimalPipe, name: "number" }, { kind: "pipe", type: i11.TranslocoPipe, name: "transloco" }] }); }
|
|
1316
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: UpgradeSubscriptionComponent, isStandalone: false, selector: "pw-upgrade-subscription", viewQueries: [{ propertyName: "passwordValidationModal", first: true, predicate: ["passwordValidationModal"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<h4 class=\"form-section m-3\">\n <i class=\"ft-check-circle\" aria-hidden=\"true\"></i> {{ 'Button.Payment' | transloco }}\n</h4>\n<div class=\"card-block\">\n <!-- Show Payment Page when there is user.has_stripe_account===false -->\n <ng-container>\n <form class=\"form\"\n (ngSubmit)=\"attemptPurchase()\"\n [formGroup]=\"form\">\n <div class=\"row\">\n <div class=\"col-md-6\">\n <div class=\"form-body p-3 payment-left card pb-0\">\n <div class=\"card-body\">\n @if (product?.max_units > 1) {\n <div class=\"row\"\n >\n <div class=\"col-12\">\n <div class=\"mb-3\">\n <h4 class=\"title\">\n {{ 'User.Subscriptions.LicensesRequired' | transloco }}\n </h4>\n <div class=\"row btns-row\">\n <div class=\"col-md-4 col-8\">\n <pw-number-picker name=\"number-picker\"\n [(value)]=\"units\"\n [min]=\"subscription.min_units || product.min_units\"\n [max]=\"product.max_units\"\n step=\"1\"\n postfix=\"Units\"\n placeholder=\"Total Licenses\"\n [inputReadOnly]=\"false\"\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 </div>\n <div class=\"text-center\">\n <small class=\"form-text text-muted danger\">\n {{ unitError }}\n </small>\n </div>\n </div>\n <p>\n If you proceed, your credit card will be charged\n <strong>{{ product.currency }}\n {{ totalAmount | number:'1.2-2' }}</strong>\n </p>\n </div>\n </div>\n }\n <!-- Shows Saved Card: Shows when user has card details and not trying to update the card details -->\n @if (cardDetails) {\n <pw-saved-card-details [data]=\"cardDetails\"\n (changeEvent)=\"showNewCard = $event\"\n [showNewCard]=\"showNewCard\">\n </pw-saved-card-details>\n }\n <!-- Add New Payment Starts, opens up when user doesn't have stripe account or tries to change the\n card details -->\n @if ((user && !cardDetails) || (cardDetails && showNewCard)) {\n <h4 class=\"title\">\n {{ 'User.Subscriptions.NewCard' | transloco }}?\n </h4>\n <div class=\"row\">\n <div class=\"col-md-9\">\n <div class=\"mb-3\">\n <label for=\"upgrade-subscription-card_number\">{{\n 'User.Subscriptions.CardNumber' | transloco\n }}</label>\n <input type=\"text\"\n id=\"upgrade-subscription-card_number\"\n class=\"form-control\"\n formControlName=\"card_number\"\n placeholder=\"Card Number\"\n name=\"card_number\" />\n @if (\n form.get('card_number').touched &&\n form.get('card_number').errors?.required\n ) {\n <div class=\"danger\"\n >\n <span> Please enter card number. </span>\n </div>\n }\n </div>\n </div>\n <div class=\"col-md-3\">\n <div class=\"mb-3\">\n <label for=\"upgrade-subscription-cvc\">{{\n 'User.Subscriptions.CVC' | transloco\n }}</label>\n <input type=\"text\"\n id=\"upgrade-subscription-cvc\"\n class=\"form-control\"\n formControlName=\"cvc\"\n placeholder=\"CVC\"\n name=\"cvc\" />\n @if (\n form.get('cvc').touched &&\n form.get('cvc').errors?.required\n ) {\n <div class=\"danger\"\n >\n <span> Please enter cvc. </span>\n </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 pw-label-style\" id=\"upgrade-subscription-exp_month-label\">Exp. Month</span>\n <p-select\n [attr.aria-labelledby]=\"'upgrade-subscription-exp_month-label'\"\n [options]=\"months\"\n formControlName=\"exp_month\"\n [placeholder]=\"'Exp. Month'\"\n optionValue=\"value\"\n [appendTo]=\"'body'\"\n optionLabel=\"value\">\n </p-select>\n @if (\n form.get('exp_month').touched &&\n form.get('exp_month').errors?.required\n ) {\n <div class=\"danger\"\n >\n <span> Please enter expiry month. </span>\n </div>\n }\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"mb-3\">\n <span class=\"sr-only\" id=\"upgrade-subscription-exp_year-label\">Exp. Year</span>\n <p-select\n [attr.aria-labelledby]=\"'upgrade-subscription-exp_year-label'\"\n [options]=\"years\"\n formControlName=\"exp_year\"\n [placeholder]=\"'Exp. Year'\"\n [appendTo]=\"'body'\"\n optionValue=\"value\"\n optionLabel=\"value\">\n </p-select>\n @if (\n form.get('exp_year').touched &&\n form.get('exp_year').errors?.required\n ) {\n <div class=\"danger\"\n >\n <span> Please enter expiry year. </span>\n </div>\n }\n </div>\n </div>\n @if (cardDetails) {\n <div class=\"col-12 mt-2\"\n >\n <a aria-label=\"Navigate to Target\"\n (click)=\"showNewCard = false; onDiscardToggle()\">Disregard and pay with current registered card</a>\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n <!-- Purchase Summary -->\n @if (product) {\n <div class=\"col-md-6\"\n >\n <div class=\"purchase-summary card p-3 payment-right\">\n <div class=\"card-body\">\n <h4 class=\"title\">{{ 'Label.PurchaseSummary' | transloco }}</h4>\n <div class=\"summary-row d-flex mb-2\">\n <div class=\"summary-left\">{{ 'Label.Plan' | transloco }}:</div>\n <div class=\"summary-right\">{{ product.name }}</div>\n </div>\n <div class=\"summary-row d-flex mb-2\">\n <div class=\"summary-left\">{{ 'Label.Price' | transloco }}:</div>\n <div class=\"summary-right\">\n {{ product.currency }}\n {{ (product.price_per_unit / 100) | number:'1.2-2' }}\n </div>\n </div>\n <div class=\"summary-row d-flex mb-2\">\n <div class=\"summary-left\">{{ 'Label.Seats' | transloco }}:</div>\n <div class=\"summary-right\">{{ form.get('units').value }}</div>\n </div>\n <div class=\"summary-row d-flex mb-2\">\n <div class=\"summary-left\">{{ 'Label.Total' | transloco }}:</div>\n <div class=\"summary-right\">\n {{ product.currency }} {{ totalAmount | number:'1.2-2' }}\n </div>\n </div>\n <div class=\"summary-row d-flex mb-2\">\n <div class=\"summary-left\">\n {{ 'Label.Recurrency' | transloco }}:\n </div>\n <div class=\"summary-right\">{{ product.billing_frequency }}</div>\n </div>\n </div>\n <div class=\"text-center\">\n <hr />\n <p>\n By subscribing you acknowledge and accept our terms of service and\n privacy policy\n </p>\n </div>\n </div>\n </div>\n }\n </div>\n <div class=\"row\">\n <div class=\"col-12 text-center mt-3\">\n <img src=\"/assets/img/icons/powered_by_stripe_v2.png\"\n class=\"payment-provider\"\n alt=\"\" />\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n <div class=\"form-actions text-end\">\n <button type=\"button\"\n class=\"btn btn-raised btn-outline-default me-1\"\n [disabled]=\"isPurchaseAttempted\"\n routerLink=\"/account/subscriptions\">\n <i class=\"ft-x\" aria-hidden=\"true\"></i>{{ 'Button.Back' | transloco }}\n </button>\n <button type=\"submit\"\n class=\"btn btn-raised btn-primary\"\n [disabled]=\"isPurchaseAttempted\"\n [buttonBusy]=\"busy\">\n <i class=\"ft-check\" aria-hidden=\"true\"></i>\n {{ 'Button.Purchase' | transloco }}\n </button>\n </div>\n </div>\n </div>\n </form>\n </ng-container>\n</div>\n\n<pw-password-validation #passwordValidationModal\n (successEvent)=\"onValidatePassword($event)\">\n <div class=\"row\">\n <div class=\"col-12\">\n <p>\n If you proceed, your credit card will be charged\n @if (totalAmount) {\n <strong>{{ product.currency }} {{ totalAmount | number:'1.2-2' }}</strong>\n }\n </p>\n </div>\n </div>\n</pw-password-validation>\n", styles: [".payment-left,.payment-right{border:1px solid rgb(204,204,204);height:100%}.payment-left h4,.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-left .summary-row.total,.payment-right .summary-row.total{padding:10px 0 0 10px}.payment-left .summary-row .summary-left,.payment-right .summary-row .summary-left{font-weight:600}.payment-provider{width:20%}@media(max-width:800px){.payment-provider{width:60%}}.summary-left{-webkit-box-flex:1;color:#555;flex-grow:1;-ms-flex-positive:1;font-weight:200;text-align:left}.summary-left.plan{color:#c93f00;font-size:14px;margin:5px 0}.summary-right{-webkit-box-flex:1;-webkit-box-pack:end;color:#000;flex-grow:1;-ms-flex-pack:end;-ms-flex-positive:1;justify-content:flex-end;text-align:right}\n"], dependencies: [{ kind: "directive", type: i4.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { 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: "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.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: 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: SavedCardDetailsComponent, selector: "pw-saved-card-details", inputs: ["data", "isChangePayment", "showNewCard"], outputs: ["changeEvent"] }, { kind: "pipe", type: i6.DecimalPipe, name: "number" }, { kind: "pipe", type: i8.TranslocoPipe, name: "transloco" }] }); }
|
|
1184
1317
|
}
|
|
1185
1318
|
__decorate([
|
|
1186
1319
|
ValidateForm('form'),
|
|
@@ -1455,7 +1588,7 @@ class UserSubscriptionDetailsComponent extends AppBaseComponent {
|
|
|
1455
1588
|
this.allowUpdate = false;
|
|
1456
1589
|
}
|
|
1457
1590
|
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 }); }
|
|
1458
|
-
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$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: i13.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: i11.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i6$3.CurrencySymbolPipe, name: "currencySymbol" }] }); }
|
|
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" }] }); }
|
|
1459
1592
|
}
|
|
1460
1593
|
__decorate([
|
|
1461
1594
|
ValidateForm('form'),
|
|
@@ -1672,7 +1805,7 @@ class UserSubscriptionListComponent extends AppBaseComponent {
|
|
|
1672
1805
|
super.ngOnDestroy();
|
|
1673
1806
|
}
|
|
1674
1807
|
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 }); }
|
|
1675
|
-
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: i13.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: i11.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i6$3.DateFormatPipe, name: "dateFormat" }] }); }
|
|
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" }] }); }
|
|
1676
1809
|
}
|
|
1677
1810
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserSubscriptionListComponent, decorators: [{
|
|
1678
1811
|
type: Component,
|
|
@@ -1754,7 +1887,7 @@ class UserInvoiceComponent extends AppBaseComponent {
|
|
|
1754
1887
|
}
|
|
1755
1888
|
}
|
|
1756
1889
|
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 }); }
|
|
1757
|
-
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\"> 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\"> 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:
|
|
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\"> 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\"> 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" }] }); }
|
|
1758
1891
|
}
|
|
1759
1892
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserInvoiceComponent, decorators: [{
|
|
1760
1893
|
type: Component,
|
|
@@ -1833,7 +1966,7 @@ class CommunicationTabComponent extends AppBaseComponent {
|
|
|
1833
1966
|
// });
|
|
1834
1967
|
}
|
|
1835
1968
|
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 }); }
|
|
1836
|
-
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
|
|
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"] }] }); }
|
|
1837
1970
|
}
|
|
1838
1971
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: CommunicationTabComponent, decorators: [{
|
|
1839
1972
|
type: Component,
|
|
@@ -1902,7 +2035,7 @@ class OthersTabComponent extends AppBaseComponent {
|
|
|
1902
2035
|
super.ngOnDestroy();
|
|
1903
2036
|
}
|
|
1904
2037
|
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 }); }
|
|
1905
|
-
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
|
|
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" }] }); }
|
|
1906
2039
|
}
|
|
1907
2040
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: OthersTabComponent, decorators: [{
|
|
1908
2041
|
type: Component,
|
|
@@ -2223,7 +2356,7 @@ class SupportDetailsComponent extends AppBaseComponent {
|
|
|
2223
2356
|
HelperService.onUploadError(event, this.toast);
|
|
2224
2357
|
}
|
|
2225
2358
|
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 }); }
|
|
2226
|
-
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$
|
|
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" }] }); }
|
|
2227
2360
|
}
|
|
2228
2361
|
__decorate([
|
|
2229
2362
|
ValidateForm('form'),
|
|
@@ -2637,7 +2770,7 @@ class EditRecommendationModalComponent {
|
|
|
2637
2770
|
});
|
|
2638
2771
|
}
|
|
2639
2772
|
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 }); }
|
|
2640
|
-
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$
|
|
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"] }] }); }
|
|
2641
2774
|
}
|
|
2642
2775
|
__decorate([
|
|
2643
2776
|
ValidateForm('form'),
|
|
@@ -2955,7 +3088,7 @@ class EditUserProfileModalComponent extends AppBaseComponent {
|
|
|
2955
3088
|
});
|
|
2956
3089
|
}
|
|
2957
3090
|
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 }); }
|
|
2958
|
-
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.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: i11.TranslocoPipe, name: "transloco" }] }); }
|
|
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" }] }); }
|
|
2959
3092
|
}
|
|
2960
3093
|
__decorate([
|
|
2961
3094
|
ValidateForm('form'),
|
|
@@ -3235,7 +3368,7 @@ class UserProjectsComponent extends AppBaseComponent {
|
|
|
3235
3368
|
});
|
|
3236
3369
|
}
|
|
3237
3370
|
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 }); }
|
|
3238
|
-
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$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: i11.TranslocoPipe, name: "transloco" }] }); }
|
|
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" }] }); }
|
|
3239
3372
|
}
|
|
3240
3373
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserProjectsComponent, decorators: [{
|
|
3241
3374
|
type: Component,
|
|
@@ -3453,7 +3586,7 @@ class UserProfilePageComponent extends AppBaseComponent {
|
|
|
3453
3586
|
super.ngOnDestroy();
|
|
3454
3587
|
}
|
|
3455
3588
|
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 }); }
|
|
3456
|
-
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:
|
|
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" }] }); }
|
|
3457
3590
|
}
|
|
3458
3591
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserProfilePageComponent, decorators: [{
|
|
3459
3592
|
type: Component,
|