@idsoftsource/initial-process 1.6.8 → 1.7.1
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.
|
@@ -1921,7 +1921,9 @@ class UserEducationService {
|
|
|
1921
1921
|
return this.httpClient.put(`${this.baseUrl}/UpdateUserEducation`, model);
|
|
1922
1922
|
}
|
|
1923
1923
|
getUserEducation(query) {
|
|
1924
|
-
return this.httpClient.get(`${this.baseUrl}/GetUserEducation
|
|
1924
|
+
return this.httpClient.get(`${this.baseUrl}/GetUserEducation`, {
|
|
1925
|
+
params: this.buildParams(query),
|
|
1926
|
+
});
|
|
1925
1927
|
}
|
|
1926
1928
|
/* ==============================
|
|
1927
1929
|
PARAM BUILDER
|
|
@@ -1975,7 +1977,9 @@ class UserExperienceService {
|
|
|
1975
1977
|
return this.httpClient.put(`${this.baseUrl}/UpdateUserExperience`, model);
|
|
1976
1978
|
}
|
|
1977
1979
|
getUserExperience(query) {
|
|
1978
|
-
return this.httpClient.get(`${this.baseUrl}/GetUserExperience
|
|
1980
|
+
return this.httpClient.get(`${this.baseUrl}/GetUserExperience`, {
|
|
1981
|
+
params: this.buildParams(query),
|
|
1982
|
+
});
|
|
1979
1983
|
}
|
|
1980
1984
|
/* ==============================
|
|
1981
1985
|
PARAM BUILDER
|
|
@@ -2032,8 +2036,14 @@ class PreviewComponent {
|
|
|
2032
2036
|
dateInputFormat: 'MM/YYYY',
|
|
2033
2037
|
containerClass: 'dark-blue',
|
|
2034
2038
|
};
|
|
2039
|
+
futureMaxDate = new Date(2035, 11, 31);
|
|
2035
2040
|
maxDate = new Date();
|
|
2036
2041
|
companyForm;
|
|
2042
|
+
options = {
|
|
2043
|
+
componentRestrictions: {
|
|
2044
|
+
country: ['US'],
|
|
2045
|
+
},
|
|
2046
|
+
};
|
|
2037
2047
|
isResume = false;
|
|
2038
2048
|
resumeModel = null;
|
|
2039
2049
|
providerName;
|
|
@@ -2283,8 +2293,6 @@ class PreviewComponent {
|
|
|
2283
2293
|
issues.push('Phone number is required');
|
|
2284
2294
|
if (!this.isBlank(item.phone)) {
|
|
2285
2295
|
const digitsOnly = item.phone.replace(/\D/g, '');
|
|
2286
|
-
if (digitsOnly.length !== 10)
|
|
2287
|
-
issues.push('Phone number must be 10 digits');
|
|
2288
2296
|
}
|
|
2289
2297
|
const yoe = item.yearsOfExperience;
|
|
2290
2298
|
if (yoe === null || yoe === undefined || Number.isNaN(Number(yoe)) || Number(yoe) <= 0)
|
|
@@ -2593,6 +2601,14 @@ class PreviewComponent {
|
|
|
2593
2601
|
orderBy,
|
|
2594
2602
|
};
|
|
2595
2603
|
}
|
|
2604
|
+
buildSectionForUserQuery(orderBy, includeForUser = false) {
|
|
2605
|
+
return {
|
|
2606
|
+
page: 1,
|
|
2607
|
+
pageSize: 100,
|
|
2608
|
+
targetUserId: this.roleContextService?.tempUserContext()?.userId ?? '',
|
|
2609
|
+
orderBy,
|
|
2610
|
+
};
|
|
2611
|
+
}
|
|
2596
2612
|
buildUserName() {
|
|
2597
2613
|
const basic = this.store.profileSignal()?.basicDetails;
|
|
2598
2614
|
const fullName = `${basic?.firstName ?? ''} ${basic?.lastName ?? ''}`.trim();
|
|
@@ -2804,7 +2820,7 @@ class PreviewComponent {
|
|
|
2804
2820
|
if (this.workExperienceServerIds[index] || !this.payloadUserId)
|
|
2805
2821
|
return;
|
|
2806
2822
|
try {
|
|
2807
|
-
const res = await firstValueFrom(this.userExperienceService.getUserExperience(this.
|
|
2823
|
+
const res = await firstValueFrom(this.userExperienceService.getUserExperience(this.buildSectionForUserQuery('createdDateTime asc')));
|
|
2808
2824
|
const saved = Array.isArray(res?.data) ? res.data : [];
|
|
2809
2825
|
const target = this.workSignature(item);
|
|
2810
2826
|
const match = saved.find((x) => this.workSignature(this.mapSavedWorkToPreview(x)) === target);
|
|
@@ -2820,7 +2836,7 @@ class PreviewComponent {
|
|
|
2820
2836
|
if (this.educationServerIds[index] || !this.payloadUserId)
|
|
2821
2837
|
return;
|
|
2822
2838
|
try {
|
|
2823
|
-
const res = await firstValueFrom(this.userEducation.getUserEducation(this.
|
|
2839
|
+
const res = await firstValueFrom(this.userEducation.getUserEducation(this.buildSectionForUserQuery('createdDateTime asc')));
|
|
2824
2840
|
const saved = Array.isArray(res?.data) ? res.data : [];
|
|
2825
2841
|
const target = this.educationSignature(item);
|
|
2826
2842
|
const match = saved.find((x) => this.educationSignature(this.mapSavedEducationToPreview(x)) === target);
|
|
@@ -2941,9 +2957,15 @@ class PreviewComponent {
|
|
|
2941
2957
|
this.licenseLocallySaved = {};
|
|
2942
2958
|
this.skillLocallySaved = {};
|
|
2943
2959
|
this.toolLocallySaved = {};
|
|
2960
|
+
var request = {};
|
|
2961
|
+
if (this.roleContextService?.tempUserContext()?.userId) {
|
|
2962
|
+
request = {
|
|
2963
|
+
targetUserId: this.roleContextService?.tempUserContext()?.userId
|
|
2964
|
+
};
|
|
2965
|
+
}
|
|
2944
2966
|
const [workRes, educationRes, certificationsRes, licensesRes, skillsRes, toolsRes, userDetailRes] = await Promise.all([
|
|
2945
|
-
firstValueFrom(this.userExperienceService.getUserExperience(this.
|
|
2946
|
-
firstValueFrom(this.userEducation.getUserEducation(this.
|
|
2967
|
+
firstValueFrom(this.userExperienceService.getUserExperience(this.buildSectionForUserQuery('createdDateTime asc'))),
|
|
2968
|
+
firstValueFrom(this.userEducation.getUserEducation(this.buildSectionForUserQuery('createdDateTime asc'))),
|
|
2947
2969
|
// ✅ Certifications (mainType = 2)
|
|
2948
2970
|
firstValueFrom(this.userDocumentService.getUserDocument({
|
|
2949
2971
|
page: 1,
|
|
@@ -2962,7 +2984,7 @@ class PreviewComponent {
|
|
|
2962
2984
|
})),
|
|
2963
2985
|
firstValueFrom(this.userSkillSetService.getUserSkillSet(this.buildSectionQuery('skillSetName asc', true))),
|
|
2964
2986
|
firstValueFrom(this.userToolService.getUserTool(this.buildSectionQuery('toolName asc', true))),
|
|
2965
|
-
firstValueFrom(this.userDetailService.getByUserId(this.payloadUserId)).catch(() => null),
|
|
2987
|
+
firstValueFrom(this.userDetailService.getByUserId(this.payloadUserId, request)).catch(() => null),
|
|
2966
2988
|
]);
|
|
2967
2989
|
// Enable dashboard button when GetByUserId has any payload.
|
|
2968
2990
|
this.hasUserDetailData = this.hasUserDetailPayload(userDetailRes);
|
|
@@ -3060,6 +3082,9 @@ class PreviewComponent {
|
|
|
3060
3082
|
}
|
|
3061
3083
|
}
|
|
3062
3084
|
this.store.resumeToolMeta.set(nextToolMeta);
|
|
3085
|
+
if (savedBasicDetails?.phone) {
|
|
3086
|
+
savedBasicDetails.phone = this.formatPhone(savedBasicDetails.phone);
|
|
3087
|
+
}
|
|
3063
3088
|
this.commitProfile({
|
|
3064
3089
|
...current,
|
|
3065
3090
|
basicDetails: savedBasicDetails ?? current.basicDetails,
|
|
@@ -4775,15 +4800,113 @@ class PreviewComponent {
|
|
|
4775
4800
|
this.isSavingCompany = false;
|
|
4776
4801
|
}
|
|
4777
4802
|
}
|
|
4803
|
+
AddressChangeCompany(address) {
|
|
4804
|
+
var doorNumber = address.address_components.find((a) => {
|
|
4805
|
+
return a.types.includes("street_number");
|
|
4806
|
+
})?.short_name;
|
|
4807
|
+
doorNumber = doorNumber ? doorNumber + ' ' : '';
|
|
4808
|
+
this.tempCompanyDetails = {
|
|
4809
|
+
...this.tempCompanyDetails,
|
|
4810
|
+
address1: doorNumber +
|
|
4811
|
+
(address.address_components.find((a) => {
|
|
4812
|
+
return a.types.includes('route');
|
|
4813
|
+
})?.short_name || ''),
|
|
4814
|
+
city: address.address_components.find((a) => {
|
|
4815
|
+
return (a.types.includes('locality') ||
|
|
4816
|
+
a.types.includes('sublocality') ||
|
|
4817
|
+
a.types.includes('sublocality_level_1'));
|
|
4818
|
+
})?.short_name || '',
|
|
4819
|
+
state: address.address_components.find((a) => {
|
|
4820
|
+
return a.types.includes('administrative_area_level_1');
|
|
4821
|
+
})?.short_name || '',
|
|
4822
|
+
country: address.address_components.find((a) => {
|
|
4823
|
+
return a.types.includes('country');
|
|
4824
|
+
})?.short_name || '',
|
|
4825
|
+
zipcode: address.address_components.find((a) => {
|
|
4826
|
+
return a.types.includes('postal_code');
|
|
4827
|
+
})?.long_name ||
|
|
4828
|
+
address.address_components?.[7]?.short_name ||
|
|
4829
|
+
''
|
|
4830
|
+
};
|
|
4831
|
+
}
|
|
4832
|
+
phoneMask(event, type) {
|
|
4833
|
+
const input = event.target;
|
|
4834
|
+
const formattedPhone = this.formatPhone(input.value);
|
|
4835
|
+
if (type === 'profile') {
|
|
4836
|
+
this.tempProfile.phone = formattedPhone;
|
|
4837
|
+
}
|
|
4838
|
+
if (type === 'company') {
|
|
4839
|
+
this.tempCompanyDetails.companyPhoneNumber = formattedPhone;
|
|
4840
|
+
}
|
|
4841
|
+
}
|
|
4842
|
+
formatPhone(phone) {
|
|
4843
|
+
let digits = (phone || '').replace(/\D/g, '');
|
|
4844
|
+
digits = digits.substring(0, 10);
|
|
4845
|
+
let formatted = '';
|
|
4846
|
+
if (digits.length > 0) {
|
|
4847
|
+
formatted = '(' + digits.substring(0, 3);
|
|
4848
|
+
}
|
|
4849
|
+
if (digits.length >= 4) {
|
|
4850
|
+
formatted += ') ' + digits.substring(3, 6);
|
|
4851
|
+
}
|
|
4852
|
+
if (digits.length >= 7) {
|
|
4853
|
+
formatted += '-' + digits.substring(6, 10);
|
|
4854
|
+
}
|
|
4855
|
+
return formatted;
|
|
4856
|
+
}
|
|
4857
|
+
AddressChangeUser(address) {
|
|
4858
|
+
var doorNumber = address.address_components.find((a) => {
|
|
4859
|
+
return a.types.includes("street_number");
|
|
4860
|
+
})?.short_name;
|
|
4861
|
+
doorNumber = doorNumber ? doorNumber + ' ' : '';
|
|
4862
|
+
this.tempProfile = {
|
|
4863
|
+
...this.tempProfile,
|
|
4864
|
+
address: doorNumber +
|
|
4865
|
+
(address.address_components.find((a) => {
|
|
4866
|
+
return a.types.includes('route');
|
|
4867
|
+
})?.short_name || ''),
|
|
4868
|
+
city: address.address_components.find((a) => {
|
|
4869
|
+
return (a.types.includes('locality') ||
|
|
4870
|
+
a.types.includes('sublocality') ||
|
|
4871
|
+
a.types.includes('sublocality_level_1'));
|
|
4872
|
+
})?.short_name || '',
|
|
4873
|
+
state: address.address_components.find((a) => {
|
|
4874
|
+
return a.types.includes('administrative_area_level_1');
|
|
4875
|
+
})?.short_name || '',
|
|
4876
|
+
country: address.address_components.find((a) => {
|
|
4877
|
+
return a.types.includes('country');
|
|
4878
|
+
})?.short_name || '',
|
|
4879
|
+
zipCode: address.address_components.find((a) => {
|
|
4880
|
+
return a.types.includes('postal_code');
|
|
4881
|
+
})?.long_name ||
|
|
4882
|
+
address.address_components?.[7]?.short_name ||
|
|
4883
|
+
''
|
|
4884
|
+
};
|
|
4885
|
+
}
|
|
4886
|
+
allowOnlyNumbers(event) {
|
|
4887
|
+
const charCode = event.which ? event.which : event.keyCode;
|
|
4888
|
+
// Allow backspace, delete, tab, arrow keys
|
|
4889
|
+
if (charCode === 8 ||
|
|
4890
|
+
charCode === 9 ||
|
|
4891
|
+
charCode === 37 ||
|
|
4892
|
+
charCode === 39 ||
|
|
4893
|
+
charCode === 46) {
|
|
4894
|
+
return;
|
|
4895
|
+
}
|
|
4896
|
+
// Block non-numeric characters
|
|
4897
|
+
if (charCode < 48 || charCode > 57) {
|
|
4898
|
+
event.preventDefault();
|
|
4899
|
+
}
|
|
4900
|
+
}
|
|
4778
4901
|
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$1.TokenService }, { token: i1$1.RoleContextService }, { token: ProvidersService }, { token: LIBRARY_CONFIG }], target: i0.ɵɵFactoryTarget.Component });
|
|
4779
|
-
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" }, outputs: { backToParent: "backToParent" }, viewQueries: [{ propertyName: "companyForm", first: true, predicate: ["companyForm"], descendants: true }], ngImport: i0, template: "<div class=\"preview-page-header\" *ngIf=\"!isResume\">\r\n <h2 class=\"preview-title\">Review Extracted Information</h2>\r\n <p class=\"preview-subtitle\">We\u2019ve automatically extracted details from your uploaded resume. Please review and confirm\r\n accuracy.</p>\r\n</div>\r\n\r\n\r\n<div [ngClass]=\"isResume ? '' : 'container py-4'\">\r\n <div class=\"section mb-5\">\r\n <div *ngIf=\"details() as data; else loading\">\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"!isEditMode()\">\r\n <div class=\"card-body p-4\">\r\n <div class=\"d-flex justify-content-between align-items-start mb-4\">\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 <span class=\"badge bg-primary-subtle text-primary border p-2\">ID: Verified</span>\r\n </div>\r\n\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 <label class=\"small text-muted d-block\">EMAIL</label>\r\n <span class=\"fw-bold small\">{{ data.email }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">PHONE</label>\r\n <span class=\"fw-bold small\">{{ data.phone }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">LOCATION</label>\r\n <span class=\"small\">{{ data.address }}, {{ data.city }}, {{ data.state }}, {{ data.zipCode }}, {{\r\n data.country }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-light d-flex align-items-center justify-content-between\">\r\n <span *ngIf=\"!basicDetailsSaved\" class=\"small text-warning fw-semibold\">\r\n <i class=\"bi bi-exclamation-circle me-1\"></i> 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 <i class=\"bi bi-check-circle me-1\"></i> 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-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 <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\"\r\n (ngModelChange)=\"tempProfile.phone = sanitizePhone($event)\" name=\"phone\" placeholder=\"Phone (10 digits)\"\r\n required pattern=\"^\\d{10}$\" maxlength=\"10\" 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-3\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.address\" name=\"address\"\r\n placeholder=\"Home Address\" required #address=\"ngModel\">\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-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\" [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n name=\"yearsOfExperience\" placeholder=\"Years of Experience\" required min=\"0\"\r\n #yearsOfExperience=\"ngModel\">\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"yearsOfExperience.invalid && (yearsOfExperience.dirty || yearsOfExperience.touched)\">\r\n Years of experience is required\r\n </div>\r\n </div>\r\n\r\n\r\n </form>\r\n </div>\r\n <div class=\"card-footer bg-light 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\" (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\" *ngIf=\"roleData.role.name == 'Provider'\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 <!-- Company Details Display Mode -->\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 || 'Not provided' }}</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 || 'Not provided' }}</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 || 'Not provided' }}, {{ companyDetails()?.city || 'Not provided' }}, {{ companyDetails()?.state || 'Not provided' }}, {{ companyDetails()?.zipcode || 'Not provided' }}, {{ companyDetails()?.country || 'Not provided' }}</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 <!-- Company Details Edit Mode -->\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 type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted }\"\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>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Address <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.address1?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.address1\" name=\"address1\" required />\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=\"image/*\" (change)=\"uploadCompanyImage($event)\" class=\"form-control\" />\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 bg-light 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 mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 <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 *ngIf=\"experience().length === 0 && !isAddingJob()\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">No work experience added</div>\r\n </div>\r\n <div class=\"list-group list-group-flush shadow-sm rounded\">\r\n <div *ngIf=\"isAddingJob() && tempJob()\" class=\"list-group-item p-3\">\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 <!-- (ngModelChange)=\"setTempJobIsCurrent($event)\" -->\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\" name=\"newIsCurrent\"\r\n 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\">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-4\">\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-4\">\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]=\"maxDate\"\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 <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=\"card-footer bg-light text-end 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\r\n\r\n <div *ngFor=\"let job of experience(); let i = index\" class=\"list-group-item p-3\">\r\n\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 <i class=\"bi bi-briefcase text-primary me-3 fs-4\"></i>\r\n <div>\r\n <h6 class=\"mb-0 fw-bold\">{{ job.jobTitle }}</h6>\r\n <span class=\"badge border mt-1\"\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 <small class=\"text-muted\">\r\n {{ job.company }} \u2022 {{ formatMonthYear(job.startDate) }} - {{ job.isCurrent ? 'Present' :\r\n formatMonthYear(job.endDate) }}\r\n </small>\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\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-sm btn-light p-0\"\r\n style=\"width: 34px; height: 34px;\"\r\n (click)=\"toggleJob(i)\"\r\n title=\"Expand\"\r\n >\r\n <i class=\"bi cursor-pointer\" [ngClass]=\"expandedIndex() === i ? 'bi-chevron-up' : 'bi-chevron-down'\"></i>\r\n </button> -->\r\n </div>\r\n </div>\r\n\r\n\r\n\r\n <div class=\"mt-3 bg-light 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 <!-- (ngModelChange)=\"setTempJobIsCurrent($event)\" -->\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n 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\">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-4\">\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-4\">\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]=\"maxDate\"\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 <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=\"card-footer bg-light text-end\" *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\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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 || 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=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">No certification added</div>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded border\">\r\n <div *ngIf=\"isAddingCertification() && tempCertification()\" class=\"list-group-item py-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">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\">Issuing Organization</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\">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]=\"maxDate\"\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 <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\">\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=\"fw-semibold\">{{ cert.name }}</div>\r\n <span class=\"badge border mt-1\"\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 *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 class=\"small text-muted\">\r\n {{ cert.issuingOrganization || '\u2014' }}\r\n <span *ngIf=\"cert.state\"> \u2022 {{ cert.state }}</span>\r\n </div>\r\n <div class=\"small text-muted\">\r\n Issue: {{ cert.issueDate ? formatMonthYear(cert.issueDate) : '\u2014' }}\r\n <span class=\"mx-1\">|</span>\r\n Expiry: {{ cert.expiryDate ? formatMonthYear(cert.expiryDate) : '\u2014' }}\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\">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\">Issuing Organization</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\">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]=\"maxDate\"\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 <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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 || 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=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">No license added</div>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded border\">\r\n <div *ngIf=\"isAddingLicense() && tempLicense()\" class=\"list-group-item py-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">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\">Issuing Authority</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\">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]=\"maxDate\"\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 <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\">\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=\"fw-semibold\">{{ lic.name }}</div>\r\n <span class=\"badge border mt-1\"\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 *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 class=\"small text-muted\">\r\n {{ lic.issuingAuthority || '\u2014' }}\r\n <span *ngIf=\"lic.state\"> \u2022 {{ lic.state }}</span>\r\n </div>\r\n <div class=\"small text-muted\">\r\n Issue: {{ lic.issueDate ? formatMonthYear(lic.issueDate) : '\u2014' }}\r\n <span class=\"mx-1\">|</span>\r\n Expiry: {{ lic.expiryDate ? formatMonthYear(lic.expiryDate) : '\u2014' }}\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\">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\">Issuing Authority</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\">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]=\"maxDate\"\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 <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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 || 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 rounded-pill 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 text-dark\">{{ 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 <!-- Tool edit panel (overlay) -->\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: 2000;\" (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 <i class=\"bi bi-arrow-left fs-5\"></i>\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;\" />\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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 || 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 rounded-pill 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 text-dark\">{{ 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 <!-- Skill edit panel (overlay) -->\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: 2000;\" (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 <i class=\"bi bi-arrow-left fs-5\"></i>\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;\" />\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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 <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\r\n <div *ngIf=\"educationList().length === 0 && !isAddingEducation() && editingEducationIndex() === null\"\r\n class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">No education added</div>\r\n <!-- <div class=\"small\">Add at least one education.</div> -->\r\n </div>\r\n\r\n <div *ngIf=\"isAddingEducation() && tempEducation()\" class=\"p-3 bg-white border rounded shadow-sm 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\">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-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]=\"maxDate\"\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 <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\r\n <div *ngFor=\"let edu of educationList(); let ei = index\" class=\"p-3 bg-white border rounded shadow-sm mb-2\">\r\n <div class=\"d-flex justify-content-between align-items-start\">\r\n <div>\r\n <h6 class=\"fw-bold mb-1\">{{ edu.degree }}</h6>\r\n <span class=\"badge border mt-1\"\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 <p class=\"small text-primary mb-0\">{{ edu.institution }}</p>\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 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-6\">\r\n <label class=\"small text-muted d-block\">City</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>\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]=\"maxDate\"\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 <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 class=\"d-flex gap-2 justify-content-center mt-5\" *ngIf=\"!isResume\">\r\n <button class=\"btn btn-outline-secondary px-5 h-auto\" (click)=\"onBackClick()\">Back</button>\r\n <button class=\"btn btn-primary px-5 shadow h-auto\" [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 </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=\"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>", styles: [".container{max-width:900px;margin:30px auto;font-family:Arial,sans-serif;color:#333}.preview-page-header{max-width:900px;margin:50px auto 10px;padding:0 12px}.preview-title{font-weight:600;margin:0}.preview-subtitle{margin-top:7px;font-size:16px}.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:10px;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:.95rem}.extra-small{font-size:.8rem}.card{transition:transform .2s ease,box-shadow .2s ease}.card:hover{transform:translateY(-3px);box-shadow:0 .5rem 1rem #0000001a!important}.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);box-shadow:0 4px 8px #0000001a}.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{box-shadow:0 10px 20px #0000001a!important}.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);box-shadow:-5px 0 15px #0000000d}.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;box-shadow:0 10px 15px #0000001a!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;background:#fff;border-radius:10px;padding:16px;box-shadow:0 4px 12px #0003}.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:10px}button.btn.btn-sm.btn-outline-primary:hover{background-color:#356895;border-color:#356895;color:#fff}button.btn.btn-sm.btn-outline-danger{border-color:#dc3545;color:#dc3545;border-radius:10px}button.btn.btn-sm.btn-outline-danger:hover{background-color:#bb2d3b;border-color:#bb2d3b;color:#fff}button.btn.btn-sm.btn-outline-primary.rounded-circle{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:50%!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:0!important;background:transparent!important;border:none!important;box-shadow: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;box-shadow:0 20px 40px #0f172a40;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-weight:600;color:#1f2937}.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:14px;box-shadow:0 20px 35px #0f172a38;border:1px solid #e5e7eb;padding:24px}.year-experience-select{max-height:150px}@media screen and (max-width: 768px){.res-flex{display:unset!important}.res-flex .fw-normal{width:100%;display:block;font-size:13px!important}}::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}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i11.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i11.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i11.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ModalModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i8.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i8.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: i8.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i8.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i8.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i8.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i8.EmailValidator, selector: "[email][formControlName],[email][formControl],[email][ngModel]", inputs: ["email"] }, { kind: "directive", type: i8.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i8.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i8.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: i12$1.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: i12$1.BsDatepickerInputDirective, selector: "input[bsDatepicker]" }] });
|
|
4902
|
+
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" }, outputs: { backToParent: "backToParent" }, viewQueries: [{ propertyName: "companyForm", first: true, predicate: ["companyForm"], descendants: true }], ngImport: i0, template: "<div class=\"preview-page-header\" *ngIf=\"!isResume\">\r\n <h2 class=\"preview-title\">Review Extracted Information</h2>\r\n <p class=\"preview-subtitle\">We\u2019ve automatically extracted details from your uploaded resume. Please review and confirm\r\n accuracy.</p>\r\n</div>\r\n\r\n\r\n<div [ngClass]=\"isResume ? '' : 'container py-4'\">\r\n <div class=\"section mb-5\">\r\n <div *ngIf=\"details() as data; else loading\">\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"!isEditMode()\">\r\n <div class=\"card-body p-4\">\r\n <div class=\"d-flex justify-content-between align-items-start mb-4\">\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 <span class=\"badge bg-primary-subtle text-primary border p-2\">Email Verified</span>\r\n </div>\r\n\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 <label class=\"small text-muted d-block\">EMAIL</label>\r\n <span class=\"fw-bold small\">{{ data.email }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">PHONE</label>\r\n <span class=\"fw-bold small\">{{ data.phone }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">LOCATION</label>\r\n <span class=\"small\">{{ data.address }}, {{ data.city }}, {{ data.state }}, {{ data.zipCode }}, {{\r\n data.country }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-light d-flex align-items-center justify-content-between\">\r\n <span *ngIf=\"!basicDetailsSaved\" class=\"small text-warning fw-semibold\">\r\n <i class=\"bi bi-exclamation-circle me-1\"></i> 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 <i class=\"bi bi-check-circle me-1\"></i> 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-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 <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{10}$\" 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 </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 <input ngx-google-places-autocomplete [options]=\"options\" type=\"text\" class=\"form-control\" (onAddressChange)=\"AddressChangeUser($event)\" [(ngModel)]=\"tempProfile.address\" name=\"address\"\r\n placeholder=\"Home Address\" required #address=\"ngModel\">\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-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\" [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n name=\"yearsOfExperience\" placeholder=\"Years of Experience\" required min=\"0\"\r\n #yearsOfExperience=\"ngModel\">\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"yearsOfExperience.invalid && (yearsOfExperience.dirty || yearsOfExperience.touched)\">\r\n Years of experience is required\r\n </div>\r\n </div>\r\n\r\n\r\n </form>\r\n </div>\r\n <div class=\"card-footer bg-light 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\" (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\" *ngIf=\"roleData.role.name == 'Provider'\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 <!-- Company Details Display Mode -->\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 <!-- Company Details Edit Mode -->\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': !tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted }\"\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>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Address <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" ngx-google-places-autocomplete class=\"form-control form-control-sm\" (onAddressChange)=\"AddressChangeCompany($event)\"\r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.address1?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.address1\" name=\"address1\" required />\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=\"image/*\" (change)=\"uploadCompanyImage($event)\" class=\"form-control\" />\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 bg-light 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 mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 <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 *ngIf=\"experience().length === 0 && !isAddingJob()\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">No work experience added</div>\r\n </div>\r\n <div class=\"list-group list-group-flush shadow-sm rounded\">\r\n <div *ngIf=\"isAddingJob() && tempJob()\" class=\"list-group-item p-3\">\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 <!-- (ngModelChange)=\"setTempJobIsCurrent($event)\" -->\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\" name=\"newIsCurrent\"\r\n 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\">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-4\">\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-4\">\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 <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=\"card-footer bg-light text-end 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\r\n\r\n <div *ngFor=\"let job of experience(); let i = index\" class=\"list-group-item p-3\">\r\n\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 <i class=\"bi bi-briefcase text-primary me-3 fs-4\"></i>\r\n <div>\r\n <h6 class=\"mb-0 fw-bold\">{{ job.jobTitle }}</h6>\r\n <span class=\"badge border mt-1\"\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 <small class=\"text-muted\">\r\n {{ job.company }} \u2022 {{ formatMonthYear(job.startDate) }} - {{ job.isCurrent ? 'Present' :\r\n formatMonthYear(job.endDate) }}\r\n </small>\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\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-sm btn-light p-0\"\r\n style=\"width: 34px; height: 34px;\"\r\n (click)=\"toggleJob(i)\"\r\n title=\"Expand\"\r\n >\r\n <i class=\"bi cursor-pointer\" [ngClass]=\"expandedIndex() === i ? 'bi-chevron-up' : 'bi-chevron-down'\"></i>\r\n </button> -->\r\n </div>\r\n </div>\r\n\r\n\r\n\r\n <div class=\"mt-3 bg-light 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 <!-- (ngModelChange)=\"setTempJobIsCurrent($event)\" -->\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n 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\">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-4\">\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-4\">\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 <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=\"card-footer bg-light text-end\" *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\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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 || 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=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">No certification added</div>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded border\">\r\n <div *ngIf=\"isAddingCertification() && tempCertification()\" class=\"list-group-item py-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">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\">Issuing Organization</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\">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 <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\">\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=\"fw-semibold\">{{ cert.name }}</div>\r\n <span class=\"badge border mt-1\"\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 *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 class=\"small text-muted\">\r\n {{ cert.issuingOrganization || '\u2014' }}\r\n <span *ngIf=\"cert.state\"> \u2022 {{ cert.state }}</span>\r\n </div>\r\n <div class=\"small text-muted\">\r\n Issue: {{ cert.issueDate ? formatMonthYear(cert.issueDate) : '\u2014' }}\r\n <span class=\"mx-1\">|</span>\r\n Expiry: {{ cert.expiryDate ? formatMonthYear(cert.expiryDate) : '\u2014' }}\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\">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\">Issuing Organization</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\">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 <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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 || 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=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">No license added</div>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded border\">\r\n <div *ngIf=\"isAddingLicense() && tempLicense()\" class=\"list-group-item py-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">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\">Issuing Authority</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\">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 <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\">\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=\"fw-semibold\">{{ lic.name }}</div>\r\n <span class=\"badge border mt-1\"\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 *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 class=\"small text-muted\">\r\n {{ lic.issuingAuthority || '\u2014' }}\r\n <span *ngIf=\"lic.state\"> \u2022 {{ lic.state }}</span>\r\n </div>\r\n <div class=\"small text-muted\">\r\n Issue: {{ lic.issueDate ? formatMonthYear(lic.issueDate) : '\u2014' }}\r\n <span class=\"mx-1\">|</span>\r\n Expiry: {{ lic.expiryDate ? formatMonthYear(lic.expiryDate) : '\u2014' }}\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\">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\">Issuing Authority</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\">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 <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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 || 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 rounded-pill 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 text-dark\">{{ 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 <!-- Tool edit panel (overlay) -->\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: 2000;\" (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 <i class=\"bi bi-arrow-left fs-5\"></i>\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;\" />\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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 || 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 rounded-pill 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 text-dark\">{{ 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 <!-- Skill edit panel (overlay) -->\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: 2000;\" (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 <i class=\"bi bi-arrow-left fs-5\"></i>\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;\" />\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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 <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\r\n <div *ngIf=\"educationList().length === 0 && !isAddingEducation() && editingEducationIndex() === null\"\r\n class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">No education added</div>\r\n <!-- <div class=\"small\">Add at least one education.</div> -->\r\n </div>\r\n\r\n <div *ngIf=\"isAddingEducation() && tempEducation()\" class=\"p-3 bg-white border rounded shadow-sm 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\">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-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 <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\r\n <div *ngFor=\"let edu of educationList(); let ei = index\" class=\"p-3 bg-white border rounded shadow-sm mb-2\">\r\n <div class=\"d-flex justify-content-between align-items-start\">\r\n <div>\r\n <h6 class=\"fw-bold mb-1\">{{ edu.degree }}</h6>\r\n <span class=\"badge border mt-1\"\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 <p class=\"small text-primary mb-0\">{{ edu.institution }}</p>\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 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-6\">\r\n <label class=\"small text-muted d-block\">City</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>\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 <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 class=\"d-flex gap-2 justify-content-center mt-5\" *ngIf=\"!isResume\">\r\n <button class=\"btn btn-outline-secondary px-5 h-auto\" (click)=\"onBackClick()\">Back</button>\r\n <button class=\"btn btn-primary px-5 shadow h-auto\" [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 </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=\"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>", styles: [".container{max-width:900px;margin:30px auto;font-family:Arial,sans-serif;color:#333}.preview-page-header{max-width:900px;margin:50px auto 10px;padding:0 12px}.preview-title{font-weight:600;margin:0}.preview-subtitle{margin-top:7px;font-size:16px}.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:10px;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:.95rem}.extra-small{font-size:.8rem}.card{transition:transform .2s ease,box-shadow .2s ease}.card:hover{transform:translateY(-3px);box-shadow:0 .5rem 1rem #0000001a!important}.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);box-shadow:0 4px 8px #0000001a}.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{box-shadow:0 10px 20px #0000001a!important}.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);box-shadow:-5px 0 15px #0000000d}.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;box-shadow:0 10px 15px #0000001a!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;background:#fff;border-radius:10px;padding:16px;box-shadow:0 4px 12px #0003}.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:10px}button.btn.btn-sm.btn-outline-primary:hover{background-color:#356895;border-color:#356895;color:#fff}button.btn.btn-sm.btn-outline-danger{border-color:#dc3545;color:#dc3545;border-radius:10px}button.btn.btn-sm.btn-outline-danger:hover{background-color:#bb2d3b;border-color:#bb2d3b;color:#fff}button.btn.btn-sm.btn-outline-primary.rounded-circle{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:50%!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:0!important;background:transparent!important;border:none!important;box-shadow: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;box-shadow:0 20px 40px #0f172a40;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-weight:600;color:#1f2937}.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:14px;box-shadow:0 20px 35px #0f172a38;border:1px solid #e5e7eb;padding:24px}.year-experience-select{max-height:150px}@media screen and (max-width: 768px){.res-flex{display:unset!important}.res-flex .fw-normal{width:100%;display:block;font-size:13px!important}}::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}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i11.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i11.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i11.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ModalModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i8.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i8.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: i8.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i8.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i8.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i8.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i8.EmailValidator, selector: "[email][formControlName],[email][formControl],[email][ngModel]", inputs: ["email"] }, { kind: "directive", type: i8.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i8.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i8.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: i12$1.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: i12$1.BsDatepickerInputDirective, selector: "input[bsDatepicker]" }] });
|
|
4780
4903
|
}
|
|
4781
4904
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PreviewComponent, decorators: [{
|
|
4782
4905
|
type: Component,
|
|
4783
4906
|
args: [{ selector: 'app-preview', standalone: true, imports: [
|
|
4784
4907
|
CommonModule, ModalModule, FormsModule, ReactiveFormsModule,
|
|
4785
4908
|
NgSelectModule, NgxStarsModule, BsDatepickerModule
|
|
4786
|
-
], template: "<div class=\"preview-page-header\" *ngIf=\"!isResume\">\r\n <h2 class=\"preview-title\">Review Extracted Information</h2>\r\n <p class=\"preview-subtitle\">We\u2019ve automatically extracted details from your uploaded resume. Please review and confirm\r\n accuracy.</p>\r\n</div>\r\n\r\n\r\n<div [ngClass]=\"isResume ? '' : 'container py-4'\">\r\n <div class=\"section mb-5\">\r\n <div *ngIf=\"details() as data; else loading\">\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"!isEditMode()\">\r\n <div class=\"card-body p-4\">\r\n <div class=\"d-flex justify-content-between align-items-start mb-4\">\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 <span class=\"badge bg-primary-subtle text-primary border p-2\">ID: Verified</span>\r\n </div>\r\n\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 <label class=\"small text-muted d-block\">EMAIL</label>\r\n <span class=\"fw-bold small\">{{ data.email }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">PHONE</label>\r\n <span class=\"fw-bold small\">{{ data.phone }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">LOCATION</label>\r\n <span class=\"small\">{{ data.address }}, {{ data.city }}, {{ data.state }}, {{ data.zipCode }}, {{\r\n data.country }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-light d-flex align-items-center justify-content-between\">\r\n <span *ngIf=\"!basicDetailsSaved\" class=\"small text-warning fw-semibold\">\r\n <i class=\"bi bi-exclamation-circle me-1\"></i> 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 <i class=\"bi bi-check-circle me-1\"></i> 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-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 <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\"\r\n (ngModelChange)=\"tempProfile.phone = sanitizePhone($event)\" name=\"phone\" placeholder=\"Phone (10 digits)\"\r\n required pattern=\"^\\d{10}$\" maxlength=\"10\" 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-3\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.address\" name=\"address\"\r\n placeholder=\"Home Address\" required #address=\"ngModel\">\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-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\" [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n name=\"yearsOfExperience\" placeholder=\"Years of Experience\" required min=\"0\"\r\n #yearsOfExperience=\"ngModel\">\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"yearsOfExperience.invalid && (yearsOfExperience.dirty || yearsOfExperience.touched)\">\r\n Years of experience is required\r\n </div>\r\n </div>\r\n\r\n\r\n </form>\r\n </div>\r\n <div class=\"card-footer bg-light 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\" (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\" *ngIf=\"roleData.role.name == 'Provider'\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 <!-- Company Details Display Mode -->\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 || 'Not provided' }}</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 || 'Not provided' }}</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 || 'Not provided' }}, {{ companyDetails()?.city || 'Not provided' }}, {{ companyDetails()?.state || 'Not provided' }}, {{ companyDetails()?.zipcode || 'Not provided' }}, {{ companyDetails()?.country || 'Not provided' }}</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 <!-- Company Details Edit Mode -->\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 type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted }\"\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>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Address <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.address1?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.address1\" name=\"address1\" required />\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=\"image/*\" (change)=\"uploadCompanyImage($event)\" class=\"form-control\" />\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 bg-light 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 mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 <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 *ngIf=\"experience().length === 0 && !isAddingJob()\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">No work experience added</div>\r\n </div>\r\n <div class=\"list-group list-group-flush shadow-sm rounded\">\r\n <div *ngIf=\"isAddingJob() && tempJob()\" class=\"list-group-item p-3\">\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 <!-- (ngModelChange)=\"setTempJobIsCurrent($event)\" -->\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\" name=\"newIsCurrent\"\r\n 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\">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-4\">\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-4\">\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]=\"maxDate\"\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 <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=\"card-footer bg-light text-end 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\r\n\r\n <div *ngFor=\"let job of experience(); let i = index\" class=\"list-group-item p-3\">\r\n\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 <i class=\"bi bi-briefcase text-primary me-3 fs-4\"></i>\r\n <div>\r\n <h6 class=\"mb-0 fw-bold\">{{ job.jobTitle }}</h6>\r\n <span class=\"badge border mt-1\"\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 <small class=\"text-muted\">\r\n {{ job.company }} \u2022 {{ formatMonthYear(job.startDate) }} - {{ job.isCurrent ? 'Present' :\r\n formatMonthYear(job.endDate) }}\r\n </small>\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\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-sm btn-light p-0\"\r\n style=\"width: 34px; height: 34px;\"\r\n (click)=\"toggleJob(i)\"\r\n title=\"Expand\"\r\n >\r\n <i class=\"bi cursor-pointer\" [ngClass]=\"expandedIndex() === i ? 'bi-chevron-up' : 'bi-chevron-down'\"></i>\r\n </button> -->\r\n </div>\r\n </div>\r\n\r\n\r\n\r\n <div class=\"mt-3 bg-light 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 <!-- (ngModelChange)=\"setTempJobIsCurrent($event)\" -->\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n 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\">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-4\">\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-4\">\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]=\"maxDate\"\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 <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=\"card-footer bg-light text-end\" *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\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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 || 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=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">No certification added</div>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded border\">\r\n <div *ngIf=\"isAddingCertification() && tempCertification()\" class=\"list-group-item py-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">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\">Issuing Organization</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\">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]=\"maxDate\"\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 <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\">\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=\"fw-semibold\">{{ cert.name }}</div>\r\n <span class=\"badge border mt-1\"\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 *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 class=\"small text-muted\">\r\n {{ cert.issuingOrganization || '\u2014' }}\r\n <span *ngIf=\"cert.state\"> \u2022 {{ cert.state }}</span>\r\n </div>\r\n <div class=\"small text-muted\">\r\n Issue: {{ cert.issueDate ? formatMonthYear(cert.issueDate) : '\u2014' }}\r\n <span class=\"mx-1\">|</span>\r\n Expiry: {{ cert.expiryDate ? formatMonthYear(cert.expiryDate) : '\u2014' }}\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\">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\">Issuing Organization</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\">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]=\"maxDate\"\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 <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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 || 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=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">No license added</div>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded border\">\r\n <div *ngIf=\"isAddingLicense() && tempLicense()\" class=\"list-group-item py-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">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\">Issuing Authority</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\">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]=\"maxDate\"\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 <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\">\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=\"fw-semibold\">{{ lic.name }}</div>\r\n <span class=\"badge border mt-1\"\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 *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 class=\"small text-muted\">\r\n {{ lic.issuingAuthority || '\u2014' }}\r\n <span *ngIf=\"lic.state\"> \u2022 {{ lic.state }}</span>\r\n </div>\r\n <div class=\"small text-muted\">\r\n Issue: {{ lic.issueDate ? formatMonthYear(lic.issueDate) : '\u2014' }}\r\n <span class=\"mx-1\">|</span>\r\n Expiry: {{ lic.expiryDate ? formatMonthYear(lic.expiryDate) : '\u2014' }}\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\">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\">Issuing Authority</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\">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]=\"maxDate\"\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 <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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 || 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 rounded-pill 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 text-dark\">{{ 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 <!-- Tool edit panel (overlay) -->\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: 2000;\" (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 <i class=\"bi bi-arrow-left fs-5\"></i>\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;\" />\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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 || 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 rounded-pill 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 text-dark\">{{ 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 <!-- Skill edit panel (overlay) -->\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: 2000;\" (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 <i class=\"bi bi-arrow-left fs-5\"></i>\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;\" />\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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 <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\r\n <div *ngIf=\"educationList().length === 0 && !isAddingEducation() && editingEducationIndex() === null\"\r\n class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">No education added</div>\r\n <!-- <div class=\"small\">Add at least one education.</div> -->\r\n </div>\r\n\r\n <div *ngIf=\"isAddingEducation() && tempEducation()\" class=\"p-3 bg-white border rounded shadow-sm 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\">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-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]=\"maxDate\"\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 <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\r\n <div *ngFor=\"let edu of educationList(); let ei = index\" class=\"p-3 bg-white border rounded shadow-sm mb-2\">\r\n <div class=\"d-flex justify-content-between align-items-start\">\r\n <div>\r\n <h6 class=\"fw-bold mb-1\">{{ edu.degree }}</h6>\r\n <span class=\"badge border mt-1\"\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 <p class=\"small text-primary mb-0\">{{ edu.institution }}</p>\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 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-6\">\r\n <label class=\"small text-muted d-block\">City</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>\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]=\"maxDate\"\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 <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 class=\"d-flex gap-2 justify-content-center mt-5\" *ngIf=\"!isResume\">\r\n <button class=\"btn btn-outline-secondary px-5 h-auto\" (click)=\"onBackClick()\">Back</button>\r\n <button class=\"btn btn-primary px-5 shadow h-auto\" [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 </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=\"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>", styles: [".container{max-width:900px;margin:30px auto;font-family:Arial,sans-serif;color:#333}.preview-page-header{max-width:900px;margin:50px auto 10px;padding:0 12px}.preview-title{font-weight:600;margin:0}.preview-subtitle{margin-top:7px;font-size:16px}.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:10px;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:.95rem}.extra-small{font-size:.8rem}.card{transition:transform .2s ease,box-shadow .2s ease}.card:hover{transform:translateY(-3px);box-shadow:0 .5rem 1rem #0000001a!important}.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);box-shadow:0 4px 8px #0000001a}.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{box-shadow:0 10px 20px #0000001a!important}.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);box-shadow:-5px 0 15px #0000000d}.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;box-shadow:0 10px 15px #0000001a!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;background:#fff;border-radius:10px;padding:16px;box-shadow:0 4px 12px #0003}.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:10px}button.btn.btn-sm.btn-outline-primary:hover{background-color:#356895;border-color:#356895;color:#fff}button.btn.btn-sm.btn-outline-danger{border-color:#dc3545;color:#dc3545;border-radius:10px}button.btn.btn-sm.btn-outline-danger:hover{background-color:#bb2d3b;border-color:#bb2d3b;color:#fff}button.btn.btn-sm.btn-outline-primary.rounded-circle{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:50%!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:0!important;background:transparent!important;border:none!important;box-shadow: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;box-shadow:0 20px 40px #0f172a40;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-weight:600;color:#1f2937}.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:14px;box-shadow:0 20px 35px #0f172a38;border:1px solid #e5e7eb;padding:24px}.year-experience-select{max-height:150px}@media screen and (max-width: 768px){.res-flex{display:unset!important}.res-flex .fw-normal{width:100%;display:block;font-size:13px!important}}::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}\n"] }]
|
|
4909
|
+
], template: "<div class=\"preview-page-header\" *ngIf=\"!isResume\">\r\n <h2 class=\"preview-title\">Review Extracted Information</h2>\r\n <p class=\"preview-subtitle\">We\u2019ve automatically extracted details from your uploaded resume. Please review and confirm\r\n accuracy.</p>\r\n</div>\r\n\r\n\r\n<div [ngClass]=\"isResume ? '' : 'container py-4'\">\r\n <div class=\"section mb-5\">\r\n <div *ngIf=\"details() as data; else loading\">\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"!isEditMode()\">\r\n <div class=\"card-body p-4\">\r\n <div class=\"d-flex justify-content-between align-items-start mb-4\">\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 <span class=\"badge bg-primary-subtle text-primary border p-2\">Email Verified</span>\r\n </div>\r\n\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 <label class=\"small text-muted d-block\">EMAIL</label>\r\n <span class=\"fw-bold small\">{{ data.email }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">PHONE</label>\r\n <span class=\"fw-bold small\">{{ data.phone }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">LOCATION</label>\r\n <span class=\"small\">{{ data.address }}, {{ data.city }}, {{ data.state }}, {{ data.zipCode }}, {{\r\n data.country }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-light d-flex align-items-center justify-content-between\">\r\n <span *ngIf=\"!basicDetailsSaved\" class=\"small text-warning fw-semibold\">\r\n <i class=\"bi bi-exclamation-circle me-1\"></i> 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 <i class=\"bi bi-check-circle me-1\"></i> 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-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 <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{10}$\" 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 </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 <input ngx-google-places-autocomplete [options]=\"options\" type=\"text\" class=\"form-control\" (onAddressChange)=\"AddressChangeUser($event)\" [(ngModel)]=\"tempProfile.address\" name=\"address\"\r\n placeholder=\"Home Address\" required #address=\"ngModel\">\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-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\" [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n name=\"yearsOfExperience\" placeholder=\"Years of Experience\" required min=\"0\"\r\n #yearsOfExperience=\"ngModel\">\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"yearsOfExperience.invalid && (yearsOfExperience.dirty || yearsOfExperience.touched)\">\r\n Years of experience is required\r\n </div>\r\n </div>\r\n\r\n\r\n </form>\r\n </div>\r\n <div class=\"card-footer bg-light 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\" (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\" *ngIf=\"roleData.role.name == 'Provider'\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 <!-- Company Details Display Mode -->\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 <!-- Company Details Edit Mode -->\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': !tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted }\"\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>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Address <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" ngx-google-places-autocomplete class=\"form-control form-control-sm\" (onAddressChange)=\"AddressChangeCompany($event)\"\r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.address1?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.address1\" name=\"address1\" required />\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=\"image/*\" (change)=\"uploadCompanyImage($event)\" class=\"form-control\" />\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 bg-light 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 mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 <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 *ngIf=\"experience().length === 0 && !isAddingJob()\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">No work experience added</div>\r\n </div>\r\n <div class=\"list-group list-group-flush shadow-sm rounded\">\r\n <div *ngIf=\"isAddingJob() && tempJob()\" class=\"list-group-item p-3\">\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 <!-- (ngModelChange)=\"setTempJobIsCurrent($event)\" -->\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\" name=\"newIsCurrent\"\r\n 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\">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-4\">\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-4\">\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 <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=\"card-footer bg-light text-end 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\r\n\r\n <div *ngFor=\"let job of experience(); let i = index\" class=\"list-group-item p-3\">\r\n\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 <i class=\"bi bi-briefcase text-primary me-3 fs-4\"></i>\r\n <div>\r\n <h6 class=\"mb-0 fw-bold\">{{ job.jobTitle }}</h6>\r\n <span class=\"badge border mt-1\"\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 <small class=\"text-muted\">\r\n {{ job.company }} \u2022 {{ formatMonthYear(job.startDate) }} - {{ job.isCurrent ? 'Present' :\r\n formatMonthYear(job.endDate) }}\r\n </small>\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\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-sm btn-light p-0\"\r\n style=\"width: 34px; height: 34px;\"\r\n (click)=\"toggleJob(i)\"\r\n title=\"Expand\"\r\n >\r\n <i class=\"bi cursor-pointer\" [ngClass]=\"expandedIndex() === i ? 'bi-chevron-up' : 'bi-chevron-down'\"></i>\r\n </button> -->\r\n </div>\r\n </div>\r\n\r\n\r\n\r\n <div class=\"mt-3 bg-light 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 <!-- (ngModelChange)=\"setTempJobIsCurrent($event)\" -->\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n 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\">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-4\">\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-4\">\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 <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=\"card-footer bg-light text-end\" *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\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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 || 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=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">No certification added</div>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded border\">\r\n <div *ngIf=\"isAddingCertification() && tempCertification()\" class=\"list-group-item py-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">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\">Issuing Organization</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\">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 <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\">\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=\"fw-semibold\">{{ cert.name }}</div>\r\n <span class=\"badge border mt-1\"\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 *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 class=\"small text-muted\">\r\n {{ cert.issuingOrganization || '\u2014' }}\r\n <span *ngIf=\"cert.state\"> \u2022 {{ cert.state }}</span>\r\n </div>\r\n <div class=\"small text-muted\">\r\n Issue: {{ cert.issueDate ? formatMonthYear(cert.issueDate) : '\u2014' }}\r\n <span class=\"mx-1\">|</span>\r\n Expiry: {{ cert.expiryDate ? formatMonthYear(cert.expiryDate) : '\u2014' }}\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\">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\">Issuing Organization</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\">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 <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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 || 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=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">No license added</div>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded border\">\r\n <div *ngIf=\"isAddingLicense() && tempLicense()\" class=\"list-group-item py-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">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\">Issuing Authority</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\">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 <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\">\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=\"fw-semibold\">{{ lic.name }}</div>\r\n <span class=\"badge border mt-1\"\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 *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 class=\"small text-muted\">\r\n {{ lic.issuingAuthority || '\u2014' }}\r\n <span *ngIf=\"lic.state\"> \u2022 {{ lic.state }}</span>\r\n </div>\r\n <div class=\"small text-muted\">\r\n Issue: {{ lic.issueDate ? formatMonthYear(lic.issueDate) : '\u2014' }}\r\n <span class=\"mx-1\">|</span>\r\n Expiry: {{ lic.expiryDate ? formatMonthYear(lic.expiryDate) : '\u2014' }}\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\">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\">Issuing Authority</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\">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 <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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 || 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 rounded-pill 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 text-dark\">{{ 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 <!-- Tool edit panel (overlay) -->\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: 2000;\" (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 <i class=\"bi bi-arrow-left fs-5\"></i>\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;\" />\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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 || 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 rounded-pill 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 text-dark\">{{ 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 <!-- Skill edit panel (overlay) -->\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: 2000;\" (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 <i class=\"bi bi-arrow-left fs-5\"></i>\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;\" />\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\">\r\n <div class=\"d-flex align-items-center gap-2\">\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 <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\r\n <div *ngIf=\"educationList().length === 0 && !isAddingEducation() && editingEducationIndex() === null\"\r\n class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">No education added</div>\r\n <!-- <div class=\"small\">Add at least one education.</div> -->\r\n </div>\r\n\r\n <div *ngIf=\"isAddingEducation() && tempEducation()\" class=\"p-3 bg-white border rounded shadow-sm 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\">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-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 <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\r\n <div *ngFor=\"let edu of educationList(); let ei = index\" class=\"p-3 bg-white border rounded shadow-sm mb-2\">\r\n <div class=\"d-flex justify-content-between align-items-start\">\r\n <div>\r\n <h6 class=\"fw-bold mb-1\">{{ edu.degree }}</h6>\r\n <span class=\"badge border mt-1\"\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 <p class=\"small text-primary mb-0\">{{ edu.institution }}</p>\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 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-6\">\r\n <label class=\"small text-muted d-block\">City</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>\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 <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 class=\"d-flex gap-2 justify-content-center mt-5\" *ngIf=\"!isResume\">\r\n <button class=\"btn btn-outline-secondary px-5 h-auto\" (click)=\"onBackClick()\">Back</button>\r\n <button class=\"btn btn-primary px-5 shadow h-auto\" [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 </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=\"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>", styles: [".container{max-width:900px;margin:30px auto;font-family:Arial,sans-serif;color:#333}.preview-page-header{max-width:900px;margin:50px auto 10px;padding:0 12px}.preview-title{font-weight:600;margin:0}.preview-subtitle{margin-top:7px;font-size:16px}.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:10px;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:.95rem}.extra-small{font-size:.8rem}.card{transition:transform .2s ease,box-shadow .2s ease}.card:hover{transform:translateY(-3px);box-shadow:0 .5rem 1rem #0000001a!important}.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);box-shadow:0 4px 8px #0000001a}.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{box-shadow:0 10px 20px #0000001a!important}.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);box-shadow:-5px 0 15px #0000000d}.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;box-shadow:0 10px 15px #0000001a!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;background:#fff;border-radius:10px;padding:16px;box-shadow:0 4px 12px #0003}.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:10px}button.btn.btn-sm.btn-outline-primary:hover{background-color:#356895;border-color:#356895;color:#fff}button.btn.btn-sm.btn-outline-danger{border-color:#dc3545;color:#dc3545;border-radius:10px}button.btn.btn-sm.btn-outline-danger:hover{background-color:#bb2d3b;border-color:#bb2d3b;color:#fff}button.btn.btn-sm.btn-outline-primary.rounded-circle{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:50%!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:0!important;background:transparent!important;border:none!important;box-shadow: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;box-shadow:0 20px 40px #0f172a40;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-weight:600;color:#1f2937}.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:14px;box-shadow:0 20px 35px #0f172a38;border:1px solid #e5e7eb;padding:24px}.year-experience-select{max-height:150px}@media screen and (max-width: 768px){.res-flex{display:unset!important}.res-flex .fw-normal{width:100%;display:block;font-size:13px!important}}::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}\n"] }]
|
|
4787
4910
|
}], ctorParameters: () => [{ type: CredentialingStore }, { type: FileService }, { type: UserSkillSetService }, { type: UserToolService }, { type: UserDocumentService }, { type: UserEducationService }, { type: UserDetailService }, { type: UserExperienceService }, { type: i1$1.TokenService }, { type: i1$1.RoleContextService }, { type: ProvidersService }, { type: undefined, decorators: [{
|
|
4788
4911
|
type: Inject,
|
|
4789
4912
|
args: [LIBRARY_CONFIG]
|