@idsoftsource/initial-process 1.4.6 → 1.4.9
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.
|
@@ -29142,7 +29142,7 @@ class FirstComponent {
|
|
|
29142
29142
|
resumeName;
|
|
29143
29143
|
fileDataUser;
|
|
29144
29144
|
model = { fileId: null, fileUrl: null, fileName: null };
|
|
29145
|
-
nextStep = new EventEmitter();
|
|
29145
|
+
nextStep = new EventEmitter();
|
|
29146
29146
|
constructor(store, tokenService, resumedetail, fileService) {
|
|
29147
29147
|
this.store = store;
|
|
29148
29148
|
this.tokenService = tokenService;
|
|
@@ -29163,7 +29163,8 @@ class FirstComponent {
|
|
|
29163
29163
|
}
|
|
29164
29164
|
}
|
|
29165
29165
|
onFileSelected(event) {
|
|
29166
|
-
|
|
29166
|
+
const input = event.target;
|
|
29167
|
+
this.fileData = input.files?.[0];
|
|
29167
29168
|
if (this.fileData) {
|
|
29168
29169
|
this.resumeName = this.fileData.name;
|
|
29169
29170
|
this.model.fileName = this.resumeName;
|
|
@@ -29171,24 +29172,18 @@ class FirstComponent {
|
|
|
29171
29172
|
setTimeout(() => {
|
|
29172
29173
|
this.store.addSuccess(true);
|
|
29173
29174
|
this.saveAWSFile();
|
|
29174
|
-
// this.uploadresume()
|
|
29175
29175
|
}, 1500);
|
|
29176
29176
|
}
|
|
29177
|
+
// ✅ MUST ADD THIS LINE
|
|
29178
|
+
input.value = '';
|
|
29177
29179
|
}
|
|
29178
29180
|
openFile(fileInput, event) {
|
|
29179
29181
|
event.stopPropagation();
|
|
29180
|
-
|
|
29181
|
-
fileInput.click();
|
|
29182
|
-
}
|
|
29183
|
-
// this.saveAWSFile();
|
|
29182
|
+
fileInput.click();
|
|
29184
29183
|
}
|
|
29185
29184
|
handleAutoNavigation() {
|
|
29186
29185
|
this.store.nextStep();
|
|
29187
29186
|
}
|
|
29188
|
-
// uploadresume() {
|
|
29189
|
-
// this.store.setProfile(this.sample)
|
|
29190
|
-
// this.handleAutoNavigation();
|
|
29191
|
-
// }
|
|
29192
29187
|
manual() {
|
|
29193
29188
|
this.store.addSuccess(false);
|
|
29194
29189
|
this.store.nextStep();
|
|
@@ -29238,6 +29233,9 @@ class FirstComponent {
|
|
|
29238
29233
|
next: (res) => {
|
|
29239
29234
|
if (res?.failed) {
|
|
29240
29235
|
this.isUploading = false;
|
|
29236
|
+
this.resumeName = null; // ✅ RESET
|
|
29237
|
+
this.fileData = null; // ✅ RESET
|
|
29238
|
+
this.model = { fileId: null, fileUrl: null, fileName: null }; // ✅ RESET
|
|
29241
29239
|
return;
|
|
29242
29240
|
}
|
|
29243
29241
|
this.handleAutoNavigation();
|
|
@@ -29249,8 +29247,9 @@ class FirstComponent {
|
|
|
29249
29247
|
},
|
|
29250
29248
|
error: (err) => {
|
|
29251
29249
|
console.error('Upload failed:', err);
|
|
29252
|
-
// 🔥 IMPORTANT: handle 504 or any error
|
|
29253
29250
|
this.isUploading = false;
|
|
29251
|
+
this.resumeName = null; // ✅ RESET
|
|
29252
|
+
this.fileData = null; // ✅ RESET
|
|
29254
29253
|
}
|
|
29255
29254
|
});
|
|
29256
29255
|
}
|
|
@@ -29258,11 +29257,11 @@ class FirstComponent {
|
|
|
29258
29257
|
this.backToParent.emit();
|
|
29259
29258
|
}
|
|
29260
29259
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FirstComponent, deps: [{ token: CredentialingStore }, { token: i6.TokenService }, { token: ResumeDetailService }, { token: FileService }], target: i0.ɵɵFactoryTarget.Component });
|
|
29261
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: FirstComponent, isStandalone: false, selector: "app-first", outputs: { backToParent: "backToParent", nextStep: "nextStep" }, ngImport: i0, template: "<div class=\"wrapper position-relative\">\r\n\r\n <h2 class=\"title\">Upload your resume *</h2>\r\n <p class=\"subtitle\">Upload your resume and we\u2019ll fill the rest.</p>\r\n\r\n\r\n
|
|
29260
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: FirstComponent, isStandalone: false, selector: "app-first", outputs: { backToParent: "backToParent", nextStep: "nextStep" }, ngImport: i0, template: "<div class=\"wrapper position-relative\">\r\n\r\n <h2 class=\"title\">Upload your resume *</h2>\r\n <p class=\"subtitle\">Upload your resume and we\u2019ll fill the rest.</p>\r\n\r\n\r\n<div class=\"option-card\" (click)=\"openFile(fileInput, $event)\">\r\n\r\n <input\r\n #fileInput\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx\"\r\n (change)=\"onFileSelected($event)\"\r\n hidden\r\n />\r\n\r\n\r\n <div class=\"card-content\">\r\n <div class=\"left\">\r\n <img src=\"assets/images/icons/upload-resume.png\" style=\"width: 55px;\" alt=\"Upload\" />\r\n </div>\r\n\r\n <div class=\"right\">\r\n <h3>Upload my resume</h3>\r\n <p>We\u2019ll extract job titles, experience, and skills.</p>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n <label class=\"option-card\" (click)=\"manual()\">\r\n\r\n <div class=\"card-content\" (click)=\"manual()\">\r\n <div class=\"left\">\r\n <img src=\"assets/images/icons/technical-support.svg\" alt=\"Manual\" />\r\n </div>\r\n\r\n <div class=\"right\" (click)=\"manual()\">\r\n <h3>Enter manually</h3>\r\n <p>You will enter all information manually.</p>\r\n </div>\r\n </div>\r\n </label>\r\n\r\n <div *ngIf=\"isUploading\" class=\"overlay\">\r\n <div class=\"spinner-container\">\r\n <div class=\"spinner\"></div>\r\n <p>Processing your resume...</p>\r\n </div>\r\n </div>\r\n<div>\r\n <button class=\"back-btn\" (click)=\"onBackClick()\">Back</button>\r\n</div>\r\n</div>\r\n\r\n", styles: [".wrapper{max-width:600px;margin:50px auto;font-family:Arial,sans-serif}.subtitle{color:#6b7280;font-size:14px;margin-bottom:10px}.title{font-size:24px;font-weight:600;margin-bottom:30px}.option-card{display:block;border:1px solid #d1d5db;border-radius:10px;padding:20px;margin-bottom:20px;cursor:pointer;transition:all .2s ease;position:relative}.option-card input[type=radio]{position:absolute;left:15px;top:43px}.card-content{display:flex;gap:20px;margin-left:30px;align-items:flex-start}.left img{width:50px;opacity:.7}.right h3{margin:0;font-size:16px;font-weight:600}.right p{margin:5px 0 10px;color:#6b7280;font-size:14px}.file-display input{font-size:13px;cursor:pointer}.error-text{color:#dc2626;font-size:12px;margin-top:5px}.option-card:hover{border-color:#6366f1;background:#f9fafb}.option-card:has(input:checked){border:2px solid #6366f1;background:#eef2ff}.wrapper{position:relative}.overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:#fffc;z-index:100;display:flex;justify-content:center;align-items:center;pointer-events:all}.spinner{width:40px;height:40px;margin-left:60px;border:4px solid #ddd;border-top:4px solid #1165B8;border-radius:50%;animation:spin 1s linear infinite}.spinner-container{text-align:center}@keyframes spin{to{transform:rotate(360deg)}}.back-btn{font-size:20px;font-weight:500;width:100px;background:#d3dae6;color:#6c757dc7;border-radius:5px;border:none;padding:8px;cursor:pointer}@media screen and (max-width: 767px){.wrapper{position:relative;width:90%}.back-btn{width:100%}}\n"], dependencies: [{ kind: "directive", type: i11.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
29262
29261
|
}
|
|
29263
29262
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FirstComponent, decorators: [{
|
|
29264
29263
|
type: Component,
|
|
29265
|
-
args: [{ selector: 'app-first', standalone: false, template: "<div class=\"wrapper position-relative\">\r\n\r\n <h2 class=\"title\">Upload your resume *</h2>\r\n <p class=\"subtitle\">Upload your resume and we\u2019ll fill the rest.</p>\r\n\r\n\r\n
|
|
29264
|
+
args: [{ selector: 'app-first', standalone: false, template: "<div class=\"wrapper position-relative\">\r\n\r\n <h2 class=\"title\">Upload your resume *</h2>\r\n <p class=\"subtitle\">Upload your resume and we\u2019ll fill the rest.</p>\r\n\r\n\r\n<div class=\"option-card\" (click)=\"openFile(fileInput, $event)\">\r\n\r\n <input\r\n #fileInput\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx\"\r\n (change)=\"onFileSelected($event)\"\r\n hidden\r\n />\r\n\r\n\r\n <div class=\"card-content\">\r\n <div class=\"left\">\r\n <img src=\"assets/images/icons/upload-resume.png\" style=\"width: 55px;\" alt=\"Upload\" />\r\n </div>\r\n\r\n <div class=\"right\">\r\n <h3>Upload my resume</h3>\r\n <p>We\u2019ll extract job titles, experience, and skills.</p>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n <label class=\"option-card\" (click)=\"manual()\">\r\n\r\n <div class=\"card-content\" (click)=\"manual()\">\r\n <div class=\"left\">\r\n <img src=\"assets/images/icons/technical-support.svg\" alt=\"Manual\" />\r\n </div>\r\n\r\n <div class=\"right\" (click)=\"manual()\">\r\n <h3>Enter manually</h3>\r\n <p>You will enter all information manually.</p>\r\n </div>\r\n </div>\r\n </label>\r\n\r\n <div *ngIf=\"isUploading\" class=\"overlay\">\r\n <div class=\"spinner-container\">\r\n <div class=\"spinner\"></div>\r\n <p>Processing your resume...</p>\r\n </div>\r\n </div>\r\n<div>\r\n <button class=\"back-btn\" (click)=\"onBackClick()\">Back</button>\r\n</div>\r\n</div>\r\n\r\n", styles: [".wrapper{max-width:600px;margin:50px auto;font-family:Arial,sans-serif}.subtitle{color:#6b7280;font-size:14px;margin-bottom:10px}.title{font-size:24px;font-weight:600;margin-bottom:30px}.option-card{display:block;border:1px solid #d1d5db;border-radius:10px;padding:20px;margin-bottom:20px;cursor:pointer;transition:all .2s ease;position:relative}.option-card input[type=radio]{position:absolute;left:15px;top:43px}.card-content{display:flex;gap:20px;margin-left:30px;align-items:flex-start}.left img{width:50px;opacity:.7}.right h3{margin:0;font-size:16px;font-weight:600}.right p{margin:5px 0 10px;color:#6b7280;font-size:14px}.file-display input{font-size:13px;cursor:pointer}.error-text{color:#dc2626;font-size:12px;margin-top:5px}.option-card:hover{border-color:#6366f1;background:#f9fafb}.option-card:has(input:checked){border:2px solid #6366f1;background:#eef2ff}.wrapper{position:relative}.overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:#fffc;z-index:100;display:flex;justify-content:center;align-items:center;pointer-events:all}.spinner{width:40px;height:40px;margin-left:60px;border:4px solid #ddd;border-top:4px solid #1165B8;border-radius:50%;animation:spin 1s linear infinite}.spinner-container{text-align:center}@keyframes spin{to{transform:rotate(360deg)}}.back-btn{font-size:20px;font-weight:500;width:100px;background:#d3dae6;color:#6c757dc7;border-radius:5px;border:none;padding:8px;cursor:pointer}@media screen and (max-width: 767px){.wrapper{position:relative;width:90%}.back-btn{width:100%}}\n"] }]
|
|
29266
29265
|
}], ctorParameters: () => [{ type: CredentialingStore }, { type: i6.TokenService }, { type: ResumeDetailService }, { type: FileService }], propDecorators: { backToParent: [{
|
|
29267
29266
|
type: Output
|
|
29268
29267
|
}], nextStep: [{
|
|
@@ -30871,11 +30870,11 @@ class PreviewComponent {
|
|
|
30871
30870
|
return d.toISOString();
|
|
30872
30871
|
}
|
|
30873
30872
|
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: i6.TokenService }, { token: LIBRARY_CONFIG }], target: i0.ɵɵFactoryTarget.Component });
|
|
30874
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: PreviewComponent, isStandalone: false, selector: "app-preview", inputs: { providerId: "providerId", providerName: "providerName", roleData: "roleData", cloudfrontUrl: "cloudfrontUrl" }, outputs: { backToParent: "backToParent" }, ngImport: i0, template: "\r\n<div class=\"preview-page-header\">\r\n <h2 class=\"preview-title\">Confirm based on your resume</h2>\r\n <p class=\"preview-subtitle\">Please confirm everything is accurate. It is based on your resume</p>\r\n</div>\r\n\r\n\r\n<div class=\"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\">\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 </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 text-end\">\r\n <button class=\"btn btn-sm btn-primary px-4\" (click)=\"toggleEdit()\">Edit Details</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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.firstName\"\r\n name=\"fName\"\r\n placeholder=\"First Name\"\r\n required\r\n #fName=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"fName.invalid && (fName.dirty || fName.touched)\">First name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.lastName\"\r\n name=\"lName\"\r\n placeholder=\"Last Name\"\r\n required\r\n #lName=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"lName.invalid && (lName.dirty || lName.touched)\">Last name is 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\r\n type=\"email\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.email\"\r\n name=\"email\"\r\n placeholder=\"Email\"\r\n required\r\n email\r\n #email=\"ngModel\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"tempProfile.phone\"\r\n (ngModelChange)=\"tempProfile.phone = sanitizePhone($event)\"\r\n name=\"phone\"\r\n placeholder=\"Phone (10 digits)\"\r\n required\r\n pattern=\"^\\d{10}$\"\r\n maxlength=\"10\"\r\n inputmode=\"numeric\"\r\n #phone=\"ngModel\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.address\"\r\n name=\"address\"\r\n placeholder=\"Home Address\"\r\n required\r\n #address=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"address.invalid && (address.dirty || address.touched)\">Home address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.city\"\r\n name=\"city\"\r\n placeholder=\"City\"\r\n required\r\n #city=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"city.invalid && (city.dirty || city.touched)\">City is required</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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.state\"\r\n name=\"state\"\r\n placeholder=\"State\"\r\n required\r\n #state=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"state.invalid && (state.dirty || state.touched)\">State is 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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.zipCode\"\r\n name=\"zipCode\"\r\n placeholder=\"Zip Code\"\r\n required\r\n #zipCode=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"zipCode.invalid && (zipCode.dirty || zipCode.touched)\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.country\"\r\n name=\"country\"\r\n placeholder=\"Country\"\r\n required\r\n #country=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"country.invalid && (country.dirty || country.touched)\">Country 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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.jobTitle\"\r\n name=\"jobTitle\"\r\n placeholder=\"Job Title\"\r\n required\r\n #jobTitle=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"jobTitle.invalid && (jobTitle.dirty || jobTitle.touched)\">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\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"number\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n name=\"yearsOfExperience\"\r\n placeholder=\"Years of Experience\"\r\n required\r\n min=\"0\"\r\n #yearsOfExperience=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *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\" (click)=\"save()\">Save Changes</button>\r\n </div>\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=\"workSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add work experience\"\r\n (click)=\"addJob()\"\r\n >\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\">Missing required fields</div>\r\n <div class=\"small\">Add at least one work experience.</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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\"\r\n name=\"newJobTitle\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\"\r\n name=\"newCompany\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\"\r\n name=\"newCity\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.startDate\"\r\n (ngModelChange)=\"patchTempJob({ startDate: $event })\"\r\n name=\"newStartDate\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"tempJob()?.endDate\"\r\n (ngModelChange)=\"patchTempJob({ endDate: $event })\"\r\n name=\"newEndDate\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\" *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 <div class=\"col-md-4 d-flex align-items-end\">\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\"\r\n name=\"newIsCurrent\"\r\n id=\"newIsCurrent\"\r\n />\r\n <label class=\"form-check-label\" for=\"newIsCurrent\">Current</label>\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">RESPONSIBILITIES (one per line)</label>\r\n <textarea\r\n rows=\"4\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\"\r\n name=\"newResponsibilities\"\r\n ></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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\"\r\n name=\"newWorkAttachment\"\r\n />\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\" (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\" (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingWork\" (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : 'Save' }}\r\n </button>\r\n </div>\r\n </div>\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 <small class=\"text-muted\">\r\n {{ job.company }} \u2022 {{ formatMonthYear(job.startDate) }} - {{ job.isCurrent ? 'Present' : formatMonthYear(job.endDate) }}\r\n </small>\r\n <div\r\n *ngIf=\"editingJobIndex() !== i && (workIssuesByIndex()[i] || []).length > 0\"\r\n class=\"alert alert-warning py-1 px-2 mt-2\"\r\n >\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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditJob(i)\"\r\n title=\"Edit\"\r\n >\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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteJob(i);\"\r\n title=\"Delete\"\r\n >\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 <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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\"\r\n name=\"jobTitle{{ i }}\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\"\r\n name=\"company{{ i }}\"\r\n />\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=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">CITY <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\"\r\n name=\"city{{ i }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.startDate\"\r\n (ngModelChange)=\"patchTempJob({ startDate: $event })\"\r\n name=\"startDate{{ i }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"tempJob()?.endDate\"\r\n (ngModelChange)=\"patchTempJob({ endDate: $event })\"\r\n name=\"endDate{{ i }}\"\r\n />\r\n <div\r\n class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\"\r\n >\r\n End date is required\r\n </div>\r\n <div class=\"small text-danger mt-1\" *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-md-4 d-flex align-items-end\">\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\"\r\n name=\"isCurrent{{ i }}\"\r\n id=\"isCurrent{{ i }}\"\r\n />\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-12\">\r\n <label class=\"small text-muted d-block\">RESPONSIBILITIES (one per line)</label>\r\n <textarea\r\n rows=\"4\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\"\r\n name=\"responsibilities{{ i }}\"\r\n ></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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\"\r\n name=\"workAttachment{{ i }}\"\r\n />\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\" (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\" (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingWork\" (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : 'Save' }}\r\n </button>\r\n </div> \r\n\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\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=\"certificationsSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add certification\"\r\n (click)=\"addCertification()\"\r\n >\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n <div *ngIf=\"certs().length === 0 && !isAddingCertification() && editingCertificationIndex() === null\" 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\">Add at least one certification.</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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\"\r\n name=\"newCertName\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is 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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\"\r\n name=\"newCertOrg\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\"\r\n name=\"newCertState\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Credential ID</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\"\r\n name=\"newCertCredentialId\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issueDate || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issueDate: $event || null })\"\r\n name=\"newCertIssueDate\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.expiryDate || ''\"\r\n (ngModelChange)=\"patchTempCertification({ expiryDate: $event || null })\"\r\n name=\"newCertExpiryDate\"\r\n />\r\n <div class=\"small text-danger mt-1\" *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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\"\r\n name=\"newCertAttachment\"\r\n />\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\" (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\" (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\" (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : 'Save' }}\r\n </button> </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 <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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditCertification(ci)\"\r\n title=\"Edit\"\r\n >\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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteCertification(ci)\"\r\n title=\"Delete\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\"\r\n name=\"certName{{ ci }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is 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\r\n type=\"text\"\r\n 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 />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\"\r\n name=\"certState{{ ci }}\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Credential ID</label>\r\n <input\r\n type=\"text\"\r\n 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 />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issueDate || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issueDate: $event || null })\"\r\n name=\"certIssue{{ ci }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.expiryDate || ''\"\r\n (ngModelChange)=\"patchTempCertification({ expiryDate: $event || null })\"\r\n name=\"certExpiry{{ ci }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\"\r\n name=\"certAttachment{{ ci }}\"\r\n />\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\" (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\" (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\" (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : 'Save' }}\r\n </button> </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=\"licensesSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add license\"\r\n (click)=\"addLicense()\"\r\n >\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n <div *ngIf=\"licenses().length === 0 && !isAddingLicense() && editingLicenseIndex() === null\" 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\">Add at least one license.</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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\"\r\n name=\"newLicName\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\"\r\n name=\"newLicAuthority\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\"\r\n name=\"newLicNumber\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\"\r\n name=\"newLicState\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.issueDate || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issueDate: $event || null })\"\r\n name=\"newLicIssueDate\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.expiryDate || ''\"\r\n (ngModelChange)=\"patchTempLicense({ expiryDate: $event || null })\"\r\n name=\"newLicExpiryDate\"\r\n />\r\n <div class=\"small text-danger mt-1\" *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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\"\r\n name=\"newLicenseAttachment\"\r\n />\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\" (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\" (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : 'Save' }}\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 <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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditLicense(li)\"\r\n title=\"Edit\"\r\n >\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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteLicense(li)\"\r\n title=\"Delete\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\"\r\n name=\"licName{{ li }}\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\"\r\n name=\"licAuthority{{ li }}\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\"\r\n name=\"licNumber{{ li }}\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\"\r\n name=\"licState{{ li }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.issueDate || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issueDate: $event || null })\"\r\n name=\"licIssue{{ li }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.expiryDate || ''\"\r\n (ngModelChange)=\"patchTempLicense({ expiryDate: $event || null })\"\r\n name=\"licExpiry{{ li }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\"\r\n name=\"licenseAttachment{{ li }}\"\r\n />\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\" (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\" (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : 'Save' }}\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=\"toolsSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add tool\"\r\n (click)=\"addTool()\"\r\n >\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\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\r\n type=\"button\"\r\n class=\"btn btn-light border rounded-pill d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openToolEditor(ti)\"\r\n title=\"Edit\"\r\n >\r\n <span class=\"fw-normal text-dark\">{{ tool }}</span>\r\n <span\r\n *ngIf=\"(toolIssuesByIndex()[ti] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\"\r\n >\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\r\n 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;\"\r\n title=\"Delete tool\"\r\n (click)=\"deleteTool(ti)\"\r\n >\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\r\n *ngIf=\"isToolEditorOpen()\"\r\n class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 2000;\"\r\n (click)=\"closeToolEditor()\"\r\n >\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\" (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') }}</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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"toolForm()?.name\"\r\n (ngModelChange)=\"patchToolForm({ name: $event })\"\r\n name=\"toolName\"\r\n />\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-12\">\r\n <label class=\"small text-muted d-block\">Service Provider</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"toolForm()?.providerName\"\r\n (ngModelChange)=\"patchToolForm({ providerName: $event })\"\r\n name=\"toolProvider\"\r\n placeholder=\"Service Provider\"\r\n />\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 class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button\r\n *ngFor=\"let s of [1,2,3,4,5]\"\r\n type=\"button\"\r\n class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempToolStars(s)\"\r\n [attr.aria-label]=\"'Set rating ' + s\"\r\n >\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\r\n type=\"number\"\r\n class=\"form-control\"\r\n [ngModel]=\"toolForm()?.year\"\r\n (ngModelChange)=\"patchToolForm({ year: $event === '' ? null : +$event })\"\r\n name=\"toolYear\"\r\n min=\"1\"\r\n max=\"30\"\r\n placeholder=\"Years of Experience\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"toolForm()?.year === null || toolForm()?.year === undefined\">Years of experience is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-check form-switch mt-2\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [ngModel]=\"toolForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchToolForm({ profileVisibility: $event })\"\r\n name=\"toolVisible\"\r\n id=\"toolVisible\"\r\n />\r\n <label class=\"form-check-label\" 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\r\n rows=\"4\"\r\n class=\"form-control\"\r\n [ngModel]=\"toolForm()?.notes\"\r\n (ngModelChange)=\"patchToolForm({ notes: $event })\"\r\n name=\"toolNotes\"\r\n placeholder=\"Comment your tool here...\"\r\n ></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\r\n *ngIf=\"!isAddingTool() && editingToolIndex() !== null\"\r\n type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\"\r\n (click)=\"deleteTool(editingToolIndex()!)\"\r\n >\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\" (click)=\"saveToolEditor()\">\r\n {{ isAddingTool() ? 'Save' : 'Update' }}\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=\"skillsSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add skill\"\r\n (click)=\"addSkill()\"\r\n >\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\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\r\n type=\"button\"\r\n class=\"btn btn-light border rounded-pill d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openSkillEditor(si)\"\r\n title=\"Edit\"\r\n >\r\n <span class=\"fw-normal text-dark\">{{ skill }}</span>\r\n <span\r\n *ngIf=\"(skillIssuesByIndex()[si] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\"\r\n >\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\r\n 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;\"\r\n title=\"Delete skill\"\r\n (click)=\"deleteSkill(si); $event.stopPropagation()\"\r\n >\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\r\n <!-- Skill edit panel (overlay) -->\r\n <div\r\n *ngIf=\"isSkillEditorOpen()\"\r\n class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 2000;\"\r\n (click)=\"closeSkillEditor()\"\r\n >\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\" (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') }}</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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"skillForm()?.name\"\r\n (ngModelChange)=\"patchSkillForm({ name: $event })\"\r\n name=\"skillName\"\r\n />\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-12\">\r\n <label class=\"small text-muted d-block\">Service Provider</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"skillForm()?.providerName\"\r\n (ngModelChange)=\"patchSkillForm({ providerName: $event })\"\r\n name=\"skillProvider\"\r\n placeholder=\"Service Provider\"\r\n />\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 class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button\r\n *ngFor=\"let s of [1,2,3,4,5]\"\r\n type=\"button\"\r\n class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempSkillStars(s)\"\r\n [attr.aria-label]=\"'Set rating ' + s\"\r\n >\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</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\r\n type=\"number\"\r\n class=\"form-control\"\r\n [ngModel]=\"skillForm()?.year\"\r\n (ngModelChange)=\"patchSkillForm({ year: $event === '' ? null : +$event })\"\r\n name=\"skillYear\"\r\n min=\"1\"\r\n max=\"30\"\r\n placeholder=\"Years of Experience\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"skillForm()?.year === null || skillForm()?.year === undefined\">Years of experience is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-check form-switch mt-2\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [ngModel]=\"skillForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchSkillForm({ profileVisibility: $event })\"\r\n name=\"skillVisible\"\r\n id=\"skillVisible\"\r\n />\r\n <label class=\"form-check-label\" 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\r\n rows=\"4\"\r\n class=\"form-control\"\r\n [ngModel]=\"skillForm()?.notes\"\r\n (ngModelChange)=\"patchSkillForm({ notes: $event })\"\r\n name=\"skillNotes\"\r\n placeholder=\"Comment your skill here...\"\r\n ></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\r\n *ngIf=\"!isAddingSkill() && editingSkillIndex() !== null\"\r\n type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\"\r\n (click)=\"deleteSkill(editingSkillIndex()!)\"\r\n >\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\" (click)=\"saveSkillEditor()\">\r\n {{ isAddingSkill() ? 'Save' : 'Update' }}\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=\"educationSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add education\"\r\n (click)=\"addEducation()\"\r\n >\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\" 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\">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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\"\r\n name=\"newEduDegree\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is 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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\"\r\n name=\"newEduInstitution\"\r\n />\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 <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\"\r\n name=\"newEduDegreeType\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">START DATE <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.startDate\"\r\n (ngModelChange)=\"patchTempEducation({ startDate: $event })\"\r\n name=\"newEduStartDate\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.endDate\"\r\n (ngModelChange)=\"patchTempEducation({ endDate: $event })\"\r\n name=\"newEduEndDate\"\r\n />\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\" *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\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\" (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" (click)=\"saveEducation()\">Save</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 <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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditEducation(ei)\"\r\n title=\"Edit\"\r\n >\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteEducation(ei)\"\r\n title=\"Delete\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\"\r\n name=\"eduDegree{{ ei }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is 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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\"\r\n name=\"eduInstitution{{ ei }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.institution)\">Institution name is 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 <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\"\r\n name=\"eduDegreeType{{ ei }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is 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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\"\r\n name=\"eduCity{{ ei }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.startDate\"\r\n (ngModelChange)=\"patchTempEducation({ startDate: $event })\"\r\n name=\"eduStartDate{{ ei }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.endDate\"\r\n (ngModelChange)=\"patchTempEducation({ endDate: $event })\"\r\n name=\"eduEndDate{{ ei }}\"\r\n />\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\" *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\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\" (click)=\"saveEducation()\">Save</button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"educationList().length === 0\" class=\"text-muted small\">No education added.</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex gap-2 justify-content-center mt-5\">\r\n <button class=\"btn btn-outline-secondary px-5\" (click)=\"onBackClick()\">Back</button>\r\n <button\r\n class=\"btn btn-primary px-5 shadow\"\r\n [disabled]=\"!canConfirmAndContinue()\"\r\n [title]=\"canConfirmAndContinue() ? '' : 'Please fill all required fields in all mandatory sections.'\"\r\n (click)=\"saveResumedetails()\"\r\n >\r\n Confirm & Continue\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=\"showPopup\" (click)=\"closeSavePopup()\">\r\n <div class=\"status-modal-card\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"status-modal-header\">\r\n <h3 class=\"mb-1\">Saving Resume Details</h3>\r\n <p class=\"text-muted mb-0\">Please wait while we process each section.</p>\r\n </div>\r\n\r\n <div class=\"status-modal-body\">\r\n <div class=\"status-modal-row\" *ngFor=\"let item of statusList\">\r\n <div class=\"status-modal-name\">{{ item.name }}</div>\r\n\r\n <div class=\"status-modal-state pending\" *ngIf=\"item.status === 'pending'\">\r\n <span class=\"spinner-border spinner-border-sm me-2\"></span> In progress\r\n </div>\r\n\r\n <div class=\"status-modal-state success\" *ngIf=\"item.status === 'success'\">\r\n <span class=\"me-1\">\u2713</span> Success\r\n </div>\r\n\r\n <div class=\"status-modal-state partial\" *ngIf=\"item.status === 'partial'\">\r\n <span class=\"me-1\">!</span> {{ item.successCount }} Success / {{ item.failCount }} Failed\r\n </div>\r\n\r\n <div class=\"status-modal-state error\" *ngIf=\"item.status === 'error'\">\r\n <span class=\"me-1\">\u2716</span> {{ item.error || 'Failed' }}\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"status-modal-footer\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary\" (click)=\"closeSavePopup()\">Back to Preview</button>\r\n <div class=\"d-flex justify-content-end\">\r\n <button\r\n [disabled]=\"showLoader\" [ng2-loading]=\"showLoader\"\r\n *ngIf=\"allSaveStepsSucceeded()\"\r\n type=\"button\"\r\n class=\"btn btn-primary\"\r\n (click)=\"goToDashboard()\"\r\n >\r\n Go to Dashboard\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBackConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Leave this page?</h4>\r\n <p class=\"text-muted mb-4\">Your data might be lost if you go back now.</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary\" (click)=\"stayOnPreview()\">Stay</button>\r\n <button type=\"button\" class=\"btn btn-danger\" (click)=\"proceedBack()\">Proceed Back</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:space-between;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}\n"], dependencies: [{ kind: "directive", type: i11.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i11.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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: "directive", type: Ng2LoadingSpinnerDirective, selector: "[ng2-loading]", inputs: ["ng2-loading", "config", "template"] }] });
|
|
30873
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: PreviewComponent, isStandalone: false, selector: "app-preview", inputs: { providerId: "providerId", providerName: "providerName", roleData: "roleData", cloudfrontUrl: "cloudfrontUrl" }, outputs: { backToParent: "backToParent" }, ngImport: i0, template: "\r\n<div class=\"preview-page-header\">\r\n <h2 class=\"preview-title\">Confirm based on your resume</h2>\r\n <p class=\"preview-subtitle\">Please confirm everything is accurate. It is based on your resume</p>\r\n</div>\r\n\r\n\r\n<div class=\"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\">\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 </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 text-end\">\r\n <button class=\"btn btn-sm btn-primary px-4\" (click)=\"toggleEdit()\">Edit Details</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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.firstName\"\r\n name=\"fName\"\r\n placeholder=\"First Name\"\r\n required\r\n #fName=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"fName.invalid && (fName.dirty || fName.touched)\">First name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.lastName\"\r\n name=\"lName\"\r\n placeholder=\"Last Name\"\r\n required\r\n #lName=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"lName.invalid && (lName.dirty || lName.touched)\">Last name is 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\r\n type=\"email\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.email\"\r\n name=\"email\"\r\n placeholder=\"Email\"\r\n required\r\n email\r\n #email=\"ngModel\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"tempProfile.phone\"\r\n (ngModelChange)=\"tempProfile.phone = sanitizePhone($event)\"\r\n name=\"phone\"\r\n placeholder=\"Phone (10 digits)\"\r\n required\r\n pattern=\"^\\d{10}$\"\r\n maxlength=\"10\"\r\n inputmode=\"numeric\"\r\n #phone=\"ngModel\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.address\"\r\n name=\"address\"\r\n placeholder=\"Home Address\"\r\n required\r\n #address=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"address.invalid && (address.dirty || address.touched)\">Home address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.city\"\r\n name=\"city\"\r\n placeholder=\"City\"\r\n required\r\n #city=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"city.invalid && (city.dirty || city.touched)\">City is required</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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.state\"\r\n name=\"state\"\r\n placeholder=\"State\"\r\n required\r\n #state=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"state.invalid && (state.dirty || state.touched)\">State is 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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.zipCode\"\r\n name=\"zipCode\"\r\n placeholder=\"Zip Code\"\r\n required\r\n #zipCode=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"zipCode.invalid && (zipCode.dirty || zipCode.touched)\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.country\"\r\n name=\"country\"\r\n placeholder=\"Country\"\r\n required\r\n #country=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"country.invalid && (country.dirty || country.touched)\">Country 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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.jobTitle\"\r\n name=\"jobTitle\"\r\n placeholder=\"Job Title\"\r\n required\r\n #jobTitle=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"jobTitle.invalid && (jobTitle.dirty || jobTitle.touched)\">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\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"number\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n name=\"yearsOfExperience\"\r\n placeholder=\"Years of Experience\"\r\n required\r\n min=\"0\"\r\n #yearsOfExperience=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *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\" (click)=\"save()\">Save Changes</button>\r\n </div>\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=\"workSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add work experience\"\r\n (click)=\"addJob()\"\r\n >\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\">Missing required fields</div>\r\n <div class=\"small\">Add at least one work experience.</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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\"\r\n name=\"newJobTitle\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\"\r\n name=\"newCompany\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\"\r\n name=\"newCity\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.startDate\"\r\n (ngModelChange)=\"patchTempJob({ startDate: $event })\"\r\n name=\"newStartDate\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"tempJob()?.endDate\"\r\n (ngModelChange)=\"patchTempJob({ endDate: $event })\"\r\n name=\"newEndDate\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\" *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 <div class=\"col-md-4 d-flex align-items-end\">\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\"\r\n name=\"newIsCurrent\"\r\n id=\"newIsCurrent\"\r\n />\r\n <label class=\"form-check-label\" for=\"newIsCurrent\">Current</label>\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">RESPONSIBILITIES (one per line)</label>\r\n <textarea\r\n rows=\"4\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\"\r\n name=\"newResponsibilities\"\r\n ></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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\"\r\n name=\"newWorkAttachment\"\r\n />\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\" (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\" (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingWork\" (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : 'Save' }}\r\n </button>\r\n </div>\r\n </div>\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 <small class=\"text-muted\">\r\n {{ job.company }} \u2022 {{ formatMonthYear(job.startDate) }} - {{ job.isCurrent ? 'Present' : formatMonthYear(job.endDate) }}\r\n </small>\r\n <div\r\n *ngIf=\"editingJobIndex() !== i && (workIssuesByIndex()[i] || []).length > 0\"\r\n class=\"alert alert-warning py-1 px-2 mt-2\"\r\n >\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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditJob(i)\"\r\n title=\"Edit\"\r\n >\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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteJob(i);\"\r\n title=\"Delete\"\r\n >\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 <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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\"\r\n name=\"jobTitle{{ i }}\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\"\r\n name=\"company{{ i }}\"\r\n />\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=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">CITY <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\"\r\n name=\"city{{ i }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.startDate\"\r\n (ngModelChange)=\"patchTempJob({ startDate: $event })\"\r\n name=\"startDate{{ i }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"tempJob()?.endDate\"\r\n (ngModelChange)=\"patchTempJob({ endDate: $event })\"\r\n name=\"endDate{{ i }}\"\r\n />\r\n <div\r\n class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\"\r\n >\r\n End date is required\r\n </div>\r\n <div class=\"small text-danger mt-1\" *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-md-4 d-flex align-items-end\">\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\"\r\n name=\"isCurrent{{ i }}\"\r\n id=\"isCurrent{{ i }}\"\r\n />\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-12\">\r\n <label class=\"small text-muted d-block\">RESPONSIBILITIES (one per line)</label>\r\n <textarea\r\n rows=\"4\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\"\r\n name=\"responsibilities{{ i }}\"\r\n ></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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\"\r\n name=\"workAttachment{{ i }}\"\r\n />\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\" (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\" (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingWork\" (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : 'Save' }}\r\n </button>\r\n </div> \r\n\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\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=\"certificationsSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add certification\"\r\n (click)=\"addCertification()\"\r\n >\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n <div *ngIf=\"certs().length === 0 && !isAddingCertification() && editingCertificationIndex() === null\" 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\">Add at least one certification.</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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\"\r\n name=\"newCertName\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is 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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\"\r\n name=\"newCertOrg\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\"\r\n name=\"newCertState\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Credential ID</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\"\r\n name=\"newCertCredentialId\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issueDate || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issueDate: $event || null })\"\r\n name=\"newCertIssueDate\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.expiryDate || ''\"\r\n (ngModelChange)=\"patchTempCertification({ expiryDate: $event || null })\"\r\n name=\"newCertExpiryDate\"\r\n />\r\n <div class=\"small text-danger mt-1\" *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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\"\r\n name=\"newCertAttachment\"\r\n />\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\" (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\" (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\" (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : 'Save' }}\r\n </button> </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 <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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditCertification(ci)\"\r\n title=\"Edit\"\r\n >\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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteCertification(ci)\"\r\n title=\"Delete\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\"\r\n name=\"certName{{ ci }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is 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\r\n type=\"text\"\r\n 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 />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\"\r\n name=\"certState{{ ci }}\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Credential ID</label>\r\n <input\r\n type=\"text\"\r\n 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 />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issueDate || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issueDate: $event || null })\"\r\n name=\"certIssue{{ ci }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.expiryDate || ''\"\r\n (ngModelChange)=\"patchTempCertification({ expiryDate: $event || null })\"\r\n name=\"certExpiry{{ ci }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\"\r\n name=\"certAttachment{{ ci }}\"\r\n />\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\" (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\" (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\" (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : 'Save' }}\r\n </button> </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=\"licensesSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add license\"\r\n (click)=\"addLicense()\"\r\n >\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n <div *ngIf=\"licenses().length === 0 && !isAddingLicense() && editingLicenseIndex() === null\" 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\">Add at least one license.</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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\"\r\n name=\"newLicName\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\"\r\n name=\"newLicAuthority\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\"\r\n name=\"newLicNumber\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\"\r\n name=\"newLicState\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.issueDate || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issueDate: $event || null })\"\r\n name=\"newLicIssueDate\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.expiryDate || ''\"\r\n (ngModelChange)=\"patchTempLicense({ expiryDate: $event || null })\"\r\n name=\"newLicExpiryDate\"\r\n />\r\n <div class=\"small text-danger mt-1\" *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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\"\r\n name=\"newLicenseAttachment\"\r\n />\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\" (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\" (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : 'Save' }}\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 <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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditLicense(li)\"\r\n title=\"Edit\"\r\n >\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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteLicense(li)\"\r\n title=\"Delete\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\"\r\n name=\"licName{{ li }}\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\"\r\n name=\"licAuthority{{ li }}\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\"\r\n name=\"licNumber{{ li }}\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\"\r\n name=\"licState{{ li }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.issueDate || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issueDate: $event || null })\"\r\n name=\"licIssue{{ li }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.expiryDate || ''\"\r\n (ngModelChange)=\"patchTempLicense({ expiryDate: $event || null })\"\r\n name=\"licExpiry{{ li }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\"\r\n name=\"licenseAttachment{{ li }}\"\r\n />\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\" (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\" (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : 'Save' }}\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=\"toolsSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add tool\"\r\n (click)=\"addTool()\"\r\n >\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\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\r\n type=\"button\"\r\n class=\"btn btn-light border rounded-pill d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openToolEditor(ti)\"\r\n title=\"Edit\"\r\n >\r\n <span class=\"fw-normal text-dark\">{{ tool }}</span>\r\n <span\r\n *ngIf=\"(toolIssuesByIndex()[ti] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\"\r\n >\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\r\n 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;\"\r\n title=\"Delete tool\"\r\n (click)=\"deleteTool(ti)\"\r\n >\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\r\n *ngIf=\"isToolEditorOpen()\"\r\n class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 2000;\"\r\n (click)=\"closeToolEditor()\"\r\n >\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\" (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') }}</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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"toolForm()?.name\"\r\n (ngModelChange)=\"patchToolForm({ name: $event })\"\r\n name=\"toolName\"\r\n />\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-12\">\r\n <label class=\"small text-muted d-block\">Service Provider</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"toolForm()?.providerName\"\r\n (ngModelChange)=\"patchToolForm({ providerName: $event })\"\r\n name=\"toolProvider\"\r\n placeholder=\"Service Provider\"\r\n />\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 class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button\r\n *ngFor=\"let s of [1,2,3,4,5]\"\r\n type=\"button\"\r\n class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempToolStars(s)\"\r\n [attr.aria-label]=\"'Set rating ' + s\"\r\n >\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\r\n type=\"number\"\r\n class=\"form-control\"\r\n [ngModel]=\"toolForm()?.year\"\r\n (ngModelChange)=\"patchToolForm({ year: $event === '' ? null : +$event })\"\r\n name=\"toolYear\"\r\n min=\"1\"\r\n max=\"30\"\r\n placeholder=\"Years of Experience\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"toolForm()?.year === null || toolForm()?.year === undefined\">Years of experience is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-check form-switch mt-2\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [ngModel]=\"toolForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchToolForm({ profileVisibility: $event })\"\r\n name=\"toolVisible\"\r\n id=\"toolVisible\"\r\n />\r\n <label class=\"form-check-label\" 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\r\n rows=\"4\"\r\n class=\"form-control\"\r\n [ngModel]=\"toolForm()?.notes\"\r\n (ngModelChange)=\"patchToolForm({ notes: $event })\"\r\n name=\"toolNotes\"\r\n placeholder=\"Comment your tool here...\"\r\n ></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\r\n *ngIf=\"!isAddingTool() && editingToolIndex() !== null\"\r\n type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\"\r\n (click)=\"deleteTool(editingToolIndex()!)\"\r\n >\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\" (click)=\"saveToolEditor()\">\r\n {{ isAddingTool() ? 'Save' : 'Update' }}\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=\"skillsSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add skill\"\r\n (click)=\"addSkill()\"\r\n >\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\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\r\n type=\"button\"\r\n class=\"btn btn-light border rounded-pill d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openSkillEditor(si)\"\r\n title=\"Edit\"\r\n >\r\n <span class=\"fw-normal text-dark\">{{ skill }}</span>\r\n <span\r\n *ngIf=\"(skillIssuesByIndex()[si] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\"\r\n >\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\r\n 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;\"\r\n title=\"Delete skill\"\r\n (click)=\"deleteSkill(si); $event.stopPropagation()\"\r\n >\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\r\n <!-- Skill edit panel (overlay) -->\r\n <div\r\n *ngIf=\"isSkillEditorOpen()\"\r\n class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 2000;\"\r\n (click)=\"closeSkillEditor()\"\r\n >\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\" (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') }}</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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"skillForm()?.name\"\r\n (ngModelChange)=\"patchSkillForm({ name: $event })\"\r\n name=\"skillName\"\r\n />\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-12\">\r\n <label class=\"small text-muted d-block\">Service Provider</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"skillForm()?.providerName\"\r\n (ngModelChange)=\"patchSkillForm({ providerName: $event })\"\r\n name=\"skillProvider\"\r\n placeholder=\"Service Provider\"\r\n />\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 class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button\r\n *ngFor=\"let s of [1,2,3,4,5]\"\r\n type=\"button\"\r\n class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempSkillStars(s)\"\r\n [attr.aria-label]=\"'Set rating ' + s\"\r\n >\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</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\r\n type=\"number\"\r\n class=\"form-control\"\r\n [ngModel]=\"skillForm()?.year\"\r\n (ngModelChange)=\"patchSkillForm({ year: $event === '' ? null : +$event })\"\r\n name=\"skillYear\"\r\n min=\"1\"\r\n max=\"30\"\r\n placeholder=\"Years of Experience\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"skillForm()?.year === null || skillForm()?.year === undefined\">Years of experience is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-check form-switch mt-2\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [ngModel]=\"skillForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchSkillForm({ profileVisibility: $event })\"\r\n name=\"skillVisible\"\r\n id=\"skillVisible\"\r\n />\r\n <label class=\"form-check-label\" 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\r\n rows=\"4\"\r\n class=\"form-control\"\r\n [ngModel]=\"skillForm()?.notes\"\r\n (ngModelChange)=\"patchSkillForm({ notes: $event })\"\r\n name=\"skillNotes\"\r\n placeholder=\"Comment your skill here...\"\r\n ></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\r\n *ngIf=\"!isAddingSkill() && editingSkillIndex() !== null\"\r\n type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\"\r\n (click)=\"deleteSkill(editingSkillIndex()!)\"\r\n >\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\" (click)=\"saveSkillEditor()\">\r\n {{ isAddingSkill() ? 'Save' : 'Update' }}\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=\"educationSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add education\"\r\n (click)=\"addEducation()\"\r\n >\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\" 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\">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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\"\r\n name=\"newEduDegree\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is 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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\"\r\n name=\"newEduInstitution\"\r\n />\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 <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\"\r\n name=\"newEduDegreeType\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">START DATE <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.startDate\"\r\n (ngModelChange)=\"patchTempEducation({ startDate: $event })\"\r\n name=\"newEduStartDate\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.endDate\"\r\n (ngModelChange)=\"patchTempEducation({ endDate: $event })\"\r\n name=\"newEduEndDate\"\r\n />\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\" *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\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\" (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" (click)=\"saveEducation()\">Save</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 <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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditEducation(ei)\"\r\n title=\"Edit\"\r\n >\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteEducation(ei)\"\r\n title=\"Delete\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\"\r\n name=\"eduDegree{{ ei }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is 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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\"\r\n name=\"eduInstitution{{ ei }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.institution)\">Institution name is 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 <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\"\r\n name=\"eduDegreeType{{ ei }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is 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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\"\r\n name=\"eduCity{{ ei }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.startDate\"\r\n (ngModelChange)=\"patchTempEducation({ startDate: $event })\"\r\n name=\"eduStartDate{{ ei }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.endDate\"\r\n (ngModelChange)=\"patchTempEducation({ endDate: $event })\"\r\n name=\"eduEndDate{{ ei }}\"\r\n />\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\" *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\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\" (click)=\"saveEducation()\">Save</button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"educationList().length === 0\" class=\"text-muted small\">No education added.</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex gap-2 justify-content-center mt-5\">\r\n <button class=\"btn btn-outline-secondary px-5\" (click)=\"onBackClick()\">Back</button>\r\n <button\r\n class=\"btn btn-primary px-5 shadow\"\r\n [disabled]=\"!canConfirmAndContinue()\"\r\n [title]=\"canConfirmAndContinue() ? '' : 'Please fill all required fields in all mandatory sections.'\"\r\n (click)=\"saveResumedetails()\"\r\n >\r\n Confirm All & Continue\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=\"showPopup\" >\r\n <div class=\"status-modal-card\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"status-modal-header\">\r\n <h3 class=\"mb-1\">Saving Resume Details</h3>\r\n <p class=\"text-muted mb-0\">Please wait while we process each section.</p>\r\n </div>\r\n\r\n <div class=\"status-modal-body\">\r\n <div class=\"status-modal-row\" *ngFor=\"let item of statusList\">\r\n <div class=\"status-modal-name\">{{ item.name }}</div>\r\n\r\n <div class=\"status-modal-state pending\" *ngIf=\"item.status === 'pending'\">\r\n <span class=\"spinner-border spinner-border-sm me-2\"></span> In progress\r\n </div>\r\n\r\n <div class=\"status-modal-state success\" *ngIf=\"item.status === 'success'\">\r\n <span class=\"me-1\">\u2713</span> Saved\r\n </div>\r\n\r\n <div class=\"status-modal-state partial\" *ngIf=\"item.status === 'partial'\">\r\n <span class=\"me-1\">!</span> {{ item.successCount }} Success / {{ item.failCount }} Failed\r\n </div>\r\n\r\n <div class=\"status-modal-state error\" *ngIf=\"item.status === 'error'\">\r\n <span class=\"me-1\">\u2716</span> {{ item.error || 'Failed' }}\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"status-modal-footer\">\r\n <!-- <button type=\"button\" class=\"btn btn-outline-secondary\" (click)=\"closeSavePopup()\">Back to Preview</button> -->\r\n <div class=\"d-flex justify-content-end\">\r\n <button\r\n [disabled]=\"showLoader\" [ng2-loading]=\"showLoader\"\r\n *ngIf=\"allSaveStepsSucceeded()\"\r\n type=\"button\"\r\n class=\"btn btn-primary\"\r\n (click)=\"goToDashboard()\"\r\n >\r\n Go to Dashboard\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBackConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Leave this page?</h4>\r\n <p class=\"text-muted mb-4\">Your data might be lost if you go back now.</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary\" (click)=\"stayOnPreview()\">Stay</button>\r\n <button type=\"button\" class=\"btn btn-danger\" (click)=\"proceedBack()\">Proceed Back</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}\n"], dependencies: [{ kind: "directive", type: i11.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i11.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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: "directive", type: Ng2LoadingSpinnerDirective, selector: "[ng2-loading]", inputs: ["ng2-loading", "config", "template"] }] });
|
|
30875
30874
|
}
|
|
30876
30875
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PreviewComponent, decorators: [{
|
|
30877
30876
|
type: Component,
|
|
30878
|
-
args: [{ selector: 'app-preview', standalone: false, template: "\r\n<div class=\"preview-page-header\">\r\n <h2 class=\"preview-title\">Confirm based on your resume</h2>\r\n <p class=\"preview-subtitle\">Please confirm everything is accurate. It is based on your resume</p>\r\n</div>\r\n\r\n\r\n<div class=\"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\">\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 </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 text-end\">\r\n <button class=\"btn btn-sm btn-primary px-4\" (click)=\"toggleEdit()\">Edit Details</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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.firstName\"\r\n name=\"fName\"\r\n placeholder=\"First Name\"\r\n required\r\n #fName=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"fName.invalid && (fName.dirty || fName.touched)\">First name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.lastName\"\r\n name=\"lName\"\r\n placeholder=\"Last Name\"\r\n required\r\n #lName=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"lName.invalid && (lName.dirty || lName.touched)\">Last name is 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\r\n type=\"email\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.email\"\r\n name=\"email\"\r\n placeholder=\"Email\"\r\n required\r\n email\r\n #email=\"ngModel\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"tempProfile.phone\"\r\n (ngModelChange)=\"tempProfile.phone = sanitizePhone($event)\"\r\n name=\"phone\"\r\n placeholder=\"Phone (10 digits)\"\r\n required\r\n pattern=\"^\\d{10}$\"\r\n maxlength=\"10\"\r\n inputmode=\"numeric\"\r\n #phone=\"ngModel\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.address\"\r\n name=\"address\"\r\n placeholder=\"Home Address\"\r\n required\r\n #address=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"address.invalid && (address.dirty || address.touched)\">Home address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.city\"\r\n name=\"city\"\r\n placeholder=\"City\"\r\n required\r\n #city=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"city.invalid && (city.dirty || city.touched)\">City is required</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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.state\"\r\n name=\"state\"\r\n placeholder=\"State\"\r\n required\r\n #state=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"state.invalid && (state.dirty || state.touched)\">State is 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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.zipCode\"\r\n name=\"zipCode\"\r\n placeholder=\"Zip Code\"\r\n required\r\n #zipCode=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"zipCode.invalid && (zipCode.dirty || zipCode.touched)\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.country\"\r\n name=\"country\"\r\n placeholder=\"Country\"\r\n required\r\n #country=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"country.invalid && (country.dirty || country.touched)\">Country 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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.jobTitle\"\r\n name=\"jobTitle\"\r\n placeholder=\"Job Title\"\r\n required\r\n #jobTitle=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"jobTitle.invalid && (jobTitle.dirty || jobTitle.touched)\">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\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"number\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n name=\"yearsOfExperience\"\r\n placeholder=\"Years of Experience\"\r\n required\r\n min=\"0\"\r\n #yearsOfExperience=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *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\" (click)=\"save()\">Save Changes</button>\r\n </div>\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=\"workSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add work experience\"\r\n (click)=\"addJob()\"\r\n >\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\">Missing required fields</div>\r\n <div class=\"small\">Add at least one work experience.</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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\"\r\n name=\"newJobTitle\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\"\r\n name=\"newCompany\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\"\r\n name=\"newCity\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.startDate\"\r\n (ngModelChange)=\"patchTempJob({ startDate: $event })\"\r\n name=\"newStartDate\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"tempJob()?.endDate\"\r\n (ngModelChange)=\"patchTempJob({ endDate: $event })\"\r\n name=\"newEndDate\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\" *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 <div class=\"col-md-4 d-flex align-items-end\">\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\"\r\n name=\"newIsCurrent\"\r\n id=\"newIsCurrent\"\r\n />\r\n <label class=\"form-check-label\" for=\"newIsCurrent\">Current</label>\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">RESPONSIBILITIES (one per line)</label>\r\n <textarea\r\n rows=\"4\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\"\r\n name=\"newResponsibilities\"\r\n ></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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\"\r\n name=\"newWorkAttachment\"\r\n />\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\" (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\" (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingWork\" (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : 'Save' }}\r\n </button>\r\n </div>\r\n </div>\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 <small class=\"text-muted\">\r\n {{ job.company }} \u2022 {{ formatMonthYear(job.startDate) }} - {{ job.isCurrent ? 'Present' : formatMonthYear(job.endDate) }}\r\n </small>\r\n <div\r\n *ngIf=\"editingJobIndex() !== i && (workIssuesByIndex()[i] || []).length > 0\"\r\n class=\"alert alert-warning py-1 px-2 mt-2\"\r\n >\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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditJob(i)\"\r\n title=\"Edit\"\r\n >\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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteJob(i);\"\r\n title=\"Delete\"\r\n >\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 <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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\"\r\n name=\"jobTitle{{ i }}\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\"\r\n name=\"company{{ i }}\"\r\n />\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=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">CITY <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\"\r\n name=\"city{{ i }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.startDate\"\r\n (ngModelChange)=\"patchTempJob({ startDate: $event })\"\r\n name=\"startDate{{ i }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"tempJob()?.endDate\"\r\n (ngModelChange)=\"patchTempJob({ endDate: $event })\"\r\n name=\"endDate{{ i }}\"\r\n />\r\n <div\r\n class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\"\r\n >\r\n End date is required\r\n </div>\r\n <div class=\"small text-danger mt-1\" *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-md-4 d-flex align-items-end\">\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\"\r\n name=\"isCurrent{{ i }}\"\r\n id=\"isCurrent{{ i }}\"\r\n />\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-12\">\r\n <label class=\"small text-muted d-block\">RESPONSIBILITIES (one per line)</label>\r\n <textarea\r\n rows=\"4\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\"\r\n name=\"responsibilities{{ i }}\"\r\n ></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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\"\r\n name=\"workAttachment{{ i }}\"\r\n />\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\" (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\" (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingWork\" (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : 'Save' }}\r\n </button>\r\n </div> \r\n\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\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=\"certificationsSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add certification\"\r\n (click)=\"addCertification()\"\r\n >\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n <div *ngIf=\"certs().length === 0 && !isAddingCertification() && editingCertificationIndex() === null\" 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\">Add at least one certification.</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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\"\r\n name=\"newCertName\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is 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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\"\r\n name=\"newCertOrg\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\"\r\n name=\"newCertState\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Credential ID</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\"\r\n name=\"newCertCredentialId\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issueDate || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issueDate: $event || null })\"\r\n name=\"newCertIssueDate\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.expiryDate || ''\"\r\n (ngModelChange)=\"patchTempCertification({ expiryDate: $event || null })\"\r\n name=\"newCertExpiryDate\"\r\n />\r\n <div class=\"small text-danger mt-1\" *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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\"\r\n name=\"newCertAttachment\"\r\n />\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\" (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\" (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\" (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : 'Save' }}\r\n </button> </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 <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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditCertification(ci)\"\r\n title=\"Edit\"\r\n >\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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteCertification(ci)\"\r\n title=\"Delete\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\"\r\n name=\"certName{{ ci }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is 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\r\n type=\"text\"\r\n 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 />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\"\r\n name=\"certState{{ ci }}\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Credential ID</label>\r\n <input\r\n type=\"text\"\r\n 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 />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issueDate || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issueDate: $event || null })\"\r\n name=\"certIssue{{ ci }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.expiryDate || ''\"\r\n (ngModelChange)=\"patchTempCertification({ expiryDate: $event || null })\"\r\n name=\"certExpiry{{ ci }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\"\r\n name=\"certAttachment{{ ci }}\"\r\n />\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\" (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\" (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\" (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : 'Save' }}\r\n </button> </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=\"licensesSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add license\"\r\n (click)=\"addLicense()\"\r\n >\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n <div *ngIf=\"licenses().length === 0 && !isAddingLicense() && editingLicenseIndex() === null\" 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\">Add at least one license.</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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\"\r\n name=\"newLicName\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\"\r\n name=\"newLicAuthority\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\"\r\n name=\"newLicNumber\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\"\r\n name=\"newLicState\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.issueDate || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issueDate: $event || null })\"\r\n name=\"newLicIssueDate\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.expiryDate || ''\"\r\n (ngModelChange)=\"patchTempLicense({ expiryDate: $event || null })\"\r\n name=\"newLicExpiryDate\"\r\n />\r\n <div class=\"small text-danger mt-1\" *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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\"\r\n name=\"newLicenseAttachment\"\r\n />\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\" (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\" (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : 'Save' }}\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 <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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditLicense(li)\"\r\n title=\"Edit\"\r\n >\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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteLicense(li)\"\r\n title=\"Delete\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\"\r\n name=\"licName{{ li }}\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\"\r\n name=\"licAuthority{{ li }}\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\"\r\n name=\"licNumber{{ li }}\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\"\r\n name=\"licState{{ li }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.issueDate || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issueDate: $event || null })\"\r\n name=\"licIssue{{ li }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.expiryDate || ''\"\r\n (ngModelChange)=\"patchTempLicense({ expiryDate: $event || null })\"\r\n name=\"licExpiry{{ li }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\"\r\n name=\"licenseAttachment{{ li }}\"\r\n />\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\" (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\" (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : 'Save' }}\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=\"toolsSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add tool\"\r\n (click)=\"addTool()\"\r\n >\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\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\r\n type=\"button\"\r\n class=\"btn btn-light border rounded-pill d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openToolEditor(ti)\"\r\n title=\"Edit\"\r\n >\r\n <span class=\"fw-normal text-dark\">{{ tool }}</span>\r\n <span\r\n *ngIf=\"(toolIssuesByIndex()[ti] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\"\r\n >\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\r\n 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;\"\r\n title=\"Delete tool\"\r\n (click)=\"deleteTool(ti)\"\r\n >\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\r\n *ngIf=\"isToolEditorOpen()\"\r\n class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 2000;\"\r\n (click)=\"closeToolEditor()\"\r\n >\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\" (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') }}</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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"toolForm()?.name\"\r\n (ngModelChange)=\"patchToolForm({ name: $event })\"\r\n name=\"toolName\"\r\n />\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-12\">\r\n <label class=\"small text-muted d-block\">Service Provider</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"toolForm()?.providerName\"\r\n (ngModelChange)=\"patchToolForm({ providerName: $event })\"\r\n name=\"toolProvider\"\r\n placeholder=\"Service Provider\"\r\n />\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 class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button\r\n *ngFor=\"let s of [1,2,3,4,5]\"\r\n type=\"button\"\r\n class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempToolStars(s)\"\r\n [attr.aria-label]=\"'Set rating ' + s\"\r\n >\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\r\n type=\"number\"\r\n class=\"form-control\"\r\n [ngModel]=\"toolForm()?.year\"\r\n (ngModelChange)=\"patchToolForm({ year: $event === '' ? null : +$event })\"\r\n name=\"toolYear\"\r\n min=\"1\"\r\n max=\"30\"\r\n placeholder=\"Years of Experience\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"toolForm()?.year === null || toolForm()?.year === undefined\">Years of experience is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-check form-switch mt-2\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [ngModel]=\"toolForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchToolForm({ profileVisibility: $event })\"\r\n name=\"toolVisible\"\r\n id=\"toolVisible\"\r\n />\r\n <label class=\"form-check-label\" 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\r\n rows=\"4\"\r\n class=\"form-control\"\r\n [ngModel]=\"toolForm()?.notes\"\r\n (ngModelChange)=\"patchToolForm({ notes: $event })\"\r\n name=\"toolNotes\"\r\n placeholder=\"Comment your tool here...\"\r\n ></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\r\n *ngIf=\"!isAddingTool() && editingToolIndex() !== null\"\r\n type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\"\r\n (click)=\"deleteTool(editingToolIndex()!)\"\r\n >\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\" (click)=\"saveToolEditor()\">\r\n {{ isAddingTool() ? 'Save' : 'Update' }}\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=\"skillsSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add skill\"\r\n (click)=\"addSkill()\"\r\n >\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\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\r\n type=\"button\"\r\n class=\"btn btn-light border rounded-pill d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openSkillEditor(si)\"\r\n title=\"Edit\"\r\n >\r\n <span class=\"fw-normal text-dark\">{{ skill }}</span>\r\n <span\r\n *ngIf=\"(skillIssuesByIndex()[si] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\"\r\n >\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\r\n 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;\"\r\n title=\"Delete skill\"\r\n (click)=\"deleteSkill(si); $event.stopPropagation()\"\r\n >\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\r\n <!-- Skill edit panel (overlay) -->\r\n <div\r\n *ngIf=\"isSkillEditorOpen()\"\r\n class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 2000;\"\r\n (click)=\"closeSkillEditor()\"\r\n >\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\" (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') }}</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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"skillForm()?.name\"\r\n (ngModelChange)=\"patchSkillForm({ name: $event })\"\r\n name=\"skillName\"\r\n />\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-12\">\r\n <label class=\"small text-muted d-block\">Service Provider</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"skillForm()?.providerName\"\r\n (ngModelChange)=\"patchSkillForm({ providerName: $event })\"\r\n name=\"skillProvider\"\r\n placeholder=\"Service Provider\"\r\n />\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 class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button\r\n *ngFor=\"let s of [1,2,3,4,5]\"\r\n type=\"button\"\r\n class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempSkillStars(s)\"\r\n [attr.aria-label]=\"'Set rating ' + s\"\r\n >\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</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\r\n type=\"number\"\r\n class=\"form-control\"\r\n [ngModel]=\"skillForm()?.year\"\r\n (ngModelChange)=\"patchSkillForm({ year: $event === '' ? null : +$event })\"\r\n name=\"skillYear\"\r\n min=\"1\"\r\n max=\"30\"\r\n placeholder=\"Years of Experience\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"skillForm()?.year === null || skillForm()?.year === undefined\">Years of experience is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-check form-switch mt-2\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [ngModel]=\"skillForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchSkillForm({ profileVisibility: $event })\"\r\n name=\"skillVisible\"\r\n id=\"skillVisible\"\r\n />\r\n <label class=\"form-check-label\" 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\r\n rows=\"4\"\r\n class=\"form-control\"\r\n [ngModel]=\"skillForm()?.notes\"\r\n (ngModelChange)=\"patchSkillForm({ notes: $event })\"\r\n name=\"skillNotes\"\r\n placeholder=\"Comment your skill here...\"\r\n ></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\r\n *ngIf=\"!isAddingSkill() && editingSkillIndex() !== null\"\r\n type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\"\r\n (click)=\"deleteSkill(editingSkillIndex()!)\"\r\n >\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\" (click)=\"saveSkillEditor()\">\r\n {{ isAddingSkill() ? 'Save' : 'Update' }}\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=\"educationSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add education\"\r\n (click)=\"addEducation()\"\r\n >\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\" 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\">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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\"\r\n name=\"newEduDegree\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is 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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\"\r\n name=\"newEduInstitution\"\r\n />\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 <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\"\r\n name=\"newEduDegreeType\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">START DATE <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.startDate\"\r\n (ngModelChange)=\"patchTempEducation({ startDate: $event })\"\r\n name=\"newEduStartDate\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.endDate\"\r\n (ngModelChange)=\"patchTempEducation({ endDate: $event })\"\r\n name=\"newEduEndDate\"\r\n />\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\" *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\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\" (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" (click)=\"saveEducation()\">Save</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 <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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditEducation(ei)\"\r\n title=\"Edit\"\r\n >\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteEducation(ei)\"\r\n title=\"Delete\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\"\r\n name=\"eduDegree{{ ei }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is 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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\"\r\n name=\"eduInstitution{{ ei }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.institution)\">Institution name is 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 <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\"\r\n name=\"eduDegreeType{{ ei }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is 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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\"\r\n name=\"eduCity{{ ei }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.startDate\"\r\n (ngModelChange)=\"patchTempEducation({ startDate: $event })\"\r\n name=\"eduStartDate{{ ei }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.endDate\"\r\n (ngModelChange)=\"patchTempEducation({ endDate: $event })\"\r\n name=\"eduEndDate{{ ei }}\"\r\n />\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\" *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\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\" (click)=\"saveEducation()\">Save</button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"educationList().length === 0\" class=\"text-muted small\">No education added.</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex gap-2 justify-content-center mt-5\">\r\n <button class=\"btn btn-outline-secondary px-5\" (click)=\"onBackClick()\">Back</button>\r\n <button\r\n class=\"btn btn-primary px-5 shadow\"\r\n [disabled]=\"!canConfirmAndContinue()\"\r\n [title]=\"canConfirmAndContinue() ? '' : 'Please fill all required fields in all mandatory sections.'\"\r\n (click)=\"saveResumedetails()\"\r\n >\r\n Confirm & Continue\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=\"showPopup\" (click)=\"closeSavePopup()\">\r\n <div class=\"status-modal-card\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"status-modal-header\">\r\n <h3 class=\"mb-1\">Saving Resume Details</h3>\r\n <p class=\"text-muted mb-0\">Please wait while we process each section.</p>\r\n </div>\r\n\r\n <div class=\"status-modal-body\">\r\n <div class=\"status-modal-row\" *ngFor=\"let item of statusList\">\r\n <div class=\"status-modal-name\">{{ item.name }}</div>\r\n\r\n <div class=\"status-modal-state pending\" *ngIf=\"item.status === 'pending'\">\r\n <span class=\"spinner-border spinner-border-sm me-2\"></span> In progress\r\n </div>\r\n\r\n <div class=\"status-modal-state success\" *ngIf=\"item.status === 'success'\">\r\n <span class=\"me-1\">\u2713</span> Success\r\n </div>\r\n\r\n <div class=\"status-modal-state partial\" *ngIf=\"item.status === 'partial'\">\r\n <span class=\"me-1\">!</span> {{ item.successCount }} Success / {{ item.failCount }} Failed\r\n </div>\r\n\r\n <div class=\"status-modal-state error\" *ngIf=\"item.status === 'error'\">\r\n <span class=\"me-1\">\u2716</span> {{ item.error || 'Failed' }}\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"status-modal-footer\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary\" (click)=\"closeSavePopup()\">Back to Preview</button>\r\n <div class=\"d-flex justify-content-end\">\r\n <button\r\n [disabled]=\"showLoader\" [ng2-loading]=\"showLoader\"\r\n *ngIf=\"allSaveStepsSucceeded()\"\r\n type=\"button\"\r\n class=\"btn btn-primary\"\r\n (click)=\"goToDashboard()\"\r\n >\r\n Go to Dashboard\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBackConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Leave this page?</h4>\r\n <p class=\"text-muted mb-4\">Your data might be lost if you go back now.</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary\" (click)=\"stayOnPreview()\">Stay</button>\r\n <button type=\"button\" class=\"btn btn-danger\" (click)=\"proceedBack()\">Proceed Back</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:space-between;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}\n"] }]
|
|
30877
|
+
args: [{ selector: 'app-preview', standalone: false, template: "\r\n<div class=\"preview-page-header\">\r\n <h2 class=\"preview-title\">Confirm based on your resume</h2>\r\n <p class=\"preview-subtitle\">Please confirm everything is accurate. It is based on your resume</p>\r\n</div>\r\n\r\n\r\n<div class=\"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\">\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 </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 text-end\">\r\n <button class=\"btn btn-sm btn-primary px-4\" (click)=\"toggleEdit()\">Edit Details</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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.firstName\"\r\n name=\"fName\"\r\n placeholder=\"First Name\"\r\n required\r\n #fName=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"fName.invalid && (fName.dirty || fName.touched)\">First name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.lastName\"\r\n name=\"lName\"\r\n placeholder=\"Last Name\"\r\n required\r\n #lName=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"lName.invalid && (lName.dirty || lName.touched)\">Last name is 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\r\n type=\"email\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.email\"\r\n name=\"email\"\r\n placeholder=\"Email\"\r\n required\r\n email\r\n #email=\"ngModel\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"tempProfile.phone\"\r\n (ngModelChange)=\"tempProfile.phone = sanitizePhone($event)\"\r\n name=\"phone\"\r\n placeholder=\"Phone (10 digits)\"\r\n required\r\n pattern=\"^\\d{10}$\"\r\n maxlength=\"10\"\r\n inputmode=\"numeric\"\r\n #phone=\"ngModel\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.address\"\r\n name=\"address\"\r\n placeholder=\"Home Address\"\r\n required\r\n #address=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"address.invalid && (address.dirty || address.touched)\">Home address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.city\"\r\n name=\"city\"\r\n placeholder=\"City\"\r\n required\r\n #city=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"city.invalid && (city.dirty || city.touched)\">City is required</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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.state\"\r\n name=\"state\"\r\n placeholder=\"State\"\r\n required\r\n #state=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"state.invalid && (state.dirty || state.touched)\">State is 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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.zipCode\"\r\n name=\"zipCode\"\r\n placeholder=\"Zip Code\"\r\n required\r\n #zipCode=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"zipCode.invalid && (zipCode.dirty || zipCode.touched)\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.country\"\r\n name=\"country\"\r\n placeholder=\"Country\"\r\n required\r\n #country=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"country.invalid && (country.dirty || country.touched)\">Country 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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.jobTitle\"\r\n name=\"jobTitle\"\r\n placeholder=\"Job Title\"\r\n required\r\n #jobTitle=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *ngIf=\"jobTitle.invalid && (jobTitle.dirty || jobTitle.touched)\">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\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"number\"\r\n class=\"form-control\"\r\n [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n name=\"yearsOfExperience\"\r\n placeholder=\"Years of Experience\"\r\n required\r\n min=\"0\"\r\n #yearsOfExperience=\"ngModel\"\r\n >\r\n <div class=\"small text-danger mt-1\" *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\" (click)=\"save()\">Save Changes</button>\r\n </div>\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=\"workSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add work experience\"\r\n (click)=\"addJob()\"\r\n >\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\">Missing required fields</div>\r\n <div class=\"small\">Add at least one work experience.</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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\"\r\n name=\"newJobTitle\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\"\r\n name=\"newCompany\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\"\r\n name=\"newCity\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.startDate\"\r\n (ngModelChange)=\"patchTempJob({ startDate: $event })\"\r\n name=\"newStartDate\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"tempJob()?.endDate\"\r\n (ngModelChange)=\"patchTempJob({ endDate: $event })\"\r\n name=\"newEndDate\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\" *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 <div class=\"col-md-4 d-flex align-items-end\">\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\"\r\n name=\"newIsCurrent\"\r\n id=\"newIsCurrent\"\r\n />\r\n <label class=\"form-check-label\" for=\"newIsCurrent\">Current</label>\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">RESPONSIBILITIES (one per line)</label>\r\n <textarea\r\n rows=\"4\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\"\r\n name=\"newResponsibilities\"\r\n ></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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\"\r\n name=\"newWorkAttachment\"\r\n />\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\" (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\" (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingWork\" (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : 'Save' }}\r\n </button>\r\n </div>\r\n </div>\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 <small class=\"text-muted\">\r\n {{ job.company }} \u2022 {{ formatMonthYear(job.startDate) }} - {{ job.isCurrent ? 'Present' : formatMonthYear(job.endDate) }}\r\n </small>\r\n <div\r\n *ngIf=\"editingJobIndex() !== i && (workIssuesByIndex()[i] || []).length > 0\"\r\n class=\"alert alert-warning py-1 px-2 mt-2\"\r\n >\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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditJob(i)\"\r\n title=\"Edit\"\r\n >\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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteJob(i);\"\r\n title=\"Delete\"\r\n >\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 <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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\"\r\n name=\"jobTitle{{ i }}\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\"\r\n name=\"company{{ i }}\"\r\n />\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=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">CITY <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\"\r\n name=\"city{{ i }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempJob()?.startDate\"\r\n (ngModelChange)=\"patchTempJob({ startDate: $event })\"\r\n name=\"startDate{{ i }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"tempJob()?.endDate\"\r\n (ngModelChange)=\"patchTempJob({ endDate: $event })\"\r\n name=\"endDate{{ i }}\"\r\n />\r\n <div\r\n class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\"\r\n >\r\n End date is required\r\n </div>\r\n <div class=\"small text-danger mt-1\" *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-md-4 d-flex align-items-end\">\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\"\r\n name=\"isCurrent{{ i }}\"\r\n id=\"isCurrent{{ i }}\"\r\n />\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-12\">\r\n <label class=\"small text-muted d-block\">RESPONSIBILITIES (one per line)</label>\r\n <textarea\r\n rows=\"4\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\"\r\n name=\"responsibilities{{ i }}\"\r\n ></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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\"\r\n name=\"workAttachment{{ i }}\"\r\n />\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\" (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\" (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingWork\" (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : 'Save' }}\r\n </button>\r\n </div> \r\n\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\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=\"certificationsSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add certification\"\r\n (click)=\"addCertification()\"\r\n >\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n <div *ngIf=\"certs().length === 0 && !isAddingCertification() && editingCertificationIndex() === null\" 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\">Add at least one certification.</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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\"\r\n name=\"newCertName\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is 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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\"\r\n name=\"newCertOrg\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\"\r\n name=\"newCertState\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Credential ID</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\"\r\n name=\"newCertCredentialId\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issueDate || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issueDate: $event || null })\"\r\n name=\"newCertIssueDate\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.expiryDate || ''\"\r\n (ngModelChange)=\"patchTempCertification({ expiryDate: $event || null })\"\r\n name=\"newCertExpiryDate\"\r\n />\r\n <div class=\"small text-danger mt-1\" *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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\"\r\n name=\"newCertAttachment\"\r\n />\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\" (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\" (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\" (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : 'Save' }}\r\n </button> </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 <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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditCertification(ci)\"\r\n title=\"Edit\"\r\n >\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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteCertification(ci)\"\r\n title=\"Delete\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\"\r\n name=\"certName{{ ci }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is 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\r\n type=\"text\"\r\n 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 />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\"\r\n name=\"certState{{ ci }}\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Credential ID</label>\r\n <input\r\n type=\"text\"\r\n 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 />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issueDate || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issueDate: $event || null })\"\r\n name=\"certIssue{{ ci }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.expiryDate || ''\"\r\n (ngModelChange)=\"patchTempCertification({ expiryDate: $event || null })\"\r\n name=\"certExpiry{{ ci }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\"\r\n name=\"certAttachment{{ ci }}\"\r\n />\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\" (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\" (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\" (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : 'Save' }}\r\n </button> </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=\"licensesSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add license\"\r\n (click)=\"addLicense()\"\r\n >\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n <div *ngIf=\"licenses().length === 0 && !isAddingLicense() && editingLicenseIndex() === null\" 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\">Add at least one license.</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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\"\r\n name=\"newLicName\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\"\r\n name=\"newLicAuthority\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\"\r\n name=\"newLicNumber\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\"\r\n name=\"newLicState\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.issueDate || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issueDate: $event || null })\"\r\n name=\"newLicIssueDate\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.expiryDate || ''\"\r\n (ngModelChange)=\"patchTempLicense({ expiryDate: $event || null })\"\r\n name=\"newLicExpiryDate\"\r\n />\r\n <div class=\"small text-danger mt-1\" *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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\"\r\n name=\"newLicenseAttachment\"\r\n />\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\" (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\" (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : 'Save' }}\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 <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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditLicense(li)\"\r\n title=\"Edit\"\r\n >\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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteLicense(li)\"\r\n title=\"Delete\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\"\r\n name=\"licName{{ li }}\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\"\r\n name=\"licAuthority{{ li }}\"\r\n />\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\"\r\n name=\"licNumber{{ li }}\"\r\n />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\"\r\n name=\"licState{{ li }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.issueDate || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issueDate: $event || null })\"\r\n name=\"licIssue{{ li }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempLicense()?.expiryDate || ''\"\r\n (ngModelChange)=\"patchTempLicense({ expiryDate: $event || null })\"\r\n name=\"licExpiry{{ li }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *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\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\"\r\n class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\"\r\n name=\"licenseAttachment{{ li }}\"\r\n />\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\" (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\" (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : 'Save' }}\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=\"toolsSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add tool\"\r\n (click)=\"addTool()\"\r\n >\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\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\r\n type=\"button\"\r\n class=\"btn btn-light border rounded-pill d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openToolEditor(ti)\"\r\n title=\"Edit\"\r\n >\r\n <span class=\"fw-normal text-dark\">{{ tool }}</span>\r\n <span\r\n *ngIf=\"(toolIssuesByIndex()[ti] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\"\r\n >\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\r\n 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;\"\r\n title=\"Delete tool\"\r\n (click)=\"deleteTool(ti)\"\r\n >\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\r\n *ngIf=\"isToolEditorOpen()\"\r\n class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 2000;\"\r\n (click)=\"closeToolEditor()\"\r\n >\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\" (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') }}</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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"toolForm()?.name\"\r\n (ngModelChange)=\"patchToolForm({ name: $event })\"\r\n name=\"toolName\"\r\n />\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-12\">\r\n <label class=\"small text-muted d-block\">Service Provider</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"toolForm()?.providerName\"\r\n (ngModelChange)=\"patchToolForm({ providerName: $event })\"\r\n name=\"toolProvider\"\r\n placeholder=\"Service Provider\"\r\n />\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 class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button\r\n *ngFor=\"let s of [1,2,3,4,5]\"\r\n type=\"button\"\r\n class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempToolStars(s)\"\r\n [attr.aria-label]=\"'Set rating ' + s\"\r\n >\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\r\n type=\"number\"\r\n class=\"form-control\"\r\n [ngModel]=\"toolForm()?.year\"\r\n (ngModelChange)=\"patchToolForm({ year: $event === '' ? null : +$event })\"\r\n name=\"toolYear\"\r\n min=\"1\"\r\n max=\"30\"\r\n placeholder=\"Years of Experience\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"toolForm()?.year === null || toolForm()?.year === undefined\">Years of experience is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-check form-switch mt-2\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [ngModel]=\"toolForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchToolForm({ profileVisibility: $event })\"\r\n name=\"toolVisible\"\r\n id=\"toolVisible\"\r\n />\r\n <label class=\"form-check-label\" 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\r\n rows=\"4\"\r\n class=\"form-control\"\r\n [ngModel]=\"toolForm()?.notes\"\r\n (ngModelChange)=\"patchToolForm({ notes: $event })\"\r\n name=\"toolNotes\"\r\n placeholder=\"Comment your tool here...\"\r\n ></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\r\n *ngIf=\"!isAddingTool() && editingToolIndex() !== null\"\r\n type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\"\r\n (click)=\"deleteTool(editingToolIndex()!)\"\r\n >\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\" (click)=\"saveToolEditor()\">\r\n {{ isAddingTool() ? 'Save' : 'Update' }}\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=\"skillsSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add skill\"\r\n (click)=\"addSkill()\"\r\n >\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\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\r\n type=\"button\"\r\n class=\"btn btn-light border rounded-pill d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openSkillEditor(si)\"\r\n title=\"Edit\"\r\n >\r\n <span class=\"fw-normal text-dark\">{{ skill }}</span>\r\n <span\r\n *ngIf=\"(skillIssuesByIndex()[si] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\"\r\n >\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\r\n 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;\"\r\n title=\"Delete skill\"\r\n (click)=\"deleteSkill(si); $event.stopPropagation()\"\r\n >\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\r\n <!-- Skill edit panel (overlay) -->\r\n <div\r\n *ngIf=\"isSkillEditorOpen()\"\r\n class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 2000;\"\r\n (click)=\"closeSkillEditor()\"\r\n >\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\" (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') }}</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\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"skillForm()?.name\"\r\n (ngModelChange)=\"patchSkillForm({ name: $event })\"\r\n name=\"skillName\"\r\n />\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-12\">\r\n <label class=\"small text-muted d-block\">Service Provider</label>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n [ngModel]=\"skillForm()?.providerName\"\r\n (ngModelChange)=\"patchSkillForm({ providerName: $event })\"\r\n name=\"skillProvider\"\r\n placeholder=\"Service Provider\"\r\n />\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 class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button\r\n *ngFor=\"let s of [1,2,3,4,5]\"\r\n type=\"button\"\r\n class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempSkillStars(s)\"\r\n [attr.aria-label]=\"'Set rating ' + s\"\r\n >\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</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\r\n type=\"number\"\r\n class=\"form-control\"\r\n [ngModel]=\"skillForm()?.year\"\r\n (ngModelChange)=\"patchSkillForm({ year: $event === '' ? null : +$event })\"\r\n name=\"skillYear\"\r\n min=\"1\"\r\n max=\"30\"\r\n placeholder=\"Years of Experience\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"skillForm()?.year === null || skillForm()?.year === undefined\">Years of experience is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-check form-switch mt-2\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [ngModel]=\"skillForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchSkillForm({ profileVisibility: $event })\"\r\n name=\"skillVisible\"\r\n id=\"skillVisible\"\r\n />\r\n <label class=\"form-check-label\" 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\r\n rows=\"4\"\r\n class=\"form-control\"\r\n [ngModel]=\"skillForm()?.notes\"\r\n (ngModelChange)=\"patchSkillForm({ notes: $event })\"\r\n name=\"skillNotes\"\r\n placeholder=\"Comment your skill here...\"\r\n ></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\r\n *ngIf=\"!isAddingSkill() && editingSkillIndex() !== null\"\r\n type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\"\r\n (click)=\"deleteSkill(editingSkillIndex()!)\"\r\n >\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\" (click)=\"saveSkillEditor()\">\r\n {{ isAddingSkill() ? 'Save' : 'Update' }}\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=\"educationSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n </div>\r\n <button\r\n 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;\"\r\n title=\"Add education\"\r\n (click)=\"addEducation()\"\r\n >\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\" 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\">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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\"\r\n name=\"newEduDegree\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is 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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\"\r\n name=\"newEduInstitution\"\r\n />\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 <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\"\r\n name=\"newEduDegreeType\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">START DATE <span class=\"text-danger\">*</span></label>\r\n <input\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.startDate\"\r\n (ngModelChange)=\"patchTempEducation({ startDate: $event })\"\r\n name=\"newEduStartDate\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.endDate\"\r\n (ngModelChange)=\"patchTempEducation({ endDate: $event })\"\r\n name=\"newEduEndDate\"\r\n />\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\" *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\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\" (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" (click)=\"saveEducation()\">Save</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 <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\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditEducation(ei)\"\r\n title=\"Edit\"\r\n >\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteEducation(ei)\"\r\n title=\"Delete\"\r\n >\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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\"\r\n name=\"eduDegree{{ ei }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is 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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\"\r\n name=\"eduInstitution{{ ei }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.institution)\">Institution name is 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 <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\"\r\n name=\"eduDegreeType{{ ei }}\"\r\n />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is 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\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\"\r\n name=\"eduCity{{ ei }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.startDate\"\r\n (ngModelChange)=\"patchTempEducation({ startDate: $event })\"\r\n name=\"eduStartDate{{ ei }}\"\r\n />\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\r\n type=\"month\"\r\n class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempEducation()?.endDate\"\r\n (ngModelChange)=\"patchTempEducation({ endDate: $event })\"\r\n name=\"eduEndDate{{ ei }}\"\r\n />\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\" *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\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\" (click)=\"saveEducation()\">Save</button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"educationList().length === 0\" class=\"text-muted small\">No education added.</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex gap-2 justify-content-center mt-5\">\r\n <button class=\"btn btn-outline-secondary px-5\" (click)=\"onBackClick()\">Back</button>\r\n <button\r\n class=\"btn btn-primary px-5 shadow\"\r\n [disabled]=\"!canConfirmAndContinue()\"\r\n [title]=\"canConfirmAndContinue() ? '' : 'Please fill all required fields in all mandatory sections.'\"\r\n (click)=\"saveResumedetails()\"\r\n >\r\n Confirm All & Continue\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=\"showPopup\" >\r\n <div class=\"status-modal-card\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"status-modal-header\">\r\n <h3 class=\"mb-1\">Saving Resume Details</h3>\r\n <p class=\"text-muted mb-0\">Please wait while we process each section.</p>\r\n </div>\r\n\r\n <div class=\"status-modal-body\">\r\n <div class=\"status-modal-row\" *ngFor=\"let item of statusList\">\r\n <div class=\"status-modal-name\">{{ item.name }}</div>\r\n\r\n <div class=\"status-modal-state pending\" *ngIf=\"item.status === 'pending'\">\r\n <span class=\"spinner-border spinner-border-sm me-2\"></span> In progress\r\n </div>\r\n\r\n <div class=\"status-modal-state success\" *ngIf=\"item.status === 'success'\">\r\n <span class=\"me-1\">\u2713</span> Saved\r\n </div>\r\n\r\n <div class=\"status-modal-state partial\" *ngIf=\"item.status === 'partial'\">\r\n <span class=\"me-1\">!</span> {{ item.successCount }} Success / {{ item.failCount }} Failed\r\n </div>\r\n\r\n <div class=\"status-modal-state error\" *ngIf=\"item.status === 'error'\">\r\n <span class=\"me-1\">\u2716</span> {{ item.error || 'Failed' }}\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"status-modal-footer\">\r\n <!-- <button type=\"button\" class=\"btn btn-outline-secondary\" (click)=\"closeSavePopup()\">Back to Preview</button> -->\r\n <div class=\"d-flex justify-content-end\">\r\n <button\r\n [disabled]=\"showLoader\" [ng2-loading]=\"showLoader\"\r\n *ngIf=\"allSaveStepsSucceeded()\"\r\n type=\"button\"\r\n class=\"btn btn-primary\"\r\n (click)=\"goToDashboard()\"\r\n >\r\n Go to Dashboard\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBackConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Leave this page?</h4>\r\n <p class=\"text-muted mb-4\">Your data might be lost if you go back now.</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary\" (click)=\"stayOnPreview()\">Stay</button>\r\n <button type=\"button\" class=\"btn btn-danger\" (click)=\"proceedBack()\">Proceed Back</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}\n"] }]
|
|
30879
30878
|
}], ctorParameters: () => [{ type: CredentialingStore }, { type: FileService }, { type: UserSkillSetService }, { type: UserToolService }, { type: UserDocumentService }, { type: UserEducationService }, { type: UserDetailService }, { type: UserExperienceService }, { type: i6.TokenService }, { type: undefined, decorators: [{
|
|
30880
30879
|
type: Inject,
|
|
30881
30880
|
args: [LIBRARY_CONFIG]
|
|
@@ -32016,7 +32015,7 @@ class InitialProcessComponent {
|
|
|
32016
32015
|
var userDetail = this.userForm.value;
|
|
32017
32016
|
var findType = this.userViewRoles.find((a) => { return a.selected; })?.code;
|
|
32018
32017
|
return {
|
|
32019
|
-
targetUserId: this.userId,
|
|
32018
|
+
// targetUserId: this.userId,
|
|
32020
32019
|
userName: this.users?.text,
|
|
32021
32020
|
providerType: findType ?? ProviderType.ServiceProvider,
|
|
32022
32021
|
providerName: provider.companyName,
|