@idsoftsource/initial-process 3.1.1 → 3.1.3
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.
|
@@ -2967,8 +2967,20 @@ class PreviewComponent {
|
|
|
2967
2967
|
roleContextService;
|
|
2968
2968
|
providerService;
|
|
2969
2969
|
frontendProviderService;
|
|
2970
|
+
cdr;
|
|
2970
2971
|
libConfig;
|
|
2971
2972
|
providerId;
|
|
2973
|
+
EMPTY_GUID = '00000000-0000-0000-0000-000000000000';
|
|
2974
|
+
/** Set when withTargetProviderIdFallback substitutes the empty GUID, i.e. there's no real targetProviderId/company. */
|
|
2975
|
+
providerIdFallbackUsed = signal(false, ...(ngDevMode ? [{ debugName: "providerIdFallbackUsed" }] : []));
|
|
2976
|
+
/** initialSetUpCreateUserDetail rejects a null targetProviderId with 400; substitute the empty GUID only when it's actually missing. */
|
|
2977
|
+
withTargetProviderIdFallback(payload) {
|
|
2978
|
+
if (payload && payload.targetProviderId == null) {
|
|
2979
|
+
payload.targetProviderId = this.EMPTY_GUID;
|
|
2980
|
+
this.providerIdFallbackUsed.set(true);
|
|
2981
|
+
}
|
|
2982
|
+
return payload;
|
|
2983
|
+
}
|
|
2972
2984
|
useremail;
|
|
2973
2985
|
educationDegreeTypeOptions = [
|
|
2974
2986
|
'Associate Degree (AA, AS, AAS)',
|
|
@@ -3079,7 +3091,7 @@ class PreviewComponent {
|
|
|
3079
3091
|
{ name: 'Insurance Agency', value: 'InsuranceAgency', img: 'assets/images/users/insurance.svg', selected: false, code: ProviderType.InsuranceAgency, id: '00000000-0000-0000-0000-000000000000', roleId: '00000000-0000-0000-0000-000000000000' },
|
|
3080
3092
|
{ name: 'Real Estate Company', value: 'RealEstateCompany', img: 'assets/images/users/realestate.svg', selected: false, code: ProviderType.RealEstateAgency, id: '00000000-0000-0000-0000-000000000000', roleId: '00000000-0000-0000-0000-000000000000' },
|
|
3081
3093
|
];
|
|
3082
|
-
constructor(store, fileService, userSkillSetService, userToolService, userDocumentService, userEducation, userDetailService, userExperienceService, tokenService, roleContextService, providerService, frontendProviderService, libConfig) {
|
|
3094
|
+
constructor(store, fileService, userSkillSetService, userToolService, userDocumentService, userEducation, userDetailService, userExperienceService, tokenService, roleContextService, providerService, frontendProviderService, cdr, libConfig) {
|
|
3083
3095
|
this.store = store;
|
|
3084
3096
|
this.fileService = fileService;
|
|
3085
3097
|
this.userSkillSetService = userSkillSetService;
|
|
@@ -3092,6 +3104,7 @@ class PreviewComponent {
|
|
|
3092
3104
|
this.roleContextService = roleContextService;
|
|
3093
3105
|
this.providerService = providerService;
|
|
3094
3106
|
this.frontendProviderService = frontendProviderService;
|
|
3107
|
+
this.cdr = cdr;
|
|
3095
3108
|
this.libConfig = libConfig;
|
|
3096
3109
|
this.resumeData = this.store.profileSignal();
|
|
3097
3110
|
}
|
|
@@ -3567,7 +3580,7 @@ class PreviewComponent {
|
|
|
3567
3580
|
timePattern: new Date().toLocaleTimeString()
|
|
3568
3581
|
}
|
|
3569
3582
|
};
|
|
3570
|
-
const res = await firstValueFrom(this.userDetailService.initialSetUpCreateUserDetail(model));
|
|
3583
|
+
const res = await firstValueFrom(this.userDetailService.initialSetUpCreateUserDetail(this.withTargetProviderIdFallback(model)));
|
|
3571
3584
|
if (res?.failed) {
|
|
3572
3585
|
this.providerSetupError = res.failures?.[0]?.message || res?.message || 'Save failed';
|
|
3573
3586
|
return;
|
|
@@ -3673,10 +3686,12 @@ class PreviewComponent {
|
|
|
3673
3686
|
if (!this.hasUnsavedCertificationItem(index))
|
|
3674
3687
|
continue;
|
|
3675
3688
|
await this.persistCertification(certifications[index], index, false);
|
|
3689
|
+
this.cdr.detectChanges();
|
|
3676
3690
|
}
|
|
3677
3691
|
}
|
|
3678
3692
|
finally {
|
|
3679
3693
|
this.isSavingCertification = false;
|
|
3694
|
+
this.cdr.detectChanges();
|
|
3680
3695
|
}
|
|
3681
3696
|
}
|
|
3682
3697
|
async confirmAllLicenses() {
|
|
@@ -3690,10 +3705,18 @@ class PreviewComponent {
|
|
|
3690
3705
|
if (!this.hasUnsavedLicenseItem(index))
|
|
3691
3706
|
continue;
|
|
3692
3707
|
await this.persistLicense(licenses[index], index, false);
|
|
3708
|
+
// The HTTP round-trip above may resolve on a task that Angular's
|
|
3709
|
+
// zone-based change detection doesn't automatically pick up (e.g. when
|
|
3710
|
+
// running under a role-context/impersonation flow whose token refresh
|
|
3711
|
+
// happens off-zone). Force a check so per-item "saved" state and the
|
|
3712
|
+
// button's loading state reflect immediately, without needing an
|
|
3713
|
+
// unrelated click to nudge change detection afterwards.
|
|
3714
|
+
this.cdr.detectChanges();
|
|
3693
3715
|
}
|
|
3694
3716
|
}
|
|
3695
3717
|
finally {
|
|
3696
3718
|
this.isSavingLicense = false;
|
|
3719
|
+
this.cdr.detectChanges();
|
|
3697
3720
|
}
|
|
3698
3721
|
}
|
|
3699
3722
|
buildSectionQuery(orderBy, includeForUser = false) {
|
|
@@ -4337,11 +4360,16 @@ class PreviewComponent {
|
|
|
4337
4360
|
}
|
|
4338
4361
|
else {
|
|
4339
4362
|
await this.persistWorkExperience(items[i], i, false);
|
|
4363
|
+
// See comment in confirmAllLicenses(): force a check so the UI
|
|
4364
|
+
// reflects the just-persisted item without waiting on an
|
|
4365
|
+
// unrelated zone-triggered event.
|
|
4366
|
+
this.cdr.detectChanges();
|
|
4340
4367
|
}
|
|
4341
4368
|
}
|
|
4342
4369
|
}
|
|
4343
4370
|
finally {
|
|
4344
4371
|
this.isSavingWork = false;
|
|
4372
|
+
this.cdr.detectChanges();
|
|
4345
4373
|
}
|
|
4346
4374
|
if (failedIndices.length > 0) {
|
|
4347
4375
|
this.workConfirmAllQueue = failedIndices.slice(1);
|
|
@@ -4378,6 +4406,7 @@ class PreviewComponent {
|
|
|
4378
4406
|
}
|
|
4379
4407
|
finally {
|
|
4380
4408
|
this.isSavingWork = false;
|
|
4409
|
+
this.cdr.detectChanges();
|
|
4381
4410
|
}
|
|
4382
4411
|
this.cancelEditJob();
|
|
4383
4412
|
}
|
|
@@ -4639,6 +4668,7 @@ class PreviewComponent {
|
|
|
4639
4668
|
}
|
|
4640
4669
|
finally {
|
|
4641
4670
|
this.isSavingSkill = false;
|
|
4671
|
+
this.cdr.detectChanges();
|
|
4642
4672
|
}
|
|
4643
4673
|
}
|
|
4644
4674
|
cancelBulkSkillConfirm() {
|
|
@@ -4669,6 +4699,7 @@ class PreviewComponent {
|
|
|
4669
4699
|
}
|
|
4670
4700
|
finally {
|
|
4671
4701
|
this.isSavingSkill = false;
|
|
4702
|
+
this.cdr.detectChanges();
|
|
4672
4703
|
}
|
|
4673
4704
|
}
|
|
4674
4705
|
async confirmAllTools() {
|
|
@@ -4688,6 +4719,7 @@ class PreviewComponent {
|
|
|
4688
4719
|
}
|
|
4689
4720
|
finally {
|
|
4690
4721
|
this.isSavingTool = false;
|
|
4722
|
+
this.cdr.detectChanges();
|
|
4691
4723
|
}
|
|
4692
4724
|
}
|
|
4693
4725
|
cancelBulkToolConfirm() {
|
|
@@ -4718,6 +4750,7 @@ class PreviewComponent {
|
|
|
4718
4750
|
}
|
|
4719
4751
|
finally {
|
|
4720
4752
|
this.isSavingTool = false;
|
|
4753
|
+
this.cdr.detectChanges();
|
|
4721
4754
|
}
|
|
4722
4755
|
}
|
|
4723
4756
|
async saveToolEditor() {
|
|
@@ -4767,6 +4800,7 @@ class PreviewComponent {
|
|
|
4767
4800
|
}
|
|
4768
4801
|
finally {
|
|
4769
4802
|
this.isSavingTool = false;
|
|
4803
|
+
this.cdr.detectChanges();
|
|
4770
4804
|
}
|
|
4771
4805
|
this.closeToolEditor();
|
|
4772
4806
|
}
|
|
@@ -4913,6 +4947,7 @@ class PreviewComponent {
|
|
|
4913
4947
|
}
|
|
4914
4948
|
finally {
|
|
4915
4949
|
this.isSavingCertification = false;
|
|
4950
|
+
this.cdr.detectChanges();
|
|
4916
4951
|
}
|
|
4917
4952
|
this.cancelEditCertification();
|
|
4918
4953
|
}
|
|
@@ -5036,6 +5071,7 @@ class PreviewComponent {
|
|
|
5036
5071
|
}
|
|
5037
5072
|
finally {
|
|
5038
5073
|
this.isSavingLicense = false;
|
|
5074
|
+
this.cdr.detectChanges();
|
|
5039
5075
|
}
|
|
5040
5076
|
this.cancelEditLicense();
|
|
5041
5077
|
}
|
|
@@ -5126,11 +5162,13 @@ class PreviewComponent {
|
|
|
5126
5162
|
}
|
|
5127
5163
|
else {
|
|
5128
5164
|
await this.persistEducation(items[i], i, false);
|
|
5165
|
+
this.cdr.detectChanges();
|
|
5129
5166
|
}
|
|
5130
5167
|
}
|
|
5131
5168
|
}
|
|
5132
5169
|
finally {
|
|
5133
5170
|
this.isSavingEducation = false;
|
|
5171
|
+
this.cdr.detectChanges();
|
|
5134
5172
|
}
|
|
5135
5173
|
if (failedIndices.length > 0) {
|
|
5136
5174
|
this.educationConfirmAllQueue = failedIndices.slice(1);
|
|
@@ -5188,6 +5226,7 @@ class PreviewComponent {
|
|
|
5188
5226
|
}
|
|
5189
5227
|
finally {
|
|
5190
5228
|
this.isSavingEducation = false;
|
|
5229
|
+
this.cdr.detectChanges();
|
|
5191
5230
|
}
|
|
5192
5231
|
this.cancelEditEducation();
|
|
5193
5232
|
}
|
|
@@ -5233,7 +5272,7 @@ class PreviewComponent {
|
|
|
5233
5272
|
await firstValueFrom(this.userDetailService.updateMyProfileData(payload.userDetail));
|
|
5234
5273
|
}
|
|
5235
5274
|
else {
|
|
5236
|
-
await firstValueFrom(this.userDetailService.initialSetUpCreateUserDetail(payload));
|
|
5275
|
+
await firstValueFrom(this.userDetailService.initialSetUpCreateUserDetail(this.withTargetProviderIdFallback(payload)));
|
|
5237
5276
|
}
|
|
5238
5277
|
this.showDashboardConfirmPopup = false;
|
|
5239
5278
|
// Clear session so a future return to this page starts fresh from T&C
|
|
@@ -5316,7 +5355,7 @@ class PreviewComponent {
|
|
|
5316
5355
|
await firstValueFrom(this.userDetailService.updateMyProfileData(payload.userDetail));
|
|
5317
5356
|
}
|
|
5318
5357
|
else {
|
|
5319
|
-
await firstValueFrom(this.userDetailService.initialSetUpCreateUserDetail(payload));
|
|
5358
|
+
await firstValueFrom(this.userDetailService.initialSetUpCreateUserDetail(this.withTargetProviderIdFallback(payload)));
|
|
5320
5359
|
}
|
|
5321
5360
|
this.hasUserDetailData = true;
|
|
5322
5361
|
this.basicDetailsSaved = true; // ✅ only on success
|
|
@@ -5428,11 +5467,17 @@ class PreviewComponent {
|
|
|
5428
5467
|
? await firstValueFrom(this.userDocumentService
|
|
5429
5468
|
.updateUserDocument(payload))
|
|
5430
5469
|
: await firstValueFrom(this.userDocumentService.createUserDocument(payload));
|
|
5470
|
+
if (res?.failed) {
|
|
5471
|
+
console.error('License validation failed:', res.failures);
|
|
5472
|
+
this.licenseLocallySaved[index] = false; // mark as failed
|
|
5473
|
+
return; // stop here, do not mark as saved
|
|
5474
|
+
}
|
|
5431
5475
|
const createdId = this.getCreatedId(res);
|
|
5432
5476
|
this.markItemSaved(this.licenseServerIds, this.licenseLocallySaved, index, createdId);
|
|
5433
5477
|
}
|
|
5434
5478
|
catch (err) {
|
|
5435
5479
|
console.error('Unable to persist license', err);
|
|
5480
|
+
this.licenseLocallySaved[index] = false;
|
|
5436
5481
|
}
|
|
5437
5482
|
}
|
|
5438
5483
|
async persistSkill(index, isEdit) {
|
|
@@ -5482,6 +5527,7 @@ class PreviewComponent {
|
|
|
5482
5527
|
const id = arr?.[batchPos]?.id ?? this.getCreatedId(res);
|
|
5483
5528
|
this.markItemSaved(this.skillServerIds, this.skillLocallySaved, originalIdx, id);
|
|
5484
5529
|
});
|
|
5530
|
+
this.cdr.detectChanges();
|
|
5485
5531
|
}
|
|
5486
5532
|
catch (err) {
|
|
5487
5533
|
console.error('Unable to batch create skills', err);
|
|
@@ -5535,6 +5581,7 @@ class PreviewComponent {
|
|
|
5535
5581
|
const id = arr?.[batchPos]?.id ?? this.getCreatedId(res);
|
|
5536
5582
|
this.markItemSaved(this.toolServerIds, this.toolLocallySaved, originalIdx, id);
|
|
5537
5583
|
});
|
|
5584
|
+
this.cdr.detectChanges();
|
|
5538
5585
|
}
|
|
5539
5586
|
catch (err) {
|
|
5540
5587
|
console.error('Unable to batch create tools', err);
|
|
@@ -6302,7 +6349,7 @@ class PreviewComponent {
|
|
|
6302
6349
|
this.companyDetailsSaved = true;
|
|
6303
6350
|
// Sync updated providerName to the user detail record
|
|
6304
6351
|
const payload = this.mapCompanyDetail(this.store.profileSignal());
|
|
6305
|
-
await firstValueFrom(this.userDetailService.initialSetUpCreateUserDetail(payload));
|
|
6352
|
+
await firstValueFrom(this.userDetailService.initialSetUpCreateUserDetail(this.withTargetProviderIdFallback(payload)));
|
|
6306
6353
|
}
|
|
6307
6354
|
catch (error) {
|
|
6308
6355
|
console.error('Error saving company details:', error);
|
|
@@ -6372,8 +6419,8 @@ class PreviewComponent {
|
|
|
6372
6419
|
event.preventDefault();
|
|
6373
6420
|
}
|
|
6374
6421
|
}
|
|
6375
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PreviewComponent, deps: [{ token: CredentialingStore }, { token: FileService }, { token: UserSkillSetService }, { token: UserToolService }, { token: UserDocumentService }, { token: UserEducationService }, { token: UserDetailService }, { token: UserExperienceService }, { token: i1$4.TokenService }, { token: i1$4.RoleContextService }, { token: ProvidersService }, { token: FrontEndProvidersService }, { token: LIBRARY_CONFIG }], target: i0.ɵɵFactoryTarget.Component });
|
|
6376
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: PreviewComponent, isStandalone: true, selector: "app-preview", inputs: { providerId: "providerId", isResume: "isResume", resumeModel: "resumeModel", providerName: "providerName", roleData: "roleData", cloudfrontUrl: "cloudfrontUrl", signatureFileId: "signatureFileId", signatureUrl: "signatureUrl" }, outputs: { backToParent: "backToParent" }, viewQueries: [{ propertyName: "companyForm", first: true, predicate: ["companyForm"], descendants: true }], ngImport: i0, template: "<div class=\"preview-page-header\" *ngIf=\"!isResume\">\r\n <div class=\"d-flex align-items-center gap-2 mb-1\">\r\n <h2 class=\"preview-title mb-0\">Review Extracted Information</h2>\r\n </div>\r\n <p class=\"preview-subtitle text-muted\">We\u2019ve automatically extracted details from your uploaded resume. Please review and confirm accuracy before proceeding.</p>\r\n</div>\r\n\r\n\r\n<div [ngClass]=\"isResume ? '' : 'container py-4'\" [class.provider-layout]=\"roleData?.role?.name === 'Provider'\">\r\n\r\n <!-- Provider initial setup: combined company + personal form (shown until both APIs succeed) -->\r\n <div class=\"section mb-5\" *ngIf=\"roleData?.role?.name === 'Provider' && !hasUserDetailData\">\r\n <div class=\"d-flex align-items-center gap-2 mb-3 section-header-title\">\r\n <img src=\"/assets/images/icons/building.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Company & Personal Details</h5>\r\n <span class=\"badge border section-flag bg-warning-subtle text-warning\">Required to continue</span>\r\n </div>\r\n <div class=\"card shadow-sm border-0\">\r\n <div class=\"card-header bg-white fw-semibold\">Company Information</div>\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-3\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': (!tempCompanyDetails.companyName?.trim() && companyFormSubmitted) || companyNameError}\"\r\n [(ngModel)]=\"tempCompanyDetails.companyName\" name=\"setupCompanyName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyName?.trim() && companyFormSubmitted\">Company name is required</div>\r\n <div class=\"invalid-feedback\" *ngIf=\"companyNameError\">{{ companyNameError }}</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" maxlength=\"14\" inputmode=\"numeric\"\r\n (input)=\"phoneMask($event, 'company')\" (keypress)=\"allowOnlyNumbers($event)\"\r\n [ngClass]=\"{'is-invalid': companyFormSubmitted && (!tempCompanyDetails.companyPhoneNumber?.trim() || getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10)}\"\r\n [(ngModel)]=\"tempCompanyDetails.companyPhoneNumber\" name=\"setupCompanyPhone\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted\">Company phone is required</div>\r\n <div class=\"invalid-feedback\" *ngIf=\"tempCompanyDetails.companyPhoneNumber?.trim() && getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10 && companyFormSubmitted\">Company phone must be 10 digits</div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Company Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempCompanyDetails.address1\" name=\"setupCompanyAddress\"\r\n [options]=\"options\" inputClass=\"form-control form-control-sm\"\r\n [invalid]=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\">Address is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.city?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.city\" name=\"setupCompanyCity\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.city?.trim() && companyFormSubmitted\">City is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.state?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.state\" name=\"setupCompanyState\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.state?.trim() && companyFormSubmitted\">State is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.zipcode?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.zipcode\" name=\"setupCompanyZip\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.zipcode?.trim() && companyFormSubmitted\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.country?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.country\" name=\"setupCompanyCountry\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.country?.trim() && companyFormSubmitted\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <input type=\"file\" accept=\".png,.jpg,.jpeg\" class=\"form-control form-control-sm\" (change)=\"uploadCompanyImage($event)\" name=\"setupCompanyLogo\" />\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"tempCompanyLogoUrl\">\r\n <label class=\"small text-muted d-block\">Logo Preview</label>\r\n <img [src]=\"tempCompanyLogoUrl\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-header bg-white fw-semibold border-top\">Personal Information</div>\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-3\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">First Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.firstName?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.firstName\" name=\"setupFirstName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.firstName?.trim() && companyFormSubmitted\">First name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.lastName?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.lastName\" name=\"setupLastName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.lastName?.trim() && companyFormSubmitted\">Last name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Email <span class=\"text-danger\">*</span></label>\r\n <input type=\"email\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.email?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.email\" name=\"setupEmail\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.email?.trim() && companyFormSubmitted\">Email is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Phone Number <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" maxlength=\"14\" inputmode=\"numeric\"\r\n (input)=\"phoneMask($event, 'profile')\" (keypress)=\"allowOnlyNumbers($event)\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.phone?.trim() && companyFormSubmitted}\"\r\n [ngModel]=\"tempProfile?.phone\" name=\"setupPhone\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.phone?.trim() && companyFormSubmitted\">Phone number is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempProfile.address\" name=\"setupAddress\" [options]=\"options\"\r\n inputClass=\"form-control form-control-sm\" [invalid]=\"!tempProfile?.address?.trim() && companyFormSubmitted\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.address?.trim() && companyFormSubmitted\">Home address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.city?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.city\" name=\"setupUserCity\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.city?.trim() && companyFormSubmitted\">City is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.state?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.state\" name=\"setupUserState\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.state?.trim() && companyFormSubmitted\">State is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.zipCode?.trim() && companyFormSubmitted}\"\r\n [ngModel]=\"tempProfile?.zipCode\" (ngModelChange)=\"tempProfile.zipCode = sanitizeZipCode($event)\"\r\n name=\"setupUserZip\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.zipCode?.trim() && companyFormSubmitted\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.country?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.country\" name=\"setupUserCountry\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.country?.trim() && companyFormSubmitted\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [(ngModel)]=\"tempProfile.jobTitle\" name=\"setupJobTitle\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control form-control-sm\" [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n [ngClass]=\"{'is-invalid': !(tempProfile?.yearsOfExperience > 0) && companyFormSubmitted}\"\r\n name=\"setupYearsOfExp\" min=\"1\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!(tempProfile?.yearsOfExperience > 0) && companyFormSubmitted\">Years of experience is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Profile Picture</label>\r\n <input #setupHeadshotFile type=\"file\" accept=\".png,.jpg,.jpeg\" class=\"d-none\" (change)=\"uploadHeadshotImage($event)\" name=\"setupHeadshotFile\" />\r\n <div class=\"position-relative\">\r\n <input type=\"text\" class=\"form-control form-control-sm pe-5\" [value]=\"headshotFileName\" readonly\r\n placeholder=\"Upload Profile Picture\" (click)=\"setupHeadshotFile.click()\" />\r\n <img *ngIf=\"!isHeadshotLoading\" src=\"assets/images/icons/upload.svg\" alt=\"Upload\" class=\"upload-icon\" style=\"position:absolute;right:12px;top:50%;transform:translateY(-50%);cursor:pointer;width:18px;\" (click)=\"setupHeadshotFile.click()\" />\r\n <div *ngIf=\"isHeadshotLoading\" style=\"position:absolute;right:12px;top:50%;transform:translateY(-50%);\">\r\n <span class=\"spinner-border spinner-border-sm text-primary\"></span>\r\n </div>\r\n </div>\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"headshotPreviewUrl\">\r\n <label class=\"small text-muted d-block\">Preview</label>\r\n <img [src]=\"cloudfrontUrl + headshotPreviewUrl\" class=\"img-thumbnail rounded-circle\" style=\"width:64px;height:64px;object-fit:cover;\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-footer d-flex align-items-center justify-content-end gap-2\">\r\n <span *ngIf=\"providerSetupError\" class=\"small text-danger me-auto\">{{ providerSetupError }}</span>\r\n <button class=\"btn btn-success px-5 \"\r\n [disabled]=\"isSavingProviderSetup || !isProviderSetupFormComplete\"\r\n (click)=\"saveProviderSetup()\">\r\n <span *ngIf=\"isSavingProviderSetup\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingProviderSetup ? 'Saving...' : 'Save & Continue' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\" *ngIf=\"roleData?.role?.name !== 'Provider' || hasUserDetailData\">\r\n <div *ngIf=\"details() as data; else loading\">\r\n <div class=\"card shadow-sm border-0 rounded-3 overflow-hidden\" *ngIf=\"!isEditMode()\">\r\n <div class=\"card-body p-0\">\r\n <div class=\"preview-card-gradient\">\r\n <div class=\"d-flex justify-content-between align-items-start mb-4\">\r\n <div class=\"d-flex align-items-start gap-3\">\r\n <div class=\"profile-avatar-circle\" *ngIf=\"!headshotPreviewUrl\">\r\n {{ (data.firstName?.[0] || '') }}{{ (data.lastName?.[0] || '') }}\r\n </div>\r\n <img *ngIf=\"headshotPreviewUrl\" [src]=\" cloudfrontUrl + headshotPreviewUrl\"\r\n class=\"rounded-circle\" style=\"width:56px;height:56px;object-fit:cover;\" alt=\"Profile\" />\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h2 class=\"fw-bold mb-1\">{{ data.firstName }} {{ data.lastName }}</h2>\r\n <span *ngIf=\"basicSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n <span class=\"badge border section-flag\"\r\n [ngClass]=\"basicDetailsSaved ? 'bg-success-subtle text-success' : 'bg-warning-subtle text-warning'\">\r\n {{ basicDetailsSaved ? 'Saved' : 'Not saved yet' }}\r\n </span>\r\n </div>\r\n <p class=\"text-muted\">{{ data.jobTitle }} \u2022 {{ data.yearsOfExperience }} Years Exp.</p>\r\n <div *ngIf=\"basicIssues().length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ basicIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <span class=\"badge bg-primary-subtle text-primary border p-2\">Email Verified</span>\r\n </div>\r\n\r\n </div>\r\n <div class=\"px-4 py-3\">\r\n <div class=\"row g-4\">\r\n <div class=\"col-12 border-bottom pb-2\">\r\n <h6 class=\"text-uppercase small fw-bold text-muted\">Summary</h6>\r\n <p class=\"text-secondary small mb-0\">{{ data.summary }}</p>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/envelope.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Email</span>\r\n <span class=\"field-value-sm d-block\">{{ data.email }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/telephone.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Phone</span>\r\n <span class=\"field-value-sm d-block\">{{ data.phone }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/geo-alt.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Location</span>\r\n <span class=\"field-value-sm d-block\">{{ data.address }}, {{ data.city }}, {{ data.state }}, {{ data.zipCode }}, {{ data.country }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer d-flex align-items-center justify-content-between\">\r\n <span *ngIf=\"!basicDetailsSaved\" class=\"small text-warning fw-semibold\">\r\n <img src=\"/assets/images/icons/exclamation-circle.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" /> Click \"Edit\" to review and save your basic info.\r\n </span>\r\n <span *ngIf=\"basicDetailsSaved\" class=\"small text-success fw-semibold\">\r\n <img src=\"/assets/images/icons/check-circle.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" /> Basic details saved.\r\n </span>\r\n <button class=\"btn btn-sm btn-primary px-4 ms-auto\" (click)=\"toggleEdit()\">Edit</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"isEditMode()\">\r\n <div class=\"card-header bg-white fw-bold\">Update Profile</div>\r\n <div class=\"card-body p-4\">\r\n <form class=\"row g-3\" #basicForm=\"ngForm\" novalidate>\r\n <div *ngIf=\"basicIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ basicIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">First Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.firstName\" name=\"fName\"\r\n placeholder=\"First Name\" required #fName=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"fName.invalid && (fName.dirty || fName.touched)\">First name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.lastName\" name=\"lName\"\r\n placeholder=\"Last Name\" required #lName=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"lName.invalid && (lName.dirty || lName.touched)\">Last name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Email <span class=\"text-danger\">*</span></label>\r\n <input type=\"email\" class=\"form-control\" [(ngModel)]=\"tempProfile.email\" name=\"email\" placeholder=\"Email\"\r\n required email #email=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"email.invalid && (email.dirty || email.touched)\">\r\n <span *ngIf=\"email.errors?.['required']\">Email is required</span>\r\n <span *ngIf=\"email.errors?.['email']\">Email format is invalid</span>\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Phone Number <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"tempProfile.phone\" (input)=\"phoneMask($event, 'profile')\"\r\n name=\"phone\" placeholder=\"Phone (10 digits)\" (keypress)=\"allowOnlyNumbers($event)\"\r\n required pattern=\"^\\(\\d{3}\\) \\d{3}-\\d{4}$\" maxlength=\"14\" inputmode=\"numeric\" #phone=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"phone.invalid && (phone.dirty || phone.touched)\">\r\n <span *ngIf=\"phone.errors?.['required']\">Phone number is required</span>\r\n <span *ngIf=\"phone.errors?.['pattern']\">Phone number must be 10 digits</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\"></span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.jobTitle\" name=\"jobTitle\"\r\n placeholder=\"Job Title\" #jobTitle=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"jobTitle.invalid && (jobTitle.dirty || jobTitle.touched)\">Job\r\n title is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngClass]=\"{'is-invalid': !(tempProfile?.yearsOfExperience > 0)}\"\r\n [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n name=\"yearsOfExperience\" placeholder=\"Years of Experience\" required min=\"1\"\r\n #yearsOfExperience=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!(tempProfile?.yearsOfExperience > 0)\">\r\n Years of experience is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempProfile.address\" name=\"address\" [options]=\"options\"\r\n placeholder=\"Home Address\" required #address=\"ngModel\"\r\n [invalid]=\"address.invalid && (address.dirty || address.touched)\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"></im-address-verify-field>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"address.invalid && (address.dirty || address.touched)\">Home\r\n address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.city\" name=\"city\" placeholder=\"City\"\r\n required #city=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"city.invalid && (city.dirty || city.touched)\">City is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.state\" name=\"state\" placeholder=\"State\"\r\n required #state=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"state.invalid && (state.dirty || state.touched)\">State is\r\n required</div>\r\n </div>\r\n\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"tempProfile.zipCode\"\r\n (ngModelChange)=\"tempProfile.zipCode = sanitizeZipCode($event)\" name=\"zipCode\" placeholder=\"Zip Code\"\r\n required pattern=\"^\\d{1,6}$\" maxlength=\"6\" inputmode=\"numeric\" #zipCode=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"zipCode.invalid && (zipCode.dirty || zipCode.touched)\">Zip code\r\n is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"zipCode.errors?.['pattern'] && (zipCode.dirty || zipCode.touched)\">\r\n Zip code must be up to 6 digits\r\n </div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.country\" name=\"country\"\r\n placeholder=\"Country\" required #country=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"country.invalid && (country.dirty || country.touched)\">Country\r\n is required</div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Summary</label>\r\n <textarea class=\"form-control\" rows=\"3\" [(ngModel)]=\"tempProfile.summary\" name=\"sum\"\r\n placeholder=\"Summary\"></textarea>\r\n </div>\r\n\r\n\r\n </form>\r\n </div>\r\n <div class=\"card-footer text-end gap-2 d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancel()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingBasic || !isBasicFormValid\" (click)=\"save()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Saving...' : 'Save Changes' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5 provider-company-first\" *ngIf=\"roleData?.role?.name === 'Provider' && hasUserDetailData && !hasRoleContextUserId\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/building.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Company Details</h5>\r\n <span *ngIf=\"companyDetailsSaved\"\r\n class=\"badge border section-flag bg-success-subtle text-success\">\r\n Saved\r\n </span>\r\n <span *ngIf=\"!companyDetailsSaved\"\r\n class=\"badge border section-flag bg-warning-subtle text-warning\">\r\n Not saved yet\r\n </span>\r\n </div>\r\n <button class=\"btn btn-sm btn-primary px-4\" (click)=\"toggleCompanyEdit()\">Edit</button>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"!isCompanyEditMode()\">\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-4\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name</label>\r\n <span class=\"fw-bold small\">{{ companyDetails()?.companyName}}</span>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone</label>\r\n <span class=\"fw-bold small\">{{ companyDetails()?.companyPhoneNumber}}</span>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Company Address</label>\r\n <span class=\"small\">{{ companyDetails()?.address1}}, {{ companyDetails()?.city}}, {{ companyDetails()?.state}}, {{ companyDetails()?.zipcode}}, {{ companyDetails()?.country}}</span>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"companyLogoUrl()\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <img [src]=\"companyLogoUrl()\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"isCompanyEditMode()\">\r\n <div class=\"card-header bg-white fw-bold\">Update Company Details</div>\r\n <div class=\"card-body p-4\">\r\n <form class=\"row g-3\" #companyForm=\"ngForm\" novalidate>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': (!tempCompanyDetails.companyName?.trim() && companyFormSubmitted) || companyNameError }\"\r\n [(ngModel)]=\"tempCompanyDetails.companyName\" name=\"companyName\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyName?.trim() && companyFormSubmitted\">\r\n Company name is required\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"companyNameError\">\r\n {{ companyNameError }}\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone <span class=\"text-danger\">*</span></label>\r\n <input (input)=\"phoneMask($event, 'company')\" type=\"text\" maxlength=\"14\" (keypress)=\"allowOnlyNumbers($event)\" inputmode=\"numeric\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{ 'is-invalid': companyFormSubmitted && (!tempCompanyDetails.companyPhoneNumber?.trim() || getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10) }\"\r\n [(ngModel)]=\"tempCompanyDetails.companyPhoneNumber\" name=\"companyPhoneNumber\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted\">\r\n Company phone is required\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"tempCompanyDetails.companyPhoneNumber?.trim() && getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10 && companyFormSubmitted\">\r\n Company phone must be 10 digits\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempCompanyDetails.address1\" name=\"address1\" [options]=\"options\"\r\n required [invalid]=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\">\r\n Address is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.city?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.city\" name=\"city\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.city?.trim() && companyFormSubmitted\">\r\n City is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.state?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.state\" name=\"state\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.state?.trim() && companyFormSubmitted\">\r\n State is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.zipcode?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.zipcode\" name=\"zipcode\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.zipcode?.trim() && companyFormSubmitted\">\r\n Zip code is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.country?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.country\" name=\"country\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.country?.trim() && companyFormSubmitted\">\r\n Country is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <input #uploadCompanyFile type=\"file\" accept=\".png,.jpg,.jpeg\" (change)=\"uploadCompanyImage($event)\" class=\"form-control\" />\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"tempCompanyLogoUrl\">\r\n <label class=\"small text-muted d-block\">Logo Preview</label>\r\n <img [src]=\"tempCompanyLogoUrl\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </form>\r\n </div>\r\n <div class=\"card-footer text-end gap-2 d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelCompanyEdit()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCompany\" \r\n (click)=\"saveCompanyDetails()\">\r\n <span *ngIf=\"isSavingCompany\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCompany ? 'Saving...' : 'Save Changes' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div [class.section-locked]=\"roleData?.role?.name === 'Provider' && !hasUserDetailData\">\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/briefcase-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Work Experience</h5>\r\n <span *ngIf=\"experience().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"workSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ workSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"experience().length === 0 || !workSectionHasUnsavedItems() || isSavingWork || isAddingJob() || editingJobIndex() !== null\"\r\n (click)=\"confirmAllWork()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add work experience\" (click)=\"addJob()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"experience().length === 0 && !isAddingJob()\" class=\"empty-state-wrap mb-3\" role=\"button\"\r\n (click)=\"addJob()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/briefcase.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No work experience added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3\">\r\n <div *ngIf=\"isAddingJob() && tempJob()\" class=\"list-group-item p-0 border-0\">\r\n <div class=\"form-panel mb-2\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\" name=\"newJobTitle\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\" name=\"newCompany\" />\r\n </div>\r\n <div class=\"align-items-end col-md-12 d-flex justify-content-end pe-3\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\" name=\"newIsCurrent\" id=\"newIsCurrent\" />\r\n <label class=\"form-check-label\" for=\"newIsCurrent\">Current</label>\r\n </div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.country\"\r\n (ngModelChange)=\"patchTempJob({ country: $event })\" name=\"newCountry\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.state\"\r\n (ngModelChange)=\"patchTempJob({ state: $event })\" name=\"newState\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\" name=\"newCity\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempJob()?.startDate)\"\r\n (bsValueChange)=\"setTempJobMonth('startDate', $event)\" name=\"newStartDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.startDate)\">Start date is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"monthInputToDate(tempJob()?.endDate)\" (bsValueChange)=\"setTempJobMonth('endDate', $event)\"\r\n name=\"newEndDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">End date is\r\n required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isMonthRangeInvalid(tempJob()?.startDate, tempJob()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Responsibilities (one per line)</label>\r\n <textarea rows=\"4\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\" name=\"newResponsibilities\"></textarea>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\" name=\"newWorkAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempJob()?.fileName\">\r\n <span>{{ tempJob()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempJob())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n <div class=\"d-flex justify-content-end gap-2 mt-3\">\r\n <button class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingWork\"\r\n (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : workActionLabel(editingJobIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n\r\n <div *ngFor=\"let job of experience(); let i = index\" class=\"list-group-item p-0 border-0 mb-2\">\r\n\r\n <div class=\"work-accent-item p-3 rounded-3 bg-white border\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div class=\"d-flex align-items-center cursor-pointer flex-grow-1\" (click)=\"toggleJob(i)\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h6 class=\"mb-0 fw-bold item-title-sm\">{{ job.jobTitle }}</h6>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedWorkItem(i) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedWorkItem(i) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ job.company || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ formatMonthYear(job.startDate) }} - {{ job.isCurrent ? 'Present' :\r\n formatMonthYear(job.endDate) }}</span>\r\n <span class=\"item-meta-line\">{{ job.city }}<span *ngIf=\"job.city && job.state\">, </span>{{ job.state }}<ng-container *ngIf=\"!job.city && !job.state\">\u2014</ng-container></span>\r\n <div *ngIf=\"editingJobIndex() !== i && (workIssuesByIndex()[i] || []).length > 0\"\r\n class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (workIssuesByIndex()[i] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center gap-2\">\r\n\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\" (click)=\"startEditJob(i)\"\r\n title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteJob(i);\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n \r\n </div>\r\n </div>\r\n\r\n\r\n\r\n <div class=\"mt-3 p-3 rounded small\" *ngIf=\"expandedIndex() === i\">\r\n <ng-container *ngIf=\"editingJobIndex() !== i; else editJobForm\">\r\n <ul class=\"mb-0\">\r\n <li *ngFor=\"let res of job.responsibilities\">{{ res }}</li>\r\n </ul>\r\n </ng-container>\r\n\r\n <ng-template #editJobForm>\r\n <div *ngIf=\"(workIssuesByIndex()[i] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (workIssuesByIndex()[i] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\" name=\"jobTitle{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.jobTitle)\">Job title is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\" name=\"company{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.company)\">Company name is required</div>\r\n </div>\r\n\r\n <div class=\"align-items-end col-md-12 d-flex justify-content-end pe-3\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\" name=\"isCurrent{{ i }}\" id=\"isCurrent{{ i }}\" />\r\n <label class=\"form-check-label\" for=\"isCurrent{{ i }}\">Current</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.country\"\r\n (ngModelChange)=\"patchTempJob({ country: $event })\" name=\"country{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.state\"\r\n (ngModelChange)=\"patchTempJob({ state: $event })\" name=\"state{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\" name=\"city{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.city)\">City is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempJob()?.startDate)\"\r\n (bsValueChange)=\"setTempJobMonth('startDate', $event)\" name=\"startDate{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.startDate)\">Start date is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"monthInputToDate(tempJob()?.endDate)\" (bsValueChange)=\"setTempJobMonth('endDate', $event)\"\r\n name=\"endDate{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">\r\n End date is required\r\n </div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isMonthRangeInvalid(tempJob()?.startDate, tempJob()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Responsibilities (one per line)</label>\r\n <textarea rows=\"4\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\" name=\"responsibilities{{ i }}\"></textarea>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\" name=\"workAttachment{{ i }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempJob()?.fileName\">\r\n <span>{{ tempJob()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempJob())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n </ng-template>\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-3\" *ngIf=\"editingJobIndex() === i\">\r\n <button class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4 \" [disabled]=\"isSavingWork\"\r\n (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : workActionLabel(editingJobIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/patch-check-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Certifications</h5>\r\n <span *ngIf=\"certs().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"certificationSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ certificationSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"certs().length === 0 || !certificationSectionHasUnsavedItems() || isSavingCertification || isAddingCertification() || editingCertificationIndex() !== null\"\r\n (click)=\"confirmAllCertifications()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add certification\" (click)=\"addCertification()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"certs().length === 0 && !isAddingCertification() && editingCertificationIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addCertification()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/patch-check.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No certifications added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3 border\">\r\n <div *ngIf=\"isAddingCertification() && tempCertification()\" class=\"list-group-item py-3 px-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\" name=\"newCertName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\" name=\"newCertOrg\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\" name=\"newCertState\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certification Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\" name=\"newCertCredentialId\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('issueDate', $event)\" name=\"newCertIssueDate\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('expiryDate', $event)\" name=\"newCertExpiryDate\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempCertification()?.issueDate || null, tempCertification()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\" name=\"newCertAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempCertification()?.fileName\">\r\n <span>{{ tempCertification()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempCertification())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\"\r\n (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : certificationActionLabel(editingCertificationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let cert of certs(); let ci = index\" class=\"list-group-item py-3 cert-accent-item\">\r\n <ng-container *ngIf=\"editingCertificationIndex() !== ci; else editCert\">\r\n <div class=\"d-flex justify-content-between align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <div class=\"fw-semibold item-title-sm\">{{ cert.name }}</div>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedCertificationItem(ci) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedCertificationItem(ci) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ cert.issuingOrganization || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.credentialId || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.issueDate ? formatMonthYear(cert.issueDate) : '\u2014' }} - {{ cert.expiryDate ? formatMonthYear(cert.expiryDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.state || '\u2014' }}</span>\r\n <div *ngIf=\"(certIssuesByIndex()[ci] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (certIssuesByIndex()[ci] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditCertification(ci)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteCertification(ci)\" title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #editCert>\r\n <div *ngIf=\"(certIssuesByIndex()[ci] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (certIssuesByIndex()[ci] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\" name=\"certName{{ ci }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\"\r\n name=\"certOrg{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\" name=\"certState{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certification Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\"\r\n name=\"certCredentialId{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('issueDate', $event)\" name=\"certIssue{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('expiryDate', $event)\" name=\"certExpiry{{ ci }}\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempCertification()?.issueDate || null, tempCertification()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\" name=\"certAttachment{{ ci }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempCertification()?.fileName\">\r\n <span>{{ tempCertification()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempCertification())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\"\r\n (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : certificationActionLabel(editingCertificationIndex()) }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/card-checklist-warning.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Licenses</h5>\r\n <span *ngIf=\"licenses().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"licenseSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ licenseSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"licenses().length === 0 || !licenseSectionHasUnsavedItems() || isSavingLicense || isAddingLicense() || editingLicenseIndex() !== null\"\r\n (click)=\"confirmAllLicenses()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add license\" (click)=\"addLicense()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"licenses().length === 0 && !isAddingLicense() && editingLicenseIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addLicense()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/card-checklist.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No licenses added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3 border\">\r\n <div *ngIf=\"isAddingLicense() && tempLicense()\" class=\"list-group-item py-3 px-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\" name=\"newLicName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempLicense()?.name)\">License name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\" name=\"newLicAuthority\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\" name=\"newLicNumber\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\" name=\"newLicState\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('issueDate', $event)\" name=\"newLicIssueDate\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('expiryDate', $event)\" name=\"newLicExpiryDate\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempLicense()?.issueDate || null, tempLicense()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">License File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\" name=\"newLicenseAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempLicense()?.fileName\">\r\n <span>{{ tempLicense()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempLicense())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelEditLicense()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingLicense\"\r\n (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : licenseActionLabel(editingLicenseIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let lic of licenses(); let li = index\" class=\"list-group-item py-3 lic-accent-item\">\r\n <ng-container *ngIf=\"editingLicenseIndex() !== li; else editLic\">\r\n <div class=\"d-flex justify-content-between align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <div class=\"fw-semibold item-title-sm\">{{ lic.name }}</div>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedLicenseItem(li) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedLicenseItem(li) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ lic.issuingAuthority || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.licenseNumber || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.issueDate ? formatMonthYear(lic.issueDate) : '\u2014' }} - {{ lic.expiryDate ? formatMonthYear(lic.expiryDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.state || '\u2014' }}</span>\r\n <div *ngIf=\"(licenseIssuesByIndex()[li] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (licenseIssuesByIndex()[li] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditLicense(li)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteLicense(li)\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #editLic>\r\n <div *ngIf=\"(licenseIssuesByIndex()[li] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (licenseIssuesByIndex()[li] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\" name=\"licName{{ li }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempLicense()?.name)\">License name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\" name=\"licAuthority{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\" name=\"licNumber{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\" name=\"licState{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('issueDate', $event)\" name=\"licIssue{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('expiryDate', $event)\" name=\"licExpiry{{ li }}\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempLicense()?.issueDate || null, tempLicense()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">License File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\" name=\"licenseAttachment{{ li }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempLicense()?.fileName\">\r\n <span>{{ tempLicense()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempLicense())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditLicense()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingLicense\"\r\n (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : licenseActionLabel(editingLicenseIndex()) }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/tools.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Tools</h5>\r\n <span *ngIf=\"tools().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"toolsSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ toolsSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"tools().length === 0 || !toolsSectionHasUnsavedItems() || isSavingTool || isToolEditorOpen()\" (click)=\"confirmAllTools()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add tool\" (click)=\"addTool()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex flex-wrap gap-2 p-3 bg-white border rounded shadow-sm\">\r\n <div *ngFor=\"let tool of tools(); let ti = index\" class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\"\r\n class=\"btn btn-light border res-flex d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openToolEditor(ti)\" title=\"Edit\">\r\n <span class=\"fw-normal item-name-text\">{{ tool }}</span>\r\n <span class=\"badge border ms-1\"\r\n [ngClass]=\"hasUnsavedToolItem(ti) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedToolItem(ti) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n <span *ngIf=\"(toolIssuesByIndex()[ti] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\">\r\n Missing info\r\n </span>\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Delete tool\" (click)=\"deleteTool(ti)\">\r\n <span class=\"fw-bold\">\u00D7</span>\r\n </button>\r\n </div>\r\n\r\n <span *ngIf=\"tools().length === 0\" class=\"text-muted small\">No tools added.</span>\r\n </div>\r\n\r\n <div *ngIf=\"isToolEditorOpen()\" class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 9999999;\" (click)=\"closeToolEditor()\">\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\"\r\n (click)=\"$event.stopPropagation()\">\r\n <div class=\"card shadow border-0 w-100\" style=\"max-width: 900px;\">\r\n <div class=\"card-header bg-white d-flex align-items-center gap-3\">\r\n <button type=\"button\" class=\"btn btn-link p-0 text-decoration-none\" (click)=\"closeToolEditor()\">\r\n <img src=\"/assets/images/icons/arrow-left-blue.svg\" width=\"20\" height=\"20\" alt=\"\" />\r\n </button>\r\n <div class=\"fw-bold\">{{ isAddingTool() ? 'Add Tool' : ('Edit ' + (toolForm()?.name || '') + ' Tool') }}\r\n </div>\r\n </div>\r\n <div class=\"card-body p-4\">\r\n <div *ngIf=\"toolFormIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ toolFormIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"row g-3\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Tool Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"toolForm()?.name\"\r\n (ngModelChange)=\"patchToolForm({ name: $event })\" name=\"toolName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(toolForm()?.name)\">Tool name is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span\r\n class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempToolStars(s)\" [attr.aria-label]=\"'Set rating ' + s\">\r\n <span [class]=\"(toolForm()?.stars || 0) >= s ? 'text-warning fs-5' : 'text-muted fs-5'\">\r\n {{ (toolForm()?.stars || 0) >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ toolForm()?.stars || 0 }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"(toolForm()?.stars || 0) <= 0\">Star rating is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngModel]=\"toolForm()?.year\"\r\n (ngModelChange)=\"patchToolForm({ year: $event === '' ? null : +$event })\" name=\"toolYear\" min=\"1\"\r\n max=\"30\" placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"toolForm()?.year === null || toolForm()?.year === undefined\">\r\n Years of experience is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4 text-center\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-checks form-switch mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"toolForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchToolForm({ profileVisibility: $event })\" name=\"toolVisible\" id=\"toolVisible\"\r\n style=\"width: 55px;height: 25px;margin-left: -57px;\" />\r\n <label class=\"form-check-label ps-2 pt-1\" for=\"toolVisible\">Visible</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Comment</label>\r\n <textarea rows=\"4\" class=\"form-control\" [ngModel]=\"toolForm()?.notes\"\r\n (ngModelChange)=\"patchToolForm({ notes: $event })\" name=\"toolNotes\"\r\n placeholder=\"Comment your tool here...\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-white d-flex justify-content-end gap-2\">\r\n <button *ngIf=\"!isAddingTool() && editingToolIndex() !== null\" type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\" (click)=\"deleteTool(editingToolIndex()!)\">\r\n Delete\r\n </button>\r\n <button type=\"button\" class=\"btn btn-link text-secondary\" (click)=\"closeToolEditor()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary px-4\" [disabled]=\"isSavingTool\" (click)=\"saveToolEditor()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Saving...' : toolActionLabel(editingToolIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row g-4 mb-5\">\r\n <div class=\"col-md-12\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/stars.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Skills</h5>\r\n <span *ngIf=\"skills().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"skillsSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ skillsSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"skills().length === 0 || !skillsSectionHasUnsavedItems() || isSavingSkill || isSkillEditorOpen()\" (click)=\"confirmAllSkills()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add skill\" (click)=\"addSkill()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex flex-wrap gap-2 p-3 bg-white border rounded shadow-sm\">\r\n <div *ngFor=\"let skill of skills(); let si = index\" class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\"\r\n class=\"btn btn-light border res-flex d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openSkillEditor(si)\" title=\"Edit\">\r\n <span class=\"fw-normal item-name-text\">{{ skill }}</span>\r\n <span class=\"badge border ms-1\"\r\n [ngClass]=\"hasUnsavedSkillItem(si) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedSkillItem(si) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n <span *ngIf=\"(skillIssuesByIndex()[si] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\">\r\n Missing info\r\n </span>\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Delete skill\"\r\n (click)=\"deleteSkill(si); $event.stopPropagation()\">\r\n <span class=\"fw-bold\">\u00D7</span>\r\n </button>\r\n </div>\r\n\r\n <span *ngIf=\"skills().length === 0\" class=\"text-muted small\">No skills added.</span>\r\n </div>\r\n <div *ngIf=\"isSkillEditorOpen()\" class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 9999999;\" (click)=\"closeSkillEditor()\">\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\"\r\n (click)=\"$event.stopPropagation()\">\r\n <div class=\"card shadow border-0 w-100\" style=\"max-width: 900px;\">\r\n <div class=\"card-header bg-white d-flex align-items-center gap-3\">\r\n <button type=\"button\" class=\"btn btn-link p-0 text-decoration-none\" (click)=\"closeSkillEditor()\">\r\n <img src=\"/assets/images/icons/arrow-left-blue.svg\" width=\"20\" height=\"20\" alt=\"\" />\r\n </button>\r\n <div class=\"fw-bold\">{{ isAddingSkill() ? 'Add Skill' : ('Edit ' + (skillForm()?.name || '') + ' Skill')\r\n }}</div>\r\n </div>\r\n <div class=\"card-body p-4\">\r\n <div *ngIf=\"skillFormIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ skillFormIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"row g-3\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Skills Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"skillForm()?.name\"\r\n (ngModelChange)=\"patchSkillForm({ name: $event })\" name=\"skillName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(skillForm()?.name)\">Skillset name is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span\r\n class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempSkillStars(s)\" [attr.aria-label]=\"'Set rating ' + s\">\r\n <span [class]=\"(skillForm()?.stars || 0) >= s ? 'text-warning fs-5' : 'text-muted fs-5'\">\r\n {{ (skillForm()?.stars || 0) >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ skillForm()?.stars || 0 }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"(skillForm()?.stars || 0) <= 0\">Star rating is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngModel]=\"skillForm()?.year\"\r\n (ngModelChange)=\"patchSkillForm({ year: $event === '' ? null : +$event })\" name=\"skillYear\" min=\"1\"\r\n max=\"30\" placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"skillForm()?.year === null || skillForm()?.year === undefined\">Years of experience is\r\n required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4 text-center\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-checks form-switch mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"skillForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchSkillForm({ profileVisibility: $event })\" name=\"skillVisible\"\r\n id=\"skillVisible\" style=\"width: 55px;height: 25px;margin-left: -57px;\" />\r\n <label class=\"form-check-label ps-2 pt-1\" for=\"skillVisible\">Visible</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Comment</label>\r\n <textarea rows=\"4\" class=\"form-control\" [ngModel]=\"skillForm()?.notes\"\r\n (ngModelChange)=\"patchSkillForm({ notes: $event })\" name=\"skillNotes\"\r\n placeholder=\"Comment your skill here...\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-white d-flex justify-content-end gap-2\">\r\n <button *ngIf=\"!isAddingSkill() && editingSkillIndex() !== null\" type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\" (click)=\"deleteSkill(editingSkillIndex()!)\">\r\n Delete\r\n </button>\r\n <button type=\"button\" class=\"btn btn-link text-secondary\" (click)=\"closeSkillEditor()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary px-4\" [disabled]=\"isSavingSkill\" (click)=\"saveSkillEditor()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Saving...' : skillActionLabel(editingSkillIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row g-4 mb-5\">\r\n <div class=\"col-md-12\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/mortarboard-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Education</h5>\r\n <span *ngIf=\"educationList().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"educationSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ educationSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"educationList().length === 0 || !educationSectionHasUnsavedItems() || isSavingEducation || isAddingEducation() || editingEducationIndex() !== null\"\r\n (click)=\"confirmAllEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add education\" (click)=\"addEducation()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"educationList().length === 0 && !isAddingEducation() && editingEducationIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addEducation()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/mortarboard.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No education added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div *ngIf=\"isAddingEducation() && tempEducation()\" class=\"mb-2\">\r\n <div class=\"form-panel\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\" name=\"newEduDegree\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Institution <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\" name=\"newEduInstitution\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree / Course Type <span class=\"text-danger\">*</span></label>\r\n <ng-select class=\"ng-select-sm\" [items]=\"educationDegreeTypeOptions\" [clearable]=\"false\"\r\n placeholder=\"Select degree / course type\" [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\" name=\"newEduDegreeType\">\r\n </ng-select>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.country\"\r\n (ngModelChange)=\"patchTempEducation({ country: $event })\" name=\"newEduCountry\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.state\"\r\n (ngModelChange)=\"patchTempEducation({ state: $event })\" name=\"newEduState\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\" name=\"newEduCity\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.startDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('startDate', $event)\" name=\"newEduStartDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.startDate)\">Start date is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.endDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('endDate', $event)\" name=\"newEduEndDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Education File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onEducationFileSelected($event)\" name=\"newEducationAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempEducation()?.fileName\">\r\n <span>{{ tempEducation()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempEducation())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingEducation\"\r\n (click)=\"saveEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Uploading...' : educationActionLabel(editingEducationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let edu of educationList(); let ei = index\" class=\"edu-accent-item p-3 bg-white border rounded-3 shadow-sm mb-2\">\r\n <div class=\"d-flex justify-content-between align-items-start\">\r\n <div class=\"d-flex align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h6 class=\"fw-bold mb-0 item-title-sm\">{{ edu.degree }}</h6>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedEducationItem(ei) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedEducationItem(ei) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ edu.institution || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.degreeType || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.startDate ? formatMonthYear(edu.startDate) : '\u2014' }} - {{ edu.endDate ? formatMonthYear(edu.endDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.city }}<span *ngIf=\"edu.city && edu.state\">, </span>{{ edu.state }}<ng-container *ngIf=\"!edu.city && !edu.state\">\u2014</ng-container></span>\r\n <div *ngIf=\"(educationIssuesByIndex()[ei] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (educationIssuesByIndex()[ei] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\" *ngIf=\"editingEducationIndex() !== ei\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditEducation(ei)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteEducation(ei)\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"editingEducationIndex() === ei\" class=\"mt-3\">\r\n <div *ngIf=\"(educationIssuesByIndex()[ei] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (educationIssuesByIndex()[ei] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\" name=\"eduDegree{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Institution <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\" name=\"eduInstitution{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.institution)\">Institution name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree / Course Type <span class=\"text-danger\">*</span></label>\r\n <ng-select class=\"ng-select-sm\" [items]=\"educationDegreeTypeOptions\" [clearable]=\"false\"\r\n placeholder=\"Select degree / course type\" [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\" name=\"eduDegreeType{{ ei }}\">\r\n </ng-select>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.country\"\r\n (ngModelChange)=\"patchTempEducation({ country: $event })\" name=\"eduCountry{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.state\"\r\n (ngModelChange)=\"patchTempEducation({ state: $event })\" name=\"eduState{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\" name=\"eduCity{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.startDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('startDate', $event)\" name=\"eduStartDate{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.startDate)\">Start date is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.endDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('endDate', $event)\" name=\"eduEndDate{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Education File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onEducationFileSelected($event)\" name=\"educationAttachment{{ ei }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempEducation()?.fileName\">\r\n <span>{{ tempEducation()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempEducation())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingEducation\" (click)=\"saveEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Uploading...' : educationActionLabel(editingEducationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n </div>\r\n <div class=\"d-flex gap-3 justify-content-center mt-5 pt-2\" *ngIf=\"!isResume\">\r\n <button class=\"btn btn-outline-secondary preview-back-btn px-5 h-auto\" style=\"border-radius: 5px !important;\" (click)=\"onBackClick()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"me-1\" style=\"vertical-align:-0.1em\">\r\n <path d=\"M11 3 5 8l6 5\" />\r\n </svg> Back\r\n </button>\r\n <button class=\"btn btn-primary preview-dashboard-btn px-5 h-auto\" style=\"border-radius: 5px !important;\" [disabled]=\"!canConfirmAndContinue() || isSavingBasic\"\r\n (click)=\"onGoToDashboardClick()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Saving...' : 'Go to Dashboard' }}\r\n <img *ngIf=\"!isSavingBasic\" src=\"/assets/images/icons/arrow-right-white.svg\" width=\"14\" height=\"14\" class=\"ms-1\" style=\"vertical-align:-0.1em\" alt=\"\" />\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<ng-template #loading>\r\n <div class=\"text-center p-5\">\r\n <div class=\"spinner-border text-primary\"></div>\r\n <p class=\"text-muted mt-2\">Loading data...</p>\r\n </div>\r\n</ng-template>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBulkSkillConfirm\">\r\n <div class=\"confirm-modal-card\" style=\"max-width: 480px;\">\r\n <h4 class=\"mb-1\">Set Rating for All Skills</h4>\r\n <p class=\"text-muted small mb-4\">Enter a star rating and years of experience to apply to all skills that are missing these values.</p>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"bulkSkillStars = s\">\r\n <span [class]=\"bulkSkillStars >= s ? 'text-warning fs-4' : 'text-muted fs-4'\">\r\n {{ bulkSkillStars >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ bulkSkillStars }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkSkillStars <= 0\">Star rating is required</div>\r\n </div>\r\n <div class=\"mb-4\">\r\n <label class=\"small text-muted d-block mb-1\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [(ngModel)]=\"bulkSkillYear\" min=\"1\" max=\"30\"\r\n placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkSkillYear === null || bulkSkillYear === undefined\">Years of experience is required</div>\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"cancelBulkSkillConfirm()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingSkill || bulkSkillStars <= 0 || bulkSkillYear === null\"\r\n (click)=\"applyBulkSkillConfirm()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Saving...' : 'Apply to All & Save' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBulkToolConfirm\">\r\n <div class=\"confirm-modal-card\" style=\"max-width: 480px;\">\r\n <h4 class=\"mb-1\">Set Rating for All Tools</h4>\r\n <p class=\"text-muted small mb-4\">Enter a star rating and years of experience to apply to all tools that are missing these values.</p>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"bulkToolStars = s\">\r\n <span [class]=\"bulkToolStars >= s ? 'text-warning fs-4' : 'text-muted fs-4'\">\r\n {{ bulkToolStars >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ bulkToolStars }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkToolStars <= 0\">Star rating is required</div>\r\n </div>\r\n <div class=\"mb-4\">\r\n <label class=\"small text-muted d-block mb-1\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [(ngModel)]=\"bulkToolYear\" min=\"1\" max=\"30\"\r\n placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkToolYear === null || bulkToolYear === undefined\">Years of experience is required</div>\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"cancelBulkToolConfirm()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingTool || bulkToolStars <= 0 || bulkToolYear === null\"\r\n (click)=\"applyBulkToolConfirm()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Saving...' : 'Apply to All & Save' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBackConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Leave this page?</h4>\r\n <p class=\"text-muted mb-4\">If you go back, only saved data will be retained.</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"stayOnPreview()\">Stay</button>\r\n <button type=\"button\" class=\"btn btn-danger h-auto\" (click)=\"proceedBack()\">Proceed Back</button>\r\n </div>\r\n </div>\r\n\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showDashboardConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Finish Setup and Continue</h4>\r\n <p class=\"text-muted mb-4\">Save your information and go to your dashboard</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" [disabled]=\"isSavingBasic\"\r\n (click)=\"cancelDashboardRedirect()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingBasic\" (click)=\"goToDashboard()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Proceeding...' : 'Proceed' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{color:#69707d}.res-flex:hover,.res-flex:focus,.res-flex:active{transform:none!important;box-shadow:none!important}.container{max-width:900px;margin:30px auto;font-family:Arial,sans-serif;color:#69707d}.preview-page-header{max-width:900px;margin:50px auto 10px;padding:0 12px}.preview-title{font-size:18px;font-weight:700;color:#69707d;margin:0}.preview-subtitle{margin-top:7px;font-size:14px;color:#69707d}.preview-card-gradient h2,.section h5.fw-bold{font-size:18px}.section{margin-bottom:25px}.section-title{font-weight:600;display:block;margin-bottom:8px}.section-title .sub{font-weight:400;color:#777;font-size:13px}.dropdown-box{border:1px solid #ddd;border-radius:8px;padding:12px 15px;display:flex;justify-content:space-between;align-items:center}.icons{display:flex;gap:10px}.icon{cursor:pointer;font-size:14px;color:#777}.card{border:1px solid #ddd;border-radius:5px;padding:20px;background:#fff}.category{border-bottom:1px solid #eee;padding:15px 0}.category:last-child{border-bottom:none}.category-header{display:flex;justify-content:space-between;font-weight:600;margin-bottom:10px}.tags{display:flex;flex-wrap:wrap;gap:10px}.tag{background:#f2f4f7;padding:6px 12px;border-radius:6px;font-size:13px}.footer{text-align:center;margin-top:15px;color:#777;cursor:pointer}.actions{display:flex;justify-content:space-between;margin:50px 0 27px}.text-secondary{white-space:pre-line;font-size:12px;color:#69707d}.extra-small{font-size:.8rem}.card{transition:transform .2s ease,box-shadow .2s ease}.card:hover{transform:translateY(-3px)}.achievement-section .badge{font-size:.75rem;white-space:normal;text-align:left}.skill-tag .badge{font-weight:500;font-size:.9rem;transition:all .2s ease;cursor:default}.skill-tag .badge:hover{transform:translateY(-2px)}.skill-tag .btn-close{opacity:.5}.skill-tag .btn-close:hover{opacity:1}.bg-light.text-dark.border{background-color:#f8f9fa!important;border-color:#dee2e6!important}.card{transition:all .3s cubic-bezier(.25,.8,.25,1)}.card:hover .bg-light{background-color:#e8f5e9!important}.position-fixed .card:hover{transform:none!important}code{background-color:#f8f9fa;padding:2px 6px;border-radius:4px}.list-group-item{transition:all .2s ease-in-out}.list-group-item:hover{background-color:#fcfcfc;transform:translate(5px)}.border-dashed{border-style:dashed!important}.tool-card{transition:all .2s ease-in-out;border-radius:12px}.tool-card:hover{transform:translateY(-5px);border-color:var(--bs-primary)!important}.tool-card:hover .icon-box{background-color:var(--bs-primary-subtle)!important}.tool-card .icon-box{width:60px;height:60px;transition:background-color .2s ease}.border-dashed{border:2px dashed #dee2e6!important}.border-dashed:hover{border-color:var(--bs-primary)!important;background-color:#fff!important}.popup{position:fixed;top:20%;right:20px;width:320px;max-width:calc(100vw - 32px);background:#fff;border-radius:10px;padding:16px}.status-row{display:flex;justify-content:space-between;margin:10px 0}.success{color:#2e7d32;font-weight:700}.error{color:#d32f2f}.pending{color:#f9a825}.section-flag{font-weight:600}button.btn.btn-sm.btn-outline-primary{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:5px!important}button.btn.btn-sm.btn-outline-primary:hover{background-color:#356895;border-color:#356895;color:#fff}button.btn.btn-sm.btn-outline-danger{border:1px solid #dc3545;color:#dc3545;border-radius:5px!important}button.btn.btn-sm.btn-outline-primary.rounded-circle{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:5px!important}button.action-icon-btn{min-width:22px;width:22px;height:22px;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:5px!important;background:transparent!important;border:none!important;line-height:1}button.action-icon-btn.btn-outline-primary{color:#4077ad!important;border-color:#4077ad!important}button.action-icon-btn.btn-outline-danger{color:#dc3545!important}.action-icon-image{width:20px;height:20px;object-fit:contain;display:inline-block}.action-icon-image.edit-icon{filter:brightness(0) saturate(100%) invert(41%) sepia(39%) saturate(774%) hue-rotate(170deg) brightness(91%) contrast(89%)}.action-icon-image.delete-icon{filter:brightness(0) saturate(100%) invert(24%) sepia(79%) saturate(4008%) hue-rotate(344deg) brightness(91%) contrast(90%)}.modal-overlay{position:fixed;inset:0;background:#11182773;display:flex;align-items:center;justify-content:center;z-index:2500;padding:20px}.status-modal-card{width:min(760px,96vw);max-height:85vh;overflow:auto;background:#fff;border-radius:16px;border:1px solid #e5e7eb}.status-modal-header{padding:20px 24px 14px;border-bottom:1px solid #eef2f7}.status-modal-body{padding:12px 20px 20px}.status-modal-footer{padding:12px 20px 20px;border-top:1px solid #eef2f7;display:flex;justify-content:end;align-items:center;gap:12px}.status-modal-row{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px 10px;border-bottom:1px solid #f1f5f9}.status-modal-row:last-child{border-bottom:0}.status-modal-name{font-size:14px;font-weight:600;color:#69707d}.status-modal-state{font-size:.92rem;font-weight:600}.status-modal-state.pending{color:#a16207}.status-modal-state.success{color:#166534}.status-modal-state.partial{color:#b45309}.status-modal-state.error{color:#b91c1c}.confirm-modal-card{width:min(520px,96vw);background:#fff;border-radius:5px;border:1px solid #e5e7eb;padding:24px}.year-experience-select{max-height:150px}@media screen and (max-width: 768px){.res-flex{flex-wrap:wrap!important;justify-content:center!important}.res-flex .fw-normal{width:100%;text-align:center;font-size:14px!important}.d-flex.flex-wrap.gap-2.p-3.bg-white.border.rounded.shadow-sm{justify-content:center}.preview-page-header{margin:20px auto 8px;padding:0 4px}.container{padding-left:4px;padding-right:4px}.preview-title{font-size:16px}.preview-subtitle{font-size:14px}.actions{margin:24px 0 16px}.section-header-title{flex-wrap:wrap}.section-header-title>.section-flag{flex-basis:53%}.section-header-row{align-items:flex-start}.preview-card-gradient{padding:14px 14px 12px}.preview-card-gradient h2{font-size:18px}.popup{width:calc(100vw - 40px);right:16px;top:12%}.card{padding:0}.card-body.p-4,.px-4.py-3{padding:12px!important}.row.g-4,.row.g-3{--bs-gutter-x: .75rem}.d-flex.gap-4{gap:10px!important}.preview-card-gradient>.d-flex.justify-content-between.align-items-start{flex-wrap:wrap;row-gap:8px}.preview-card-gradient>.d-flex.justify-content-between.align-items-start>.badge.bg-primary-subtle{margin-left:auto}}@media screen and (max-width: 575px){.preview-title{font-size:16px}.preview-subtitle{font-size:14px}.section>.d-flex{flex-wrap:wrap;row-gap:8px}.section>.d-flex>.d-flex:last-child{width:100%;justify-content:flex-end}}::ng-deep .bs-datepicker-head{background-color:#4077ad!important}::ng-deep .bs-datepicker-body table td span.selected,.bs-datepicker-body table td.selected span{background-color:#4077ad!important}.profile-avatar-circle{width:58px;height:58px;border-radius:5px;background:#4077ad;display:flex;align-items:center;justify-content:center;font-size:22px;font-weight:700;color:#fff;letter-spacing:1px;flex-shrink:0}.section-header-icon{font-size:20px;line-height:1;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;opacity:.9;filter:invert(47%) sepia(8%) saturate(483%) hue-rotate(176deg) brightness(91%) contrast(87%)}.section-header-title h5.fw-bold{color:#69707d}.text-muted{color:#69707d!important}h6.text-uppercase.fw-bold.text-muted{font-size:14px;color:#69707d!important}.work-accent-item{border-left:4px solid #4077ad!important;border-radius:0 5px 5px 0!important;transition:background-color .18s ease,box-shadow .18s ease}.work-accent-item:hover{background-color:#f5f8ff!important;box-shadow:0 4px 14px #4077ad17!important}.edu-accent-item{border-left:4px solid #4077AD!important;border-radius:0 5px 5px 0!important;transition:background-color .18s ease,box-shadow .18s ease}.edu-accent-item:hover{background-color:#f8f8ff!important;box-shadow:0 4px 14px #6366f117!important}.cert-accent-item{border-left:4px solid #059669!important;border-radius:0 5px 5px 0!important;transition:background-color .18s ease}.cert-accent-item:hover{background-color:#f0fdf4!important}.lic-accent-item{border-left:4px solid #d97706!important;border-radius:0 5px 5px 0!important;transition:background-color .18s ease}.lic-accent-item:hover{background-color:#fffbeb!important}.field-label-sm{font-size:14px;font-weight:700;letter-spacing:.08em;color:#69707d;margin-bottom:3px;display:block}.item-name-text{color:#69707d}.field-value-sm{font-weight:600;font-size:12px;color:#69707d}.item-title-sm{font-size:14px;color:#69707d!important}.item-meta-line{display:block;font-size:12px;color:#69707d;margin-top:3px}.empty-state-wrap{text-align:center;padding:32px 20px;background:#fafbfc;border:1.5px dashed #d1d5db;border-radius:5px;cursor:pointer;transition:background-color .18s ease,border-color .18s ease}.empty-state-wrap .empty-icon{font-size:2rem;color:#d1d5db;margin-bottom:8px}.empty-state-wrap p{color:#9ca3af;margin:0;font-size:14px}.empty-state-wrap:hover{background:#f0f6ff;border-color:#4077ad}.form-panel{background:#fff;border:1px solid #e2e8f0;border-radius:5px;padding:20px}.form-panel .form-control,.form-panel .form-select{border-color:#d1d5db;border-radius:8px;font-size:12px}.form-panel .form-control:focus,.form-panel .form-select:focus{border-color:#4077ad;box-shadow:0 0 0 3px #4077ad1f}.section-header-bar{display:flex;align-items:center;justify-content:space-between;padding:10px 0 14px;border-bottom:2px solid #f1f5f9;margin-bottom:16px}.preview-card-gradient{background:linear-gradient(135deg,#fff,#eff6ff);border-bottom:1px solid #e2e8f0;padding:20px 24px 16px;border-radius:5px 5px 0 0}.item-icon-circle{width:40px;height:40px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:700;color:#fff;flex-shrink:0}.item-avatar--work{background:linear-gradient(135deg,#4077ad,#2d5a8a)}.item-avatar--edu{background:linear-gradient(135deg,#4077ad,#4338ca)}.provider-layout{display:flex;flex-direction:column}.provider-company-first{order:-1}.section-locked{pointer-events:none;opacity:.45;filter:blur(1.5px);-webkit-user-select:none;user-select:none}.btn.btn-primary{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-primary:hover:not(:disabled),.btn.btn-primary:focus:not(:disabled),.btn.btn-primary:active:not(:disabled){background-color:#356895!important;border-color:#356895!important;color:#fff!important}.btn.btn-success,.btn.btn-outline-success{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-success:hover:not(:disabled),.btn.btn-success:focus:not(:disabled),.btn.btn-success:active:not(:disabled),.btn.btn-outline-success:hover:not(:disabled),.btn.btn-outline-success:focus:not(:disabled),.btn.btn-outline-success:active:not(:disabled){background-color:#336843!important;border-color:#336843!important;color:#fff!important}.btn.btn-outline-secondary.rounded-pill{background-color:#69707d!important;border-color:#69707d!important;color:#fff!important;border-radius:5px!important}.btn.btn-outline-secondary.rounded-pill:hover:not(:disabled),.btn.btn-outline-secondary.rounded-pill:focus:not(:disabled),.btn.btn-outline-secondary.rounded-pill:active:not(:disabled){background-color:#565c66!important;border-color:#565c66!important;color:#fff!important}.preview-back-btn{background-color:#426c85!important;border-color:#426c85!important;color:#fff!important}.preview-dashboard-btn{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-outline-success:hover:not(:disabled),.btn.btn-outline-success:focus:not(:disabled),.btn.btn-outline-success:active:not(:disabled){background-color:transparent!important;border-color:#198754!important;color:#198754!important}.btn.btn-outline-secondary:not(.rounded-pill){background-color:#d4dae6!important;border-color:#d4dae6!important;color:#69707d!important}.btn.btn-outline-secondary:not(.rounded-pill):hover:not(:disabled),.btn.btn-outline-secondary:not(.rounded-pill):focus:not(:disabled),.btn.btn-outline-secondary:not(.rounded-pill):active:not(:disabled){background-color:#c2cbde!important;border-color:#c2cbde!important;color:#69707d!important}.btn.btn-danger{background-color:#b43026!important;border-color:#b43026!important;color:#fff!important}.btn.btn-danger:hover:not(:disabled),.btn.btn-danger:focus:not(:disabled),.btn.btn-danger:active:not(:disabled){background-color:#96271f!important;border-color:#96271f!important;color:#fff!important}.btn.btn-outline-danger.rounded-circle{border-color:#b43026!important;color:#b43026!important;border-radius:5px!important}.btn.btn-outline-danger.rounded-circle:hover:not(:disabled),.btn.btn-outline-danger.rounded-circle:focus:not(:disabled),.btn.btn-outline-danger.rounded-circle:active:not(:disabled){border-color:#96271f!important;color:#b43026!important}.btn.btn-link.text-secondary{background-color:#d4dae6!important;border-color:#d4dae6!important;color:#69707d!important;text-decoration:none!important;border-radius:5px}.btn.btn-link.text-secondary:hover:not(:disabled),.btn.btn-link.text-secondary:focus:not(:disabled){background-color:#c2cbde!important;color:#69707d!important}.btn.btn-link.text-danger{background-color:#b43026!important;border-color:#b43026!important;color:#fff!important;text-decoration:none!important;border-radius:5px}.btn.btn-link.text-danger:hover:not(:disabled),.btn.btn-link.text-danger:focus:not(:disabled){background-color:#96271f!important;color:#fff!important}.btn{border-radius:5px!important;box-shadow:none!important}.badge.bg-warning-subtle.text-warning{background-color:#fff3cd!important;color:#664d03!important;border-color:#ffe69c!important}.badge.bg-success-subtle.text-success{background-color:#4077ad!important;color:#fff!important;border-color:#4077ad!important}.badge.bg-primary-subtle.text-primary{background-color:#e0edf2!important;color:#4077ad!important;border-color:#e0edf2!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ModalModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i7.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: i7.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i7.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i7.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i7.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i7.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i7.EmailValidator, selector: "[email][formControlName],[email][formControl],[email][ngModel]", inputs: ["email"] }, { kind: "directive", type: i7.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i7.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i7.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: NgSelectModule }, { kind: "component", type: i12.NgSelectComponent, selector: "ng-select", inputs: ["bindLabel", "bindValue", "markFirst", "placeholder", "notFoundText", "typeToSearchText", "addTagText", "loadingText", "clearAllText", "appearance", "dropdownPosition", "appendTo", "loading", "closeOnSelect", "hideSelected", "selectOnTab", "openOnEnter", "maxSelectedItems", "groupBy", "groupValue", "bufferAmount", "virtualScroll", "selectableGroup", "selectableGroupAsModel", "searchFn", "trackByFn", "clearOnBackspace", "labelForId", "inputAttrs", "tabIndex", "readonly", "searchWhileComposing", "minTermLength", "editableSearchTerm", "keyDownFn", "typeahead", "multiple", "addTag", "searchable", "clearable", "isOpen", "items", "compareWith", "clearSearchOnAdd", "deselectOnClick"], outputs: ["blur", "focus", "change", "open", "close", "search", "clear", "add", "remove", "scroll", "scrollToEnd"] }, { kind: "ngmodule", type: NgxStarsModule }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "directive", type: i13.BsDatepickerDirective, selector: "[bsDatepicker]", inputs: ["placement", "triggers", "outsideClick", "container", "outsideEsc", "isDisabled", "minDate", "maxDate", "ignoreMinMaxErrors", "minMode", "daysDisabled", "datesDisabled", "datesEnabled", "dateCustomClasses", "dateTooltipTexts", "isOpen", "bsValue", "bsConfig"], outputs: ["onShown", "onHidden", "bsValueChange"], exportAs: ["bsDatepicker"] }, { kind: "directive", type: i13.BsDatepickerInputDirective, selector: "input[bsDatepicker]" }, { kind: "ngmodule", type: TextMaskModule }, { kind: "ngmodule", type: AddressVerifyFieldModule }, { kind: "component", type: AddressVerifyFieldComponent, selector: "im-address-verify-field", inputs: ["placeholder", "options", "maxLength", "inputId", "name", "autocompleteAttr", "inputClass", "invalid", "inputStyle", "initialLat", "initialLng"], outputs: ["addressResolved", "manualEdit"] }] });
|
|
6422
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PreviewComponent, deps: [{ token: CredentialingStore }, { token: FileService }, { token: UserSkillSetService }, { token: UserToolService }, { token: UserDocumentService }, { token: UserEducationService }, { token: UserDetailService }, { token: UserExperienceService }, { token: i1$4.TokenService }, { token: i1$4.RoleContextService }, { token: ProvidersService }, { token: FrontEndProvidersService }, { token: i0.ChangeDetectorRef }, { token: LIBRARY_CONFIG }], target: i0.ɵɵFactoryTarget.Component });
|
|
6423
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: PreviewComponent, isStandalone: true, selector: "app-preview", inputs: { providerId: "providerId", isResume: "isResume", resumeModel: "resumeModel", providerName: "providerName", roleData: "roleData", cloudfrontUrl: "cloudfrontUrl", signatureFileId: "signatureFileId", signatureUrl: "signatureUrl" }, outputs: { backToParent: "backToParent" }, viewQueries: [{ propertyName: "companyForm", first: true, predicate: ["companyForm"], descendants: true }], ngImport: i0, template: "<div class=\"preview-page-header\" *ngIf=\"!isResume\">\r\n <div class=\"d-flex align-items-center gap-2 mb-1\">\r\n <h2 class=\"preview-title mb-0\">Review Extracted Information</h2>\r\n </div>\r\n <p class=\"preview-subtitle text-muted\">We\u2019ve automatically extracted details from your uploaded resume. Please review and confirm accuracy before proceeding.</p>\r\n</div>\r\n\r\n\r\n<div [ngClass]=\"isResume ? '' : 'container py-4'\" [class.provider-layout]=\"roleData?.role?.name === 'Provider'\">\r\n\r\n <!-- Provider initial setup: combined company + personal form (shown until both APIs succeed) -->\r\n <div class=\"section mb-5\" *ngIf=\"roleData?.role?.name === 'Provider' && !hasUserDetailData\">\r\n <div class=\"d-flex align-items-center gap-2 mb-3 section-header-title\">\r\n <img src=\"/assets/images/icons/building.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Company & Personal Details</h5>\r\n <span class=\"badge border section-flag bg-warning-subtle text-warning\">Required to continue</span>\r\n </div>\r\n <div class=\"card shadow-sm border-0\">\r\n <div class=\"card-header bg-white fw-semibold\">Company Information</div>\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-3\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': (!tempCompanyDetails.companyName?.trim() && companyFormSubmitted) || companyNameError}\"\r\n [(ngModel)]=\"tempCompanyDetails.companyName\" name=\"setupCompanyName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyName?.trim() && companyFormSubmitted\">Company name is required</div>\r\n <div class=\"invalid-feedback\" *ngIf=\"companyNameError\">{{ companyNameError }}</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" maxlength=\"14\" inputmode=\"numeric\"\r\n (input)=\"phoneMask($event, 'company')\" (keypress)=\"allowOnlyNumbers($event)\"\r\n [ngClass]=\"{'is-invalid': companyFormSubmitted && (!tempCompanyDetails.companyPhoneNumber?.trim() || getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10)}\"\r\n [(ngModel)]=\"tempCompanyDetails.companyPhoneNumber\" name=\"setupCompanyPhone\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted\">Company phone is required</div>\r\n <div class=\"invalid-feedback\" *ngIf=\"tempCompanyDetails.companyPhoneNumber?.trim() && getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10 && companyFormSubmitted\">Company phone must be 10 digits</div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Company Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempCompanyDetails.address1\" name=\"setupCompanyAddress\"\r\n [options]=\"options\" inputClass=\"form-control form-control-sm\"\r\n [invalid]=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\">Address is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.city?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.city\" name=\"setupCompanyCity\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.city?.trim() && companyFormSubmitted\">City is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.state?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.state\" name=\"setupCompanyState\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.state?.trim() && companyFormSubmitted\">State is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.zipcode?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.zipcode\" name=\"setupCompanyZip\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.zipcode?.trim() && companyFormSubmitted\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.country?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.country\" name=\"setupCompanyCountry\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.country?.trim() && companyFormSubmitted\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <input type=\"file\" accept=\".png,.jpg,.jpeg\" class=\"form-control form-control-sm\" (change)=\"uploadCompanyImage($event)\" name=\"setupCompanyLogo\" />\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"tempCompanyLogoUrl\">\r\n <label class=\"small text-muted d-block\">Logo Preview</label>\r\n <img [src]=\"tempCompanyLogoUrl\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-header bg-white fw-semibold border-top\">Personal Information</div>\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-3\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">First Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.firstName?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.firstName\" name=\"setupFirstName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.firstName?.trim() && companyFormSubmitted\">First name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.lastName?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.lastName\" name=\"setupLastName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.lastName?.trim() && companyFormSubmitted\">Last name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Email <span class=\"text-danger\">*</span></label>\r\n <input type=\"email\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.email?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.email\" name=\"setupEmail\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.email?.trim() && companyFormSubmitted\">Email is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Phone Number <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" maxlength=\"14\" inputmode=\"numeric\"\r\n (input)=\"phoneMask($event, 'profile')\" (keypress)=\"allowOnlyNumbers($event)\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.phone?.trim() && companyFormSubmitted}\"\r\n [ngModel]=\"tempProfile?.phone\" name=\"setupPhone\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.phone?.trim() && companyFormSubmitted\">Phone number is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempProfile.address\" name=\"setupAddress\" [options]=\"options\"\r\n inputClass=\"form-control form-control-sm\" [invalid]=\"!tempProfile?.address?.trim() && companyFormSubmitted\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.address?.trim() && companyFormSubmitted\">Home address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.city?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.city\" name=\"setupUserCity\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.city?.trim() && companyFormSubmitted\">City is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.state?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.state\" name=\"setupUserState\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.state?.trim() && companyFormSubmitted\">State is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.zipCode?.trim() && companyFormSubmitted}\"\r\n [ngModel]=\"tempProfile?.zipCode\" (ngModelChange)=\"tempProfile.zipCode = sanitizeZipCode($event)\"\r\n name=\"setupUserZip\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.zipCode?.trim() && companyFormSubmitted\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.country?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.country\" name=\"setupUserCountry\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.country?.trim() && companyFormSubmitted\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [(ngModel)]=\"tempProfile.jobTitle\" name=\"setupJobTitle\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control form-control-sm\" [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n [ngClass]=\"{'is-invalid': !(tempProfile?.yearsOfExperience > 0) && companyFormSubmitted}\"\r\n name=\"setupYearsOfExp\" min=\"1\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!(tempProfile?.yearsOfExperience > 0) && companyFormSubmitted\">Years of experience is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Profile Picture</label>\r\n <input #setupHeadshotFile type=\"file\" accept=\".png,.jpg,.jpeg\" class=\"d-none\" (change)=\"uploadHeadshotImage($event)\" name=\"setupHeadshotFile\" />\r\n <div class=\"position-relative\">\r\n <input type=\"text\" class=\"form-control form-control-sm pe-5\" [value]=\"headshotFileName\" readonly\r\n placeholder=\"Upload Profile Picture\" (click)=\"setupHeadshotFile.click()\" />\r\n <img *ngIf=\"!isHeadshotLoading\" src=\"assets/images/icons/upload.svg\" alt=\"Upload\" class=\"upload-icon\" style=\"position:absolute;right:12px;top:50%;transform:translateY(-50%);cursor:pointer;width:18px;\" (click)=\"setupHeadshotFile.click()\" />\r\n <div *ngIf=\"isHeadshotLoading\" style=\"position:absolute;right:12px;top:50%;transform:translateY(-50%);\">\r\n <span class=\"spinner-border spinner-border-sm text-primary\"></span>\r\n </div>\r\n </div>\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"headshotPreviewUrl\">\r\n <label class=\"small text-muted d-block\">Preview</label>\r\n <img [src]=\"cloudfrontUrl + headshotPreviewUrl\" class=\"img-thumbnail rounded-circle\" style=\"width:64px;height:64px;object-fit:cover;\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-footer d-flex align-items-center justify-content-end gap-2\">\r\n <span *ngIf=\"providerSetupError\" class=\"small text-danger me-auto\">{{ providerSetupError }}</span>\r\n <button class=\"btn btn-success px-5 \"\r\n [disabled]=\"isSavingProviderSetup || !isProviderSetupFormComplete\"\r\n (click)=\"saveProviderSetup()\">\r\n <span *ngIf=\"isSavingProviderSetup\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingProviderSetup ? 'Saving...' : 'Save & Continue' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\" *ngIf=\"roleData?.role?.name !== 'Provider' || hasUserDetailData\">\r\n <div *ngIf=\"details() as data; else loading\">\r\n <div class=\"card shadow-sm border-0 rounded-3 overflow-hidden\" *ngIf=\"!isEditMode()\">\r\n <div class=\"card-body p-0\">\r\n <div class=\"preview-card-gradient\">\r\n <div class=\"d-flex justify-content-between align-items-start mb-4\">\r\n <div class=\"d-flex align-items-start gap-3\">\r\n <div class=\"profile-avatar-circle\" *ngIf=\"!headshotPreviewUrl\">\r\n {{ (data.firstName?.[0] || '') }}{{ (data.lastName?.[0] || '') }}\r\n </div>\r\n <img *ngIf=\"headshotPreviewUrl\" [src]=\" cloudfrontUrl + headshotPreviewUrl\"\r\n class=\"rounded-circle\" style=\"width:56px;height:56px;object-fit:cover;\" alt=\"Profile\" />\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h2 class=\"fw-bold mb-1\">{{ data.firstName }} {{ data.lastName }}</h2>\r\n <span *ngIf=\"basicSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n <span class=\"badge border section-flag\"\r\n [ngClass]=\"basicDetailsSaved ? 'bg-success-subtle text-success' : 'bg-warning-subtle text-warning'\">\r\n {{ basicDetailsSaved ? 'Saved' : 'Not saved yet' }}\r\n </span>\r\n </div>\r\n <p class=\"text-muted\">{{ data.jobTitle }} \u2022 {{ data.yearsOfExperience }} Years Exp.</p>\r\n <div *ngIf=\"basicIssues().length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ basicIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <span class=\"badge bg-primary-subtle text-primary border p-2\">Email Verified</span>\r\n </div>\r\n\r\n </div>\r\n <div class=\"px-4 py-3\">\r\n <div class=\"row g-4\">\r\n <div class=\"col-12 border-bottom pb-2\">\r\n <h6 class=\"text-uppercase small fw-bold text-muted\">Summary</h6>\r\n <p class=\"text-secondary small mb-0\">{{ data.summary }}</p>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/envelope.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Email</span>\r\n <span class=\"field-value-sm d-block\">{{ data.email }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/telephone.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Phone</span>\r\n <span class=\"field-value-sm d-block\">{{ data.phone }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/geo-alt.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Location</span>\r\n <span class=\"field-value-sm d-block\">{{ data.address }}, {{ data.city }}, {{ data.state }}, {{ data.zipCode }}, {{ data.country }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer d-flex align-items-center justify-content-between\">\r\n <span *ngIf=\"!basicDetailsSaved\" class=\"small text-warning fw-semibold\">\r\n <img src=\"/assets/images/icons/exclamation-circle.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" /> Click \"Edit\" to review and save your basic info.\r\n </span>\r\n <span *ngIf=\"basicDetailsSaved\" class=\"small text-success fw-semibold\">\r\n <img src=\"/assets/images/icons/check-circle.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" /> Basic details saved.\r\n </span>\r\n <button class=\"btn btn-sm btn-primary px-4 ms-auto\" (click)=\"toggleEdit()\">Edit</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"isEditMode()\">\r\n <div class=\"card-header bg-white fw-bold\">Update Profile</div>\r\n <div class=\"card-body p-4\">\r\n <form class=\"row g-3\" #basicForm=\"ngForm\" novalidate>\r\n <div *ngIf=\"basicIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ basicIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">First Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.firstName\" name=\"fName\"\r\n placeholder=\"First Name\" required #fName=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"fName.invalid && (fName.dirty || fName.touched)\">First name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.lastName\" name=\"lName\"\r\n placeholder=\"Last Name\" required #lName=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"lName.invalid && (lName.dirty || lName.touched)\">Last name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Email <span class=\"text-danger\">*</span></label>\r\n <input type=\"email\" class=\"form-control\" [(ngModel)]=\"tempProfile.email\" name=\"email\" placeholder=\"Email\"\r\n required email #email=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"email.invalid && (email.dirty || email.touched)\">\r\n <span *ngIf=\"email.errors?.['required']\">Email is required</span>\r\n <span *ngIf=\"email.errors?.['email']\">Email format is invalid</span>\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Phone Number <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"tempProfile.phone\" (input)=\"phoneMask($event, 'profile')\"\r\n name=\"phone\" placeholder=\"Phone (10 digits)\" (keypress)=\"allowOnlyNumbers($event)\"\r\n required pattern=\"^\\(\\d{3}\\) \\d{3}-\\d{4}$\" maxlength=\"14\" inputmode=\"numeric\" #phone=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"phone.invalid && (phone.dirty || phone.touched)\">\r\n <span *ngIf=\"phone.errors?.['required']\">Phone number is required</span>\r\n <span *ngIf=\"phone.errors?.['pattern']\">Phone number must be 10 digits</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\"></span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.jobTitle\" name=\"jobTitle\"\r\n placeholder=\"Job Title\" #jobTitle=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"jobTitle.invalid && (jobTitle.dirty || jobTitle.touched)\">Job\r\n title is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngClass]=\"{'is-invalid': !(tempProfile?.yearsOfExperience > 0)}\"\r\n [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n name=\"yearsOfExperience\" placeholder=\"Years of Experience\" required min=\"1\"\r\n #yearsOfExperience=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!(tempProfile?.yearsOfExperience > 0)\">\r\n Years of experience is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempProfile.address\" name=\"address\" [options]=\"options\"\r\n placeholder=\"Home Address\" required #address=\"ngModel\"\r\n [invalid]=\"address.invalid && (address.dirty || address.touched)\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"></im-address-verify-field>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"address.invalid && (address.dirty || address.touched)\">Home\r\n address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.city\" name=\"city\" placeholder=\"City\"\r\n required #city=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"city.invalid && (city.dirty || city.touched)\">City is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.state\" name=\"state\" placeholder=\"State\"\r\n required #state=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"state.invalid && (state.dirty || state.touched)\">State is\r\n required</div>\r\n </div>\r\n\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"tempProfile.zipCode\"\r\n (ngModelChange)=\"tempProfile.zipCode = sanitizeZipCode($event)\" name=\"zipCode\" placeholder=\"Zip Code\"\r\n required pattern=\"^\\d{1,6}$\" maxlength=\"6\" inputmode=\"numeric\" #zipCode=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"zipCode.invalid && (zipCode.dirty || zipCode.touched)\">Zip code\r\n is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"zipCode.errors?.['pattern'] && (zipCode.dirty || zipCode.touched)\">\r\n Zip code must be up to 6 digits\r\n </div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.country\" name=\"country\"\r\n placeholder=\"Country\" required #country=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"country.invalid && (country.dirty || country.touched)\">Country\r\n is required</div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Summary</label>\r\n <textarea class=\"form-control\" rows=\"3\" [(ngModel)]=\"tempProfile.summary\" name=\"sum\"\r\n placeholder=\"Summary\"></textarea>\r\n </div>\r\n\r\n\r\n </form>\r\n </div>\r\n <div class=\"card-footer text-end gap-2 d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancel()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingBasic || !isBasicFormValid\" (click)=\"save()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Saving...' : 'Save Changes' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5 provider-company-first\" *ngIf=\"roleData?.role?.name === 'Provider' && hasUserDetailData && !providerIdFallbackUsed()\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/building.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Company Details</h5>\r\n <span *ngIf=\"companyDetailsSaved\"\r\n class=\"badge border section-flag bg-success-subtle text-success\">\r\n Saved\r\n </span>\r\n <span *ngIf=\"!companyDetailsSaved\"\r\n class=\"badge border section-flag bg-warning-subtle text-warning\">\r\n Not saved yet\r\n </span>\r\n </div>\r\n <button class=\"btn btn-sm btn-primary px-4\" (click)=\"toggleCompanyEdit()\">Edit</button>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"!isCompanyEditMode()\">\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-4\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name</label>\r\n <span class=\"fw-bold small\">{{ companyDetails()?.companyName}}</span>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone</label>\r\n <span class=\"fw-bold small\">{{ companyDetails()?.companyPhoneNumber}}</span>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Company Address</label>\r\n <span class=\"small\">{{ companyDetails()?.address1}}, {{ companyDetails()?.city}}, {{ companyDetails()?.state}}, {{ companyDetails()?.zipcode}}, {{ companyDetails()?.country}}</span>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"companyLogoUrl()\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <img [src]=\"companyLogoUrl()\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"isCompanyEditMode()\">\r\n <div class=\"card-header bg-white fw-bold\">Update Company Details</div>\r\n <div class=\"card-body p-4\">\r\n <form class=\"row g-3\" #companyForm=\"ngForm\" novalidate>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': (!tempCompanyDetails.companyName?.trim() && companyFormSubmitted) || companyNameError }\"\r\n [(ngModel)]=\"tempCompanyDetails.companyName\" name=\"companyName\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyName?.trim() && companyFormSubmitted\">\r\n Company name is required\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"companyNameError\">\r\n {{ companyNameError }}\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone <span class=\"text-danger\">*</span></label>\r\n <input (input)=\"phoneMask($event, 'company')\" type=\"text\" maxlength=\"14\" (keypress)=\"allowOnlyNumbers($event)\" inputmode=\"numeric\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{ 'is-invalid': companyFormSubmitted && (!tempCompanyDetails.companyPhoneNumber?.trim() || getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10) }\"\r\n [(ngModel)]=\"tempCompanyDetails.companyPhoneNumber\" name=\"companyPhoneNumber\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted\">\r\n Company phone is required\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"tempCompanyDetails.companyPhoneNumber?.trim() && getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10 && companyFormSubmitted\">\r\n Company phone must be 10 digits\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempCompanyDetails.address1\" name=\"address1\" [options]=\"options\"\r\n required [invalid]=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\">\r\n Address is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.city?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.city\" name=\"city\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.city?.trim() && companyFormSubmitted\">\r\n City is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.state?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.state\" name=\"state\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.state?.trim() && companyFormSubmitted\">\r\n State is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.zipcode?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.zipcode\" name=\"zipcode\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.zipcode?.trim() && companyFormSubmitted\">\r\n Zip code is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.country?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.country\" name=\"country\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.country?.trim() && companyFormSubmitted\">\r\n Country is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <input #uploadCompanyFile type=\"file\" accept=\".png,.jpg,.jpeg\" (change)=\"uploadCompanyImage($event)\" class=\"form-control\" />\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"tempCompanyLogoUrl\">\r\n <label class=\"small text-muted d-block\">Logo Preview</label>\r\n <img [src]=\"tempCompanyLogoUrl\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </form>\r\n </div>\r\n <div class=\"card-footer text-end gap-2 d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelCompanyEdit()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCompany\" \r\n (click)=\"saveCompanyDetails()\">\r\n <span *ngIf=\"isSavingCompany\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCompany ? 'Saving...' : 'Save Changes' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div [class.section-locked]=\"roleData?.role?.name === 'Provider' && !hasUserDetailData\">\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/briefcase-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Work Experience</h5>\r\n <span *ngIf=\"experience().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"workSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ workSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"experience().length === 0 || !workSectionHasUnsavedItems() || isSavingWork || isAddingJob() || editingJobIndex() !== null\"\r\n (click)=\"confirmAllWork()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add work experience\" (click)=\"addJob()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"experience().length === 0 && !isAddingJob()\" class=\"empty-state-wrap mb-3\" role=\"button\"\r\n (click)=\"addJob()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/briefcase.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No work experience added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3\">\r\n <div *ngIf=\"isAddingJob() && tempJob()\" class=\"list-group-item p-0 border-0\">\r\n <div class=\"form-panel mb-2\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\" name=\"newJobTitle\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\" name=\"newCompany\" />\r\n </div>\r\n <div class=\"align-items-end col-md-12 d-flex justify-content-end pe-3\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\" name=\"newIsCurrent\" id=\"newIsCurrent\" />\r\n <label class=\"form-check-label\" for=\"newIsCurrent\">Current</label>\r\n </div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.country\"\r\n (ngModelChange)=\"patchTempJob({ country: $event })\" name=\"newCountry\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.state\"\r\n (ngModelChange)=\"patchTempJob({ state: $event })\" name=\"newState\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\" name=\"newCity\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempJob()?.startDate)\"\r\n (bsValueChange)=\"setTempJobMonth('startDate', $event)\" name=\"newStartDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.startDate)\">Start date is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"monthInputToDate(tempJob()?.endDate)\" (bsValueChange)=\"setTempJobMonth('endDate', $event)\"\r\n name=\"newEndDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">End date is\r\n required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isMonthRangeInvalid(tempJob()?.startDate, tempJob()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Responsibilities (one per line)</label>\r\n <textarea rows=\"4\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\" name=\"newResponsibilities\"></textarea>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\" name=\"newWorkAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempJob()?.fileName\">\r\n <span>{{ tempJob()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempJob())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n <div class=\"d-flex justify-content-end gap-2 mt-3\">\r\n <button class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingWork\"\r\n (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : workActionLabel(editingJobIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n\r\n <div *ngFor=\"let job of experience(); let i = index\" class=\"list-group-item p-0 border-0 mb-2\">\r\n\r\n <div class=\"work-accent-item p-3 rounded-3 bg-white border\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div class=\"d-flex align-items-center cursor-pointer flex-grow-1\" (click)=\"toggleJob(i)\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h6 class=\"mb-0 fw-bold item-title-sm\">{{ job.jobTitle }}</h6>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedWorkItem(i) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedWorkItem(i) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ job.company || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ formatMonthYear(job.startDate) }} - {{ job.isCurrent ? 'Present' :\r\n formatMonthYear(job.endDate) }}</span>\r\n <span class=\"item-meta-line\">{{ job.city }}<span *ngIf=\"job.city && job.state\">, </span>{{ job.state }}<ng-container *ngIf=\"!job.city && !job.state\">\u2014</ng-container></span>\r\n <div *ngIf=\"editingJobIndex() !== i && (workIssuesByIndex()[i] || []).length > 0\"\r\n class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (workIssuesByIndex()[i] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center gap-2\">\r\n\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\" (click)=\"startEditJob(i)\"\r\n title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteJob(i);\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n \r\n </div>\r\n </div>\r\n\r\n\r\n\r\n <div class=\"mt-3 p-3 rounded small\" *ngIf=\"expandedIndex() === i\">\r\n <ng-container *ngIf=\"editingJobIndex() !== i; else editJobForm\">\r\n <ul class=\"mb-0\">\r\n <li *ngFor=\"let res of job.responsibilities\">{{ res }}</li>\r\n </ul>\r\n </ng-container>\r\n\r\n <ng-template #editJobForm>\r\n <div *ngIf=\"(workIssuesByIndex()[i] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (workIssuesByIndex()[i] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\" name=\"jobTitle{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.jobTitle)\">Job title is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\" name=\"company{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.company)\">Company name is required</div>\r\n </div>\r\n\r\n <div class=\"align-items-end col-md-12 d-flex justify-content-end pe-3\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\" name=\"isCurrent{{ i }}\" id=\"isCurrent{{ i }}\" />\r\n <label class=\"form-check-label\" for=\"isCurrent{{ i }}\">Current</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.country\"\r\n (ngModelChange)=\"patchTempJob({ country: $event })\" name=\"country{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.state\"\r\n (ngModelChange)=\"patchTempJob({ state: $event })\" name=\"state{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\" name=\"city{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.city)\">City is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempJob()?.startDate)\"\r\n (bsValueChange)=\"setTempJobMonth('startDate', $event)\" name=\"startDate{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.startDate)\">Start date is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"monthInputToDate(tempJob()?.endDate)\" (bsValueChange)=\"setTempJobMonth('endDate', $event)\"\r\n name=\"endDate{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">\r\n End date is required\r\n </div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isMonthRangeInvalid(tempJob()?.startDate, tempJob()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Responsibilities (one per line)</label>\r\n <textarea rows=\"4\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\" name=\"responsibilities{{ i }}\"></textarea>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\" name=\"workAttachment{{ i }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempJob()?.fileName\">\r\n <span>{{ tempJob()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempJob())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n </ng-template>\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-3\" *ngIf=\"editingJobIndex() === i\">\r\n <button class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4 \" [disabled]=\"isSavingWork\"\r\n (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : workActionLabel(editingJobIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/patch-check-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Certifications</h5>\r\n <span *ngIf=\"certs().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"certificationSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ certificationSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"certs().length === 0 || !certificationSectionHasUnsavedItems() || isSavingCertification || isAddingCertification() || editingCertificationIndex() !== null\"\r\n (click)=\"confirmAllCertifications()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add certification\" (click)=\"addCertification()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"certs().length === 0 && !isAddingCertification() && editingCertificationIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addCertification()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/patch-check.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No certifications added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3 border\">\r\n <div *ngIf=\"isAddingCertification() && tempCertification()\" class=\"list-group-item py-3 px-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\" name=\"newCertName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\" name=\"newCertOrg\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\" name=\"newCertState\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certification Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\" name=\"newCertCredentialId\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('issueDate', $event)\" name=\"newCertIssueDate\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('expiryDate', $event)\" name=\"newCertExpiryDate\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempCertification()?.issueDate || null, tempCertification()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\" name=\"newCertAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempCertification()?.fileName\">\r\n <span>{{ tempCertification()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempCertification())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\"\r\n (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : certificationActionLabel(editingCertificationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let cert of certs(); let ci = index\" class=\"list-group-item py-3 cert-accent-item\">\r\n <ng-container *ngIf=\"editingCertificationIndex() !== ci; else editCert\">\r\n <div class=\"d-flex justify-content-between align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <div class=\"fw-semibold item-title-sm\">{{ cert.name }}</div>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedCertificationItem(ci) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedCertificationItem(ci) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ cert.issuingOrganization || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.credentialId || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.issueDate ? formatMonthYear(cert.issueDate) : '\u2014' }} - {{ cert.expiryDate ? formatMonthYear(cert.expiryDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.state || '\u2014' }}</span>\r\n <div *ngIf=\"(certIssuesByIndex()[ci] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (certIssuesByIndex()[ci] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditCertification(ci)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteCertification(ci)\" title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #editCert>\r\n <div *ngIf=\"(certIssuesByIndex()[ci] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (certIssuesByIndex()[ci] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\" name=\"certName{{ ci }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\"\r\n name=\"certOrg{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\" name=\"certState{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certification Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\"\r\n name=\"certCredentialId{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('issueDate', $event)\" name=\"certIssue{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('expiryDate', $event)\" name=\"certExpiry{{ ci }}\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempCertification()?.issueDate || null, tempCertification()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\" name=\"certAttachment{{ ci }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempCertification()?.fileName\">\r\n <span>{{ tempCertification()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempCertification())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\"\r\n (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : certificationActionLabel(editingCertificationIndex()) }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/card-checklist-warning.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Licenses</h5>\r\n <span *ngIf=\"licenses().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"licenseSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ licenseSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"licenses().length === 0 || !licenseSectionHasUnsavedItems() || isSavingLicense || isAddingLicense() || editingLicenseIndex() !== null\"\r\n (click)=\"confirmAllLicenses()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add license\" (click)=\"addLicense()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"licenses().length === 0 && !isAddingLicense() && editingLicenseIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addLicense()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/card-checklist.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No licenses added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3 border\">\r\n <div *ngIf=\"isAddingLicense() && tempLicense()\" class=\"list-group-item py-3 px-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\" name=\"newLicName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempLicense()?.name)\">License name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\" name=\"newLicAuthority\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\" name=\"newLicNumber\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\" name=\"newLicState\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('issueDate', $event)\" name=\"newLicIssueDate\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('expiryDate', $event)\" name=\"newLicExpiryDate\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempLicense()?.issueDate || null, tempLicense()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">License File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\" name=\"newLicenseAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempLicense()?.fileName\">\r\n <span>{{ tempLicense()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempLicense())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelEditLicense()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingLicense\"\r\n (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : licenseActionLabel(editingLicenseIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let lic of licenses(); let li = index\" class=\"list-group-item py-3 lic-accent-item\">\r\n <ng-container *ngIf=\"editingLicenseIndex() !== li; else editLic\">\r\n <div class=\"d-flex justify-content-between align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <div class=\"fw-semibold item-title-sm\">{{ lic.name }}</div>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedLicenseItem(li) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedLicenseItem(li) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ lic.issuingAuthority || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.licenseNumber || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.issueDate ? formatMonthYear(lic.issueDate) : '\u2014' }} - {{ lic.expiryDate ? formatMonthYear(lic.expiryDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.state || '\u2014' }}</span>\r\n <div *ngIf=\"(licenseIssuesByIndex()[li] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (licenseIssuesByIndex()[li] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditLicense(li)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteLicense(li)\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #editLic>\r\n <div *ngIf=\"(licenseIssuesByIndex()[li] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (licenseIssuesByIndex()[li] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\" name=\"licName{{ li }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempLicense()?.name)\">License name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\" name=\"licAuthority{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\" name=\"licNumber{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\" name=\"licState{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('issueDate', $event)\" name=\"licIssue{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('expiryDate', $event)\" name=\"licExpiry{{ li }}\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempLicense()?.issueDate || null, tempLicense()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">License File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\" name=\"licenseAttachment{{ li }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempLicense()?.fileName\">\r\n <span>{{ tempLicense()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempLicense())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditLicense()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingLicense\"\r\n (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : licenseActionLabel(editingLicenseIndex()) }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/tools.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Tools</h5>\r\n <span *ngIf=\"tools().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"toolsSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ toolsSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"tools().length === 0 || !toolsSectionHasUnsavedItems() || isSavingTool || isToolEditorOpen()\" (click)=\"confirmAllTools()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add tool\" (click)=\"addTool()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex flex-wrap gap-2 p-3 bg-white border rounded shadow-sm\">\r\n <div *ngFor=\"let tool of tools(); let ti = index\" class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\"\r\n class=\"btn btn-light border res-flex d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openToolEditor(ti)\" title=\"Edit\">\r\n <span class=\"fw-normal item-name-text\">{{ tool }}</span>\r\n <span class=\"badge border ms-1\"\r\n [ngClass]=\"hasUnsavedToolItem(ti) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedToolItem(ti) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n <span *ngIf=\"(toolIssuesByIndex()[ti] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\">\r\n Missing info\r\n </span>\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Delete tool\" (click)=\"deleteTool(ti)\">\r\n <span class=\"fw-bold\">\u00D7</span>\r\n </button>\r\n </div>\r\n\r\n <span *ngIf=\"tools().length === 0\" class=\"text-muted small\">No tools added.</span>\r\n </div>\r\n\r\n <div *ngIf=\"isToolEditorOpen()\" class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 9999999;\" (click)=\"closeToolEditor()\">\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\"\r\n (click)=\"$event.stopPropagation()\">\r\n <div class=\"card shadow border-0 w-100\" style=\"max-width: 900px;\">\r\n <div class=\"card-header bg-white d-flex align-items-center gap-3\">\r\n <button type=\"button\" class=\"btn btn-link p-0 text-decoration-none\" (click)=\"closeToolEditor()\">\r\n <img src=\"/assets/images/icons/arrow-left-blue.svg\" width=\"20\" height=\"20\" alt=\"\" />\r\n </button>\r\n <div class=\"fw-bold\">{{ isAddingTool() ? 'Add Tool' : ('Edit ' + (toolForm()?.name || '') + ' Tool') }}\r\n </div>\r\n </div>\r\n <div class=\"card-body p-4\">\r\n <div *ngIf=\"toolFormIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ toolFormIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"row g-3\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Tool Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"toolForm()?.name\"\r\n (ngModelChange)=\"patchToolForm({ name: $event })\" name=\"toolName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(toolForm()?.name)\">Tool name is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span\r\n class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempToolStars(s)\" [attr.aria-label]=\"'Set rating ' + s\">\r\n <span [class]=\"(toolForm()?.stars || 0) >= s ? 'text-warning fs-5' : 'text-muted fs-5'\">\r\n {{ (toolForm()?.stars || 0) >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ toolForm()?.stars || 0 }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"(toolForm()?.stars || 0) <= 0\">Star rating is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngModel]=\"toolForm()?.year\"\r\n (ngModelChange)=\"patchToolForm({ year: $event === '' ? null : +$event })\" name=\"toolYear\" min=\"1\"\r\n max=\"30\" placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"toolForm()?.year === null || toolForm()?.year === undefined\">\r\n Years of experience is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4 text-center\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-checks form-switch mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"toolForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchToolForm({ profileVisibility: $event })\" name=\"toolVisible\" id=\"toolVisible\"\r\n style=\"width: 55px;height: 25px;margin-left: -57px;\" />\r\n <label class=\"form-check-label ps-2 pt-1\" for=\"toolVisible\">Visible</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Comment</label>\r\n <textarea rows=\"4\" class=\"form-control\" [ngModel]=\"toolForm()?.notes\"\r\n (ngModelChange)=\"patchToolForm({ notes: $event })\" name=\"toolNotes\"\r\n placeholder=\"Comment your tool here...\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-white d-flex justify-content-end gap-2\">\r\n <button *ngIf=\"!isAddingTool() && editingToolIndex() !== null\" type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\" (click)=\"deleteTool(editingToolIndex()!)\">\r\n Delete\r\n </button>\r\n <button type=\"button\" class=\"btn btn-link text-secondary\" (click)=\"closeToolEditor()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary px-4\" [disabled]=\"isSavingTool\" (click)=\"saveToolEditor()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Saving...' : toolActionLabel(editingToolIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row g-4 mb-5\">\r\n <div class=\"col-md-12\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/stars.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Skills</h5>\r\n <span *ngIf=\"skills().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"skillsSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ skillsSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"skills().length === 0 || !skillsSectionHasUnsavedItems() || isSavingSkill || isSkillEditorOpen()\" (click)=\"confirmAllSkills()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add skill\" (click)=\"addSkill()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex flex-wrap gap-2 p-3 bg-white border rounded shadow-sm\">\r\n <div *ngFor=\"let skill of skills(); let si = index\" class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\"\r\n class=\"btn btn-light border res-flex d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openSkillEditor(si)\" title=\"Edit\">\r\n <span class=\"fw-normal item-name-text\">{{ skill }}</span>\r\n <span class=\"badge border ms-1\"\r\n [ngClass]=\"hasUnsavedSkillItem(si) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedSkillItem(si) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n <span *ngIf=\"(skillIssuesByIndex()[si] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\">\r\n Missing info\r\n </span>\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Delete skill\"\r\n (click)=\"deleteSkill(si); $event.stopPropagation()\">\r\n <span class=\"fw-bold\">\u00D7</span>\r\n </button>\r\n </div>\r\n\r\n <span *ngIf=\"skills().length === 0\" class=\"text-muted small\">No skills added.</span>\r\n </div>\r\n <div *ngIf=\"isSkillEditorOpen()\" class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 9999999;\" (click)=\"closeSkillEditor()\">\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\"\r\n (click)=\"$event.stopPropagation()\">\r\n <div class=\"card shadow border-0 w-100\" style=\"max-width: 900px;\">\r\n <div class=\"card-header bg-white d-flex align-items-center gap-3\">\r\n <button type=\"button\" class=\"btn btn-link p-0 text-decoration-none\" (click)=\"closeSkillEditor()\">\r\n <img src=\"/assets/images/icons/arrow-left-blue.svg\" width=\"20\" height=\"20\" alt=\"\" />\r\n </button>\r\n <div class=\"fw-bold\">{{ isAddingSkill() ? 'Add Skill' : ('Edit ' + (skillForm()?.name || '') + ' Skill')\r\n }}</div>\r\n </div>\r\n <div class=\"card-body p-4\">\r\n <div *ngIf=\"skillFormIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ skillFormIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"row g-3\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Skills Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"skillForm()?.name\"\r\n (ngModelChange)=\"patchSkillForm({ name: $event })\" name=\"skillName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(skillForm()?.name)\">Skillset name is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span\r\n class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempSkillStars(s)\" [attr.aria-label]=\"'Set rating ' + s\">\r\n <span [class]=\"(skillForm()?.stars || 0) >= s ? 'text-warning fs-5' : 'text-muted fs-5'\">\r\n {{ (skillForm()?.stars || 0) >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ skillForm()?.stars || 0 }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"(skillForm()?.stars || 0) <= 0\">Star rating is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngModel]=\"skillForm()?.year\"\r\n (ngModelChange)=\"patchSkillForm({ year: $event === '' ? null : +$event })\" name=\"skillYear\" min=\"1\"\r\n max=\"30\" placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"skillForm()?.year === null || skillForm()?.year === undefined\">Years of experience is\r\n required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4 text-center\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-checks form-switch mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"skillForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchSkillForm({ profileVisibility: $event })\" name=\"skillVisible\"\r\n id=\"skillVisible\" style=\"width: 55px;height: 25px;margin-left: -57px;\" />\r\n <label class=\"form-check-label ps-2 pt-1\" for=\"skillVisible\">Visible</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Comment</label>\r\n <textarea rows=\"4\" class=\"form-control\" [ngModel]=\"skillForm()?.notes\"\r\n (ngModelChange)=\"patchSkillForm({ notes: $event })\" name=\"skillNotes\"\r\n placeholder=\"Comment your skill here...\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-white d-flex justify-content-end gap-2\">\r\n <button *ngIf=\"!isAddingSkill() && editingSkillIndex() !== null\" type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\" (click)=\"deleteSkill(editingSkillIndex()!)\">\r\n Delete\r\n </button>\r\n <button type=\"button\" class=\"btn btn-link text-secondary\" (click)=\"closeSkillEditor()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary px-4\" [disabled]=\"isSavingSkill\" (click)=\"saveSkillEditor()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Saving...' : skillActionLabel(editingSkillIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row g-4 mb-5\">\r\n <div class=\"col-md-12\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/mortarboard-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Education</h5>\r\n <span *ngIf=\"educationList().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"educationSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ educationSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"educationList().length === 0 || !educationSectionHasUnsavedItems() || isSavingEducation || isAddingEducation() || editingEducationIndex() !== null\"\r\n (click)=\"confirmAllEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add education\" (click)=\"addEducation()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"educationList().length === 0 && !isAddingEducation() && editingEducationIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addEducation()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/mortarboard.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No education added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div *ngIf=\"isAddingEducation() && tempEducation()\" class=\"mb-2\">\r\n <div class=\"form-panel\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\" name=\"newEduDegree\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Institution <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\" name=\"newEduInstitution\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree / Course Type <span class=\"text-danger\">*</span></label>\r\n <ng-select class=\"ng-select-sm\" [items]=\"educationDegreeTypeOptions\" [clearable]=\"false\"\r\n placeholder=\"Select degree / course type\" [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\" name=\"newEduDegreeType\">\r\n </ng-select>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.country\"\r\n (ngModelChange)=\"patchTempEducation({ country: $event })\" name=\"newEduCountry\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.state\"\r\n (ngModelChange)=\"patchTempEducation({ state: $event })\" name=\"newEduState\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\" name=\"newEduCity\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.startDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('startDate', $event)\" name=\"newEduStartDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.startDate)\">Start date is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.endDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('endDate', $event)\" name=\"newEduEndDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Education File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onEducationFileSelected($event)\" name=\"newEducationAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempEducation()?.fileName\">\r\n <span>{{ tempEducation()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempEducation())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingEducation\"\r\n (click)=\"saveEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Uploading...' : educationActionLabel(editingEducationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let edu of educationList(); let ei = index\" class=\"edu-accent-item p-3 bg-white border rounded-3 shadow-sm mb-2\">\r\n <div class=\"d-flex justify-content-between align-items-start\">\r\n <div class=\"d-flex align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h6 class=\"fw-bold mb-0 item-title-sm\">{{ edu.degree }}</h6>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedEducationItem(ei) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedEducationItem(ei) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ edu.institution || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.degreeType || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.startDate ? formatMonthYear(edu.startDate) : '\u2014' }} - {{ edu.endDate ? formatMonthYear(edu.endDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.city }}<span *ngIf=\"edu.city && edu.state\">, </span>{{ edu.state }}<ng-container *ngIf=\"!edu.city && !edu.state\">\u2014</ng-container></span>\r\n <div *ngIf=\"(educationIssuesByIndex()[ei] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (educationIssuesByIndex()[ei] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\" *ngIf=\"editingEducationIndex() !== ei\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditEducation(ei)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteEducation(ei)\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"editingEducationIndex() === ei\" class=\"mt-3\">\r\n <div *ngIf=\"(educationIssuesByIndex()[ei] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (educationIssuesByIndex()[ei] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\" name=\"eduDegree{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Institution <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\" name=\"eduInstitution{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.institution)\">Institution name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree / Course Type <span class=\"text-danger\">*</span></label>\r\n <ng-select class=\"ng-select-sm\" [items]=\"educationDegreeTypeOptions\" [clearable]=\"false\"\r\n placeholder=\"Select degree / course type\" [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\" name=\"eduDegreeType{{ ei }}\">\r\n </ng-select>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.country\"\r\n (ngModelChange)=\"patchTempEducation({ country: $event })\" name=\"eduCountry{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.state\"\r\n (ngModelChange)=\"patchTempEducation({ state: $event })\" name=\"eduState{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\" name=\"eduCity{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.startDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('startDate', $event)\" name=\"eduStartDate{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.startDate)\">Start date is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.endDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('endDate', $event)\" name=\"eduEndDate{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Education File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onEducationFileSelected($event)\" name=\"educationAttachment{{ ei }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempEducation()?.fileName\">\r\n <span>{{ tempEducation()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempEducation())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingEducation\" (click)=\"saveEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Uploading...' : educationActionLabel(editingEducationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n </div>\r\n <div class=\"d-flex gap-3 justify-content-center mt-5 pt-2\" *ngIf=\"!isResume\">\r\n <button class=\"btn btn-outline-secondary preview-back-btn px-5 h-auto\" style=\"border-radius: 5px !important;\" (click)=\"onBackClick()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"me-1\" style=\"vertical-align:-0.1em\">\r\n <path d=\"M11 3 5 8l6 5\" />\r\n </svg> Back\r\n </button>\r\n <button class=\"btn btn-primary preview-dashboard-btn px-5 h-auto\" style=\"border-radius: 5px !important;\" [disabled]=\"!canConfirmAndContinue() || isSavingBasic\"\r\n (click)=\"onGoToDashboardClick()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Saving...' : 'Go to Dashboard' }}\r\n <img *ngIf=\"!isSavingBasic\" src=\"/assets/images/icons/arrow-right-white.svg\" width=\"14\" height=\"14\" class=\"ms-1\" style=\"vertical-align:-0.1em\" alt=\"\" />\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<ng-template #loading>\r\n <div class=\"text-center p-5\">\r\n <div class=\"spinner-border text-primary\"></div>\r\n <p class=\"text-muted mt-2\">Loading data...</p>\r\n </div>\r\n</ng-template>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBulkSkillConfirm\">\r\n <div class=\"confirm-modal-card\" style=\"max-width: 480px;\">\r\n <h4 class=\"mb-1\">Set Rating for All Skills</h4>\r\n <p class=\"text-muted small mb-4\">Enter a star rating and years of experience to apply to all skills that are missing these values.</p>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"bulkSkillStars = s\">\r\n <span [class]=\"bulkSkillStars >= s ? 'text-warning fs-4' : 'text-muted fs-4'\">\r\n {{ bulkSkillStars >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ bulkSkillStars }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkSkillStars <= 0\">Star rating is required</div>\r\n </div>\r\n <div class=\"mb-4\">\r\n <label class=\"small text-muted d-block mb-1\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [(ngModel)]=\"bulkSkillYear\" min=\"1\" max=\"30\"\r\n placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkSkillYear === null || bulkSkillYear === undefined\">Years of experience is required</div>\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"cancelBulkSkillConfirm()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingSkill || bulkSkillStars <= 0 || bulkSkillYear === null\"\r\n (click)=\"applyBulkSkillConfirm()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Saving...' : 'Apply to All & Save' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBulkToolConfirm\">\r\n <div class=\"confirm-modal-card\" style=\"max-width: 480px;\">\r\n <h4 class=\"mb-1\">Set Rating for All Tools</h4>\r\n <p class=\"text-muted small mb-4\">Enter a star rating and years of experience to apply to all tools that are missing these values.</p>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"bulkToolStars = s\">\r\n <span [class]=\"bulkToolStars >= s ? 'text-warning fs-4' : 'text-muted fs-4'\">\r\n {{ bulkToolStars >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ bulkToolStars }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkToolStars <= 0\">Star rating is required</div>\r\n </div>\r\n <div class=\"mb-4\">\r\n <label class=\"small text-muted d-block mb-1\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [(ngModel)]=\"bulkToolYear\" min=\"1\" max=\"30\"\r\n placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkToolYear === null || bulkToolYear === undefined\">Years of experience is required</div>\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"cancelBulkToolConfirm()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingTool || bulkToolStars <= 0 || bulkToolYear === null\"\r\n (click)=\"applyBulkToolConfirm()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Saving...' : 'Apply to All & Save' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBackConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Leave this page?</h4>\r\n <p class=\"text-muted mb-4\">If you go back, only saved data will be retained.</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"stayOnPreview()\">Stay</button>\r\n <button type=\"button\" class=\"btn btn-danger h-auto\" (click)=\"proceedBack()\">Proceed Back</button>\r\n </div>\r\n </div>\r\n\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showDashboardConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Finish Setup and Continue</h4>\r\n <p class=\"text-muted mb-4\">Save your information and go to your dashboard</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" [disabled]=\"isSavingBasic\"\r\n (click)=\"cancelDashboardRedirect()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingBasic\" (click)=\"goToDashboard()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Proceeding...' : 'Proceed' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{color:#69707d}.res-flex:hover,.res-flex:focus,.res-flex:active{transform:none!important;box-shadow:none!important}.container{max-width:900px;margin:30px auto;font-family:Arial,sans-serif;color:#69707d}.preview-page-header{max-width:900px;margin:50px auto 10px;padding:0 12px}.preview-title{font-size:18px;font-weight:700;color:#69707d;margin:0}.preview-subtitle{margin-top:7px;font-size:14px;color:#69707d}.preview-card-gradient h2,.section h5.fw-bold{font-size:18px}.section{margin-bottom:25px}.section-title{font-weight:600;display:block;margin-bottom:8px}.section-title .sub{font-weight:400;color:#777;font-size:13px}.dropdown-box{border:1px solid #ddd;border-radius:8px;padding:12px 15px;display:flex;justify-content:space-between;align-items:center}.icons{display:flex;gap:10px}.icon{cursor:pointer;font-size:14px;color:#777}.card{border:1px solid #ddd;border-radius:5px;padding:20px;background:#fff}.category{border-bottom:1px solid #eee;padding:15px 0}.category:last-child{border-bottom:none}.category-header{display:flex;justify-content:space-between;font-weight:600;margin-bottom:10px}.tags{display:flex;flex-wrap:wrap;gap:10px}.tag{background:#f2f4f7;padding:6px 12px;border-radius:6px;font-size:13px}.footer{text-align:center;margin-top:15px;color:#777;cursor:pointer}.actions{display:flex;justify-content:space-between;margin:50px 0 27px}.text-secondary{white-space:pre-line;font-size:12px;color:#69707d}.extra-small{font-size:.8rem}.card{transition:transform .2s ease,box-shadow .2s ease}.card:hover{transform:translateY(-3px)}.achievement-section .badge{font-size:.75rem;white-space:normal;text-align:left}.skill-tag .badge{font-weight:500;font-size:.9rem;transition:all .2s ease;cursor:default}.skill-tag .badge:hover{transform:translateY(-2px)}.skill-tag .btn-close{opacity:.5}.skill-tag .btn-close:hover{opacity:1}.bg-light.text-dark.border{background-color:#f8f9fa!important;border-color:#dee2e6!important}.card{transition:all .3s cubic-bezier(.25,.8,.25,1)}.card:hover .bg-light{background-color:#e8f5e9!important}.position-fixed .card:hover{transform:none!important}code{background-color:#f8f9fa;padding:2px 6px;border-radius:4px}.list-group-item{transition:all .2s ease-in-out}.list-group-item:hover{background-color:#fcfcfc;transform:translate(5px)}.border-dashed{border-style:dashed!important}.tool-card{transition:all .2s ease-in-out;border-radius:12px}.tool-card:hover{transform:translateY(-5px);border-color:var(--bs-primary)!important}.tool-card:hover .icon-box{background-color:var(--bs-primary-subtle)!important}.tool-card .icon-box{width:60px;height:60px;transition:background-color .2s ease}.border-dashed{border:2px dashed #dee2e6!important}.border-dashed:hover{border-color:var(--bs-primary)!important;background-color:#fff!important}.popup{position:fixed;top:20%;right:20px;width:320px;max-width:calc(100vw - 32px);background:#fff;border-radius:10px;padding:16px}.status-row{display:flex;justify-content:space-between;margin:10px 0}.success{color:#2e7d32;font-weight:700}.error{color:#d32f2f}.pending{color:#f9a825}.section-flag{font-weight:600}button.btn.btn-sm.btn-outline-primary{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:5px!important}button.btn.btn-sm.btn-outline-primary:hover{background-color:#356895;border-color:#356895;color:#fff}button.btn.btn-sm.btn-outline-danger{border:1px solid #dc3545;color:#dc3545;border-radius:5px!important}button.btn.btn-sm.btn-outline-primary.rounded-circle{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:5px!important}button.action-icon-btn{min-width:22px;width:22px;height:22px;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:5px!important;background:transparent!important;border:none!important;line-height:1}button.action-icon-btn.btn-outline-primary{color:#4077ad!important;border-color:#4077ad!important}button.action-icon-btn.btn-outline-danger{color:#dc3545!important}.action-icon-image{width:20px;height:20px;object-fit:contain;display:inline-block}.action-icon-image.edit-icon{filter:brightness(0) saturate(100%) invert(41%) sepia(39%) saturate(774%) hue-rotate(170deg) brightness(91%) contrast(89%)}.action-icon-image.delete-icon{filter:brightness(0) saturate(100%) invert(24%) sepia(79%) saturate(4008%) hue-rotate(344deg) brightness(91%) contrast(90%)}.modal-overlay{position:fixed;inset:0;background:#11182773;display:flex;align-items:center;justify-content:center;z-index:2500;padding:20px}.status-modal-card{width:min(760px,96vw);max-height:85vh;overflow:auto;background:#fff;border-radius:16px;border:1px solid #e5e7eb}.status-modal-header{padding:20px 24px 14px;border-bottom:1px solid #eef2f7}.status-modal-body{padding:12px 20px 20px}.status-modal-footer{padding:12px 20px 20px;border-top:1px solid #eef2f7;display:flex;justify-content:end;align-items:center;gap:12px}.status-modal-row{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px 10px;border-bottom:1px solid #f1f5f9}.status-modal-row:last-child{border-bottom:0}.status-modal-name{font-size:14px;font-weight:600;color:#69707d}.status-modal-state{font-size:.92rem;font-weight:600}.status-modal-state.pending{color:#a16207}.status-modal-state.success{color:#166534}.status-modal-state.partial{color:#b45309}.status-modal-state.error{color:#b91c1c}.confirm-modal-card{width:min(520px,96vw);background:#fff;border-radius:5px;border:1px solid #e5e7eb;padding:24px}.year-experience-select{max-height:150px}@media screen and (max-width: 768px){.res-flex{flex-wrap:wrap!important;justify-content:center!important}.res-flex .fw-normal{width:100%;text-align:center;font-size:14px!important}.d-flex.flex-wrap.gap-2.p-3.bg-white.border.rounded.shadow-sm{justify-content:center}.preview-page-header{margin:20px auto 8px;padding:0 4px}.container{padding-left:4px;padding-right:4px}.preview-title{font-size:16px}.preview-subtitle{font-size:14px}.actions{margin:24px 0 16px}.section-header-title{flex-wrap:wrap}.section-header-title>.section-flag{flex-basis:53%}.section-header-row{align-items:flex-start}.preview-card-gradient{padding:14px 14px 12px}.preview-card-gradient h2{font-size:18px}.popup{width:calc(100vw - 40px);right:16px;top:12%}.card{padding:0}.card-body.p-4,.px-4.py-3{padding:12px!important}.row.g-4,.row.g-3{--bs-gutter-x: .75rem}.d-flex.gap-4{gap:10px!important}.preview-card-gradient>.d-flex.justify-content-between.align-items-start{flex-wrap:wrap;row-gap:8px}.preview-card-gradient>.d-flex.justify-content-between.align-items-start>.badge.bg-primary-subtle{margin-left:auto}}@media screen and (max-width: 575px){.preview-title{font-size:16px}.preview-subtitle{font-size:14px}.section>.d-flex{flex-wrap:wrap;row-gap:8px}.section>.d-flex>.d-flex:last-child{width:100%;justify-content:flex-end}}::ng-deep .bs-datepicker-head{background-color:#4077ad!important}::ng-deep .bs-datepicker-body table td span.selected,.bs-datepicker-body table td.selected span{background-color:#4077ad!important}.profile-avatar-circle{width:58px;height:58px;border-radius:5px;background:#4077ad;display:flex;align-items:center;justify-content:center;font-size:22px;font-weight:700;color:#fff;letter-spacing:1px;flex-shrink:0}.section-header-icon{font-size:20px;line-height:1;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;opacity:.9;filter:invert(47%) sepia(8%) saturate(483%) hue-rotate(176deg) brightness(91%) contrast(87%)}.section-header-title h5.fw-bold{color:#69707d}.text-muted{color:#69707d!important}h6.text-uppercase.fw-bold.text-muted{font-size:14px;color:#69707d!important}.work-accent-item{border-left:4px solid #4077ad!important;border-radius:0 5px 5px 0!important;transition:background-color .18s ease,box-shadow .18s ease}.work-accent-item:hover{background-color:#f5f8ff!important;box-shadow:0 4px 14px #4077ad17!important}.edu-accent-item{border-left:4px solid #4077AD!important;border-radius:0 5px 5px 0!important;transition:background-color .18s ease,box-shadow .18s ease}.edu-accent-item:hover{background-color:#f8f8ff!important;box-shadow:0 4px 14px #6366f117!important}.cert-accent-item{border-left:4px solid #059669!important;border-radius:0 5px 5px 0!important;transition:background-color .18s ease}.cert-accent-item:hover{background-color:#f0fdf4!important}.lic-accent-item{border-left:4px solid #d97706!important;border-radius:0 5px 5px 0!important;transition:background-color .18s ease}.lic-accent-item:hover{background-color:#fffbeb!important}.field-label-sm{font-size:14px;font-weight:700;letter-spacing:.08em;color:#69707d;margin-bottom:3px;display:block}.item-name-text{color:#69707d}.field-value-sm{font-weight:600;font-size:12px;color:#69707d}.item-title-sm{font-size:14px;color:#69707d!important}.item-meta-line{display:block;font-size:12px;color:#69707d;margin-top:3px}.empty-state-wrap{text-align:center;padding:32px 20px;background:#fafbfc;border:1.5px dashed #d1d5db;border-radius:5px;cursor:pointer;transition:background-color .18s ease,border-color .18s ease}.empty-state-wrap .empty-icon{font-size:2rem;color:#d1d5db;margin-bottom:8px}.empty-state-wrap p{color:#9ca3af;margin:0;font-size:14px}.empty-state-wrap:hover{background:#f0f6ff;border-color:#4077ad}.form-panel{background:#fff;border:1px solid #e2e8f0;border-radius:5px;padding:20px}.form-panel .form-control,.form-panel .form-select{border-color:#d1d5db;border-radius:8px;font-size:12px}.form-panel .form-control:focus,.form-panel .form-select:focus{border-color:#4077ad;box-shadow:0 0 0 3px #4077ad1f}.section-header-bar{display:flex;align-items:center;justify-content:space-between;padding:10px 0 14px;border-bottom:2px solid #f1f5f9;margin-bottom:16px}.preview-card-gradient{background:linear-gradient(135deg,#fff,#eff6ff);border-bottom:1px solid #e2e8f0;padding:20px 24px 16px;border-radius:5px 5px 0 0}.item-icon-circle{width:40px;height:40px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:700;color:#fff;flex-shrink:0}.item-avatar--work{background:linear-gradient(135deg,#4077ad,#2d5a8a)}.item-avatar--edu{background:linear-gradient(135deg,#4077ad,#4338ca)}.provider-layout{display:flex;flex-direction:column}.provider-company-first{order:-1}.section-locked{pointer-events:none;opacity:.45;filter:blur(1.5px);-webkit-user-select:none;user-select:none}.btn.btn-primary{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-primary:hover:not(:disabled),.btn.btn-primary:focus:not(:disabled),.btn.btn-primary:active:not(:disabled){background-color:#356895!important;border-color:#356895!important;color:#fff!important}.btn.btn-success,.btn.btn-outline-success{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-success:hover:not(:disabled),.btn.btn-success:focus:not(:disabled),.btn.btn-success:active:not(:disabled),.btn.btn-outline-success:hover:not(:disabled),.btn.btn-outline-success:focus:not(:disabled),.btn.btn-outline-success:active:not(:disabled){background-color:#336843!important;border-color:#336843!important;color:#fff!important}.btn.btn-outline-secondary.rounded-pill{background-color:#69707d!important;border-color:#69707d!important;color:#fff!important;border-radius:5px!important}.btn.btn-outline-secondary.rounded-pill:hover:not(:disabled),.btn.btn-outline-secondary.rounded-pill:focus:not(:disabled),.btn.btn-outline-secondary.rounded-pill:active:not(:disabled){background-color:#565c66!important;border-color:#565c66!important;color:#fff!important}.preview-back-btn{background-color:#426c85!important;border-color:#426c85!important;color:#fff!important}.preview-dashboard-btn{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-outline-success:hover:not(:disabled),.btn.btn-outline-success:focus:not(:disabled),.btn.btn-outline-success:active:not(:disabled){background-color:transparent!important;border-color:#198754!important;color:#198754!important}.btn.btn-outline-secondary:not(.rounded-pill){background-color:#d4dae6!important;border-color:#d4dae6!important;color:#69707d!important}.btn.btn-outline-secondary:not(.rounded-pill):hover:not(:disabled),.btn.btn-outline-secondary:not(.rounded-pill):focus:not(:disabled),.btn.btn-outline-secondary:not(.rounded-pill):active:not(:disabled){background-color:#c2cbde!important;border-color:#c2cbde!important;color:#69707d!important}.btn.btn-danger{background-color:#b43026!important;border-color:#b43026!important;color:#fff!important}.btn.btn-danger:hover:not(:disabled),.btn.btn-danger:focus:not(:disabled),.btn.btn-danger:active:not(:disabled){background-color:#96271f!important;border-color:#96271f!important;color:#fff!important}.btn.btn-outline-danger.rounded-circle{border-color:#b43026!important;color:#b43026!important;border-radius:5px!important}.btn.btn-outline-danger.rounded-circle:hover:not(:disabled),.btn.btn-outline-danger.rounded-circle:focus:not(:disabled),.btn.btn-outline-danger.rounded-circle:active:not(:disabled){border-color:#96271f!important;color:#b43026!important}.btn.btn-link.text-secondary{background-color:#d4dae6!important;border-color:#d4dae6!important;color:#69707d!important;text-decoration:none!important;border-radius:5px}.btn.btn-link.text-secondary:hover:not(:disabled),.btn.btn-link.text-secondary:focus:not(:disabled){background-color:#c2cbde!important;color:#69707d!important}.btn.btn-link.text-danger{background-color:#b43026!important;border-color:#b43026!important;color:#fff!important;text-decoration:none!important;border-radius:5px}.btn.btn-link.text-danger:hover:not(:disabled),.btn.btn-link.text-danger:focus:not(:disabled){background-color:#96271f!important;color:#fff!important}.btn{border-radius:5px!important;box-shadow:none!important}.badge.bg-warning-subtle.text-warning{background-color:#fff3cd!important;color:#664d03!important;border-color:#ffe69c!important}.badge.bg-success-subtle.text-success{background-color:#4077ad!important;color:#fff!important;border-color:#4077ad!important}.badge.bg-primary-subtle.text-primary{background-color:#e0edf2!important;color:#4077ad!important;border-color:#e0edf2!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ModalModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i7.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: i7.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i7.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i7.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i7.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i7.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i7.EmailValidator, selector: "[email][formControlName],[email][formControl],[email][ngModel]", inputs: ["email"] }, { kind: "directive", type: i7.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i7.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i7.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: NgSelectModule }, { kind: "component", type: i12.NgSelectComponent, selector: "ng-select", inputs: ["bindLabel", "bindValue", "markFirst", "placeholder", "notFoundText", "typeToSearchText", "addTagText", "loadingText", "clearAllText", "appearance", "dropdownPosition", "appendTo", "loading", "closeOnSelect", "hideSelected", "selectOnTab", "openOnEnter", "maxSelectedItems", "groupBy", "groupValue", "bufferAmount", "virtualScroll", "selectableGroup", "selectableGroupAsModel", "searchFn", "trackByFn", "clearOnBackspace", "labelForId", "inputAttrs", "tabIndex", "readonly", "searchWhileComposing", "minTermLength", "editableSearchTerm", "keyDownFn", "typeahead", "multiple", "addTag", "searchable", "clearable", "isOpen", "items", "compareWith", "clearSearchOnAdd", "deselectOnClick"], outputs: ["blur", "focus", "change", "open", "close", "search", "clear", "add", "remove", "scroll", "scrollToEnd"] }, { kind: "ngmodule", type: NgxStarsModule }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "directive", type: i13.BsDatepickerDirective, selector: "[bsDatepicker]", inputs: ["placement", "triggers", "outsideClick", "container", "outsideEsc", "isDisabled", "minDate", "maxDate", "ignoreMinMaxErrors", "minMode", "daysDisabled", "datesDisabled", "datesEnabled", "dateCustomClasses", "dateTooltipTexts", "isOpen", "bsValue", "bsConfig"], outputs: ["onShown", "onHidden", "bsValueChange"], exportAs: ["bsDatepicker"] }, { kind: "directive", type: i13.BsDatepickerInputDirective, selector: "input[bsDatepicker]" }, { kind: "ngmodule", type: TextMaskModule }, { kind: "ngmodule", type: AddressVerifyFieldModule }, { kind: "component", type: AddressVerifyFieldComponent, selector: "im-address-verify-field", inputs: ["placeholder", "options", "maxLength", "inputId", "name", "autocompleteAttr", "inputClass", "invalid", "inputStyle", "initialLat", "initialLng"], outputs: ["addressResolved", "manualEdit"] }] });
|
|
6377
6424
|
}
|
|
6378
6425
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PreviewComponent, decorators: [{
|
|
6379
6426
|
type: Component,
|
|
@@ -6381,8 +6428,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6381
6428
|
CommonModule, ModalModule, FormsModule, ReactiveFormsModule,
|
|
6382
6429
|
NgSelectModule, NgxStarsModule, BsDatepickerModule, TextMaskModule,
|
|
6383
6430
|
AddressVerifyFieldModule
|
|
6384
|
-
], template: "<div class=\"preview-page-header\" *ngIf=\"!isResume\">\r\n <div class=\"d-flex align-items-center gap-2 mb-1\">\r\n <h2 class=\"preview-title mb-0\">Review Extracted Information</h2>\r\n </div>\r\n <p class=\"preview-subtitle text-muted\">We\u2019ve automatically extracted details from your uploaded resume. Please review and confirm accuracy before proceeding.</p>\r\n</div>\r\n\r\n\r\n<div [ngClass]=\"isResume ? '' : 'container py-4'\" [class.provider-layout]=\"roleData?.role?.name === 'Provider'\">\r\n\r\n <!-- Provider initial setup: combined company + personal form (shown until both APIs succeed) -->\r\n <div class=\"section mb-5\" *ngIf=\"roleData?.role?.name === 'Provider' && !hasUserDetailData\">\r\n <div class=\"d-flex align-items-center gap-2 mb-3 section-header-title\">\r\n <img src=\"/assets/images/icons/building.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Company & Personal Details</h5>\r\n <span class=\"badge border section-flag bg-warning-subtle text-warning\">Required to continue</span>\r\n </div>\r\n <div class=\"card shadow-sm border-0\">\r\n <div class=\"card-header bg-white fw-semibold\">Company Information</div>\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-3\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': (!tempCompanyDetails.companyName?.trim() && companyFormSubmitted) || companyNameError}\"\r\n [(ngModel)]=\"tempCompanyDetails.companyName\" name=\"setupCompanyName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyName?.trim() && companyFormSubmitted\">Company name is required</div>\r\n <div class=\"invalid-feedback\" *ngIf=\"companyNameError\">{{ companyNameError }}</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" maxlength=\"14\" inputmode=\"numeric\"\r\n (input)=\"phoneMask($event, 'company')\" (keypress)=\"allowOnlyNumbers($event)\"\r\n [ngClass]=\"{'is-invalid': companyFormSubmitted && (!tempCompanyDetails.companyPhoneNumber?.trim() || getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10)}\"\r\n [(ngModel)]=\"tempCompanyDetails.companyPhoneNumber\" name=\"setupCompanyPhone\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted\">Company phone is required</div>\r\n <div class=\"invalid-feedback\" *ngIf=\"tempCompanyDetails.companyPhoneNumber?.trim() && getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10 && companyFormSubmitted\">Company phone must be 10 digits</div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Company Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempCompanyDetails.address1\" name=\"setupCompanyAddress\"\r\n [options]=\"options\" inputClass=\"form-control form-control-sm\"\r\n [invalid]=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\">Address is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.city?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.city\" name=\"setupCompanyCity\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.city?.trim() && companyFormSubmitted\">City is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.state?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.state\" name=\"setupCompanyState\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.state?.trim() && companyFormSubmitted\">State is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.zipcode?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.zipcode\" name=\"setupCompanyZip\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.zipcode?.trim() && companyFormSubmitted\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.country?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.country\" name=\"setupCompanyCountry\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.country?.trim() && companyFormSubmitted\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <input type=\"file\" accept=\".png,.jpg,.jpeg\" class=\"form-control form-control-sm\" (change)=\"uploadCompanyImage($event)\" name=\"setupCompanyLogo\" />\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"tempCompanyLogoUrl\">\r\n <label class=\"small text-muted d-block\">Logo Preview</label>\r\n <img [src]=\"tempCompanyLogoUrl\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-header bg-white fw-semibold border-top\">Personal Information</div>\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-3\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">First Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.firstName?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.firstName\" name=\"setupFirstName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.firstName?.trim() && companyFormSubmitted\">First name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.lastName?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.lastName\" name=\"setupLastName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.lastName?.trim() && companyFormSubmitted\">Last name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Email <span class=\"text-danger\">*</span></label>\r\n <input type=\"email\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.email?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.email\" name=\"setupEmail\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.email?.trim() && companyFormSubmitted\">Email is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Phone Number <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" maxlength=\"14\" inputmode=\"numeric\"\r\n (input)=\"phoneMask($event, 'profile')\" (keypress)=\"allowOnlyNumbers($event)\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.phone?.trim() && companyFormSubmitted}\"\r\n [ngModel]=\"tempProfile?.phone\" name=\"setupPhone\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.phone?.trim() && companyFormSubmitted\">Phone number is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempProfile.address\" name=\"setupAddress\" [options]=\"options\"\r\n inputClass=\"form-control form-control-sm\" [invalid]=\"!tempProfile?.address?.trim() && companyFormSubmitted\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.address?.trim() && companyFormSubmitted\">Home address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.city?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.city\" name=\"setupUserCity\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.city?.trim() && companyFormSubmitted\">City is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.state?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.state\" name=\"setupUserState\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.state?.trim() && companyFormSubmitted\">State is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.zipCode?.trim() && companyFormSubmitted}\"\r\n [ngModel]=\"tempProfile?.zipCode\" (ngModelChange)=\"tempProfile.zipCode = sanitizeZipCode($event)\"\r\n name=\"setupUserZip\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.zipCode?.trim() && companyFormSubmitted\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.country?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.country\" name=\"setupUserCountry\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.country?.trim() && companyFormSubmitted\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [(ngModel)]=\"tempProfile.jobTitle\" name=\"setupJobTitle\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control form-control-sm\" [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n [ngClass]=\"{'is-invalid': !(tempProfile?.yearsOfExperience > 0) && companyFormSubmitted}\"\r\n name=\"setupYearsOfExp\" min=\"1\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!(tempProfile?.yearsOfExperience > 0) && companyFormSubmitted\">Years of experience is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Profile Picture</label>\r\n <input #setupHeadshotFile type=\"file\" accept=\".png,.jpg,.jpeg\" class=\"d-none\" (change)=\"uploadHeadshotImage($event)\" name=\"setupHeadshotFile\" />\r\n <div class=\"position-relative\">\r\n <input type=\"text\" class=\"form-control form-control-sm pe-5\" [value]=\"headshotFileName\" readonly\r\n placeholder=\"Upload Profile Picture\" (click)=\"setupHeadshotFile.click()\" />\r\n <img *ngIf=\"!isHeadshotLoading\" src=\"assets/images/icons/upload.svg\" alt=\"Upload\" class=\"upload-icon\" style=\"position:absolute;right:12px;top:50%;transform:translateY(-50%);cursor:pointer;width:18px;\" (click)=\"setupHeadshotFile.click()\" />\r\n <div *ngIf=\"isHeadshotLoading\" style=\"position:absolute;right:12px;top:50%;transform:translateY(-50%);\">\r\n <span class=\"spinner-border spinner-border-sm text-primary\"></span>\r\n </div>\r\n </div>\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"headshotPreviewUrl\">\r\n <label class=\"small text-muted d-block\">Preview</label>\r\n <img [src]=\"cloudfrontUrl + headshotPreviewUrl\" class=\"img-thumbnail rounded-circle\" style=\"width:64px;height:64px;object-fit:cover;\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-footer d-flex align-items-center justify-content-end gap-2\">\r\n <span *ngIf=\"providerSetupError\" class=\"small text-danger me-auto\">{{ providerSetupError }}</span>\r\n <button class=\"btn btn-success px-5 \"\r\n [disabled]=\"isSavingProviderSetup || !isProviderSetupFormComplete\"\r\n (click)=\"saveProviderSetup()\">\r\n <span *ngIf=\"isSavingProviderSetup\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingProviderSetup ? 'Saving...' : 'Save & Continue' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\" *ngIf=\"roleData?.role?.name !== 'Provider' || hasUserDetailData\">\r\n <div *ngIf=\"details() as data; else loading\">\r\n <div class=\"card shadow-sm border-0 rounded-3 overflow-hidden\" *ngIf=\"!isEditMode()\">\r\n <div class=\"card-body p-0\">\r\n <div class=\"preview-card-gradient\">\r\n <div class=\"d-flex justify-content-between align-items-start mb-4\">\r\n <div class=\"d-flex align-items-start gap-3\">\r\n <div class=\"profile-avatar-circle\" *ngIf=\"!headshotPreviewUrl\">\r\n {{ (data.firstName?.[0] || '') }}{{ (data.lastName?.[0] || '') }}\r\n </div>\r\n <img *ngIf=\"headshotPreviewUrl\" [src]=\" cloudfrontUrl + headshotPreviewUrl\"\r\n class=\"rounded-circle\" style=\"width:56px;height:56px;object-fit:cover;\" alt=\"Profile\" />\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h2 class=\"fw-bold mb-1\">{{ data.firstName }} {{ data.lastName }}</h2>\r\n <span *ngIf=\"basicSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n <span class=\"badge border section-flag\"\r\n [ngClass]=\"basicDetailsSaved ? 'bg-success-subtle text-success' : 'bg-warning-subtle text-warning'\">\r\n {{ basicDetailsSaved ? 'Saved' : 'Not saved yet' }}\r\n </span>\r\n </div>\r\n <p class=\"text-muted\">{{ data.jobTitle }} \u2022 {{ data.yearsOfExperience }} Years Exp.</p>\r\n <div *ngIf=\"basicIssues().length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ basicIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <span class=\"badge bg-primary-subtle text-primary border p-2\">Email Verified</span>\r\n </div>\r\n\r\n </div>\r\n <div class=\"px-4 py-3\">\r\n <div class=\"row g-4\">\r\n <div class=\"col-12 border-bottom pb-2\">\r\n <h6 class=\"text-uppercase small fw-bold text-muted\">Summary</h6>\r\n <p class=\"text-secondary small mb-0\">{{ data.summary }}</p>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/envelope.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Email</span>\r\n <span class=\"field-value-sm d-block\">{{ data.email }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/telephone.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Phone</span>\r\n <span class=\"field-value-sm d-block\">{{ data.phone }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/geo-alt.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Location</span>\r\n <span class=\"field-value-sm d-block\">{{ data.address }}, {{ data.city }}, {{ data.state }}, {{ data.zipCode }}, {{ data.country }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer d-flex align-items-center justify-content-between\">\r\n <span *ngIf=\"!basicDetailsSaved\" class=\"small text-warning fw-semibold\">\r\n <img src=\"/assets/images/icons/exclamation-circle.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" /> Click \"Edit\" to review and save your basic info.\r\n </span>\r\n <span *ngIf=\"basicDetailsSaved\" class=\"small text-success fw-semibold\">\r\n <img src=\"/assets/images/icons/check-circle.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" /> Basic details saved.\r\n </span>\r\n <button class=\"btn btn-sm btn-primary px-4 ms-auto\" (click)=\"toggleEdit()\">Edit</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"isEditMode()\">\r\n <div class=\"card-header bg-white fw-bold\">Update Profile</div>\r\n <div class=\"card-body p-4\">\r\n <form class=\"row g-3\" #basicForm=\"ngForm\" novalidate>\r\n <div *ngIf=\"basicIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ basicIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">First Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.firstName\" name=\"fName\"\r\n placeholder=\"First Name\" required #fName=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"fName.invalid && (fName.dirty || fName.touched)\">First name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.lastName\" name=\"lName\"\r\n placeholder=\"Last Name\" required #lName=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"lName.invalid && (lName.dirty || lName.touched)\">Last name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Email <span class=\"text-danger\">*</span></label>\r\n <input type=\"email\" class=\"form-control\" [(ngModel)]=\"tempProfile.email\" name=\"email\" placeholder=\"Email\"\r\n required email #email=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"email.invalid && (email.dirty || email.touched)\">\r\n <span *ngIf=\"email.errors?.['required']\">Email is required</span>\r\n <span *ngIf=\"email.errors?.['email']\">Email format is invalid</span>\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Phone Number <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"tempProfile.phone\" (input)=\"phoneMask($event, 'profile')\"\r\n name=\"phone\" placeholder=\"Phone (10 digits)\" (keypress)=\"allowOnlyNumbers($event)\"\r\n required pattern=\"^\\(\\d{3}\\) \\d{3}-\\d{4}$\" maxlength=\"14\" inputmode=\"numeric\" #phone=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"phone.invalid && (phone.dirty || phone.touched)\">\r\n <span *ngIf=\"phone.errors?.['required']\">Phone number is required</span>\r\n <span *ngIf=\"phone.errors?.['pattern']\">Phone number must be 10 digits</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\"></span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.jobTitle\" name=\"jobTitle\"\r\n placeholder=\"Job Title\" #jobTitle=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"jobTitle.invalid && (jobTitle.dirty || jobTitle.touched)\">Job\r\n title is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngClass]=\"{'is-invalid': !(tempProfile?.yearsOfExperience > 0)}\"\r\n [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n name=\"yearsOfExperience\" placeholder=\"Years of Experience\" required min=\"1\"\r\n #yearsOfExperience=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!(tempProfile?.yearsOfExperience > 0)\">\r\n Years of experience is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempProfile.address\" name=\"address\" [options]=\"options\"\r\n placeholder=\"Home Address\" required #address=\"ngModel\"\r\n [invalid]=\"address.invalid && (address.dirty || address.touched)\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"></im-address-verify-field>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"address.invalid && (address.dirty || address.touched)\">Home\r\n address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.city\" name=\"city\" placeholder=\"City\"\r\n required #city=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"city.invalid && (city.dirty || city.touched)\">City is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.state\" name=\"state\" placeholder=\"State\"\r\n required #state=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"state.invalid && (state.dirty || state.touched)\">State is\r\n required</div>\r\n </div>\r\n\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"tempProfile.zipCode\"\r\n (ngModelChange)=\"tempProfile.zipCode = sanitizeZipCode($event)\" name=\"zipCode\" placeholder=\"Zip Code\"\r\n required pattern=\"^\\d{1,6}$\" maxlength=\"6\" inputmode=\"numeric\" #zipCode=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"zipCode.invalid && (zipCode.dirty || zipCode.touched)\">Zip code\r\n is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"zipCode.errors?.['pattern'] && (zipCode.dirty || zipCode.touched)\">\r\n Zip code must be up to 6 digits\r\n </div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.country\" name=\"country\"\r\n placeholder=\"Country\" required #country=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"country.invalid && (country.dirty || country.touched)\">Country\r\n is required</div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Summary</label>\r\n <textarea class=\"form-control\" rows=\"3\" [(ngModel)]=\"tempProfile.summary\" name=\"sum\"\r\n placeholder=\"Summary\"></textarea>\r\n </div>\r\n\r\n\r\n </form>\r\n </div>\r\n <div class=\"card-footer text-end gap-2 d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancel()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingBasic || !isBasicFormValid\" (click)=\"save()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Saving...' : 'Save Changes' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5 provider-company-first\" *ngIf=\"roleData?.role?.name === 'Provider' && hasUserDetailData && !hasRoleContextUserId\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/building.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Company Details</h5>\r\n <span *ngIf=\"companyDetailsSaved\"\r\n class=\"badge border section-flag bg-success-subtle text-success\">\r\n Saved\r\n </span>\r\n <span *ngIf=\"!companyDetailsSaved\"\r\n class=\"badge border section-flag bg-warning-subtle text-warning\">\r\n Not saved yet\r\n </span>\r\n </div>\r\n <button class=\"btn btn-sm btn-primary px-4\" (click)=\"toggleCompanyEdit()\">Edit</button>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"!isCompanyEditMode()\">\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-4\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name</label>\r\n <span class=\"fw-bold small\">{{ companyDetails()?.companyName}}</span>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone</label>\r\n <span class=\"fw-bold small\">{{ companyDetails()?.companyPhoneNumber}}</span>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Company Address</label>\r\n <span class=\"small\">{{ companyDetails()?.address1}}, {{ companyDetails()?.city}}, {{ companyDetails()?.state}}, {{ companyDetails()?.zipcode}}, {{ companyDetails()?.country}}</span>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"companyLogoUrl()\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <img [src]=\"companyLogoUrl()\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"isCompanyEditMode()\">\r\n <div class=\"card-header bg-white fw-bold\">Update Company Details</div>\r\n <div class=\"card-body p-4\">\r\n <form class=\"row g-3\" #companyForm=\"ngForm\" novalidate>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': (!tempCompanyDetails.companyName?.trim() && companyFormSubmitted) || companyNameError }\"\r\n [(ngModel)]=\"tempCompanyDetails.companyName\" name=\"companyName\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyName?.trim() && companyFormSubmitted\">\r\n Company name is required\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"companyNameError\">\r\n {{ companyNameError }}\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone <span class=\"text-danger\">*</span></label>\r\n <input (input)=\"phoneMask($event, 'company')\" type=\"text\" maxlength=\"14\" (keypress)=\"allowOnlyNumbers($event)\" inputmode=\"numeric\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{ 'is-invalid': companyFormSubmitted && (!tempCompanyDetails.companyPhoneNumber?.trim() || getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10) }\"\r\n [(ngModel)]=\"tempCompanyDetails.companyPhoneNumber\" name=\"companyPhoneNumber\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted\">\r\n Company phone is required\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"tempCompanyDetails.companyPhoneNumber?.trim() && getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10 && companyFormSubmitted\">\r\n Company phone must be 10 digits\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempCompanyDetails.address1\" name=\"address1\" [options]=\"options\"\r\n required [invalid]=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\">\r\n Address is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.city?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.city\" name=\"city\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.city?.trim() && companyFormSubmitted\">\r\n City is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.state?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.state\" name=\"state\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.state?.trim() && companyFormSubmitted\">\r\n State is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.zipcode?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.zipcode\" name=\"zipcode\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.zipcode?.trim() && companyFormSubmitted\">\r\n Zip code is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.country?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.country\" name=\"country\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.country?.trim() && companyFormSubmitted\">\r\n Country is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <input #uploadCompanyFile type=\"file\" accept=\".png,.jpg,.jpeg\" (change)=\"uploadCompanyImage($event)\" class=\"form-control\" />\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"tempCompanyLogoUrl\">\r\n <label class=\"small text-muted d-block\">Logo Preview</label>\r\n <img [src]=\"tempCompanyLogoUrl\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </form>\r\n </div>\r\n <div class=\"card-footer text-end gap-2 d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelCompanyEdit()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCompany\" \r\n (click)=\"saveCompanyDetails()\">\r\n <span *ngIf=\"isSavingCompany\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCompany ? 'Saving...' : 'Save Changes' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div [class.section-locked]=\"roleData?.role?.name === 'Provider' && !hasUserDetailData\">\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/briefcase-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Work Experience</h5>\r\n <span *ngIf=\"experience().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"workSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ workSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"experience().length === 0 || !workSectionHasUnsavedItems() || isSavingWork || isAddingJob() || editingJobIndex() !== null\"\r\n (click)=\"confirmAllWork()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add work experience\" (click)=\"addJob()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"experience().length === 0 && !isAddingJob()\" class=\"empty-state-wrap mb-3\" role=\"button\"\r\n (click)=\"addJob()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/briefcase.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No work experience added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3\">\r\n <div *ngIf=\"isAddingJob() && tempJob()\" class=\"list-group-item p-0 border-0\">\r\n <div class=\"form-panel mb-2\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\" name=\"newJobTitle\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\" name=\"newCompany\" />\r\n </div>\r\n <div class=\"align-items-end col-md-12 d-flex justify-content-end pe-3\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\" name=\"newIsCurrent\" id=\"newIsCurrent\" />\r\n <label class=\"form-check-label\" for=\"newIsCurrent\">Current</label>\r\n </div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.country\"\r\n (ngModelChange)=\"patchTempJob({ country: $event })\" name=\"newCountry\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.state\"\r\n (ngModelChange)=\"patchTempJob({ state: $event })\" name=\"newState\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\" name=\"newCity\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempJob()?.startDate)\"\r\n (bsValueChange)=\"setTempJobMonth('startDate', $event)\" name=\"newStartDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.startDate)\">Start date is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"monthInputToDate(tempJob()?.endDate)\" (bsValueChange)=\"setTempJobMonth('endDate', $event)\"\r\n name=\"newEndDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">End date is\r\n required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isMonthRangeInvalid(tempJob()?.startDate, tempJob()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Responsibilities (one per line)</label>\r\n <textarea rows=\"4\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\" name=\"newResponsibilities\"></textarea>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\" name=\"newWorkAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempJob()?.fileName\">\r\n <span>{{ tempJob()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempJob())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n <div class=\"d-flex justify-content-end gap-2 mt-3\">\r\n <button class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingWork\"\r\n (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : workActionLabel(editingJobIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n\r\n <div *ngFor=\"let job of experience(); let i = index\" class=\"list-group-item p-0 border-0 mb-2\">\r\n\r\n <div class=\"work-accent-item p-3 rounded-3 bg-white border\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div class=\"d-flex align-items-center cursor-pointer flex-grow-1\" (click)=\"toggleJob(i)\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h6 class=\"mb-0 fw-bold item-title-sm\">{{ job.jobTitle }}</h6>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedWorkItem(i) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedWorkItem(i) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ job.company || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ formatMonthYear(job.startDate) }} - {{ job.isCurrent ? 'Present' :\r\n formatMonthYear(job.endDate) }}</span>\r\n <span class=\"item-meta-line\">{{ job.city }}<span *ngIf=\"job.city && job.state\">, </span>{{ job.state }}<ng-container *ngIf=\"!job.city && !job.state\">\u2014</ng-container></span>\r\n <div *ngIf=\"editingJobIndex() !== i && (workIssuesByIndex()[i] || []).length > 0\"\r\n class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (workIssuesByIndex()[i] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center gap-2\">\r\n\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\" (click)=\"startEditJob(i)\"\r\n title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteJob(i);\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n \r\n </div>\r\n </div>\r\n\r\n\r\n\r\n <div class=\"mt-3 p-3 rounded small\" *ngIf=\"expandedIndex() === i\">\r\n <ng-container *ngIf=\"editingJobIndex() !== i; else editJobForm\">\r\n <ul class=\"mb-0\">\r\n <li *ngFor=\"let res of job.responsibilities\">{{ res }}</li>\r\n </ul>\r\n </ng-container>\r\n\r\n <ng-template #editJobForm>\r\n <div *ngIf=\"(workIssuesByIndex()[i] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (workIssuesByIndex()[i] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\" name=\"jobTitle{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.jobTitle)\">Job title is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\" name=\"company{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.company)\">Company name is required</div>\r\n </div>\r\n\r\n <div class=\"align-items-end col-md-12 d-flex justify-content-end pe-3\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\" name=\"isCurrent{{ i }}\" id=\"isCurrent{{ i }}\" />\r\n <label class=\"form-check-label\" for=\"isCurrent{{ i }}\">Current</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.country\"\r\n (ngModelChange)=\"patchTempJob({ country: $event })\" name=\"country{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.state\"\r\n (ngModelChange)=\"patchTempJob({ state: $event })\" name=\"state{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\" name=\"city{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.city)\">City is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempJob()?.startDate)\"\r\n (bsValueChange)=\"setTempJobMonth('startDate', $event)\" name=\"startDate{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.startDate)\">Start date is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"monthInputToDate(tempJob()?.endDate)\" (bsValueChange)=\"setTempJobMonth('endDate', $event)\"\r\n name=\"endDate{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">\r\n End date is required\r\n </div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isMonthRangeInvalid(tempJob()?.startDate, tempJob()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Responsibilities (one per line)</label>\r\n <textarea rows=\"4\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\" name=\"responsibilities{{ i }}\"></textarea>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\" name=\"workAttachment{{ i }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempJob()?.fileName\">\r\n <span>{{ tempJob()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempJob())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n </ng-template>\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-3\" *ngIf=\"editingJobIndex() === i\">\r\n <button class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4 \" [disabled]=\"isSavingWork\"\r\n (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : workActionLabel(editingJobIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/patch-check-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Certifications</h5>\r\n <span *ngIf=\"certs().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"certificationSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ certificationSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"certs().length === 0 || !certificationSectionHasUnsavedItems() || isSavingCertification || isAddingCertification() || editingCertificationIndex() !== null\"\r\n (click)=\"confirmAllCertifications()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add certification\" (click)=\"addCertification()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"certs().length === 0 && !isAddingCertification() && editingCertificationIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addCertification()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/patch-check.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No certifications added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3 border\">\r\n <div *ngIf=\"isAddingCertification() && tempCertification()\" class=\"list-group-item py-3 px-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\" name=\"newCertName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\" name=\"newCertOrg\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\" name=\"newCertState\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certification Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\" name=\"newCertCredentialId\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('issueDate', $event)\" name=\"newCertIssueDate\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('expiryDate', $event)\" name=\"newCertExpiryDate\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempCertification()?.issueDate || null, tempCertification()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\" name=\"newCertAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempCertification()?.fileName\">\r\n <span>{{ tempCertification()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempCertification())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\"\r\n (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : certificationActionLabel(editingCertificationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let cert of certs(); let ci = index\" class=\"list-group-item py-3 cert-accent-item\">\r\n <ng-container *ngIf=\"editingCertificationIndex() !== ci; else editCert\">\r\n <div class=\"d-flex justify-content-between align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <div class=\"fw-semibold item-title-sm\">{{ cert.name }}</div>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedCertificationItem(ci) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedCertificationItem(ci) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ cert.issuingOrganization || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.credentialId || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.issueDate ? formatMonthYear(cert.issueDate) : '\u2014' }} - {{ cert.expiryDate ? formatMonthYear(cert.expiryDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.state || '\u2014' }}</span>\r\n <div *ngIf=\"(certIssuesByIndex()[ci] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (certIssuesByIndex()[ci] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditCertification(ci)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteCertification(ci)\" title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #editCert>\r\n <div *ngIf=\"(certIssuesByIndex()[ci] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (certIssuesByIndex()[ci] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\" name=\"certName{{ ci }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\"\r\n name=\"certOrg{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\" name=\"certState{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certification Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\"\r\n name=\"certCredentialId{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('issueDate', $event)\" name=\"certIssue{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('expiryDate', $event)\" name=\"certExpiry{{ ci }}\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempCertification()?.issueDate || null, tempCertification()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\" name=\"certAttachment{{ ci }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempCertification()?.fileName\">\r\n <span>{{ tempCertification()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempCertification())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\"\r\n (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : certificationActionLabel(editingCertificationIndex()) }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/card-checklist-warning.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Licenses</h5>\r\n <span *ngIf=\"licenses().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"licenseSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ licenseSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"licenses().length === 0 || !licenseSectionHasUnsavedItems() || isSavingLicense || isAddingLicense() || editingLicenseIndex() !== null\"\r\n (click)=\"confirmAllLicenses()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add license\" (click)=\"addLicense()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"licenses().length === 0 && !isAddingLicense() && editingLicenseIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addLicense()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/card-checklist.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No licenses added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3 border\">\r\n <div *ngIf=\"isAddingLicense() && tempLicense()\" class=\"list-group-item py-3 px-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\" name=\"newLicName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempLicense()?.name)\">License name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\" name=\"newLicAuthority\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\" name=\"newLicNumber\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\" name=\"newLicState\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('issueDate', $event)\" name=\"newLicIssueDate\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('expiryDate', $event)\" name=\"newLicExpiryDate\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempLicense()?.issueDate || null, tempLicense()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">License File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\" name=\"newLicenseAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempLicense()?.fileName\">\r\n <span>{{ tempLicense()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempLicense())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelEditLicense()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingLicense\"\r\n (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : licenseActionLabel(editingLicenseIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let lic of licenses(); let li = index\" class=\"list-group-item py-3 lic-accent-item\">\r\n <ng-container *ngIf=\"editingLicenseIndex() !== li; else editLic\">\r\n <div class=\"d-flex justify-content-between align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <div class=\"fw-semibold item-title-sm\">{{ lic.name }}</div>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedLicenseItem(li) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedLicenseItem(li) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ lic.issuingAuthority || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.licenseNumber || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.issueDate ? formatMonthYear(lic.issueDate) : '\u2014' }} - {{ lic.expiryDate ? formatMonthYear(lic.expiryDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.state || '\u2014' }}</span>\r\n <div *ngIf=\"(licenseIssuesByIndex()[li] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (licenseIssuesByIndex()[li] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditLicense(li)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteLicense(li)\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #editLic>\r\n <div *ngIf=\"(licenseIssuesByIndex()[li] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (licenseIssuesByIndex()[li] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\" name=\"licName{{ li }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempLicense()?.name)\">License name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\" name=\"licAuthority{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\" name=\"licNumber{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\" name=\"licState{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('issueDate', $event)\" name=\"licIssue{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('expiryDate', $event)\" name=\"licExpiry{{ li }}\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempLicense()?.issueDate || null, tempLicense()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">License File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\" name=\"licenseAttachment{{ li }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempLicense()?.fileName\">\r\n <span>{{ tempLicense()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempLicense())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditLicense()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingLicense\"\r\n (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : licenseActionLabel(editingLicenseIndex()) }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/tools.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Tools</h5>\r\n <span *ngIf=\"tools().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"toolsSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ toolsSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"tools().length === 0 || !toolsSectionHasUnsavedItems() || isSavingTool || isToolEditorOpen()\" (click)=\"confirmAllTools()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add tool\" (click)=\"addTool()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex flex-wrap gap-2 p-3 bg-white border rounded shadow-sm\">\r\n <div *ngFor=\"let tool of tools(); let ti = index\" class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\"\r\n class=\"btn btn-light border res-flex d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openToolEditor(ti)\" title=\"Edit\">\r\n <span class=\"fw-normal item-name-text\">{{ tool }}</span>\r\n <span class=\"badge border ms-1\"\r\n [ngClass]=\"hasUnsavedToolItem(ti) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedToolItem(ti) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n <span *ngIf=\"(toolIssuesByIndex()[ti] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\">\r\n Missing info\r\n </span>\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Delete tool\" (click)=\"deleteTool(ti)\">\r\n <span class=\"fw-bold\">\u00D7</span>\r\n </button>\r\n </div>\r\n\r\n <span *ngIf=\"tools().length === 0\" class=\"text-muted small\">No tools added.</span>\r\n </div>\r\n\r\n <div *ngIf=\"isToolEditorOpen()\" class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 9999999;\" (click)=\"closeToolEditor()\">\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\"\r\n (click)=\"$event.stopPropagation()\">\r\n <div class=\"card shadow border-0 w-100\" style=\"max-width: 900px;\">\r\n <div class=\"card-header bg-white d-flex align-items-center gap-3\">\r\n <button type=\"button\" class=\"btn btn-link p-0 text-decoration-none\" (click)=\"closeToolEditor()\">\r\n <img src=\"/assets/images/icons/arrow-left-blue.svg\" width=\"20\" height=\"20\" alt=\"\" />\r\n </button>\r\n <div class=\"fw-bold\">{{ isAddingTool() ? 'Add Tool' : ('Edit ' + (toolForm()?.name || '') + ' Tool') }}\r\n </div>\r\n </div>\r\n <div class=\"card-body p-4\">\r\n <div *ngIf=\"toolFormIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ toolFormIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"row g-3\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Tool Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"toolForm()?.name\"\r\n (ngModelChange)=\"patchToolForm({ name: $event })\" name=\"toolName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(toolForm()?.name)\">Tool name is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span\r\n class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempToolStars(s)\" [attr.aria-label]=\"'Set rating ' + s\">\r\n <span [class]=\"(toolForm()?.stars || 0) >= s ? 'text-warning fs-5' : 'text-muted fs-5'\">\r\n {{ (toolForm()?.stars || 0) >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ toolForm()?.stars || 0 }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"(toolForm()?.stars || 0) <= 0\">Star rating is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngModel]=\"toolForm()?.year\"\r\n (ngModelChange)=\"patchToolForm({ year: $event === '' ? null : +$event })\" name=\"toolYear\" min=\"1\"\r\n max=\"30\" placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"toolForm()?.year === null || toolForm()?.year === undefined\">\r\n Years of experience is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4 text-center\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-checks form-switch mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"toolForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchToolForm({ profileVisibility: $event })\" name=\"toolVisible\" id=\"toolVisible\"\r\n style=\"width: 55px;height: 25px;margin-left: -57px;\" />\r\n <label class=\"form-check-label ps-2 pt-1\" for=\"toolVisible\">Visible</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Comment</label>\r\n <textarea rows=\"4\" class=\"form-control\" [ngModel]=\"toolForm()?.notes\"\r\n (ngModelChange)=\"patchToolForm({ notes: $event })\" name=\"toolNotes\"\r\n placeholder=\"Comment your tool here...\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-white d-flex justify-content-end gap-2\">\r\n <button *ngIf=\"!isAddingTool() && editingToolIndex() !== null\" type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\" (click)=\"deleteTool(editingToolIndex()!)\">\r\n Delete\r\n </button>\r\n <button type=\"button\" class=\"btn btn-link text-secondary\" (click)=\"closeToolEditor()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary px-4\" [disabled]=\"isSavingTool\" (click)=\"saveToolEditor()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Saving...' : toolActionLabel(editingToolIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row g-4 mb-5\">\r\n <div class=\"col-md-12\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/stars.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Skills</h5>\r\n <span *ngIf=\"skills().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"skillsSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ skillsSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"skills().length === 0 || !skillsSectionHasUnsavedItems() || isSavingSkill || isSkillEditorOpen()\" (click)=\"confirmAllSkills()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add skill\" (click)=\"addSkill()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex flex-wrap gap-2 p-3 bg-white border rounded shadow-sm\">\r\n <div *ngFor=\"let skill of skills(); let si = index\" class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\"\r\n class=\"btn btn-light border res-flex d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openSkillEditor(si)\" title=\"Edit\">\r\n <span class=\"fw-normal item-name-text\">{{ skill }}</span>\r\n <span class=\"badge border ms-1\"\r\n [ngClass]=\"hasUnsavedSkillItem(si) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedSkillItem(si) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n <span *ngIf=\"(skillIssuesByIndex()[si] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\">\r\n Missing info\r\n </span>\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Delete skill\"\r\n (click)=\"deleteSkill(si); $event.stopPropagation()\">\r\n <span class=\"fw-bold\">\u00D7</span>\r\n </button>\r\n </div>\r\n\r\n <span *ngIf=\"skills().length === 0\" class=\"text-muted small\">No skills added.</span>\r\n </div>\r\n <div *ngIf=\"isSkillEditorOpen()\" class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 9999999;\" (click)=\"closeSkillEditor()\">\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\"\r\n (click)=\"$event.stopPropagation()\">\r\n <div class=\"card shadow border-0 w-100\" style=\"max-width: 900px;\">\r\n <div class=\"card-header bg-white d-flex align-items-center gap-3\">\r\n <button type=\"button\" class=\"btn btn-link p-0 text-decoration-none\" (click)=\"closeSkillEditor()\">\r\n <img src=\"/assets/images/icons/arrow-left-blue.svg\" width=\"20\" height=\"20\" alt=\"\" />\r\n </button>\r\n <div class=\"fw-bold\">{{ isAddingSkill() ? 'Add Skill' : ('Edit ' + (skillForm()?.name || '') + ' Skill')\r\n }}</div>\r\n </div>\r\n <div class=\"card-body p-4\">\r\n <div *ngIf=\"skillFormIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ skillFormIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"row g-3\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Skills Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"skillForm()?.name\"\r\n (ngModelChange)=\"patchSkillForm({ name: $event })\" name=\"skillName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(skillForm()?.name)\">Skillset name is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span\r\n class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempSkillStars(s)\" [attr.aria-label]=\"'Set rating ' + s\">\r\n <span [class]=\"(skillForm()?.stars || 0) >= s ? 'text-warning fs-5' : 'text-muted fs-5'\">\r\n {{ (skillForm()?.stars || 0) >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ skillForm()?.stars || 0 }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"(skillForm()?.stars || 0) <= 0\">Star rating is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngModel]=\"skillForm()?.year\"\r\n (ngModelChange)=\"patchSkillForm({ year: $event === '' ? null : +$event })\" name=\"skillYear\" min=\"1\"\r\n max=\"30\" placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"skillForm()?.year === null || skillForm()?.year === undefined\">Years of experience is\r\n required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4 text-center\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-checks form-switch mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"skillForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchSkillForm({ profileVisibility: $event })\" name=\"skillVisible\"\r\n id=\"skillVisible\" style=\"width: 55px;height: 25px;margin-left: -57px;\" />\r\n <label class=\"form-check-label ps-2 pt-1\" for=\"skillVisible\">Visible</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Comment</label>\r\n <textarea rows=\"4\" class=\"form-control\" [ngModel]=\"skillForm()?.notes\"\r\n (ngModelChange)=\"patchSkillForm({ notes: $event })\" name=\"skillNotes\"\r\n placeholder=\"Comment your skill here...\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-white d-flex justify-content-end gap-2\">\r\n <button *ngIf=\"!isAddingSkill() && editingSkillIndex() !== null\" type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\" (click)=\"deleteSkill(editingSkillIndex()!)\">\r\n Delete\r\n </button>\r\n <button type=\"button\" class=\"btn btn-link text-secondary\" (click)=\"closeSkillEditor()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary px-4\" [disabled]=\"isSavingSkill\" (click)=\"saveSkillEditor()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Saving...' : skillActionLabel(editingSkillIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row g-4 mb-5\">\r\n <div class=\"col-md-12\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/mortarboard-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Education</h5>\r\n <span *ngIf=\"educationList().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"educationSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ educationSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"educationList().length === 0 || !educationSectionHasUnsavedItems() || isSavingEducation || isAddingEducation() || editingEducationIndex() !== null\"\r\n (click)=\"confirmAllEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add education\" (click)=\"addEducation()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"educationList().length === 0 && !isAddingEducation() && editingEducationIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addEducation()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/mortarboard.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No education added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div *ngIf=\"isAddingEducation() && tempEducation()\" class=\"mb-2\">\r\n <div class=\"form-panel\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\" name=\"newEduDegree\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Institution <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\" name=\"newEduInstitution\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree / Course Type <span class=\"text-danger\">*</span></label>\r\n <ng-select class=\"ng-select-sm\" [items]=\"educationDegreeTypeOptions\" [clearable]=\"false\"\r\n placeholder=\"Select degree / course type\" [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\" name=\"newEduDegreeType\">\r\n </ng-select>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.country\"\r\n (ngModelChange)=\"patchTempEducation({ country: $event })\" name=\"newEduCountry\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.state\"\r\n (ngModelChange)=\"patchTempEducation({ state: $event })\" name=\"newEduState\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\" name=\"newEduCity\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.startDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('startDate', $event)\" name=\"newEduStartDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.startDate)\">Start date is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.endDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('endDate', $event)\" name=\"newEduEndDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Education File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onEducationFileSelected($event)\" name=\"newEducationAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempEducation()?.fileName\">\r\n <span>{{ tempEducation()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempEducation())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingEducation\"\r\n (click)=\"saveEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Uploading...' : educationActionLabel(editingEducationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let edu of educationList(); let ei = index\" class=\"edu-accent-item p-3 bg-white border rounded-3 shadow-sm mb-2\">\r\n <div class=\"d-flex justify-content-between align-items-start\">\r\n <div class=\"d-flex align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h6 class=\"fw-bold mb-0 item-title-sm\">{{ edu.degree }}</h6>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedEducationItem(ei) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedEducationItem(ei) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ edu.institution || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.degreeType || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.startDate ? formatMonthYear(edu.startDate) : '\u2014' }} - {{ edu.endDate ? formatMonthYear(edu.endDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.city }}<span *ngIf=\"edu.city && edu.state\">, </span>{{ edu.state }}<ng-container *ngIf=\"!edu.city && !edu.state\">\u2014</ng-container></span>\r\n <div *ngIf=\"(educationIssuesByIndex()[ei] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (educationIssuesByIndex()[ei] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\" *ngIf=\"editingEducationIndex() !== ei\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditEducation(ei)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteEducation(ei)\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"editingEducationIndex() === ei\" class=\"mt-3\">\r\n <div *ngIf=\"(educationIssuesByIndex()[ei] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (educationIssuesByIndex()[ei] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\" name=\"eduDegree{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Institution <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\" name=\"eduInstitution{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.institution)\">Institution name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree / Course Type <span class=\"text-danger\">*</span></label>\r\n <ng-select class=\"ng-select-sm\" [items]=\"educationDegreeTypeOptions\" [clearable]=\"false\"\r\n placeholder=\"Select degree / course type\" [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\" name=\"eduDegreeType{{ ei }}\">\r\n </ng-select>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.country\"\r\n (ngModelChange)=\"patchTempEducation({ country: $event })\" name=\"eduCountry{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.state\"\r\n (ngModelChange)=\"patchTempEducation({ state: $event })\" name=\"eduState{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\" name=\"eduCity{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.startDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('startDate', $event)\" name=\"eduStartDate{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.startDate)\">Start date is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.endDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('endDate', $event)\" name=\"eduEndDate{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Education File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onEducationFileSelected($event)\" name=\"educationAttachment{{ ei }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempEducation()?.fileName\">\r\n <span>{{ tempEducation()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempEducation())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingEducation\" (click)=\"saveEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Uploading...' : educationActionLabel(editingEducationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n </div>\r\n <div class=\"d-flex gap-3 justify-content-center mt-5 pt-2\" *ngIf=\"!isResume\">\r\n <button class=\"btn btn-outline-secondary preview-back-btn px-5 h-auto\" style=\"border-radius: 5px !important;\" (click)=\"onBackClick()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"me-1\" style=\"vertical-align:-0.1em\">\r\n <path d=\"M11 3 5 8l6 5\" />\r\n </svg> Back\r\n </button>\r\n <button class=\"btn btn-primary preview-dashboard-btn px-5 h-auto\" style=\"border-radius: 5px !important;\" [disabled]=\"!canConfirmAndContinue() || isSavingBasic\"\r\n (click)=\"onGoToDashboardClick()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Saving...' : 'Go to Dashboard' }}\r\n <img *ngIf=\"!isSavingBasic\" src=\"/assets/images/icons/arrow-right-white.svg\" width=\"14\" height=\"14\" class=\"ms-1\" style=\"vertical-align:-0.1em\" alt=\"\" />\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<ng-template #loading>\r\n <div class=\"text-center p-5\">\r\n <div class=\"spinner-border text-primary\"></div>\r\n <p class=\"text-muted mt-2\">Loading data...</p>\r\n </div>\r\n</ng-template>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBulkSkillConfirm\">\r\n <div class=\"confirm-modal-card\" style=\"max-width: 480px;\">\r\n <h4 class=\"mb-1\">Set Rating for All Skills</h4>\r\n <p class=\"text-muted small mb-4\">Enter a star rating and years of experience to apply to all skills that are missing these values.</p>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"bulkSkillStars = s\">\r\n <span [class]=\"bulkSkillStars >= s ? 'text-warning fs-4' : 'text-muted fs-4'\">\r\n {{ bulkSkillStars >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ bulkSkillStars }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkSkillStars <= 0\">Star rating is required</div>\r\n </div>\r\n <div class=\"mb-4\">\r\n <label class=\"small text-muted d-block mb-1\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [(ngModel)]=\"bulkSkillYear\" min=\"1\" max=\"30\"\r\n placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkSkillYear === null || bulkSkillYear === undefined\">Years of experience is required</div>\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"cancelBulkSkillConfirm()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingSkill || bulkSkillStars <= 0 || bulkSkillYear === null\"\r\n (click)=\"applyBulkSkillConfirm()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Saving...' : 'Apply to All & Save' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBulkToolConfirm\">\r\n <div class=\"confirm-modal-card\" style=\"max-width: 480px;\">\r\n <h4 class=\"mb-1\">Set Rating for All Tools</h4>\r\n <p class=\"text-muted small mb-4\">Enter a star rating and years of experience to apply to all tools that are missing these values.</p>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"bulkToolStars = s\">\r\n <span [class]=\"bulkToolStars >= s ? 'text-warning fs-4' : 'text-muted fs-4'\">\r\n {{ bulkToolStars >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ bulkToolStars }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkToolStars <= 0\">Star rating is required</div>\r\n </div>\r\n <div class=\"mb-4\">\r\n <label class=\"small text-muted d-block mb-1\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [(ngModel)]=\"bulkToolYear\" min=\"1\" max=\"30\"\r\n placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkToolYear === null || bulkToolYear === undefined\">Years of experience is required</div>\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"cancelBulkToolConfirm()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingTool || bulkToolStars <= 0 || bulkToolYear === null\"\r\n (click)=\"applyBulkToolConfirm()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Saving...' : 'Apply to All & Save' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBackConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Leave this page?</h4>\r\n <p class=\"text-muted mb-4\">If you go back, only saved data will be retained.</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"stayOnPreview()\">Stay</button>\r\n <button type=\"button\" class=\"btn btn-danger h-auto\" (click)=\"proceedBack()\">Proceed Back</button>\r\n </div>\r\n </div>\r\n\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showDashboardConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Finish Setup and Continue</h4>\r\n <p class=\"text-muted mb-4\">Save your information and go to your dashboard</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" [disabled]=\"isSavingBasic\"\r\n (click)=\"cancelDashboardRedirect()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingBasic\" (click)=\"goToDashboard()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Proceeding...' : 'Proceed' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{color:#69707d}.res-flex:hover,.res-flex:focus,.res-flex:active{transform:none!important;box-shadow:none!important}.container{max-width:900px;margin:30px auto;font-family:Arial,sans-serif;color:#69707d}.preview-page-header{max-width:900px;margin:50px auto 10px;padding:0 12px}.preview-title{font-size:18px;font-weight:700;color:#69707d;margin:0}.preview-subtitle{margin-top:7px;font-size:14px;color:#69707d}.preview-card-gradient h2,.section h5.fw-bold{font-size:18px}.section{margin-bottom:25px}.section-title{font-weight:600;display:block;margin-bottom:8px}.section-title .sub{font-weight:400;color:#777;font-size:13px}.dropdown-box{border:1px solid #ddd;border-radius:8px;padding:12px 15px;display:flex;justify-content:space-between;align-items:center}.icons{display:flex;gap:10px}.icon{cursor:pointer;font-size:14px;color:#777}.card{border:1px solid #ddd;border-radius:5px;padding:20px;background:#fff}.category{border-bottom:1px solid #eee;padding:15px 0}.category:last-child{border-bottom:none}.category-header{display:flex;justify-content:space-between;font-weight:600;margin-bottom:10px}.tags{display:flex;flex-wrap:wrap;gap:10px}.tag{background:#f2f4f7;padding:6px 12px;border-radius:6px;font-size:13px}.footer{text-align:center;margin-top:15px;color:#777;cursor:pointer}.actions{display:flex;justify-content:space-between;margin:50px 0 27px}.text-secondary{white-space:pre-line;font-size:12px;color:#69707d}.extra-small{font-size:.8rem}.card{transition:transform .2s ease,box-shadow .2s ease}.card:hover{transform:translateY(-3px)}.achievement-section .badge{font-size:.75rem;white-space:normal;text-align:left}.skill-tag .badge{font-weight:500;font-size:.9rem;transition:all .2s ease;cursor:default}.skill-tag .badge:hover{transform:translateY(-2px)}.skill-tag .btn-close{opacity:.5}.skill-tag .btn-close:hover{opacity:1}.bg-light.text-dark.border{background-color:#f8f9fa!important;border-color:#dee2e6!important}.card{transition:all .3s cubic-bezier(.25,.8,.25,1)}.card:hover .bg-light{background-color:#e8f5e9!important}.position-fixed .card:hover{transform:none!important}code{background-color:#f8f9fa;padding:2px 6px;border-radius:4px}.list-group-item{transition:all .2s ease-in-out}.list-group-item:hover{background-color:#fcfcfc;transform:translate(5px)}.border-dashed{border-style:dashed!important}.tool-card{transition:all .2s ease-in-out;border-radius:12px}.tool-card:hover{transform:translateY(-5px);border-color:var(--bs-primary)!important}.tool-card:hover .icon-box{background-color:var(--bs-primary-subtle)!important}.tool-card .icon-box{width:60px;height:60px;transition:background-color .2s ease}.border-dashed{border:2px dashed #dee2e6!important}.border-dashed:hover{border-color:var(--bs-primary)!important;background-color:#fff!important}.popup{position:fixed;top:20%;right:20px;width:320px;max-width:calc(100vw - 32px);background:#fff;border-radius:10px;padding:16px}.status-row{display:flex;justify-content:space-between;margin:10px 0}.success{color:#2e7d32;font-weight:700}.error{color:#d32f2f}.pending{color:#f9a825}.section-flag{font-weight:600}button.btn.btn-sm.btn-outline-primary{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:5px!important}button.btn.btn-sm.btn-outline-primary:hover{background-color:#356895;border-color:#356895;color:#fff}button.btn.btn-sm.btn-outline-danger{border:1px solid #dc3545;color:#dc3545;border-radius:5px!important}button.btn.btn-sm.btn-outline-primary.rounded-circle{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:5px!important}button.action-icon-btn{min-width:22px;width:22px;height:22px;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:5px!important;background:transparent!important;border:none!important;line-height:1}button.action-icon-btn.btn-outline-primary{color:#4077ad!important;border-color:#4077ad!important}button.action-icon-btn.btn-outline-danger{color:#dc3545!important}.action-icon-image{width:20px;height:20px;object-fit:contain;display:inline-block}.action-icon-image.edit-icon{filter:brightness(0) saturate(100%) invert(41%) sepia(39%) saturate(774%) hue-rotate(170deg) brightness(91%) contrast(89%)}.action-icon-image.delete-icon{filter:brightness(0) saturate(100%) invert(24%) sepia(79%) saturate(4008%) hue-rotate(344deg) brightness(91%) contrast(90%)}.modal-overlay{position:fixed;inset:0;background:#11182773;display:flex;align-items:center;justify-content:center;z-index:2500;padding:20px}.status-modal-card{width:min(760px,96vw);max-height:85vh;overflow:auto;background:#fff;border-radius:16px;border:1px solid #e5e7eb}.status-modal-header{padding:20px 24px 14px;border-bottom:1px solid #eef2f7}.status-modal-body{padding:12px 20px 20px}.status-modal-footer{padding:12px 20px 20px;border-top:1px solid #eef2f7;display:flex;justify-content:end;align-items:center;gap:12px}.status-modal-row{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px 10px;border-bottom:1px solid #f1f5f9}.status-modal-row:last-child{border-bottom:0}.status-modal-name{font-size:14px;font-weight:600;color:#69707d}.status-modal-state{font-size:.92rem;font-weight:600}.status-modal-state.pending{color:#a16207}.status-modal-state.success{color:#166534}.status-modal-state.partial{color:#b45309}.status-modal-state.error{color:#b91c1c}.confirm-modal-card{width:min(520px,96vw);background:#fff;border-radius:5px;border:1px solid #e5e7eb;padding:24px}.year-experience-select{max-height:150px}@media screen and (max-width: 768px){.res-flex{flex-wrap:wrap!important;justify-content:center!important}.res-flex .fw-normal{width:100%;text-align:center;font-size:14px!important}.d-flex.flex-wrap.gap-2.p-3.bg-white.border.rounded.shadow-sm{justify-content:center}.preview-page-header{margin:20px auto 8px;padding:0 4px}.container{padding-left:4px;padding-right:4px}.preview-title{font-size:16px}.preview-subtitle{font-size:14px}.actions{margin:24px 0 16px}.section-header-title{flex-wrap:wrap}.section-header-title>.section-flag{flex-basis:53%}.section-header-row{align-items:flex-start}.preview-card-gradient{padding:14px 14px 12px}.preview-card-gradient h2{font-size:18px}.popup{width:calc(100vw - 40px);right:16px;top:12%}.card{padding:0}.card-body.p-4,.px-4.py-3{padding:12px!important}.row.g-4,.row.g-3{--bs-gutter-x: .75rem}.d-flex.gap-4{gap:10px!important}.preview-card-gradient>.d-flex.justify-content-between.align-items-start{flex-wrap:wrap;row-gap:8px}.preview-card-gradient>.d-flex.justify-content-between.align-items-start>.badge.bg-primary-subtle{margin-left:auto}}@media screen and (max-width: 575px){.preview-title{font-size:16px}.preview-subtitle{font-size:14px}.section>.d-flex{flex-wrap:wrap;row-gap:8px}.section>.d-flex>.d-flex:last-child{width:100%;justify-content:flex-end}}::ng-deep .bs-datepicker-head{background-color:#4077ad!important}::ng-deep .bs-datepicker-body table td span.selected,.bs-datepicker-body table td.selected span{background-color:#4077ad!important}.profile-avatar-circle{width:58px;height:58px;border-radius:5px;background:#4077ad;display:flex;align-items:center;justify-content:center;font-size:22px;font-weight:700;color:#fff;letter-spacing:1px;flex-shrink:0}.section-header-icon{font-size:20px;line-height:1;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;opacity:.9;filter:invert(47%) sepia(8%) saturate(483%) hue-rotate(176deg) brightness(91%) contrast(87%)}.section-header-title h5.fw-bold{color:#69707d}.text-muted{color:#69707d!important}h6.text-uppercase.fw-bold.text-muted{font-size:14px;color:#69707d!important}.work-accent-item{border-left:4px solid #4077ad!important;border-radius:0 5px 5px 0!important;transition:background-color .18s ease,box-shadow .18s ease}.work-accent-item:hover{background-color:#f5f8ff!important;box-shadow:0 4px 14px #4077ad17!important}.edu-accent-item{border-left:4px solid #4077AD!important;border-radius:0 5px 5px 0!important;transition:background-color .18s ease,box-shadow .18s ease}.edu-accent-item:hover{background-color:#f8f8ff!important;box-shadow:0 4px 14px #6366f117!important}.cert-accent-item{border-left:4px solid #059669!important;border-radius:0 5px 5px 0!important;transition:background-color .18s ease}.cert-accent-item:hover{background-color:#f0fdf4!important}.lic-accent-item{border-left:4px solid #d97706!important;border-radius:0 5px 5px 0!important;transition:background-color .18s ease}.lic-accent-item:hover{background-color:#fffbeb!important}.field-label-sm{font-size:14px;font-weight:700;letter-spacing:.08em;color:#69707d;margin-bottom:3px;display:block}.item-name-text{color:#69707d}.field-value-sm{font-weight:600;font-size:12px;color:#69707d}.item-title-sm{font-size:14px;color:#69707d!important}.item-meta-line{display:block;font-size:12px;color:#69707d;margin-top:3px}.empty-state-wrap{text-align:center;padding:32px 20px;background:#fafbfc;border:1.5px dashed #d1d5db;border-radius:5px;cursor:pointer;transition:background-color .18s ease,border-color .18s ease}.empty-state-wrap .empty-icon{font-size:2rem;color:#d1d5db;margin-bottom:8px}.empty-state-wrap p{color:#9ca3af;margin:0;font-size:14px}.empty-state-wrap:hover{background:#f0f6ff;border-color:#4077ad}.form-panel{background:#fff;border:1px solid #e2e8f0;border-radius:5px;padding:20px}.form-panel .form-control,.form-panel .form-select{border-color:#d1d5db;border-radius:8px;font-size:12px}.form-panel .form-control:focus,.form-panel .form-select:focus{border-color:#4077ad;box-shadow:0 0 0 3px #4077ad1f}.section-header-bar{display:flex;align-items:center;justify-content:space-between;padding:10px 0 14px;border-bottom:2px solid #f1f5f9;margin-bottom:16px}.preview-card-gradient{background:linear-gradient(135deg,#fff,#eff6ff);border-bottom:1px solid #e2e8f0;padding:20px 24px 16px;border-radius:5px 5px 0 0}.item-icon-circle{width:40px;height:40px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:700;color:#fff;flex-shrink:0}.item-avatar--work{background:linear-gradient(135deg,#4077ad,#2d5a8a)}.item-avatar--edu{background:linear-gradient(135deg,#4077ad,#4338ca)}.provider-layout{display:flex;flex-direction:column}.provider-company-first{order:-1}.section-locked{pointer-events:none;opacity:.45;filter:blur(1.5px);-webkit-user-select:none;user-select:none}.btn.btn-primary{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-primary:hover:not(:disabled),.btn.btn-primary:focus:not(:disabled),.btn.btn-primary:active:not(:disabled){background-color:#356895!important;border-color:#356895!important;color:#fff!important}.btn.btn-success,.btn.btn-outline-success{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-success:hover:not(:disabled),.btn.btn-success:focus:not(:disabled),.btn.btn-success:active:not(:disabled),.btn.btn-outline-success:hover:not(:disabled),.btn.btn-outline-success:focus:not(:disabled),.btn.btn-outline-success:active:not(:disabled){background-color:#336843!important;border-color:#336843!important;color:#fff!important}.btn.btn-outline-secondary.rounded-pill{background-color:#69707d!important;border-color:#69707d!important;color:#fff!important;border-radius:5px!important}.btn.btn-outline-secondary.rounded-pill:hover:not(:disabled),.btn.btn-outline-secondary.rounded-pill:focus:not(:disabled),.btn.btn-outline-secondary.rounded-pill:active:not(:disabled){background-color:#565c66!important;border-color:#565c66!important;color:#fff!important}.preview-back-btn{background-color:#426c85!important;border-color:#426c85!important;color:#fff!important}.preview-dashboard-btn{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-outline-success:hover:not(:disabled),.btn.btn-outline-success:focus:not(:disabled),.btn.btn-outline-success:active:not(:disabled){background-color:transparent!important;border-color:#198754!important;color:#198754!important}.btn.btn-outline-secondary:not(.rounded-pill){background-color:#d4dae6!important;border-color:#d4dae6!important;color:#69707d!important}.btn.btn-outline-secondary:not(.rounded-pill):hover:not(:disabled),.btn.btn-outline-secondary:not(.rounded-pill):focus:not(:disabled),.btn.btn-outline-secondary:not(.rounded-pill):active:not(:disabled){background-color:#c2cbde!important;border-color:#c2cbde!important;color:#69707d!important}.btn.btn-danger{background-color:#b43026!important;border-color:#b43026!important;color:#fff!important}.btn.btn-danger:hover:not(:disabled),.btn.btn-danger:focus:not(:disabled),.btn.btn-danger:active:not(:disabled){background-color:#96271f!important;border-color:#96271f!important;color:#fff!important}.btn.btn-outline-danger.rounded-circle{border-color:#b43026!important;color:#b43026!important;border-radius:5px!important}.btn.btn-outline-danger.rounded-circle:hover:not(:disabled),.btn.btn-outline-danger.rounded-circle:focus:not(:disabled),.btn.btn-outline-danger.rounded-circle:active:not(:disabled){border-color:#96271f!important;color:#b43026!important}.btn.btn-link.text-secondary{background-color:#d4dae6!important;border-color:#d4dae6!important;color:#69707d!important;text-decoration:none!important;border-radius:5px}.btn.btn-link.text-secondary:hover:not(:disabled),.btn.btn-link.text-secondary:focus:not(:disabled){background-color:#c2cbde!important;color:#69707d!important}.btn.btn-link.text-danger{background-color:#b43026!important;border-color:#b43026!important;color:#fff!important;text-decoration:none!important;border-radius:5px}.btn.btn-link.text-danger:hover:not(:disabled),.btn.btn-link.text-danger:focus:not(:disabled){background-color:#96271f!important;color:#fff!important}.btn{border-radius:5px!important;box-shadow:none!important}.badge.bg-warning-subtle.text-warning{background-color:#fff3cd!important;color:#664d03!important;border-color:#ffe69c!important}.badge.bg-success-subtle.text-success{background-color:#4077ad!important;color:#fff!important;border-color:#4077ad!important}.badge.bg-primary-subtle.text-primary{background-color:#e0edf2!important;color:#4077ad!important;border-color:#e0edf2!important}\n"] }]
|
|
6385
|
-
}], ctorParameters: () => [{ type: CredentialingStore }, { type: FileService }, { type: UserSkillSetService }, { type: UserToolService }, { type: UserDocumentService }, { type: UserEducationService }, { type: UserDetailService }, { type: UserExperienceService }, { type: i1$4.TokenService }, { type: i1$4.RoleContextService }, { type: ProvidersService }, { type: FrontEndProvidersService }, { type: undefined, decorators: [{
|
|
6431
|
+
], template: "<div class=\"preview-page-header\" *ngIf=\"!isResume\">\r\n <div class=\"d-flex align-items-center gap-2 mb-1\">\r\n <h2 class=\"preview-title mb-0\">Review Extracted Information</h2>\r\n </div>\r\n <p class=\"preview-subtitle text-muted\">We\u2019ve automatically extracted details from your uploaded resume. Please review and confirm accuracy before proceeding.</p>\r\n</div>\r\n\r\n\r\n<div [ngClass]=\"isResume ? '' : 'container py-4'\" [class.provider-layout]=\"roleData?.role?.name === 'Provider'\">\r\n\r\n <!-- Provider initial setup: combined company + personal form (shown until both APIs succeed) -->\r\n <div class=\"section mb-5\" *ngIf=\"roleData?.role?.name === 'Provider' && !hasUserDetailData\">\r\n <div class=\"d-flex align-items-center gap-2 mb-3 section-header-title\">\r\n <img src=\"/assets/images/icons/building.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Company & Personal Details</h5>\r\n <span class=\"badge border section-flag bg-warning-subtle text-warning\">Required to continue</span>\r\n </div>\r\n <div class=\"card shadow-sm border-0\">\r\n <div class=\"card-header bg-white fw-semibold\">Company Information</div>\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-3\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': (!tempCompanyDetails.companyName?.trim() && companyFormSubmitted) || companyNameError}\"\r\n [(ngModel)]=\"tempCompanyDetails.companyName\" name=\"setupCompanyName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyName?.trim() && companyFormSubmitted\">Company name is required</div>\r\n <div class=\"invalid-feedback\" *ngIf=\"companyNameError\">{{ companyNameError }}</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" maxlength=\"14\" inputmode=\"numeric\"\r\n (input)=\"phoneMask($event, 'company')\" (keypress)=\"allowOnlyNumbers($event)\"\r\n [ngClass]=\"{'is-invalid': companyFormSubmitted && (!tempCompanyDetails.companyPhoneNumber?.trim() || getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10)}\"\r\n [(ngModel)]=\"tempCompanyDetails.companyPhoneNumber\" name=\"setupCompanyPhone\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted\">Company phone is required</div>\r\n <div class=\"invalid-feedback\" *ngIf=\"tempCompanyDetails.companyPhoneNumber?.trim() && getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10 && companyFormSubmitted\">Company phone must be 10 digits</div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Company Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempCompanyDetails.address1\" name=\"setupCompanyAddress\"\r\n [options]=\"options\" inputClass=\"form-control form-control-sm\"\r\n [invalid]=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\">Address is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.city?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.city\" name=\"setupCompanyCity\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.city?.trim() && companyFormSubmitted\">City is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.state?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.state\" name=\"setupCompanyState\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.state?.trim() && companyFormSubmitted\">State is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.zipcode?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.zipcode\" name=\"setupCompanyZip\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.zipcode?.trim() && companyFormSubmitted\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.country?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.country\" name=\"setupCompanyCountry\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.country?.trim() && companyFormSubmitted\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <input type=\"file\" accept=\".png,.jpg,.jpeg\" class=\"form-control form-control-sm\" (change)=\"uploadCompanyImage($event)\" name=\"setupCompanyLogo\" />\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"tempCompanyLogoUrl\">\r\n <label class=\"small text-muted d-block\">Logo Preview</label>\r\n <img [src]=\"tempCompanyLogoUrl\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-header bg-white fw-semibold border-top\">Personal Information</div>\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-3\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">First Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.firstName?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.firstName\" name=\"setupFirstName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.firstName?.trim() && companyFormSubmitted\">First name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.lastName?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.lastName\" name=\"setupLastName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.lastName?.trim() && companyFormSubmitted\">Last name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Email <span class=\"text-danger\">*</span></label>\r\n <input type=\"email\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.email?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.email\" name=\"setupEmail\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.email?.trim() && companyFormSubmitted\">Email is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Phone Number <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" maxlength=\"14\" inputmode=\"numeric\"\r\n (input)=\"phoneMask($event, 'profile')\" (keypress)=\"allowOnlyNumbers($event)\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.phone?.trim() && companyFormSubmitted}\"\r\n [ngModel]=\"tempProfile?.phone\" name=\"setupPhone\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.phone?.trim() && companyFormSubmitted\">Phone number is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempProfile.address\" name=\"setupAddress\" [options]=\"options\"\r\n inputClass=\"form-control form-control-sm\" [invalid]=\"!tempProfile?.address?.trim() && companyFormSubmitted\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.address?.trim() && companyFormSubmitted\">Home address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.city?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.city\" name=\"setupUserCity\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.city?.trim() && companyFormSubmitted\">City is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.state?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.state\" name=\"setupUserState\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.state?.trim() && companyFormSubmitted\">State is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.zipCode?.trim() && companyFormSubmitted}\"\r\n [ngModel]=\"tempProfile?.zipCode\" (ngModelChange)=\"tempProfile.zipCode = sanitizeZipCode($event)\"\r\n name=\"setupUserZip\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.zipCode?.trim() && companyFormSubmitted\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.country?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.country\" name=\"setupUserCountry\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.country?.trim() && companyFormSubmitted\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [(ngModel)]=\"tempProfile.jobTitle\" name=\"setupJobTitle\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control form-control-sm\" [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n [ngClass]=\"{'is-invalid': !(tempProfile?.yearsOfExperience > 0) && companyFormSubmitted}\"\r\n name=\"setupYearsOfExp\" min=\"1\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!(tempProfile?.yearsOfExperience > 0) && companyFormSubmitted\">Years of experience is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Profile Picture</label>\r\n <input #setupHeadshotFile type=\"file\" accept=\".png,.jpg,.jpeg\" class=\"d-none\" (change)=\"uploadHeadshotImage($event)\" name=\"setupHeadshotFile\" />\r\n <div class=\"position-relative\">\r\n <input type=\"text\" class=\"form-control form-control-sm pe-5\" [value]=\"headshotFileName\" readonly\r\n placeholder=\"Upload Profile Picture\" (click)=\"setupHeadshotFile.click()\" />\r\n <img *ngIf=\"!isHeadshotLoading\" src=\"assets/images/icons/upload.svg\" alt=\"Upload\" class=\"upload-icon\" style=\"position:absolute;right:12px;top:50%;transform:translateY(-50%);cursor:pointer;width:18px;\" (click)=\"setupHeadshotFile.click()\" />\r\n <div *ngIf=\"isHeadshotLoading\" style=\"position:absolute;right:12px;top:50%;transform:translateY(-50%);\">\r\n <span class=\"spinner-border spinner-border-sm text-primary\"></span>\r\n </div>\r\n </div>\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"headshotPreviewUrl\">\r\n <label class=\"small text-muted d-block\">Preview</label>\r\n <img [src]=\"cloudfrontUrl + headshotPreviewUrl\" class=\"img-thumbnail rounded-circle\" style=\"width:64px;height:64px;object-fit:cover;\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-footer d-flex align-items-center justify-content-end gap-2\">\r\n <span *ngIf=\"providerSetupError\" class=\"small text-danger me-auto\">{{ providerSetupError }}</span>\r\n <button class=\"btn btn-success px-5 \"\r\n [disabled]=\"isSavingProviderSetup || !isProviderSetupFormComplete\"\r\n (click)=\"saveProviderSetup()\">\r\n <span *ngIf=\"isSavingProviderSetup\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingProviderSetup ? 'Saving...' : 'Save & Continue' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\" *ngIf=\"roleData?.role?.name !== 'Provider' || hasUserDetailData\">\r\n <div *ngIf=\"details() as data; else loading\">\r\n <div class=\"card shadow-sm border-0 rounded-3 overflow-hidden\" *ngIf=\"!isEditMode()\">\r\n <div class=\"card-body p-0\">\r\n <div class=\"preview-card-gradient\">\r\n <div class=\"d-flex justify-content-between align-items-start mb-4\">\r\n <div class=\"d-flex align-items-start gap-3\">\r\n <div class=\"profile-avatar-circle\" *ngIf=\"!headshotPreviewUrl\">\r\n {{ (data.firstName?.[0] || '') }}{{ (data.lastName?.[0] || '') }}\r\n </div>\r\n <img *ngIf=\"headshotPreviewUrl\" [src]=\" cloudfrontUrl + headshotPreviewUrl\"\r\n class=\"rounded-circle\" style=\"width:56px;height:56px;object-fit:cover;\" alt=\"Profile\" />\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h2 class=\"fw-bold mb-1\">{{ data.firstName }} {{ data.lastName }}</h2>\r\n <span *ngIf=\"basicSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n <span class=\"badge border section-flag\"\r\n [ngClass]=\"basicDetailsSaved ? 'bg-success-subtle text-success' : 'bg-warning-subtle text-warning'\">\r\n {{ basicDetailsSaved ? 'Saved' : 'Not saved yet' }}\r\n </span>\r\n </div>\r\n <p class=\"text-muted\">{{ data.jobTitle }} \u2022 {{ data.yearsOfExperience }} Years Exp.</p>\r\n <div *ngIf=\"basicIssues().length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ basicIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <span class=\"badge bg-primary-subtle text-primary border p-2\">Email Verified</span>\r\n </div>\r\n\r\n </div>\r\n <div class=\"px-4 py-3\">\r\n <div class=\"row g-4\">\r\n <div class=\"col-12 border-bottom pb-2\">\r\n <h6 class=\"text-uppercase small fw-bold text-muted\">Summary</h6>\r\n <p class=\"text-secondary small mb-0\">{{ data.summary }}</p>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/envelope.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Email</span>\r\n <span class=\"field-value-sm d-block\">{{ data.email }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/telephone.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Phone</span>\r\n <span class=\"field-value-sm d-block\">{{ data.phone }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/geo-alt.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Location</span>\r\n <span class=\"field-value-sm d-block\">{{ data.address }}, {{ data.city }}, {{ data.state }}, {{ data.zipCode }}, {{ data.country }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer d-flex align-items-center justify-content-between\">\r\n <span *ngIf=\"!basicDetailsSaved\" class=\"small text-warning fw-semibold\">\r\n <img src=\"/assets/images/icons/exclamation-circle.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" /> Click \"Edit\" to review and save your basic info.\r\n </span>\r\n <span *ngIf=\"basicDetailsSaved\" class=\"small text-success fw-semibold\">\r\n <img src=\"/assets/images/icons/check-circle.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" /> Basic details saved.\r\n </span>\r\n <button class=\"btn btn-sm btn-primary px-4 ms-auto\" (click)=\"toggleEdit()\">Edit</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"isEditMode()\">\r\n <div class=\"card-header bg-white fw-bold\">Update Profile</div>\r\n <div class=\"card-body p-4\">\r\n <form class=\"row g-3\" #basicForm=\"ngForm\" novalidate>\r\n <div *ngIf=\"basicIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ basicIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">First Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.firstName\" name=\"fName\"\r\n placeholder=\"First Name\" required #fName=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"fName.invalid && (fName.dirty || fName.touched)\">First name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.lastName\" name=\"lName\"\r\n placeholder=\"Last Name\" required #lName=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"lName.invalid && (lName.dirty || lName.touched)\">Last name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Email <span class=\"text-danger\">*</span></label>\r\n <input type=\"email\" class=\"form-control\" [(ngModel)]=\"tempProfile.email\" name=\"email\" placeholder=\"Email\"\r\n required email #email=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"email.invalid && (email.dirty || email.touched)\">\r\n <span *ngIf=\"email.errors?.['required']\">Email is required</span>\r\n <span *ngIf=\"email.errors?.['email']\">Email format is invalid</span>\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Phone Number <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"tempProfile.phone\" (input)=\"phoneMask($event, 'profile')\"\r\n name=\"phone\" placeholder=\"Phone (10 digits)\" (keypress)=\"allowOnlyNumbers($event)\"\r\n required pattern=\"^\\(\\d{3}\\) \\d{3}-\\d{4}$\" maxlength=\"14\" inputmode=\"numeric\" #phone=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"phone.invalid && (phone.dirty || phone.touched)\">\r\n <span *ngIf=\"phone.errors?.['required']\">Phone number is required</span>\r\n <span *ngIf=\"phone.errors?.['pattern']\">Phone number must be 10 digits</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\"></span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.jobTitle\" name=\"jobTitle\"\r\n placeholder=\"Job Title\" #jobTitle=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"jobTitle.invalid && (jobTitle.dirty || jobTitle.touched)\">Job\r\n title is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngClass]=\"{'is-invalid': !(tempProfile?.yearsOfExperience > 0)}\"\r\n [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n name=\"yearsOfExperience\" placeholder=\"Years of Experience\" required min=\"1\"\r\n #yearsOfExperience=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!(tempProfile?.yearsOfExperience > 0)\">\r\n Years of experience is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempProfile.address\" name=\"address\" [options]=\"options\"\r\n placeholder=\"Home Address\" required #address=\"ngModel\"\r\n [invalid]=\"address.invalid && (address.dirty || address.touched)\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"></im-address-verify-field>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"address.invalid && (address.dirty || address.touched)\">Home\r\n address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.city\" name=\"city\" placeholder=\"City\"\r\n required #city=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"city.invalid && (city.dirty || city.touched)\">City is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.state\" name=\"state\" placeholder=\"State\"\r\n required #state=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"state.invalid && (state.dirty || state.touched)\">State is\r\n required</div>\r\n </div>\r\n\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"tempProfile.zipCode\"\r\n (ngModelChange)=\"tempProfile.zipCode = sanitizeZipCode($event)\" name=\"zipCode\" placeholder=\"Zip Code\"\r\n required pattern=\"^\\d{1,6}$\" maxlength=\"6\" inputmode=\"numeric\" #zipCode=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"zipCode.invalid && (zipCode.dirty || zipCode.touched)\">Zip code\r\n is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"zipCode.errors?.['pattern'] && (zipCode.dirty || zipCode.touched)\">\r\n Zip code must be up to 6 digits\r\n </div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.country\" name=\"country\"\r\n placeholder=\"Country\" required #country=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"country.invalid && (country.dirty || country.touched)\">Country\r\n is required</div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Summary</label>\r\n <textarea class=\"form-control\" rows=\"3\" [(ngModel)]=\"tempProfile.summary\" name=\"sum\"\r\n placeholder=\"Summary\"></textarea>\r\n </div>\r\n\r\n\r\n </form>\r\n </div>\r\n <div class=\"card-footer text-end gap-2 d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancel()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingBasic || !isBasicFormValid\" (click)=\"save()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Saving...' : 'Save Changes' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5 provider-company-first\" *ngIf=\"roleData?.role?.name === 'Provider' && hasUserDetailData && !providerIdFallbackUsed()\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/building.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Company Details</h5>\r\n <span *ngIf=\"companyDetailsSaved\"\r\n class=\"badge border section-flag bg-success-subtle text-success\">\r\n Saved\r\n </span>\r\n <span *ngIf=\"!companyDetailsSaved\"\r\n class=\"badge border section-flag bg-warning-subtle text-warning\">\r\n Not saved yet\r\n </span>\r\n </div>\r\n <button class=\"btn btn-sm btn-primary px-4\" (click)=\"toggleCompanyEdit()\">Edit</button>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"!isCompanyEditMode()\">\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-4\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name</label>\r\n <span class=\"fw-bold small\">{{ companyDetails()?.companyName}}</span>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone</label>\r\n <span class=\"fw-bold small\">{{ companyDetails()?.companyPhoneNumber}}</span>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Company Address</label>\r\n <span class=\"small\">{{ companyDetails()?.address1}}, {{ companyDetails()?.city}}, {{ companyDetails()?.state}}, {{ companyDetails()?.zipcode}}, {{ companyDetails()?.country}}</span>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"companyLogoUrl()\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <img [src]=\"companyLogoUrl()\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"isCompanyEditMode()\">\r\n <div class=\"card-header bg-white fw-bold\">Update Company Details</div>\r\n <div class=\"card-body p-4\">\r\n <form class=\"row g-3\" #companyForm=\"ngForm\" novalidate>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': (!tempCompanyDetails.companyName?.trim() && companyFormSubmitted) || companyNameError }\"\r\n [(ngModel)]=\"tempCompanyDetails.companyName\" name=\"companyName\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyName?.trim() && companyFormSubmitted\">\r\n Company name is required\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"companyNameError\">\r\n {{ companyNameError }}\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone <span class=\"text-danger\">*</span></label>\r\n <input (input)=\"phoneMask($event, 'company')\" type=\"text\" maxlength=\"14\" (keypress)=\"allowOnlyNumbers($event)\" inputmode=\"numeric\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{ 'is-invalid': companyFormSubmitted && (!tempCompanyDetails.companyPhoneNumber?.trim() || getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10) }\"\r\n [(ngModel)]=\"tempCompanyDetails.companyPhoneNumber\" name=\"companyPhoneNumber\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted\">\r\n Company phone is required\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"tempCompanyDetails.companyPhoneNumber?.trim() && getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10 && companyFormSubmitted\">\r\n Company phone must be 10 digits\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempCompanyDetails.address1\" name=\"address1\" [options]=\"options\"\r\n required [invalid]=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\">\r\n Address is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.city?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.city\" name=\"city\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.city?.trim() && companyFormSubmitted\">\r\n City is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.state?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.state\" name=\"state\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.state?.trim() && companyFormSubmitted\">\r\n State is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.zipcode?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.zipcode\" name=\"zipcode\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.zipcode?.trim() && companyFormSubmitted\">\r\n Zip code is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.country?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.country\" name=\"country\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.country?.trim() && companyFormSubmitted\">\r\n Country is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <input #uploadCompanyFile type=\"file\" accept=\".png,.jpg,.jpeg\" (change)=\"uploadCompanyImage($event)\" class=\"form-control\" />\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"tempCompanyLogoUrl\">\r\n <label class=\"small text-muted d-block\">Logo Preview</label>\r\n <img [src]=\"tempCompanyLogoUrl\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </form>\r\n </div>\r\n <div class=\"card-footer text-end gap-2 d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelCompanyEdit()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCompany\" \r\n (click)=\"saveCompanyDetails()\">\r\n <span *ngIf=\"isSavingCompany\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCompany ? 'Saving...' : 'Save Changes' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div [class.section-locked]=\"roleData?.role?.name === 'Provider' && !hasUserDetailData\">\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/briefcase-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Work Experience</h5>\r\n <span *ngIf=\"experience().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"workSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ workSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"experience().length === 0 || !workSectionHasUnsavedItems() || isSavingWork || isAddingJob() || editingJobIndex() !== null\"\r\n (click)=\"confirmAllWork()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add work experience\" (click)=\"addJob()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"experience().length === 0 && !isAddingJob()\" class=\"empty-state-wrap mb-3\" role=\"button\"\r\n (click)=\"addJob()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/briefcase.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No work experience added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3\">\r\n <div *ngIf=\"isAddingJob() && tempJob()\" class=\"list-group-item p-0 border-0\">\r\n <div class=\"form-panel mb-2\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\" name=\"newJobTitle\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\" name=\"newCompany\" />\r\n </div>\r\n <div class=\"align-items-end col-md-12 d-flex justify-content-end pe-3\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\" name=\"newIsCurrent\" id=\"newIsCurrent\" />\r\n <label class=\"form-check-label\" for=\"newIsCurrent\">Current</label>\r\n </div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.country\"\r\n (ngModelChange)=\"patchTempJob({ country: $event })\" name=\"newCountry\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.state\"\r\n (ngModelChange)=\"patchTempJob({ state: $event })\" name=\"newState\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\" name=\"newCity\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempJob()?.startDate)\"\r\n (bsValueChange)=\"setTempJobMonth('startDate', $event)\" name=\"newStartDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.startDate)\">Start date is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"monthInputToDate(tempJob()?.endDate)\" (bsValueChange)=\"setTempJobMonth('endDate', $event)\"\r\n name=\"newEndDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">End date is\r\n required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isMonthRangeInvalid(tempJob()?.startDate, tempJob()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Responsibilities (one per line)</label>\r\n <textarea rows=\"4\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\" name=\"newResponsibilities\"></textarea>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\" name=\"newWorkAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempJob()?.fileName\">\r\n <span>{{ tempJob()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempJob())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n <div class=\"d-flex justify-content-end gap-2 mt-3\">\r\n <button class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingWork\"\r\n (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : workActionLabel(editingJobIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n\r\n <div *ngFor=\"let job of experience(); let i = index\" class=\"list-group-item p-0 border-0 mb-2\">\r\n\r\n <div class=\"work-accent-item p-3 rounded-3 bg-white border\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div class=\"d-flex align-items-center cursor-pointer flex-grow-1\" (click)=\"toggleJob(i)\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h6 class=\"mb-0 fw-bold item-title-sm\">{{ job.jobTitle }}</h6>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedWorkItem(i) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedWorkItem(i) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ job.company || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ formatMonthYear(job.startDate) }} - {{ job.isCurrent ? 'Present' :\r\n formatMonthYear(job.endDate) }}</span>\r\n <span class=\"item-meta-line\">{{ job.city }}<span *ngIf=\"job.city && job.state\">, </span>{{ job.state }}<ng-container *ngIf=\"!job.city && !job.state\">\u2014</ng-container></span>\r\n <div *ngIf=\"editingJobIndex() !== i && (workIssuesByIndex()[i] || []).length > 0\"\r\n class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (workIssuesByIndex()[i] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center gap-2\">\r\n\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\" (click)=\"startEditJob(i)\"\r\n title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteJob(i);\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n \r\n </div>\r\n </div>\r\n\r\n\r\n\r\n <div class=\"mt-3 p-3 rounded small\" *ngIf=\"expandedIndex() === i\">\r\n <ng-container *ngIf=\"editingJobIndex() !== i; else editJobForm\">\r\n <ul class=\"mb-0\">\r\n <li *ngFor=\"let res of job.responsibilities\">{{ res }}</li>\r\n </ul>\r\n </ng-container>\r\n\r\n <ng-template #editJobForm>\r\n <div *ngIf=\"(workIssuesByIndex()[i] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (workIssuesByIndex()[i] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\" name=\"jobTitle{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.jobTitle)\">Job title is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\" name=\"company{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.company)\">Company name is required</div>\r\n </div>\r\n\r\n <div class=\"align-items-end col-md-12 d-flex justify-content-end pe-3\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\" name=\"isCurrent{{ i }}\" id=\"isCurrent{{ i }}\" />\r\n <label class=\"form-check-label\" for=\"isCurrent{{ i }}\">Current</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.country\"\r\n (ngModelChange)=\"patchTempJob({ country: $event })\" name=\"country{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.state\"\r\n (ngModelChange)=\"patchTempJob({ state: $event })\" name=\"state{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\" name=\"city{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.city)\">City is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempJob()?.startDate)\"\r\n (bsValueChange)=\"setTempJobMonth('startDate', $event)\" name=\"startDate{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.startDate)\">Start date is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"monthInputToDate(tempJob()?.endDate)\" (bsValueChange)=\"setTempJobMonth('endDate', $event)\"\r\n name=\"endDate{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">\r\n End date is required\r\n </div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isMonthRangeInvalid(tempJob()?.startDate, tempJob()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Responsibilities (one per line)</label>\r\n <textarea rows=\"4\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\" name=\"responsibilities{{ i }}\"></textarea>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\" name=\"workAttachment{{ i }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempJob()?.fileName\">\r\n <span>{{ tempJob()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempJob())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n </ng-template>\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-3\" *ngIf=\"editingJobIndex() === i\">\r\n <button class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4 \" [disabled]=\"isSavingWork\"\r\n (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : workActionLabel(editingJobIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/patch-check-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Certifications</h5>\r\n <span *ngIf=\"certs().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"certificationSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ certificationSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"certs().length === 0 || !certificationSectionHasUnsavedItems() || isSavingCertification || isAddingCertification() || editingCertificationIndex() !== null\"\r\n (click)=\"confirmAllCertifications()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add certification\" (click)=\"addCertification()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"certs().length === 0 && !isAddingCertification() && editingCertificationIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addCertification()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/patch-check.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No certifications added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3 border\">\r\n <div *ngIf=\"isAddingCertification() && tempCertification()\" class=\"list-group-item py-3 px-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\" name=\"newCertName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\" name=\"newCertOrg\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\" name=\"newCertState\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certification Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\" name=\"newCertCredentialId\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('issueDate', $event)\" name=\"newCertIssueDate\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('expiryDate', $event)\" name=\"newCertExpiryDate\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempCertification()?.issueDate || null, tempCertification()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\" name=\"newCertAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempCertification()?.fileName\">\r\n <span>{{ tempCertification()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempCertification())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\"\r\n (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : certificationActionLabel(editingCertificationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let cert of certs(); let ci = index\" class=\"list-group-item py-3 cert-accent-item\">\r\n <ng-container *ngIf=\"editingCertificationIndex() !== ci; else editCert\">\r\n <div class=\"d-flex justify-content-between align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <div class=\"fw-semibold item-title-sm\">{{ cert.name }}</div>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedCertificationItem(ci) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedCertificationItem(ci) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ cert.issuingOrganization || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.credentialId || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.issueDate ? formatMonthYear(cert.issueDate) : '\u2014' }} - {{ cert.expiryDate ? formatMonthYear(cert.expiryDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.state || '\u2014' }}</span>\r\n <div *ngIf=\"(certIssuesByIndex()[ci] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (certIssuesByIndex()[ci] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditCertification(ci)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteCertification(ci)\" title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #editCert>\r\n <div *ngIf=\"(certIssuesByIndex()[ci] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (certIssuesByIndex()[ci] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\" name=\"certName{{ ci }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\"\r\n name=\"certOrg{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\" name=\"certState{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certification Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\"\r\n name=\"certCredentialId{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('issueDate', $event)\" name=\"certIssue{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('expiryDate', $event)\" name=\"certExpiry{{ ci }}\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempCertification()?.issueDate || null, tempCertification()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\" name=\"certAttachment{{ ci }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempCertification()?.fileName\">\r\n <span>{{ tempCertification()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempCertification())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\"\r\n (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : certificationActionLabel(editingCertificationIndex()) }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/card-checklist-warning.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Licenses</h5>\r\n <span *ngIf=\"licenses().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"licenseSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ licenseSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"licenses().length === 0 || !licenseSectionHasUnsavedItems() || isSavingLicense || isAddingLicense() || editingLicenseIndex() !== null\"\r\n (click)=\"confirmAllLicenses()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add license\" (click)=\"addLicense()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"licenses().length === 0 && !isAddingLicense() && editingLicenseIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addLicense()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/card-checklist.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No licenses added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3 border\">\r\n <div *ngIf=\"isAddingLicense() && tempLicense()\" class=\"list-group-item py-3 px-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\" name=\"newLicName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempLicense()?.name)\">License name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\" name=\"newLicAuthority\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\" name=\"newLicNumber\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\" name=\"newLicState\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('issueDate', $event)\" name=\"newLicIssueDate\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('expiryDate', $event)\" name=\"newLicExpiryDate\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempLicense()?.issueDate || null, tempLicense()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">License File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\" name=\"newLicenseAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempLicense()?.fileName\">\r\n <span>{{ tempLicense()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempLicense())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelEditLicense()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingLicense\"\r\n (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : licenseActionLabel(editingLicenseIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let lic of licenses(); let li = index\" class=\"list-group-item py-3 lic-accent-item\">\r\n <ng-container *ngIf=\"editingLicenseIndex() !== li; else editLic\">\r\n <div class=\"d-flex justify-content-between align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <div class=\"fw-semibold item-title-sm\">{{ lic.name }}</div>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedLicenseItem(li) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedLicenseItem(li) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ lic.issuingAuthority || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.licenseNumber || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.issueDate ? formatMonthYear(lic.issueDate) : '\u2014' }} - {{ lic.expiryDate ? formatMonthYear(lic.expiryDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.state || '\u2014' }}</span>\r\n <div *ngIf=\"(licenseIssuesByIndex()[li] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (licenseIssuesByIndex()[li] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditLicense(li)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteLicense(li)\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #editLic>\r\n <div *ngIf=\"(licenseIssuesByIndex()[li] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (licenseIssuesByIndex()[li] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\" name=\"licName{{ li }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempLicense()?.name)\">License name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\" name=\"licAuthority{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\" name=\"licNumber{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\" name=\"licState{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('issueDate', $event)\" name=\"licIssue{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('expiryDate', $event)\" name=\"licExpiry{{ li }}\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempLicense()?.issueDate || null, tempLicense()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">License File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\" name=\"licenseAttachment{{ li }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempLicense()?.fileName\">\r\n <span>{{ tempLicense()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempLicense())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditLicense()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingLicense\"\r\n (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : licenseActionLabel(editingLicenseIndex()) }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/tools.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Tools</h5>\r\n <span *ngIf=\"tools().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"toolsSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ toolsSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"tools().length === 0 || !toolsSectionHasUnsavedItems() || isSavingTool || isToolEditorOpen()\" (click)=\"confirmAllTools()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add tool\" (click)=\"addTool()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex flex-wrap gap-2 p-3 bg-white border rounded shadow-sm\">\r\n <div *ngFor=\"let tool of tools(); let ti = index\" class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\"\r\n class=\"btn btn-light border res-flex d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openToolEditor(ti)\" title=\"Edit\">\r\n <span class=\"fw-normal item-name-text\">{{ tool }}</span>\r\n <span class=\"badge border ms-1\"\r\n [ngClass]=\"hasUnsavedToolItem(ti) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedToolItem(ti) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n <span *ngIf=\"(toolIssuesByIndex()[ti] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\">\r\n Missing info\r\n </span>\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Delete tool\" (click)=\"deleteTool(ti)\">\r\n <span class=\"fw-bold\">\u00D7</span>\r\n </button>\r\n </div>\r\n\r\n <span *ngIf=\"tools().length === 0\" class=\"text-muted small\">No tools added.</span>\r\n </div>\r\n\r\n <div *ngIf=\"isToolEditorOpen()\" class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 9999999;\" (click)=\"closeToolEditor()\">\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\"\r\n (click)=\"$event.stopPropagation()\">\r\n <div class=\"card shadow border-0 w-100\" style=\"max-width: 900px;\">\r\n <div class=\"card-header bg-white d-flex align-items-center gap-3\">\r\n <button type=\"button\" class=\"btn btn-link p-0 text-decoration-none\" (click)=\"closeToolEditor()\">\r\n <img src=\"/assets/images/icons/arrow-left-blue.svg\" width=\"20\" height=\"20\" alt=\"\" />\r\n </button>\r\n <div class=\"fw-bold\">{{ isAddingTool() ? 'Add Tool' : ('Edit ' + (toolForm()?.name || '') + ' Tool') }}\r\n </div>\r\n </div>\r\n <div class=\"card-body p-4\">\r\n <div *ngIf=\"toolFormIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ toolFormIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"row g-3\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Tool Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"toolForm()?.name\"\r\n (ngModelChange)=\"patchToolForm({ name: $event })\" name=\"toolName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(toolForm()?.name)\">Tool name is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span\r\n class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempToolStars(s)\" [attr.aria-label]=\"'Set rating ' + s\">\r\n <span [class]=\"(toolForm()?.stars || 0) >= s ? 'text-warning fs-5' : 'text-muted fs-5'\">\r\n {{ (toolForm()?.stars || 0) >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ toolForm()?.stars || 0 }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"(toolForm()?.stars || 0) <= 0\">Star rating is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngModel]=\"toolForm()?.year\"\r\n (ngModelChange)=\"patchToolForm({ year: $event === '' ? null : +$event })\" name=\"toolYear\" min=\"1\"\r\n max=\"30\" placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"toolForm()?.year === null || toolForm()?.year === undefined\">\r\n Years of experience is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4 text-center\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-checks form-switch mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"toolForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchToolForm({ profileVisibility: $event })\" name=\"toolVisible\" id=\"toolVisible\"\r\n style=\"width: 55px;height: 25px;margin-left: -57px;\" />\r\n <label class=\"form-check-label ps-2 pt-1\" for=\"toolVisible\">Visible</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Comment</label>\r\n <textarea rows=\"4\" class=\"form-control\" [ngModel]=\"toolForm()?.notes\"\r\n (ngModelChange)=\"patchToolForm({ notes: $event })\" name=\"toolNotes\"\r\n placeholder=\"Comment your tool here...\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-white d-flex justify-content-end gap-2\">\r\n <button *ngIf=\"!isAddingTool() && editingToolIndex() !== null\" type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\" (click)=\"deleteTool(editingToolIndex()!)\">\r\n Delete\r\n </button>\r\n <button type=\"button\" class=\"btn btn-link text-secondary\" (click)=\"closeToolEditor()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary px-4\" [disabled]=\"isSavingTool\" (click)=\"saveToolEditor()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Saving...' : toolActionLabel(editingToolIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row g-4 mb-5\">\r\n <div class=\"col-md-12\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/stars.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Skills</h5>\r\n <span *ngIf=\"skills().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"skillsSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ skillsSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"skills().length === 0 || !skillsSectionHasUnsavedItems() || isSavingSkill || isSkillEditorOpen()\" (click)=\"confirmAllSkills()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add skill\" (click)=\"addSkill()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex flex-wrap gap-2 p-3 bg-white border rounded shadow-sm\">\r\n <div *ngFor=\"let skill of skills(); let si = index\" class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\"\r\n class=\"btn btn-light border res-flex d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openSkillEditor(si)\" title=\"Edit\">\r\n <span class=\"fw-normal item-name-text\">{{ skill }}</span>\r\n <span class=\"badge border ms-1\"\r\n [ngClass]=\"hasUnsavedSkillItem(si) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedSkillItem(si) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n <span *ngIf=\"(skillIssuesByIndex()[si] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\">\r\n Missing info\r\n </span>\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Delete skill\"\r\n (click)=\"deleteSkill(si); $event.stopPropagation()\">\r\n <span class=\"fw-bold\">\u00D7</span>\r\n </button>\r\n </div>\r\n\r\n <span *ngIf=\"skills().length === 0\" class=\"text-muted small\">No skills added.</span>\r\n </div>\r\n <div *ngIf=\"isSkillEditorOpen()\" class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 9999999;\" (click)=\"closeSkillEditor()\">\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\"\r\n (click)=\"$event.stopPropagation()\">\r\n <div class=\"card shadow border-0 w-100\" style=\"max-width: 900px;\">\r\n <div class=\"card-header bg-white d-flex align-items-center gap-3\">\r\n <button type=\"button\" class=\"btn btn-link p-0 text-decoration-none\" (click)=\"closeSkillEditor()\">\r\n <img src=\"/assets/images/icons/arrow-left-blue.svg\" width=\"20\" height=\"20\" alt=\"\" />\r\n </button>\r\n <div class=\"fw-bold\">{{ isAddingSkill() ? 'Add Skill' : ('Edit ' + (skillForm()?.name || '') + ' Skill')\r\n }}</div>\r\n </div>\r\n <div class=\"card-body p-4\">\r\n <div *ngIf=\"skillFormIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ skillFormIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"row g-3\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Skills Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"skillForm()?.name\"\r\n (ngModelChange)=\"patchSkillForm({ name: $event })\" name=\"skillName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(skillForm()?.name)\">Skillset name is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span\r\n class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempSkillStars(s)\" [attr.aria-label]=\"'Set rating ' + s\">\r\n <span [class]=\"(skillForm()?.stars || 0) >= s ? 'text-warning fs-5' : 'text-muted fs-5'\">\r\n {{ (skillForm()?.stars || 0) >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ skillForm()?.stars || 0 }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"(skillForm()?.stars || 0) <= 0\">Star rating is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngModel]=\"skillForm()?.year\"\r\n (ngModelChange)=\"patchSkillForm({ year: $event === '' ? null : +$event })\" name=\"skillYear\" min=\"1\"\r\n max=\"30\" placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"skillForm()?.year === null || skillForm()?.year === undefined\">Years of experience is\r\n required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4 text-center\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-checks form-switch mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"skillForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchSkillForm({ profileVisibility: $event })\" name=\"skillVisible\"\r\n id=\"skillVisible\" style=\"width: 55px;height: 25px;margin-left: -57px;\" />\r\n <label class=\"form-check-label ps-2 pt-1\" for=\"skillVisible\">Visible</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Comment</label>\r\n <textarea rows=\"4\" class=\"form-control\" [ngModel]=\"skillForm()?.notes\"\r\n (ngModelChange)=\"patchSkillForm({ notes: $event })\" name=\"skillNotes\"\r\n placeholder=\"Comment your skill here...\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-white d-flex justify-content-end gap-2\">\r\n <button *ngIf=\"!isAddingSkill() && editingSkillIndex() !== null\" type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\" (click)=\"deleteSkill(editingSkillIndex()!)\">\r\n Delete\r\n </button>\r\n <button type=\"button\" class=\"btn btn-link text-secondary\" (click)=\"closeSkillEditor()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary px-4\" [disabled]=\"isSavingSkill\" (click)=\"saveSkillEditor()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Saving...' : skillActionLabel(editingSkillIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row g-4 mb-5\">\r\n <div class=\"col-md-12\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/mortarboard-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Education</h5>\r\n <span *ngIf=\"educationList().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"educationSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ educationSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"educationList().length === 0 || !educationSectionHasUnsavedItems() || isSavingEducation || isAddingEducation() || editingEducationIndex() !== null\"\r\n (click)=\"confirmAllEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add education\" (click)=\"addEducation()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"educationList().length === 0 && !isAddingEducation() && editingEducationIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addEducation()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/mortarboard.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No education added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div *ngIf=\"isAddingEducation() && tempEducation()\" class=\"mb-2\">\r\n <div class=\"form-panel\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\" name=\"newEduDegree\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Institution <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\" name=\"newEduInstitution\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree / Course Type <span class=\"text-danger\">*</span></label>\r\n <ng-select class=\"ng-select-sm\" [items]=\"educationDegreeTypeOptions\" [clearable]=\"false\"\r\n placeholder=\"Select degree / course type\" [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\" name=\"newEduDegreeType\">\r\n </ng-select>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.country\"\r\n (ngModelChange)=\"patchTempEducation({ country: $event })\" name=\"newEduCountry\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.state\"\r\n (ngModelChange)=\"patchTempEducation({ state: $event })\" name=\"newEduState\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\" name=\"newEduCity\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.startDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('startDate', $event)\" name=\"newEduStartDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.startDate)\">Start date is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.endDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('endDate', $event)\" name=\"newEduEndDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Education File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onEducationFileSelected($event)\" name=\"newEducationAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempEducation()?.fileName\">\r\n <span>{{ tempEducation()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempEducation())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingEducation\"\r\n (click)=\"saveEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Uploading...' : educationActionLabel(editingEducationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let edu of educationList(); let ei = index\" class=\"edu-accent-item p-3 bg-white border rounded-3 shadow-sm mb-2\">\r\n <div class=\"d-flex justify-content-between align-items-start\">\r\n <div class=\"d-flex align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h6 class=\"fw-bold mb-0 item-title-sm\">{{ edu.degree }}</h6>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedEducationItem(ei) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedEducationItem(ei) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ edu.institution || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.degreeType || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.startDate ? formatMonthYear(edu.startDate) : '\u2014' }} - {{ edu.endDate ? formatMonthYear(edu.endDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.city }}<span *ngIf=\"edu.city && edu.state\">, </span>{{ edu.state }}<ng-container *ngIf=\"!edu.city && !edu.state\">\u2014</ng-container></span>\r\n <div *ngIf=\"(educationIssuesByIndex()[ei] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (educationIssuesByIndex()[ei] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\" *ngIf=\"editingEducationIndex() !== ei\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditEducation(ei)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteEducation(ei)\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"editingEducationIndex() === ei\" class=\"mt-3\">\r\n <div *ngIf=\"(educationIssuesByIndex()[ei] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (educationIssuesByIndex()[ei] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\" name=\"eduDegree{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Institution <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\" name=\"eduInstitution{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.institution)\">Institution name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree / Course Type <span class=\"text-danger\">*</span></label>\r\n <ng-select class=\"ng-select-sm\" [items]=\"educationDegreeTypeOptions\" [clearable]=\"false\"\r\n placeholder=\"Select degree / course type\" [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\" name=\"eduDegreeType{{ ei }}\">\r\n </ng-select>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.country\"\r\n (ngModelChange)=\"patchTempEducation({ country: $event })\" name=\"eduCountry{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.state\"\r\n (ngModelChange)=\"patchTempEducation({ state: $event })\" name=\"eduState{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\" name=\"eduCity{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.startDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('startDate', $event)\" name=\"eduStartDate{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.startDate)\">Start date is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.endDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('endDate', $event)\" name=\"eduEndDate{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Education File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onEducationFileSelected($event)\" name=\"educationAttachment{{ ei }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempEducation()?.fileName\">\r\n <span>{{ tempEducation()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempEducation())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingEducation\" (click)=\"saveEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Uploading...' : educationActionLabel(editingEducationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n </div>\r\n <div class=\"d-flex gap-3 justify-content-center mt-5 pt-2\" *ngIf=\"!isResume\">\r\n <button class=\"btn btn-outline-secondary preview-back-btn px-5 h-auto\" style=\"border-radius: 5px !important;\" (click)=\"onBackClick()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"me-1\" style=\"vertical-align:-0.1em\">\r\n <path d=\"M11 3 5 8l6 5\" />\r\n </svg> Back\r\n </button>\r\n <button class=\"btn btn-primary preview-dashboard-btn px-5 h-auto\" style=\"border-radius: 5px !important;\" [disabled]=\"!canConfirmAndContinue() || isSavingBasic\"\r\n (click)=\"onGoToDashboardClick()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Saving...' : 'Go to Dashboard' }}\r\n <img *ngIf=\"!isSavingBasic\" src=\"/assets/images/icons/arrow-right-white.svg\" width=\"14\" height=\"14\" class=\"ms-1\" style=\"vertical-align:-0.1em\" alt=\"\" />\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<ng-template #loading>\r\n <div class=\"text-center p-5\">\r\n <div class=\"spinner-border text-primary\"></div>\r\n <p class=\"text-muted mt-2\">Loading data...</p>\r\n </div>\r\n</ng-template>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBulkSkillConfirm\">\r\n <div class=\"confirm-modal-card\" style=\"max-width: 480px;\">\r\n <h4 class=\"mb-1\">Set Rating for All Skills</h4>\r\n <p class=\"text-muted small mb-4\">Enter a star rating and years of experience to apply to all skills that are missing these values.</p>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"bulkSkillStars = s\">\r\n <span [class]=\"bulkSkillStars >= s ? 'text-warning fs-4' : 'text-muted fs-4'\">\r\n {{ bulkSkillStars >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ bulkSkillStars }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkSkillStars <= 0\">Star rating is required</div>\r\n </div>\r\n <div class=\"mb-4\">\r\n <label class=\"small text-muted d-block mb-1\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [(ngModel)]=\"bulkSkillYear\" min=\"1\" max=\"30\"\r\n placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkSkillYear === null || bulkSkillYear === undefined\">Years of experience is required</div>\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"cancelBulkSkillConfirm()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingSkill || bulkSkillStars <= 0 || bulkSkillYear === null\"\r\n (click)=\"applyBulkSkillConfirm()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Saving...' : 'Apply to All & Save' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBulkToolConfirm\">\r\n <div class=\"confirm-modal-card\" style=\"max-width: 480px;\">\r\n <h4 class=\"mb-1\">Set Rating for All Tools</h4>\r\n <p class=\"text-muted small mb-4\">Enter a star rating and years of experience to apply to all tools that are missing these values.</p>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"bulkToolStars = s\">\r\n <span [class]=\"bulkToolStars >= s ? 'text-warning fs-4' : 'text-muted fs-4'\">\r\n {{ bulkToolStars >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ bulkToolStars }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkToolStars <= 0\">Star rating is required</div>\r\n </div>\r\n <div class=\"mb-4\">\r\n <label class=\"small text-muted d-block mb-1\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [(ngModel)]=\"bulkToolYear\" min=\"1\" max=\"30\"\r\n placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkToolYear === null || bulkToolYear === undefined\">Years of experience is required</div>\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"cancelBulkToolConfirm()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingTool || bulkToolStars <= 0 || bulkToolYear === null\"\r\n (click)=\"applyBulkToolConfirm()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Saving...' : 'Apply to All & Save' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBackConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Leave this page?</h4>\r\n <p class=\"text-muted mb-4\">If you go back, only saved data will be retained.</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"stayOnPreview()\">Stay</button>\r\n <button type=\"button\" class=\"btn btn-danger h-auto\" (click)=\"proceedBack()\">Proceed Back</button>\r\n </div>\r\n </div>\r\n\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showDashboardConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Finish Setup and Continue</h4>\r\n <p class=\"text-muted mb-4\">Save your information and go to your dashboard</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" [disabled]=\"isSavingBasic\"\r\n (click)=\"cancelDashboardRedirect()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingBasic\" (click)=\"goToDashboard()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Proceeding...' : 'Proceed' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{color:#69707d}.res-flex:hover,.res-flex:focus,.res-flex:active{transform:none!important;box-shadow:none!important}.container{max-width:900px;margin:30px auto;font-family:Arial,sans-serif;color:#69707d}.preview-page-header{max-width:900px;margin:50px auto 10px;padding:0 12px}.preview-title{font-size:18px;font-weight:700;color:#69707d;margin:0}.preview-subtitle{margin-top:7px;font-size:14px;color:#69707d}.preview-card-gradient h2,.section h5.fw-bold{font-size:18px}.section{margin-bottom:25px}.section-title{font-weight:600;display:block;margin-bottom:8px}.section-title .sub{font-weight:400;color:#777;font-size:13px}.dropdown-box{border:1px solid #ddd;border-radius:8px;padding:12px 15px;display:flex;justify-content:space-between;align-items:center}.icons{display:flex;gap:10px}.icon{cursor:pointer;font-size:14px;color:#777}.card{border:1px solid #ddd;border-radius:5px;padding:20px;background:#fff}.category{border-bottom:1px solid #eee;padding:15px 0}.category:last-child{border-bottom:none}.category-header{display:flex;justify-content:space-between;font-weight:600;margin-bottom:10px}.tags{display:flex;flex-wrap:wrap;gap:10px}.tag{background:#f2f4f7;padding:6px 12px;border-radius:6px;font-size:13px}.footer{text-align:center;margin-top:15px;color:#777;cursor:pointer}.actions{display:flex;justify-content:space-between;margin:50px 0 27px}.text-secondary{white-space:pre-line;font-size:12px;color:#69707d}.extra-small{font-size:.8rem}.card{transition:transform .2s ease,box-shadow .2s ease}.card:hover{transform:translateY(-3px)}.achievement-section .badge{font-size:.75rem;white-space:normal;text-align:left}.skill-tag .badge{font-weight:500;font-size:.9rem;transition:all .2s ease;cursor:default}.skill-tag .badge:hover{transform:translateY(-2px)}.skill-tag .btn-close{opacity:.5}.skill-tag .btn-close:hover{opacity:1}.bg-light.text-dark.border{background-color:#f8f9fa!important;border-color:#dee2e6!important}.card{transition:all .3s cubic-bezier(.25,.8,.25,1)}.card:hover .bg-light{background-color:#e8f5e9!important}.position-fixed .card:hover{transform:none!important}code{background-color:#f8f9fa;padding:2px 6px;border-radius:4px}.list-group-item{transition:all .2s ease-in-out}.list-group-item:hover{background-color:#fcfcfc;transform:translate(5px)}.border-dashed{border-style:dashed!important}.tool-card{transition:all .2s ease-in-out;border-radius:12px}.tool-card:hover{transform:translateY(-5px);border-color:var(--bs-primary)!important}.tool-card:hover .icon-box{background-color:var(--bs-primary-subtle)!important}.tool-card .icon-box{width:60px;height:60px;transition:background-color .2s ease}.border-dashed{border:2px dashed #dee2e6!important}.border-dashed:hover{border-color:var(--bs-primary)!important;background-color:#fff!important}.popup{position:fixed;top:20%;right:20px;width:320px;max-width:calc(100vw - 32px);background:#fff;border-radius:10px;padding:16px}.status-row{display:flex;justify-content:space-between;margin:10px 0}.success{color:#2e7d32;font-weight:700}.error{color:#d32f2f}.pending{color:#f9a825}.section-flag{font-weight:600}button.btn.btn-sm.btn-outline-primary{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:5px!important}button.btn.btn-sm.btn-outline-primary:hover{background-color:#356895;border-color:#356895;color:#fff}button.btn.btn-sm.btn-outline-danger{border:1px solid #dc3545;color:#dc3545;border-radius:5px!important}button.btn.btn-sm.btn-outline-primary.rounded-circle{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:5px!important}button.action-icon-btn{min-width:22px;width:22px;height:22px;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:5px!important;background:transparent!important;border:none!important;line-height:1}button.action-icon-btn.btn-outline-primary{color:#4077ad!important;border-color:#4077ad!important}button.action-icon-btn.btn-outline-danger{color:#dc3545!important}.action-icon-image{width:20px;height:20px;object-fit:contain;display:inline-block}.action-icon-image.edit-icon{filter:brightness(0) saturate(100%) invert(41%) sepia(39%) saturate(774%) hue-rotate(170deg) brightness(91%) contrast(89%)}.action-icon-image.delete-icon{filter:brightness(0) saturate(100%) invert(24%) sepia(79%) saturate(4008%) hue-rotate(344deg) brightness(91%) contrast(90%)}.modal-overlay{position:fixed;inset:0;background:#11182773;display:flex;align-items:center;justify-content:center;z-index:2500;padding:20px}.status-modal-card{width:min(760px,96vw);max-height:85vh;overflow:auto;background:#fff;border-radius:16px;border:1px solid #e5e7eb}.status-modal-header{padding:20px 24px 14px;border-bottom:1px solid #eef2f7}.status-modal-body{padding:12px 20px 20px}.status-modal-footer{padding:12px 20px 20px;border-top:1px solid #eef2f7;display:flex;justify-content:end;align-items:center;gap:12px}.status-modal-row{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px 10px;border-bottom:1px solid #f1f5f9}.status-modal-row:last-child{border-bottom:0}.status-modal-name{font-size:14px;font-weight:600;color:#69707d}.status-modal-state{font-size:.92rem;font-weight:600}.status-modal-state.pending{color:#a16207}.status-modal-state.success{color:#166534}.status-modal-state.partial{color:#b45309}.status-modal-state.error{color:#b91c1c}.confirm-modal-card{width:min(520px,96vw);background:#fff;border-radius:5px;border:1px solid #e5e7eb;padding:24px}.year-experience-select{max-height:150px}@media screen and (max-width: 768px){.res-flex{flex-wrap:wrap!important;justify-content:center!important}.res-flex .fw-normal{width:100%;text-align:center;font-size:14px!important}.d-flex.flex-wrap.gap-2.p-3.bg-white.border.rounded.shadow-sm{justify-content:center}.preview-page-header{margin:20px auto 8px;padding:0 4px}.container{padding-left:4px;padding-right:4px}.preview-title{font-size:16px}.preview-subtitle{font-size:14px}.actions{margin:24px 0 16px}.section-header-title{flex-wrap:wrap}.section-header-title>.section-flag{flex-basis:53%}.section-header-row{align-items:flex-start}.preview-card-gradient{padding:14px 14px 12px}.preview-card-gradient h2{font-size:18px}.popup{width:calc(100vw - 40px);right:16px;top:12%}.card{padding:0}.card-body.p-4,.px-4.py-3{padding:12px!important}.row.g-4,.row.g-3{--bs-gutter-x: .75rem}.d-flex.gap-4{gap:10px!important}.preview-card-gradient>.d-flex.justify-content-between.align-items-start{flex-wrap:wrap;row-gap:8px}.preview-card-gradient>.d-flex.justify-content-between.align-items-start>.badge.bg-primary-subtle{margin-left:auto}}@media screen and (max-width: 575px){.preview-title{font-size:16px}.preview-subtitle{font-size:14px}.section>.d-flex{flex-wrap:wrap;row-gap:8px}.section>.d-flex>.d-flex:last-child{width:100%;justify-content:flex-end}}::ng-deep .bs-datepicker-head{background-color:#4077ad!important}::ng-deep .bs-datepicker-body table td span.selected,.bs-datepicker-body table td.selected span{background-color:#4077ad!important}.profile-avatar-circle{width:58px;height:58px;border-radius:5px;background:#4077ad;display:flex;align-items:center;justify-content:center;font-size:22px;font-weight:700;color:#fff;letter-spacing:1px;flex-shrink:0}.section-header-icon{font-size:20px;line-height:1;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;opacity:.9;filter:invert(47%) sepia(8%) saturate(483%) hue-rotate(176deg) brightness(91%) contrast(87%)}.section-header-title h5.fw-bold{color:#69707d}.text-muted{color:#69707d!important}h6.text-uppercase.fw-bold.text-muted{font-size:14px;color:#69707d!important}.work-accent-item{border-left:4px solid #4077ad!important;border-radius:0 5px 5px 0!important;transition:background-color .18s ease,box-shadow .18s ease}.work-accent-item:hover{background-color:#f5f8ff!important;box-shadow:0 4px 14px #4077ad17!important}.edu-accent-item{border-left:4px solid #4077AD!important;border-radius:0 5px 5px 0!important;transition:background-color .18s ease,box-shadow .18s ease}.edu-accent-item:hover{background-color:#f8f8ff!important;box-shadow:0 4px 14px #6366f117!important}.cert-accent-item{border-left:4px solid #059669!important;border-radius:0 5px 5px 0!important;transition:background-color .18s ease}.cert-accent-item:hover{background-color:#f0fdf4!important}.lic-accent-item{border-left:4px solid #d97706!important;border-radius:0 5px 5px 0!important;transition:background-color .18s ease}.lic-accent-item:hover{background-color:#fffbeb!important}.field-label-sm{font-size:14px;font-weight:700;letter-spacing:.08em;color:#69707d;margin-bottom:3px;display:block}.item-name-text{color:#69707d}.field-value-sm{font-weight:600;font-size:12px;color:#69707d}.item-title-sm{font-size:14px;color:#69707d!important}.item-meta-line{display:block;font-size:12px;color:#69707d;margin-top:3px}.empty-state-wrap{text-align:center;padding:32px 20px;background:#fafbfc;border:1.5px dashed #d1d5db;border-radius:5px;cursor:pointer;transition:background-color .18s ease,border-color .18s ease}.empty-state-wrap .empty-icon{font-size:2rem;color:#d1d5db;margin-bottom:8px}.empty-state-wrap p{color:#9ca3af;margin:0;font-size:14px}.empty-state-wrap:hover{background:#f0f6ff;border-color:#4077ad}.form-panel{background:#fff;border:1px solid #e2e8f0;border-radius:5px;padding:20px}.form-panel .form-control,.form-panel .form-select{border-color:#d1d5db;border-radius:8px;font-size:12px}.form-panel .form-control:focus,.form-panel .form-select:focus{border-color:#4077ad;box-shadow:0 0 0 3px #4077ad1f}.section-header-bar{display:flex;align-items:center;justify-content:space-between;padding:10px 0 14px;border-bottom:2px solid #f1f5f9;margin-bottom:16px}.preview-card-gradient{background:linear-gradient(135deg,#fff,#eff6ff);border-bottom:1px solid #e2e8f0;padding:20px 24px 16px;border-radius:5px 5px 0 0}.item-icon-circle{width:40px;height:40px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:700;color:#fff;flex-shrink:0}.item-avatar--work{background:linear-gradient(135deg,#4077ad,#2d5a8a)}.item-avatar--edu{background:linear-gradient(135deg,#4077ad,#4338ca)}.provider-layout{display:flex;flex-direction:column}.provider-company-first{order:-1}.section-locked{pointer-events:none;opacity:.45;filter:blur(1.5px);-webkit-user-select:none;user-select:none}.btn.btn-primary{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-primary:hover:not(:disabled),.btn.btn-primary:focus:not(:disabled),.btn.btn-primary:active:not(:disabled){background-color:#356895!important;border-color:#356895!important;color:#fff!important}.btn.btn-success,.btn.btn-outline-success{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-success:hover:not(:disabled),.btn.btn-success:focus:not(:disabled),.btn.btn-success:active:not(:disabled),.btn.btn-outline-success:hover:not(:disabled),.btn.btn-outline-success:focus:not(:disabled),.btn.btn-outline-success:active:not(:disabled){background-color:#336843!important;border-color:#336843!important;color:#fff!important}.btn.btn-outline-secondary.rounded-pill{background-color:#69707d!important;border-color:#69707d!important;color:#fff!important;border-radius:5px!important}.btn.btn-outline-secondary.rounded-pill:hover:not(:disabled),.btn.btn-outline-secondary.rounded-pill:focus:not(:disabled),.btn.btn-outline-secondary.rounded-pill:active:not(:disabled){background-color:#565c66!important;border-color:#565c66!important;color:#fff!important}.preview-back-btn{background-color:#426c85!important;border-color:#426c85!important;color:#fff!important}.preview-dashboard-btn{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-outline-success:hover:not(:disabled),.btn.btn-outline-success:focus:not(:disabled),.btn.btn-outline-success:active:not(:disabled){background-color:transparent!important;border-color:#198754!important;color:#198754!important}.btn.btn-outline-secondary:not(.rounded-pill){background-color:#d4dae6!important;border-color:#d4dae6!important;color:#69707d!important}.btn.btn-outline-secondary:not(.rounded-pill):hover:not(:disabled),.btn.btn-outline-secondary:not(.rounded-pill):focus:not(:disabled),.btn.btn-outline-secondary:not(.rounded-pill):active:not(:disabled){background-color:#c2cbde!important;border-color:#c2cbde!important;color:#69707d!important}.btn.btn-danger{background-color:#b43026!important;border-color:#b43026!important;color:#fff!important}.btn.btn-danger:hover:not(:disabled),.btn.btn-danger:focus:not(:disabled),.btn.btn-danger:active:not(:disabled){background-color:#96271f!important;border-color:#96271f!important;color:#fff!important}.btn.btn-outline-danger.rounded-circle{border-color:#b43026!important;color:#b43026!important;border-radius:5px!important}.btn.btn-outline-danger.rounded-circle:hover:not(:disabled),.btn.btn-outline-danger.rounded-circle:focus:not(:disabled),.btn.btn-outline-danger.rounded-circle:active:not(:disabled){border-color:#96271f!important;color:#b43026!important}.btn.btn-link.text-secondary{background-color:#d4dae6!important;border-color:#d4dae6!important;color:#69707d!important;text-decoration:none!important;border-radius:5px}.btn.btn-link.text-secondary:hover:not(:disabled),.btn.btn-link.text-secondary:focus:not(:disabled){background-color:#c2cbde!important;color:#69707d!important}.btn.btn-link.text-danger{background-color:#b43026!important;border-color:#b43026!important;color:#fff!important;text-decoration:none!important;border-radius:5px}.btn.btn-link.text-danger:hover:not(:disabled),.btn.btn-link.text-danger:focus:not(:disabled){background-color:#96271f!important;color:#fff!important}.btn{border-radius:5px!important;box-shadow:none!important}.badge.bg-warning-subtle.text-warning{background-color:#fff3cd!important;color:#664d03!important;border-color:#ffe69c!important}.badge.bg-success-subtle.text-success{background-color:#4077ad!important;color:#fff!important;border-color:#4077ad!important}.badge.bg-primary-subtle.text-primary{background-color:#e0edf2!important;color:#4077ad!important;border-color:#e0edf2!important}\n"] }]
|
|
6432
|
+
}], ctorParameters: () => [{ type: CredentialingStore }, { type: FileService }, { type: UserSkillSetService }, { type: UserToolService }, { type: UserDocumentService }, { type: UserEducationService }, { type: UserDetailService }, { type: UserExperienceService }, { type: i1$4.TokenService }, { type: i1$4.RoleContextService }, { type: ProvidersService }, { type: FrontEndProvidersService }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
|
|
6386
6433
|
type: Inject,
|
|
6387
6434
|
args: [LIBRARY_CONFIG]
|
|
6388
6435
|
}] }], propDecorators: { providerId: [{
|