@idsoftsource/initial-process 3.2.5 → 3.2.8
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.
|
@@ -1056,6 +1056,7 @@ class CredentialingStore {
|
|
|
1056
1056
|
this.profileSignal.set(null);
|
|
1057
1057
|
this.resumeSkillMeta.set({});
|
|
1058
1058
|
this.resumeToolMeta.set({});
|
|
1059
|
+
this.resumeProfessionMeta.set({});
|
|
1059
1060
|
this.uploadedResumeFile.set(null);
|
|
1060
1061
|
this.stepView.set('add');
|
|
1061
1062
|
this.toolStepView.set('add');
|
|
@@ -1183,6 +1184,8 @@ class CredentialingStore {
|
|
|
1183
1184
|
resumeSkillMeta = signal({}, ...(ngDevMode ? [{ debugName: "resumeSkillMeta" }] : []));
|
|
1184
1185
|
// Extra per-tool details for the resume-preview flow (indexed by tool position)
|
|
1185
1186
|
resumeToolMeta = signal({}, ...(ngDevMode ? [{ debugName: "resumeToolMeta" }] : []));
|
|
1187
|
+
// Extra per-profession details for the resume-preview flow (indexed by profession position)
|
|
1188
|
+
resumeProfessionMeta = signal({}, ...(ngDevMode ? [{ debugName: "resumeProfessionMeta" }] : []));
|
|
1186
1189
|
// Expose it as a read-only signal for components
|
|
1187
1190
|
profile = this.profileSignal();
|
|
1188
1191
|
// Step 3: Producer Type / Jobs
|
|
@@ -1205,6 +1208,9 @@ class CredentialingStore {
|
|
|
1205
1208
|
setResumeToolMeta(index, meta) {
|
|
1206
1209
|
this.resumeToolMeta.update(curr => ({ ...curr, [index]: meta }));
|
|
1207
1210
|
}
|
|
1211
|
+
setResumeProfessionMeta(index, meta) {
|
|
1212
|
+
this.resumeProfessionMeta.update(curr => ({ ...curr, [index]: meta }));
|
|
1213
|
+
}
|
|
1208
1214
|
removeRole(role) {
|
|
1209
1215
|
const roles = this.selectedRoles().filter(r => r !== role);
|
|
1210
1216
|
this.selectedRoles.set(roles);
|
|
@@ -2803,6 +2809,86 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
2803
2809
|
}]
|
|
2804
2810
|
}], ctorParameters: () => [{ type: i1.HttpClient }] });
|
|
2805
2811
|
|
|
2812
|
+
class ProfessionService {
|
|
2813
|
+
http = inject(HttpClient);
|
|
2814
|
+
baseUrl = 'Profession';
|
|
2815
|
+
getProfessions(query = {}) {
|
|
2816
|
+
return this.http.get(this.baseUrl + '/GetProfession', {
|
|
2817
|
+
params: this.buildParams(query),
|
|
2818
|
+
});
|
|
2819
|
+
}
|
|
2820
|
+
buildParams(query) {
|
|
2821
|
+
let params = new HttpParams();
|
|
2822
|
+
if (!query)
|
|
2823
|
+
return params;
|
|
2824
|
+
Object.keys(query).forEach(key => {
|
|
2825
|
+
if (query[key] !== null && query[key] !== undefined) {
|
|
2826
|
+
params = params.set(key, query[key]);
|
|
2827
|
+
}
|
|
2828
|
+
});
|
|
2829
|
+
return params;
|
|
2830
|
+
}
|
|
2831
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProfessionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2832
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProfessionService, providedIn: 'root' });
|
|
2833
|
+
}
|
|
2834
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProfessionService, decorators: [{
|
|
2835
|
+
type: Injectable,
|
|
2836
|
+
args: [{
|
|
2837
|
+
providedIn: 'root',
|
|
2838
|
+
}]
|
|
2839
|
+
}] });
|
|
2840
|
+
|
|
2841
|
+
class UserProfessionService {
|
|
2842
|
+
httpClient;
|
|
2843
|
+
constructor(httpClient) {
|
|
2844
|
+
this.httpClient = httpClient;
|
|
2845
|
+
}
|
|
2846
|
+
// --------------------------------
|
|
2847
|
+
// Create User Profession
|
|
2848
|
+
// --------------------------------
|
|
2849
|
+
createUserProfession(models) {
|
|
2850
|
+
return this.httpClient.post(`FrontEndUser/CreateUserProfession`, models);
|
|
2851
|
+
}
|
|
2852
|
+
// --------------------------------
|
|
2853
|
+
// Update User Profession
|
|
2854
|
+
// --------------------------------
|
|
2855
|
+
updateUserProfession(model) {
|
|
2856
|
+
return this.httpClient.put(`FrontEndUser/UpdateUserProfession`, model);
|
|
2857
|
+
}
|
|
2858
|
+
// --------------------------------
|
|
2859
|
+
// Bulk Delete User Profession
|
|
2860
|
+
// --------------------------------
|
|
2861
|
+
bulkDelete(ids) {
|
|
2862
|
+
return this.httpClient.post(`FrontEndUser/UserProfessionBulkDelete`, ids);
|
|
2863
|
+
}
|
|
2864
|
+
// --------------------------------
|
|
2865
|
+
// Get User Profession (Gridify)
|
|
2866
|
+
// --------------------------------
|
|
2867
|
+
getUserProfession(query) {
|
|
2868
|
+
return this.httpClient.get(`FrontEndUser/GetUserProfession`, { params: this.buildParams(query) });
|
|
2869
|
+
}
|
|
2870
|
+
buildParams(query) {
|
|
2871
|
+
let params = new HttpParams();
|
|
2872
|
+
if (!query)
|
|
2873
|
+
return params;
|
|
2874
|
+
Object.keys(query).forEach(key => {
|
|
2875
|
+
const value = query[key];
|
|
2876
|
+
if (value !== null && value !== undefined) {
|
|
2877
|
+
params = params.set(key, value);
|
|
2878
|
+
}
|
|
2879
|
+
});
|
|
2880
|
+
return params;
|
|
2881
|
+
}
|
|
2882
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: UserProfessionService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2883
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: UserProfessionService, providedIn: 'root' });
|
|
2884
|
+
}
|
|
2885
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: UserProfessionService, decorators: [{
|
|
2886
|
+
type: Injectable,
|
|
2887
|
+
args: [{
|
|
2888
|
+
providedIn: 'root',
|
|
2889
|
+
}]
|
|
2890
|
+
}], ctorParameters: () => [{ type: i1.HttpClient }] });
|
|
2891
|
+
|
|
2806
2892
|
class UserDocumentService {
|
|
2807
2893
|
httpClient;
|
|
2808
2894
|
// 🔹 Base controller name
|
|
@@ -3021,6 +3107,8 @@ class PreviewComponent {
|
|
|
3021
3107
|
fileService;
|
|
3022
3108
|
userSkillSetService;
|
|
3023
3109
|
userToolService;
|
|
3110
|
+
professionService;
|
|
3111
|
+
userProfessionService;
|
|
3024
3112
|
userDocumentService;
|
|
3025
3113
|
userEducation;
|
|
3026
3114
|
userDetailService;
|
|
@@ -3084,12 +3172,19 @@ class PreviewComponent {
|
|
|
3084
3172
|
hasUserDetailData = false;
|
|
3085
3173
|
isSavingSkill = false;
|
|
3086
3174
|
isSavingTool = false;
|
|
3175
|
+
isSavingProfession = false;
|
|
3176
|
+
professionTypes = [];
|
|
3177
|
+
userProfessionOptions = [];
|
|
3087
3178
|
showBulkSkillConfirm = false;
|
|
3088
3179
|
bulkSkillStars = 0;
|
|
3089
3180
|
bulkSkillYear = null;
|
|
3181
|
+
bulkSkillProfessionId = null;
|
|
3182
|
+
bulkSkillProfessionName = '';
|
|
3090
3183
|
showBulkToolConfirm = false;
|
|
3091
3184
|
bulkToolStars = 0;
|
|
3092
3185
|
bulkToolYear = null;
|
|
3186
|
+
bulkToolProfessionId = null;
|
|
3187
|
+
bulkToolProfessionName = '';
|
|
3093
3188
|
workConfirmAllQueue = [];
|
|
3094
3189
|
educationConfirmAllQueue = [];
|
|
3095
3190
|
payloadUserId;
|
|
@@ -3109,12 +3204,14 @@ class PreviewComponent {
|
|
|
3109
3204
|
licenseServerIds = {};
|
|
3110
3205
|
skillServerIds = {};
|
|
3111
3206
|
toolServerIds = {};
|
|
3207
|
+
professionServerIds = {};
|
|
3112
3208
|
workExperienceLocallySaved = {};
|
|
3113
3209
|
educationLocallySaved = {};
|
|
3114
3210
|
certificationLocallySaved = {};
|
|
3115
3211
|
licenseLocallySaved = {};
|
|
3116
3212
|
skillLocallySaved = {};
|
|
3117
3213
|
toolLocallySaved = {};
|
|
3214
|
+
professionLocallySaved = {};
|
|
3118
3215
|
monthDateCache = new Map();
|
|
3119
3216
|
uploadFolderBySection = {
|
|
3120
3217
|
work: 'Experience',
|
|
@@ -3151,11 +3248,13 @@ class PreviewComponent {
|
|
|
3151
3248
|
{ name: 'Insurance Agency', value: 'InsuranceAgency', img: 'assets/images/users/insurance.svg', selected: false, code: ProviderType.InsuranceAgency, id: '00000000-0000-0000-0000-000000000000', roleId: '00000000-0000-0000-0000-000000000000' },
|
|
3152
3249
|
{ name: 'Real Estate Company', value: 'RealEstateCompany', img: 'assets/images/users/realestate.svg', selected: false, code: ProviderType.RealEstateAgency, id: '00000000-0000-0000-0000-000000000000', roleId: '00000000-0000-0000-0000-000000000000' },
|
|
3153
3250
|
];
|
|
3154
|
-
constructor(store, fileService, userSkillSetService, userToolService, userDocumentService, userEducation, userDetailService, userExperienceService, tokenService, roleContextService, providerService, frontendProviderService, cdr, libConfig) {
|
|
3251
|
+
constructor(store, fileService, userSkillSetService, userToolService, professionService, userProfessionService, userDocumentService, userEducation, userDetailService, userExperienceService, tokenService, roleContextService, providerService, frontendProviderService, cdr, libConfig) {
|
|
3155
3252
|
this.store = store;
|
|
3156
3253
|
this.fileService = fileService;
|
|
3157
3254
|
this.userSkillSetService = userSkillSetService;
|
|
3158
3255
|
this.userToolService = userToolService;
|
|
3256
|
+
this.professionService = professionService;
|
|
3257
|
+
this.userProfessionService = userProfessionService;
|
|
3159
3258
|
this.userDocumentService = userDocumentService;
|
|
3160
3259
|
this.userEducation = userEducation;
|
|
3161
3260
|
this.userDetailService = userDetailService;
|
|
@@ -3195,6 +3294,7 @@ class PreviewComponent {
|
|
|
3195
3294
|
}
|
|
3196
3295
|
this.prefillSectionFieldsFromBasicDetails();
|
|
3197
3296
|
this.expYears = Array.from({ length: 30 }, (_, i) => i + 1);
|
|
3297
|
+
this.loadProfessionTypes();
|
|
3198
3298
|
await this.loadSavedSectionsFromApis();
|
|
3199
3299
|
if (this.roleData?.role?.name === 'Provider') {
|
|
3200
3300
|
const storedCompanyDetails = this.store.profileSignal()?.companyDetails;
|
|
@@ -3248,6 +3348,171 @@ class PreviewComponent {
|
|
|
3248
3348
|
licenses = computed(() => this.store.profileSignal()?.licenses || [], ...(ngDevMode ? [{ debugName: "licenses" }] : []));
|
|
3249
3349
|
skills = computed(() => this.store.profileSignal()?.skills || [], ...(ngDevMode ? [{ debugName: "skills" }] : []));
|
|
3250
3350
|
tools = computed(() => this.store.profileSignal()?.tools || [], ...(ngDevMode ? [{ debugName: "tools" }] : []));
|
|
3351
|
+
professions = computed(() => this.store.profileSignal()?.professions || [], ...(ngDevMode ? [{ debugName: "professions" }] : []));
|
|
3352
|
+
async refreshUserProfessionOptions() {
|
|
3353
|
+
try {
|
|
3354
|
+
const res = await firstValueFrom(this.userProfessionService.getUserProfession(this.buildSectionQuery('professionName asc', true)));
|
|
3355
|
+
this.userProfessionOptions = Array.isArray(res?.data) ? res.data : [];
|
|
3356
|
+
this.applySavedProfessionsToTable();
|
|
3357
|
+
}
|
|
3358
|
+
catch (err) {
|
|
3359
|
+
console.error('Unable to refresh user profession options', err);
|
|
3360
|
+
}
|
|
3361
|
+
}
|
|
3362
|
+
loadProfessionTypes() {
|
|
3363
|
+
this.professionService.getProfessions({ filter: 'isActive=true', orderBy: 'professionName asc' }).subscribe({
|
|
3364
|
+
next: (res) => { this.professionTypes = res?.data || []; },
|
|
3365
|
+
error: () => { this.professionTypes = []; }
|
|
3366
|
+
});
|
|
3367
|
+
}
|
|
3368
|
+
// Profession table: select-and-fill-in-place (replaces the modal editor UX)
|
|
3369
|
+
professionSearchQry = null;
|
|
3370
|
+
isSavingProfessionsTable = false;
|
|
3371
|
+
savedProfessionTypeIds = new Set();
|
|
3372
|
+
professionTypeServerIds = {};
|
|
3373
|
+
professionSavedSnapshots = {};
|
|
3374
|
+
professionSelections = {};
|
|
3375
|
+
applySavedProfessionsToTable() {
|
|
3376
|
+
this.professionServerIds = {};
|
|
3377
|
+
this.professionSavedSnapshots = {};
|
|
3378
|
+
(this.userProfessionOptions ?? []).forEach((item) => {
|
|
3379
|
+
const typeId = item?.professionId;
|
|
3380
|
+
if (!typeId)
|
|
3381
|
+
return;
|
|
3382
|
+
this.savedProfessionTypeIds.add(typeId);
|
|
3383
|
+
this.professionTypeServerIds[typeId] = item.id;
|
|
3384
|
+
const snapshot = {
|
|
3385
|
+
starRating: item.starRating ?? 0,
|
|
3386
|
+
year: item.year ?? null,
|
|
3387
|
+
profileVisibility: !!item.profileVisibility,
|
|
3388
|
+
notes: item.notes ?? '',
|
|
3389
|
+
};
|
|
3390
|
+
this.professionSavedSnapshots[typeId] = snapshot;
|
|
3391
|
+
this.professionSelections[typeId] = { selected: true, ...snapshot };
|
|
3392
|
+
});
|
|
3393
|
+
}
|
|
3394
|
+
hasProfessionRowChanged(id) {
|
|
3395
|
+
const snap = this.professionSavedSnapshots[id];
|
|
3396
|
+
const sel = this.professionSelections[id];
|
|
3397
|
+
if (!snap || !sel)
|
|
3398
|
+
return false;
|
|
3399
|
+
return snap.starRating !== (sel.starRating ?? 0)
|
|
3400
|
+
|| snap.year !== (sel.year ?? null)
|
|
3401
|
+
|| snap.profileVisibility !== !!sel.profileVisibility
|
|
3402
|
+
|| snap.notes !== (sel.notes ?? '');
|
|
3403
|
+
}
|
|
3404
|
+
get filteredProfessionTypes() {
|
|
3405
|
+
const q = (this.professionSearchQry || '').trim().toLowerCase();
|
|
3406
|
+
if (!q)
|
|
3407
|
+
return this.professionTypes;
|
|
3408
|
+
return this.professionTypes.filter((p) => (p.professionName || '').toLowerCase().includes(q));
|
|
3409
|
+
}
|
|
3410
|
+
get professionSubmitLabel() {
|
|
3411
|
+
const selectedIds = Object.keys(this.professionSelections).filter(id => this.professionSelections[id].selected);
|
|
3412
|
+
const hasNew = selectedIds.some(id => !this.savedProfessionTypeIds.has(id));
|
|
3413
|
+
const hasChanged = selectedIds.some(id => this.savedProfessionTypeIds.has(id) && this.hasProfessionRowChanged(id));
|
|
3414
|
+
if (hasNew && hasChanged)
|
|
3415
|
+
return 'Save Changes';
|
|
3416
|
+
if (hasChanged)
|
|
3417
|
+
return 'Update Profession';
|
|
3418
|
+
return 'Save Profession';
|
|
3419
|
+
}
|
|
3420
|
+
isProfessionSaved(id) {
|
|
3421
|
+
return this.savedProfessionTypeIds.has(id);
|
|
3422
|
+
}
|
|
3423
|
+
get selectedProfessionCount() {
|
|
3424
|
+
return Object.keys(this.professionSelections).filter(id => {
|
|
3425
|
+
const sel = this.professionSelections[id];
|
|
3426
|
+
if (!sel.selected)
|
|
3427
|
+
return false;
|
|
3428
|
+
if (!this.savedProfessionTypeIds.has(id))
|
|
3429
|
+
return true;
|
|
3430
|
+
return this.hasProfessionRowChanged(id);
|
|
3431
|
+
}).length;
|
|
3432
|
+
}
|
|
3433
|
+
getProfessionSelection(id) {
|
|
3434
|
+
if (!this.professionSelections[id]) {
|
|
3435
|
+
this.professionSelections[id] = { selected: false, starRating: 0, year: null, profileVisibility: false, notes: '' };
|
|
3436
|
+
}
|
|
3437
|
+
return this.professionSelections[id];
|
|
3438
|
+
}
|
|
3439
|
+
onProfessionRowCheck(profession, event) {
|
|
3440
|
+
const checked = event.target.checked;
|
|
3441
|
+
this.getProfessionSelection(profession.id).selected = checked;
|
|
3442
|
+
}
|
|
3443
|
+
setProfessionRowStars(profession, stars) {
|
|
3444
|
+
this.getProfessionSelection(profession.id).starRating = stars * 2;
|
|
3445
|
+
}
|
|
3446
|
+
createManualProfessionRow() {
|
|
3447
|
+
const q = this.professionSearchQry?.trim();
|
|
3448
|
+
if (!q)
|
|
3449
|
+
return;
|
|
3450
|
+
const existing = this.professionTypes.find((p) => (p.professionName || '').toLowerCase() === q.toLowerCase());
|
|
3451
|
+
if (existing) {
|
|
3452
|
+
this.getProfessionSelection(existing.id).selected = true;
|
|
3453
|
+
}
|
|
3454
|
+
else {
|
|
3455
|
+
const manual = { id: `manual-${Date.now()}`, professionName: q, professionGroup: '', residentialCommercial: '', isManual: true };
|
|
3456
|
+
this.professionTypes = [manual, ...this.professionTypes];
|
|
3457
|
+
this.getProfessionSelection(manual.id).selected = true;
|
|
3458
|
+
}
|
|
3459
|
+
this.professionSearchQry = null;
|
|
3460
|
+
}
|
|
3461
|
+
buildProfessionPayload(id) {
|
|
3462
|
+
const profType = this.professionTypes.find((p) => p.id === id) || {};
|
|
3463
|
+
const sel = this.professionSelections[id];
|
|
3464
|
+
const emailId = this.resumeData?.basicDetails?.email ?? null;
|
|
3465
|
+
return {
|
|
3466
|
+
forUser: ForUser.ForProducer,
|
|
3467
|
+
targetProviderId: this.effectiveTargetProviderId,
|
|
3468
|
+
providerId: this.effectiveTargetProviderId,
|
|
3469
|
+
targetUserId: this.effectiveTargetUserId,
|
|
3470
|
+
userId: this.effectiveTargetUserId,
|
|
3471
|
+
userName: this.payloadUserName,
|
|
3472
|
+
professionId: profType.isManual ? null : id,
|
|
3473
|
+
professionName: profType.professionName,
|
|
3474
|
+
professionGroup: profType.professionGroup ?? '',
|
|
3475
|
+
residentialCommercial: profType.residentialCommercial ?? '',
|
|
3476
|
+
notes: sel.notes ?? '',
|
|
3477
|
+
year: sel.year ?? null,
|
|
3478
|
+
starRating: sel.starRating ?? null,
|
|
3479
|
+
profileVisibility: sel.profileVisibility ?? false,
|
|
3480
|
+
status: RequestedStatus.InReview,
|
|
3481
|
+
emailId,
|
|
3482
|
+
};
|
|
3483
|
+
}
|
|
3484
|
+
async submitProfessions() {
|
|
3485
|
+
const allSelectedIds = Object.keys(this.professionSelections).filter(id => this.professionSelections[id].selected);
|
|
3486
|
+
const newIds = allSelectedIds.filter(id => !this.savedProfessionTypeIds.has(id));
|
|
3487
|
+
const changedSavedIds = allSelectedIds.filter(id => this.savedProfessionTypeIds.has(id) && this.hasProfessionRowChanged(id));
|
|
3488
|
+
if ((!newIds.length && !changedSavedIds.length) || this.isSavingProfessionsTable)
|
|
3489
|
+
return;
|
|
3490
|
+
this.isSavingProfessionsTable = true;
|
|
3491
|
+
try {
|
|
3492
|
+
if (newIds.length) {
|
|
3493
|
+
const createPayloads = newIds.map(id => this.buildProfessionPayload(id));
|
|
3494
|
+
const res = await firstValueFrom(this.userProfessionService.createUserProfession(createPayloads));
|
|
3495
|
+
if (res?.failed) {
|
|
3496
|
+
console.error('Unable to create user profession(s)', res.failures);
|
|
3497
|
+
return;
|
|
3498
|
+
}
|
|
3499
|
+
}
|
|
3500
|
+
for (const id of changedSavedIds) {
|
|
3501
|
+
const payload = { ...this.buildProfessionPayload(id), id: this.professionTypeServerIds[id] };
|
|
3502
|
+
const res = await firstValueFrom(this.userProfessionService.updateUserProfession(payload));
|
|
3503
|
+
if (res?.failed) {
|
|
3504
|
+
console.error('Unable to update user profession', res.failures);
|
|
3505
|
+
}
|
|
3506
|
+
}
|
|
3507
|
+
await this.refreshUserProfessionOptions();
|
|
3508
|
+
}
|
|
3509
|
+
catch (err) {
|
|
3510
|
+
console.error('Unable to save user profession(s)', err);
|
|
3511
|
+
}
|
|
3512
|
+
finally {
|
|
3513
|
+
this.isSavingProfessionsTable = false;
|
|
3514
|
+
}
|
|
3515
|
+
}
|
|
3251
3516
|
isBlank(value) {
|
|
3252
3517
|
return typeof value !== 'string' || value.trim().length === 0;
|
|
3253
3518
|
}
|
|
@@ -3488,6 +3753,20 @@ class PreviewComponent {
|
|
|
3488
3753
|
issues.push('Years of experience is required');
|
|
3489
3754
|
return issues;
|
|
3490
3755
|
}
|
|
3756
|
+
professionItemIssues(name, index) {
|
|
3757
|
+
const issues = [];
|
|
3758
|
+
if (this.isBlank(name))
|
|
3759
|
+
issues.push('Profession name is required');
|
|
3760
|
+
const meta = this.store.resumeProfessionMeta()?.[index] ?? {};
|
|
3761
|
+
if (this.isBlankOrNull(meta.professionId))
|
|
3762
|
+
issues.push('Profession type is required');
|
|
3763
|
+
const stars = Math.round((meta.starRating ?? 0) / 2);
|
|
3764
|
+
if (!stars || stars <= 0)
|
|
3765
|
+
issues.push('Star rating is required');
|
|
3766
|
+
if (meta.year === null || meta.year === undefined)
|
|
3767
|
+
issues.push('Years of experience is required');
|
|
3768
|
+
return issues;
|
|
3769
|
+
}
|
|
3491
3770
|
basicIssues = computed(() => this.basicDetailsIssues(this.details()), ...(ngDevMode ? [{ debugName: "basicIssues" }] : []));
|
|
3492
3771
|
basicSectionHasIssues = computed(() => this.basicIssues().length > 0, ...(ngDevMode ? [{ debugName: "basicSectionHasIssues" }] : []));
|
|
3493
3772
|
workIssuesByIndex = computed(() => this.experience().map((w) => this.workItemIssues(w)), ...(ngDevMode ? [{ debugName: "workIssuesByIndex" }] : []));
|
|
@@ -3496,6 +3775,7 @@ class PreviewComponent {
|
|
|
3496
3775
|
licenseIssuesByIndex = computed(() => this.licenses().map((l) => this.licenseItemIssues(l)), ...(ngDevMode ? [{ debugName: "licenseIssuesByIndex" }] : []));
|
|
3497
3776
|
skillIssuesByIndex = computed(() => this.skills().map((s, i) => this.skillItemIssues(s, i)), ...(ngDevMode ? [{ debugName: "skillIssuesByIndex" }] : []));
|
|
3498
3777
|
toolIssuesByIndex = computed(() => this.tools().map((t, i) => this.toolItemIssues(t, i)), ...(ngDevMode ? [{ debugName: "toolIssuesByIndex" }] : []));
|
|
3778
|
+
professionIssuesByIndex = computed(() => this.professions().map((p, i) => this.professionItemIssues(p, i)), ...(ngDevMode ? [{ debugName: "professionIssuesByIndex" }] : []));
|
|
3499
3779
|
// Editor overlay validation based on temporary editor values (so it shows immediately on "Edit")
|
|
3500
3780
|
skillFormIssues = computed(() => {
|
|
3501
3781
|
const form = this.skillForm();
|
|
@@ -3523,6 +3803,21 @@ class PreviewComponent {
|
|
|
3523
3803
|
issues.push('Years of experience is required');
|
|
3524
3804
|
return issues;
|
|
3525
3805
|
}, ...(ngDevMode ? [{ debugName: "toolFormIssues" }] : []));
|
|
3806
|
+
professionFormIssues = computed(() => {
|
|
3807
|
+
const form = this.professionForm();
|
|
3808
|
+
if (!form)
|
|
3809
|
+
return [];
|
|
3810
|
+
const issues = [];
|
|
3811
|
+
if (this.isBlank(form.name))
|
|
3812
|
+
issues.push('Profession name is required');
|
|
3813
|
+
if (this.isBlankOrNull(form.professionId))
|
|
3814
|
+
issues.push('Profession type is required');
|
|
3815
|
+
if (!form.stars || form.stars <= 0)
|
|
3816
|
+
issues.push('Star rating is required');
|
|
3817
|
+
if (form.year === null || form.year === undefined)
|
|
3818
|
+
issues.push('Years of experience is required');
|
|
3819
|
+
return issues;
|
|
3820
|
+
}, ...(ngDevMode ? [{ debugName: "professionFormIssues" }] : []));
|
|
3526
3821
|
workSectionHasIssues = computed(() => {
|
|
3527
3822
|
const hasValidationIssues = this.workIssuesByIndex().some((x) => x.length > 0);
|
|
3528
3823
|
const hasUnsavedItems = this.workSectionHasUnsavedItems();
|
|
@@ -3553,6 +3848,11 @@ class PreviewComponent {
|
|
|
3553
3848
|
const hasUnsavedItems = this.toolsSectionHasUnsavedItems();
|
|
3554
3849
|
return hasValidationIssues || hasUnsavedItems;
|
|
3555
3850
|
}, ...(ngDevMode ? [{ debugName: "toolsSectionHasIssues" }] : []));
|
|
3851
|
+
professionsSectionHasIssues = computed(() => {
|
|
3852
|
+
const hasValidationIssues = this.professionIssuesByIndex().some((x) => x.length > 0);
|
|
3853
|
+
const hasUnsavedItems = this.professionsSectionHasUnsavedItems();
|
|
3854
|
+
return hasValidationIssues || hasUnsavedItems;
|
|
3855
|
+
}, ...(ngDevMode ? [{ debugName: "professionsSectionHasIssues" }] : []));
|
|
3556
3856
|
workSectionHasUnsavedItems() {
|
|
3557
3857
|
return this.experience().some((_, i) => this.hasUnsavedWorkItem(i));
|
|
3558
3858
|
}
|
|
@@ -3571,6 +3871,9 @@ class PreviewComponent {
|
|
|
3571
3871
|
toolsSectionHasUnsavedItems() {
|
|
3572
3872
|
return this.tools().some((_, i) => this.hasUnsavedToolItem(i));
|
|
3573
3873
|
}
|
|
3874
|
+
professionsSectionHasUnsavedItems() {
|
|
3875
|
+
return this.professions().some((_, i) => this.hasUnsavedProfessionItem(i));
|
|
3876
|
+
}
|
|
3574
3877
|
isAnyEditorOpen = computed(() => {
|
|
3575
3878
|
return this.isEditMode() ||
|
|
3576
3879
|
this.jobEditor().mode !== 'closed' ||
|
|
@@ -3578,7 +3881,8 @@ class PreviewComponent {
|
|
|
3578
3881
|
this.certificationEditor().mode !== 'closed' ||
|
|
3579
3882
|
this.licenseEditor().mode !== 'closed' ||
|
|
3580
3883
|
this.skillEditor().mode !== 'closed' ||
|
|
3581
|
-
this.toolEditor().mode !== 'closed'
|
|
3884
|
+
this.toolEditor().mode !== 'closed' ||
|
|
3885
|
+
this.professionEditor().mode !== 'closed';
|
|
3582
3886
|
}, ...(ngDevMode ? [{ debugName: "isAnyEditorOpen" }] : []));
|
|
3583
3887
|
canConfirmAndContinue() {
|
|
3584
3888
|
return this.hasUserDetailData;
|
|
@@ -3830,6 +4134,7 @@ class PreviewComponent {
|
|
|
3830
4134
|
item?.userToolId,
|
|
3831
4135
|
item?.skillSetId,
|
|
3832
4136
|
item?.toolId,
|
|
4137
|
+
item?.userProfessionId,
|
|
3833
4138
|
];
|
|
3834
4139
|
const found = candidates.find((x) => typeof x === 'string' && x.trim());
|
|
3835
4140
|
return found ?? null;
|
|
@@ -3883,6 +4188,9 @@ class PreviewComponent {
|
|
|
3883
4188
|
hasUnsavedToolItem(index) {
|
|
3884
4189
|
return !this.toolServerIds[index] && !this.toolLocallySaved[index];
|
|
3885
4190
|
}
|
|
4191
|
+
hasUnsavedProfessionItem(index) {
|
|
4192
|
+
return !this.professionServerIds[index] && !this.professionLocallySaved[index];
|
|
4193
|
+
}
|
|
3886
4194
|
mapSavedWorkToPreview(item) {
|
|
3887
4195
|
return {
|
|
3888
4196
|
company: item?.companyName ?? '',
|
|
@@ -4137,6 +4445,29 @@ class PreviewComponent {
|
|
|
4137
4445
|
console.error('Unable to resolve tool server id', err);
|
|
4138
4446
|
}
|
|
4139
4447
|
}
|
|
4448
|
+
async ensureProfessionServerId(index) {
|
|
4449
|
+
if (this.professionServerIds[index] || !this.payloadUserId)
|
|
4450
|
+
return;
|
|
4451
|
+
try {
|
|
4452
|
+
const payload = this.mapProfessions(this.resumeData)[index];
|
|
4453
|
+
if (!payload)
|
|
4454
|
+
return;
|
|
4455
|
+
const res = await firstValueFrom(this.userProfessionService.getUserProfession(this.buildSectionQuery('professionName asc', true)));
|
|
4456
|
+
const saved = Array.isArray(res?.data) ? res.data : [];
|
|
4457
|
+
const targetName = this.normalizedText(payload.professionName);
|
|
4458
|
+
const targetYear = payload.year;
|
|
4459
|
+
const targetStars = payload.starRating;
|
|
4460
|
+
const match = saved.find((x) => this.normalizedText(x?.professionName) === targetName
|
|
4461
|
+
&& (x?.year ?? null) === (targetYear ?? null)
|
|
4462
|
+
&& (x?.starRating ?? null) === (targetStars ?? null));
|
|
4463
|
+
const matchId = this.getEntityId(match);
|
|
4464
|
+
if (matchId)
|
|
4465
|
+
this.professionServerIds[index] = matchId;
|
|
4466
|
+
}
|
|
4467
|
+
catch (err) {
|
|
4468
|
+
console.error('Unable to resolve profession server id', err);
|
|
4469
|
+
}
|
|
4470
|
+
}
|
|
4140
4471
|
async loadSavedSectionsFromApis() {
|
|
4141
4472
|
if (this.store.sectionDataLoaded())
|
|
4142
4473
|
return;
|
|
@@ -4150,19 +4481,21 @@ class PreviewComponent {
|
|
|
4150
4481
|
this.licenseServerIds = {};
|
|
4151
4482
|
this.skillServerIds = {};
|
|
4152
4483
|
this.toolServerIds = {};
|
|
4484
|
+
this.professionServerIds = {};
|
|
4153
4485
|
this.workExperienceLocallySaved = {};
|
|
4154
4486
|
this.educationLocallySaved = {};
|
|
4155
4487
|
this.certificationLocallySaved = {};
|
|
4156
4488
|
this.licenseLocallySaved = {};
|
|
4157
4489
|
this.skillLocallySaved = {};
|
|
4158
4490
|
this.toolLocallySaved = {};
|
|
4491
|
+
this.professionLocallySaved = {};
|
|
4159
4492
|
var request = {};
|
|
4160
4493
|
if (this.effectiveTargetUserId) {
|
|
4161
4494
|
request = {
|
|
4162
4495
|
targetUserId: this.effectiveTargetUserId
|
|
4163
4496
|
};
|
|
4164
4497
|
}
|
|
4165
|
-
const [workRes, educationRes, certificationsRes, licensesRes, skillsRes, toolsRes, userDetailRes] = await Promise.all([
|
|
4498
|
+
const [workRes, educationRes, certificationsRes, licensesRes, skillsRes, toolsRes, professionsRes, userDetailRes] = await Promise.all([
|
|
4166
4499
|
firstValueFrom(this.userExperienceService.getUserExperience(this.buildSectionForUserQuery('createdDateTime asc'))),
|
|
4167
4500
|
firstValueFrom(this.userEducation.getUserEducation(this.buildSectionForUserQuery('createdDateTime asc'))),
|
|
4168
4501
|
// ✅ Certifications (mainType = 2)
|
|
@@ -4183,6 +4516,7 @@ class PreviewComponent {
|
|
|
4183
4516
|
})),
|
|
4184
4517
|
firstValueFrom(this.userSkillSetService.getUserSkillSet(this.buildSectionQuery('skillSetName asc', true))),
|
|
4185
4518
|
firstValueFrom(this.userToolService.getUserTool(this.buildSectionQuery('toolName asc', true))),
|
|
4519
|
+
firstValueFrom(this.userProfessionService.getUserProfession(this.buildSectionQuery('professionName asc', true))),
|
|
4186
4520
|
firstValueFrom(this.userDetailService.getByUserId(this.payloadUserId, request)).catch(() => null),
|
|
4187
4521
|
]);
|
|
4188
4522
|
this.store.sectionDataLoaded.set(true);
|
|
@@ -4217,6 +4551,9 @@ class PreviewComponent {
|
|
|
4217
4551
|
const savedLicenses = Array.isArray(licensesRes?.data) ? licensesRes.data : [];
|
|
4218
4552
|
const savedSkills = Array.isArray(skillsRes?.data) ? skillsRes.data : [];
|
|
4219
4553
|
const savedTools = Array.isArray(toolsRes?.data) ? toolsRes.data : [];
|
|
4554
|
+
const savedProfessions = Array.isArray(professionsRes?.data) ? professionsRes.data : [];
|
|
4555
|
+
this.userProfessionOptions = savedProfessions;
|
|
4556
|
+
this.applySavedProfessionsToTable();
|
|
4220
4557
|
const savedWorkPreview = savedWork.map((item) => this.mapSavedWorkToPreview(item));
|
|
4221
4558
|
const prevWorkLocallySaved = { ...this.workExperienceLocallySaved };
|
|
4222
4559
|
const prevWorkServerIds = { ...this.workExperienceServerIds };
|
|
@@ -4342,6 +4679,37 @@ class PreviewComponent {
|
|
|
4342
4679
|
}
|
|
4343
4680
|
}
|
|
4344
4681
|
this.store.resumeToolMeta.set(nextToolMeta);
|
|
4682
|
+
const currentProfessions = current.professions ?? [];
|
|
4683
|
+
const savedProfessionNames = savedProfessions.map((item) => (item?.professionName ?? '').toString());
|
|
4684
|
+
const prevProfessionLocallySaved = { ...this.professionLocallySaved };
|
|
4685
|
+
const prevProfessionServerIds = { ...this.professionServerIds };
|
|
4686
|
+
const mergedProfessions = this.mergeSavedAndCurrent(savedProfessionNames, currentProfessions, (name) => this.normalizedText(name));
|
|
4687
|
+
const nextProfessions = mergedProfessions.merged;
|
|
4688
|
+
const nextProfessionMeta = {};
|
|
4689
|
+
savedProfessions.forEach((item, index) => {
|
|
4690
|
+
const id = this.getEntityId(item);
|
|
4691
|
+
if (id)
|
|
4692
|
+
this.professionServerIds[index] = id;
|
|
4693
|
+
nextProfessionMeta[index] = {
|
|
4694
|
+
professionId: item?.professionId ?? null,
|
|
4695
|
+
professionGroup: item?.professionGroup ?? '',
|
|
4696
|
+
residentialCommercial: item?.residentialCommercial ?? '',
|
|
4697
|
+
starRating: item?.starRating ?? null,
|
|
4698
|
+
year: item?.year ?? null,
|
|
4699
|
+
notes: item?.notes ?? '',
|
|
4700
|
+
};
|
|
4701
|
+
});
|
|
4702
|
+
const oldProfessionMeta = this.store.resumeProfessionMeta() ?? {};
|
|
4703
|
+
for (let i = savedProfessions.length; i < nextProfessions.length; i++) {
|
|
4704
|
+
const sourceCurrentIndex = mergedProfessions.appendedCurrentIndexes[i - savedProfessions.length];
|
|
4705
|
+
if (sourceCurrentIndex !== undefined && oldProfessionMeta[sourceCurrentIndex]) {
|
|
4706
|
+
nextProfessionMeta[i] = oldProfessionMeta[sourceCurrentIndex];
|
|
4707
|
+
}
|
|
4708
|
+
if (sourceCurrentIndex !== undefined && (prevProfessionLocallySaved[sourceCurrentIndex] || prevProfessionServerIds[sourceCurrentIndex])) {
|
|
4709
|
+
this.professionLocallySaved[i] = true;
|
|
4710
|
+
}
|
|
4711
|
+
}
|
|
4712
|
+
this.store.resumeProfessionMeta.set(nextProfessionMeta);
|
|
4345
4713
|
if (savedBasicDetails?.phone) {
|
|
4346
4714
|
savedBasicDetails.phone = this.formatPhone(savedBasicDetails.phone);
|
|
4347
4715
|
}
|
|
@@ -4585,6 +4953,8 @@ class PreviewComponent {
|
|
|
4585
4953
|
data: {
|
|
4586
4954
|
name: current.skills[index] ?? '',
|
|
4587
4955
|
providerName: meta.providerName ?? '',
|
|
4956
|
+
professionId: meta.professionId ?? null,
|
|
4957
|
+
professionName: meta.professionName ?? '',
|
|
4588
4958
|
stars: Math.round((meta.starRating ?? 0) / 2),
|
|
4589
4959
|
year: meta.year ?? null,
|
|
4590
4960
|
profileVisibility: !!meta.profileVisibility,
|
|
@@ -4596,7 +4966,7 @@ class PreviewComponent {
|
|
|
4596
4966
|
this.skillEditor.set({
|
|
4597
4967
|
mode: 'add',
|
|
4598
4968
|
index: null,
|
|
4599
|
-
data: { name: '', providerName: '', stars: 0, year: null, profileVisibility: false, notes: '' }
|
|
4969
|
+
data: { name: '', providerName: '', professionId: null, professionName: '', stars: 0, year: null, profileVisibility: false, notes: '' }
|
|
4600
4970
|
});
|
|
4601
4971
|
}
|
|
4602
4972
|
closeSkillEditor() {
|
|
@@ -4605,6 +4975,12 @@ class PreviewComponent {
|
|
|
4605
4975
|
setTempSkillStars(stars) {
|
|
4606
4976
|
this.patchSkillForm({ stars });
|
|
4607
4977
|
}
|
|
4978
|
+
onSkillProfessionChange(item) {
|
|
4979
|
+
this.patchSkillForm({
|
|
4980
|
+
professionId: item?.professionId ?? null,
|
|
4981
|
+
professionName: item?.professionName ?? '',
|
|
4982
|
+
});
|
|
4983
|
+
}
|
|
4608
4984
|
async saveSkillEditor() {
|
|
4609
4985
|
const current = this.store.profileSignal();
|
|
4610
4986
|
const idx = this.editingSkillIndex();
|
|
@@ -4642,6 +5018,8 @@ class PreviewComponent {
|
|
|
4642
5018
|
if (metaIndex !== null) {
|
|
4643
5019
|
this.store.setResumeSkillMeta(metaIndex, {
|
|
4644
5020
|
providerName: (form.providerName || '').trim() || undefined,
|
|
5021
|
+
professionId: form.professionId ?? null,
|
|
5022
|
+
professionName: form.professionName ?? '',
|
|
4645
5023
|
starRating: (form.stars || 0) * 2,
|
|
4646
5024
|
year: form.year,
|
|
4647
5025
|
profileVisibility: form.profileVisibility,
|
|
@@ -4715,6 +5093,8 @@ class PreviewComponent {
|
|
|
4715
5093
|
data: {
|
|
4716
5094
|
name: current.tools[index] ?? '',
|
|
4717
5095
|
providerName: meta.providerName ?? '',
|
|
5096
|
+
professionId: meta.professionId ?? null,
|
|
5097
|
+
professionName: meta.professionName ?? '',
|
|
4718
5098
|
stars: Math.round((meta.starRating ?? 0) / 2),
|
|
4719
5099
|
year: meta.year ?? null,
|
|
4720
5100
|
profileVisibility: !!meta.profileVisibility,
|
|
@@ -4726,7 +5106,7 @@ class PreviewComponent {
|
|
|
4726
5106
|
this.toolEditor.set({
|
|
4727
5107
|
mode: 'add',
|
|
4728
5108
|
index: null,
|
|
4729
|
-
data: { name: '', providerName: '', stars: 0, year: null, profileVisibility: false, notes: '' }
|
|
5109
|
+
data: { name: '', providerName: '', professionId: null, professionName: '', stars: 0, year: null, profileVisibility: false, notes: '' }
|
|
4730
5110
|
});
|
|
4731
5111
|
}
|
|
4732
5112
|
closeToolEditor() {
|
|
@@ -4735,6 +5115,166 @@ class PreviewComponent {
|
|
|
4735
5115
|
setTempToolStars(stars) {
|
|
4736
5116
|
this.patchToolForm({ stars });
|
|
4737
5117
|
}
|
|
5118
|
+
onToolProfessionChange(item) {
|
|
5119
|
+
this.patchToolForm({
|
|
5120
|
+
professionId: item?.professionId ?? null,
|
|
5121
|
+
professionName: item?.professionName ?? '',
|
|
5122
|
+
});
|
|
5123
|
+
}
|
|
5124
|
+
// Profession editing (same popup UX as skills, but with a profession-type dropdown)
|
|
5125
|
+
professionEditor = signal({ mode: 'closed', index: null, data: null }, ...(ngDevMode ? [{ debugName: "professionEditor" }] : []));
|
|
5126
|
+
isProfessionEditorOpen() { return this.professionEditor().mode !== 'closed'; }
|
|
5127
|
+
isAddingProfession() { return this.professionEditor().mode === 'add'; }
|
|
5128
|
+
editingProfessionIndex() { return this.professionEditor().mode === 'edit' ? this.professionEditor().index : null; }
|
|
5129
|
+
professionForm() { return this.professionEditor().data; }
|
|
5130
|
+
patchProfessionForm(patch) {
|
|
5131
|
+
const curr = this.professionForm();
|
|
5132
|
+
if (!curr)
|
|
5133
|
+
return;
|
|
5134
|
+
this.professionEditor.update((e) => ({ ...e, data: { ...curr, ...patch } }));
|
|
5135
|
+
}
|
|
5136
|
+
openProfessionEditor(index) {
|
|
5137
|
+
const current = this.store.profileSignal();
|
|
5138
|
+
if (!current || !current.professions?.length || index < 0 || index >= current.professions.length)
|
|
5139
|
+
return;
|
|
5140
|
+
if (!this.professionServerIds[index]) {
|
|
5141
|
+
void this.ensureProfessionServerId(index);
|
|
5142
|
+
}
|
|
5143
|
+
const meta = this.store.resumeProfessionMeta()?.[index] ?? {};
|
|
5144
|
+
this.professionEditor.set({
|
|
5145
|
+
mode: 'edit',
|
|
5146
|
+
index,
|
|
5147
|
+
data: {
|
|
5148
|
+
name: current.professions[index] ?? '',
|
|
5149
|
+
professionId: meta.professionId ?? null,
|
|
5150
|
+
professionGroup: meta.professionGroup ?? '',
|
|
5151
|
+
residentialCommercial: meta.residentialCommercial ?? '',
|
|
5152
|
+
stars: Math.round((meta.starRating ?? 0) / 2),
|
|
5153
|
+
year: meta.year ?? null,
|
|
5154
|
+
notes: meta.notes ?? '',
|
|
5155
|
+
}
|
|
5156
|
+
});
|
|
5157
|
+
}
|
|
5158
|
+
addProfession() {
|
|
5159
|
+
this.professionEditor.set({
|
|
5160
|
+
mode: 'add',
|
|
5161
|
+
index: null,
|
|
5162
|
+
data: { name: '', professionId: null, professionGroup: '', residentialCommercial: '', stars: 0, year: null, notes: '' }
|
|
5163
|
+
});
|
|
5164
|
+
}
|
|
5165
|
+
closeProfessionEditor() {
|
|
5166
|
+
this.professionEditor.set({ mode: 'closed', index: null, data: null });
|
|
5167
|
+
}
|
|
5168
|
+
setTempProfessionStars(stars) {
|
|
5169
|
+
this.patchProfessionForm({ stars });
|
|
5170
|
+
}
|
|
5171
|
+
onProfessionTypeChange(item) {
|
|
5172
|
+
this.patchProfessionForm({
|
|
5173
|
+
professionId: item?.id ?? null,
|
|
5174
|
+
professionGroup: item?.professionGroup ?? '',
|
|
5175
|
+
residentialCommercial: item?.residentialCommercial ?? '',
|
|
5176
|
+
});
|
|
5177
|
+
}
|
|
5178
|
+
async saveProfessionEditor() {
|
|
5179
|
+
const current = this.store.profileSignal();
|
|
5180
|
+
const idx = this.editingProfessionIndex();
|
|
5181
|
+
if (!current)
|
|
5182
|
+
return;
|
|
5183
|
+
const form = this.professionForm();
|
|
5184
|
+
if (!form)
|
|
5185
|
+
return;
|
|
5186
|
+
const nextName = (form.name || '').trim();
|
|
5187
|
+
if (!nextName)
|
|
5188
|
+
return;
|
|
5189
|
+
if (this.isBlankOrNull(form.professionId))
|
|
5190
|
+
return;
|
|
5191
|
+
if (!form.stars || form.stars <= 0)
|
|
5192
|
+
return;
|
|
5193
|
+
if (form.year === null || form.year === undefined)
|
|
5194
|
+
return;
|
|
5195
|
+
this.isSavingProfession = true;
|
|
5196
|
+
try {
|
|
5197
|
+
const nextProfessions = [...(current.professions ?? [])];
|
|
5198
|
+
if (this.isAddingProfession()) {
|
|
5199
|
+
nextProfessions.push(nextName);
|
|
5200
|
+
}
|
|
5201
|
+
else if (idx !== null) {
|
|
5202
|
+
nextProfessions[idx] = nextName;
|
|
5203
|
+
}
|
|
5204
|
+
else {
|
|
5205
|
+
return;
|
|
5206
|
+
}
|
|
5207
|
+
if (this.isAddingProfession()) {
|
|
5208
|
+
this.appendToMainModel('professions', nextName);
|
|
5209
|
+
}
|
|
5210
|
+
else if (idx !== null) {
|
|
5211
|
+
this.updateInMainModel('professions', idx, nextName);
|
|
5212
|
+
}
|
|
5213
|
+
const metaIndex = this.isAddingProfession() ? nextProfessions.length - 1 : idx;
|
|
5214
|
+
if (metaIndex !== null) {
|
|
5215
|
+
this.store.setResumeProfessionMeta(metaIndex, {
|
|
5216
|
+
professionId: form.professionId,
|
|
5217
|
+
professionGroup: form.professionGroup,
|
|
5218
|
+
residentialCommercial: form.residentialCommercial,
|
|
5219
|
+
starRating: (form.stars || 0) * 2,
|
|
5220
|
+
year: form.year,
|
|
5221
|
+
notes: form.notes,
|
|
5222
|
+
});
|
|
5223
|
+
await this.persistProfession(metaIndex, !this.isAddingProfession());
|
|
5224
|
+
}
|
|
5225
|
+
}
|
|
5226
|
+
finally {
|
|
5227
|
+
this.isSavingProfession = false;
|
|
5228
|
+
}
|
|
5229
|
+
this.closeProfessionEditor();
|
|
5230
|
+
}
|
|
5231
|
+
reindexProfessionMetaAfterDelete(deletedIndex) {
|
|
5232
|
+
const meta = this.store.resumeProfessionMeta() ?? {};
|
|
5233
|
+
const next = {};
|
|
5234
|
+
Object.keys(meta).forEach((k) => {
|
|
5235
|
+
const idx = Number(k);
|
|
5236
|
+
if (Number.isNaN(idx))
|
|
5237
|
+
return;
|
|
5238
|
+
if (idx < deletedIndex)
|
|
5239
|
+
next[idx] = meta[idx];
|
|
5240
|
+
else if (idx > deletedIndex)
|
|
5241
|
+
next[idx - 1] = meta[idx];
|
|
5242
|
+
});
|
|
5243
|
+
this.store.resumeProfessionMeta.set(next);
|
|
5244
|
+
}
|
|
5245
|
+
async deleteProfession(index) {
|
|
5246
|
+
const current = this.store.profileSignal();
|
|
5247
|
+
if (!current?.professions?.length)
|
|
5248
|
+
return;
|
|
5249
|
+
if (index < 0 || index >= current.professions.length)
|
|
5250
|
+
return;
|
|
5251
|
+
if (!this.confirmDelete('Delete this profession?'))
|
|
5252
|
+
return;
|
|
5253
|
+
const serverId = this.professionServerIds[index];
|
|
5254
|
+
if (serverId) {
|
|
5255
|
+
await firstValueFrom(this.userProfessionService.bulkDelete([serverId]));
|
|
5256
|
+
}
|
|
5257
|
+
const nextProfessions = current.professions.filter((_, i) => i !== index);
|
|
5258
|
+
this.commitProfile({ ...current, professions: nextProfessions });
|
|
5259
|
+
this.reindexProfessionMetaAfterDelete(index);
|
|
5260
|
+
this.professionServerIds = this.reindexServerIdsAfterDelete(this.professionServerIds, index);
|
|
5261
|
+
this.professionLocallySaved = this.reindexSavedFlagsAfterDelete(this.professionLocallySaved, index);
|
|
5262
|
+
if (this.editingProfessionIndex() === index)
|
|
5263
|
+
this.closeProfessionEditor();
|
|
5264
|
+
}
|
|
5265
|
+
async confirmAllProfessions() {
|
|
5266
|
+
const professions = this.store.profileSignal()?.professions ?? [];
|
|
5267
|
+
if (!professions.length || this.isSavingProfession || this.isProfessionEditorOpen())
|
|
5268
|
+
return;
|
|
5269
|
+
this.isSavingProfession = true;
|
|
5270
|
+
try {
|
|
5271
|
+
await this.batchPersistProfessions(professions);
|
|
5272
|
+
}
|
|
5273
|
+
finally {
|
|
5274
|
+
this.isSavingProfession = false;
|
|
5275
|
+
this.cdr.detectChanges();
|
|
5276
|
+
}
|
|
5277
|
+
}
|
|
4738
5278
|
async confirmAllSkills() {
|
|
4739
5279
|
const skills = this.store.profileSignal()?.skills ?? [];
|
|
4740
5280
|
if (!skills.length || this.isSavingSkill || this.isSkillEditorOpen())
|
|
@@ -4743,6 +5283,8 @@ class PreviewComponent {
|
|
|
4743
5283
|
if (hasInvalid) {
|
|
4744
5284
|
this.bulkSkillStars = 0;
|
|
4745
5285
|
this.bulkSkillYear = null;
|
|
5286
|
+
this.bulkSkillProfessionId = null;
|
|
5287
|
+
this.bulkSkillProfessionName = '';
|
|
4746
5288
|
this.showBulkSkillConfirm = true;
|
|
4747
5289
|
return;
|
|
4748
5290
|
}
|
|
@@ -4758,6 +5300,10 @@ class PreviewComponent {
|
|
|
4758
5300
|
cancelBulkSkillConfirm() {
|
|
4759
5301
|
this.showBulkSkillConfirm = false;
|
|
4760
5302
|
}
|
|
5303
|
+
onBulkSkillProfessionChange(item) {
|
|
5304
|
+
this.bulkSkillProfessionId = item?.professionId ?? null;
|
|
5305
|
+
this.bulkSkillProfessionName = item?.professionName ?? '';
|
|
5306
|
+
}
|
|
4761
5307
|
async applyBulkSkillConfirm() {
|
|
4762
5308
|
if (!this.bulkSkillStars || this.bulkSkillStars <= 0)
|
|
4763
5309
|
return;
|
|
@@ -4770,6 +5316,8 @@ class PreviewComponent {
|
|
|
4770
5316
|
const existingYear = meta.year ?? null;
|
|
4771
5317
|
this.store.setResumeSkillMeta(i, {
|
|
4772
5318
|
...meta,
|
|
5319
|
+
professionId: meta.professionId ?? this.bulkSkillProfessionId,
|
|
5320
|
+
professionName: meta.professionId ? meta.professionName : this.bulkSkillProfessionName,
|
|
4773
5321
|
starRating: existingStars > 0 ? meta.starRating : this.bulkSkillStars * 2,
|
|
4774
5322
|
year: existingYear !== null ? existingYear : this.bulkSkillYear,
|
|
4775
5323
|
profileVisibility: meta.profileVisibility ?? false,
|
|
@@ -4794,6 +5342,8 @@ class PreviewComponent {
|
|
|
4794
5342
|
if (hasInvalid) {
|
|
4795
5343
|
this.bulkToolStars = 0;
|
|
4796
5344
|
this.bulkToolYear = null;
|
|
5345
|
+
this.bulkToolProfessionId = null;
|
|
5346
|
+
this.bulkToolProfessionName = '';
|
|
4797
5347
|
this.showBulkToolConfirm = true;
|
|
4798
5348
|
return;
|
|
4799
5349
|
}
|
|
@@ -4809,6 +5359,10 @@ class PreviewComponent {
|
|
|
4809
5359
|
cancelBulkToolConfirm() {
|
|
4810
5360
|
this.showBulkToolConfirm = false;
|
|
4811
5361
|
}
|
|
5362
|
+
onBulkToolProfessionChange(item) {
|
|
5363
|
+
this.bulkToolProfessionId = item?.professionId ?? null;
|
|
5364
|
+
this.bulkToolProfessionName = item?.professionName ?? '';
|
|
5365
|
+
}
|
|
4812
5366
|
async applyBulkToolConfirm() {
|
|
4813
5367
|
if (!this.bulkToolStars || this.bulkToolStars <= 0)
|
|
4814
5368
|
return;
|
|
@@ -4821,6 +5375,8 @@ class PreviewComponent {
|
|
|
4821
5375
|
const existingYear = meta.year ?? null;
|
|
4822
5376
|
this.store.setResumeToolMeta(i, {
|
|
4823
5377
|
...meta,
|
|
5378
|
+
professionId: meta.professionId ?? this.bulkToolProfessionId,
|
|
5379
|
+
professionName: meta.professionId ? meta.professionName : this.bulkToolProfessionName,
|
|
4824
5380
|
starRating: existingStars > 0 ? meta.starRating : this.bulkToolStars * 2,
|
|
4825
5381
|
year: existingYear !== null ? existingYear : this.bulkToolYear,
|
|
4826
5382
|
profileVisibility: meta.profileVisibility ?? false,
|
|
@@ -4874,6 +5430,8 @@ class PreviewComponent {
|
|
|
4874
5430
|
if (metaIndex !== null) {
|
|
4875
5431
|
this.store.setResumeToolMeta(metaIndex, {
|
|
4876
5432
|
providerName: (form.providerName || '').trim() || undefined,
|
|
5433
|
+
professionId: form.professionId ?? null,
|
|
5434
|
+
professionName: form.professionName ?? '',
|
|
4877
5435
|
starRating: (form.stars || 0) * 2,
|
|
4878
5436
|
year: form.year,
|
|
4879
5437
|
profileVisibility: form.profileVisibility,
|
|
@@ -4946,6 +5504,8 @@ class PreviewComponent {
|
|
|
4946
5504
|
issueDate: null,
|
|
4947
5505
|
expiryDate: null,
|
|
4948
5506
|
credentialId: null,
|
|
5507
|
+
professionId: null,
|
|
5508
|
+
professionName: '',
|
|
4949
5509
|
fileId: null,
|
|
4950
5510
|
fileUrl: null,
|
|
4951
5511
|
fileName: null,
|
|
@@ -4953,6 +5513,12 @@ class PreviewComponent {
|
|
|
4953
5513
|
}
|
|
4954
5514
|
});
|
|
4955
5515
|
}
|
|
5516
|
+
onCertificationProfessionChange(item) {
|
|
5517
|
+
this.patchTempCertification({
|
|
5518
|
+
professionId: item?.professionId ?? null,
|
|
5519
|
+
professionName: item?.professionName ?? '',
|
|
5520
|
+
});
|
|
5521
|
+
}
|
|
4956
5522
|
startEditCertification(index) {
|
|
4957
5523
|
const current = this.store.profileSignal();
|
|
4958
5524
|
const cert = current?.certifications?.[index];
|
|
@@ -5019,6 +5585,8 @@ class PreviewComponent {
|
|
|
5019
5585
|
credentialId: this.normalizeNullableString(nextCert.credentialId),
|
|
5020
5586
|
issueDate: this.normalizeMonthInput(nextCert.issueDate),
|
|
5021
5587
|
expiryDate: this.normalizeMonthInput(nextCert.expiryDate),
|
|
5588
|
+
professionId: nextCert.professionId ?? null,
|
|
5589
|
+
professionName: nextCert.professionName ?? '',
|
|
5022
5590
|
};
|
|
5023
5591
|
if (this.isAddingCertification())
|
|
5024
5592
|
this.appendToMainModel('certifications', normalized);
|
|
@@ -5624,6 +6192,60 @@ class PreviewComponent {
|
|
|
5624
6192
|
}
|
|
5625
6193
|
}
|
|
5626
6194
|
}
|
|
6195
|
+
async persistProfession(index, isEdit) {
|
|
6196
|
+
if (!this.resumeData)
|
|
6197
|
+
return;
|
|
6198
|
+
this.buildUserName();
|
|
6199
|
+
const payload = this.mapProfessions(this.resumeData)[index];
|
|
6200
|
+
if (!payload)
|
|
6201
|
+
return;
|
|
6202
|
+
if (isEdit && !this.professionServerIds[index]) {
|
|
6203
|
+
await this.ensureProfessionServerId(index);
|
|
6204
|
+
}
|
|
6205
|
+
const hasServerId = !!this.professionServerIds[index];
|
|
6206
|
+
if (hasServerId)
|
|
6207
|
+
payload.id = this.professionServerIds[index];
|
|
6208
|
+
try {
|
|
6209
|
+
const res = (isEdit && hasServerId)
|
|
6210
|
+
? await firstValueFrom(this.userProfessionService.updateUserProfession(payload))
|
|
6211
|
+
: await firstValueFrom(this.userProfessionService.createUserProfession([payload]));
|
|
6212
|
+
const createdId = this.getCreatedId(res);
|
|
6213
|
+
this.markItemSaved(this.professionServerIds, this.professionLocallySaved, index, createdId);
|
|
6214
|
+
}
|
|
6215
|
+
catch (err) {
|
|
6216
|
+
console.error('Unable to persist profession', err);
|
|
6217
|
+
}
|
|
6218
|
+
}
|
|
6219
|
+
async batchPersistProfessions(professions) {
|
|
6220
|
+
if (!this.resumeData)
|
|
6221
|
+
return;
|
|
6222
|
+
this.buildUserName();
|
|
6223
|
+
const newIndices = [];
|
|
6224
|
+
const newPayloads = [];
|
|
6225
|
+
for (let i = 0; i < professions.length; i++) {
|
|
6226
|
+
if (!this.hasUnsavedProfessionItem(i))
|
|
6227
|
+
continue;
|
|
6228
|
+
const payload = this.mapProfessions(this.resumeData)[i];
|
|
6229
|
+
if (payload) {
|
|
6230
|
+
newIndices.push(i);
|
|
6231
|
+
newPayloads.push(payload);
|
|
6232
|
+
}
|
|
6233
|
+
}
|
|
6234
|
+
if (newPayloads.length > 0) {
|
|
6235
|
+
try {
|
|
6236
|
+
const res = await firstValueFrom(this.userProfessionService.createUserProfession(newPayloads));
|
|
6237
|
+
const arr = Array.isArray(res) ? res : (Array.isArray(res?.data) ? res.data : null);
|
|
6238
|
+
newIndices.forEach((originalIdx, batchPos) => {
|
|
6239
|
+
const id = arr?.[batchPos]?.id ?? this.getCreatedId(res);
|
|
6240
|
+
this.markItemSaved(this.professionServerIds, this.professionLocallySaved, originalIdx, id);
|
|
6241
|
+
});
|
|
6242
|
+
this.cdr.detectChanges();
|
|
6243
|
+
}
|
|
6244
|
+
catch (err) {
|
|
6245
|
+
console.error('Unable to batch create professions', err);
|
|
6246
|
+
}
|
|
6247
|
+
}
|
|
6248
|
+
}
|
|
5627
6249
|
async persistTool(index, isEdit) {
|
|
5628
6250
|
if (!this.resumeData)
|
|
5629
6251
|
return;
|
|
@@ -6058,6 +6680,8 @@ class PreviewComponent {
|
|
|
6058
6680
|
number: exp.credentialId ?? null,
|
|
6059
6681
|
issuedBy: exp.issuingOrganization,
|
|
6060
6682
|
documentTypeName: exp.name,
|
|
6683
|
+
professionId: exp.professionId ?? null,
|
|
6684
|
+
professionName: exp.professionName ?? '',
|
|
6061
6685
|
issueDate: this.formatDate(exp.issueDate),
|
|
6062
6686
|
expiryDate: this.formatDate(exp.expiryDate),
|
|
6063
6687
|
status: RequestedStatus.SaveasDraft,
|
|
@@ -6117,6 +6741,8 @@ class PreviewComponent {
|
|
|
6117
6741
|
userName: this.payloadUserName,
|
|
6118
6742
|
skillSetId: null,
|
|
6119
6743
|
skillSetName: exp,
|
|
6744
|
+
professionId: m.professionId ?? null,
|
|
6745
|
+
professionName: m.professionName ?? '',
|
|
6120
6746
|
notes: m.notes ?? "",
|
|
6121
6747
|
year: m.year ?? null,
|
|
6122
6748
|
starRating: m.starRating ?? null,
|
|
@@ -6141,6 +6767,8 @@ class PreviewComponent {
|
|
|
6141
6767
|
userName: this.payloadUserName,
|
|
6142
6768
|
toolId: null,
|
|
6143
6769
|
toolName: exp,
|
|
6770
|
+
professionId: m.professionId ?? null,
|
|
6771
|
+
professionName: m.professionName ?? '',
|
|
6144
6772
|
starRating: m.starRating ?? null,
|
|
6145
6773
|
year: m.year ?? null,
|
|
6146
6774
|
make: null,
|
|
@@ -6156,6 +6784,31 @@ class PreviewComponent {
|
|
|
6156
6784
|
};
|
|
6157
6785
|
});
|
|
6158
6786
|
}
|
|
6787
|
+
mapProfessions(data) {
|
|
6788
|
+
const emailId = data?.basicDetails?.email ?? null;
|
|
6789
|
+
const meta = this.store.resumeProfessionMeta?.() ?? {};
|
|
6790
|
+
return (data?.professions ?? []).map((exp, index) => {
|
|
6791
|
+
const m = meta[index] ?? {};
|
|
6792
|
+
return {
|
|
6793
|
+
forUser: 2,
|
|
6794
|
+
targetProviderId: this.effectiveTargetProviderId,
|
|
6795
|
+
providerId: this.effectiveTargetProviderId,
|
|
6796
|
+
providerName: this.effectiveProviderName,
|
|
6797
|
+
targetUserId: this.effectiveTargetUserId,
|
|
6798
|
+
userId: this.effectiveTargetUserId,
|
|
6799
|
+
userName: this.payloadUserName,
|
|
6800
|
+
professionId: m.professionId ?? null,
|
|
6801
|
+
professionName: exp,
|
|
6802
|
+
professionGroup: m.professionGroup ?? '',
|
|
6803
|
+
residentialCommercial: m.residentialCommercial ?? '',
|
|
6804
|
+
notes: m.notes ?? "",
|
|
6805
|
+
year: m.year ?? null,
|
|
6806
|
+
starRating: m.starRating ?? null,
|
|
6807
|
+
status: 2,
|
|
6808
|
+
emailId,
|
|
6809
|
+
};
|
|
6810
|
+
});
|
|
6811
|
+
}
|
|
6159
6812
|
formatDate(date) {
|
|
6160
6813
|
if (!date)
|
|
6161
6814
|
return null;
|
|
@@ -6205,6 +6858,13 @@ class PreviewComponent {
|
|
|
6205
6858
|
return 'Save';
|
|
6206
6859
|
return this.hasUnsavedToolItem(index) ? 'Save' : 'Update';
|
|
6207
6860
|
}
|
|
6861
|
+
professionActionLabel(index) {
|
|
6862
|
+
if (this.isAddingProfession())
|
|
6863
|
+
return 'Save';
|
|
6864
|
+
if (index === null || index < 0)
|
|
6865
|
+
return 'Save';
|
|
6866
|
+
return this.hasUnsavedProfessionItem(index) ? 'Save' : 'Update';
|
|
6867
|
+
}
|
|
6208
6868
|
// Company Details Methods
|
|
6209
6869
|
isCompanyEditMode() {
|
|
6210
6870
|
return this.companyEditMode;
|
|
@@ -6536,8 +7196,8 @@ class PreviewComponent {
|
|
|
6536
7196
|
event.preventDefault();
|
|
6537
7197
|
}
|
|
6538
7198
|
}
|
|
6539
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PreviewComponent, deps: [{ token: CredentialingStore }, { token: FileService }, { token: UserSkillSetService }, { token: UserToolService }, { token: UserDocumentService }, { token: UserEducationService }, { token: UserDetailService }, { token: UserExperienceService }, { token: i1$4.TokenService }, { token: i1$4.RoleContextService }, { token: ProvidersService }, { token: FrontEndProvidersService }, { token: i0.ChangeDetectorRef }, { token: LIBRARY_CONFIG }], target: i0.ɵɵFactoryTarget.Component });
|
|
6540
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: PreviewComponent, isStandalone: true, selector: "app-preview", inputs: { providerId: "providerId", isResume: "isResume", resumeModel: "resumeModel", providerName: "providerName", roleData: "roleData", cloudfrontUrl: "cloudfrontUrl", signatureFileId: "signatureFileId", signatureUrl: "signatureUrl" }, outputs: { backToParent: "backToParent" }, viewQueries: [{ propertyName: "companyForm", first: true, predicate: ["companyForm"], descendants: true }], ngImport: i0, template: "<div class=\"preview-page-header\" *ngIf=\"!isResume\">\r\n <div class=\"d-flex align-items-center gap-2 mb-1\">\r\n <h2 class=\"preview-title mb-0\">Review Extracted Information</h2>\r\n </div>\r\n <p class=\"preview-subtitle text-muted\">We\u2019ve automatically extracted details from your uploaded resume. Please review and confirm accuracy before proceeding.</p>\r\n</div>\r\n\r\n\r\n<div [ngClass]=\"isResume ? '' : 'container py-4'\" [class.provider-layout]=\"roleData?.role?.name === 'Provider'\">\r\n\r\n <!-- Provider initial setup: combined company + personal form (shown until both APIs succeed) -->\r\n <div class=\"section mb-5\" *ngIf=\"roleData?.role?.name === 'Provider' && !hasUserDetailData && !isResume\">\r\n <div class=\"d-flex align-items-center gap-2 mb-3 section-header-title\">\r\n <img src=\"/assets/images/icons/building.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Company & Personal Details</h5>\r\n <span class=\"badge border section-flag bg-warning-subtle text-warning\">Required to continue</span>\r\n </div>\r\n <div class=\"card shadow-sm border-0\">\r\n <div class=\"card-header bg-white fw-semibold\">Company Information</div>\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-3\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': (!tempCompanyDetails.companyName?.trim() && companyFormSubmitted) || companyNameError}\"\r\n [(ngModel)]=\"tempCompanyDetails.companyName\" name=\"setupCompanyName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyName?.trim() && companyFormSubmitted\">Company name is required</div>\r\n <div class=\"invalid-feedback\" *ngIf=\"companyNameError\">{{ companyNameError }}</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" maxlength=\"14\" inputmode=\"numeric\"\r\n (input)=\"phoneMask($event, 'company')\" (keypress)=\"allowOnlyNumbers($event)\"\r\n [ngClass]=\"{'is-invalid': companyFormSubmitted && (!tempCompanyDetails.companyPhoneNumber?.trim() || getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10)}\"\r\n [(ngModel)]=\"tempCompanyDetails.companyPhoneNumber\" name=\"setupCompanyPhone\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted\">Company phone is required</div>\r\n <div class=\"invalid-feedback\" *ngIf=\"tempCompanyDetails.companyPhoneNumber?.trim() && getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10 && companyFormSubmitted\">Company phone must be 10 digits</div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Company Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempCompanyDetails.address1\" name=\"setupCompanyAddress\"\r\n [options]=\"options\" inputClass=\"form-control form-control-sm\"\r\n [invalid]=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\"\r\n [initialLat]=\"tempCompanyDetails.latitude\" [initialLng]=\"tempCompanyDetails.longitude\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"\r\n (manualEdit)=\"onCompanyAddressManualEdit()\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\">Address is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.city?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.city\" name=\"setupCompanyCity\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.city?.trim() && companyFormSubmitted\">City is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.state?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.state\" name=\"setupCompanyState\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.state?.trim() && companyFormSubmitted\">State is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.zipcode?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.zipcode\" name=\"setupCompanyZip\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.zipcode?.trim() && companyFormSubmitted\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.country?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.country\" name=\"setupCompanyCountry\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.country?.trim() && companyFormSubmitted\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <input type=\"file\" accept=\".png,.jpg,.jpeg\" class=\"form-control form-control-sm\" (change)=\"uploadCompanyImage($event)\" name=\"setupCompanyLogo\" />\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"tempCompanyLogoUrl\">\r\n <label class=\"small text-muted d-block\">Logo Preview</label>\r\n <img [src]=\"tempCompanyLogoUrl\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-header bg-white fw-semibold border-top\">Personal Information</div>\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-3\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">First Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.firstName?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.firstName\" name=\"setupFirstName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.firstName?.trim() && companyFormSubmitted\">First name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.lastName?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.lastName\" name=\"setupLastName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.lastName?.trim() && companyFormSubmitted\">Last name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Email <span class=\"text-danger\">*</span></label>\r\n <input type=\"email\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.email?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.email\" name=\"setupEmail\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.email?.trim() && companyFormSubmitted\">Email is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Phone Number <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" maxlength=\"14\" inputmode=\"numeric\"\r\n (input)=\"phoneMask($event, 'profile')\" (keypress)=\"allowOnlyNumbers($event)\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.phone?.trim() && companyFormSubmitted}\"\r\n [ngModel]=\"tempProfile?.phone\" name=\"setupPhone\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.phone?.trim() && companyFormSubmitted\">Phone number is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempProfile.address\" name=\"setupAddress\" [options]=\"options\"\r\n inputClass=\"form-control form-control-sm\" [invalid]=\"!tempProfile?.address?.trim() && companyFormSubmitted\"\r\n [initialLat]=\"tempProfile.latitude\" [initialLng]=\"tempProfile.longitude\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"\r\n (manualEdit)=\"onUserAddressManualEdit()\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.address?.trim() && companyFormSubmitted\">Home address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.city?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.city\" name=\"setupUserCity\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.city?.trim() && companyFormSubmitted\">City is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.state?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.state\" name=\"setupUserState\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.state?.trim() && companyFormSubmitted\">State is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.zipCode?.trim() && companyFormSubmitted}\"\r\n [ngModel]=\"tempProfile?.zipCode\" (ngModelChange)=\"tempProfile.zipCode = sanitizeZipCode($event)\"\r\n name=\"setupUserZip\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.zipCode?.trim() && companyFormSubmitted\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.country?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.country\" name=\"setupUserCountry\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.country?.trim() && companyFormSubmitted\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [(ngModel)]=\"tempProfile.jobTitle\" name=\"setupJobTitle\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control form-control-sm\" [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n [ngClass]=\"{'is-invalid': !(tempProfile?.yearsOfExperience > 0) && companyFormSubmitted}\"\r\n name=\"setupYearsOfExp\" min=\"1\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!(tempProfile?.yearsOfExperience > 0) && companyFormSubmitted\">Years of experience is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Profile Picture</label>\r\n <input #setupHeadshotFile type=\"file\" accept=\".png,.jpg,.jpeg\" class=\"d-none\" (change)=\"uploadHeadshotImage($event)\" name=\"setupHeadshotFile\" />\r\n <div class=\"position-relative\">\r\n <input type=\"text\" class=\"form-control form-control-sm pe-5\" [value]=\"headshotFileName\" readonly\r\n placeholder=\"Upload Profile Picture\" (click)=\"setupHeadshotFile.click()\" />\r\n <img *ngIf=\"!isHeadshotLoading\" src=\"assets/images/icons/upload.svg\" alt=\"Upload\" class=\"upload-icon\" style=\"position:absolute;right:12px;top:50%;transform:translateY(-50%);cursor:pointer;width:18px;\" (click)=\"setupHeadshotFile.click()\" />\r\n <div *ngIf=\"isHeadshotLoading\" style=\"position:absolute;right:12px;top:50%;transform:translateY(-50%);\">\r\n <span class=\"spinner-border spinner-border-sm text-primary\"></span>\r\n </div>\r\n </div>\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"headshotPreviewUrl\">\r\n <label class=\"small text-muted d-block\">Preview</label>\r\n <img [src]=\"headshotPreviewUrl\" class=\"img-thumbnail rounded-circle\" style=\"width:64px;height:64px;object-fit:cover;\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-footer d-flex align-items-center justify-content-end gap-2\">\r\n <span *ngIf=\"providerSetupError\" class=\"small text-danger me-auto\">{{ providerSetupError }}</span>\r\n <button class=\"btn btn-success px-5 \"\r\n [disabled]=\"isSavingProviderSetup || !isProviderSetupFormComplete\"\r\n (click)=\"saveProviderSetup()\">\r\n <span *ngIf=\"isSavingProviderSetup\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingProviderSetup ? 'Saving...' : 'Save & Continue' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\" *ngIf=\"roleData?.role?.name !== 'Provider' || hasUserDetailData\">\r\n <div *ngIf=\"details() as data; else loading\">\r\n <div class=\"card shadow-sm border-0 rounded-3 overflow-hidden\" *ngIf=\"!isEditMode()\">\r\n <div class=\"card-body p-0\">\r\n <div class=\"preview-card-gradient\">\r\n <div class=\"d-flex justify-content-between align-items-start mb-4\">\r\n <div class=\"d-flex align-items-start gap-3\">\r\n <div class=\"profile-avatar-circle\" *ngIf=\"!headshotPreviewUrl\">\r\n {{ (data.firstName?.[0] || '') }}{{ (data.lastName?.[0] || '') }}\r\n </div>\r\n <img *ngIf=\"headshotPreviewUrl\" [src]=\"headshotPreviewUrl\"\r\n class=\"rounded-circle\" style=\"width:56px;height:56px;object-fit:cover;\" alt=\"Profile\" />\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h2 class=\"fw-bold mb-1\">{{ data.firstName }} {{ data.lastName }}</h2>\r\n <span *ngIf=\"basicSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n <span class=\"badge border section-flag\"\r\n [ngClass]=\"basicDetailsSaved ? 'bg-success-subtle text-success' : 'bg-warning-subtle text-warning'\">\r\n {{ basicDetailsSaved ? 'Saved' : 'Not saved yet' }}\r\n </span>\r\n </div>\r\n <p class=\"text-muted\">{{ data.jobTitle }} \u2022 {{ data.yearsOfExperience }} Years Exp.</p>\r\n <div *ngIf=\"basicIssues().length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ basicIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <span class=\"badge bg-primary-subtle text-primary border p-2\">Email Verified</span>\r\n </div>\r\n\r\n </div>\r\n <div class=\"px-4 py-3\">\r\n <div class=\"row g-4\">\r\n <div class=\"col-12 border-bottom pb-2\">\r\n <h6 class=\"text-uppercase small fw-bold text-muted\">Summary</h6>\r\n <p class=\"text-secondary small mb-0\">{{ data.summary }}</p>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/envelope.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Email</span>\r\n <span class=\"field-value-sm d-block\">{{ data.email }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/telephone.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Phone</span>\r\n <span class=\"field-value-sm d-block\">{{ data.phone }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/geo-alt.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Location</span>\r\n <span class=\"field-value-sm d-block\">{{ data.address }}, {{ data.city }}, {{ data.state }}, {{ data.zipCode }}, {{ data.country }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer d-flex align-items-center justify-content-between\">\r\n <span *ngIf=\"!basicDetailsSaved\" class=\"small text-warning fw-semibold\">\r\n <img src=\"/assets/images/icons/exclamation-circle.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" /> Click \"Edit\" to review and save your basic info.\r\n </span>\r\n <span *ngIf=\"basicDetailsSaved\" class=\"small text-success fw-semibold\">\r\n <img src=\"/assets/images/icons/check-circle.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" /> Basic details saved.\r\n </span>\r\n <button class=\"btn btn-sm btn-primary px-4 ms-auto\" (click)=\"toggleEdit()\">Edit</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"isEditMode()\">\r\n <div class=\"card-header bg-white fw-bold\">Update Profile</div>\r\n <div class=\"card-body p-4\">\r\n <form class=\"row g-3\" #basicForm=\"ngForm\" novalidate>\r\n <div *ngIf=\"basicIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ basicIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">First Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.firstName\" name=\"fName\"\r\n placeholder=\"First Name\" required #fName=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"fName.invalid && (fName.dirty || fName.touched)\">First name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.lastName\" name=\"lName\"\r\n placeholder=\"Last Name\" required #lName=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"lName.invalid && (lName.dirty || lName.touched)\">Last name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Email <span class=\"text-danger\">*</span></label>\r\n <input type=\"email\" class=\"form-control\" [(ngModel)]=\"tempProfile.email\" name=\"email\" placeholder=\"Email\"\r\n required email #email=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"email.invalid && (email.dirty || email.touched)\">\r\n <span *ngIf=\"email.errors?.['required']\">Email is required</span>\r\n <span *ngIf=\"email.errors?.['email']\">Email format is invalid</span>\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Phone Number <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"tempProfile.phone\" (input)=\"phoneMask($event, 'profile')\"\r\n name=\"phone\" placeholder=\"Phone (10 digits)\" (keypress)=\"allowOnlyNumbers($event)\"\r\n required pattern=\"^\\(\\d{3}\\) \\d{3}-\\d{4}$\" maxlength=\"14\" inputmode=\"numeric\" #phone=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"phone.invalid && (phone.dirty || phone.touched)\">\r\n <span *ngIf=\"phone.errors?.['required']\">Phone number is required</span>\r\n <span *ngIf=\"phone.errors?.['pattern']\">Phone number must be 10 digits</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\"></span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.jobTitle\" name=\"jobTitle\"\r\n placeholder=\"Job Title\" #jobTitle=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"jobTitle.invalid && (jobTitle.dirty || jobTitle.touched)\">Job\r\n title is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngClass]=\"{'is-invalid': !(tempProfile?.yearsOfExperience > 0)}\"\r\n [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n name=\"yearsOfExperience\" placeholder=\"Years of Experience\" required min=\"1\"\r\n #yearsOfExperience=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!(tempProfile?.yearsOfExperience > 0)\">\r\n Years of experience is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempProfile.address\" name=\"address\" [options]=\"options\"\r\n placeholder=\"Home Address\" required #address=\"ngModel\"\r\n [invalid]=\"address.invalid && (address.dirty || address.touched)\"\r\n [initialLat]=\"tempProfile.latitude\" [initialLng]=\"tempProfile.longitude\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"\r\n (manualEdit)=\"onUserAddressManualEdit()\"></im-address-verify-field>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"address.invalid && (address.dirty || address.touched)\">Home\r\n address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.city\" name=\"city\" placeholder=\"City\"\r\n required #city=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"city.invalid && (city.dirty || city.touched)\">City is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.state\" name=\"state\" placeholder=\"State\"\r\n required #state=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"state.invalid && (state.dirty || state.touched)\">State is\r\n required</div>\r\n </div>\r\n\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"tempProfile.zipCode\"\r\n (ngModelChange)=\"tempProfile.zipCode = sanitizeZipCode($event)\" name=\"zipCode\" placeholder=\"Zip Code\"\r\n required pattern=\"^\\d{1,6}$\" maxlength=\"6\" inputmode=\"numeric\" #zipCode=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"zipCode.invalid && (zipCode.dirty || zipCode.touched)\">Zip code\r\n is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"zipCode.errors?.['pattern'] && (zipCode.dirty || zipCode.touched)\">\r\n Zip code must be up to 6 digits\r\n </div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.country\" name=\"country\"\r\n placeholder=\"Country\" required #country=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"country.invalid && (country.dirty || country.touched)\">Country\r\n is required</div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Summary</label>\r\n <textarea class=\"form-control\" rows=\"3\" [(ngModel)]=\"tempProfile.summary\" name=\"sum\"\r\n placeholder=\"Summary\"></textarea>\r\n </div>\r\n\r\n\r\n </form>\r\n </div>\r\n <div class=\"card-footer text-end gap-2 d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancel()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingBasic || !isBasicFormValid\" (click)=\"save()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Saving...' : 'Save Changes' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5 provider-company-first\" *ngIf=\"roleData?.role?.name === 'Provider' && hasUserDetailData && !isResume\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/building.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Company Details</h5>\r\n <span *ngIf=\"companyDetailsSaved\"\r\n class=\"badge border section-flag bg-success-subtle text-success\">\r\n Saved\r\n </span>\r\n <span *ngIf=\"!companyDetailsSaved\"\r\n class=\"badge border section-flag bg-warning-subtle text-warning\">\r\n Not saved yet\r\n </span>\r\n </div>\r\n <button class=\"btn btn-sm btn-primary px-4\" (click)=\"toggleCompanyEdit()\">Edit</button>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"!isCompanyEditMode()\">\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-4\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name</label>\r\n <span class=\"fw-bold small\">{{ companyDetails()?.companyName}}</span>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone</label>\r\n <span class=\"fw-bold small\">{{ companyDetails()?.companyPhoneNumber}}</span>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Company Address</label>\r\n <span class=\"small\">{{ companyDetails()?.address1}}, {{ companyDetails()?.city}}, {{ companyDetails()?.state}}, {{ companyDetails()?.zipcode}}, {{ companyDetails()?.country}}</span>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"companyLogoUrl()\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <img [src]=\"companyLogoUrl()\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"isCompanyEditMode()\">\r\n <div class=\"card-header bg-white fw-bold\">Update Company Details</div>\r\n <div class=\"card-body p-4\">\r\n <form class=\"row g-3\" #companyForm=\"ngForm\" novalidate>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': (!tempCompanyDetails.companyName?.trim() && companyFormSubmitted) || companyNameError }\"\r\n [(ngModel)]=\"tempCompanyDetails.companyName\" name=\"companyName\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyName?.trim() && companyFormSubmitted\">\r\n Company name is required\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"companyNameError\">\r\n {{ companyNameError }}\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone <span class=\"text-danger\">*</span></label>\r\n <input (input)=\"phoneMask($event, 'company')\" type=\"text\" maxlength=\"14\" (keypress)=\"allowOnlyNumbers($event)\" inputmode=\"numeric\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{ 'is-invalid': companyFormSubmitted && (!tempCompanyDetails.companyPhoneNumber?.trim() || getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10) }\"\r\n [(ngModel)]=\"tempCompanyDetails.companyPhoneNumber\" name=\"companyPhoneNumber\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted\">\r\n Company phone is required\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"tempCompanyDetails.companyPhoneNumber?.trim() && getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10 && companyFormSubmitted\">\r\n Company phone must be 10 digits\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempCompanyDetails.address1\" name=\"address1\" [options]=\"options\"\r\n required [invalid]=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\"\r\n [initialLat]=\"tempCompanyDetails.latitude\" [initialLng]=\"tempCompanyDetails.longitude\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"\r\n (manualEdit)=\"onCompanyAddressManualEdit()\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\">\r\n Address is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.city?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.city\" name=\"city\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.city?.trim() && companyFormSubmitted\">\r\n City is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.state?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.state\" name=\"state\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.state?.trim() && companyFormSubmitted\">\r\n State is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.zipcode?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.zipcode\" name=\"zipcode\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.zipcode?.trim() && companyFormSubmitted\">\r\n Zip code is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.country?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.country\" name=\"country\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.country?.trim() && companyFormSubmitted\">\r\n Country is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <input #uploadCompanyFile type=\"file\" accept=\".png,.jpg,.jpeg\" (change)=\"uploadCompanyImage($event)\" class=\"form-control\" />\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"tempCompanyLogoUrl\">\r\n <label class=\"small text-muted d-block\">Logo Preview</label>\r\n <img [src]=\"tempCompanyLogoUrl\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </form>\r\n </div>\r\n <div class=\"card-footer text-end gap-2 d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelCompanyEdit()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCompany\" \r\n (click)=\"saveCompanyDetails()\">\r\n <span *ngIf=\"isSavingCompany\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCompany ? 'Saving...' : 'Save Changes' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div [class.section-locked]=\"roleData?.role?.name === 'Provider' && !hasUserDetailData\">\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/briefcase-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Work Experience</h5>\r\n <span *ngIf=\"experience().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"workSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ workSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"experience().length === 0 || !workSectionHasUnsavedItems() || isSavingWork || isAddingJob() || editingJobIndex() !== null\"\r\n (click)=\"confirmAllWork()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add work experience\" (click)=\"addJob()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"experience().length === 0 && !isAddingJob()\" class=\"empty-state-wrap mb-3\" role=\"button\"\r\n (click)=\"addJob()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/briefcase.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No work experience added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3\">\r\n <div *ngIf=\"isAddingJob() && tempJob()\" class=\"list-group-item p-0 border-0\">\r\n <div class=\"form-panel mb-2\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\" name=\"newJobTitle\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\" name=\"newCompany\" />\r\n </div>\r\n <div class=\"align-items-end col-md-12 d-flex justify-content-end pe-3\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\" name=\"newIsCurrent\" id=\"newIsCurrent\" />\r\n <label class=\"form-check-label\" for=\"newIsCurrent\">Current</label>\r\n </div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.country\"\r\n (ngModelChange)=\"patchTempJob({ country: $event })\" name=\"newCountry\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.state\"\r\n (ngModelChange)=\"patchTempJob({ state: $event })\" name=\"newState\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\" name=\"newCity\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempJob()?.startDate)\"\r\n (bsValueChange)=\"setTempJobMonth('startDate', $event)\" name=\"newStartDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.startDate)\">Start date is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"monthInputToDate(tempJob()?.endDate)\" (bsValueChange)=\"setTempJobMonth('endDate', $event)\"\r\n name=\"newEndDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">End date is\r\n required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isMonthRangeInvalid(tempJob()?.startDate, tempJob()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Responsibilities (one per line)</label>\r\n <textarea rows=\"4\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\" name=\"newResponsibilities\"></textarea>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\" name=\"newWorkAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempJob()?.fileName\">\r\n <span>{{ tempJob()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempJob())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n <div class=\"d-flex justify-content-end gap-2 mt-3\">\r\n <button class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingWork\"\r\n (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : workActionLabel(editingJobIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n\r\n <div *ngFor=\"let job of experience(); let i = index\" class=\"list-group-item p-0 border-0 mb-2\">\r\n\r\n <div class=\"work-accent-item p-3 rounded-3 bg-white border\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div class=\"d-flex align-items-center cursor-pointer flex-grow-1\" (click)=\"toggleJob(i)\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h6 class=\"mb-0 fw-bold item-title-sm\">{{ job.jobTitle }}</h6>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedWorkItem(i) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedWorkItem(i) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ job.company || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ formatMonthYear(job.startDate) }} - {{ job.isCurrent ? 'Present' :\r\n formatMonthYear(job.endDate) }}</span>\r\n <span class=\"item-meta-line\">{{ job.city }}<span *ngIf=\"job.city && job.state\">, </span>{{ job.state }}<ng-container *ngIf=\"!job.city && !job.state\">\u2014</ng-container></span>\r\n <div *ngIf=\"editingJobIndex() !== i && (workIssuesByIndex()[i] || []).length > 0\"\r\n class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (workIssuesByIndex()[i] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center gap-2\">\r\n\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\" (click)=\"startEditJob(i)\"\r\n title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteJob(i);\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n \r\n </div>\r\n </div>\r\n\r\n\r\n\r\n <div class=\"mt-3 p-3 rounded small\" *ngIf=\"expandedIndex() === i\">\r\n <ng-container *ngIf=\"editingJobIndex() !== i; else editJobForm\">\r\n <ul class=\"mb-0\">\r\n <li *ngFor=\"let res of job.responsibilities\">{{ res }}</li>\r\n </ul>\r\n </ng-container>\r\n\r\n <ng-template #editJobForm>\r\n <div *ngIf=\"(workIssuesByIndex()[i] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (workIssuesByIndex()[i] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\" name=\"jobTitle{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.jobTitle)\">Job title is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\" name=\"company{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.company)\">Company name is required</div>\r\n </div>\r\n\r\n <div class=\"align-items-end col-md-12 d-flex justify-content-end pe-3\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\" name=\"isCurrent{{ i }}\" id=\"isCurrent{{ i }}\" />\r\n <label class=\"form-check-label\" for=\"isCurrent{{ i }}\">Current</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.country\"\r\n (ngModelChange)=\"patchTempJob({ country: $event })\" name=\"country{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.state\"\r\n (ngModelChange)=\"patchTempJob({ state: $event })\" name=\"state{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\" name=\"city{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.city)\">City is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempJob()?.startDate)\"\r\n (bsValueChange)=\"setTempJobMonth('startDate', $event)\" name=\"startDate{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.startDate)\">Start date is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"monthInputToDate(tempJob()?.endDate)\" (bsValueChange)=\"setTempJobMonth('endDate', $event)\"\r\n name=\"endDate{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">\r\n End date is required\r\n </div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isMonthRangeInvalid(tempJob()?.startDate, tempJob()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Responsibilities (one per line)</label>\r\n <textarea rows=\"4\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\" name=\"responsibilities{{ i }}\"></textarea>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\" name=\"workAttachment{{ i }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempJob()?.fileName\">\r\n <span>{{ tempJob()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempJob())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n </ng-template>\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-3\" *ngIf=\"editingJobIndex() === i\">\r\n <button class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4 \" [disabled]=\"isSavingWork\"\r\n (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : workActionLabel(editingJobIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/patch-check-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Certifications</h5>\r\n <span *ngIf=\"certs().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"certificationSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ certificationSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"certs().length === 0 || !certificationSectionHasUnsavedItems() || isSavingCertification || isAddingCertification() || editingCertificationIndex() !== null\"\r\n (click)=\"confirmAllCertifications()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add certification\" (click)=\"addCertification()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"certs().length === 0 && !isAddingCertification() && editingCertificationIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addCertification()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/patch-check.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No certifications added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3 border\">\r\n <div *ngIf=\"isAddingCertification() && tempCertification()\" class=\"list-group-item py-3 px-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\" name=\"newCertName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\" name=\"newCertOrg\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\" name=\"newCertState\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certification Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\" name=\"newCertCredentialId\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('issueDate', $event)\" name=\"newCertIssueDate\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('expiryDate', $event)\" name=\"newCertExpiryDate\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempCertification()?.issueDate || null, tempCertification()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\" name=\"newCertAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempCertification()?.fileName\">\r\n <span>{{ tempCertification()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempCertification())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\"\r\n (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : certificationActionLabel(editingCertificationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let cert of certs(); let ci = index\" class=\"list-group-item py-3 cert-accent-item\">\r\n <ng-container *ngIf=\"editingCertificationIndex() !== ci; else editCert\">\r\n <div class=\"d-flex justify-content-between align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <div class=\"fw-semibold item-title-sm\">{{ cert.name }}</div>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedCertificationItem(ci) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedCertificationItem(ci) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ cert.issuingOrganization || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.credentialId || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.issueDate ? formatMonthYear(cert.issueDate) : '\u2014' }} - {{ cert.expiryDate ? formatMonthYear(cert.expiryDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.state || '\u2014' }}</span>\r\n <div *ngIf=\"(certIssuesByIndex()[ci] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (certIssuesByIndex()[ci] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditCertification(ci)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteCertification(ci)\" title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #editCert>\r\n <div *ngIf=\"(certIssuesByIndex()[ci] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (certIssuesByIndex()[ci] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\" name=\"certName{{ ci }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\"\r\n name=\"certOrg{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\" name=\"certState{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certification Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\"\r\n name=\"certCredentialId{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('issueDate', $event)\" name=\"certIssue{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('expiryDate', $event)\" name=\"certExpiry{{ ci }}\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempCertification()?.issueDate || null, tempCertification()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\" name=\"certAttachment{{ ci }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempCertification()?.fileName\">\r\n <span>{{ tempCertification()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempCertification())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\"\r\n (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : certificationActionLabel(editingCertificationIndex()) }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/card-checklist-warning.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Licenses</h5>\r\n <span *ngIf=\"licenses().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"licenseSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ licenseSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"licenses().length === 0 || !licenseSectionHasUnsavedItems() || isSavingLicense || isAddingLicense() || editingLicenseIndex() !== null\"\r\n (click)=\"confirmAllLicenses()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add license\" (click)=\"addLicense()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"licenses().length === 0 && !isAddingLicense() && editingLicenseIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addLicense()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/card-checklist.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No licenses added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3 border\">\r\n <div *ngIf=\"isAddingLicense() && tempLicense()\" class=\"list-group-item py-3 px-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\" name=\"newLicName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempLicense()?.name)\">License name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\" name=\"newLicAuthority\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\" name=\"newLicNumber\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\" name=\"newLicState\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('issueDate', $event)\" name=\"newLicIssueDate\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('expiryDate', $event)\" name=\"newLicExpiryDate\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempLicense()?.issueDate || null, tempLicense()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">License File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\" name=\"newLicenseAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempLicense()?.fileName\">\r\n <span>{{ tempLicense()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempLicense())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelEditLicense()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingLicense\"\r\n (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : licenseActionLabel(editingLicenseIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let lic of licenses(); let li = index\" class=\"list-group-item py-3 lic-accent-item\">\r\n <ng-container *ngIf=\"editingLicenseIndex() !== li; else editLic\">\r\n <div class=\"d-flex justify-content-between align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <div class=\"fw-semibold item-title-sm\">{{ lic.name }}</div>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedLicenseItem(li) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedLicenseItem(li) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ lic.issuingAuthority || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.licenseNumber || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.issueDate ? formatMonthYear(lic.issueDate) : '\u2014' }} - {{ lic.expiryDate ? formatMonthYear(lic.expiryDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.state || '\u2014' }}</span>\r\n <div *ngIf=\"(licenseIssuesByIndex()[li] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (licenseIssuesByIndex()[li] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditLicense(li)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteLicense(li)\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #editLic>\r\n <div *ngIf=\"(licenseIssuesByIndex()[li] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (licenseIssuesByIndex()[li] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\" name=\"licName{{ li }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempLicense()?.name)\">License name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\" name=\"licAuthority{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\" name=\"licNumber{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\" name=\"licState{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('issueDate', $event)\" name=\"licIssue{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('expiryDate', $event)\" name=\"licExpiry{{ li }}\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempLicense()?.issueDate || null, tempLicense()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">License File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\" name=\"licenseAttachment{{ li }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempLicense()?.fileName\">\r\n <span>{{ tempLicense()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempLicense())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditLicense()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingLicense\"\r\n (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : licenseActionLabel(editingLicenseIndex()) }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/tools.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Tools</h5>\r\n <span *ngIf=\"tools().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"toolsSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ toolsSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"tools().length === 0 || !toolsSectionHasUnsavedItems() || isSavingTool || isToolEditorOpen()\" (click)=\"confirmAllTools()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add tool\" (click)=\"addTool()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex flex-wrap gap-2 p-3 bg-white border rounded shadow-sm\">\r\n <div *ngFor=\"let tool of tools(); let ti = index\" class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\"\r\n class=\"btn btn-light border res-flex d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openToolEditor(ti)\" title=\"Edit\">\r\n <span class=\"fw-normal item-name-text\">{{ tool }}</span>\r\n <span class=\"badge border ms-1\"\r\n [ngClass]=\"hasUnsavedToolItem(ti) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedToolItem(ti) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n <span *ngIf=\"(toolIssuesByIndex()[ti] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\">\r\n Missing info\r\n </span>\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Delete tool\" (click)=\"deleteTool(ti)\">\r\n <span class=\"fw-bold\">\u00D7</span>\r\n </button>\r\n </div>\r\n\r\n <span *ngIf=\"tools().length === 0\" class=\"text-muted small\">No tools added.</span>\r\n </div>\r\n\r\n <div *ngIf=\"isToolEditorOpen()\" class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 9999999;\" (click)=\"closeToolEditor()\">\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\"\r\n (click)=\"$event.stopPropagation()\">\r\n <div class=\"card shadow border-0 w-100\" style=\"max-width: 900px;\">\r\n <div class=\"card-header bg-white d-flex align-items-center gap-3\">\r\n <button type=\"button\" class=\"btn btn-link p-0 text-decoration-none\" (click)=\"closeToolEditor()\">\r\n <img src=\"/assets/images/icons/arrow-left-blue.svg\" width=\"20\" height=\"20\" alt=\"\" />\r\n </button>\r\n <div class=\"fw-bold\">{{ isAddingTool() ? 'Add Tool' : ('Edit ' + (toolForm()?.name || '') + ' Tool') }}\r\n </div>\r\n </div>\r\n <div class=\"card-body p-4\">\r\n <div *ngIf=\"toolFormIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ toolFormIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"row g-3\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Tool Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"toolForm()?.name\"\r\n (ngModelChange)=\"patchToolForm({ name: $event })\" name=\"toolName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(toolForm()?.name)\">Tool name is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span\r\n class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempToolStars(s)\" [attr.aria-label]=\"'Set rating ' + s\">\r\n <span [class]=\"(toolForm()?.stars || 0) >= s ? 'text-warning fs-5' : 'text-muted fs-5'\">\r\n {{ (toolForm()?.stars || 0) >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ toolForm()?.stars || 0 }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"(toolForm()?.stars || 0) <= 0\">Star rating is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngModel]=\"toolForm()?.year\"\r\n (ngModelChange)=\"patchToolForm({ year: $event === '' ? null : +$event })\" name=\"toolYear\" min=\"1\"\r\n max=\"30\" placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"toolForm()?.year === null || toolForm()?.year === undefined\">\r\n Years of experience is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4 text-center\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-checks form-switch mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"toolForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchToolForm({ profileVisibility: $event })\" name=\"toolVisible\" id=\"toolVisible\"\r\n style=\"width: 55px;height: 25px;margin-left: -57px;\" />\r\n <label class=\"form-check-label ps-2 pt-1\" for=\"toolVisible\">Visible</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Comment</label>\r\n <textarea rows=\"4\" class=\"form-control\" [ngModel]=\"toolForm()?.notes\"\r\n (ngModelChange)=\"patchToolForm({ notes: $event })\" name=\"toolNotes\"\r\n placeholder=\"Comment your tool here...\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-white d-flex justify-content-end gap-2\">\r\n <button *ngIf=\"!isAddingTool() && editingToolIndex() !== null\" type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\" (click)=\"deleteTool(editingToolIndex()!)\">\r\n Delete\r\n </button>\r\n <button type=\"button\" class=\"btn btn-link text-secondary\" (click)=\"closeToolEditor()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary px-4\" [disabled]=\"isSavingTool\" (click)=\"saveToolEditor()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Saving...' : toolActionLabel(editingToolIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row g-4 mb-5\">\r\n <div class=\"col-md-12\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/stars.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Skills</h5>\r\n <span *ngIf=\"skills().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"skillsSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ skillsSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"skills().length === 0 || !skillsSectionHasUnsavedItems() || isSavingSkill || isSkillEditorOpen()\" (click)=\"confirmAllSkills()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add skill\" (click)=\"addSkill()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex flex-wrap gap-2 p-3 bg-white border rounded shadow-sm\">\r\n <div *ngFor=\"let skill of skills(); let si = index\" class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\"\r\n class=\"btn btn-light border res-flex d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openSkillEditor(si)\" title=\"Edit\">\r\n <span class=\"fw-normal item-name-text\">{{ skill }}</span>\r\n <span class=\"badge border ms-1\"\r\n [ngClass]=\"hasUnsavedSkillItem(si) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedSkillItem(si) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n <span *ngIf=\"(skillIssuesByIndex()[si] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\">\r\n Missing info\r\n </span>\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Delete skill\"\r\n (click)=\"deleteSkill(si); $event.stopPropagation()\">\r\n <span class=\"fw-bold\">\u00D7</span>\r\n </button>\r\n </div>\r\n\r\n <span *ngIf=\"skills().length === 0\" class=\"text-muted small\">No skills added.</span>\r\n </div>\r\n <div *ngIf=\"isSkillEditorOpen()\" class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 9999999;\" (click)=\"closeSkillEditor()\">\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\"\r\n (click)=\"$event.stopPropagation()\">\r\n <div class=\"card shadow border-0 w-100\" style=\"max-width: 900px;\">\r\n <div class=\"card-header bg-white d-flex align-items-center gap-3\">\r\n <button type=\"button\" class=\"btn btn-link p-0 text-decoration-none\" (click)=\"closeSkillEditor()\">\r\n <img src=\"/assets/images/icons/arrow-left-blue.svg\" width=\"20\" height=\"20\" alt=\"\" />\r\n </button>\r\n <div class=\"fw-bold\">{{ isAddingSkill() ? 'Add Skill' : ('Edit ' + (skillForm()?.name || '') + ' Skill')\r\n }}</div>\r\n </div>\r\n <div class=\"card-body p-4\">\r\n <div *ngIf=\"skillFormIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ skillFormIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"row g-3\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Skills Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"skillForm()?.name\"\r\n (ngModelChange)=\"patchSkillForm({ name: $event })\" name=\"skillName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(skillForm()?.name)\">Skillset name is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span\r\n class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempSkillStars(s)\" [attr.aria-label]=\"'Set rating ' + s\">\r\n <span [class]=\"(skillForm()?.stars || 0) >= s ? 'text-warning fs-5' : 'text-muted fs-5'\">\r\n {{ (skillForm()?.stars || 0) >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ skillForm()?.stars || 0 }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"(skillForm()?.stars || 0) <= 0\">Star rating is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngModel]=\"skillForm()?.year\"\r\n (ngModelChange)=\"patchSkillForm({ year: $event === '' ? null : +$event })\" name=\"skillYear\" min=\"1\"\r\n max=\"30\" placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"skillForm()?.year === null || skillForm()?.year === undefined\">Years of experience is\r\n required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4 text-center\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-checks form-switch mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"skillForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchSkillForm({ profileVisibility: $event })\" name=\"skillVisible\"\r\n id=\"skillVisible\" style=\"width: 55px;height: 25px;margin-left: -57px;\" />\r\n <label class=\"form-check-label ps-2 pt-1\" for=\"skillVisible\">Visible</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Comment</label>\r\n <textarea rows=\"4\" class=\"form-control\" [ngModel]=\"skillForm()?.notes\"\r\n (ngModelChange)=\"patchSkillForm({ notes: $event })\" name=\"skillNotes\"\r\n placeholder=\"Comment your skill here...\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-white d-flex justify-content-end gap-2\">\r\n <button *ngIf=\"!isAddingSkill() && editingSkillIndex() !== null\" type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\" (click)=\"deleteSkill(editingSkillIndex()!)\">\r\n Delete\r\n </button>\r\n <button type=\"button\" class=\"btn btn-link text-secondary\" (click)=\"closeSkillEditor()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary px-4\" [disabled]=\"isSavingSkill\" (click)=\"saveSkillEditor()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Saving...' : skillActionLabel(editingSkillIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row g-4 mb-5\">\r\n <div class=\"col-md-12\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/mortarboard-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Education</h5>\r\n <span *ngIf=\"educationList().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"educationSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ educationSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"educationList().length === 0 || !educationSectionHasUnsavedItems() || isSavingEducation || isAddingEducation() || editingEducationIndex() !== null\"\r\n (click)=\"confirmAllEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add education\" (click)=\"addEducation()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"educationList().length === 0 && !isAddingEducation() && editingEducationIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addEducation()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/mortarboard.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No education added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div *ngIf=\"isAddingEducation() && tempEducation()\" class=\"mb-2\">\r\n <div class=\"form-panel\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\" name=\"newEduDegree\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Institution <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\" name=\"newEduInstitution\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree / Course Type <span class=\"text-danger\">*</span></label>\r\n <ng-select class=\"ng-select-sm\" [items]=\"educationDegreeTypeOptions\" [clearable]=\"false\"\r\n placeholder=\"Select degree / course type\" [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\" name=\"newEduDegreeType\">\r\n </ng-select>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.country\"\r\n (ngModelChange)=\"patchTempEducation({ country: $event })\" name=\"newEduCountry\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.state\"\r\n (ngModelChange)=\"patchTempEducation({ state: $event })\" name=\"newEduState\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\" name=\"newEduCity\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.startDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('startDate', $event)\" name=\"newEduStartDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.startDate)\">Start date is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.endDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('endDate', $event)\" name=\"newEduEndDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Education File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onEducationFileSelected($event)\" name=\"newEducationAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempEducation()?.fileName\">\r\n <span>{{ tempEducation()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempEducation())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingEducation\"\r\n (click)=\"saveEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Uploading...' : educationActionLabel(editingEducationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let edu of educationList(); let ei = index\" class=\"edu-accent-item p-3 bg-white border rounded-3 shadow-sm mb-2\">\r\n <div class=\"d-flex justify-content-between align-items-start\">\r\n <div class=\"d-flex align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h6 class=\"fw-bold mb-0 item-title-sm\">{{ edu.degree }}</h6>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedEducationItem(ei) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedEducationItem(ei) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ edu.institution || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.degreeType || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.startDate ? formatMonthYear(edu.startDate) : '\u2014' }} - {{ edu.endDate ? formatMonthYear(edu.endDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.city }}<span *ngIf=\"edu.city && edu.state\">, </span>{{ edu.state }}<ng-container *ngIf=\"!edu.city && !edu.state\">\u2014</ng-container></span>\r\n <div *ngIf=\"(educationIssuesByIndex()[ei] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (educationIssuesByIndex()[ei] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\" *ngIf=\"editingEducationIndex() !== ei\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditEducation(ei)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteEducation(ei)\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"editingEducationIndex() === ei\" class=\"mt-3\">\r\n <div *ngIf=\"(educationIssuesByIndex()[ei] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (educationIssuesByIndex()[ei] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\" name=\"eduDegree{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Institution <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\" name=\"eduInstitution{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.institution)\">Institution name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree / Course Type <span class=\"text-danger\">*</span></label>\r\n <ng-select class=\"ng-select-sm\" [items]=\"educationDegreeTypeOptions\" [clearable]=\"false\"\r\n placeholder=\"Select degree / course type\" [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\" name=\"eduDegreeType{{ ei }}\">\r\n </ng-select>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.country\"\r\n (ngModelChange)=\"patchTempEducation({ country: $event })\" name=\"eduCountry{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.state\"\r\n (ngModelChange)=\"patchTempEducation({ state: $event })\" name=\"eduState{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\" name=\"eduCity{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.startDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('startDate', $event)\" name=\"eduStartDate{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.startDate)\">Start date is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.endDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('endDate', $event)\" name=\"eduEndDate{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Education File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onEducationFileSelected($event)\" name=\"educationAttachment{{ ei }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempEducation()?.fileName\">\r\n <span>{{ tempEducation()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempEducation())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingEducation\" (click)=\"saveEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Uploading...' : educationActionLabel(editingEducationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n </div>\r\n <div class=\"d-flex gap-3 justify-content-center mt-5 pt-2\" *ngIf=\"!isResume\">\r\n <button class=\"btn btn-outline-secondary preview-back-btn px-5 h-auto\" style=\"border-radius: 5px !important;\" (click)=\"onBackClick()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"me-1\" style=\"vertical-align:-0.1em\">\r\n <path d=\"M11 3 5 8l6 5\" />\r\n </svg> Back\r\n </button>\r\n <button class=\"btn btn-primary preview-dashboard-btn px-5 h-auto\" style=\"border-radius: 5px !important;\" [disabled]=\"!canConfirmAndContinue() || isSavingBasic\"\r\n (click)=\"onGoToDashboardClick()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Saving...' : 'Go to Dashboard' }}\r\n <img *ngIf=\"!isSavingBasic\" src=\"/assets/images/icons/arrow-right-white.svg\" width=\"14\" height=\"14\" class=\"ms-1\" style=\"vertical-align:-0.1em\" alt=\"\" />\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<ng-template #loading>\r\n <div class=\"text-center p-5\">\r\n <div class=\"spinner-border text-primary\"></div>\r\n <p class=\"text-muted mt-2\">Loading data...</p>\r\n </div>\r\n</ng-template>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBulkSkillConfirm\">\r\n <div class=\"confirm-modal-card\" style=\"max-width: 480px;\">\r\n <h4 class=\"mb-1\">Set Rating for All Skills</h4>\r\n <p class=\"text-muted small mb-4\">Enter a star rating and years of experience to apply to all skills that are missing these values.</p>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"bulkSkillStars = s\">\r\n <span [class]=\"bulkSkillStars >= s ? 'text-warning fs-4' : 'text-muted fs-4'\">\r\n {{ bulkSkillStars >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ bulkSkillStars }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkSkillStars <= 0\">Star rating is required</div>\r\n </div>\r\n <div class=\"mb-4\">\r\n <label class=\"small text-muted d-block mb-1\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [(ngModel)]=\"bulkSkillYear\" min=\"1\" max=\"30\"\r\n placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkSkillYear === null || bulkSkillYear === undefined\">Years of experience is required</div>\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"cancelBulkSkillConfirm()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingSkill || bulkSkillStars <= 0 || bulkSkillYear === null\"\r\n (click)=\"applyBulkSkillConfirm()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Saving...' : 'Apply to All & Save' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBulkToolConfirm\">\r\n <div class=\"confirm-modal-card\" style=\"max-width: 480px;\">\r\n <h4 class=\"mb-1\">Set Rating for All Tools</h4>\r\n <p class=\"text-muted small mb-4\">Enter a star rating and years of experience to apply to all tools that are missing these values.</p>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"bulkToolStars = s\">\r\n <span [class]=\"bulkToolStars >= s ? 'text-warning fs-4' : 'text-muted fs-4'\">\r\n {{ bulkToolStars >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ bulkToolStars }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkToolStars <= 0\">Star rating is required</div>\r\n </div>\r\n <div class=\"mb-4\">\r\n <label class=\"small text-muted d-block mb-1\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [(ngModel)]=\"bulkToolYear\" min=\"1\" max=\"30\"\r\n placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkToolYear === null || bulkToolYear === undefined\">Years of experience is required</div>\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"cancelBulkToolConfirm()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingTool || bulkToolStars <= 0 || bulkToolYear === null\"\r\n (click)=\"applyBulkToolConfirm()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Saving...' : 'Apply to All & Save' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBackConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Leave this page?</h4>\r\n <p class=\"text-muted mb-4\">If you go back, only saved data will be retained.</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"stayOnPreview()\">Stay</button>\r\n <button type=\"button\" class=\"btn btn-danger h-auto\" (click)=\"proceedBack()\">Proceed Back</button>\r\n </div>\r\n </div>\r\n\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showDashboardConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Finish Setup and Continue</h4>\r\n <p class=\"text-muted mb-4\">Save your information and go to your dashboard</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" [disabled]=\"isSavingBasic\"\r\n (click)=\"cancelDashboardRedirect()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingBasic\" (click)=\"goToDashboard()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Proceeding...' : 'Proceed' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{color:#69707d}.res-flex:hover,.res-flex:focus,.res-flex:active{transform:none!important;box-shadow:none!important}.container{max-width:900px;margin:30px auto;font-family:Arial,sans-serif;color:#69707d}.preview-page-header{max-width:900px;margin:50px auto 10px;padding:0 12px}.preview-title{font-size:18px;font-weight:700;color:#69707d;margin:0}.preview-subtitle{margin-top:7px;font-size:14px;color:#69707d}.preview-card-gradient h2,.section h5.fw-bold{font-size:18px}.section{margin-bottom:25px}.section-title{font-weight:600;display:block;margin-bottom:8px}.section-title .sub{font-weight:400;color:#777;font-size:13px}.dropdown-box{border:1px solid #ddd;border-radius:8px;padding:12px 15px;display:flex;justify-content:space-between;align-items:center}.icons{display:flex;gap:10px}.icon{cursor:pointer;font-size:14px;color:#777}.card{border:1px solid #ddd;border-radius:5px;padding:20px;background:#fff}.category{border-bottom:1px solid #eee;padding:15px 0}.category:last-child{border-bottom:none}.category-header{display:flex;justify-content:space-between;font-weight:600;margin-bottom:10px}.tags{display:flex;flex-wrap:wrap;gap:10px}.tag{background:#f2f4f7;padding:6px 12px;border-radius:6px;font-size:13px}.footer{text-align:center;margin-top:15px;color:#777;cursor:pointer}.actions{display:flex;justify-content:space-between;margin:50px 0 27px}.text-secondary{white-space:pre-line;font-size:12px;color:#69707d}.extra-small{font-size:.8rem}.card{transition:transform .2s ease,box-shadow .2s ease}.card:hover{transform:translateY(-3px)}.achievement-section .badge{font-size:.75rem;white-space:normal;text-align:left}.skill-tag .badge{font-weight:500;font-size:.9rem;transition:all .2s ease;cursor:default}.skill-tag .badge:hover{transform:translateY(-2px)}.skill-tag .btn-close{opacity:.5}.skill-tag .btn-close:hover{opacity:1}.bg-light.text-dark.border{background-color:#f8f9fa!important;border-color:#dee2e6!important}.card{transition:all .3s cubic-bezier(.25,.8,.25,1)}.card:hover .bg-light{background-color:#e8f5e9!important}.position-fixed .card:hover{transform:none!important}code{background-color:#f8f9fa;padding:2px 6px;border-radius:4px}.list-group-item{transition:all .2s ease-in-out}.list-group-item:hover{background-color:#fcfcfc;transform:translate(5px)}.border-dashed{border-style:dashed!important}.tool-card{transition:all .2s ease-in-out;border-radius:12px}.tool-card:hover{transform:translateY(-5px);border-color:var(--bs-primary)!important}.tool-card:hover .icon-box{background-color:var(--bs-primary-subtle)!important}.tool-card .icon-box{width:60px;height:60px;transition:background-color .2s ease}.border-dashed{border:2px dashed #dee2e6!important}.border-dashed:hover{border-color:var(--bs-primary)!important;background-color:#fff!important}.popup{position:fixed;top:20%;right:20px;width:320px;max-width:calc(100vw - 32px);background:#fff;border-radius:10px;padding:16px}.status-row{display:flex;justify-content:space-between;margin:10px 0}.success{color:#2e7d32;font-weight:700}.error{color:#d32f2f}.pending{color:#f9a825}.section-flag{font-weight:600}button.btn.btn-sm.btn-outline-primary{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:5px!important}button.btn.btn-sm.btn-outline-primary:hover{background-color:#356895;border-color:#356895;color:#fff}button.btn.btn-sm.btn-outline-danger{border:1px solid #dc3545;color:#dc3545;border-radius:5px!important}button.btn.btn-sm.btn-outline-primary.rounded-circle{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:5px!important}button.action-icon-btn{min-width:22px;width:22px;height:22px;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:5px!important;background:transparent!important;border:none!important;line-height:1}button.action-icon-btn.btn-outline-primary{color:#4077ad!important;border-color:#4077ad!important}button.action-icon-btn.btn-outline-danger{color:#dc3545!important}.action-icon-image{width:20px;height:20px;object-fit:contain;display:inline-block}.action-icon-image.edit-icon{filter:brightness(0) saturate(100%) invert(41%) sepia(39%) saturate(774%) hue-rotate(170deg) brightness(91%) contrast(89%)}.action-icon-image.delete-icon{filter:brightness(0) saturate(100%) invert(24%) sepia(79%) saturate(4008%) hue-rotate(344deg) brightness(91%) contrast(90%)}.modal-overlay{position:fixed;inset:0;background:#11182773;display:flex;align-items:center;justify-content:center;z-index:2500;padding:20px}.status-modal-card{width:min(760px,96vw);max-height:85vh;overflow:auto;background:#fff;border-radius:16px;border:1px solid #e5e7eb}.status-modal-header{padding:20px 24px 14px;border-bottom:1px solid #eef2f7}.status-modal-body{padding:12px 20px 20px}.status-modal-footer{padding:12px 20px 20px;border-top:1px solid #eef2f7;display:flex;justify-content:end;align-items:center;gap:12px}.status-modal-row{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px 10px;border-bottom:1px solid #f1f5f9}.status-modal-row:last-child{border-bottom:0}.status-modal-name{font-size:14px;font-weight:600;color:#69707d}.status-modal-state{font-size:.92rem;font-weight:600}.status-modal-state.pending{color:#a16207}.status-modal-state.success{color:#166534}.status-modal-state.partial{color:#b45309}.status-modal-state.error{color:#b91c1c}.confirm-modal-card{width:min(520px,96vw);background:#fff;border-radius:5px;border:1px solid #e5e7eb;padding:24px}.year-experience-select{max-height:150px}@media screen and (max-width: 768px){.res-flex{flex-wrap:wrap!important;justify-content:center!important}.res-flex .fw-normal{width:100%;text-align:center;font-size:14px!important}.d-flex.flex-wrap.gap-2.p-3.bg-white.border.rounded.shadow-sm{justify-content:center}.preview-page-header{margin:20px auto 8px;padding:0 4px}.container{padding-left:4px;padding-right:4px}.preview-title{font-size:16px}.preview-subtitle{font-size:14px}.actions{margin:24px 0 16px}.section-header-title{flex-wrap:wrap}.section-header-title>.section-flag{flex-basis:53%}.section-header-row{align-items:flex-start}.preview-card-gradient{padding:14px 14px 12px}.preview-card-gradient h2{font-size:18px}.popup{width:calc(100vw - 40px);right:16px;top:12%}.card{padding:0}.card-body.p-4,.px-4.py-3{padding:12px!important}.row.g-4,.row.g-3{--bs-gutter-x: .75rem}.d-flex.gap-4{gap:10px!important}.preview-card-gradient>.d-flex.justify-content-between.align-items-start{flex-wrap:wrap;row-gap:8px}.preview-card-gradient>.d-flex.justify-content-between.align-items-start>.badge.bg-primary-subtle{margin-left:auto}}@media screen and (max-width: 575px){.preview-title{font-size:16px}.preview-subtitle{font-size:14px}.section>.d-flex{flex-wrap:wrap;row-gap:8px}.section>.d-flex>.d-flex:last-child{width:100%;justify-content:flex-end}}::ng-deep .bs-datepicker-head{background-color:#4077ad!important}::ng-deep .bs-datepicker-body table td span.selected,.bs-datepicker-body table td.selected span{background-color:#4077ad!important}.profile-avatar-circle{width:58px;height:58px;border-radius:5px;background:#4077ad;display:flex;align-items:center;justify-content:center;font-size:22px;font-weight:700;color:#fff;letter-spacing:1px;flex-shrink:0}.section-header-icon{font-size:20px;line-height:1;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;opacity:.9;filter:invert(47%) sepia(8%) saturate(483%) hue-rotate(176deg) brightness(91%) contrast(87%)}.section-header-title h5.fw-bold{color:#69707d}.text-muted{color:#69707d!important}h6.text-uppercase.fw-bold.text-muted{font-size:14px;color:#69707d!important}.work-accent-item{border-radius:5px!important;transition:background-color .18s ease,box-shadow .18s ease}.work-accent-item:hover{background-color:#f5f8ff!important;box-shadow:0 4px 14px #4077ad17!important}.edu-accent-item{border-radius:5px!important;transition:background-color .18s ease,box-shadow .18s ease}.edu-accent-item:hover{background-color:#f8f8ff!important;box-shadow:0 4px 14px #6366f117!important}.cert-accent-item{border-radius:5px!important;transition:background-color .18s ease}.cert-accent-item:hover{background-color:#f0fdf4!important}.lic-accent-item{border-radius:5px!important;transition:background-color .18s ease}.lic-accent-item:hover{background-color:#fffbeb!important}.field-label-sm{font-size:14px;font-weight:700;letter-spacing:.08em;color:#69707d;margin-bottom:3px;display:block}.item-name-text{color:#69707d}.field-value-sm{font-weight:600;font-size:12px;color:#69707d}.item-title-sm{font-size:14px;color:#69707d!important}.item-meta-line{display:block;font-size:12px;color:#69707d;margin-top:3px}.empty-state-wrap{text-align:center;padding:32px 20px;background:#fafbfc;border:1.5px dashed #d1d5db;border-radius:5px;cursor:pointer;transition:background-color .18s ease,border-color .18s ease}.empty-state-wrap .empty-icon{font-size:2rem;color:#d1d5db;margin-bottom:8px}.empty-state-wrap p{color:#9ca3af;margin:0;font-size:14px}.empty-state-wrap:hover{background:#f0f6ff;border-color:#4077ad}.form-panel{background:#fff;border:1px solid #e2e8f0;border-radius:5px;padding:20px}.form-panel .form-control,.form-panel .form-select{border-color:#d1d5db;border-radius:8px;font-size:12px}.form-panel .form-control:focus,.form-panel .form-select:focus{border-color:#4077ad;box-shadow:0 0 0 3px #4077ad1f}.section-header-bar{display:flex;align-items:center;justify-content:space-between;padding:10px 0 14px;border-bottom:2px solid #f1f5f9;margin-bottom:16px}.preview-card-gradient{background:linear-gradient(135deg,#fff,#eff6ff);border-bottom:1px solid #e2e8f0;padding:20px 24px 16px;border-radius:5px 5px 0 0}.item-icon-circle{width:40px;height:40px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:700;color:#fff;flex-shrink:0}.item-avatar--work{background:linear-gradient(135deg,#4077ad,#2d5a8a)}.item-avatar--edu{background:linear-gradient(135deg,#4077ad,#4338ca)}.provider-layout{display:flex;flex-direction:column}.provider-company-first{order:-1}.section-locked{pointer-events:none;opacity:.45;filter:blur(1.5px);-webkit-user-select:none;user-select:none}.btn.btn-primary{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-primary:hover:not(:disabled),.btn.btn-primary:focus:not(:disabled),.btn.btn-primary:active:not(:disabled){background-color:#356895!important;border-color:#356895!important;color:#fff!important}.btn.btn-success,.btn.btn-outline-success{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-success:hover:not(:disabled),.btn.btn-success:focus:not(:disabled),.btn.btn-success:active:not(:disabled),.btn.btn-outline-success:hover:not(:disabled),.btn.btn-outline-success:focus:not(:disabled),.btn.btn-outline-success:active:not(:disabled){background-color:#336843!important;border-color:#336843!important;color:#fff!important}.btn.btn-outline-secondary.rounded-pill{background-color:#69707d!important;border-color:#69707d!important;color:#fff!important;border-radius:5px!important}.btn.btn-outline-secondary.rounded-pill:hover:not(:disabled),.btn.btn-outline-secondary.rounded-pill:focus:not(:disabled),.btn.btn-outline-secondary.rounded-pill:active:not(:disabled){background-color:#565c66!important;border-color:#565c66!important;color:#fff!important}.preview-back-btn{background-color:#426c85!important;border-color:#426c85!important;color:#fff!important}.preview-dashboard-btn{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-outline-success:hover:not(:disabled),.btn.btn-outline-success:focus:not(:disabled),.btn.btn-outline-success:active:not(:disabled){background-color:transparent!important;border-color:#198754!important;color:#198754!important}.btn.btn-outline-secondary:not(.rounded-pill){background-color:#d4dae6!important;border-color:#d4dae6!important;color:#69707d!important}.btn.btn-outline-secondary:not(.rounded-pill):hover:not(:disabled),.btn.btn-outline-secondary:not(.rounded-pill):focus:not(:disabled),.btn.btn-outline-secondary:not(.rounded-pill):active:not(:disabled){background-color:#c2cbde!important;border-color:#c2cbde!important;color:#69707d!important}.btn.btn-danger{background-color:#b43026!important;border-color:#b43026!important;color:#fff!important}.btn.btn-danger:hover:not(:disabled),.btn.btn-danger:focus:not(:disabled),.btn.btn-danger:active:not(:disabled){background-color:#96271f!important;border-color:#96271f!important;color:#fff!important}.btn.btn-outline-danger.rounded-circle{border-color:#b43026!important;color:#b43026!important;border-radius:5px!important}.btn.btn-outline-danger.rounded-circle:hover:not(:disabled),.btn.btn-outline-danger.rounded-circle:focus:not(:disabled),.btn.btn-outline-danger.rounded-circle:active:not(:disabled){border-color:#96271f!important;color:#b43026!important}.btn.btn-link.text-secondary{background-color:#d4dae6!important;border-color:#d4dae6!important;color:#69707d!important;text-decoration:none!important;border-radius:5px}.btn.btn-link.text-secondary:hover:not(:disabled),.btn.btn-link.text-secondary:focus:not(:disabled){background-color:#c2cbde!important;color:#69707d!important}.btn.btn-link.text-danger{background-color:#b43026!important;border-color:#b43026!important;color:#fff!important;text-decoration:none!important;border-radius:5px}.btn.btn-link.text-danger:hover:not(:disabled),.btn.btn-link.text-danger:focus:not(:disabled){background-color:#96271f!important;color:#fff!important}.btn{border-radius:5px!important;box-shadow:none!important}.badge.bg-warning-subtle.text-warning{background-color:#fff3cd!important;color:#664d03!important;border-color:#ffe69c!important}.badge.bg-success-subtle.text-success{background-color:#4077ad!important;color:#fff!important;border-color:#4077ad!important}.badge.bg-primary-subtle.text-primary{background-color:#e0edf2!important;color:#4077ad!important;border-color:#e0edf2!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ModalModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i7.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i7.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i7.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i7.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i7.EmailValidator, selector: "[email][formControlName],[email][formControl],[email][ngModel]", inputs: ["email"] }, { kind: "directive", type: i7.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i7.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i7.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: NgSelectModule }, { kind: "component", type: i12.NgSelectComponent, selector: "ng-select", inputs: ["bindLabel", "bindValue", "markFirst", "placeholder", "notFoundText", "typeToSearchText", "addTagText", "loadingText", "clearAllText", "appearance", "dropdownPosition", "appendTo", "loading", "closeOnSelect", "hideSelected", "selectOnTab", "openOnEnter", "maxSelectedItems", "groupBy", "groupValue", "bufferAmount", "virtualScroll", "selectableGroup", "selectableGroupAsModel", "searchFn", "trackByFn", "clearOnBackspace", "labelForId", "inputAttrs", "tabIndex", "readonly", "searchWhileComposing", "minTermLength", "editableSearchTerm", "keyDownFn", "typeahead", "multiple", "addTag", "searchable", "clearable", "isOpen", "items", "compareWith", "clearSearchOnAdd", "deselectOnClick"], outputs: ["blur", "focus", "change", "open", "close", "search", "clear", "add", "remove", "scroll", "scrollToEnd"] }, { kind: "ngmodule", type: NgxStarsModule }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "directive", type: i13.BsDatepickerDirective, selector: "[bsDatepicker]", inputs: ["placement", "triggers", "outsideClick", "container", "outsideEsc", "isDisabled", "minDate", "maxDate", "ignoreMinMaxErrors", "minMode", "daysDisabled", "datesDisabled", "datesEnabled", "dateCustomClasses", "dateTooltipTexts", "isOpen", "bsValue", "bsConfig"], outputs: ["onShown", "onHidden", "bsValueChange"], exportAs: ["bsDatepicker"] }, { kind: "directive", type: i13.BsDatepickerInputDirective, selector: "input[bsDatepicker]" }, { kind: "ngmodule", type: TextMaskModule }, { kind: "ngmodule", type: AddressVerifyFieldModule }, { kind: "component", type: AddressVerifyFieldComponent, selector: "im-address-verify-field", inputs: ["placeholder", "options", "maxLength", "inputId", "name", "autocompleteAttr", "inputClass", "invalid", "inputStyle", "initialLat", "initialLng"], outputs: ["addressResolved", "manualEdit"] }] });
|
|
7199
|
+
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: ProfessionService }, { token: UserProfessionService }, { token: UserDocumentService }, { token: UserEducationService }, { token: UserDetailService }, { token: UserExperienceService }, { token: i1$4.TokenService }, { token: i1$4.RoleContextService }, { token: ProvidersService }, { token: FrontEndProvidersService }, { token: i0.ChangeDetectorRef }, { token: LIBRARY_CONFIG }], target: i0.ɵɵFactoryTarget.Component });
|
|
7200
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: PreviewComponent, isStandalone: true, selector: "app-preview", inputs: { providerId: "providerId", isResume: "isResume", resumeModel: "resumeModel", providerName: "providerName", roleData: "roleData", cloudfrontUrl: "cloudfrontUrl", signatureFileId: "signatureFileId", signatureUrl: "signatureUrl" }, outputs: { backToParent: "backToParent" }, viewQueries: [{ propertyName: "companyForm", first: true, predicate: ["companyForm"], descendants: true }], ngImport: i0, template: "<div class=\"preview-page-header\" *ngIf=\"!isResume\">\r\n <div class=\"d-flex align-items-center gap-2 mb-1\">\r\n <h2 class=\"preview-title mb-0\">Review Extracted Information</h2>\r\n </div>\r\n <p class=\"preview-subtitle text-muted\">We\u2019ve automatically extracted details from your uploaded resume. Please review and confirm accuracy before proceeding.</p>\r\n</div>\r\n\r\n\r\n<div [ngClass]=\"isResume ? '' : 'container py-4'\" [class.provider-layout]=\"roleData?.role?.name === 'Provider'\">\r\n\r\n <!-- Provider initial setup: combined company + personal form (shown until both APIs succeed) -->\r\n <div class=\"section mb-5\" *ngIf=\"roleData?.role?.name === 'Provider' && !hasUserDetailData && !isResume\">\r\n <div class=\"d-flex align-items-center gap-2 mb-3 section-header-title\">\r\n <img src=\"/assets/images/icons/building.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Company & Personal Details</h5>\r\n <span class=\"badge border section-flag bg-warning-subtle text-warning\">Required to continue</span>\r\n </div>\r\n <div class=\"card shadow-sm border-0\">\r\n <div class=\"card-header bg-white fw-semibold\">Company Information</div>\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-3\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': (!tempCompanyDetails.companyName?.trim() && companyFormSubmitted) || companyNameError}\"\r\n [(ngModel)]=\"tempCompanyDetails.companyName\" name=\"setupCompanyName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyName?.trim() && companyFormSubmitted\">Company name is required</div>\r\n <div class=\"invalid-feedback\" *ngIf=\"companyNameError\">{{ companyNameError }}</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" maxlength=\"14\" inputmode=\"numeric\"\r\n (input)=\"phoneMask($event, 'company')\" (keypress)=\"allowOnlyNumbers($event)\"\r\n [ngClass]=\"{'is-invalid': companyFormSubmitted && (!tempCompanyDetails.companyPhoneNumber?.trim() || getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10)}\"\r\n [(ngModel)]=\"tempCompanyDetails.companyPhoneNumber\" name=\"setupCompanyPhone\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted\">Company phone is required</div>\r\n <div class=\"invalid-feedback\" *ngIf=\"tempCompanyDetails.companyPhoneNumber?.trim() && getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10 && companyFormSubmitted\">Company phone must be 10 digits</div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Company Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempCompanyDetails.address1\" name=\"setupCompanyAddress\"\r\n [options]=\"options\" inputClass=\"form-control form-control-sm\"\r\n [invalid]=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\"\r\n [initialLat]=\"tempCompanyDetails.latitude\" [initialLng]=\"tempCompanyDetails.longitude\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"\r\n (manualEdit)=\"onCompanyAddressManualEdit()\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\">Address is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.city?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.city\" name=\"setupCompanyCity\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.city?.trim() && companyFormSubmitted\">City is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.state?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.state\" name=\"setupCompanyState\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.state?.trim() && companyFormSubmitted\">State is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.zipcode?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.zipcode\" name=\"setupCompanyZip\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.zipcode?.trim() && companyFormSubmitted\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.country?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.country\" name=\"setupCompanyCountry\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.country?.trim() && companyFormSubmitted\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <input type=\"file\" accept=\".png,.jpg,.jpeg\" class=\"form-control form-control-sm\" (change)=\"uploadCompanyImage($event)\" name=\"setupCompanyLogo\" />\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"tempCompanyLogoUrl\">\r\n <label class=\"small text-muted d-block\">Logo Preview</label>\r\n <img [src]=\"tempCompanyLogoUrl\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-header bg-white fw-semibold border-top\">Personal Information</div>\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-3\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">First Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.firstName?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.firstName\" name=\"setupFirstName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.firstName?.trim() && companyFormSubmitted\">First name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.lastName?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.lastName\" name=\"setupLastName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.lastName?.trim() && companyFormSubmitted\">Last name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Email <span class=\"text-danger\">*</span></label>\r\n <input type=\"email\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.email?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.email\" name=\"setupEmail\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.email?.trim() && companyFormSubmitted\">Email is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Phone Number <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" maxlength=\"14\" inputmode=\"numeric\"\r\n (input)=\"phoneMask($event, 'profile')\" (keypress)=\"allowOnlyNumbers($event)\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.phone?.trim() && companyFormSubmitted}\"\r\n [ngModel]=\"tempProfile?.phone\" name=\"setupPhone\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.phone?.trim() && companyFormSubmitted\">Phone number is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempProfile.address\" name=\"setupAddress\" [options]=\"options\"\r\n inputClass=\"form-control form-control-sm\" [invalid]=\"!tempProfile?.address?.trim() && companyFormSubmitted\"\r\n [initialLat]=\"tempProfile.latitude\" [initialLng]=\"tempProfile.longitude\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"\r\n (manualEdit)=\"onUserAddressManualEdit()\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.address?.trim() && companyFormSubmitted\">Home address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.city?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.city\" name=\"setupUserCity\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.city?.trim() && companyFormSubmitted\">City is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.state?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.state\" name=\"setupUserState\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.state?.trim() && companyFormSubmitted\">State is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.zipCode?.trim() && companyFormSubmitted}\"\r\n [ngModel]=\"tempProfile?.zipCode\" (ngModelChange)=\"tempProfile.zipCode = sanitizeZipCode($event)\"\r\n name=\"setupUserZip\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.zipCode?.trim() && companyFormSubmitted\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.country?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.country\" name=\"setupUserCountry\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.country?.trim() && companyFormSubmitted\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [(ngModel)]=\"tempProfile.jobTitle\" name=\"setupJobTitle\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control form-control-sm\" [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n [ngClass]=\"{'is-invalid': !(tempProfile?.yearsOfExperience > 0) && companyFormSubmitted}\"\r\n name=\"setupYearsOfExp\" min=\"1\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!(tempProfile?.yearsOfExperience > 0) && companyFormSubmitted\">Years of experience is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Profile Picture</label>\r\n <input #setupHeadshotFile type=\"file\" accept=\".png,.jpg,.jpeg\" class=\"d-none\" (change)=\"uploadHeadshotImage($event)\" name=\"setupHeadshotFile\" />\r\n <div class=\"position-relative\">\r\n <input type=\"text\" class=\"form-control form-control-sm pe-5\" [value]=\"headshotFileName\" readonly\r\n placeholder=\"Upload Profile Picture\" (click)=\"setupHeadshotFile.click()\" />\r\n <img *ngIf=\"!isHeadshotLoading\" src=\"assets/images/icons/upload.svg\" alt=\"Upload\" class=\"upload-icon\" style=\"position:absolute;right:12px;top:50%;transform:translateY(-50%);cursor:pointer;width:18px;\" (click)=\"setupHeadshotFile.click()\" />\r\n <div *ngIf=\"isHeadshotLoading\" style=\"position:absolute;right:12px;top:50%;transform:translateY(-50%);\">\r\n <span class=\"spinner-border spinner-border-sm text-primary\"></span>\r\n </div>\r\n </div>\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"headshotPreviewUrl\">\r\n <label class=\"small text-muted d-block\">Preview</label>\r\n <img [src]=\"headshotPreviewUrl\" class=\"img-thumbnail rounded-circle\" style=\"width:64px;height:64px;object-fit:cover;\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-footer d-flex align-items-center justify-content-end gap-2\">\r\n <span *ngIf=\"providerSetupError\" class=\"small text-danger me-auto\">{{ providerSetupError }}</span>\r\n <button class=\"btn btn-success px-5 \"\r\n [disabled]=\"isSavingProviderSetup || !isProviderSetupFormComplete\"\r\n (click)=\"saveProviderSetup()\">\r\n <span *ngIf=\"isSavingProviderSetup\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingProviderSetup ? 'Saving...' : 'Save & Continue' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\" *ngIf=\"roleData?.role?.name !== 'Provider' || hasUserDetailData\">\r\n <div *ngIf=\"details() as data; else loading\">\r\n <div class=\"card shadow-sm border-0 rounded-3 overflow-hidden\" *ngIf=\"!isEditMode()\">\r\n <div class=\"card-body p-0\">\r\n <div class=\"preview-card-gradient\">\r\n <div class=\"d-flex justify-content-between align-items-start mb-4\">\r\n <div class=\"d-flex align-items-start gap-3\">\r\n <div class=\"profile-avatar-circle\" *ngIf=\"!headshotPreviewUrl\">\r\n {{ (data.firstName?.[0] || '') }}{{ (data.lastName?.[0] || '') }}\r\n </div>\r\n <img *ngIf=\"headshotPreviewUrl\" [src]=\"headshotPreviewUrl\"\r\n class=\"rounded-circle\" style=\"width:56px;height:56px;object-fit:cover;\" alt=\"Profile\" />\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h2 class=\"fw-bold mb-1\">{{ data.firstName }} {{ data.lastName }}</h2>\r\n <span *ngIf=\"basicSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n <span class=\"badge border section-flag\"\r\n [ngClass]=\"basicDetailsSaved ? 'bg-success-subtle text-success' : 'bg-warning-subtle text-warning'\">\r\n {{ basicDetailsSaved ? 'Saved' : 'Not saved yet' }}\r\n </span>\r\n </div>\r\n <p class=\"text-muted\">{{ data.jobTitle }} \u2022 {{ data.yearsOfExperience }} Years Exp.</p>\r\n <div *ngIf=\"basicIssues().length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ basicIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <span class=\"badge bg-primary-subtle text-primary border p-2\">Email Verified</span>\r\n </div>\r\n\r\n </div>\r\n <div class=\"px-4 py-3\">\r\n <div class=\"row g-4\">\r\n <div class=\"col-12 border-bottom pb-2\">\r\n <h6 class=\"text-uppercase small fw-bold text-muted\">Summary</h6>\r\n <p class=\"text-secondary small mb-0\">{{ data.summary }}</p>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/envelope.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Email</span>\r\n <span class=\"field-value-sm d-block\">{{ data.email }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/telephone.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Phone</span>\r\n <span class=\"field-value-sm d-block\">{{ data.phone }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/geo-alt.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Location</span>\r\n <span class=\"field-value-sm d-block\">{{ data.address }}, {{ data.city }}, {{ data.state }}, {{ data.zipCode }}, {{ data.country }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer d-flex align-items-center justify-content-between\">\r\n <span *ngIf=\"!basicDetailsSaved\" class=\"small text-warning fw-semibold\">\r\n <img src=\"/assets/images/icons/exclamation-circle.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" /> Click \"Edit\" to review and save your basic info.\r\n </span>\r\n <span *ngIf=\"basicDetailsSaved\" class=\"small text-success fw-semibold\">\r\n <img src=\"/assets/images/icons/check-circle.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" /> Basic details saved.\r\n </span>\r\n <button class=\"btn btn-sm btn-primary px-4 ms-auto\" (click)=\"toggleEdit()\">Edit</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"isEditMode()\">\r\n <div class=\"card-header bg-white fw-bold\">Update Profile</div>\r\n <div class=\"card-body p-4\">\r\n <form class=\"row g-3\" #basicForm=\"ngForm\" novalidate>\r\n <div *ngIf=\"basicIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ basicIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">First Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.firstName\" name=\"fName\"\r\n placeholder=\"First Name\" required #fName=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"fName.invalid && (fName.dirty || fName.touched)\">First name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.lastName\" name=\"lName\"\r\n placeholder=\"Last Name\" required #lName=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"lName.invalid && (lName.dirty || lName.touched)\">Last name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Email <span class=\"text-danger\">*</span></label>\r\n <input type=\"email\" class=\"form-control\" [(ngModel)]=\"tempProfile.email\" name=\"email\" placeholder=\"Email\"\r\n required email #email=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"email.invalid && (email.dirty || email.touched)\">\r\n <span *ngIf=\"email.errors?.['required']\">Email is required</span>\r\n <span *ngIf=\"email.errors?.['email']\">Email format is invalid</span>\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Phone Number <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"tempProfile.phone\" (input)=\"phoneMask($event, 'profile')\"\r\n name=\"phone\" placeholder=\"Phone (10 digits)\" (keypress)=\"allowOnlyNumbers($event)\"\r\n required pattern=\"^\\(\\d{3}\\) \\d{3}-\\d{4}$\" maxlength=\"14\" inputmode=\"numeric\" #phone=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"phone.invalid && (phone.dirty || phone.touched)\">\r\n <span *ngIf=\"phone.errors?.['required']\">Phone number is required</span>\r\n <span *ngIf=\"phone.errors?.['pattern']\">Phone number must be 10 digits</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\"></span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.jobTitle\" name=\"jobTitle\"\r\n placeholder=\"Job Title\" #jobTitle=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"jobTitle.invalid && (jobTitle.dirty || jobTitle.touched)\">Job\r\n title is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngClass]=\"{'is-invalid': !(tempProfile?.yearsOfExperience > 0)}\"\r\n [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n name=\"yearsOfExperience\" placeholder=\"Years of Experience\" required min=\"1\"\r\n #yearsOfExperience=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!(tempProfile?.yearsOfExperience > 0)\">\r\n Years of experience is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempProfile.address\" name=\"address\" [options]=\"options\"\r\n placeholder=\"Home Address\" required #address=\"ngModel\"\r\n [invalid]=\"address.invalid && (address.dirty || address.touched)\"\r\n [initialLat]=\"tempProfile.latitude\" [initialLng]=\"tempProfile.longitude\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"\r\n (manualEdit)=\"onUserAddressManualEdit()\"></im-address-verify-field>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"address.invalid && (address.dirty || address.touched)\">Home\r\n address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.city\" name=\"city\" placeholder=\"City\"\r\n required #city=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"city.invalid && (city.dirty || city.touched)\">City is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.state\" name=\"state\" placeholder=\"State\"\r\n required #state=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"state.invalid && (state.dirty || state.touched)\">State is\r\n required</div>\r\n </div>\r\n\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"tempProfile.zipCode\"\r\n (ngModelChange)=\"tempProfile.zipCode = sanitizeZipCode($event)\" name=\"zipCode\" placeholder=\"Zip Code\"\r\n required pattern=\"^\\d{1,6}$\" maxlength=\"6\" inputmode=\"numeric\" #zipCode=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"zipCode.invalid && (zipCode.dirty || zipCode.touched)\">Zip code\r\n is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"zipCode.errors?.['pattern'] && (zipCode.dirty || zipCode.touched)\">\r\n Zip code must be up to 6 digits\r\n </div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.country\" name=\"country\"\r\n placeholder=\"Country\" required #country=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"country.invalid && (country.dirty || country.touched)\">Country\r\n is required</div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Summary</label>\r\n <textarea class=\"form-control\" rows=\"3\" [(ngModel)]=\"tempProfile.summary\" name=\"sum\"\r\n placeholder=\"Summary\"></textarea>\r\n </div>\r\n\r\n\r\n </form>\r\n </div>\r\n <div class=\"card-footer text-end gap-2 d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancel()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingBasic || !isBasicFormValid\" (click)=\"save()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Saving...' : 'Save Changes' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5 provider-company-first\" *ngIf=\"roleData?.role?.name === 'Provider' && hasUserDetailData && !isResume\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/building.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Company Details</h5>\r\n <span *ngIf=\"companyDetailsSaved\"\r\n class=\"badge border section-flag bg-success-subtle text-success\">\r\n Saved\r\n </span>\r\n <span *ngIf=\"!companyDetailsSaved\"\r\n class=\"badge border section-flag bg-warning-subtle text-warning\">\r\n Not saved yet\r\n </span>\r\n </div>\r\n <button class=\"btn btn-sm btn-primary px-4\" (click)=\"toggleCompanyEdit()\">Edit</button>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"!isCompanyEditMode()\">\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-4\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name</label>\r\n <span class=\"fw-bold small\">{{ companyDetails()?.companyName}}</span>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone</label>\r\n <span class=\"fw-bold small\">{{ companyDetails()?.companyPhoneNumber}}</span>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Company Address</label>\r\n <span class=\"small\">{{ companyDetails()?.address1}}, {{ companyDetails()?.city}}, {{ companyDetails()?.state}}, {{ companyDetails()?.zipcode}}, {{ companyDetails()?.country}}</span>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"companyLogoUrl()\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <img [src]=\"companyLogoUrl()\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"isCompanyEditMode()\">\r\n <div class=\"card-header bg-white fw-bold\">Update Company Details</div>\r\n <div class=\"card-body p-4\">\r\n <form class=\"row g-3\" #companyForm=\"ngForm\" novalidate>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': (!tempCompanyDetails.companyName?.trim() && companyFormSubmitted) || companyNameError }\"\r\n [(ngModel)]=\"tempCompanyDetails.companyName\" name=\"companyName\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyName?.trim() && companyFormSubmitted\">\r\n Company name is required\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"companyNameError\">\r\n {{ companyNameError }}\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone <span class=\"text-danger\">*</span></label>\r\n <input (input)=\"phoneMask($event, 'company')\" type=\"text\" maxlength=\"14\" (keypress)=\"allowOnlyNumbers($event)\" inputmode=\"numeric\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{ 'is-invalid': companyFormSubmitted && (!tempCompanyDetails.companyPhoneNumber?.trim() || getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10) }\"\r\n [(ngModel)]=\"tempCompanyDetails.companyPhoneNumber\" name=\"companyPhoneNumber\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted\">\r\n Company phone is required\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"tempCompanyDetails.companyPhoneNumber?.trim() && getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10 && companyFormSubmitted\">\r\n Company phone must be 10 digits\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempCompanyDetails.address1\" name=\"address1\" [options]=\"options\"\r\n required [invalid]=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\"\r\n [initialLat]=\"tempCompanyDetails.latitude\" [initialLng]=\"tempCompanyDetails.longitude\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"\r\n (manualEdit)=\"onCompanyAddressManualEdit()\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\">\r\n Address is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.city?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.city\" name=\"city\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.city?.trim() && companyFormSubmitted\">\r\n City is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.state?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.state\" name=\"state\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.state?.trim() && companyFormSubmitted\">\r\n State is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.zipcode?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.zipcode\" name=\"zipcode\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.zipcode?.trim() && companyFormSubmitted\">\r\n Zip code is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.country?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.country\" name=\"country\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.country?.trim() && companyFormSubmitted\">\r\n Country is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <input #uploadCompanyFile type=\"file\" accept=\".png,.jpg,.jpeg\" (change)=\"uploadCompanyImage($event)\" class=\"form-control\" />\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"tempCompanyLogoUrl\">\r\n <label class=\"small text-muted d-block\">Logo Preview</label>\r\n <img [src]=\"tempCompanyLogoUrl\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </form>\r\n </div>\r\n <div class=\"card-footer text-end gap-2 d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelCompanyEdit()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCompany\" \r\n (click)=\"saveCompanyDetails()\">\r\n <span *ngIf=\"isSavingCompany\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCompany ? 'Saving...' : 'Save Changes' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div [class.section-locked]=\"roleData?.role?.name === 'Provider' && !hasUserDetailData\">\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/briefcase-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Profession</h5>\r\n <span *ngIf=\"selectedProfessionCount > 0\" class=\"badge border section-flag bg-warning-subtle text-warning\">\r\n {{ selectedProfessionCount }} selected\r\n </span>\r\n </div>\r\n <button type=\"button\" class=\"btn btn-sm btn-primary px-4\"\r\n [disabled]=\"selectedProfessionCount === 0 || isSavingProfessionsTable\"\r\n (click)=\"submitProfessions()\">\r\n <span *ngIf=\"isSavingProfessionsTable\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingProfessionsTable ? 'Saving...' : professionSubmitLabel }}\r\n </button>\r\n </div>\r\n\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Search / Create the Profession(s)</label>\r\n <input type=\"text\" class=\"form-control\" placeholder=\"Search Profession\"\r\n [(ngModel)]=\"professionSearchQry\" name=\"professionSearchQry\"\r\n (keydown.enter)=\"createManualProfessionRow()\" />\r\n </div>\r\n\r\n <div class=\"table-responsive bg-white border rounded shadow-sm\">\r\n <table class=\"table align-middle mb-0 profession-table\">\r\n <thead>\r\n <tr>\r\n <th style=\"width: 36px;\"></th>\r\n <th>Profession Name</th>\r\n <th>Group</th>\r\n <th>Type</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let p of filteredProfessionTypes\">\r\n <tr [class.profession-row-selected]=\"getProfessionSelection(p.id).selected\">\r\n <td>\r\n <input type=\"checkbox\" class=\"form-check-input\" [checked]=\"getProfessionSelection(p.id).selected\"\r\n (change)=\"onProfessionRowCheck(p, $event)\" />\r\n </td>\r\n <td>\r\n {{ p.professionName }}\r\n <span *ngIf=\"isProfessionSaved(p.id)\" class=\"badge border bg-success-subtle text-success ms-1\">Saved</span>\r\n </td>\r\n <td>{{ p.professionGroup || '\u2013' }}</td>\r\n <td>{{ p.residentialCommercial || '\u2013' }}</td>\r\n </tr>\r\n <tr *ngIf=\"getProfessionSelection(p.id).selected\" class=\"profession-row-selected\">\r\n <td></td>\r\n <td colspan=\"3\">\r\n <div class=\"d-flex flex-wrap align-items-start gap-4 py-2\">\r\n <div class=\"flex-shrink-0\" style=\"white-space: nowrap;\">\r\n <label class=\"small text-muted d-block mb-1\">Self Ability Rating</label>\r\n <span *ngFor=\"let s of [1,2,3,4,5]\" class=\"fs-5\" style=\"cursor: pointer;\"\r\n (click)=\"setProfessionRowStars(p, s)\"\r\n [class.text-warning]=\"(getProfessionSelection(p.id).starRating || 0) / 2 >= s\"\r\n [class.text-muted]=\"(getProfessionSelection(p.id).starRating || 0) / 2 < s\">\u2605</span>\r\n </div>\r\n <div class=\"flex-shrink-0\" style=\"white-space: nowrap;\">\r\n <label class=\"small text-muted d-block mb-1\">Experience</label>\r\n <div class=\"d-flex align-items-center gap-1\">\r\n <input type=\"number\" class=\"form-control form-control-sm\" style=\"width: 70px;\" min=\"0\" max=\"30\"\r\n [(ngModel)]=\"getProfessionSelection(p.id).year\" [name]=\"'profYear-' + p.id\" />\r\n <span class=\"small text-muted\">Yrs</span>\r\n </div>\r\n </div>\r\n <div class=\"d-flex flex-column align-items-center flex-shrink-0\" style=\"min-width: 80px; white-space: nowrap;\">\r\n <label class=\"small text-muted d-block mb-1\">Visibility</label>\r\n <input type=\"checkbox\" class=\"profession-visibility-checkbox\" [(ngModel)]=\"getProfessionSelection(p.id).profileVisibility\"\r\n [name]=\"'profVis-' + p.id\" />\r\n </div>\r\n <div class=\"flex-grow-1\" style=\"min-width: 200px;\">\r\n <label class=\"small text-muted d-block mb-1\">Notes</label>\r\n <textarea rows=\"3\" class=\"form-control form-control-sm profession-notes-input\" [(ngModel)]=\"getProfessionSelection(p.id).notes\"\r\n [name]=\"'profNotes-' + p.id\" placeholder=\"Notes\"></textarea>\r\n </div>\r\n </div>\r\n </td>\r\n </tr>\r\n </ng-container>\r\n <tr *ngIf=\"filteredProfessionTypes.length === 0\">\r\n <td colspan=\"4\" class=\"text-center text-muted small py-3\">No professions found.</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/briefcase-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Work Experience</h5>\r\n <span *ngIf=\"experience().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"workSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ workSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"experience().length === 0 || !workSectionHasUnsavedItems() || isSavingWork || isAddingJob() || editingJobIndex() !== null\"\r\n (click)=\"confirmAllWork()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add work experience\" (click)=\"addJob()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"experience().length === 0 && !isAddingJob()\" class=\"empty-state-wrap mb-3\" role=\"button\"\r\n (click)=\"addJob()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/briefcase.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No work experience added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3\">\r\n <div *ngIf=\"isAddingJob() && tempJob()\" class=\"list-group-item p-0 border-0\">\r\n <div class=\"form-panel mb-2\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\" name=\"newJobTitle\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\" name=\"newCompany\" />\r\n </div>\r\n <div class=\"align-items-end col-md-12 d-flex justify-content-end pe-3\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\" name=\"newIsCurrent\" id=\"newIsCurrent\" />\r\n <label class=\"form-check-label\" for=\"newIsCurrent\">Current</label>\r\n </div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.country\"\r\n (ngModelChange)=\"patchTempJob({ country: $event })\" name=\"newCountry\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.state\"\r\n (ngModelChange)=\"patchTempJob({ state: $event })\" name=\"newState\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\" name=\"newCity\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempJob()?.startDate)\"\r\n (bsValueChange)=\"setTempJobMonth('startDate', $event)\" name=\"newStartDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.startDate)\">Start date is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"monthInputToDate(tempJob()?.endDate)\" (bsValueChange)=\"setTempJobMonth('endDate', $event)\"\r\n name=\"newEndDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">End date is\r\n required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isMonthRangeInvalid(tempJob()?.startDate, tempJob()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Responsibilities (one per line)</label>\r\n <textarea rows=\"4\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\" name=\"newResponsibilities\"></textarea>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\" name=\"newWorkAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempJob()?.fileName\">\r\n <span>{{ tempJob()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempJob())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n <div class=\"d-flex justify-content-end gap-2 mt-3\">\r\n <button class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingWork\"\r\n (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : workActionLabel(editingJobIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n\r\n <div *ngFor=\"let job of experience(); let i = index\" class=\"list-group-item p-0 border-0 mb-2\">\r\n\r\n <div class=\"work-accent-item p-3 rounded-3 bg-white border\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div class=\"d-flex align-items-center cursor-pointer flex-grow-1\" (click)=\"toggleJob(i)\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h6 class=\"mb-0 fw-bold item-title-sm\">{{ job.jobTitle }}</h6>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedWorkItem(i) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedWorkItem(i) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ job.company || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ formatMonthYear(job.startDate) }} - {{ job.isCurrent ? 'Present' :\r\n formatMonthYear(job.endDate) }}</span>\r\n <span class=\"item-meta-line\">{{ job.city }}<span *ngIf=\"job.city && job.state\">, </span>{{ job.state }}<ng-container *ngIf=\"!job.city && !job.state\">\u2014</ng-container></span>\r\n <div *ngIf=\"editingJobIndex() !== i && (workIssuesByIndex()[i] || []).length > 0\"\r\n class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (workIssuesByIndex()[i] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center gap-2\">\r\n\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\" (click)=\"startEditJob(i)\"\r\n title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteJob(i);\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n \r\n </div>\r\n </div>\r\n\r\n\r\n\r\n <div class=\"mt-3 p-3 rounded small\" *ngIf=\"expandedIndex() === i\">\r\n <ng-container *ngIf=\"editingJobIndex() !== i; else editJobForm\">\r\n <ul class=\"mb-0\">\r\n <li *ngFor=\"let res of job.responsibilities\">{{ res }}</li>\r\n </ul>\r\n </ng-container>\r\n\r\n <ng-template #editJobForm>\r\n <div *ngIf=\"(workIssuesByIndex()[i] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (workIssuesByIndex()[i] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\" name=\"jobTitle{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.jobTitle)\">Job title is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\" name=\"company{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.company)\">Company name is required</div>\r\n </div>\r\n\r\n <div class=\"align-items-end col-md-12 d-flex justify-content-end pe-3\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\" name=\"isCurrent{{ i }}\" id=\"isCurrent{{ i }}\" />\r\n <label class=\"form-check-label\" for=\"isCurrent{{ i }}\">Current</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.country\"\r\n (ngModelChange)=\"patchTempJob({ country: $event })\" name=\"country{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.state\"\r\n (ngModelChange)=\"patchTempJob({ state: $event })\" name=\"state{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\" name=\"city{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.city)\">City is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempJob()?.startDate)\"\r\n (bsValueChange)=\"setTempJobMonth('startDate', $event)\" name=\"startDate{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.startDate)\">Start date is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"monthInputToDate(tempJob()?.endDate)\" (bsValueChange)=\"setTempJobMonth('endDate', $event)\"\r\n name=\"endDate{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">\r\n End date is required\r\n </div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isMonthRangeInvalid(tempJob()?.startDate, tempJob()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Responsibilities (one per line)</label>\r\n <textarea rows=\"4\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\" name=\"responsibilities{{ i }}\"></textarea>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\" name=\"workAttachment{{ i }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempJob()?.fileName\">\r\n <span>{{ tempJob()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempJob())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n </ng-template>\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-3\" *ngIf=\"editingJobIndex() === i\">\r\n <button class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4 \" [disabled]=\"isSavingWork\"\r\n (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : workActionLabel(editingJobIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/patch-check-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Certifications</h5>\r\n <span *ngIf=\"certs().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"certificationSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ certificationSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"certs().length === 0 || !certificationSectionHasUnsavedItems() || isSavingCertification || isAddingCertification() || editingCertificationIndex() !== null\"\r\n (click)=\"confirmAllCertifications()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add certification\" (click)=\"addCertification()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"certs().length === 0 && !isAddingCertification() && editingCertificationIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addCertification()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/patch-check.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No certifications added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3 border\">\r\n <div *ngIf=\"isAddingCertification() && tempCertification()\" class=\"list-group-item py-3 px-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Profession Type</label>\r\n <ng-select [items]=\"userProfessionOptions\" bindLabel=\"professionName\" bindValue=\"professionId\"\r\n [ngModel]=\"tempCertification()?.professionId\" (change)=\"onCertificationProfessionChange($event)\"\r\n name=\"newCertProfessionType\" placeholder=\"Select or search profession type\" [clearable]=\"true\">\r\n </ng-select>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\" name=\"newCertName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\" name=\"newCertOrg\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\" name=\"newCertState\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certification Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\" name=\"newCertCredentialId\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('issueDate', $event)\" name=\"newCertIssueDate\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('expiryDate', $event)\" name=\"newCertExpiryDate\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempCertification()?.issueDate || null, tempCertification()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\" name=\"newCertAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempCertification()?.fileName\">\r\n <span>{{ tempCertification()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempCertification())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\"\r\n [disabled]=\"isSavingCertification\"\r\n (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : certificationActionLabel(editingCertificationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let cert of certs(); let ci = index\" class=\"list-group-item py-3 cert-accent-item\">\r\n <ng-container *ngIf=\"editingCertificationIndex() !== ci; else editCert\">\r\n <div class=\"d-flex justify-content-between align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <div class=\"fw-semibold item-title-sm\">{{ cert.name }}</div>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedCertificationItem(ci) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedCertificationItem(ci) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ cert.issuingOrganization || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.credentialId || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.issueDate ? formatMonthYear(cert.issueDate) : '\u2014' }} - {{ cert.expiryDate ? formatMonthYear(cert.expiryDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.state || '\u2014' }}</span>\r\n <div *ngIf=\"(certIssuesByIndex()[ci] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (certIssuesByIndex()[ci] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditCertification(ci)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteCertification(ci)\" title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #editCert>\r\n <div *ngIf=\"(certIssuesByIndex()[ci] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (certIssuesByIndex()[ci] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Profession Type</label>\r\n <ng-select [items]=\"userProfessionOptions\" bindLabel=\"professionName\" bindValue=\"professionId\"\r\n [ngModel]=\"tempCertification()?.professionId\" (change)=\"onCertificationProfessionChange($event)\"\r\n name=\"certProfessionType{{ ci }}\" placeholder=\"Select or search profession type\" [clearable]=\"true\">\r\n </ng-select>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\" name=\"certName{{ ci }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\"\r\n name=\"certOrg{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\" name=\"certState{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certification Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\"\r\n name=\"certCredentialId{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('issueDate', $event)\" name=\"certIssue{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('expiryDate', $event)\" name=\"certExpiry{{ ci }}\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempCertification()?.issueDate || null, tempCertification()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\" name=\"certAttachment{{ ci }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempCertification()?.fileName\">\r\n <span>{{ tempCertification()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempCertification())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\"\r\n (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : certificationActionLabel(editingCertificationIndex()) }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/card-checklist-warning.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Licenses</h5>\r\n <span *ngIf=\"licenses().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"licenseSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ licenseSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"licenses().length === 0 || !licenseSectionHasUnsavedItems() || isSavingLicense || isAddingLicense() || editingLicenseIndex() !== null\"\r\n (click)=\"confirmAllLicenses()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add license\" (click)=\"addLicense()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"licenses().length === 0 && !isAddingLicense() && editingLicenseIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addLicense()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/card-checklist.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No licenses added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3 border\">\r\n <div *ngIf=\"isAddingLicense() && tempLicense()\" class=\"list-group-item py-3 px-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\" name=\"newLicName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempLicense()?.name)\">License name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\" name=\"newLicAuthority\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\" name=\"newLicNumber\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\" name=\"newLicState\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('issueDate', $event)\" name=\"newLicIssueDate\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('expiryDate', $event)\" name=\"newLicExpiryDate\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempLicense()?.issueDate || null, tempLicense()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">License File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\" name=\"newLicenseAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempLicense()?.fileName\">\r\n <span>{{ tempLicense()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempLicense())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelEditLicense()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingLicense\"\r\n (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : licenseActionLabel(editingLicenseIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let lic of licenses(); let li = index\" class=\"list-group-item py-3 lic-accent-item\">\r\n <ng-container *ngIf=\"editingLicenseIndex() !== li; else editLic\">\r\n <div class=\"d-flex justify-content-between align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <div class=\"fw-semibold item-title-sm\">{{ lic.name }}</div>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedLicenseItem(li) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedLicenseItem(li) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ lic.issuingAuthority || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.licenseNumber || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.issueDate ? formatMonthYear(lic.issueDate) : '\u2014' }} - {{ lic.expiryDate ? formatMonthYear(lic.expiryDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.state || '\u2014' }}</span>\r\n <div *ngIf=\"(licenseIssuesByIndex()[li] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (licenseIssuesByIndex()[li] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditLicense(li)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteLicense(li)\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #editLic>\r\n <div *ngIf=\"(licenseIssuesByIndex()[li] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (licenseIssuesByIndex()[li] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\" name=\"licName{{ li }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempLicense()?.name)\">License name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\" name=\"licAuthority{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\" name=\"licNumber{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\" name=\"licState{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('issueDate', $event)\" name=\"licIssue{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('expiryDate', $event)\" name=\"licExpiry{{ li }}\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempLicense()?.issueDate || null, tempLicense()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">License File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\" name=\"licenseAttachment{{ li }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempLicense()?.fileName\">\r\n <span>{{ tempLicense()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempLicense())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditLicense()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingLicense\"\r\n (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : licenseActionLabel(editingLicenseIndex()) }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/tools.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Tools</h5>\r\n <span *ngIf=\"tools().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"toolsSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ toolsSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"tools().length === 0 || !toolsSectionHasUnsavedItems() || isSavingTool || isToolEditorOpen()\" (click)=\"confirmAllTools()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add tool\" (click)=\"addTool()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex flex-wrap gap-2 p-3 bg-white border rounded shadow-sm\">\r\n <div *ngFor=\"let tool of tools(); let ti = index\" class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\"\r\n class=\"btn btn-light border res-flex d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openToolEditor(ti)\" title=\"Edit\">\r\n <span class=\"fw-normal item-name-text\">{{ tool }}</span>\r\n <span class=\"badge border ms-1\"\r\n [ngClass]=\"hasUnsavedToolItem(ti) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedToolItem(ti) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n <span *ngIf=\"(toolIssuesByIndex()[ti] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\">\r\n Missing info\r\n </span>\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Delete tool\" (click)=\"deleteTool(ti)\">\r\n <span class=\"fw-bold\">\u00D7</span>\r\n </button>\r\n </div>\r\n\r\n <span *ngIf=\"tools().length === 0\" class=\"text-muted small\">No tools added.</span>\r\n </div>\r\n\r\n <div *ngIf=\"isToolEditorOpen()\" class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 9999999;\" (click)=\"closeToolEditor()\">\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\"\r\n (click)=\"$event.stopPropagation()\">\r\n <div class=\"card shadow border-0 w-100\" style=\"max-width: 900px;\">\r\n <div class=\"card-header bg-white d-flex align-items-center gap-3\">\r\n <button type=\"button\" class=\"btn btn-link p-0 text-decoration-none\" (click)=\"closeToolEditor()\">\r\n <img src=\"/assets/images/icons/arrow-left-blue.svg\" width=\"20\" height=\"20\" alt=\"\" />\r\n </button>\r\n <div class=\"fw-bold\">{{ isAddingTool() ? 'Add Tool' : ('Edit ' + (toolForm()?.name || '') + ' Tool') }}\r\n </div>\r\n </div>\r\n <div class=\"card-body p-4\">\r\n <div *ngIf=\"toolFormIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ toolFormIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"row g-3\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Profession Type</label>\r\n <ng-select [items]=\"userProfessionOptions\" bindLabel=\"professionName\" bindValue=\"professionId\"\r\n [ngModel]=\"toolForm()?.professionId\" (change)=\"onToolProfessionChange($event)\"\r\n name=\"toolProfessionType\" placeholder=\"Select or search profession type\" [clearable]=\"true\">\r\n </ng-select>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Tool Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"toolForm()?.name\"\r\n (ngModelChange)=\"patchToolForm({ name: $event })\" name=\"toolName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(toolForm()?.name)\">Tool name is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span\r\n class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempToolStars(s)\" [attr.aria-label]=\"'Set rating ' + s\">\r\n <span [class]=\"(toolForm()?.stars || 0) >= s ? 'text-warning fs-5' : 'text-muted fs-5'\">\r\n {{ (toolForm()?.stars || 0) >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ toolForm()?.stars || 0 }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"(toolForm()?.stars || 0) <= 0\">Star rating is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngModel]=\"toolForm()?.year\"\r\n (ngModelChange)=\"patchToolForm({ year: $event === '' ? null : +$event })\" name=\"toolYear\" min=\"1\"\r\n max=\"30\" placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"toolForm()?.year === null || toolForm()?.year === undefined\">\r\n Years of experience is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4 text-center\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-checks form-switch mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"toolForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchToolForm({ profileVisibility: $event })\" name=\"toolVisible\" id=\"toolVisible\"\r\n style=\"width: 55px;height: 25px;margin-left: -57px;\" />\r\n <label class=\"form-check-label ps-2 pt-1\" for=\"toolVisible\">Visible</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Comment</label>\r\n <textarea rows=\"4\" class=\"form-control\" [ngModel]=\"toolForm()?.notes\"\r\n (ngModelChange)=\"patchToolForm({ notes: $event })\" name=\"toolNotes\"\r\n placeholder=\"Enter additional details (optional)\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-white d-flex justify-content-end gap-2\">\r\n <button *ngIf=\"!isAddingTool() && editingToolIndex() !== null\" type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\" (click)=\"deleteTool(editingToolIndex()!)\">\r\n Delete\r\n </button>\r\n <button type=\"button\" class=\"btn btn-link text-secondary\" (click)=\"closeToolEditor()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary px-4\" [disabled]=\"isSavingTool\" (click)=\"saveToolEditor()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Saving...' : toolActionLabel(editingToolIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row g-4 mb-5\">\r\n <div class=\"col-md-12\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/stars.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Skills</h5>\r\n <span *ngIf=\"skills().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"skillsSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ skillsSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"skills().length === 0 || !skillsSectionHasUnsavedItems() || isSavingSkill || isSkillEditorOpen()\" (click)=\"confirmAllSkills()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add skill\" (click)=\"addSkill()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex flex-wrap gap-2 p-3 bg-white border rounded shadow-sm\">\r\n <div *ngFor=\"let skill of skills(); let si = index\" class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\"\r\n class=\"btn btn-light border res-flex d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openSkillEditor(si)\" title=\"Edit\">\r\n <span class=\"fw-normal item-name-text\">{{ skill }}</span>\r\n <span class=\"badge border ms-1\"\r\n [ngClass]=\"hasUnsavedSkillItem(si) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedSkillItem(si) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n <span *ngIf=\"(skillIssuesByIndex()[si] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\">\r\n Missing info\r\n </span>\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Delete skill\"\r\n (click)=\"deleteSkill(si); $event.stopPropagation()\">\r\n <span class=\"fw-bold\">\u00D7</span>\r\n </button>\r\n </div>\r\n\r\n <span *ngIf=\"skills().length === 0\" class=\"text-muted small\">No skills added.</span>\r\n </div>\r\n <div *ngIf=\"isSkillEditorOpen()\" class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 9999999;\" (click)=\"closeSkillEditor()\">\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\"\r\n (click)=\"$event.stopPropagation()\">\r\n <div class=\"card shadow border-0 w-100\" style=\"max-width: 900px;\">\r\n <div class=\"card-header bg-white d-flex align-items-center gap-3\">\r\n <button type=\"button\" class=\"btn btn-link p-0 text-decoration-none\" (click)=\"closeSkillEditor()\">\r\n <img src=\"/assets/images/icons/arrow-left-blue.svg\" width=\"20\" height=\"20\" alt=\"\" />\r\n </button>\r\n <div class=\"fw-bold\">{{ isAddingSkill() ? 'Add Skill' : ('Edit ' + (skillForm()?.name || '') + ' Skill')\r\n }}</div>\r\n </div>\r\n <div class=\"card-body p-4\">\r\n <div *ngIf=\"skillFormIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ skillFormIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"row g-3\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Profession Type</label>\r\n <ng-select [items]=\"userProfessionOptions\" bindLabel=\"professionName\" bindValue=\"professionId\"\r\n [ngModel]=\"skillForm()?.professionId\" (change)=\"onSkillProfessionChange($event)\"\r\n name=\"skillProfessionType\" placeholder=\"Select or search profession type\" [clearable]=\"true\">\r\n </ng-select>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Skills Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"skillForm()?.name\"\r\n (ngModelChange)=\"patchSkillForm({ name: $event })\" name=\"skillName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(skillForm()?.name)\">Skillset name is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span\r\n class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempSkillStars(s)\" [attr.aria-label]=\"'Set rating ' + s\">\r\n <span [class]=\"(skillForm()?.stars || 0) >= s ? 'text-warning fs-5' : 'text-muted fs-5'\">\r\n {{ (skillForm()?.stars || 0) >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ skillForm()?.stars || 0 }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"(skillForm()?.stars || 0) <= 0\">Star rating is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngModel]=\"skillForm()?.year\"\r\n (ngModelChange)=\"patchSkillForm({ year: $event === '' ? null : +$event })\" name=\"skillYear\" min=\"1\"\r\n max=\"30\" placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"skillForm()?.year === null || skillForm()?.year === undefined\">Years of experience is\r\n required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4 text-center\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-checks form-switch mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"skillForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchSkillForm({ profileVisibility: $event })\" name=\"skillVisible\"\r\n id=\"skillVisible\" style=\"width: 55px;height: 25px;margin-left: -57px;\" />\r\n <label class=\"form-check-label ps-2 pt-1\" for=\"skillVisible\">Visible</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Comment</label>\r\n <textarea rows=\"4\" class=\"form-control\" [ngModel]=\"skillForm()?.notes\"\r\n (ngModelChange)=\"patchSkillForm({ notes: $event })\" name=\"skillNotes\"\r\n placeholder=\"Enter additional details (optional)\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-white d-flex justify-content-end gap-2\">\r\n <button *ngIf=\"!isAddingSkill() && editingSkillIndex() !== null\" type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\" (click)=\"deleteSkill(editingSkillIndex()!)\">\r\n Delete\r\n </button>\r\n <button type=\"button\" class=\"btn btn-link text-secondary\" (click)=\"closeSkillEditor()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary px-4\" [disabled]=\"isSavingSkill\" (click)=\"saveSkillEditor()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Saving...' : skillActionLabel(editingSkillIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row g-4 mb-5\">\r\n <div class=\"col-md-12\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/mortarboard-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Education</h5>\r\n <span *ngIf=\"educationList().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"educationSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ educationSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"educationList().length === 0 || !educationSectionHasUnsavedItems() || isSavingEducation || isAddingEducation() || editingEducationIndex() !== null\"\r\n (click)=\"confirmAllEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add education\" (click)=\"addEducation()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"educationList().length === 0 && !isAddingEducation() && editingEducationIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addEducation()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/mortarboard.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No education added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div *ngIf=\"isAddingEducation() && tempEducation()\" class=\"mb-2\">\r\n <div class=\"form-panel\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\" name=\"newEduDegree\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Institution <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\" name=\"newEduInstitution\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree / Course Type <span class=\"text-danger\">*</span></label>\r\n <ng-select class=\"ng-select-sm\" [items]=\"educationDegreeTypeOptions\" [clearable]=\"false\"\r\n placeholder=\"Select degree / course type\" [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\" name=\"newEduDegreeType\">\r\n </ng-select>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.country\"\r\n (ngModelChange)=\"patchTempEducation({ country: $event })\" name=\"newEduCountry\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.state\"\r\n (ngModelChange)=\"patchTempEducation({ state: $event })\" name=\"newEduState\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\" name=\"newEduCity\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.startDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('startDate', $event)\" name=\"newEduStartDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.startDate)\">Start date is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.endDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('endDate', $event)\" name=\"newEduEndDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Education File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onEducationFileSelected($event)\" name=\"newEducationAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempEducation()?.fileName\">\r\n <span>{{ tempEducation()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempEducation())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingEducation\"\r\n (click)=\"saveEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Uploading...' : educationActionLabel(editingEducationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let edu of educationList(); let ei = index\" class=\"edu-accent-item p-3 bg-white border rounded-3 shadow-sm mb-2\">\r\n <div class=\"d-flex justify-content-between align-items-start\">\r\n <div class=\"d-flex align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h6 class=\"fw-bold mb-0 item-title-sm\">{{ edu.degree }}</h6>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedEducationItem(ei) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedEducationItem(ei) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ edu.institution || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.degreeType || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.startDate ? formatMonthYear(edu.startDate) : '\u2014' }} - {{ edu.endDate ? formatMonthYear(edu.endDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.city }}<span *ngIf=\"edu.city && edu.state\">, </span>{{ edu.state }}<ng-container *ngIf=\"!edu.city && !edu.state\">\u2014</ng-container></span>\r\n <div *ngIf=\"(educationIssuesByIndex()[ei] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (educationIssuesByIndex()[ei] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\" *ngIf=\"editingEducationIndex() !== ei\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditEducation(ei)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteEducation(ei)\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"editingEducationIndex() === ei\" class=\"mt-3\">\r\n <div *ngIf=\"(educationIssuesByIndex()[ei] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (educationIssuesByIndex()[ei] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\" name=\"eduDegree{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Institution <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\" name=\"eduInstitution{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.institution)\">Institution name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree / Course Type <span class=\"text-danger\">*</span></label>\r\n <ng-select class=\"ng-select-sm\" [items]=\"educationDegreeTypeOptions\" [clearable]=\"false\"\r\n placeholder=\"Select degree / course type\" [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\" name=\"eduDegreeType{{ ei }}\">\r\n </ng-select>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.country\"\r\n (ngModelChange)=\"patchTempEducation({ country: $event })\" name=\"eduCountry{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.state\"\r\n (ngModelChange)=\"patchTempEducation({ state: $event })\" name=\"eduState{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\" name=\"eduCity{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.startDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('startDate', $event)\" name=\"eduStartDate{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.startDate)\">Start date is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.endDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('endDate', $event)\" name=\"eduEndDate{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Education File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onEducationFileSelected($event)\" name=\"educationAttachment{{ ei }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempEducation()?.fileName\">\r\n <span>{{ tempEducation()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempEducation())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingEducation\" (click)=\"saveEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Uploading...' : educationActionLabel(editingEducationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n </div>\r\n <div class=\"d-flex gap-3 justify-content-center mt-5 pt-2\" *ngIf=\"!isResume\">\r\n <button class=\"btn btn-outline-secondary preview-back-btn px-5 h-auto\" style=\"border-radius: 5px !important;\" (click)=\"onBackClick()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"me-1\" style=\"vertical-align:-0.1em\">\r\n <path d=\"M11 3 5 8l6 5\" />\r\n </svg> Back\r\n </button>\r\n <button class=\"btn btn-primary preview-dashboard-btn px-5 h-auto\" style=\"border-radius: 5px !important;\" [disabled]=\"!canConfirmAndContinue() || isSavingBasic\"\r\n (click)=\"onGoToDashboardClick()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Saving...' : 'Go to Dashboard' }}\r\n <img *ngIf=\"!isSavingBasic\" src=\"/assets/images/icons/arrow-right-white.svg\" width=\"14\" height=\"14\" class=\"ms-1\" style=\"vertical-align:-0.1em\" alt=\"\" />\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<ng-template #loading>\r\n <div class=\"text-center p-5\">\r\n <div class=\"spinner-border text-primary\"></div>\r\n <p class=\"text-muted mt-2\">Loading data...</p>\r\n </div>\r\n</ng-template>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBulkSkillConfirm\">\r\n <div class=\"confirm-modal-card\" style=\"max-width: 480px;\">\r\n <h4 class=\"mb-1\">Set Rating for All Skills</h4>\r\n <p class=\"text-muted small mb-4\">Enter a star rating and years of experience (and optionally a profession type) to apply to all skills that are missing these values.</p>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Profession Type</label>\r\n <ng-select [items]=\"userProfessionOptions\" bindLabel=\"professionName\" bindValue=\"professionId\"\r\n [ngModel]=\"bulkSkillProfessionId\" (change)=\"onBulkSkillProfessionChange($event)\"\r\n name=\"bulkSkillProfessionType\" placeholder=\"Select or search profession type\" [clearable]=\"true\">\r\n </ng-select>\r\n </div>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"bulkSkillStars = s\">\r\n <span [class]=\"bulkSkillStars >= s ? 'text-warning fs-4' : 'text-muted fs-4'\">\r\n {{ bulkSkillStars >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ bulkSkillStars }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkSkillStars <= 0\">Star rating is required</div>\r\n </div>\r\n <div class=\"mb-4\">\r\n <label class=\"small text-muted d-block mb-1\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [(ngModel)]=\"bulkSkillYear\" min=\"1\" max=\"30\"\r\n placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkSkillYear === null || bulkSkillYear === undefined\">Years of experience is required</div>\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"cancelBulkSkillConfirm()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\"\r\n [disabled]=\"isSavingSkill || bulkSkillStars <= 0 || bulkSkillYear === null\"\r\n (click)=\"applyBulkSkillConfirm()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Saving...' : 'Apply to All & Save' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBulkToolConfirm\">\r\n <div class=\"confirm-modal-card\" style=\"max-width: 480px;\">\r\n <h4 class=\"mb-1\">Set Rating for All Tools</h4>\r\n <p class=\"text-muted small mb-4\">Enter a star rating and years of experience (and optionally a profession type) to apply to all tools that are missing these values.</p>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Profession Type</label>\r\n <ng-select [items]=\"userProfessionOptions\" bindLabel=\"professionName\" bindValue=\"professionId\"\r\n [ngModel]=\"bulkToolProfessionId\" (change)=\"onBulkToolProfessionChange($event)\"\r\n name=\"bulkToolProfessionType\" placeholder=\"Select or search profession type\" [clearable]=\"true\">\r\n </ng-select>\r\n </div>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"bulkToolStars = s\">\r\n <span [class]=\"bulkToolStars >= s ? 'text-warning fs-4' : 'text-muted fs-4'\">\r\n {{ bulkToolStars >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ bulkToolStars }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkToolStars <= 0\">Star rating is required</div>\r\n </div>\r\n <div class=\"mb-4\">\r\n <label class=\"small text-muted d-block mb-1\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [(ngModel)]=\"bulkToolYear\" min=\"1\" max=\"30\"\r\n placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkToolYear === null || bulkToolYear === undefined\">Years of experience is required</div>\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"cancelBulkToolConfirm()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\"\r\n [disabled]=\"isSavingTool || bulkToolStars <= 0 || bulkToolYear === null\"\r\n (click)=\"applyBulkToolConfirm()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Saving...' : 'Apply to All & Save' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBackConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Leave this page?</h4>\r\n <p class=\"text-muted mb-4\">If you go back, only saved data will be retained.</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"stayOnPreview()\">Stay</button>\r\n <button type=\"button\" class=\"btn btn-danger h-auto\" (click)=\"proceedBack()\">Proceed Back</button>\r\n </div>\r\n </div>\r\n\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showDashboardConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Finish Setup and Continue</h4>\r\n <p class=\"text-muted mb-4\">Save your information and go to your dashboard</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" [disabled]=\"isSavingBasic\"\r\n (click)=\"cancelDashboardRedirect()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingBasic\" (click)=\"goToDashboard()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Proceeding...' : 'Proceed' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{color:#69707d}.res-flex:hover,.res-flex:focus,.res-flex:active{transform:none!important;box-shadow:none!important}.profession-row-selected{background-color:#f2f4fa!important}.profession-row-selected>td{background-color:#f2f4fa!important}.profession-visibility-checkbox{all:revert;width:16px!important;height:16px!important;min-width:16px!important;max-width:16px!important;margin:0!important;padding:0!important;position:static!important;float:none!important;vertical-align:middle!important;background-image:none!important;transform:none!important}.profession-table{font-size:14px;color:#69707d}.profession-table th{font-size:13px;font-weight:600;color:#69707d;text-transform:uppercase;letter-spacing:.03em}.profession-table td{font-size:14px;color:#69707d}.profession-table label.small{font-size:12px;color:#69707d}.profession-notes-input{min-height:76px;resize:vertical}.container{max-width:900px;margin:30px auto;font-family:Arial,sans-serif;color:#69707d}.preview-page-header{max-width:900px;margin:50px auto 10px;padding:0 12px}.preview-title{font-size:18px;font-weight:700;color:#69707d;margin:0}.preview-subtitle{margin-top:7px;font-size:14px;color:#69707d}.preview-card-gradient h2,.section h5.fw-bold{font-size:18px}.section{margin-bottom:25px}.section-title{font-weight:600;display:block;margin-bottom:8px}.section-title .sub{font-weight:400;color:#777;font-size:13px}.dropdown-box{border:1px solid #ddd;border-radius:8px;padding:12px 15px;display:flex;justify-content:space-between;align-items:center}.icons{display:flex;gap:10px}.icon{cursor:pointer;font-size:14px;color:#777}.card{border:1px solid #ddd;border-radius:5px;padding:20px;background:#fff}.category{border-bottom:1px solid #eee;padding:15px 0}.category:last-child{border-bottom:none}.category-header{display:flex;justify-content:space-between;font-weight:600;margin-bottom:10px}.tags{display:flex;flex-wrap:wrap;gap:10px}.tag{background:#f2f4f7;padding:6px 12px;border-radius:6px;font-size:13px}.footer{text-align:center;margin-top:15px;color:#777;cursor:pointer}.actions{display:flex;justify-content:space-between;margin:50px 0 27px}.text-secondary{white-space:pre-line;font-size:12px;color:#69707d}.extra-small{font-size:.8rem}.card{transition:transform .2s ease,box-shadow .2s ease}.card:hover{transform:translateY(-3px)}.achievement-section .badge{font-size:.75rem;white-space:normal;text-align:left}.skill-tag .badge{font-weight:500;font-size:.9rem;transition:all .2s ease;cursor:default}.skill-tag .badge:hover{transform:translateY(-2px)}.skill-tag .btn-close{opacity:.5}.skill-tag .btn-close:hover{opacity:1}.bg-light.text-dark.border{background-color:#f8f9fa!important;border-color:#dee2e6!important}.card{transition:all .3s cubic-bezier(.25,.8,.25,1)}.card:hover .bg-light{background-color:#e8f5e9!important}.position-fixed .card:hover{transform:none!important}code{background-color:#f8f9fa;padding:2px 6px;border-radius:4px}.list-group-item{transition:all .2s ease-in-out}.list-group-item:hover{background-color:#fcfcfc;transform:translate(5px)}.border-dashed{border-style:dashed!important}.tool-card{transition:all .2s ease-in-out;border-radius:12px}.tool-card:hover{transform:translateY(-5px);border-color:var(--bs-primary)!important}.tool-card:hover .icon-box{background-color:var(--bs-primary-subtle)!important}.tool-card .icon-box{width:60px;height:60px;transition:background-color .2s ease}.border-dashed{border:2px dashed #dee2e6!important}.border-dashed:hover{border-color:var(--bs-primary)!important;background-color:#fff!important}.popup{position:fixed;top:20%;right:20px;width:320px;max-width:calc(100vw - 32px);background:#fff;border-radius:10px;padding:16px}.status-row{display:flex;justify-content:space-between;margin:10px 0}.success{color:#2e7d32;font-weight:700}.error{color:#d32f2f}.pending{color:#f9a825}.section-flag{font-weight:600}button.btn.btn-sm.btn-outline-primary{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:5px!important}button.btn.btn-sm.btn-outline-primary:hover{background-color:#356895;border-color:#356895;color:#fff}button.btn.btn-sm.btn-outline-danger{border:1px solid #dc3545;color:#dc3545;border-radius:5px!important}button.btn.btn-sm.btn-outline-primary.rounded-circle{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:5px!important}button.action-icon-btn{min-width:22px;width:22px;height:22px;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:5px!important;background:transparent!important;border:none!important;line-height:1}button.action-icon-btn.btn-outline-primary{color:#4077ad!important;border-color:#4077ad!important}button.action-icon-btn.btn-outline-danger{color:#dc3545!important}.action-icon-image{width:20px;height:20px;object-fit:contain;display:inline-block}.action-icon-image.edit-icon{filter:brightness(0) saturate(100%) invert(41%) sepia(39%) saturate(774%) hue-rotate(170deg) brightness(91%) contrast(89%)}.action-icon-image.delete-icon{filter:brightness(0) saturate(100%) invert(24%) sepia(79%) saturate(4008%) hue-rotate(344deg) brightness(91%) contrast(90%)}.modal-overlay{position:fixed;inset:0;background:#11182773;display:flex;align-items:center;justify-content:center;z-index:2500;padding:20px}.status-modal-card{width:min(760px,96vw);max-height:85vh;overflow:auto;background:#fff;border-radius:16px;border:1px solid #e5e7eb}.status-modal-header{padding:20px 24px 14px;border-bottom:1px solid #eef2f7}.status-modal-body{padding:12px 20px 20px}.status-modal-footer{padding:12px 20px 20px;border-top:1px solid #eef2f7;display:flex;justify-content:end;align-items:center;gap:12px}.status-modal-row{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px 10px;border-bottom:1px solid #f1f5f9}.status-modal-row:last-child{border-bottom:0}.status-modal-name{font-size:14px;font-weight:600;color:#69707d}.status-modal-state{font-size:.92rem;font-weight:600}.status-modal-state.pending{color:#a16207}.status-modal-state.success{color:#166534}.status-modal-state.partial{color:#b45309}.status-modal-state.error{color:#b91c1c}.confirm-modal-card{width:min(520px,96vw);background:#fff;border-radius:5px;border:1px solid #e5e7eb;padding:24px}.year-experience-select{max-height:150px}@media screen and (max-width: 768px){.res-flex{flex-wrap:wrap!important;justify-content:center!important}.res-flex .fw-normal{width:100%;text-align:center;font-size:14px!important}.d-flex.flex-wrap.gap-2.p-3.bg-white.border.rounded.shadow-sm{justify-content:center}.preview-page-header{margin:20px auto 8px;padding:0 4px}.container{padding-left:4px;padding-right:4px}.preview-title{font-size:16px}.preview-subtitle{font-size:14px}.actions{margin:24px 0 16px}.section-header-title{flex-wrap:wrap}.section-header-title>.section-flag{flex-basis:53%}.section-header-row{align-items:flex-start}.preview-card-gradient{padding:14px 14px 12px}.preview-card-gradient h2{font-size:18px}.popup{width:calc(100vw - 40px);right:16px;top:12%}.card{padding:0}.card-body.p-4,.px-4.py-3{padding:12px!important}.row.g-4,.row.g-3{--bs-gutter-x: .75rem}.d-flex.gap-4{gap:10px!important}.preview-card-gradient>.d-flex.justify-content-between.align-items-start{flex-wrap:wrap;row-gap:8px}.preview-card-gradient>.d-flex.justify-content-between.align-items-start>.badge.bg-primary-subtle{margin-left:auto}}@media screen and (max-width: 575px){.preview-title{font-size:16px}.preview-subtitle{font-size:14px}.section>.d-flex{flex-wrap:wrap;row-gap:8px}.section>.d-flex>.d-flex:last-child{width:100%;justify-content:flex-end}}::ng-deep .bs-datepicker-head{background-color:#4077ad!important}::ng-deep .bs-datepicker-body table td span.selected,.bs-datepicker-body table td.selected span{background-color:#4077ad!important}.profile-avatar-circle{width:58px;height:58px;border-radius:5px;background:#4077ad;display:flex;align-items:center;justify-content:center;font-size:22px;font-weight:700;color:#fff;letter-spacing:1px;flex-shrink:0}.section-header-icon{font-size:20px;line-height:1;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;opacity:.9;filter:invert(47%) sepia(8%) saturate(483%) hue-rotate(176deg) brightness(91%) contrast(87%)}.section-header-title h5.fw-bold{color:#69707d}.text-muted{color:#69707d!important}h6.text-uppercase.fw-bold.text-muted{font-size:14px;color:#69707d!important}.work-accent-item{border-radius:5px!important;transition:background-color .18s ease,box-shadow .18s ease}.work-accent-item:hover{background-color:#f5f8ff!important;box-shadow:0 4px 14px #4077ad17!important}.edu-accent-item{border-radius:5px!important;transition:background-color .18s ease,box-shadow .18s ease}.edu-accent-item:hover{background-color:#f8f8ff!important;box-shadow:0 4px 14px #6366f117!important}.cert-accent-item{border-radius:5px!important;transition:background-color .18s ease}.cert-accent-item:hover{background-color:#f0fdf4!important}.lic-accent-item{border-radius:5px!important;transition:background-color .18s ease}.lic-accent-item:hover{background-color:#fffbeb!important}.field-label-sm{font-size:14px;font-weight:700;letter-spacing:.08em;color:#69707d;margin-bottom:3px;display:block}.item-name-text{color:#69707d}.field-value-sm{font-weight:600;font-size:12px;color:#69707d}.item-title-sm{font-size:14px;color:#69707d!important}.item-meta-line{display:block;font-size:12px;color:#69707d;margin-top:3px}.empty-state-wrap{text-align:center;padding:32px 20px;background:#fafbfc;border:1.5px dashed #d1d5db;border-radius:5px;cursor:pointer;transition:background-color .18s ease,border-color .18s ease}.empty-state-wrap .empty-icon{font-size:2rem;color:#d1d5db;margin-bottom:8px}.empty-state-wrap p{color:#9ca3af;margin:0;font-size:14px}.empty-state-wrap:hover{background:#f0f6ff;border-color:#4077ad}.form-panel{background:#fff;border:1px solid #e2e8f0;border-radius:5px;padding:20px}.form-panel .form-control,.form-panel .form-select{border-color:#d1d5db;border-radius:8px;font-size:12px}.form-panel .form-control:focus,.form-panel .form-select:focus{border-color:#4077ad;box-shadow:0 0 0 3px #4077ad1f}.section-header-bar{display:flex;align-items:center;justify-content:space-between;padding:10px 0 14px;border-bottom:2px solid #f1f5f9;margin-bottom:16px}.preview-card-gradient{background:linear-gradient(135deg,#fff,#eff6ff);border-bottom:1px solid #e2e8f0;padding:20px 24px 16px;border-radius:5px 5px 0 0}.item-icon-circle{width:40px;height:40px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:700;color:#fff;flex-shrink:0}.item-avatar--work{background:linear-gradient(135deg,#4077ad,#2d5a8a)}.item-avatar--edu{background:linear-gradient(135deg,#4077ad,#4338ca)}.provider-layout{display:flex;flex-direction:column}.provider-company-first{order:-1}.section-locked{pointer-events:none;opacity:.45;filter:blur(1.5px);-webkit-user-select:none;user-select:none}.btn.btn-primary{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-primary:hover:not(:disabled),.btn.btn-primary:focus:not(:disabled),.btn.btn-primary:active:not(:disabled){background-color:#356895!important;border-color:#356895!important;color:#fff!important}.btn.btn-success,.btn.btn-outline-success{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-success:hover:not(:disabled),.btn.btn-success:focus:not(:disabled),.btn.btn-success:active:not(:disabled),.btn.btn-outline-success:hover:not(:disabled),.btn.btn-outline-success:focus:not(:disabled),.btn.btn-outline-success:active:not(:disabled){background-color:#336843!important;border-color:#336843!important;color:#fff!important}.btn.btn-outline-secondary.rounded-pill{background-color:#69707d!important;border-color:#69707d!important;color:#fff!important;border-radius:5px!important}.btn.btn-outline-secondary.rounded-pill:hover:not(:disabled),.btn.btn-outline-secondary.rounded-pill:focus:not(:disabled),.btn.btn-outline-secondary.rounded-pill:active:not(:disabled){background-color:#565c66!important;border-color:#565c66!important;color:#fff!important}.preview-back-btn{background-color:#426c85!important;border-color:#426c85!important;color:#fff!important}.preview-dashboard-btn{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-outline-success:hover:not(:disabled),.btn.btn-outline-success:focus:not(:disabled),.btn.btn-outline-success:active:not(:disabled){background-color:transparent!important;border-color:#198754!important;color:#198754!important}.btn.btn-outline-secondary:not(.rounded-pill){background-color:#d4dae6!important;border-color:#d4dae6!important;color:#69707d!important}.btn.btn-outline-secondary:not(.rounded-pill):hover:not(:disabled),.btn.btn-outline-secondary:not(.rounded-pill):focus:not(:disabled),.btn.btn-outline-secondary:not(.rounded-pill):active:not(:disabled){background-color:#c2cbde!important;border-color:#c2cbde!important;color:#69707d!important}.btn.btn-danger{background-color:#b43026!important;border-color:#b43026!important;color:#fff!important}.btn.btn-danger:hover:not(:disabled),.btn.btn-danger:focus:not(:disabled),.btn.btn-danger:active:not(:disabled){background-color:#96271f!important;border-color:#96271f!important;color:#fff!important}.btn.btn-outline-danger.rounded-circle{border-color:#b43026!important;color:#b43026!important;border-radius:5px!important}.btn.btn-outline-danger.rounded-circle:hover:not(:disabled),.btn.btn-outline-danger.rounded-circle:focus:not(:disabled),.btn.btn-outline-danger.rounded-circle:active:not(:disabled){border-color:#96271f!important;color:#b43026!important}.btn.btn-link.text-secondary{background-color:#d4dae6!important;border-color:#d4dae6!important;color:#69707d!important;text-decoration:none!important;border-radius:5px}.btn.btn-link.text-secondary:hover:not(:disabled),.btn.btn-link.text-secondary:focus:not(:disabled){background-color:#c2cbde!important;color:#69707d!important}.btn.btn-link.text-danger{background-color:#b43026!important;border-color:#b43026!important;color:#fff!important;text-decoration:none!important;border-radius:5px}.btn.btn-link.text-danger:hover:not(:disabled),.btn.btn-link.text-danger:focus:not(:disabled){background-color:#96271f!important;color:#fff!important}.btn{border-radius:5px!important;box-shadow:none!important}.badge.bg-warning-subtle.text-warning{background-color:#fff3cd!important;color:#664d03!important;border-color:#ffe69c!important}.badge.bg-success-subtle.text-success{background-color:#4077ad!important;color:#fff!important;border-color:#4077ad!important}.badge.bg-primary-subtle.text-primary{background-color:#e0edf2!important;color:#4077ad!important;border-color:#e0edf2!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ModalModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i7.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i7.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i7.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i7.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i7.EmailValidator, selector: "[email][formControlName],[email][formControl],[email][ngModel]", inputs: ["email"] }, { kind: "directive", type: i7.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i7.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i7.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: NgSelectModule }, { kind: "component", type: i12.NgSelectComponent, selector: "ng-select", inputs: ["bindLabel", "bindValue", "markFirst", "placeholder", "notFoundText", "typeToSearchText", "addTagText", "loadingText", "clearAllText", "appearance", "dropdownPosition", "appendTo", "loading", "closeOnSelect", "hideSelected", "selectOnTab", "openOnEnter", "maxSelectedItems", "groupBy", "groupValue", "bufferAmount", "virtualScroll", "selectableGroup", "selectableGroupAsModel", "searchFn", "trackByFn", "clearOnBackspace", "labelForId", "inputAttrs", "tabIndex", "readonly", "searchWhileComposing", "minTermLength", "editableSearchTerm", "keyDownFn", "typeahead", "multiple", "addTag", "searchable", "clearable", "isOpen", "items", "compareWith", "clearSearchOnAdd", "deselectOnClick"], outputs: ["blur", "focus", "change", "open", "close", "search", "clear", "add", "remove", "scroll", "scrollToEnd"] }, { kind: "ngmodule", type: NgxStarsModule }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "directive", type: i13.BsDatepickerDirective, selector: "[bsDatepicker]", inputs: ["placement", "triggers", "outsideClick", "container", "outsideEsc", "isDisabled", "minDate", "maxDate", "ignoreMinMaxErrors", "minMode", "daysDisabled", "datesDisabled", "datesEnabled", "dateCustomClasses", "dateTooltipTexts", "isOpen", "bsValue", "bsConfig"], outputs: ["onShown", "onHidden", "bsValueChange"], exportAs: ["bsDatepicker"] }, { kind: "directive", type: i13.BsDatepickerInputDirective, selector: "input[bsDatepicker]" }, { kind: "ngmodule", type: TextMaskModule }, { kind: "ngmodule", type: AddressVerifyFieldModule }, { kind: "component", type: AddressVerifyFieldComponent, selector: "im-address-verify-field", inputs: ["placeholder", "options", "maxLength", "inputId", "name", "autocompleteAttr", "inputClass", "invalid", "inputStyle", "initialLat", "initialLng"], outputs: ["addressResolved", "manualEdit"] }] });
|
|
6541
7201
|
}
|
|
6542
7202
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PreviewComponent, decorators: [{
|
|
6543
7203
|
type: Component,
|
|
@@ -6545,8 +7205,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6545
7205
|
CommonModule, ModalModule, FormsModule, ReactiveFormsModule,
|
|
6546
7206
|
NgSelectModule, NgxStarsModule, BsDatepickerModule, TextMaskModule,
|
|
6547
7207
|
AddressVerifyFieldModule
|
|
6548
|
-
], template: "<div class=\"preview-page-header\" *ngIf=\"!isResume\">\r\n <div class=\"d-flex align-items-center gap-2 mb-1\">\r\n <h2 class=\"preview-title mb-0\">Review Extracted Information</h2>\r\n </div>\r\n <p class=\"preview-subtitle text-muted\">We\u2019ve automatically extracted details from your uploaded resume. Please review and confirm accuracy before proceeding.</p>\r\n</div>\r\n\r\n\r\n<div [ngClass]=\"isResume ? '' : 'container py-4'\" [class.provider-layout]=\"roleData?.role?.name === 'Provider'\">\r\n\r\n <!-- Provider initial setup: combined company + personal form (shown until both APIs succeed) -->\r\n <div class=\"section mb-5\" *ngIf=\"roleData?.role?.name === 'Provider' && !hasUserDetailData && !isResume\">\r\n <div class=\"d-flex align-items-center gap-2 mb-3 section-header-title\">\r\n <img src=\"/assets/images/icons/building.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Company & Personal Details</h5>\r\n <span class=\"badge border section-flag bg-warning-subtle text-warning\">Required to continue</span>\r\n </div>\r\n <div class=\"card shadow-sm border-0\">\r\n <div class=\"card-header bg-white fw-semibold\">Company Information</div>\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-3\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': (!tempCompanyDetails.companyName?.trim() && companyFormSubmitted) || companyNameError}\"\r\n [(ngModel)]=\"tempCompanyDetails.companyName\" name=\"setupCompanyName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyName?.trim() && companyFormSubmitted\">Company name is required</div>\r\n <div class=\"invalid-feedback\" *ngIf=\"companyNameError\">{{ companyNameError }}</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" maxlength=\"14\" inputmode=\"numeric\"\r\n (input)=\"phoneMask($event, 'company')\" (keypress)=\"allowOnlyNumbers($event)\"\r\n [ngClass]=\"{'is-invalid': companyFormSubmitted && (!tempCompanyDetails.companyPhoneNumber?.trim() || getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10)}\"\r\n [(ngModel)]=\"tempCompanyDetails.companyPhoneNumber\" name=\"setupCompanyPhone\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted\">Company phone is required</div>\r\n <div class=\"invalid-feedback\" *ngIf=\"tempCompanyDetails.companyPhoneNumber?.trim() && getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10 && companyFormSubmitted\">Company phone must be 10 digits</div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Company Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempCompanyDetails.address1\" name=\"setupCompanyAddress\"\r\n [options]=\"options\" inputClass=\"form-control form-control-sm\"\r\n [invalid]=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\"\r\n [initialLat]=\"tempCompanyDetails.latitude\" [initialLng]=\"tempCompanyDetails.longitude\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"\r\n (manualEdit)=\"onCompanyAddressManualEdit()\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\">Address is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.city?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.city\" name=\"setupCompanyCity\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.city?.trim() && companyFormSubmitted\">City is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.state?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.state\" name=\"setupCompanyState\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.state?.trim() && companyFormSubmitted\">State is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.zipcode?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.zipcode\" name=\"setupCompanyZip\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.zipcode?.trim() && companyFormSubmitted\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.country?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.country\" name=\"setupCompanyCountry\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.country?.trim() && companyFormSubmitted\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <input type=\"file\" accept=\".png,.jpg,.jpeg\" class=\"form-control form-control-sm\" (change)=\"uploadCompanyImage($event)\" name=\"setupCompanyLogo\" />\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"tempCompanyLogoUrl\">\r\n <label class=\"small text-muted d-block\">Logo Preview</label>\r\n <img [src]=\"tempCompanyLogoUrl\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-header bg-white fw-semibold border-top\">Personal Information</div>\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-3\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">First Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.firstName?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.firstName\" name=\"setupFirstName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.firstName?.trim() && companyFormSubmitted\">First name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.lastName?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.lastName\" name=\"setupLastName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.lastName?.trim() && companyFormSubmitted\">Last name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Email <span class=\"text-danger\">*</span></label>\r\n <input type=\"email\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.email?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.email\" name=\"setupEmail\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.email?.trim() && companyFormSubmitted\">Email is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Phone Number <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" maxlength=\"14\" inputmode=\"numeric\"\r\n (input)=\"phoneMask($event, 'profile')\" (keypress)=\"allowOnlyNumbers($event)\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.phone?.trim() && companyFormSubmitted}\"\r\n [ngModel]=\"tempProfile?.phone\" name=\"setupPhone\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.phone?.trim() && companyFormSubmitted\">Phone number is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempProfile.address\" name=\"setupAddress\" [options]=\"options\"\r\n inputClass=\"form-control form-control-sm\" [invalid]=\"!tempProfile?.address?.trim() && companyFormSubmitted\"\r\n [initialLat]=\"tempProfile.latitude\" [initialLng]=\"tempProfile.longitude\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"\r\n (manualEdit)=\"onUserAddressManualEdit()\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.address?.trim() && companyFormSubmitted\">Home address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.city?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.city\" name=\"setupUserCity\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.city?.trim() && companyFormSubmitted\">City is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.state?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.state\" name=\"setupUserState\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.state?.trim() && companyFormSubmitted\">State is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.zipCode?.trim() && companyFormSubmitted}\"\r\n [ngModel]=\"tempProfile?.zipCode\" (ngModelChange)=\"tempProfile.zipCode = sanitizeZipCode($event)\"\r\n name=\"setupUserZip\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.zipCode?.trim() && companyFormSubmitted\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.country?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.country\" name=\"setupUserCountry\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.country?.trim() && companyFormSubmitted\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [(ngModel)]=\"tempProfile.jobTitle\" name=\"setupJobTitle\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control form-control-sm\" [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n [ngClass]=\"{'is-invalid': !(tempProfile?.yearsOfExperience > 0) && companyFormSubmitted}\"\r\n name=\"setupYearsOfExp\" min=\"1\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!(tempProfile?.yearsOfExperience > 0) && companyFormSubmitted\">Years of experience is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Profile Picture</label>\r\n <input #setupHeadshotFile type=\"file\" accept=\".png,.jpg,.jpeg\" class=\"d-none\" (change)=\"uploadHeadshotImage($event)\" name=\"setupHeadshotFile\" />\r\n <div class=\"position-relative\">\r\n <input type=\"text\" class=\"form-control form-control-sm pe-5\" [value]=\"headshotFileName\" readonly\r\n placeholder=\"Upload Profile Picture\" (click)=\"setupHeadshotFile.click()\" />\r\n <img *ngIf=\"!isHeadshotLoading\" src=\"assets/images/icons/upload.svg\" alt=\"Upload\" class=\"upload-icon\" style=\"position:absolute;right:12px;top:50%;transform:translateY(-50%);cursor:pointer;width:18px;\" (click)=\"setupHeadshotFile.click()\" />\r\n <div *ngIf=\"isHeadshotLoading\" style=\"position:absolute;right:12px;top:50%;transform:translateY(-50%);\">\r\n <span class=\"spinner-border spinner-border-sm text-primary\"></span>\r\n </div>\r\n </div>\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"headshotPreviewUrl\">\r\n <label class=\"small text-muted d-block\">Preview</label>\r\n <img [src]=\"headshotPreviewUrl\" class=\"img-thumbnail rounded-circle\" style=\"width:64px;height:64px;object-fit:cover;\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-footer d-flex align-items-center justify-content-end gap-2\">\r\n <span *ngIf=\"providerSetupError\" class=\"small text-danger me-auto\">{{ providerSetupError }}</span>\r\n <button class=\"btn btn-success px-5 \"\r\n [disabled]=\"isSavingProviderSetup || !isProviderSetupFormComplete\"\r\n (click)=\"saveProviderSetup()\">\r\n <span *ngIf=\"isSavingProviderSetup\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingProviderSetup ? 'Saving...' : 'Save & Continue' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\" *ngIf=\"roleData?.role?.name !== 'Provider' || hasUserDetailData\">\r\n <div *ngIf=\"details() as data; else loading\">\r\n <div class=\"card shadow-sm border-0 rounded-3 overflow-hidden\" *ngIf=\"!isEditMode()\">\r\n <div class=\"card-body p-0\">\r\n <div class=\"preview-card-gradient\">\r\n <div class=\"d-flex justify-content-between align-items-start mb-4\">\r\n <div class=\"d-flex align-items-start gap-3\">\r\n <div class=\"profile-avatar-circle\" *ngIf=\"!headshotPreviewUrl\">\r\n {{ (data.firstName?.[0] || '') }}{{ (data.lastName?.[0] || '') }}\r\n </div>\r\n <img *ngIf=\"headshotPreviewUrl\" [src]=\"headshotPreviewUrl\"\r\n class=\"rounded-circle\" style=\"width:56px;height:56px;object-fit:cover;\" alt=\"Profile\" />\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h2 class=\"fw-bold mb-1\">{{ data.firstName }} {{ data.lastName }}</h2>\r\n <span *ngIf=\"basicSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n <span class=\"badge border section-flag\"\r\n [ngClass]=\"basicDetailsSaved ? 'bg-success-subtle text-success' : 'bg-warning-subtle text-warning'\">\r\n {{ basicDetailsSaved ? 'Saved' : 'Not saved yet' }}\r\n </span>\r\n </div>\r\n <p class=\"text-muted\">{{ data.jobTitle }} \u2022 {{ data.yearsOfExperience }} Years Exp.</p>\r\n <div *ngIf=\"basicIssues().length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ basicIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <span class=\"badge bg-primary-subtle text-primary border p-2\">Email Verified</span>\r\n </div>\r\n\r\n </div>\r\n <div class=\"px-4 py-3\">\r\n <div class=\"row g-4\">\r\n <div class=\"col-12 border-bottom pb-2\">\r\n <h6 class=\"text-uppercase small fw-bold text-muted\">Summary</h6>\r\n <p class=\"text-secondary small mb-0\">{{ data.summary }}</p>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/envelope.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Email</span>\r\n <span class=\"field-value-sm d-block\">{{ data.email }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/telephone.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Phone</span>\r\n <span class=\"field-value-sm d-block\">{{ data.phone }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/geo-alt.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Location</span>\r\n <span class=\"field-value-sm d-block\">{{ data.address }}, {{ data.city }}, {{ data.state }}, {{ data.zipCode }}, {{ data.country }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer d-flex align-items-center justify-content-between\">\r\n <span *ngIf=\"!basicDetailsSaved\" class=\"small text-warning fw-semibold\">\r\n <img src=\"/assets/images/icons/exclamation-circle.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" /> Click \"Edit\" to review and save your basic info.\r\n </span>\r\n <span *ngIf=\"basicDetailsSaved\" class=\"small text-success fw-semibold\">\r\n <img src=\"/assets/images/icons/check-circle.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" /> Basic details saved.\r\n </span>\r\n <button class=\"btn btn-sm btn-primary px-4 ms-auto\" (click)=\"toggleEdit()\">Edit</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"isEditMode()\">\r\n <div class=\"card-header bg-white fw-bold\">Update Profile</div>\r\n <div class=\"card-body p-4\">\r\n <form class=\"row g-3\" #basicForm=\"ngForm\" novalidate>\r\n <div *ngIf=\"basicIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ basicIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">First Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.firstName\" name=\"fName\"\r\n placeholder=\"First Name\" required #fName=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"fName.invalid && (fName.dirty || fName.touched)\">First name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.lastName\" name=\"lName\"\r\n placeholder=\"Last Name\" required #lName=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"lName.invalid && (lName.dirty || lName.touched)\">Last name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Email <span class=\"text-danger\">*</span></label>\r\n <input type=\"email\" class=\"form-control\" [(ngModel)]=\"tempProfile.email\" name=\"email\" placeholder=\"Email\"\r\n required email #email=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"email.invalid && (email.dirty || email.touched)\">\r\n <span *ngIf=\"email.errors?.['required']\">Email is required</span>\r\n <span *ngIf=\"email.errors?.['email']\">Email format is invalid</span>\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Phone Number <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"tempProfile.phone\" (input)=\"phoneMask($event, 'profile')\"\r\n name=\"phone\" placeholder=\"Phone (10 digits)\" (keypress)=\"allowOnlyNumbers($event)\"\r\n required pattern=\"^\\(\\d{3}\\) \\d{3}-\\d{4}$\" maxlength=\"14\" inputmode=\"numeric\" #phone=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"phone.invalid && (phone.dirty || phone.touched)\">\r\n <span *ngIf=\"phone.errors?.['required']\">Phone number is required</span>\r\n <span *ngIf=\"phone.errors?.['pattern']\">Phone number must be 10 digits</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\"></span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.jobTitle\" name=\"jobTitle\"\r\n placeholder=\"Job Title\" #jobTitle=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"jobTitle.invalid && (jobTitle.dirty || jobTitle.touched)\">Job\r\n title is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngClass]=\"{'is-invalid': !(tempProfile?.yearsOfExperience > 0)}\"\r\n [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n name=\"yearsOfExperience\" placeholder=\"Years of Experience\" required min=\"1\"\r\n #yearsOfExperience=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!(tempProfile?.yearsOfExperience > 0)\">\r\n Years of experience is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempProfile.address\" name=\"address\" [options]=\"options\"\r\n placeholder=\"Home Address\" required #address=\"ngModel\"\r\n [invalid]=\"address.invalid && (address.dirty || address.touched)\"\r\n [initialLat]=\"tempProfile.latitude\" [initialLng]=\"tempProfile.longitude\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"\r\n (manualEdit)=\"onUserAddressManualEdit()\"></im-address-verify-field>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"address.invalid && (address.dirty || address.touched)\">Home\r\n address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.city\" name=\"city\" placeholder=\"City\"\r\n required #city=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"city.invalid && (city.dirty || city.touched)\">City is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.state\" name=\"state\" placeholder=\"State\"\r\n required #state=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"state.invalid && (state.dirty || state.touched)\">State is\r\n required</div>\r\n </div>\r\n\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"tempProfile.zipCode\"\r\n (ngModelChange)=\"tempProfile.zipCode = sanitizeZipCode($event)\" name=\"zipCode\" placeholder=\"Zip Code\"\r\n required pattern=\"^\\d{1,6}$\" maxlength=\"6\" inputmode=\"numeric\" #zipCode=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"zipCode.invalid && (zipCode.dirty || zipCode.touched)\">Zip code\r\n is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"zipCode.errors?.['pattern'] && (zipCode.dirty || zipCode.touched)\">\r\n Zip code must be up to 6 digits\r\n </div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.country\" name=\"country\"\r\n placeholder=\"Country\" required #country=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"country.invalid && (country.dirty || country.touched)\">Country\r\n is required</div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Summary</label>\r\n <textarea class=\"form-control\" rows=\"3\" [(ngModel)]=\"tempProfile.summary\" name=\"sum\"\r\n placeholder=\"Summary\"></textarea>\r\n </div>\r\n\r\n\r\n </form>\r\n </div>\r\n <div class=\"card-footer text-end gap-2 d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancel()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingBasic || !isBasicFormValid\" (click)=\"save()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Saving...' : 'Save Changes' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5 provider-company-first\" *ngIf=\"roleData?.role?.name === 'Provider' && hasUserDetailData && !isResume\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/building.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Company Details</h5>\r\n <span *ngIf=\"companyDetailsSaved\"\r\n class=\"badge border section-flag bg-success-subtle text-success\">\r\n Saved\r\n </span>\r\n <span *ngIf=\"!companyDetailsSaved\"\r\n class=\"badge border section-flag bg-warning-subtle text-warning\">\r\n Not saved yet\r\n </span>\r\n </div>\r\n <button class=\"btn btn-sm btn-primary px-4\" (click)=\"toggleCompanyEdit()\">Edit</button>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"!isCompanyEditMode()\">\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-4\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name</label>\r\n <span class=\"fw-bold small\">{{ companyDetails()?.companyName}}</span>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone</label>\r\n <span class=\"fw-bold small\">{{ companyDetails()?.companyPhoneNumber}}</span>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Company Address</label>\r\n <span class=\"small\">{{ companyDetails()?.address1}}, {{ companyDetails()?.city}}, {{ companyDetails()?.state}}, {{ companyDetails()?.zipcode}}, {{ companyDetails()?.country}}</span>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"companyLogoUrl()\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <img [src]=\"companyLogoUrl()\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"isCompanyEditMode()\">\r\n <div class=\"card-header bg-white fw-bold\">Update Company Details</div>\r\n <div class=\"card-body p-4\">\r\n <form class=\"row g-3\" #companyForm=\"ngForm\" novalidate>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': (!tempCompanyDetails.companyName?.trim() && companyFormSubmitted) || companyNameError }\"\r\n [(ngModel)]=\"tempCompanyDetails.companyName\" name=\"companyName\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyName?.trim() && companyFormSubmitted\">\r\n Company name is required\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"companyNameError\">\r\n {{ companyNameError }}\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone <span class=\"text-danger\">*</span></label>\r\n <input (input)=\"phoneMask($event, 'company')\" type=\"text\" maxlength=\"14\" (keypress)=\"allowOnlyNumbers($event)\" inputmode=\"numeric\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{ 'is-invalid': companyFormSubmitted && (!tempCompanyDetails.companyPhoneNumber?.trim() || getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10) }\"\r\n [(ngModel)]=\"tempCompanyDetails.companyPhoneNumber\" name=\"companyPhoneNumber\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted\">\r\n Company phone is required\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"tempCompanyDetails.companyPhoneNumber?.trim() && getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10 && companyFormSubmitted\">\r\n Company phone must be 10 digits\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempCompanyDetails.address1\" name=\"address1\" [options]=\"options\"\r\n required [invalid]=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\"\r\n [initialLat]=\"tempCompanyDetails.latitude\" [initialLng]=\"tempCompanyDetails.longitude\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"\r\n (manualEdit)=\"onCompanyAddressManualEdit()\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\">\r\n Address is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.city?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.city\" name=\"city\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.city?.trim() && companyFormSubmitted\">\r\n City is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.state?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.state\" name=\"state\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.state?.trim() && companyFormSubmitted\">\r\n State is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.zipcode?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.zipcode\" name=\"zipcode\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.zipcode?.trim() && companyFormSubmitted\">\r\n Zip code is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.country?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.country\" name=\"country\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.country?.trim() && companyFormSubmitted\">\r\n Country is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <input #uploadCompanyFile type=\"file\" accept=\".png,.jpg,.jpeg\" (change)=\"uploadCompanyImage($event)\" class=\"form-control\" />\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"tempCompanyLogoUrl\">\r\n <label class=\"small text-muted d-block\">Logo Preview</label>\r\n <img [src]=\"tempCompanyLogoUrl\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </form>\r\n </div>\r\n <div class=\"card-footer text-end gap-2 d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelCompanyEdit()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCompany\" \r\n (click)=\"saveCompanyDetails()\">\r\n <span *ngIf=\"isSavingCompany\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCompany ? 'Saving...' : 'Save Changes' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div [class.section-locked]=\"roleData?.role?.name === 'Provider' && !hasUserDetailData\">\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/briefcase-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Work Experience</h5>\r\n <span *ngIf=\"experience().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"workSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ workSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"experience().length === 0 || !workSectionHasUnsavedItems() || isSavingWork || isAddingJob() || editingJobIndex() !== null\"\r\n (click)=\"confirmAllWork()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add work experience\" (click)=\"addJob()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"experience().length === 0 && !isAddingJob()\" class=\"empty-state-wrap mb-3\" role=\"button\"\r\n (click)=\"addJob()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/briefcase.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No work experience added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3\">\r\n <div *ngIf=\"isAddingJob() && tempJob()\" class=\"list-group-item p-0 border-0\">\r\n <div class=\"form-panel mb-2\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\" name=\"newJobTitle\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\" name=\"newCompany\" />\r\n </div>\r\n <div class=\"align-items-end col-md-12 d-flex justify-content-end pe-3\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\" name=\"newIsCurrent\" id=\"newIsCurrent\" />\r\n <label class=\"form-check-label\" for=\"newIsCurrent\">Current</label>\r\n </div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.country\"\r\n (ngModelChange)=\"patchTempJob({ country: $event })\" name=\"newCountry\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.state\"\r\n (ngModelChange)=\"patchTempJob({ state: $event })\" name=\"newState\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\" name=\"newCity\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempJob()?.startDate)\"\r\n (bsValueChange)=\"setTempJobMonth('startDate', $event)\" name=\"newStartDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.startDate)\">Start date is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"monthInputToDate(tempJob()?.endDate)\" (bsValueChange)=\"setTempJobMonth('endDate', $event)\"\r\n name=\"newEndDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">End date is\r\n required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isMonthRangeInvalid(tempJob()?.startDate, tempJob()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Responsibilities (one per line)</label>\r\n <textarea rows=\"4\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\" name=\"newResponsibilities\"></textarea>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\" name=\"newWorkAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempJob()?.fileName\">\r\n <span>{{ tempJob()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempJob())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n <div class=\"d-flex justify-content-end gap-2 mt-3\">\r\n <button class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingWork\"\r\n (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : workActionLabel(editingJobIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n\r\n <div *ngFor=\"let job of experience(); let i = index\" class=\"list-group-item p-0 border-0 mb-2\">\r\n\r\n <div class=\"work-accent-item p-3 rounded-3 bg-white border\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div class=\"d-flex align-items-center cursor-pointer flex-grow-1\" (click)=\"toggleJob(i)\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h6 class=\"mb-0 fw-bold item-title-sm\">{{ job.jobTitle }}</h6>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedWorkItem(i) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedWorkItem(i) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ job.company || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ formatMonthYear(job.startDate) }} - {{ job.isCurrent ? 'Present' :\r\n formatMonthYear(job.endDate) }}</span>\r\n <span class=\"item-meta-line\">{{ job.city }}<span *ngIf=\"job.city && job.state\">, </span>{{ job.state }}<ng-container *ngIf=\"!job.city && !job.state\">\u2014</ng-container></span>\r\n <div *ngIf=\"editingJobIndex() !== i && (workIssuesByIndex()[i] || []).length > 0\"\r\n class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (workIssuesByIndex()[i] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center gap-2\">\r\n\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\" (click)=\"startEditJob(i)\"\r\n title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteJob(i);\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n \r\n </div>\r\n </div>\r\n\r\n\r\n\r\n <div class=\"mt-3 p-3 rounded small\" *ngIf=\"expandedIndex() === i\">\r\n <ng-container *ngIf=\"editingJobIndex() !== i; else editJobForm\">\r\n <ul class=\"mb-0\">\r\n <li *ngFor=\"let res of job.responsibilities\">{{ res }}</li>\r\n </ul>\r\n </ng-container>\r\n\r\n <ng-template #editJobForm>\r\n <div *ngIf=\"(workIssuesByIndex()[i] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (workIssuesByIndex()[i] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\" name=\"jobTitle{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.jobTitle)\">Job title is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\" name=\"company{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.company)\">Company name is required</div>\r\n </div>\r\n\r\n <div class=\"align-items-end col-md-12 d-flex justify-content-end pe-3\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\" name=\"isCurrent{{ i }}\" id=\"isCurrent{{ i }}\" />\r\n <label class=\"form-check-label\" for=\"isCurrent{{ i }}\">Current</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.country\"\r\n (ngModelChange)=\"patchTempJob({ country: $event })\" name=\"country{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.state\"\r\n (ngModelChange)=\"patchTempJob({ state: $event })\" name=\"state{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\" name=\"city{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.city)\">City is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempJob()?.startDate)\"\r\n (bsValueChange)=\"setTempJobMonth('startDate', $event)\" name=\"startDate{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.startDate)\">Start date is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"monthInputToDate(tempJob()?.endDate)\" (bsValueChange)=\"setTempJobMonth('endDate', $event)\"\r\n name=\"endDate{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">\r\n End date is required\r\n </div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isMonthRangeInvalid(tempJob()?.startDate, tempJob()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Responsibilities (one per line)</label>\r\n <textarea rows=\"4\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\" name=\"responsibilities{{ i }}\"></textarea>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\" name=\"workAttachment{{ i }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempJob()?.fileName\">\r\n <span>{{ tempJob()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempJob())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n </ng-template>\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-3\" *ngIf=\"editingJobIndex() === i\">\r\n <button class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4 \" [disabled]=\"isSavingWork\"\r\n (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : workActionLabel(editingJobIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/patch-check-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Certifications</h5>\r\n <span *ngIf=\"certs().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"certificationSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ certificationSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"certs().length === 0 || !certificationSectionHasUnsavedItems() || isSavingCertification || isAddingCertification() || editingCertificationIndex() !== null\"\r\n (click)=\"confirmAllCertifications()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add certification\" (click)=\"addCertification()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"certs().length === 0 && !isAddingCertification() && editingCertificationIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addCertification()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/patch-check.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No certifications added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3 border\">\r\n <div *ngIf=\"isAddingCertification() && tempCertification()\" class=\"list-group-item py-3 px-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\" name=\"newCertName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\" name=\"newCertOrg\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\" name=\"newCertState\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certification Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\" name=\"newCertCredentialId\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('issueDate', $event)\" name=\"newCertIssueDate\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('expiryDate', $event)\" name=\"newCertExpiryDate\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempCertification()?.issueDate || null, tempCertification()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\" name=\"newCertAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempCertification()?.fileName\">\r\n <span>{{ tempCertification()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempCertification())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\"\r\n (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : certificationActionLabel(editingCertificationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let cert of certs(); let ci = index\" class=\"list-group-item py-3 cert-accent-item\">\r\n <ng-container *ngIf=\"editingCertificationIndex() !== ci; else editCert\">\r\n <div class=\"d-flex justify-content-between align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <div class=\"fw-semibold item-title-sm\">{{ cert.name }}</div>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedCertificationItem(ci) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedCertificationItem(ci) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ cert.issuingOrganization || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.credentialId || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.issueDate ? formatMonthYear(cert.issueDate) : '\u2014' }} - {{ cert.expiryDate ? formatMonthYear(cert.expiryDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.state || '\u2014' }}</span>\r\n <div *ngIf=\"(certIssuesByIndex()[ci] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (certIssuesByIndex()[ci] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditCertification(ci)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteCertification(ci)\" title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #editCert>\r\n <div *ngIf=\"(certIssuesByIndex()[ci] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (certIssuesByIndex()[ci] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\" name=\"certName{{ ci }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\"\r\n name=\"certOrg{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\" name=\"certState{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certification Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\"\r\n name=\"certCredentialId{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('issueDate', $event)\" name=\"certIssue{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('expiryDate', $event)\" name=\"certExpiry{{ ci }}\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempCertification()?.issueDate || null, tempCertification()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\" name=\"certAttachment{{ ci }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempCertification()?.fileName\">\r\n <span>{{ tempCertification()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempCertification())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\"\r\n (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : certificationActionLabel(editingCertificationIndex()) }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/card-checklist-warning.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Licenses</h5>\r\n <span *ngIf=\"licenses().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"licenseSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ licenseSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"licenses().length === 0 || !licenseSectionHasUnsavedItems() || isSavingLicense || isAddingLicense() || editingLicenseIndex() !== null\"\r\n (click)=\"confirmAllLicenses()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add license\" (click)=\"addLicense()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"licenses().length === 0 && !isAddingLicense() && editingLicenseIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addLicense()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/card-checklist.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No licenses added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3 border\">\r\n <div *ngIf=\"isAddingLicense() && tempLicense()\" class=\"list-group-item py-3 px-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\" name=\"newLicName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempLicense()?.name)\">License name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\" name=\"newLicAuthority\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\" name=\"newLicNumber\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\" name=\"newLicState\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('issueDate', $event)\" name=\"newLicIssueDate\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('expiryDate', $event)\" name=\"newLicExpiryDate\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempLicense()?.issueDate || null, tempLicense()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">License File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\" name=\"newLicenseAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempLicense()?.fileName\">\r\n <span>{{ tempLicense()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempLicense())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelEditLicense()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingLicense\"\r\n (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : licenseActionLabel(editingLicenseIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let lic of licenses(); let li = index\" class=\"list-group-item py-3 lic-accent-item\">\r\n <ng-container *ngIf=\"editingLicenseIndex() !== li; else editLic\">\r\n <div class=\"d-flex justify-content-between align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <div class=\"fw-semibold item-title-sm\">{{ lic.name }}</div>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedLicenseItem(li) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedLicenseItem(li) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ lic.issuingAuthority || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.licenseNumber || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.issueDate ? formatMonthYear(lic.issueDate) : '\u2014' }} - {{ lic.expiryDate ? formatMonthYear(lic.expiryDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.state || '\u2014' }}</span>\r\n <div *ngIf=\"(licenseIssuesByIndex()[li] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (licenseIssuesByIndex()[li] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditLicense(li)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteLicense(li)\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #editLic>\r\n <div *ngIf=\"(licenseIssuesByIndex()[li] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (licenseIssuesByIndex()[li] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\" name=\"licName{{ li }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempLicense()?.name)\">License name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\" name=\"licAuthority{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\" name=\"licNumber{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\" name=\"licState{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('issueDate', $event)\" name=\"licIssue{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('expiryDate', $event)\" name=\"licExpiry{{ li }}\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempLicense()?.issueDate || null, tempLicense()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">License File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\" name=\"licenseAttachment{{ li }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempLicense()?.fileName\">\r\n <span>{{ tempLicense()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempLicense())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditLicense()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingLicense\"\r\n (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : licenseActionLabel(editingLicenseIndex()) }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/tools.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Tools</h5>\r\n <span *ngIf=\"tools().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"toolsSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ toolsSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"tools().length === 0 || !toolsSectionHasUnsavedItems() || isSavingTool || isToolEditorOpen()\" (click)=\"confirmAllTools()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add tool\" (click)=\"addTool()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex flex-wrap gap-2 p-3 bg-white border rounded shadow-sm\">\r\n <div *ngFor=\"let tool of tools(); let ti = index\" class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\"\r\n class=\"btn btn-light border res-flex d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openToolEditor(ti)\" title=\"Edit\">\r\n <span class=\"fw-normal item-name-text\">{{ tool }}</span>\r\n <span class=\"badge border ms-1\"\r\n [ngClass]=\"hasUnsavedToolItem(ti) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedToolItem(ti) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n <span *ngIf=\"(toolIssuesByIndex()[ti] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\">\r\n Missing info\r\n </span>\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Delete tool\" (click)=\"deleteTool(ti)\">\r\n <span class=\"fw-bold\">\u00D7</span>\r\n </button>\r\n </div>\r\n\r\n <span *ngIf=\"tools().length === 0\" class=\"text-muted small\">No tools added.</span>\r\n </div>\r\n\r\n <div *ngIf=\"isToolEditorOpen()\" class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 9999999;\" (click)=\"closeToolEditor()\">\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\"\r\n (click)=\"$event.stopPropagation()\">\r\n <div class=\"card shadow border-0 w-100\" style=\"max-width: 900px;\">\r\n <div class=\"card-header bg-white d-flex align-items-center gap-3\">\r\n <button type=\"button\" class=\"btn btn-link p-0 text-decoration-none\" (click)=\"closeToolEditor()\">\r\n <img src=\"/assets/images/icons/arrow-left-blue.svg\" width=\"20\" height=\"20\" alt=\"\" />\r\n </button>\r\n <div class=\"fw-bold\">{{ isAddingTool() ? 'Add Tool' : ('Edit ' + (toolForm()?.name || '') + ' Tool') }}\r\n </div>\r\n </div>\r\n <div class=\"card-body p-4\">\r\n <div *ngIf=\"toolFormIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ toolFormIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"row g-3\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Tool Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"toolForm()?.name\"\r\n (ngModelChange)=\"patchToolForm({ name: $event })\" name=\"toolName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(toolForm()?.name)\">Tool name is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span\r\n class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempToolStars(s)\" [attr.aria-label]=\"'Set rating ' + s\">\r\n <span [class]=\"(toolForm()?.stars || 0) >= s ? 'text-warning fs-5' : 'text-muted fs-5'\">\r\n {{ (toolForm()?.stars || 0) >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ toolForm()?.stars || 0 }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"(toolForm()?.stars || 0) <= 0\">Star rating is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngModel]=\"toolForm()?.year\"\r\n (ngModelChange)=\"patchToolForm({ year: $event === '' ? null : +$event })\" name=\"toolYear\" min=\"1\"\r\n max=\"30\" placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"toolForm()?.year === null || toolForm()?.year === undefined\">\r\n Years of experience is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4 text-center\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-checks form-switch mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"toolForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchToolForm({ profileVisibility: $event })\" name=\"toolVisible\" id=\"toolVisible\"\r\n style=\"width: 55px;height: 25px;margin-left: -57px;\" />\r\n <label class=\"form-check-label ps-2 pt-1\" for=\"toolVisible\">Visible</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Comment</label>\r\n <textarea rows=\"4\" class=\"form-control\" [ngModel]=\"toolForm()?.notes\"\r\n (ngModelChange)=\"patchToolForm({ notes: $event })\" name=\"toolNotes\"\r\n placeholder=\"Comment your tool here...\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-white d-flex justify-content-end gap-2\">\r\n <button *ngIf=\"!isAddingTool() && editingToolIndex() !== null\" type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\" (click)=\"deleteTool(editingToolIndex()!)\">\r\n Delete\r\n </button>\r\n <button type=\"button\" class=\"btn btn-link text-secondary\" (click)=\"closeToolEditor()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary px-4\" [disabled]=\"isSavingTool\" (click)=\"saveToolEditor()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Saving...' : toolActionLabel(editingToolIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row g-4 mb-5\">\r\n <div class=\"col-md-12\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/stars.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Skills</h5>\r\n <span *ngIf=\"skills().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"skillsSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ skillsSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"skills().length === 0 || !skillsSectionHasUnsavedItems() || isSavingSkill || isSkillEditorOpen()\" (click)=\"confirmAllSkills()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add skill\" (click)=\"addSkill()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex flex-wrap gap-2 p-3 bg-white border rounded shadow-sm\">\r\n <div *ngFor=\"let skill of skills(); let si = index\" class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\"\r\n class=\"btn btn-light border res-flex d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openSkillEditor(si)\" title=\"Edit\">\r\n <span class=\"fw-normal item-name-text\">{{ skill }}</span>\r\n <span class=\"badge border ms-1\"\r\n [ngClass]=\"hasUnsavedSkillItem(si) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedSkillItem(si) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n <span *ngIf=\"(skillIssuesByIndex()[si] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\">\r\n Missing info\r\n </span>\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Delete skill\"\r\n (click)=\"deleteSkill(si); $event.stopPropagation()\">\r\n <span class=\"fw-bold\">\u00D7</span>\r\n </button>\r\n </div>\r\n\r\n <span *ngIf=\"skills().length === 0\" class=\"text-muted small\">No skills added.</span>\r\n </div>\r\n <div *ngIf=\"isSkillEditorOpen()\" class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 9999999;\" (click)=\"closeSkillEditor()\">\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\"\r\n (click)=\"$event.stopPropagation()\">\r\n <div class=\"card shadow border-0 w-100\" style=\"max-width: 900px;\">\r\n <div class=\"card-header bg-white d-flex align-items-center gap-3\">\r\n <button type=\"button\" class=\"btn btn-link p-0 text-decoration-none\" (click)=\"closeSkillEditor()\">\r\n <img src=\"/assets/images/icons/arrow-left-blue.svg\" width=\"20\" height=\"20\" alt=\"\" />\r\n </button>\r\n <div class=\"fw-bold\">{{ isAddingSkill() ? 'Add Skill' : ('Edit ' + (skillForm()?.name || '') + ' Skill')\r\n }}</div>\r\n </div>\r\n <div class=\"card-body p-4\">\r\n <div *ngIf=\"skillFormIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ skillFormIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"row g-3\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Skills Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"skillForm()?.name\"\r\n (ngModelChange)=\"patchSkillForm({ name: $event })\" name=\"skillName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(skillForm()?.name)\">Skillset name is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span\r\n class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempSkillStars(s)\" [attr.aria-label]=\"'Set rating ' + s\">\r\n <span [class]=\"(skillForm()?.stars || 0) >= s ? 'text-warning fs-5' : 'text-muted fs-5'\">\r\n {{ (skillForm()?.stars || 0) >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ skillForm()?.stars || 0 }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"(skillForm()?.stars || 0) <= 0\">Star rating is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngModel]=\"skillForm()?.year\"\r\n (ngModelChange)=\"patchSkillForm({ year: $event === '' ? null : +$event })\" name=\"skillYear\" min=\"1\"\r\n max=\"30\" placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"skillForm()?.year === null || skillForm()?.year === undefined\">Years of experience is\r\n required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4 text-center\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-checks form-switch mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"skillForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchSkillForm({ profileVisibility: $event })\" name=\"skillVisible\"\r\n id=\"skillVisible\" style=\"width: 55px;height: 25px;margin-left: -57px;\" />\r\n <label class=\"form-check-label ps-2 pt-1\" for=\"skillVisible\">Visible</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Comment</label>\r\n <textarea rows=\"4\" class=\"form-control\" [ngModel]=\"skillForm()?.notes\"\r\n (ngModelChange)=\"patchSkillForm({ notes: $event })\" name=\"skillNotes\"\r\n placeholder=\"Comment your skill here...\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-white d-flex justify-content-end gap-2\">\r\n <button *ngIf=\"!isAddingSkill() && editingSkillIndex() !== null\" type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\" (click)=\"deleteSkill(editingSkillIndex()!)\">\r\n Delete\r\n </button>\r\n <button type=\"button\" class=\"btn btn-link text-secondary\" (click)=\"closeSkillEditor()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary px-4\" [disabled]=\"isSavingSkill\" (click)=\"saveSkillEditor()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Saving...' : skillActionLabel(editingSkillIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row g-4 mb-5\">\r\n <div class=\"col-md-12\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/mortarboard-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Education</h5>\r\n <span *ngIf=\"educationList().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"educationSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ educationSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"educationList().length === 0 || !educationSectionHasUnsavedItems() || isSavingEducation || isAddingEducation() || editingEducationIndex() !== null\"\r\n (click)=\"confirmAllEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add education\" (click)=\"addEducation()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"educationList().length === 0 && !isAddingEducation() && editingEducationIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addEducation()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/mortarboard.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No education added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div *ngIf=\"isAddingEducation() && tempEducation()\" class=\"mb-2\">\r\n <div class=\"form-panel\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\" name=\"newEduDegree\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Institution <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\" name=\"newEduInstitution\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree / Course Type <span class=\"text-danger\">*</span></label>\r\n <ng-select class=\"ng-select-sm\" [items]=\"educationDegreeTypeOptions\" [clearable]=\"false\"\r\n placeholder=\"Select degree / course type\" [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\" name=\"newEduDegreeType\">\r\n </ng-select>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.country\"\r\n (ngModelChange)=\"patchTempEducation({ country: $event })\" name=\"newEduCountry\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.state\"\r\n (ngModelChange)=\"patchTempEducation({ state: $event })\" name=\"newEduState\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\" name=\"newEduCity\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.startDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('startDate', $event)\" name=\"newEduStartDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.startDate)\">Start date is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.endDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('endDate', $event)\" name=\"newEduEndDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Education File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onEducationFileSelected($event)\" name=\"newEducationAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempEducation()?.fileName\">\r\n <span>{{ tempEducation()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempEducation())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingEducation\"\r\n (click)=\"saveEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Uploading...' : educationActionLabel(editingEducationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let edu of educationList(); let ei = index\" class=\"edu-accent-item p-3 bg-white border rounded-3 shadow-sm mb-2\">\r\n <div class=\"d-flex justify-content-between align-items-start\">\r\n <div class=\"d-flex align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h6 class=\"fw-bold mb-0 item-title-sm\">{{ edu.degree }}</h6>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedEducationItem(ei) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedEducationItem(ei) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ edu.institution || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.degreeType || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.startDate ? formatMonthYear(edu.startDate) : '\u2014' }} - {{ edu.endDate ? formatMonthYear(edu.endDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.city }}<span *ngIf=\"edu.city && edu.state\">, </span>{{ edu.state }}<ng-container *ngIf=\"!edu.city && !edu.state\">\u2014</ng-container></span>\r\n <div *ngIf=\"(educationIssuesByIndex()[ei] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (educationIssuesByIndex()[ei] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\" *ngIf=\"editingEducationIndex() !== ei\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditEducation(ei)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteEducation(ei)\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"editingEducationIndex() === ei\" class=\"mt-3\">\r\n <div *ngIf=\"(educationIssuesByIndex()[ei] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (educationIssuesByIndex()[ei] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\" name=\"eduDegree{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Institution <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\" name=\"eduInstitution{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.institution)\">Institution name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree / Course Type <span class=\"text-danger\">*</span></label>\r\n <ng-select class=\"ng-select-sm\" [items]=\"educationDegreeTypeOptions\" [clearable]=\"false\"\r\n placeholder=\"Select degree / course type\" [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\" name=\"eduDegreeType{{ ei }}\">\r\n </ng-select>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.country\"\r\n (ngModelChange)=\"patchTempEducation({ country: $event })\" name=\"eduCountry{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.state\"\r\n (ngModelChange)=\"patchTempEducation({ state: $event })\" name=\"eduState{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\" name=\"eduCity{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.startDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('startDate', $event)\" name=\"eduStartDate{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.startDate)\">Start date is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.endDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('endDate', $event)\" name=\"eduEndDate{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Education File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onEducationFileSelected($event)\" name=\"educationAttachment{{ ei }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempEducation()?.fileName\">\r\n <span>{{ tempEducation()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempEducation())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingEducation\" (click)=\"saveEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Uploading...' : educationActionLabel(editingEducationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n </div>\r\n <div class=\"d-flex gap-3 justify-content-center mt-5 pt-2\" *ngIf=\"!isResume\">\r\n <button class=\"btn btn-outline-secondary preview-back-btn px-5 h-auto\" style=\"border-radius: 5px !important;\" (click)=\"onBackClick()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"me-1\" style=\"vertical-align:-0.1em\">\r\n <path d=\"M11 3 5 8l6 5\" />\r\n </svg> Back\r\n </button>\r\n <button class=\"btn btn-primary preview-dashboard-btn px-5 h-auto\" style=\"border-radius: 5px !important;\" [disabled]=\"!canConfirmAndContinue() || isSavingBasic\"\r\n (click)=\"onGoToDashboardClick()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Saving...' : 'Go to Dashboard' }}\r\n <img *ngIf=\"!isSavingBasic\" src=\"/assets/images/icons/arrow-right-white.svg\" width=\"14\" height=\"14\" class=\"ms-1\" style=\"vertical-align:-0.1em\" alt=\"\" />\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<ng-template #loading>\r\n <div class=\"text-center p-5\">\r\n <div class=\"spinner-border text-primary\"></div>\r\n <p class=\"text-muted mt-2\">Loading data...</p>\r\n </div>\r\n</ng-template>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBulkSkillConfirm\">\r\n <div class=\"confirm-modal-card\" style=\"max-width: 480px;\">\r\n <h4 class=\"mb-1\">Set Rating for All Skills</h4>\r\n <p class=\"text-muted small mb-4\">Enter a star rating and years of experience to apply to all skills that are missing these values.</p>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"bulkSkillStars = s\">\r\n <span [class]=\"bulkSkillStars >= s ? 'text-warning fs-4' : 'text-muted fs-4'\">\r\n {{ bulkSkillStars >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ bulkSkillStars }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkSkillStars <= 0\">Star rating is required</div>\r\n </div>\r\n <div class=\"mb-4\">\r\n <label class=\"small text-muted d-block mb-1\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [(ngModel)]=\"bulkSkillYear\" min=\"1\" max=\"30\"\r\n placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkSkillYear === null || bulkSkillYear === undefined\">Years of experience is required</div>\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"cancelBulkSkillConfirm()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingSkill || bulkSkillStars <= 0 || bulkSkillYear === null\"\r\n (click)=\"applyBulkSkillConfirm()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Saving...' : 'Apply to All & Save' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBulkToolConfirm\">\r\n <div class=\"confirm-modal-card\" style=\"max-width: 480px;\">\r\n <h4 class=\"mb-1\">Set Rating for All Tools</h4>\r\n <p class=\"text-muted small mb-4\">Enter a star rating and years of experience to apply to all tools that are missing these values.</p>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"bulkToolStars = s\">\r\n <span [class]=\"bulkToolStars >= s ? 'text-warning fs-4' : 'text-muted fs-4'\">\r\n {{ bulkToolStars >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ bulkToolStars }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkToolStars <= 0\">Star rating is required</div>\r\n </div>\r\n <div class=\"mb-4\">\r\n <label class=\"small text-muted d-block mb-1\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [(ngModel)]=\"bulkToolYear\" min=\"1\" max=\"30\"\r\n placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkToolYear === null || bulkToolYear === undefined\">Years of experience is required</div>\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"cancelBulkToolConfirm()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingTool || bulkToolStars <= 0 || bulkToolYear === null\"\r\n (click)=\"applyBulkToolConfirm()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Saving...' : 'Apply to All & Save' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBackConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Leave this page?</h4>\r\n <p class=\"text-muted mb-4\">If you go back, only saved data will be retained.</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"stayOnPreview()\">Stay</button>\r\n <button type=\"button\" class=\"btn btn-danger h-auto\" (click)=\"proceedBack()\">Proceed Back</button>\r\n </div>\r\n </div>\r\n\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showDashboardConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Finish Setup and Continue</h4>\r\n <p class=\"text-muted mb-4\">Save your information and go to your dashboard</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" [disabled]=\"isSavingBasic\"\r\n (click)=\"cancelDashboardRedirect()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingBasic\" (click)=\"goToDashboard()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Proceeding...' : 'Proceed' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{color:#69707d}.res-flex:hover,.res-flex:focus,.res-flex:active{transform:none!important;box-shadow:none!important}.container{max-width:900px;margin:30px auto;font-family:Arial,sans-serif;color:#69707d}.preview-page-header{max-width:900px;margin:50px auto 10px;padding:0 12px}.preview-title{font-size:18px;font-weight:700;color:#69707d;margin:0}.preview-subtitle{margin-top:7px;font-size:14px;color:#69707d}.preview-card-gradient h2,.section h5.fw-bold{font-size:18px}.section{margin-bottom:25px}.section-title{font-weight:600;display:block;margin-bottom:8px}.section-title .sub{font-weight:400;color:#777;font-size:13px}.dropdown-box{border:1px solid #ddd;border-radius:8px;padding:12px 15px;display:flex;justify-content:space-between;align-items:center}.icons{display:flex;gap:10px}.icon{cursor:pointer;font-size:14px;color:#777}.card{border:1px solid #ddd;border-radius:5px;padding:20px;background:#fff}.category{border-bottom:1px solid #eee;padding:15px 0}.category:last-child{border-bottom:none}.category-header{display:flex;justify-content:space-between;font-weight:600;margin-bottom:10px}.tags{display:flex;flex-wrap:wrap;gap:10px}.tag{background:#f2f4f7;padding:6px 12px;border-radius:6px;font-size:13px}.footer{text-align:center;margin-top:15px;color:#777;cursor:pointer}.actions{display:flex;justify-content:space-between;margin:50px 0 27px}.text-secondary{white-space:pre-line;font-size:12px;color:#69707d}.extra-small{font-size:.8rem}.card{transition:transform .2s ease,box-shadow .2s ease}.card:hover{transform:translateY(-3px)}.achievement-section .badge{font-size:.75rem;white-space:normal;text-align:left}.skill-tag .badge{font-weight:500;font-size:.9rem;transition:all .2s ease;cursor:default}.skill-tag .badge:hover{transform:translateY(-2px)}.skill-tag .btn-close{opacity:.5}.skill-tag .btn-close:hover{opacity:1}.bg-light.text-dark.border{background-color:#f8f9fa!important;border-color:#dee2e6!important}.card{transition:all .3s cubic-bezier(.25,.8,.25,1)}.card:hover .bg-light{background-color:#e8f5e9!important}.position-fixed .card:hover{transform:none!important}code{background-color:#f8f9fa;padding:2px 6px;border-radius:4px}.list-group-item{transition:all .2s ease-in-out}.list-group-item:hover{background-color:#fcfcfc;transform:translate(5px)}.border-dashed{border-style:dashed!important}.tool-card{transition:all .2s ease-in-out;border-radius:12px}.tool-card:hover{transform:translateY(-5px);border-color:var(--bs-primary)!important}.tool-card:hover .icon-box{background-color:var(--bs-primary-subtle)!important}.tool-card .icon-box{width:60px;height:60px;transition:background-color .2s ease}.border-dashed{border:2px dashed #dee2e6!important}.border-dashed:hover{border-color:var(--bs-primary)!important;background-color:#fff!important}.popup{position:fixed;top:20%;right:20px;width:320px;max-width:calc(100vw - 32px);background:#fff;border-radius:10px;padding:16px}.status-row{display:flex;justify-content:space-between;margin:10px 0}.success{color:#2e7d32;font-weight:700}.error{color:#d32f2f}.pending{color:#f9a825}.section-flag{font-weight:600}button.btn.btn-sm.btn-outline-primary{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:5px!important}button.btn.btn-sm.btn-outline-primary:hover{background-color:#356895;border-color:#356895;color:#fff}button.btn.btn-sm.btn-outline-danger{border:1px solid #dc3545;color:#dc3545;border-radius:5px!important}button.btn.btn-sm.btn-outline-primary.rounded-circle{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:5px!important}button.action-icon-btn{min-width:22px;width:22px;height:22px;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:5px!important;background:transparent!important;border:none!important;line-height:1}button.action-icon-btn.btn-outline-primary{color:#4077ad!important;border-color:#4077ad!important}button.action-icon-btn.btn-outline-danger{color:#dc3545!important}.action-icon-image{width:20px;height:20px;object-fit:contain;display:inline-block}.action-icon-image.edit-icon{filter:brightness(0) saturate(100%) invert(41%) sepia(39%) saturate(774%) hue-rotate(170deg) brightness(91%) contrast(89%)}.action-icon-image.delete-icon{filter:brightness(0) saturate(100%) invert(24%) sepia(79%) saturate(4008%) hue-rotate(344deg) brightness(91%) contrast(90%)}.modal-overlay{position:fixed;inset:0;background:#11182773;display:flex;align-items:center;justify-content:center;z-index:2500;padding:20px}.status-modal-card{width:min(760px,96vw);max-height:85vh;overflow:auto;background:#fff;border-radius:16px;border:1px solid #e5e7eb}.status-modal-header{padding:20px 24px 14px;border-bottom:1px solid #eef2f7}.status-modal-body{padding:12px 20px 20px}.status-modal-footer{padding:12px 20px 20px;border-top:1px solid #eef2f7;display:flex;justify-content:end;align-items:center;gap:12px}.status-modal-row{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px 10px;border-bottom:1px solid #f1f5f9}.status-modal-row:last-child{border-bottom:0}.status-modal-name{font-size:14px;font-weight:600;color:#69707d}.status-modal-state{font-size:.92rem;font-weight:600}.status-modal-state.pending{color:#a16207}.status-modal-state.success{color:#166534}.status-modal-state.partial{color:#b45309}.status-modal-state.error{color:#b91c1c}.confirm-modal-card{width:min(520px,96vw);background:#fff;border-radius:5px;border:1px solid #e5e7eb;padding:24px}.year-experience-select{max-height:150px}@media screen and (max-width: 768px){.res-flex{flex-wrap:wrap!important;justify-content:center!important}.res-flex .fw-normal{width:100%;text-align:center;font-size:14px!important}.d-flex.flex-wrap.gap-2.p-3.bg-white.border.rounded.shadow-sm{justify-content:center}.preview-page-header{margin:20px auto 8px;padding:0 4px}.container{padding-left:4px;padding-right:4px}.preview-title{font-size:16px}.preview-subtitle{font-size:14px}.actions{margin:24px 0 16px}.section-header-title{flex-wrap:wrap}.section-header-title>.section-flag{flex-basis:53%}.section-header-row{align-items:flex-start}.preview-card-gradient{padding:14px 14px 12px}.preview-card-gradient h2{font-size:18px}.popup{width:calc(100vw - 40px);right:16px;top:12%}.card{padding:0}.card-body.p-4,.px-4.py-3{padding:12px!important}.row.g-4,.row.g-3{--bs-gutter-x: .75rem}.d-flex.gap-4{gap:10px!important}.preview-card-gradient>.d-flex.justify-content-between.align-items-start{flex-wrap:wrap;row-gap:8px}.preview-card-gradient>.d-flex.justify-content-between.align-items-start>.badge.bg-primary-subtle{margin-left:auto}}@media screen and (max-width: 575px){.preview-title{font-size:16px}.preview-subtitle{font-size:14px}.section>.d-flex{flex-wrap:wrap;row-gap:8px}.section>.d-flex>.d-flex:last-child{width:100%;justify-content:flex-end}}::ng-deep .bs-datepicker-head{background-color:#4077ad!important}::ng-deep .bs-datepicker-body table td span.selected,.bs-datepicker-body table td.selected span{background-color:#4077ad!important}.profile-avatar-circle{width:58px;height:58px;border-radius:5px;background:#4077ad;display:flex;align-items:center;justify-content:center;font-size:22px;font-weight:700;color:#fff;letter-spacing:1px;flex-shrink:0}.section-header-icon{font-size:20px;line-height:1;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;opacity:.9;filter:invert(47%) sepia(8%) saturate(483%) hue-rotate(176deg) brightness(91%) contrast(87%)}.section-header-title h5.fw-bold{color:#69707d}.text-muted{color:#69707d!important}h6.text-uppercase.fw-bold.text-muted{font-size:14px;color:#69707d!important}.work-accent-item{border-radius:5px!important;transition:background-color .18s ease,box-shadow .18s ease}.work-accent-item:hover{background-color:#f5f8ff!important;box-shadow:0 4px 14px #4077ad17!important}.edu-accent-item{border-radius:5px!important;transition:background-color .18s ease,box-shadow .18s ease}.edu-accent-item:hover{background-color:#f8f8ff!important;box-shadow:0 4px 14px #6366f117!important}.cert-accent-item{border-radius:5px!important;transition:background-color .18s ease}.cert-accent-item:hover{background-color:#f0fdf4!important}.lic-accent-item{border-radius:5px!important;transition:background-color .18s ease}.lic-accent-item:hover{background-color:#fffbeb!important}.field-label-sm{font-size:14px;font-weight:700;letter-spacing:.08em;color:#69707d;margin-bottom:3px;display:block}.item-name-text{color:#69707d}.field-value-sm{font-weight:600;font-size:12px;color:#69707d}.item-title-sm{font-size:14px;color:#69707d!important}.item-meta-line{display:block;font-size:12px;color:#69707d;margin-top:3px}.empty-state-wrap{text-align:center;padding:32px 20px;background:#fafbfc;border:1.5px dashed #d1d5db;border-radius:5px;cursor:pointer;transition:background-color .18s ease,border-color .18s ease}.empty-state-wrap .empty-icon{font-size:2rem;color:#d1d5db;margin-bottom:8px}.empty-state-wrap p{color:#9ca3af;margin:0;font-size:14px}.empty-state-wrap:hover{background:#f0f6ff;border-color:#4077ad}.form-panel{background:#fff;border:1px solid #e2e8f0;border-radius:5px;padding:20px}.form-panel .form-control,.form-panel .form-select{border-color:#d1d5db;border-radius:8px;font-size:12px}.form-panel .form-control:focus,.form-panel .form-select:focus{border-color:#4077ad;box-shadow:0 0 0 3px #4077ad1f}.section-header-bar{display:flex;align-items:center;justify-content:space-between;padding:10px 0 14px;border-bottom:2px solid #f1f5f9;margin-bottom:16px}.preview-card-gradient{background:linear-gradient(135deg,#fff,#eff6ff);border-bottom:1px solid #e2e8f0;padding:20px 24px 16px;border-radius:5px 5px 0 0}.item-icon-circle{width:40px;height:40px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:700;color:#fff;flex-shrink:0}.item-avatar--work{background:linear-gradient(135deg,#4077ad,#2d5a8a)}.item-avatar--edu{background:linear-gradient(135deg,#4077ad,#4338ca)}.provider-layout{display:flex;flex-direction:column}.provider-company-first{order:-1}.section-locked{pointer-events:none;opacity:.45;filter:blur(1.5px);-webkit-user-select:none;user-select:none}.btn.btn-primary{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-primary:hover:not(:disabled),.btn.btn-primary:focus:not(:disabled),.btn.btn-primary:active:not(:disabled){background-color:#356895!important;border-color:#356895!important;color:#fff!important}.btn.btn-success,.btn.btn-outline-success{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-success:hover:not(:disabled),.btn.btn-success:focus:not(:disabled),.btn.btn-success:active:not(:disabled),.btn.btn-outline-success:hover:not(:disabled),.btn.btn-outline-success:focus:not(:disabled),.btn.btn-outline-success:active:not(:disabled){background-color:#336843!important;border-color:#336843!important;color:#fff!important}.btn.btn-outline-secondary.rounded-pill{background-color:#69707d!important;border-color:#69707d!important;color:#fff!important;border-radius:5px!important}.btn.btn-outline-secondary.rounded-pill:hover:not(:disabled),.btn.btn-outline-secondary.rounded-pill:focus:not(:disabled),.btn.btn-outline-secondary.rounded-pill:active:not(:disabled){background-color:#565c66!important;border-color:#565c66!important;color:#fff!important}.preview-back-btn{background-color:#426c85!important;border-color:#426c85!important;color:#fff!important}.preview-dashboard-btn{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-outline-success:hover:not(:disabled),.btn.btn-outline-success:focus:not(:disabled),.btn.btn-outline-success:active:not(:disabled){background-color:transparent!important;border-color:#198754!important;color:#198754!important}.btn.btn-outline-secondary:not(.rounded-pill){background-color:#d4dae6!important;border-color:#d4dae6!important;color:#69707d!important}.btn.btn-outline-secondary:not(.rounded-pill):hover:not(:disabled),.btn.btn-outline-secondary:not(.rounded-pill):focus:not(:disabled),.btn.btn-outline-secondary:not(.rounded-pill):active:not(:disabled){background-color:#c2cbde!important;border-color:#c2cbde!important;color:#69707d!important}.btn.btn-danger{background-color:#b43026!important;border-color:#b43026!important;color:#fff!important}.btn.btn-danger:hover:not(:disabled),.btn.btn-danger:focus:not(:disabled),.btn.btn-danger:active:not(:disabled){background-color:#96271f!important;border-color:#96271f!important;color:#fff!important}.btn.btn-outline-danger.rounded-circle{border-color:#b43026!important;color:#b43026!important;border-radius:5px!important}.btn.btn-outline-danger.rounded-circle:hover:not(:disabled),.btn.btn-outline-danger.rounded-circle:focus:not(:disabled),.btn.btn-outline-danger.rounded-circle:active:not(:disabled){border-color:#96271f!important;color:#b43026!important}.btn.btn-link.text-secondary{background-color:#d4dae6!important;border-color:#d4dae6!important;color:#69707d!important;text-decoration:none!important;border-radius:5px}.btn.btn-link.text-secondary:hover:not(:disabled),.btn.btn-link.text-secondary:focus:not(:disabled){background-color:#c2cbde!important;color:#69707d!important}.btn.btn-link.text-danger{background-color:#b43026!important;border-color:#b43026!important;color:#fff!important;text-decoration:none!important;border-radius:5px}.btn.btn-link.text-danger:hover:not(:disabled),.btn.btn-link.text-danger:focus:not(:disabled){background-color:#96271f!important;color:#fff!important}.btn{border-radius:5px!important;box-shadow:none!important}.badge.bg-warning-subtle.text-warning{background-color:#fff3cd!important;color:#664d03!important;border-color:#ffe69c!important}.badge.bg-success-subtle.text-success{background-color:#4077ad!important;color:#fff!important;border-color:#4077ad!important}.badge.bg-primary-subtle.text-primary{background-color:#e0edf2!important;color:#4077ad!important;border-color:#e0edf2!important}\n"] }]
|
|
6549
|
-
}], ctorParameters: () => [{ type: CredentialingStore }, { type: FileService }, { type: UserSkillSetService }, { type: UserToolService }, { type: UserDocumentService }, { type: UserEducationService }, { type: UserDetailService }, { type: UserExperienceService }, { type: i1$4.TokenService }, { type: i1$4.RoleContextService }, { type: ProvidersService }, { type: FrontEndProvidersService }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
|
|
7208
|
+
], template: "<div class=\"preview-page-header\" *ngIf=\"!isResume\">\r\n <div class=\"d-flex align-items-center gap-2 mb-1\">\r\n <h2 class=\"preview-title mb-0\">Review Extracted Information</h2>\r\n </div>\r\n <p class=\"preview-subtitle text-muted\">We\u2019ve automatically extracted details from your uploaded resume. Please review and confirm accuracy before proceeding.</p>\r\n</div>\r\n\r\n\r\n<div [ngClass]=\"isResume ? '' : 'container py-4'\" [class.provider-layout]=\"roleData?.role?.name === 'Provider'\">\r\n\r\n <!-- Provider initial setup: combined company + personal form (shown until both APIs succeed) -->\r\n <div class=\"section mb-5\" *ngIf=\"roleData?.role?.name === 'Provider' && !hasUserDetailData && !isResume\">\r\n <div class=\"d-flex align-items-center gap-2 mb-3 section-header-title\">\r\n <img src=\"/assets/images/icons/building.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Company & Personal Details</h5>\r\n <span class=\"badge border section-flag bg-warning-subtle text-warning\">Required to continue</span>\r\n </div>\r\n <div class=\"card shadow-sm border-0\">\r\n <div class=\"card-header bg-white fw-semibold\">Company Information</div>\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-3\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': (!tempCompanyDetails.companyName?.trim() && companyFormSubmitted) || companyNameError}\"\r\n [(ngModel)]=\"tempCompanyDetails.companyName\" name=\"setupCompanyName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyName?.trim() && companyFormSubmitted\">Company name is required</div>\r\n <div class=\"invalid-feedback\" *ngIf=\"companyNameError\">{{ companyNameError }}</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" maxlength=\"14\" inputmode=\"numeric\"\r\n (input)=\"phoneMask($event, 'company')\" (keypress)=\"allowOnlyNumbers($event)\"\r\n [ngClass]=\"{'is-invalid': companyFormSubmitted && (!tempCompanyDetails.companyPhoneNumber?.trim() || getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10)}\"\r\n [(ngModel)]=\"tempCompanyDetails.companyPhoneNumber\" name=\"setupCompanyPhone\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted\">Company phone is required</div>\r\n <div class=\"invalid-feedback\" *ngIf=\"tempCompanyDetails.companyPhoneNumber?.trim() && getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10 && companyFormSubmitted\">Company phone must be 10 digits</div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Company Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempCompanyDetails.address1\" name=\"setupCompanyAddress\"\r\n [options]=\"options\" inputClass=\"form-control form-control-sm\"\r\n [invalid]=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\"\r\n [initialLat]=\"tempCompanyDetails.latitude\" [initialLng]=\"tempCompanyDetails.longitude\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"\r\n (manualEdit)=\"onCompanyAddressManualEdit()\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\">Address is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.city?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.city\" name=\"setupCompanyCity\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.city?.trim() && companyFormSubmitted\">City is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.state?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.state\" name=\"setupCompanyState\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.state?.trim() && companyFormSubmitted\">State is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.zipcode?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.zipcode\" name=\"setupCompanyZip\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.zipcode?.trim() && companyFormSubmitted\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempCompanyDetails.country?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempCompanyDetails.country\" name=\"setupCompanyCountry\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.country?.trim() && companyFormSubmitted\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <input type=\"file\" accept=\".png,.jpg,.jpeg\" class=\"form-control form-control-sm\" (change)=\"uploadCompanyImage($event)\" name=\"setupCompanyLogo\" />\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"tempCompanyLogoUrl\">\r\n <label class=\"small text-muted d-block\">Logo Preview</label>\r\n <img [src]=\"tempCompanyLogoUrl\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-header bg-white fw-semibold border-top\">Personal Information</div>\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-3\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">First Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.firstName?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.firstName\" name=\"setupFirstName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.firstName?.trim() && companyFormSubmitted\">First name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.lastName?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.lastName\" name=\"setupLastName\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.lastName?.trim() && companyFormSubmitted\">Last name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Email <span class=\"text-danger\">*</span></label>\r\n <input type=\"email\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.email?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.email\" name=\"setupEmail\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.email?.trim() && companyFormSubmitted\">Email is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Phone Number <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" maxlength=\"14\" inputmode=\"numeric\"\r\n (input)=\"phoneMask($event, 'profile')\" (keypress)=\"allowOnlyNumbers($event)\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.phone?.trim() && companyFormSubmitted}\"\r\n [ngModel]=\"tempProfile?.phone\" name=\"setupPhone\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.phone?.trim() && companyFormSubmitted\">Phone number is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempProfile.address\" name=\"setupAddress\" [options]=\"options\"\r\n inputClass=\"form-control form-control-sm\" [invalid]=\"!tempProfile?.address?.trim() && companyFormSubmitted\"\r\n [initialLat]=\"tempProfile.latitude\" [initialLng]=\"tempProfile.longitude\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"\r\n (manualEdit)=\"onUserAddressManualEdit()\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.address?.trim() && companyFormSubmitted\">Home address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.city?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.city\" name=\"setupUserCity\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.city?.trim() && companyFormSubmitted\">City is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.state?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.state\" name=\"setupUserState\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.state?.trim() && companyFormSubmitted\">State is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.zipCode?.trim() && companyFormSubmitted}\"\r\n [ngModel]=\"tempProfile?.zipCode\" (ngModelChange)=\"tempProfile.zipCode = sanitizeZipCode($event)\"\r\n name=\"setupUserZip\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.zipCode?.trim() && companyFormSubmitted\">Zip code is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{'is-invalid': !tempProfile?.country?.trim() && companyFormSubmitted}\"\r\n [(ngModel)]=\"tempProfile.country\" name=\"setupUserCountry\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempProfile?.country?.trim() && companyFormSubmitted\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [(ngModel)]=\"tempProfile.jobTitle\" name=\"setupJobTitle\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control form-control-sm\" [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n [ngClass]=\"{'is-invalid': !(tempProfile?.yearsOfExperience > 0) && companyFormSubmitted}\"\r\n name=\"setupYearsOfExp\" min=\"1\" />\r\n <div class=\"invalid-feedback\" *ngIf=\"!(tempProfile?.yearsOfExperience > 0) && companyFormSubmitted\">Years of experience is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Profile Picture</label>\r\n <input #setupHeadshotFile type=\"file\" accept=\".png,.jpg,.jpeg\" class=\"d-none\" (change)=\"uploadHeadshotImage($event)\" name=\"setupHeadshotFile\" />\r\n <div class=\"position-relative\">\r\n <input type=\"text\" class=\"form-control form-control-sm pe-5\" [value]=\"headshotFileName\" readonly\r\n placeholder=\"Upload Profile Picture\" (click)=\"setupHeadshotFile.click()\" />\r\n <img *ngIf=\"!isHeadshotLoading\" src=\"assets/images/icons/upload.svg\" alt=\"Upload\" class=\"upload-icon\" style=\"position:absolute;right:12px;top:50%;transform:translateY(-50%);cursor:pointer;width:18px;\" (click)=\"setupHeadshotFile.click()\" />\r\n <div *ngIf=\"isHeadshotLoading\" style=\"position:absolute;right:12px;top:50%;transform:translateY(-50%);\">\r\n <span class=\"spinner-border spinner-border-sm text-primary\"></span>\r\n </div>\r\n </div>\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"headshotPreviewUrl\">\r\n <label class=\"small text-muted d-block\">Preview</label>\r\n <img [src]=\"headshotPreviewUrl\" class=\"img-thumbnail rounded-circle\" style=\"width:64px;height:64px;object-fit:cover;\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-footer d-flex align-items-center justify-content-end gap-2\">\r\n <span *ngIf=\"providerSetupError\" class=\"small text-danger me-auto\">{{ providerSetupError }}</span>\r\n <button class=\"btn btn-success px-5 \"\r\n [disabled]=\"isSavingProviderSetup || !isProviderSetupFormComplete\"\r\n (click)=\"saveProviderSetup()\">\r\n <span *ngIf=\"isSavingProviderSetup\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingProviderSetup ? 'Saving...' : 'Save & Continue' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\" *ngIf=\"roleData?.role?.name !== 'Provider' || hasUserDetailData\">\r\n <div *ngIf=\"details() as data; else loading\">\r\n <div class=\"card shadow-sm border-0 rounded-3 overflow-hidden\" *ngIf=\"!isEditMode()\">\r\n <div class=\"card-body p-0\">\r\n <div class=\"preview-card-gradient\">\r\n <div class=\"d-flex justify-content-between align-items-start mb-4\">\r\n <div class=\"d-flex align-items-start gap-3\">\r\n <div class=\"profile-avatar-circle\" *ngIf=\"!headshotPreviewUrl\">\r\n {{ (data.firstName?.[0] || '') }}{{ (data.lastName?.[0] || '') }}\r\n </div>\r\n <img *ngIf=\"headshotPreviewUrl\" [src]=\"headshotPreviewUrl\"\r\n class=\"rounded-circle\" style=\"width:56px;height:56px;object-fit:cover;\" alt=\"Profile\" />\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h2 class=\"fw-bold mb-1\">{{ data.firstName }} {{ data.lastName }}</h2>\r\n <span *ngIf=\"basicSectionHasIssues()\" class=\"badge bg-warning-subtle text-warning border section-flag\">\r\n Missing info\r\n </span>\r\n <span class=\"badge border section-flag\"\r\n [ngClass]=\"basicDetailsSaved ? 'bg-success-subtle text-success' : 'bg-warning-subtle text-warning'\">\r\n {{ basicDetailsSaved ? 'Saved' : 'Not saved yet' }}\r\n </span>\r\n </div>\r\n <p class=\"text-muted\">{{ data.jobTitle }} \u2022 {{ data.yearsOfExperience }} Years Exp.</p>\r\n <div *ngIf=\"basicIssues().length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ basicIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <span class=\"badge bg-primary-subtle text-primary border p-2\">Email Verified</span>\r\n </div>\r\n\r\n </div>\r\n <div class=\"px-4 py-3\">\r\n <div class=\"row g-4\">\r\n <div class=\"col-12 border-bottom pb-2\">\r\n <h6 class=\"text-uppercase small fw-bold text-muted\">Summary</h6>\r\n <p class=\"text-secondary small mb-0\">{{ data.summary }}</p>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/envelope.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Email</span>\r\n <span class=\"field-value-sm d-block\">{{ data.email }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/telephone.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Phone</span>\r\n <span class=\"field-value-sm d-block\">{{ data.phone }}</span>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <span class=\"field-label-sm\"><img src=\"/assets/images/icons/geo-alt.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" />Location</span>\r\n <span class=\"field-value-sm d-block\">{{ data.address }}, {{ data.city }}, {{ data.state }}, {{ data.zipCode }}, {{ data.country }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer d-flex align-items-center justify-content-between\">\r\n <span *ngIf=\"!basicDetailsSaved\" class=\"small text-warning fw-semibold\">\r\n <img src=\"/assets/images/icons/exclamation-circle.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" /> Click \"Edit\" to review and save your basic info.\r\n </span>\r\n <span *ngIf=\"basicDetailsSaved\" class=\"small text-success fw-semibold\">\r\n <img src=\"/assets/images/icons/check-circle.svg\" width=\"13\" height=\"13\" class=\"me-1\" style=\"vertical-align:-0.1em\" alt=\"\" /> Basic details saved.\r\n </span>\r\n <button class=\"btn btn-sm btn-primary px-4 ms-auto\" (click)=\"toggleEdit()\">Edit</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"isEditMode()\">\r\n <div class=\"card-header bg-white fw-bold\">Update Profile</div>\r\n <div class=\"card-body p-4\">\r\n <form class=\"row g-3\" #basicForm=\"ngForm\" novalidate>\r\n <div *ngIf=\"basicIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ basicIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">First Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.firstName\" name=\"fName\"\r\n placeholder=\"First Name\" required #fName=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"fName.invalid && (fName.dirty || fName.touched)\">First name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Last Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.lastName\" name=\"lName\"\r\n placeholder=\"Last Name\" required #lName=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"lName.invalid && (lName.dirty || lName.touched)\">Last name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Email <span class=\"text-danger\">*</span></label>\r\n <input type=\"email\" class=\"form-control\" [(ngModel)]=\"tempProfile.email\" name=\"email\" placeholder=\"Email\"\r\n required email #email=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"email.invalid && (email.dirty || email.touched)\">\r\n <span *ngIf=\"email.errors?.['required']\">Email is required</span>\r\n <span *ngIf=\"email.errors?.['email']\">Email format is invalid</span>\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Phone Number <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"tempProfile.phone\" (input)=\"phoneMask($event, 'profile')\"\r\n name=\"phone\" placeholder=\"Phone (10 digits)\" (keypress)=\"allowOnlyNumbers($event)\"\r\n required pattern=\"^\\(\\d{3}\\) \\d{3}-\\d{4}$\" maxlength=\"14\" inputmode=\"numeric\" #phone=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"phone.invalid && (phone.dirty || phone.touched)\">\r\n <span *ngIf=\"phone.errors?.['required']\">Phone number is required</span>\r\n <span *ngIf=\"phone.errors?.['pattern']\">Phone number must be 10 digits</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\"></span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.jobTitle\" name=\"jobTitle\"\r\n placeholder=\"Job Title\" #jobTitle=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"jobTitle.invalid && (jobTitle.dirty || jobTitle.touched)\">Job\r\n title is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngClass]=\"{'is-invalid': !(tempProfile?.yearsOfExperience > 0)}\"\r\n [(ngModel)]=\"tempProfile.yearsOfExperience\"\r\n name=\"yearsOfExperience\" placeholder=\"Years of Experience\" required min=\"1\"\r\n #yearsOfExperience=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!(tempProfile?.yearsOfExperience > 0)\">\r\n Years of experience is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-3\">\r\n <label class=\"small text-muted d-block\">Home Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempProfile.address\" name=\"address\" [options]=\"options\"\r\n placeholder=\"Home Address\" required #address=\"ngModel\"\r\n [invalid]=\"address.invalid && (address.dirty || address.touched)\"\r\n [initialLat]=\"tempProfile.latitude\" [initialLng]=\"tempProfile.longitude\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"\r\n (manualEdit)=\"onUserAddressManualEdit()\"></im-address-verify-field>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"address.invalid && (address.dirty || address.touched)\">Home\r\n address is required</div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.city\" name=\"city\" placeholder=\"City\"\r\n required #city=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"city.invalid && (city.dirty || city.touched)\">City is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.state\" name=\"state\" placeholder=\"State\"\r\n required #state=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"state.invalid && (state.dirty || state.touched)\">State is\r\n required</div>\r\n </div>\r\n\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"tempProfile.zipCode\"\r\n (ngModelChange)=\"tempProfile.zipCode = sanitizeZipCode($event)\" name=\"zipCode\" placeholder=\"Zip Code\"\r\n required pattern=\"^\\d{1,6}$\" maxlength=\"6\" inputmode=\"numeric\" #zipCode=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"zipCode.invalid && (zipCode.dirty || zipCode.touched)\">Zip code\r\n is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"zipCode.errors?.['pattern'] && (zipCode.dirty || zipCode.touched)\">\r\n Zip code must be up to 6 digits\r\n </div>\r\n </div>\r\n <div class=\"col-md-2\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"tempProfile.country\" name=\"country\"\r\n placeholder=\"Country\" required #country=\"ngModel\">\r\n <div class=\"small text-danger mt-1\" *ngIf=\"country.invalid && (country.dirty || country.touched)\">Country\r\n is required</div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Summary</label>\r\n <textarea class=\"form-control\" rows=\"3\" [(ngModel)]=\"tempProfile.summary\" name=\"sum\"\r\n placeholder=\"Summary\"></textarea>\r\n </div>\r\n\r\n\r\n </form>\r\n </div>\r\n <div class=\"card-footer text-end gap-2 d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancel()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingBasic || !isBasicFormValid\" (click)=\"save()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Saving...' : 'Save Changes' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5 provider-company-first\" *ngIf=\"roleData?.role?.name === 'Provider' && hasUserDetailData && !isResume\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/building.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Company Details</h5>\r\n <span *ngIf=\"companyDetailsSaved\"\r\n class=\"badge border section-flag bg-success-subtle text-success\">\r\n Saved\r\n </span>\r\n <span *ngIf=\"!companyDetailsSaved\"\r\n class=\"badge border section-flag bg-warning-subtle text-warning\">\r\n Not saved yet\r\n </span>\r\n </div>\r\n <button class=\"btn btn-sm btn-primary px-4\" (click)=\"toggleCompanyEdit()\">Edit</button>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"!isCompanyEditMode()\">\r\n <div class=\"card-body p-4\">\r\n <div class=\"row g-4\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name</label>\r\n <span class=\"fw-bold small\">{{ companyDetails()?.companyName}}</span>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone</label>\r\n <span class=\"fw-bold small\">{{ companyDetails()?.companyPhoneNumber}}</span>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Company Address</label>\r\n <span class=\"small\">{{ companyDetails()?.address1}}, {{ companyDetails()?.city}}, {{ companyDetails()?.state}}, {{ companyDetails()?.zipcode}}, {{ companyDetails()?.country}}</span>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"companyLogoUrl()\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <img [src]=\"companyLogoUrl()\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card shadow-sm border-0\" *ngIf=\"isCompanyEditMode()\">\r\n <div class=\"card-header bg-white fw-bold\">Update Company Details</div>\r\n <div class=\"card-body p-4\">\r\n <form class=\"row g-3\" #companyForm=\"ngForm\" novalidate>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': (!tempCompanyDetails.companyName?.trim() && companyFormSubmitted) || companyNameError }\"\r\n [(ngModel)]=\"tempCompanyDetails.companyName\" name=\"companyName\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyName?.trim() && companyFormSubmitted\">\r\n Company name is required\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"companyNameError\">\r\n {{ companyNameError }}\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Phone <span class=\"text-danger\">*</span></label>\r\n <input (input)=\"phoneMask($event, 'company')\" type=\"text\" maxlength=\"14\" (keypress)=\"allowOnlyNumbers($event)\" inputmode=\"numeric\" class=\"form-control form-control-sm\"\r\n [ngClass]=\"{ 'is-invalid': companyFormSubmitted && (!tempCompanyDetails.companyPhoneNumber?.trim() || getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10) }\"\r\n [(ngModel)]=\"tempCompanyDetails.companyPhoneNumber\" name=\"companyPhoneNumber\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.companyPhoneNumber?.trim() && companyFormSubmitted\">\r\n Company phone is required\r\n </div>\r\n <div class=\"invalid-feedback\" *ngIf=\"tempCompanyDetails.companyPhoneNumber?.trim() && getDigitCount(tempCompanyDetails.companyPhoneNumber) !== 10 && companyFormSubmitted\">\r\n Company phone must be 10 digits\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Address <span class=\"text-danger\">*</span></label>\r\n <im-address-verify-field [(ngModel)]=\"tempCompanyDetails.address1\" name=\"address1\" [options]=\"options\"\r\n required [invalid]=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\"\r\n [initialLat]=\"tempCompanyDetails.latitude\" [initialLng]=\"tempCompanyDetails.longitude\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"\r\n (manualEdit)=\"onCompanyAddressManualEdit()\"></im-address-verify-field>\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.address1?.trim() && companyFormSubmitted\">\r\n Address is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.city?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.city\" name=\"city\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.city?.trim() && companyFormSubmitted\">\r\n City is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.state?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.state\" name=\"state\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.state?.trim() && companyFormSubmitted\">\r\n State is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Zip Code <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.zipcode?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.zipcode\" name=\"zipcode\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.zipcode?.trim() && companyFormSubmitted\">\r\n Zip code is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" \r\n [ngClass]=\"{ 'is-invalid': !tempCompanyDetails.country?.trim() && companyFormSubmitted }\"\r\n [(ngModel)]=\"tempCompanyDetails.country\" name=\"country\" required />\r\n <div class=\"invalid-feedback\" *ngIf=\"!tempCompanyDetails.country?.trim() && companyFormSubmitted\">\r\n Country is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company Logo</label>\r\n <input #uploadCompanyFile type=\"file\" accept=\".png,.jpg,.jpeg\" (change)=\"uploadCompanyImage($event)\" class=\"form-control\" />\r\n <small class=\"text-muted d-block mt-1\" style=\"font-size: 12px;\">Allowed formats: PNG, JPG, JPEG</small>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"tempCompanyLogoUrl\">\r\n <label class=\"small text-muted d-block\">Logo Preview</label>\r\n <img [src]=\"tempCompanyLogoUrl\" class=\"img-thumbnail\" style=\"max-height: 80px;\" />\r\n </div>\r\n </form>\r\n </div>\r\n <div class=\"card-footer text-end gap-2 d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelCompanyEdit()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCompany\" \r\n (click)=\"saveCompanyDetails()\">\r\n <span *ngIf=\"isSavingCompany\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCompany ? 'Saving...' : 'Save Changes' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div [class.section-locked]=\"roleData?.role?.name === 'Provider' && !hasUserDetailData\">\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/briefcase-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Profession</h5>\r\n <span *ngIf=\"selectedProfessionCount > 0\" class=\"badge border section-flag bg-warning-subtle text-warning\">\r\n {{ selectedProfessionCount }} selected\r\n </span>\r\n </div>\r\n <button type=\"button\" class=\"btn btn-sm btn-primary px-4\"\r\n [disabled]=\"selectedProfessionCount === 0 || isSavingProfessionsTable\"\r\n (click)=\"submitProfessions()\">\r\n <span *ngIf=\"isSavingProfessionsTable\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingProfessionsTable ? 'Saving...' : professionSubmitLabel }}\r\n </button>\r\n </div>\r\n\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Search / Create the Profession(s)</label>\r\n <input type=\"text\" class=\"form-control\" placeholder=\"Search Profession\"\r\n [(ngModel)]=\"professionSearchQry\" name=\"professionSearchQry\"\r\n (keydown.enter)=\"createManualProfessionRow()\" />\r\n </div>\r\n\r\n <div class=\"table-responsive bg-white border rounded shadow-sm\">\r\n <table class=\"table align-middle mb-0 profession-table\">\r\n <thead>\r\n <tr>\r\n <th style=\"width: 36px;\"></th>\r\n <th>Profession Name</th>\r\n <th>Group</th>\r\n <th>Type</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let p of filteredProfessionTypes\">\r\n <tr [class.profession-row-selected]=\"getProfessionSelection(p.id).selected\">\r\n <td>\r\n <input type=\"checkbox\" class=\"form-check-input\" [checked]=\"getProfessionSelection(p.id).selected\"\r\n (change)=\"onProfessionRowCheck(p, $event)\" />\r\n </td>\r\n <td>\r\n {{ p.professionName }}\r\n <span *ngIf=\"isProfessionSaved(p.id)\" class=\"badge border bg-success-subtle text-success ms-1\">Saved</span>\r\n </td>\r\n <td>{{ p.professionGroup || '\u2013' }}</td>\r\n <td>{{ p.residentialCommercial || '\u2013' }}</td>\r\n </tr>\r\n <tr *ngIf=\"getProfessionSelection(p.id).selected\" class=\"profession-row-selected\">\r\n <td></td>\r\n <td colspan=\"3\">\r\n <div class=\"d-flex flex-wrap align-items-start gap-4 py-2\">\r\n <div class=\"flex-shrink-0\" style=\"white-space: nowrap;\">\r\n <label class=\"small text-muted d-block mb-1\">Self Ability Rating</label>\r\n <span *ngFor=\"let s of [1,2,3,4,5]\" class=\"fs-5\" style=\"cursor: pointer;\"\r\n (click)=\"setProfessionRowStars(p, s)\"\r\n [class.text-warning]=\"(getProfessionSelection(p.id).starRating || 0) / 2 >= s\"\r\n [class.text-muted]=\"(getProfessionSelection(p.id).starRating || 0) / 2 < s\">\u2605</span>\r\n </div>\r\n <div class=\"flex-shrink-0\" style=\"white-space: nowrap;\">\r\n <label class=\"small text-muted d-block mb-1\">Experience</label>\r\n <div class=\"d-flex align-items-center gap-1\">\r\n <input type=\"number\" class=\"form-control form-control-sm\" style=\"width: 70px;\" min=\"0\" max=\"30\"\r\n [(ngModel)]=\"getProfessionSelection(p.id).year\" [name]=\"'profYear-' + p.id\" />\r\n <span class=\"small text-muted\">Yrs</span>\r\n </div>\r\n </div>\r\n <div class=\"d-flex flex-column align-items-center flex-shrink-0\" style=\"min-width: 80px; white-space: nowrap;\">\r\n <label class=\"small text-muted d-block mb-1\">Visibility</label>\r\n <input type=\"checkbox\" class=\"profession-visibility-checkbox\" [(ngModel)]=\"getProfessionSelection(p.id).profileVisibility\"\r\n [name]=\"'profVis-' + p.id\" />\r\n </div>\r\n <div class=\"flex-grow-1\" style=\"min-width: 200px;\">\r\n <label class=\"small text-muted d-block mb-1\">Notes</label>\r\n <textarea rows=\"3\" class=\"form-control form-control-sm profession-notes-input\" [(ngModel)]=\"getProfessionSelection(p.id).notes\"\r\n [name]=\"'profNotes-' + p.id\" placeholder=\"Notes\"></textarea>\r\n </div>\r\n </div>\r\n </td>\r\n </tr>\r\n </ng-container>\r\n <tr *ngIf=\"filteredProfessionTypes.length === 0\">\r\n <td colspan=\"4\" class=\"text-center text-muted small py-3\">No professions found.</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/briefcase-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Work Experience</h5>\r\n <span *ngIf=\"experience().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"workSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ workSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"experience().length === 0 || !workSectionHasUnsavedItems() || isSavingWork || isAddingJob() || editingJobIndex() !== null\"\r\n (click)=\"confirmAllWork()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add work experience\" (click)=\"addJob()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"experience().length === 0 && !isAddingJob()\" class=\"empty-state-wrap mb-3\" role=\"button\"\r\n (click)=\"addJob()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/briefcase.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No work experience added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3\">\r\n <div *ngIf=\"isAddingJob() && tempJob()\" class=\"list-group-item p-0 border-0\">\r\n <div class=\"form-panel mb-2\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\" name=\"newJobTitle\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\" name=\"newCompany\" />\r\n </div>\r\n <div class=\"align-items-end col-md-12 d-flex justify-content-end pe-3\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\" name=\"newIsCurrent\" id=\"newIsCurrent\" />\r\n <label class=\"form-check-label\" for=\"newIsCurrent\">Current</label>\r\n </div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.country\"\r\n (ngModelChange)=\"patchTempJob({ country: $event })\" name=\"newCountry\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.state\"\r\n (ngModelChange)=\"patchTempJob({ state: $event })\" name=\"newState\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\" name=\"newCity\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempJob()?.startDate)\"\r\n (bsValueChange)=\"setTempJobMonth('startDate', $event)\" name=\"newStartDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.startDate)\">Start date is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"monthInputToDate(tempJob()?.endDate)\" (bsValueChange)=\"setTempJobMonth('endDate', $event)\"\r\n name=\"newEndDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">End date is\r\n required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isMonthRangeInvalid(tempJob()?.startDate, tempJob()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Responsibilities (one per line)</label>\r\n <textarea rows=\"4\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\" name=\"newResponsibilities\"></textarea>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\" name=\"newWorkAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempJob()?.fileName\">\r\n <span>{{ tempJob()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempJob())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n <div class=\"d-flex justify-content-end gap-2 mt-3\">\r\n <button class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingWork\"\r\n (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : workActionLabel(editingJobIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n\r\n <div *ngFor=\"let job of experience(); let i = index\" class=\"list-group-item p-0 border-0 mb-2\">\r\n\r\n <div class=\"work-accent-item p-3 rounded-3 bg-white border\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div class=\"d-flex align-items-center cursor-pointer flex-grow-1\" (click)=\"toggleJob(i)\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h6 class=\"mb-0 fw-bold item-title-sm\">{{ job.jobTitle }}</h6>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedWorkItem(i) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedWorkItem(i) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ job.company || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ formatMonthYear(job.startDate) }} - {{ job.isCurrent ? 'Present' :\r\n formatMonthYear(job.endDate) }}</span>\r\n <span class=\"item-meta-line\">{{ job.city }}<span *ngIf=\"job.city && job.state\">, </span>{{ job.state }}<ng-container *ngIf=\"!job.city && !job.state\">\u2014</ng-container></span>\r\n <div *ngIf=\"editingJobIndex() !== i && (workIssuesByIndex()[i] || []).length > 0\"\r\n class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (workIssuesByIndex()[i] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center gap-2\">\r\n\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\" (click)=\"startEditJob(i)\"\r\n title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteJob(i);\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n \r\n </div>\r\n </div>\r\n\r\n\r\n\r\n <div class=\"mt-3 p-3 rounded small\" *ngIf=\"expandedIndex() === i\">\r\n <ng-container *ngIf=\"editingJobIndex() !== i; else editJobForm\">\r\n <ul class=\"mb-0\">\r\n <li *ngFor=\"let res of job.responsibilities\">{{ res }}</li>\r\n </ul>\r\n </ng-container>\r\n\r\n <ng-template #editJobForm>\r\n <div *ngIf=\"(workIssuesByIndex()[i] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (workIssuesByIndex()[i] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Job Title <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.jobTitle\"\r\n (ngModelChange)=\"patchTempJob({ jobTitle: $event })\" name=\"jobTitle{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.jobTitle)\">Job title is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Company <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.company\"\r\n (ngModelChange)=\"patchTempJob({ company: $event })\" name=\"company{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.company)\">Company name is required</div>\r\n </div>\r\n\r\n <div class=\"align-items-end col-md-12 d-flex justify-content-end pe-3\">\r\n <div class=\"form-check\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"tempJob()?.isCurrent\"\r\n (ngModelChange)=\"setTempJobIsCurrent($event)\" name=\"isCurrent{{ i }}\" id=\"isCurrent{{ i }}\" />\r\n <label class=\"form-check-label\" for=\"isCurrent{{ i }}\">Current</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.country\"\r\n (ngModelChange)=\"patchTempJob({ country: $event })\" name=\"country{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.state\"\r\n (ngModelChange)=\"patchTempJob({ state: $event })\" name=\"state{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempJob()?.city\"\r\n (ngModelChange)=\"patchTempJob({ city: $event })\" name=\"city{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.city)\">City is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempJob()?.startDate)\"\r\n (bsValueChange)=\"setTempJobMonth('startDate', $event)\" name=\"startDate{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempJob()?.startDate)\">Start date is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [disabled]=\"tempJob()?.isCurrent\"\r\n [ngModel]=\"monthInputToDate(tempJob()?.endDate)\" (bsValueChange)=\"setTempJobMonth('endDate', $event)\"\r\n name=\"endDate{{ i }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"!tempJob()?.isCurrent && isBlank(tempJob()?.endDate)\">\r\n End date is required\r\n </div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"!tempJob()?.isCurrent && isMonthRangeInvalid(tempJob()?.startDate, tempJob()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Responsibilities (one per line)</label>\r\n <textarea rows=\"4\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"(tempJob()?.responsibilities || []).join('\\n')\"\r\n (ngModelChange)=\"updateTempResponsibilities($event)\" name=\"responsibilities{{ i }}\"></textarea>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onWorkExperienceFileSelected($event)\" name=\"workAttachment{{ i }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempJob()?.fileName\">\r\n <span>{{ tempJob()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempJob())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n </ng-template>\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-3\" *ngIf=\"editingJobIndex() === i\">\r\n <button class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditJob(); $event.stopPropagation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4 \" [disabled]=\"isSavingWork\"\r\n (click)=\"saveEditJob(); $event.stopPropagation()\">\r\n <span *ngIf=\"isSavingWork\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingWork ? 'Uploading...' : workActionLabel(editingJobIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/patch-check-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Certifications</h5>\r\n <span *ngIf=\"certs().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"certificationSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ certificationSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"certs().length === 0 || !certificationSectionHasUnsavedItems() || isSavingCertification || isAddingCertification() || editingCertificationIndex() !== null\"\r\n (click)=\"confirmAllCertifications()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add certification\" (click)=\"addCertification()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"certs().length === 0 && !isAddingCertification() && editingCertificationIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addCertification()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/patch-check.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No certifications added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3 border\">\r\n <div *ngIf=\"isAddingCertification() && tempCertification()\" class=\"list-group-item py-3 px-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Profession Type</label>\r\n <ng-select [items]=\"userProfessionOptions\" bindLabel=\"professionName\" bindValue=\"professionId\"\r\n [ngModel]=\"tempCertification()?.professionId\" (change)=\"onCertificationProfessionChange($event)\"\r\n name=\"newCertProfessionType\" placeholder=\"Select or search profession type\" [clearable]=\"true\">\r\n </ng-select>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\" name=\"newCertName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\" name=\"newCertOrg\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\" name=\"newCertState\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certification Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\" name=\"newCertCredentialId\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('issueDate', $event)\" name=\"newCertIssueDate\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('expiryDate', $event)\" name=\"newCertExpiryDate\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempCertification()?.issueDate || null, tempCertification()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\" name=\"newCertAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempCertification()?.fileName\">\r\n <span>{{ tempCertification()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempCertification())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\"\r\n [disabled]=\"isSavingCertification\"\r\n (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : certificationActionLabel(editingCertificationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let cert of certs(); let ci = index\" class=\"list-group-item py-3 cert-accent-item\">\r\n <ng-container *ngIf=\"editingCertificationIndex() !== ci; else editCert\">\r\n <div class=\"d-flex justify-content-between align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <div class=\"fw-semibold item-title-sm\">{{ cert.name }}</div>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedCertificationItem(ci) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedCertificationItem(ci) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ cert.issuingOrganization || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.credentialId || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.issueDate ? formatMonthYear(cert.issueDate) : '\u2014' }} - {{ cert.expiryDate ? formatMonthYear(cert.expiryDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ cert.state || '\u2014' }}</span>\r\n <div *ngIf=\"(certIssuesByIndex()[ci] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (certIssuesByIndex()[ci] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditCertification(ci)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\"\r\n (click)=\"deleteCertification(ci)\" title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #editCert>\r\n <div *ngIf=\"(certIssuesByIndex()[ci] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (certIssuesByIndex()[ci] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Profession Type</label>\r\n <ng-select [items]=\"userProfessionOptions\" bindLabel=\"professionName\" bindValue=\"professionId\"\r\n [ngModel]=\"tempCertification()?.professionId\" (change)=\"onCertificationProfessionChange($event)\"\r\n name=\"certProfessionType{{ ci }}\" placeholder=\"Select or search profession type\" [clearable]=\"true\">\r\n </ng-select>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.name\"\r\n (ngModelChange)=\"patchTempCertification({ name: $event })\" name=\"certName{{ ci }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempCertification()?.name)\">Certificate name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certificate Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.issuingOrganization || ''\"\r\n (ngModelChange)=\"patchTempCertification({ issuingOrganization: $event || null })\"\r\n name=\"certOrg{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempCertification()?.state || ''\"\r\n (ngModelChange)=\"patchTempCertification({ state: $event || null })\" name=\"certState{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Certification Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\"\r\n [ngModel]=\"tempCertification()?.credentialId || ''\"\r\n (ngModelChange)=\"patchTempCertification({ credentialId: $event || null })\"\r\n name=\"certCredentialId{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('issueDate', $event)\" name=\"certIssue{{ ci }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempCertification()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempCertificationMonth('expiryDate', $event)\" name=\"certExpiry{{ ci }}\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempCertification()?.issueDate || null, tempCertification()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Certification File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onCertificationFileSelected($event)\" name=\"certAttachment{{ ci }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempCertification()?.fileName\">\r\n <span>{{ tempCertification()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempCertification())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditCertification()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingCertification\"\r\n (click)=\"saveCertificationEditor()\">\r\n <span *ngIf=\"isSavingCertification\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingCertification ? 'Uploading...' : certificationActionLabel(editingCertificationIndex()) }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/card-checklist-warning.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Licenses</h5>\r\n <span *ngIf=\"licenses().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"licenseSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ licenseSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"licenses().length === 0 || !licenseSectionHasUnsavedItems() || isSavingLicense || isAddingLicense() || editingLicenseIndex() !== null\"\r\n (click)=\"confirmAllLicenses()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add license\" (click)=\"addLicense()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"licenses().length === 0 && !isAddingLicense() && editingLicenseIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addLicense()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/card-checklist.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No licenses added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div class=\"list-group list-group-flush shadow-sm rounded-3 border\">\r\n <div *ngIf=\"isAddingLicense() && tempLicense()\" class=\"list-group-item py-3 px-3\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\" name=\"newLicName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempLicense()?.name)\">License name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\" name=\"newLicAuthority\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\" name=\"newLicNumber\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\" name=\"newLicState\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('issueDate', $event)\" name=\"newLicIssueDate\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('expiryDate', $event)\" name=\"newLicExpiryDate\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempLicense()?.issueDate || null, tempLicense()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">License File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\" name=\"newLicenseAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempLicense()?.fileName\">\r\n <span>{{ tempLicense()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempLicense())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelEditLicense()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingLicense\"\r\n (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : licenseActionLabel(editingLicenseIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let lic of licenses(); let li = index\" class=\"list-group-item py-3 lic-accent-item\">\r\n <ng-container *ngIf=\"editingLicenseIndex() !== li; else editLic\">\r\n <div class=\"d-flex justify-content-between align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <div class=\"fw-semibold item-title-sm\">{{ lic.name }}</div>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedLicenseItem(li) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedLicenseItem(li) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ lic.issuingAuthority || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.licenseNumber || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.issueDate ? formatMonthYear(lic.issueDate) : '\u2014' }} - {{ lic.expiryDate ? formatMonthYear(lic.expiryDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ lic.state || '\u2014' }}</span>\r\n <div *ngIf=\"(licenseIssuesByIndex()[li] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (licenseIssuesByIndex()[li] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditLicense(li)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteLicense(li)\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #editLic>\r\n <div *ngIf=\"(licenseIssuesByIndex()[li] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (licenseIssuesByIndex()[li] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.name\"\r\n (ngModelChange)=\"patchTempLicense({ name: $event })\" name=\"licName{{ li }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempLicense()?.name)\">License name is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Issued By</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.issuingAuthority || ''\"\r\n (ngModelChange)=\"patchTempLicense({ issuingAuthority: $event || null })\" name=\"licAuthority{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">License Number</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.licenseNumber || ''\"\r\n (ngModelChange)=\"patchTempLicense({ licenseNumber: $event || null })\" name=\"licNumber{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issued State</label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempLicense()?.state || ''\"\r\n (ngModelChange)=\"patchTempLicense({ state: $event || null })\" name=\"licState{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Issue Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.issueDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('issueDate', $event)\" name=\"licIssue{{ li }}\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Expiry Date</label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempLicense()?.expiryDate || null)\"\r\n (bsValueChange)=\"setTempLicenseMonth('expiryDate', $event)\" name=\"licExpiry{{ li }}\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempLicense()?.issueDate || null, tempLicense()?.expiryDate || null)\">\r\n Issued date must be less than expiry date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">License File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onLicenseFileSelected($event)\" name=\"licenseAttachment{{ li }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempLicense()?.fileName\">\r\n <span>{{ tempLicense()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempLicense())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditLicense()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingLicense\"\r\n (click)=\"saveLicenseEditor()\">\r\n <span *ngIf=\"isSavingLicense\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingLicense ? 'Uploading...' : licenseActionLabel(editingLicenseIndex()) }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section mb-5\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/tools.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Tools</h5>\r\n <span *ngIf=\"tools().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"toolsSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ toolsSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"tools().length === 0 || !toolsSectionHasUnsavedItems() || isSavingTool || isToolEditorOpen()\" (click)=\"confirmAllTools()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add tool\" (click)=\"addTool()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex flex-wrap gap-2 p-3 bg-white border rounded shadow-sm\">\r\n <div *ngFor=\"let tool of tools(); let ti = index\" class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\"\r\n class=\"btn btn-light border res-flex d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openToolEditor(ti)\" title=\"Edit\">\r\n <span class=\"fw-normal item-name-text\">{{ tool }}</span>\r\n <span class=\"badge border ms-1\"\r\n [ngClass]=\"hasUnsavedToolItem(ti) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedToolItem(ti) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n <span *ngIf=\"(toolIssuesByIndex()[ti] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\">\r\n Missing info\r\n </span>\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Delete tool\" (click)=\"deleteTool(ti)\">\r\n <span class=\"fw-bold\">\u00D7</span>\r\n </button>\r\n </div>\r\n\r\n <span *ngIf=\"tools().length === 0\" class=\"text-muted small\">No tools added.</span>\r\n </div>\r\n\r\n <div *ngIf=\"isToolEditorOpen()\" class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 9999999;\" (click)=\"closeToolEditor()\">\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\"\r\n (click)=\"$event.stopPropagation()\">\r\n <div class=\"card shadow border-0 w-100\" style=\"max-width: 900px;\">\r\n <div class=\"card-header bg-white d-flex align-items-center gap-3\">\r\n <button type=\"button\" class=\"btn btn-link p-0 text-decoration-none\" (click)=\"closeToolEditor()\">\r\n <img src=\"/assets/images/icons/arrow-left-blue.svg\" width=\"20\" height=\"20\" alt=\"\" />\r\n </button>\r\n <div class=\"fw-bold\">{{ isAddingTool() ? 'Add Tool' : ('Edit ' + (toolForm()?.name || '') + ' Tool') }}\r\n </div>\r\n </div>\r\n <div class=\"card-body p-4\">\r\n <div *ngIf=\"toolFormIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ toolFormIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"row g-3\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Profession Type</label>\r\n <ng-select [items]=\"userProfessionOptions\" bindLabel=\"professionName\" bindValue=\"professionId\"\r\n [ngModel]=\"toolForm()?.professionId\" (change)=\"onToolProfessionChange($event)\"\r\n name=\"toolProfessionType\" placeholder=\"Select or search profession type\" [clearable]=\"true\">\r\n </ng-select>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Tool Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"toolForm()?.name\"\r\n (ngModelChange)=\"patchToolForm({ name: $event })\" name=\"toolName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(toolForm()?.name)\">Tool name is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span\r\n class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempToolStars(s)\" [attr.aria-label]=\"'Set rating ' + s\">\r\n <span [class]=\"(toolForm()?.stars || 0) >= s ? 'text-warning fs-5' : 'text-muted fs-5'\">\r\n {{ (toolForm()?.stars || 0) >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ toolForm()?.stars || 0 }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"(toolForm()?.stars || 0) <= 0\">Star rating is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngModel]=\"toolForm()?.year\"\r\n (ngModelChange)=\"patchToolForm({ year: $event === '' ? null : +$event })\" name=\"toolYear\" min=\"1\"\r\n max=\"30\" placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"toolForm()?.year === null || toolForm()?.year === undefined\">\r\n Years of experience is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4 text-center\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-checks form-switch mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"toolForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchToolForm({ profileVisibility: $event })\" name=\"toolVisible\" id=\"toolVisible\"\r\n style=\"width: 55px;height: 25px;margin-left: -57px;\" />\r\n <label class=\"form-check-label ps-2 pt-1\" for=\"toolVisible\">Visible</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Comment</label>\r\n <textarea rows=\"4\" class=\"form-control\" [ngModel]=\"toolForm()?.notes\"\r\n (ngModelChange)=\"patchToolForm({ notes: $event })\" name=\"toolNotes\"\r\n placeholder=\"Enter additional details (optional)\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-white d-flex justify-content-end gap-2\">\r\n <button *ngIf=\"!isAddingTool() && editingToolIndex() !== null\" type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\" (click)=\"deleteTool(editingToolIndex()!)\">\r\n Delete\r\n </button>\r\n <button type=\"button\" class=\"btn btn-link text-secondary\" (click)=\"closeToolEditor()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary px-4\" [disabled]=\"isSavingTool\" (click)=\"saveToolEditor()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Saving...' : toolActionLabel(editingToolIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row g-4 mb-5\">\r\n <div class=\"col-md-12\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/stars.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Skills</h5>\r\n <span *ngIf=\"skills().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"skillsSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ skillsSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"skills().length === 0 || !skillsSectionHasUnsavedItems() || isSavingSkill || isSkillEditorOpen()\" (click)=\"confirmAllSkills()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add skill\" (click)=\"addSkill()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex flex-wrap gap-2 p-3 bg-white border rounded shadow-sm\">\r\n <div *ngFor=\"let skill of skills(); let si = index\" class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\"\r\n class=\"btn btn-light border res-flex d-inline-flex align-items-center gap-2 px-3 py-2\"\r\n (click)=\"openSkillEditor(si)\" title=\"Edit\">\r\n <span class=\"fw-normal item-name-text\">{{ skill }}</span>\r\n <span class=\"badge border ms-1\"\r\n [ngClass]=\"hasUnsavedSkillItem(si) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedSkillItem(si) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n <span *ngIf=\"(skillIssuesByIndex()[si] || []).length > 0\"\r\n class=\"badge bg-warning-subtle text-warning border ms-1\">\r\n Missing info\r\n </span>\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-danger rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Delete skill\"\r\n (click)=\"deleteSkill(si); $event.stopPropagation()\">\r\n <span class=\"fw-bold\">\u00D7</span>\r\n </button>\r\n </div>\r\n\r\n <span *ngIf=\"skills().length === 0\" class=\"text-muted small\">No skills added.</span>\r\n </div>\r\n <div *ngIf=\"isSkillEditorOpen()\" class=\"position-fixed top-0 start-0 w-100 h-100\"\r\n style=\"background: rgba(0,0,0,0.35); z-index: 9999999;\" (click)=\"closeSkillEditor()\">\r\n <div class=\"container h-100 d-flex align-items-start justify-content-center pt-4\"\r\n (click)=\"$event.stopPropagation()\">\r\n <div class=\"card shadow border-0 w-100\" style=\"max-width: 900px;\">\r\n <div class=\"card-header bg-white d-flex align-items-center gap-3\">\r\n <button type=\"button\" class=\"btn btn-link p-0 text-decoration-none\" (click)=\"closeSkillEditor()\">\r\n <img src=\"/assets/images/icons/arrow-left-blue.svg\" width=\"20\" height=\"20\" alt=\"\" />\r\n </button>\r\n <div class=\"fw-bold\">{{ isAddingSkill() ? 'Add Skill' : ('Edit ' + (skillForm()?.name || '') + ' Skill')\r\n }}</div>\r\n </div>\r\n <div class=\"card-body p-4\">\r\n <div *ngIf=\"skillFormIssues().length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ skillFormIssues().join(' \u2022 ') }}</div>\r\n </div>\r\n <div class=\"row g-3\">\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Profession Type</label>\r\n <ng-select [items]=\"userProfessionOptions\" bindLabel=\"professionName\" bindValue=\"professionId\"\r\n [ngModel]=\"skillForm()?.professionId\" (change)=\"onSkillProfessionChange($event)\"\r\n name=\"skillProfessionType\" placeholder=\"Select or search profession type\" [clearable]=\"true\">\r\n </ng-select>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Skills Name <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control\" [ngModel]=\"skillForm()?.name\"\r\n (ngModelChange)=\"patchSkillForm({ name: $event })\" name=\"skillName\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(skillForm()?.name)\">Skillset name is required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span\r\n class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"setTempSkillStars(s)\" [attr.aria-label]=\"'Set rating ' + s\">\r\n <span [class]=\"(skillForm()?.stars || 0) >= s ? 'text-warning fs-5' : 'text-muted fs-5'\">\r\n {{ (skillForm()?.stars || 0) >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ skillForm()?.stars || 0 }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"(skillForm()?.stars || 0) <= 0\">Star rating is required\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [ngModel]=\"skillForm()?.year\"\r\n (ngModelChange)=\"patchSkillForm({ year: $event === '' ? null : +$event })\" name=\"skillYear\" min=\"1\"\r\n max=\"30\" placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"skillForm()?.year === null || skillForm()?.year === undefined\">Years of experience is\r\n required</div>\r\n </div>\r\n\r\n <div class=\"col-md-4 text-center\">\r\n <label class=\"small text-muted d-block\">Profile Visibility</label>\r\n <div class=\"form-checks form-switch mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" [ngModel]=\"skillForm()?.profileVisibility\"\r\n (ngModelChange)=\"patchSkillForm({ profileVisibility: $event })\" name=\"skillVisible\"\r\n id=\"skillVisible\" style=\"width: 55px;height: 25px;margin-left: -57px;\" />\r\n <label class=\"form-check-label ps-2 pt-1\" for=\"skillVisible\">Visible</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Comment</label>\r\n <textarea rows=\"4\" class=\"form-control\" [ngModel]=\"skillForm()?.notes\"\r\n (ngModelChange)=\"patchSkillForm({ notes: $event })\" name=\"skillNotes\"\r\n placeholder=\"Enter additional details (optional)\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"card-footer bg-white d-flex justify-content-end gap-2\">\r\n <button *ngIf=\"!isAddingSkill() && editingSkillIndex() !== null\" type=\"button\"\r\n class=\"btn btn-link text-danger me-auto\" (click)=\"deleteSkill(editingSkillIndex()!)\">\r\n Delete\r\n </button>\r\n <button type=\"button\" class=\"btn btn-link text-secondary\" (click)=\"closeSkillEditor()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary px-4\" [disabled]=\"isSavingSkill\" (click)=\"saveSkillEditor()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Saving...' : skillActionLabel(editingSkillIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row g-4 mb-5\">\r\n <div class=\"col-md-12\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3 section-header-row\">\r\n <div class=\"d-flex align-items-center gap-2 section-header-title\">\r\n <img src=\"/assets/images/icons/mortarboard-fill.svg\" width=\"20\" height=\"20\" class=\"section-header-icon\" alt=\"\" />\r\n <h5 class=\"fw-bold mb-0\">Education</h5>\r\n <span *ngIf=\"educationList().length > 0\" class=\"badge border section-flag\"\r\n [ngClass]=\"educationSectionHasUnsavedItems() ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ educationSectionHasUnsavedItems() ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-success\"\r\n [disabled]=\"educationList().length === 0 || !educationSectionHasUnsavedItems() || isSavingEducation || isAddingEducation() || editingEducationIndex() !== null\"\r\n (click)=\"confirmAllEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Confirming...' : 'Confirm All' }}\r\n </button>\r\n <button type=\"button\"\r\n class=\"btn btn-sm btn-outline-primary rounded-circle d-inline-flex align-items-center justify-content-center\"\r\n style=\"width: 32px; height: 32px; line-height: 1;\" title=\"Add education\" (click)=\"addEducation()\">\r\n <span class=\"fw-bold fs-5\">+</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"educationList().length === 0 && !isAddingEducation() && editingEducationIndex() === null\"\r\n class=\"empty-state-wrap mb-3\" role=\"button\" (click)=\"addEducation()\">\r\n <div class=\"empty-icon\"><img src=\"/assets/images/icons/mortarboard.svg\" width=\"32\" height=\"32\" alt=\"\" /></div>\r\n <p>No education added yet. Click <strong>+</strong> to add one.</p>\r\n </div>\r\n\r\n <div *ngIf=\"isAddingEducation() && tempEducation()\" class=\"mb-2\">\r\n <div class=\"form-panel\">\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\" name=\"newEduDegree\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Institution <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\" name=\"newEduInstitution\" />\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree / Course Type <span class=\"text-danger\">*</span></label>\r\n <ng-select class=\"ng-select-sm\" [items]=\"educationDegreeTypeOptions\" [clearable]=\"false\"\r\n placeholder=\"Select degree / course type\" [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\" name=\"newEduDegreeType\">\r\n </ng-select>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.country\"\r\n (ngModelChange)=\"patchTempEducation({ country: $event })\" name=\"newEduCountry\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.state\"\r\n (ngModelChange)=\"patchTempEducation({ state: $event })\" name=\"newEduState\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\" name=\"newEduCity\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.startDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('startDate', $event)\" name=\"newEduStartDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.startDate)\">Start date is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.endDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('endDate', $event)\" name=\"newEduEndDate\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Education File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onEducationFileSelected($event)\" name=\"newEducationAttachment\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempEducation()?.fileName\">\r\n <span>{{ tempEducation()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempEducation())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-link text-secondary\"\r\n (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingEducation\"\r\n (click)=\"saveEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Uploading...' : educationActionLabel(editingEducationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngFor=\"let edu of educationList(); let ei = index\" class=\"edu-accent-item p-3 bg-white border rounded-3 shadow-sm mb-2\">\r\n <div class=\"d-flex justify-content-between align-items-start\">\r\n <div class=\"d-flex align-items-start gap-3\">\r\n <div>\r\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\r\n <h6 class=\"fw-bold mb-0 item-title-sm\">{{ edu.degree }}</h6>\r\n <span class=\"badge border\"\r\n [ngClass]=\"hasUnsavedEducationItem(ei) ? 'bg-warning-subtle text-warning' : 'bg-success-subtle text-success'\">\r\n {{ hasUnsavedEducationItem(ei) ? 'Not saved yet' : 'Saved' }}\r\n </span>\r\n </div>\r\n <span class=\"item-meta-line\">{{ edu.institution || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.degreeType || '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.startDate ? formatMonthYear(edu.startDate) : '\u2014' }} - {{ edu.endDate ? formatMonthYear(edu.endDate) : '\u2014' }}</span>\r\n <span class=\"item-meta-line\">{{ edu.city }}<span *ngIf=\"edu.city && edu.state\">, </span>{{ edu.state }}<ng-container *ngIf=\"!edu.city && !edu.state\">\u2014</ng-container></span>\r\n <div *ngIf=\"(educationIssuesByIndex()[ei] || []).length > 0\" class=\"alert alert-warning py-1 px-2 mt-2\">\r\n <div class=\"fw-semibold small\">Missing required fields</div>\r\n <div class=\"small\">{{ (educationIssuesByIndex()[ei] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\" *ngIf=\"editingEducationIndex() !== ei\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary action-icon-btn\"\r\n (click)=\"startEditEducation(ei)\" title=\"Edit\">\r\n <img class=\"action-icon-image edit-icon\" src=\"/assets/images/icons/edit-text.png\" alt=\"Edit\" />\r\n </button>\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger action-icon-btn\" (click)=\"deleteEducation(ei)\"\r\n title=\"Delete\">\r\n <img class=\"action-icon-image delete-icon\" src=\"/assets/images/icons/delete.png\" alt=\"Delete\" />\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"editingEducationIndex() === ei\" class=\"mt-3\">\r\n <div *ngIf=\"(educationIssuesByIndex()[ei] || []).length > 0\" class=\"alert alert-warning py-2 px-3 mb-3\">\r\n <div class=\"fw-semibold\">Missing required fields</div>\r\n <div class=\"small\">{{ (educationIssuesByIndex()[ei] || []).join(' \u2022 ') }}</div>\r\n </div>\r\n <form class=\"row g-2\">\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.degree\"\r\n (ngModelChange)=\"patchTempEducation({ degree: $event })\" name=\"eduDegree{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degree)\">Degree / Course name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Institution <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.institution\"\r\n (ngModelChange)=\"patchTempEducation({ institution: $event })\" name=\"eduInstitution{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.institution)\">Institution name is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Degree / Course Type <span class=\"text-danger\">*</span></label>\r\n <ng-select class=\"ng-select-sm\" [items]=\"educationDegreeTypeOptions\" [clearable]=\"false\"\r\n placeholder=\"Select degree / course type\" [ngModel]=\"tempEducation()?.degreeType\"\r\n (ngModelChange)=\"patchTempEducation({ degreeType: $event })\" name=\"eduDegreeType{{ ei }}\">\r\n </ng-select>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.degreeType)\">Degree / Course type is\r\n required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">Country <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.country\"\r\n (ngModelChange)=\"patchTempEducation({ country: $event })\" name=\"eduCountry{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.country)\">Country is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">State <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.state\"\r\n (ngModelChange)=\"patchTempEducation({ state: $event })\" name=\"eduState{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.state)\">State is required</div>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <label class=\"small text-muted d-block\">City <span class=\"text-danger\">*</span></label>\r\n <input type=\"text\" class=\"form-control form-control-sm\" [ngModel]=\"tempEducation()?.city\"\r\n (ngModelChange)=\"patchTempEducation({ city: $event })\" name=\"eduCity{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.city)\">City is required</div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">Start Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"maxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.startDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('startDate', $event)\" name=\"eduStartDate{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.startDate)\">Start date is required\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\">\r\n <label class=\"small text-muted d-block\">End Date <span class=\"text-danger\">*</span></label>\r\n <input class=\"form-control form-control-sm\" placeholder=\"MM/YYYY\" bsDatepicker [maxDate]=\"futureMaxDate\"\r\n [bsConfig]=\"monthPickerConfig\" [ngModel]=\"monthInputToDate(tempEducation()?.endDate)\"\r\n (bsValueChange)=\"setTempEducationMonth('endDate', $event)\" name=\"eduEndDate{{ ei }}\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"isBlank(tempEducation()?.endDate)\">End date is required</div>\r\n <div class=\"small text-danger mt-1\"\r\n *ngIf=\"isMonthRangeInvalid(tempEducation()?.startDate, tempEducation()?.endDate)\">\r\n Start date must be less than end date\r\n </div>\r\n </div>\r\n <div class=\"col-12\">\r\n <label class=\"small text-muted d-block\">Education File</label>\r\n <input type=\"file\" accept=\".pdf,.doc,.docx,.jpg,.jpeg,.png\" class=\"form-control form-control-sm\"\r\n (change)=\"onEducationFileSelected($event)\" name=\"educationAttachment{{ ei }}\" />\r\n <small class=\"text-muted\" style=\"font-size: 12px;\">Allowed formats: PDF, DOC, DOCX, JPG, JPEG, PNG</small>\r\n <div class=\"small text-muted mt-1 d-flex align-items-center gap-2\" *ngIf=\"tempEducation()?.fileName\">\r\n <span>{{ tempEducation()?.fileName }}</span>\r\n <button type=\"button\" class=\"btn btn-link btn-sm p-0\"\r\n (click)=\"previewSelectedFile(tempEducation())\">Preview</button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"d-flex justify-content-end gap-2 mt-2\">\r\n <button class=\"btn btn-sm btn-link text-secondary\" (click)=\"cancelEditEducation()\">Cancel</button>\r\n <button class=\"btn btn-sm btn-success px-4\" [disabled]=\"isSavingEducation\" (click)=\"saveEducation()\">\r\n <span *ngIf=\"isSavingEducation\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingEducation ? 'Uploading...' : educationActionLabel(editingEducationIndex()) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n </div>\r\n <div class=\"d-flex gap-3 justify-content-center mt-5 pt-2\" *ngIf=\"!isResume\">\r\n <button class=\"btn btn-outline-secondary preview-back-btn px-5 h-auto\" style=\"border-radius: 5px !important;\" (click)=\"onBackClick()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"me-1\" style=\"vertical-align:-0.1em\">\r\n <path d=\"M11 3 5 8l6 5\" />\r\n </svg> Back\r\n </button>\r\n <button class=\"btn btn-primary preview-dashboard-btn px-5 h-auto\" style=\"border-radius: 5px !important;\" [disabled]=\"!canConfirmAndContinue() || isSavingBasic\"\r\n (click)=\"onGoToDashboardClick()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Saving...' : 'Go to Dashboard' }}\r\n <img *ngIf=\"!isSavingBasic\" src=\"/assets/images/icons/arrow-right-white.svg\" width=\"14\" height=\"14\" class=\"ms-1\" style=\"vertical-align:-0.1em\" alt=\"\" />\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<ng-template #loading>\r\n <div class=\"text-center p-5\">\r\n <div class=\"spinner-border text-primary\"></div>\r\n <p class=\"text-muted mt-2\">Loading data...</p>\r\n </div>\r\n</ng-template>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBulkSkillConfirm\">\r\n <div class=\"confirm-modal-card\" style=\"max-width: 480px;\">\r\n <h4 class=\"mb-1\">Set Rating for All Skills</h4>\r\n <p class=\"text-muted small mb-4\">Enter a star rating and years of experience (and optionally a profession type) to apply to all skills that are missing these values.</p>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Profession Type</label>\r\n <ng-select [items]=\"userProfessionOptions\" bindLabel=\"professionName\" bindValue=\"professionId\"\r\n [ngModel]=\"bulkSkillProfessionId\" (change)=\"onBulkSkillProfessionChange($event)\"\r\n name=\"bulkSkillProfessionType\" placeholder=\"Select or search profession type\" [clearable]=\"true\">\r\n </ng-select>\r\n </div>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"bulkSkillStars = s\">\r\n <span [class]=\"bulkSkillStars >= s ? 'text-warning fs-4' : 'text-muted fs-4'\">\r\n {{ bulkSkillStars >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ bulkSkillStars }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkSkillStars <= 0\">Star rating is required</div>\r\n </div>\r\n <div class=\"mb-4\">\r\n <label class=\"small text-muted d-block mb-1\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [(ngModel)]=\"bulkSkillYear\" min=\"1\" max=\"30\"\r\n placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkSkillYear === null || bulkSkillYear === undefined\">Years of experience is required</div>\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"cancelBulkSkillConfirm()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\"\r\n [disabled]=\"isSavingSkill || bulkSkillStars <= 0 || bulkSkillYear === null\"\r\n (click)=\"applyBulkSkillConfirm()\">\r\n <span *ngIf=\"isSavingSkill\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingSkill ? 'Saving...' : 'Apply to All & Save' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBulkToolConfirm\">\r\n <div class=\"confirm-modal-card\" style=\"max-width: 480px;\">\r\n <h4 class=\"mb-1\">Set Rating for All Tools</h4>\r\n <p class=\"text-muted small mb-4\">Enter a star rating and years of experience (and optionally a profession type) to apply to all tools that are missing these values.</p>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Profession Type</label>\r\n <ng-select [items]=\"userProfessionOptions\" bindLabel=\"professionName\" bindValue=\"professionId\"\r\n [ngModel]=\"bulkToolProfessionId\" (change)=\"onBulkToolProfessionChange($event)\"\r\n name=\"bulkToolProfessionType\" placeholder=\"Select or search profession type\" [clearable]=\"true\">\r\n </ng-select>\r\n </div>\r\n <div class=\"mb-3\">\r\n <label class=\"small text-muted d-block mb-1\">Self-ability Rating <span class=\"text-danger\">*</span></label>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <button *ngFor=\"let s of [1,2,3,4,5]\" type=\"button\" class=\"btn btn-link p-0 text-decoration-none\"\r\n (click)=\"bulkToolStars = s\">\r\n <span [class]=\"bulkToolStars >= s ? 'text-warning fs-4' : 'text-muted fs-4'\">\r\n {{ bulkToolStars >= s ? '\u2605' : '\u2606' }}\r\n </span>\r\n </button>\r\n <span class=\"small text-muted\">{{ bulkToolStars }}/5</span>\r\n </div>\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkToolStars <= 0\">Star rating is required</div>\r\n </div>\r\n <div class=\"mb-4\">\r\n <label class=\"small text-muted d-block mb-1\">Years of Experience <span class=\"text-danger\">*</span></label>\r\n <input type=\"number\" class=\"form-control\" [(ngModel)]=\"bulkToolYear\" min=\"1\" max=\"30\"\r\n placeholder=\"Years of Experience\" />\r\n <div class=\"small text-danger mt-1\" *ngIf=\"bulkToolYear === null || bulkToolYear === undefined\">Years of experience is required</div>\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"cancelBulkToolConfirm()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\"\r\n [disabled]=\"isSavingTool || bulkToolStars <= 0 || bulkToolYear === null\"\r\n (click)=\"applyBulkToolConfirm()\">\r\n <span *ngIf=\"isSavingTool\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingTool ? 'Saving...' : 'Apply to All & Save' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showBackConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Leave this page?</h4>\r\n <p class=\"text-muted mb-4\">If you go back, only saved data will be retained.</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" (click)=\"stayOnPreview()\">Stay</button>\r\n <button type=\"button\" class=\"btn btn-danger h-auto\" (click)=\"proceedBack()\">Proceed Back</button>\r\n </div>\r\n </div>\r\n\r\n</div>\r\n\r\n<div class=\"modal-overlay\" *ngIf=\"showDashboardConfirmPopup\">\r\n <div class=\"confirm-modal-card\">\r\n <h4 class=\"mb-2\">Finish Setup and Continue</h4>\r\n <p class=\"text-muted mb-4\">Save your information and go to your dashboard</p>\r\n <div class=\"d-flex justify-content-end gap-2\">\r\n <button type=\"button\" class=\"btn btn-outline-secondary h-auto\" [disabled]=\"isSavingBasic\"\r\n (click)=\"cancelDashboardRedirect()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary h-auto\" [disabled]=\"isSavingBasic\" (click)=\"goToDashboard()\">\r\n <span *ngIf=\"isSavingBasic\" class=\"spinner-border spinner-border-sm me-1\"></span>\r\n {{ isSavingBasic ? 'Proceeding...' : 'Proceed' }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{color:#69707d}.res-flex:hover,.res-flex:focus,.res-flex:active{transform:none!important;box-shadow:none!important}.profession-row-selected{background-color:#f2f4fa!important}.profession-row-selected>td{background-color:#f2f4fa!important}.profession-visibility-checkbox{all:revert;width:16px!important;height:16px!important;min-width:16px!important;max-width:16px!important;margin:0!important;padding:0!important;position:static!important;float:none!important;vertical-align:middle!important;background-image:none!important;transform:none!important}.profession-table{font-size:14px;color:#69707d}.profession-table th{font-size:13px;font-weight:600;color:#69707d;text-transform:uppercase;letter-spacing:.03em}.profession-table td{font-size:14px;color:#69707d}.profession-table label.small{font-size:12px;color:#69707d}.profession-notes-input{min-height:76px;resize:vertical}.container{max-width:900px;margin:30px auto;font-family:Arial,sans-serif;color:#69707d}.preview-page-header{max-width:900px;margin:50px auto 10px;padding:0 12px}.preview-title{font-size:18px;font-weight:700;color:#69707d;margin:0}.preview-subtitle{margin-top:7px;font-size:14px;color:#69707d}.preview-card-gradient h2,.section h5.fw-bold{font-size:18px}.section{margin-bottom:25px}.section-title{font-weight:600;display:block;margin-bottom:8px}.section-title .sub{font-weight:400;color:#777;font-size:13px}.dropdown-box{border:1px solid #ddd;border-radius:8px;padding:12px 15px;display:flex;justify-content:space-between;align-items:center}.icons{display:flex;gap:10px}.icon{cursor:pointer;font-size:14px;color:#777}.card{border:1px solid #ddd;border-radius:5px;padding:20px;background:#fff}.category{border-bottom:1px solid #eee;padding:15px 0}.category:last-child{border-bottom:none}.category-header{display:flex;justify-content:space-between;font-weight:600;margin-bottom:10px}.tags{display:flex;flex-wrap:wrap;gap:10px}.tag{background:#f2f4f7;padding:6px 12px;border-radius:6px;font-size:13px}.footer{text-align:center;margin-top:15px;color:#777;cursor:pointer}.actions{display:flex;justify-content:space-between;margin:50px 0 27px}.text-secondary{white-space:pre-line;font-size:12px;color:#69707d}.extra-small{font-size:.8rem}.card{transition:transform .2s ease,box-shadow .2s ease}.card:hover{transform:translateY(-3px)}.achievement-section .badge{font-size:.75rem;white-space:normal;text-align:left}.skill-tag .badge{font-weight:500;font-size:.9rem;transition:all .2s ease;cursor:default}.skill-tag .badge:hover{transform:translateY(-2px)}.skill-tag .btn-close{opacity:.5}.skill-tag .btn-close:hover{opacity:1}.bg-light.text-dark.border{background-color:#f8f9fa!important;border-color:#dee2e6!important}.card{transition:all .3s cubic-bezier(.25,.8,.25,1)}.card:hover .bg-light{background-color:#e8f5e9!important}.position-fixed .card:hover{transform:none!important}code{background-color:#f8f9fa;padding:2px 6px;border-radius:4px}.list-group-item{transition:all .2s ease-in-out}.list-group-item:hover{background-color:#fcfcfc;transform:translate(5px)}.border-dashed{border-style:dashed!important}.tool-card{transition:all .2s ease-in-out;border-radius:12px}.tool-card:hover{transform:translateY(-5px);border-color:var(--bs-primary)!important}.tool-card:hover .icon-box{background-color:var(--bs-primary-subtle)!important}.tool-card .icon-box{width:60px;height:60px;transition:background-color .2s ease}.border-dashed{border:2px dashed #dee2e6!important}.border-dashed:hover{border-color:var(--bs-primary)!important;background-color:#fff!important}.popup{position:fixed;top:20%;right:20px;width:320px;max-width:calc(100vw - 32px);background:#fff;border-radius:10px;padding:16px}.status-row{display:flex;justify-content:space-between;margin:10px 0}.success{color:#2e7d32;font-weight:700}.error{color:#d32f2f}.pending{color:#f9a825}.section-flag{font-weight:600}button.btn.btn-sm.btn-outline-primary{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:5px!important}button.btn.btn-sm.btn-outline-primary:hover{background-color:#356895;border-color:#356895;color:#fff}button.btn.btn-sm.btn-outline-danger{border:1px solid #dc3545;color:#dc3545;border-radius:5px!important}button.btn.btn-sm.btn-outline-primary.rounded-circle{background-color:#4077ad;border-color:#4077ad;color:#fff;border-radius:5px!important}button.action-icon-btn{min-width:22px;width:22px;height:22px;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:5px!important;background:transparent!important;border:none!important;line-height:1}button.action-icon-btn.btn-outline-primary{color:#4077ad!important;border-color:#4077ad!important}button.action-icon-btn.btn-outline-danger{color:#dc3545!important}.action-icon-image{width:20px;height:20px;object-fit:contain;display:inline-block}.action-icon-image.edit-icon{filter:brightness(0) saturate(100%) invert(41%) sepia(39%) saturate(774%) hue-rotate(170deg) brightness(91%) contrast(89%)}.action-icon-image.delete-icon{filter:brightness(0) saturate(100%) invert(24%) sepia(79%) saturate(4008%) hue-rotate(344deg) brightness(91%) contrast(90%)}.modal-overlay{position:fixed;inset:0;background:#11182773;display:flex;align-items:center;justify-content:center;z-index:2500;padding:20px}.status-modal-card{width:min(760px,96vw);max-height:85vh;overflow:auto;background:#fff;border-radius:16px;border:1px solid #e5e7eb}.status-modal-header{padding:20px 24px 14px;border-bottom:1px solid #eef2f7}.status-modal-body{padding:12px 20px 20px}.status-modal-footer{padding:12px 20px 20px;border-top:1px solid #eef2f7;display:flex;justify-content:end;align-items:center;gap:12px}.status-modal-row{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px 10px;border-bottom:1px solid #f1f5f9}.status-modal-row:last-child{border-bottom:0}.status-modal-name{font-size:14px;font-weight:600;color:#69707d}.status-modal-state{font-size:.92rem;font-weight:600}.status-modal-state.pending{color:#a16207}.status-modal-state.success{color:#166534}.status-modal-state.partial{color:#b45309}.status-modal-state.error{color:#b91c1c}.confirm-modal-card{width:min(520px,96vw);background:#fff;border-radius:5px;border:1px solid #e5e7eb;padding:24px}.year-experience-select{max-height:150px}@media screen and (max-width: 768px){.res-flex{flex-wrap:wrap!important;justify-content:center!important}.res-flex .fw-normal{width:100%;text-align:center;font-size:14px!important}.d-flex.flex-wrap.gap-2.p-3.bg-white.border.rounded.shadow-sm{justify-content:center}.preview-page-header{margin:20px auto 8px;padding:0 4px}.container{padding-left:4px;padding-right:4px}.preview-title{font-size:16px}.preview-subtitle{font-size:14px}.actions{margin:24px 0 16px}.section-header-title{flex-wrap:wrap}.section-header-title>.section-flag{flex-basis:53%}.section-header-row{align-items:flex-start}.preview-card-gradient{padding:14px 14px 12px}.preview-card-gradient h2{font-size:18px}.popup{width:calc(100vw - 40px);right:16px;top:12%}.card{padding:0}.card-body.p-4,.px-4.py-3{padding:12px!important}.row.g-4,.row.g-3{--bs-gutter-x: .75rem}.d-flex.gap-4{gap:10px!important}.preview-card-gradient>.d-flex.justify-content-between.align-items-start{flex-wrap:wrap;row-gap:8px}.preview-card-gradient>.d-flex.justify-content-between.align-items-start>.badge.bg-primary-subtle{margin-left:auto}}@media screen and (max-width: 575px){.preview-title{font-size:16px}.preview-subtitle{font-size:14px}.section>.d-flex{flex-wrap:wrap;row-gap:8px}.section>.d-flex>.d-flex:last-child{width:100%;justify-content:flex-end}}::ng-deep .bs-datepicker-head{background-color:#4077ad!important}::ng-deep .bs-datepicker-body table td span.selected,.bs-datepicker-body table td.selected span{background-color:#4077ad!important}.profile-avatar-circle{width:58px;height:58px;border-radius:5px;background:#4077ad;display:flex;align-items:center;justify-content:center;font-size:22px;font-weight:700;color:#fff;letter-spacing:1px;flex-shrink:0}.section-header-icon{font-size:20px;line-height:1;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;opacity:.9;filter:invert(47%) sepia(8%) saturate(483%) hue-rotate(176deg) brightness(91%) contrast(87%)}.section-header-title h5.fw-bold{color:#69707d}.text-muted{color:#69707d!important}h6.text-uppercase.fw-bold.text-muted{font-size:14px;color:#69707d!important}.work-accent-item{border-radius:5px!important;transition:background-color .18s ease,box-shadow .18s ease}.work-accent-item:hover{background-color:#f5f8ff!important;box-shadow:0 4px 14px #4077ad17!important}.edu-accent-item{border-radius:5px!important;transition:background-color .18s ease,box-shadow .18s ease}.edu-accent-item:hover{background-color:#f8f8ff!important;box-shadow:0 4px 14px #6366f117!important}.cert-accent-item{border-radius:5px!important;transition:background-color .18s ease}.cert-accent-item:hover{background-color:#f0fdf4!important}.lic-accent-item{border-radius:5px!important;transition:background-color .18s ease}.lic-accent-item:hover{background-color:#fffbeb!important}.field-label-sm{font-size:14px;font-weight:700;letter-spacing:.08em;color:#69707d;margin-bottom:3px;display:block}.item-name-text{color:#69707d}.field-value-sm{font-weight:600;font-size:12px;color:#69707d}.item-title-sm{font-size:14px;color:#69707d!important}.item-meta-line{display:block;font-size:12px;color:#69707d;margin-top:3px}.empty-state-wrap{text-align:center;padding:32px 20px;background:#fafbfc;border:1.5px dashed #d1d5db;border-radius:5px;cursor:pointer;transition:background-color .18s ease,border-color .18s ease}.empty-state-wrap .empty-icon{font-size:2rem;color:#d1d5db;margin-bottom:8px}.empty-state-wrap p{color:#9ca3af;margin:0;font-size:14px}.empty-state-wrap:hover{background:#f0f6ff;border-color:#4077ad}.form-panel{background:#fff;border:1px solid #e2e8f0;border-radius:5px;padding:20px}.form-panel .form-control,.form-panel .form-select{border-color:#d1d5db;border-radius:8px;font-size:12px}.form-panel .form-control:focus,.form-panel .form-select:focus{border-color:#4077ad;box-shadow:0 0 0 3px #4077ad1f}.section-header-bar{display:flex;align-items:center;justify-content:space-between;padding:10px 0 14px;border-bottom:2px solid #f1f5f9;margin-bottom:16px}.preview-card-gradient{background:linear-gradient(135deg,#fff,#eff6ff);border-bottom:1px solid #e2e8f0;padding:20px 24px 16px;border-radius:5px 5px 0 0}.item-icon-circle{width:40px;height:40px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:700;color:#fff;flex-shrink:0}.item-avatar--work{background:linear-gradient(135deg,#4077ad,#2d5a8a)}.item-avatar--edu{background:linear-gradient(135deg,#4077ad,#4338ca)}.provider-layout{display:flex;flex-direction:column}.provider-company-first{order:-1}.section-locked{pointer-events:none;opacity:.45;filter:blur(1.5px);-webkit-user-select:none;user-select:none}.btn.btn-primary{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-primary:hover:not(:disabled),.btn.btn-primary:focus:not(:disabled),.btn.btn-primary:active:not(:disabled){background-color:#356895!important;border-color:#356895!important;color:#fff!important}.btn.btn-success,.btn.btn-outline-success{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-success:hover:not(:disabled),.btn.btn-success:focus:not(:disabled),.btn.btn-success:active:not(:disabled),.btn.btn-outline-success:hover:not(:disabled),.btn.btn-outline-success:focus:not(:disabled),.btn.btn-outline-success:active:not(:disabled){background-color:#336843!important;border-color:#336843!important;color:#fff!important}.btn.btn-outline-secondary.rounded-pill{background-color:#69707d!important;border-color:#69707d!important;color:#fff!important;border-radius:5px!important}.btn.btn-outline-secondary.rounded-pill:hover:not(:disabled),.btn.btn-outline-secondary.rounded-pill:focus:not(:disabled),.btn.btn-outline-secondary.rounded-pill:active:not(:disabled){background-color:#565c66!important;border-color:#565c66!important;color:#fff!important}.preview-back-btn{background-color:#426c85!important;border-color:#426c85!important;color:#fff!important}.preview-dashboard-btn{background-color:#4077ad!important;border-color:#4077ad!important;color:#fff!important}.btn.btn-outline-success:hover:not(:disabled),.btn.btn-outline-success:focus:not(:disabled),.btn.btn-outline-success:active:not(:disabled){background-color:transparent!important;border-color:#198754!important;color:#198754!important}.btn.btn-outline-secondary:not(.rounded-pill){background-color:#d4dae6!important;border-color:#d4dae6!important;color:#69707d!important}.btn.btn-outline-secondary:not(.rounded-pill):hover:not(:disabled),.btn.btn-outline-secondary:not(.rounded-pill):focus:not(:disabled),.btn.btn-outline-secondary:not(.rounded-pill):active:not(:disabled){background-color:#c2cbde!important;border-color:#c2cbde!important;color:#69707d!important}.btn.btn-danger{background-color:#b43026!important;border-color:#b43026!important;color:#fff!important}.btn.btn-danger:hover:not(:disabled),.btn.btn-danger:focus:not(:disabled),.btn.btn-danger:active:not(:disabled){background-color:#96271f!important;border-color:#96271f!important;color:#fff!important}.btn.btn-outline-danger.rounded-circle{border-color:#b43026!important;color:#b43026!important;border-radius:5px!important}.btn.btn-outline-danger.rounded-circle:hover:not(:disabled),.btn.btn-outline-danger.rounded-circle:focus:not(:disabled),.btn.btn-outline-danger.rounded-circle:active:not(:disabled){border-color:#96271f!important;color:#b43026!important}.btn.btn-link.text-secondary{background-color:#d4dae6!important;border-color:#d4dae6!important;color:#69707d!important;text-decoration:none!important;border-radius:5px}.btn.btn-link.text-secondary:hover:not(:disabled),.btn.btn-link.text-secondary:focus:not(:disabled){background-color:#c2cbde!important;color:#69707d!important}.btn.btn-link.text-danger{background-color:#b43026!important;border-color:#b43026!important;color:#fff!important;text-decoration:none!important;border-radius:5px}.btn.btn-link.text-danger:hover:not(:disabled),.btn.btn-link.text-danger:focus:not(:disabled){background-color:#96271f!important;color:#fff!important}.btn{border-radius:5px!important;box-shadow:none!important}.badge.bg-warning-subtle.text-warning{background-color:#fff3cd!important;color:#664d03!important;border-color:#ffe69c!important}.badge.bg-success-subtle.text-success{background-color:#4077ad!important;color:#fff!important;border-color:#4077ad!important}.badge.bg-primary-subtle.text-primary{background-color:#e0edf2!important;color:#4077ad!important;border-color:#e0edf2!important}\n"] }]
|
|
7209
|
+
}], ctorParameters: () => [{ type: CredentialingStore }, { type: FileService }, { type: UserSkillSetService }, { type: UserToolService }, { type: ProfessionService }, { type: UserProfessionService }, { type: UserDocumentService }, { type: UserEducationService }, { type: UserDetailService }, { type: UserExperienceService }, { type: i1$4.TokenService }, { type: i1$4.RoleContextService }, { type: ProvidersService }, { type: FrontEndProvidersService }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
|
|
6550
7210
|
type: Inject,
|
|
6551
7211
|
args: [LIBRARY_CONFIG]
|
|
6552
7212
|
}] }], propDecorators: { providerId: [{
|
|
@@ -7774,35 +8434,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
7774
8434
|
type: Input
|
|
7775
8435
|
}] } });
|
|
7776
8436
|
|
|
7777
|
-
class ProfessionService {
|
|
7778
|
-
http = inject(HttpClient);
|
|
7779
|
-
baseUrl = 'Profession';
|
|
7780
|
-
getProfessions(query = {}) {
|
|
7781
|
-
return this.http.get(this.baseUrl + '/GetProfession', {
|
|
7782
|
-
params: this.buildParams(query),
|
|
7783
|
-
});
|
|
7784
|
-
}
|
|
7785
|
-
buildParams(query) {
|
|
7786
|
-
let params = new HttpParams();
|
|
7787
|
-
if (!query)
|
|
7788
|
-
return params;
|
|
7789
|
-
Object.keys(query).forEach(key => {
|
|
7790
|
-
if (query[key] !== null && query[key] !== undefined) {
|
|
7791
|
-
params = params.set(key, query[key]);
|
|
7792
|
-
}
|
|
7793
|
-
});
|
|
7794
|
-
return params;
|
|
7795
|
-
}
|
|
7796
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProfessionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
7797
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProfessionService, providedIn: 'root' });
|
|
7798
|
-
}
|
|
7799
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProfessionService, decorators: [{
|
|
7800
|
-
type: Injectable,
|
|
7801
|
-
args: [{
|
|
7802
|
-
providedIn: 'root',
|
|
7803
|
-
}]
|
|
7804
|
-
}] });
|
|
7805
|
-
|
|
7806
8437
|
class CertificationComponent {
|
|
7807
8438
|
roleContextService;
|
|
7808
8439
|
userDocumentService;
|
|
@@ -35108,6 +35739,14 @@ A B2B Corporate Client may use the platform for its own business operations or t
|
|
|
35108
35739
|
closeInfoPopup() {
|
|
35109
35740
|
this.infoPopupRole = null;
|
|
35110
35741
|
}
|
|
35742
|
+
activeTooltipRole = null;
|
|
35743
|
+
toggleTooltip(event, role) {
|
|
35744
|
+
event.stopPropagation();
|
|
35745
|
+
this.activeTooltipRole = this.activeTooltipRole === role ? null : role;
|
|
35746
|
+
}
|
|
35747
|
+
closeTooltip() {
|
|
35748
|
+
this.activeTooltipRole = null;
|
|
35749
|
+
}
|
|
35111
35750
|
selectedUserRole(role) {
|
|
35112
35751
|
if (this.selectedRoleValue !== null && role.value !== this.selectedRoleValue) {
|
|
35113
35752
|
sessionStorage.removeItem('providerId');
|
|
@@ -36408,11 +37047,11 @@ A B2B Corporate Client may use the platform for its own business operations or t
|
|
|
36408
37047
|
this.destroy$.complete();
|
|
36409
37048
|
}
|
|
36410
37049
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: InitialProcessComponent, deps: [{ token: i2.Router }, { token: i2.ActivatedRoute }, { token: UserDetailService }, { token: i7.FormBuilder }, { token: FileService }, { token: ProvidersService }, { token: RolesService }, { token: i1$1.BsModalService }, { token: ProviderContractorSubCategoryService }, { token: ProviderContractorSubCategoryService }, { token: i9.AuthService }, { token: i1$4.TokenService }, { token: i1$4.RoleContextService }, { token: i1$4.AuthLogoutService }, { token: CredentialingStore }, { token: LIBRARY_CONFIG }], target: i0.ɵɵFactoryTarget.Component });
|
|
36411
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: InitialProcessComponent, isStandalone: false, selector: "app-initial-process", inputs: { providerName: "providerName" }, host: { listeners: { "window:beforeunload": "onBeforeUnload($event)" } }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div class=\"container\">\r\n <div *ngIf=\"isInitializing\" class=\"text-center p-5\">\r\n <div class=\"spinner-border text-primary\"></div>\r\n </div>\r\n <ng-container *ngIf=\"!isInitializing\">\r\n <div class=\"mb-4 logout-container\" *ngIf=\"showlogout\">\r\n <button class=\"logout-btn\" (click)=\"logout()\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4\"/>\r\n <polyline points=\"16 17 21 12 16 7\"/>\r\n <line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\"/>\r\n </svg>\r\n Logout\r\n </button>\r\n </div>\r\n <div class=\"card pb-2 mob pr-5\" style=\"margin-bottom: 30px;\">\r\n <div [hidden]=\"view !== 1\">\r\n\r\n <!-- \u2500\u2500 Welcome Banner \u2500\u2500 -->\r\n <div class=\"v1-welcome\">\r\n <div class=\"v1-welcome-icon\">\r\n <svg width=\"26\" height=\"26\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2\"/>\r\n <circle cx=\"9\" cy=\"7\" r=\"4\"/>\r\n <path d=\"M23 21v-2a4 4 0 00-3-3.87\"/>\r\n <path d=\"M16 3.13a4 4 0 010 7.75\"/>\r\n </svg>\r\n </div>\r\n <div class=\"v1-welcome-text\">\r\n <h2 class=\"v1-welcome-title\">Welcome to <span class=\"v1-brand\">{{ branding.displayName }}</span></h2>\r\n <p class=\"v1-welcome-sub\">Our members and service providers rely on accurate info in your profile to connect\r\n you with work that suits your capabilities. Keep your profile complete, skills updated, licenses current,\r\n photos and logos professional, and schedule up to date.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Main Body: agreements + signature \u2500\u2500 -->\r\n <div class=\"v1-body\">\r\n\r\n <!-- Left: agreement cards -->\r\n <div class=\"v1-agreements\">\r\n\r\n <!-- Terms card -->\r\n <div class=\"v1-agreement-card\" [class.v1-card--agreed]=\"model.acceptTerms\"\r\n [class.v1-card--invalid]=\"!model.acceptTerms && validatePage==1\">\r\n <div class=\"v1-card-icon\">\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z\"/>\r\n <polyline points=\"14 2 14 8 20 8\"/>\r\n <line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\"/>\r\n <line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\"/>\r\n </svg>\r\n </div>\r\n <div class=\"v1-card-body\">\r\n <p class=\"v1-card-title\">Terms and Conditions</p>\r\n <p class=\"v1-card-sub\">Read and accept to continue</p>\r\n </div>\r\n <button type=\"button\" class=\"v1-agree-btn\" [class.v1-agree-btn--done]=\"model.acceptTerms\"\r\n [disabled]=\"isTermsLoading\"\r\n (click)=\"openModal(termsAndConditionsModel,'Terms and Conditions',$event)\">\r\n <span class=\"v1-agree-spinner\" *ngIf=\"isTermsLoading\"></span>\r\n <svg *ngIf=\"!isTermsLoading && model.acceptTerms\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n {{ isTermsLoading ? 'Loading...' : (model.acceptTerms ? 'Agreed' : 'Read & Agree') }}\r\n </button>\r\n </div>\r\n\r\n <!-- Privacy card -->\r\n <div class=\"v1-agreement-card\" [class.v1-card--agreed]=\"model.privacy\"\r\n [class.v1-card--invalid]=\"!model.privacy && validatePage==1\">\r\n <div class=\"v1-card-icon\">\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"/>\r\n </svg>\r\n </div>\r\n <div class=\"v1-card-body\">\r\n <p class=\"v1-card-title\">Privacy Statement</p>\r\n <p class=\"v1-card-sub\">Read and accept to continue</p>\r\n </div>\r\n <button type=\"button\" class=\"v1-agree-btn\" [class.v1-agree-btn--done]=\"model.privacy\"\r\n [disabled]=\"isPrivacyLoading\"\r\n (click)=\"openModal(termsAndConditionsModel,'Privacy Statement',$event)\">\r\n <span class=\"v1-agree-spinner\" *ngIf=\"isPrivacyLoading\"></span>\r\n <svg *ngIf=\"!isPrivacyLoading && model.privacy\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n {{ isPrivacyLoading ? 'Loading...' : (model.privacy ? 'Agreed' : 'Read & Agree') }}\r\n </button>\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- Right: signature pad -->\r\n <div class=\"v1-signature\">\r\n <div class=\"v1-sig-header\">\r\n <span class=\"v1-sig-label\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M17 3a2.828 2.828 0 114 4L7.5 20.5 2 22l1.5-5.5L17 3z\"/>\r\n </svg>\r\n Signature\r\n </span>\r\n <button (click)=\"clearPad()\" class=\"v1-clear-btn\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M18 6L6 18M6 6l12 12\"/>\r\n </svg>\r\n Clear\r\n </button>\r\n </div>\r\n <div class=\"v1-sig-pad\">\r\n <div [ngClass]=\"{'d-none': signaturePadData?.publicUrl}\" style=\"width:100%\">\r\n <canvas #canvas></canvas>\r\n </div>\r\n <div [ngClass]=\"{'d-none': !signaturePadData?.publicUrl}\" style=\"width:100%\">\r\n <img [src]=\"signaturePadData?.publicUrl\" alt style=\"width:100%;height:120px;object-fit:contain;display:block;\">\r\n </div>\r\n <p class=\"v1-sig-hint\" *ngIf=\"!signaturePadData?.publicUrl && (!points || !points?.length)\">\r\n Draw your signature here\r\n </p>\r\n </div>\r\n <div *ngIf=\"validatePage==1 && (!points || !points?.length || points.length==0) && !fileData\"\r\n class=\"v1-error-msg\">\r\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/>\r\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>\r\n </svg>\r\n Signature is required\r\n </div>\r\n <div *ngIf=\"uploadError\" class=\"v1-error-msg\">{{ uploadError }}</div>\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- \u2500\u2500 Continue Button \u2500\u2500 -->\r\n <div class=\"v1-footer\">\r\n <button class=\"v1-continue-btn\" (click)=\"next(2)\"\r\n [disabled]=\"((!points || !points?.length || points.length==0) && !fileData && !signaturePadData?.publicUrl) || !model.acceptTerms || !model.privacy\">\r\n <span *ngIf=\"!showLoader\">Continue</span>\r\n <span *ngIf=\"showLoader\" class=\"v1-spinner\"></span>\r\n <svg *ngIf=\"!showLoader\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n </div>\r\n <ng-container *ngIf=\"view == 2\">\r\n\r\n <!-- \u2500\u2500 Role-select header \u2500\u2500 -->\r\n <div class=\"v2-header\">\r\n <div class=\"v2-header-icon\">\r\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"8\" r=\"4\"/>\r\n <path d=\"M6 20v-2a4 4 0 014-4h4a4 4 0 014 4v2\"/>\r\n </svg>\r\n </div>\r\n <div>\r\n <h2 class=\"v2-title\">Choose your role</h2>\r\n <p class=\"v2-sub\">Choose the areas you'd like to be part of \u2014 programs, services, events, or\r\n collaborations. Connect your business to others and prospective clients.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Role cards grid \u2500\u2500 -->\r\n <div class=\"v2-grid\">\r\n <ng-container *ngFor=\"let userType of userViewRoles\">\r\n <div class=\"v2-role-card\" [class.v2-role-card--active]=\"userType.value === selectedRoleValue\"\r\n (click)=\"selectedUserRole(userType)\">\r\n <button type=\"button\" class=\"v2-role-info-btn\" *ngIf=\"userType.details\"\r\n (click)=\"openInfoPopup($event, userType)\" title=\"More info\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\r\n <line x1=\"12\" y1=\"11\" x2=\"12\" y2=\"16\"/>\r\n <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"/>\r\n </svg>\r\n </button>\r\n <div class=\"v2-role-img-wrap\">\r\n <img [src]=\"userType?.img\" alt=\"\">\r\n </div>\r\n <span class=\"v2-role-name\">{{userType.name}}</span>\r\n <span class=\"v2-role-subtitle\" *ngIf=\"userType.subtitle\">{{userType.subtitle}}</span>\r\n <div class=\"v2-role-tooltip\" *ngIf=\"userType.tooltip\">{{userType.tooltip}}</div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Role info popup \u2500\u2500 -->\r\n <div class=\"v2-info-overlay\" *ngIf=\"infoPopupRole\" (click)=\"closeInfoPopup()\">\r\n <div class=\"v2-info-popup\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"v2-info-popup-header\">\r\n <span class=\"v2-info-popup-title\">{{ infoPopupRole.name }}</span>\r\n <button type=\"button\" class=\"v2-info-popup-close\" (click)=\"closeInfoPopup()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M18 6L6 18M6 6l12 12\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n <div class=\"v2-info-popup-body\">{{ infoPopupRole.details }}</div>\r\n </div>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Footer: Back + Continue \u2500\u2500 -->\r\n <div class=\"v2-footer\">\r\n <button class=\"v2-back-btn\" (click)=\"previous()\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M19 12H5M12 5l-7 7 7 7\"/>\r\n </svg>\r\n Back\r\n </button>\r\n <button class=\"v2-continue-btn\" (click)=\"next(3)\" [disabled]=\"!isUserSelected || isLoadingSubCategories\">\r\n <span *ngIf=\"isLoadingSubCategories\" class=\"v1-spinner\"></span>\r\n <ng-container *ngIf=\"!isLoadingSubCategories\">\r\n Continue\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </ng-container>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"view == 3\">\r\n\r\n <!-- Header -->\r\n <div class=\"ip-header\">\r\n <div class=\"ip-header-icon\">\r\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z\"/>\r\n <polyline points=\"9 22 9 12 15 12 15 22\"/>\r\n </svg>\r\n </div>\r\n <div>\r\n <h2 class=\"ip-title\">Business Information</h2>\r\n <p class=\"ip-sub\">Tell us about your company so we can connect you with the right work.</p>\r\n </div>\r\n </div>\r\n\r\n <form [formGroup]=\"companyForm\">\r\n\r\n <!-- Company Details -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Company Details</p>\r\n <div class=\"ip-grid-2\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"companyName\">Company Name <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': (f.companyName.errors && validatePage == 3) || providerError}\"\r\n type=\"text\" class=\"ip-input\" id=\"companyName\" placeholder=\"Company Name\"\r\n formControlName=\"companyName\">\r\n <span *ngIf=\"f.companyName.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.companyName.errors.required\">Company Name is required</span>\r\n <span *ngIf=\"f.companyName.errors.minlength\">Minimum 2 characters</span>\r\n <span *ngIf=\"f.companyName.errors.maxLength\">Maximum 100 characters</span>\r\n </span>\r\n <span *ngIf=\"providerError\" class=\"ip-error\">{{ providerError }}</span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"inputPhone\">Phone Number <span class=\"ip-required\">*</span></label>\r\n <input class=\"ip-input\" type=\"text\" name=\"inputPhone\" placeholder=\"Company Phone Number\"\r\n id=\"inputPhone\" autocomplete=\"off\" formControlName=\"phoneNumber\" [maxLength]=\"14\"\r\n (input)=\"formatPhone($event,companyForm)\"\r\n [ngClass]=\"{'ip-input--invalid': (f.phoneNumber.errors && validatePage == 3) || providerError}\">\r\n <span *ngIf=\"f.phoneNumber.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.phoneNumber.errors.required\">Phone Number is required</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Address -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Address</p>\r\n <div class=\"ip-grid-2\" style=\"margin-bottom: 12px;\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"businessAddress\">Address Line 1 <span class=\"ip-required\">*</span></label>\r\n <im-address-verify-field formControlName=\"address1\" inputId=\"businessAddress\" [options]=\"options\"\r\n inputClass=\"\" [inputStyle]=\"addressInputStyle\" placeholder=\"Business Address 1\"\r\n [invalid]=\"f.address1.errors && validatePage == 3\"\r\n [initialLat]=\"f.latitude.value\" [initialLng]=\"f.longitude.value\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"\r\n (manualEdit)=\"onCompanyAddressManualEdit()\"></im-address-verify-field>\r\n <span *ngIf=\"f.address1.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.address1.errors.required\">Business Address 1 is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"businessAddress2\">Address Line 2</label>\r\n <input type=\"text\" class=\"ip-input\" id=\"businessAddress2\" placeholder=\"Business Address 2\">\r\n </div>\r\n </div>\r\n <div class=\"ip-grid-4\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"City\">City <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': f.city.errors && validatePage == 3}\"\r\n type=\"text\" class=\"ip-input\" id=\"City\" placeholder=\"City\" formControlName=\"city\">\r\n <span *ngIf=\"f.city.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.city.errors.required\">City is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"State\">State <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': f.state.errors && validatePage == 3}\"\r\n type=\"text\" class=\"ip-input\" id=\"State\" placeholder=\"State\" formControlName=\"state\">\r\n <span *ngIf=\"f.state.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.state.errors.required\">State is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"Zipcode\">Zipcode <span class=\"ip-required\">*</span></label>\r\n <input [textMask]=\"{ mask: zipcodeMask }\"\r\n [ngClass]=\"{'ip-input--invalid': f.zipcode.errors && validatePage == 3}\"\r\n type=\"text\" class=\"ip-input\" id=\"Zipcode\" placeholder=\"Zipcode\" formControlName=\"zipcode\">\r\n <span *ngIf=\"f.zipcode.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.zipcode.errors.required\">Zipcode is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"Country\">Country <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': f.country.errors && validatePage == 3}\"\r\n type=\"text\" class=\"ip-input\" id=\"Country\" placeholder=\"Country\" formControlName=\"country\">\r\n <span *ngIf=\"f.country.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.country.errors.required\">Country is required</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </form>\r\n\r\n <!-- Company Logo (intentionally outside formGroup) -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Company Logo</p>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\">Company Logo <span class=\"ip-required\">*</span></label>\r\n <div class=\"ip-upload-wrap\">\r\n <input #uploadLogoInput type=\"file\" accept=\".png,.jpg,.jpeg\" (change)=\"uploadLogo($event)\"\r\n class=\"upload-initial-input rounded-circle opacity-0 position-absolute\" />\r\n <input (click)=\"uploadImage2.click()\" [(ngModel)]=\"logoName\" readonly type=\"text\"\r\n class=\"ip-input\" placeholder=\"Click to upload company logo\">\r\n <img #uploadImage2 class=\"ip-upload-icon\" (click)=\"uploadLogoInput.click()\"\r\n src=\"assets/images/icons/upload.svg\" alt=\"Upload\">\r\n </div>\r\n <small class=\"ip-upload-hint text-muted d-block\">Allowed formats: PNG, JPG, JPEG</small>\r\n <span *ngIf=\"isLogoRequired\" class=\"ip-error\">Please upload a company logo</span>\r\n <span *ngIf=\"isneeded\" class=\"ip-error\">Company Logo is required</span>\r\n </div>\r\n </div>\r\n\r\n <!-- Contractor Category -->\r\n <div *ngIf=\"selectedRole?.name == 'Contractor'\" class=\"ip-section\">\r\n <p class=\"ip-section-label\">Contractor Category</p>\r\n\r\n <!-- Category selector \u2014 ng-select logic intact, restyled as pill tag-input -->\r\n <div class=\"cc-select-wrap\">\r\n <ng-select [items]=\"contractorSubCategories\" bindLabel=\"name\" [multiple]=\"true\" [closeOnSelect]=\"false\"\r\n (ngModelChange)=\"changeContractor($event)\" [(ngModel)]=\"selectedContractorCategories\"\r\n >\r\n </ng-select>\r\n </div>\r\n\r\n <!-- Sub-items as pill chips per selected category -->\r\n <ng-container *ngFor=\"let item of selectedContractorCategories; let i=index\">\r\n <div class=\"cc-group\">\r\n\r\n <!-- \"Select all\" toggle pill for this category -->\r\n <label class=\"cc-select-all-pill\" [class.cc-select-all-pill--on]=\"item.selectAll\">\r\n <input type=\"checkbox\" [(ngModel)]=\"item.selectAll\" [name]=\"item?.id\" [id]=\"item?.id\"\r\n (change)=\"selectAll($event,item?.items)\" class=\"cc-hidden-check\">\r\n <svg *ngIf=\"item.selectAll\" width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n {{ item?.name }} \u2014 Select all\r\n </label>\r\n\r\n <!-- Individual sub-item pills -->\r\n <div class=\"cc-sub-pills\">\r\n <label *ngFor=\"let subItem of item?.items\" class=\"cc-sub-pill\"\r\n [class.cc-sub-pill--on]=\"subItem.selected\">\r\n <input type=\"checkbox\" [(ngModel)]=\"subItem.selected\" [name]=\"subItem?.id\" [id]=\"subItem?.id\"\r\n (change)=\"unCheckedEvent($event,item)\" class=\"cc-hidden-check\">\r\n <svg *ngIf=\"subItem.selected\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n {{ subItem?.name }}\r\n </label>\r\n </div>\r\n\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"ip-footer\">\r\n <button class=\"ip-back-btn\" (click)=\"previous()\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M19 12H5M12 5l-7 7 7 7\"/>\r\n </svg>\r\n Back\r\n </button>\r\n <button class=\"ip-next-btn\" (click)=\"next(4)\">\r\n Continue\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"view == 4\">\r\n\r\n <!-- Header -->\r\n <div class=\"ip-header\">\r\n <div class=\"ip-header-icon\">\r\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"8\" r=\"4\"/>\r\n <path d=\"M6 20v-2a4 4 0 014-4h4a4 4 0 014 4v2\"/>\r\n </svg>\r\n </div>\r\n <div>\r\n <h2 class=\"ip-title\">Your Profile</h2>\r\n <p class=\"ip-sub\">We need a few basics and a headshot to complete your profile.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Copy from provider toggle -->\r\n <div *ngIf=\"isBusiness\" class=\"ip-copy-row\">\r\n <input [(ngModel)]=\"isCopy\" type=\"checkbox\" name=\"isCopy\" id=\"isCopy\"\r\n class=\"ip-copy-check\" (change)=\"changeAddressUser()\">\r\n <label for=\"isCopy\" class=\"ip-copy-label\">Copy from Provider Information</label>\r\n </div>\r\n\r\n <form [formGroup]=\"userForm\">\r\n\r\n <!-- Personal Details -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Personal Details</p>\r\n <div class=\"ip-grid-3\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"firstName\">First Name <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.firstName.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" placeholder=\"First Name\" formControlName=\"firstName\" id=\"firstName\">\r\n <span *ngIf=\"u.firstName.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.firstName.errors.required\">First Name is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"lastName\">Last Name <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.lastName.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" placeholder=\"Last Name\" formControlName=\"lastName\" id=\"lastName\">\r\n <span *ngIf=\"u.lastName.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.lastName.errors.required\">Last Name is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"email\">Email <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.email.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" placeholder=\"Email\" formControlName=\"email\" id=\"email\">\r\n <span *ngIf=\"u.email.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.email.errors.required\">Email is required</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Home Address -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Home Address</p>\r\n <div class=\"ip-field\" style=\"margin-bottom: 12px;\">\r\n <label class=\"ip-label\" for=\"address1\">Address Line 1 <span class=\"ip-required\">*</span></label>\r\n <im-address-verify-field formControlName=\"address1\" inputId=\"address1\" [options]=\"options\"\r\n inputClass=\"\" [inputStyle]=\"addressInputStyle\" placeholder=\"Home Address 1\"\r\n [invalid]=\"u.address1.errors && validatePage == 4\"\r\n [initialLat]=\"u.latitude.value\" [initialLng]=\"u.longitude.value\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"\r\n (manualEdit)=\"onUserAddressManualEdit()\"></im-address-verify-field>\r\n <span *ngIf=\"u.address1.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.address1.errors.required\">Home Address 1 is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-grid-3\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"homeAddress2\">Address Line 2</label>\r\n <input type=\"text\" class=\"ip-input\" id=\"homeAddress2\" formControlName=\"address2\"\r\n placeholder=\"Home Address 2\">\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"City\">City <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.city.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" id=\"City\" placeholder=\"City\" formControlName=\"city\">\r\n <span *ngIf=\"u.city.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.city.errors.required\">City is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"State\">State <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.state.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" id=\"State\" placeholder=\"State\" formControlName=\"state\">\r\n <span *ngIf=\"u.state.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.state.errors.required\">State is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"Zipcode\">Zipcode <span class=\"ip-required\">*</span></label>\r\n <input [textMask]=\"{ mask: zipcodeMask }\"\r\n [ngClass]=\"{'ip-input--invalid': u.zipcode.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" id=\"Zipcode\" placeholder=\"Zipcode\" formControlName=\"zipcode\">\r\n <span *ngIf=\"u.zipcode.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.zipcode.errors.required\">Zipcode is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"Country\">Country <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.country.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" id=\"Country\" placeholder=\"Country\" formControlName=\"country\">\r\n <span *ngIf=\"u.country.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.country.errors.required\">Country is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"inputPhone\">Phone Number <span class=\"ip-required\">*</span></label>\r\n <input class=\"ip-input\" type=\"text\" (input)=\"formatPhone($event,userForm)\"\r\n name=\"inputPhone\" placeholder=\"Phone Number\" id=\"inputPhone\" autocomplete=\"off\"\r\n formControlName=\"phoneNumber\" [maxLength]=\"14\"\r\n [ngClass]=\"{'ip-input--invalid': u.phoneNumber.errors && validatePage == 4}\">\r\n <span *ngIf=\"u.phoneNumber.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.phoneNumber.errors.required\">Phone Number is required</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </form>\r\n\r\n <!-- Profile Picture (intentionally outside formGroup) -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Profile Picture</p>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\">Profile Picture <span class=\"ip-required\">*</span></label>\r\n <div class=\"ip-upload-wrap\">\r\n <input #uploadFile type=\"file\" accept=\".png,.jpg,.jpeg\" (change)=\"uploadUserImage($event)\"\r\n class=\"upload-initial-input rounded-circle opacity-0 position-absolute\" />\r\n <input (click)=\"uploadImage1.click()\" [(ngModel)]=\"fileName\" readonly type=\"text\"\r\n class=\"ip-input\" id=\"upload\" accept=\".png,.jpg,.jpeg\" placeholder=\"Click to upload profile picture\">\r\n <img #uploadImage1 class=\"ip-upload-icon\" (click)=\"uploadFile.click()\"\r\n src=\"assets/images/icons/upload.svg\" alt=\"Upload\">\r\n </div>\r\n <small class=\"ip-upload-hint text-muted d-block\">Allowed formats: PNG, JPG, JPEG</small>\r\n <span *ngIf=\"isImageRequired\" class=\"ip-error\">Please upload a profile image</span>\r\n <span *ngIf=\"userError\" class=\"ip-error\">{{ userError }}</span>\r\n </div>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"ip-footer\">\r\n <button class=\"ip-back-btn\" (click)=\"previous()\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M19 12H5M12 5l-7 7 7 7\"/>\r\n </svg>\r\n Back\r\n </button>\r\n <button class=\"ip-next-btn\" (click)=\"next(5)\" [disabled]=\"showLoader\">\r\n <span *ngIf=\"!showLoader\">Continue</span>\r\n <span *ngIf=\"showLoader\" class=\"v1-spinner\"></span>\r\n <svg *ngIf=\"!showLoader\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"view == 5\">\r\n <div class=\"v5-wrap\">\r\n\r\n <!-- Success icon -->\r\n <div class=\"v5-icon\">\r\n <svg width=\"36\" height=\"36\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M22 11.08V12a10 10 0 11-5.93-9.14\"/>\r\n <polyline points=\"22 4 12 14.01 9 11.01\"/>\r\n </svg>\r\n </div>\r\n\r\n <h2 class=\"v5-title\">You're all set!</h2>\r\n <p class=\"v5-sub\">Account created successfully. Next step: complete your profile.</p>\r\n\r\n <!-- Info cards -->\r\n <div class=\"v5-cards\">\r\n <div class=\"v5-card\">\r\n <div class=\"v5-card-icon\">\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\r\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/>\r\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>\r\n </svg>\r\n </div>\r\n <p class=\"v5-card-text\">Profile completion is mandatory to participate in rosters, programs, requests, and platform workflows. Incomplete profiles will have limited access.</p>\r\n </div>\r\n <div class=\"v5-card\">\r\n <div class=\"v5-card-icon v5-card-icon--green\">\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><path d=\"M3 9h18M9 21V9\"/>\r\n </svg>\r\n </div>\r\n <p class=\"v5-card-text\">You may access your dashboard at any time, but full functionality is available only after profile completion.</p>\r\n </div>\r\n </div>\r\n\r\n <button (click)=\"dashboard()\" class=\"v5-cta\">\r\n Go to Dashboard\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </button>\r\n\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"view == 10\">\r\n <app-credentialing (back)=\"onCredentialingBack()\" [data]=\"credentialingData\" [signatureFileId]=\"signatureFileId\"\r\n [signatureUrl]=\"signatureUrl\"></app-credentialing>\r\n </ng-container>\r\n </div>\r\n</ng-container>\r\n</div>\r\n\r\n<ng-template #termsAndConditionsModel>\r\n <div class=\"modal-dialog modal-dialog-centered tc-modal-dialog\">\r\n <div class=\"modal-content tc-modal\">\r\n\r\n <!-- HEADER -->\r\n <div class=\"tc-modal-header\">\r\n \r\n <h4 class=\"tc-modal-title\">{{ termsAndConditionTitle }}</h4>\r\n <span class=\"tc-modal-meta\" *ngIf=\"legalMeta\">Last Modified: {{ legalMeta.createdDate | date:'MMM d, y, h:mm:ss a' }}, {{ legalMeta.versionName }}</span>\r\n </div>\r\n\r\n\r\n <div class=\"tc-scroll-wrapper\">\r\n <div class=\"tc-modal-body\"\r\n (scroll)=\"onTermsScroll($event)\">\r\n <ng-container *ngIf=\"termsAndConditionTitle == 'Terms and Conditions'\">\r\n <app-terms-conditions [PrivacyAndTerms]=\"privacyAndTerms\" [title]=\"title\" [branding]=\"branding\"\r\n (metaLoaded)=\"onLegalMetaLoaded($event)\">\r\n </app-terms-conditions>\r\n </ng-container>\r\n <ng-container *ngIf=\"termsAndConditionTitle != 'Terms and Conditions'\">\r\n <app-privacy-policy [PrivacyAndTerms]=\"privacyAndTerms\" [title]=\"title\" [branding]=\"branding\"\r\n (metaLoaded)=\"onLegalMetaLoaded($event)\">\r\n </app-privacy-policy>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Floating scroll-to-bottom button -->\r\n <button class=\"tc-scroll-fab\" *ngIf=\"!isAgreeEnabled && legalMeta\" (click)=\"scrollToBottomClick($event)\"\r\n title=\"Scroll to bottom\">\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 5v14M5 15l7 7 7-7\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <!-- FOOTER -->\r\n <div class=\"tc-modal-footer\">\r\n <button type=\"button\" class=\"tc-btn tc-btn-decline\"\r\n (click)=\"decline(termsAndConditionTitle); modelRef.hide();\">\r\n Decline\r\n </button>\r\n <button type=\"button\" class=\"tc-btn tc-btn-agree\"\r\n [disabled]=\"!isAgreeEnabled\"\r\n (click)=\"agree(termsAndConditionTitle); modelRef.hide();\">\r\n I Agree\r\n </button>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n</ng-template>", styles: ["@charset \"UTF-8\";.brand-name{font-weight:700;font-size:calc(100% + 4px)}.spinner{width:38px;height:38px;border:dotted white;border-top:2px solid #f6f6f6;border-radius:62%;animation:spin 1.7s linear infinite;margin:-9px 0 0 -28px}@keyframes spin{to{transform:rotate(360deg)}}::ng-deep .backdrop{background-color:transparent!important}.filter-black{filter:brightness(.4)!important}.footer-view{margin-top:3rem;margin-left:0;margin-right:0}.footer-signature{margin-top:9rem}.slider-view{width:11rem;margin-left:1px}.container{margin-top:40px}.container .card{border-radius:5px}.container .header{padding:33px 10px 0}.container .header .logo{width:15%;height:80%}.container .form-control{padding:.75rem 1rem;border-color:#a1a1a1}.container .form-control:focus{color:#000;box-shadow:none;border-color:#a1a1a1!important}.container .form-control::placeholder{font-weight:500;font-size:12px;color:#a1a1a1}.container .link{color:#4077ad}.container .link-signup{font-weight:bolder}.container .form-check-label{margin-bottom:0;padding-top:9px}.container .content-view{margin-top:10%}.container .content-description{margin-top:25%}.container .tag-content{color:#fff9e8;margin-left:9%}.container .tag-content p{color:#fff9e8}.container .form-check-input:checked{background-color:#000;border-color:#000}.container .img-tick{margin:-31px 12px 0 -35px}.container .form-check-input[type=checkbox]{border-radius:2px;border:2px solid #000000}.container .form-check-input:focus{box-shadow:none}.container input[type=checkbox]{accent-color:#000000}.term-list{padding:48px 60px 6px 0;margin-left:30px;color:\"#1f1f1fdb\"}.add-tab{padding:75px 75px 6px 1px;margin-left:50px;color:\"#1f1f1fdb\"}.add-tab-view{padding:75px 75px 6px 1px;margin-left:80px;color:\"#1f1f1fdb\"}.inspect-add{margin-top:3rem}.add-btn{font-size:16px;border-radius:5px;transition:.2s;padding:.25rem .5rem;background:#fff;border:1px solid rgba(148,147,147,.1882352941);color:#444;line-height:48px;box-shadow:0 1px 9px #98a2b3;width:9rem}.add-btn:hover{border:1px solid rgba(148,147,147,.1882352941);box-shadow:none}.agree{padding:0 0 8px 47px}.agree .form-check-input[type=checkbox]{border-radius:2px;border:2px solid #98A2B3;width:14px;height:14px;margin:5px 9px 0 -35px}.agree .form-check-input:focus{box-shadow:none}.agree .form-check-input:checked{background-color:#000;border-color:#000}.agree .invalid-feedback{font-size:10px!important;margin:0 0 0 21px}.checkmark{vertical-align:text-bottom;color:#98a2b3;font-weight:500;font-size:12px}.term-signature{padding-left:16rem;padding-right:65px;position:absolute;margin:150px 0 0 50%}.participate-tab{height:135px;width:142px}.card-design{height:147px;width:147px;padding-left:10px;margin-left:42px;background:#fff0;border:2px solid #98A2B3;box-shadow:0 0 4px #98a2b3;border-radius:27px;margin-bottom:42px}.upload{height:39px;margin-top:-4px;width:126px;font-size:12px}.participate-tab{margin-top:-25px}.slider{width:14rem;margin-left:69px}.btn-clear{background:#d3dae6;color:#98a2b3;font-size:12px;border-radius:5px;transition:.2s;padding:6px;border:none;height:auto;width:46%;line-height:28px}.btn-close{background:#f1f4fa;color:#98a2b3;font-size:17px;border-radius:5px;transition:.2s;padding:6px;border:none;height:auto;font-weight:500;width:116px;color:#737a87;line-height:28px}.view-logo{padding-top:1%;padding-bottom:4%;text-align:center}.back-btn{border-radius:45px;height:41px}.next{background:#4077ad;border-radius:30px;height:60px;width:60px;border:white}.profile-field{margin-top:-10px}.profile-field input{line-height:30px;margin:-10px 3px 3px}.load-page{padding:21px 49px 13px 34px}.sign-img{width:291px;height:95px;border-radius:8px;border:1px solid rgba(179,178,178,.33);margin-top:19px}.upload-image{height:16px;width:16px;position:absolute;margin-left:66rem;margin-top:-39px}.para-comma{font-weight:500}.go-btn{border-radius:45px;height:50px;padding:0 20px;background:#4077ad;border:1px solid #4077ad;color:#fff;line-height:28px;font-size:14px;font-weight:500}.text-label{color:#747b83;font-weight:500}.form{padding:20px;border-radius:5px}.form-control:focus{color:#000;box-shadow:none;border-color:#848484!important}.form-control::placeholder{font-weight:500;font-size:12px;color:#bec1be;padding-left:10px}.btn-primary:active{background-color:#50575e}@media screen and (min-width: 500px) and (max-width: 769px){.content-view{background:#0c1620;width:44rem;margin:31px 0 0!important;padding:28px 32px 17px 71px!important;border-radius:29px}.upload-image{margin-left:25rem!important}}@media screen and (min-width: 768px) and (max-width: 1024px){.back-btn{height:31px;width:82px;position:absolute;margin-left:-53px}.back-tab{position:absolute;margin-left:-87px;height:37px}.go-btn{width:175px;height:44px}.term-signature{padding-left:10px}.upload-image{margin-left:40rem}}@media screen and (min-width: 374px) and (max-width: 426px){.head-logo{width:216px;padding-bottom:16px}.slider{visibility:hidden}.back-btn{height:31px;width:82px;position:absolute;margin-left:73px;margin-top:23px}.go-btn{width:175px;height:44px}.upload-image{margin-left:16rem}.term-signature{margin:84% 0 7px 4%}}@media screen and (min-width: 320px) and (max-width: 426px){.footer-signature{margin-top:20rem}.login .head-logo{padding:16px 2px 0;width:38%!important;height:40%!important}.container{margin-top:5px!important}.card{padding:2px!important}.tag-content{margin:3% 0 0!important;background-color:#121b24;border-radius:13px}.img-tick{margin:3px!important}.slider{visibility:hidden}.load-page{padding:0}.head-logo{width:216px;padding-bottom:16px}.back-btn{height:26px;width:71px;position:absolute;margin-left:-17rem!important;font-size:10px;margin-top:23px}.go-btn{width:142px;height:36px;margin-right:-28px;font-size:10px}.add-tab,.add-tab-view{padding:30px 33px 2px 3px;margin-left:15px}.add-btn{width:6rem}.slider-tab{visibility:hidden}.back-tab{margin-left:-14rem;margin-top:1px;font-size:14px;height:39px}.participate-tab{height:96px;width:87px}.card-design{height:124px;width:125px;padding-left:17px;margin-left:30px}.term-signature{padding:22px 22px 13px 27px}.term-list{padding:43px 10px 10px 3px;margin-left:0;text-align:-webkit-center}}@media screen and (min-width: 320px) and (max-width: 376px){.agree{padding:0 0 8px 25px}.participate-tab{height:96px;width:87px}.card-design{height:109px;width:97px;padding-left:4px;margin-left:10px}.card-design h6{font-size:10px;padding-left:14px;font-weight:600}.sign-img{width:270px}.term-list{padding:20px 20px 6px 4px;margin-left:13px}}@media screen and (min-width: 320px) and (max-width: 350px){.upload-image{height:13px;width:11px;margin-left:10rem;margin-top:-35px}.btn-clear{width:92px}.term-signature{margin:84% 0 7px 4%}}.disabled-btn{cursor:not-allowed!important;background:#4077ad!important;color:#fff!important}.modal-dialog .modal-content{border-radius:12px;background:#fff!important;border:1px solid rgba(128,128,128,.3294117647)!important}.title-popup{font-size:18px;color:#0c1620}.tc-modal-dialog{max-width:min(780px,96vw)}.tc-modal{border-radius:10px!important;border:none!important;overflow:hidden;box-shadow:0 32px 72px #00000038,0 6px 20px #0000001a!important;height:min(720px,90vh);display:flex;flex-direction:column}.tc-modal-header{display:flex;align-items:center;flex-wrap:wrap;gap:6px 12px;padding:10px 28px 14px;background:#4077ad;border-bottom:none;flex-shrink:0}.tc-modal-header .tc-header-icon{width:40px;height:40px;border-radius:11px;display:flex;align-items:center;justify-content:center;color:#fff;flex-shrink:0}.tc-modal-header .tc-modal-title{font-family:Inter,system-ui,sans-serif;font-size:18px;font-weight:700;color:#fff;letter-spacing:-.01em;padding:10px;margin:0;flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tc-modal-header .tc-modal-meta{font-weight:600;font-size:12px;color:#fff;flex-shrink:0;white-space:nowrap}@media screen and (max-width: 767px){.tc-modal-header .tc-modal-header{flex-flow:column;align-items:center;text-align:center}.tc-modal-header .tc-modal-title{flex:1 1 100%;white-space:normal}.tc-modal-header .tc-modal-meta{flex:1 1 100%;opacity:.85}}.tc-scroll-hint{display:flex;align-items:center;gap:7px;padding:9px 28px;background:#f0f9ff;border-bottom:none;font-size:12px;color:#4077ad;font-family:Inter,system-ui,sans-serif;letter-spacing:.01em;flex-shrink:0}.tc-scroll-hint svg{flex-shrink:0}.tc-scroll-hint strong{font-weight:700}.tc-scroll-hint .tc-progress-pill{margin-left:auto;background:#4077ad;color:#fff;font-size:11px;font-weight:700;letter-spacing:.04em;padding:2px 9px;border-radius:99px;min-width:42px;text-align:center;transition:background .2s ease}.tc-progress-bar{height:3px;background:#e0f2fe;flex-shrink:0}.tc-progress-bar .tc-progress-fill{height:100%;background:linear-gradient(90deg,#4077ad,#38bdf8);border-radius:0 99px 99px 0;transition:width .12s ease}.tc-scroll-wrapper{position:relative;flex:1 1 auto;overflow:hidden;display:flex;flex-direction:column}.tc-modal-body{flex:1 1 auto;overflow-y:auto;padding:26px 32px;background:#fff;scrollbar-width:thin;scrollbar-color:#cbd5e1 transparent}.tc-modal-body::-webkit-scrollbar{width:5px}.tc-modal-body::-webkit-scrollbar-track{background:transparent}.tc-modal-body::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:99px}.tc-modal-body::-webkit-scrollbar-thumb:hover{background:#94a3b8}.tc-scroll-fab{position:absolute;bottom:20px;right:20px;width:46px;height:46px;border-radius:50%;background:linear-gradient(135deg,#4077ad 0% 100%);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:10;transition:transform .18s ease,box-shadow .18s ease}.tc-scroll-fab:hover{transform:translateY(-3px) scale(1.1);animation:none}@keyframes tc-fab-bounce{0%,to{transform:translateY(0);box-shadow:0 4px 18px #2563eb80}50%{transform:translateY(5px);box-shadow:0 2px 10px #2563eb59}}.tc-modal-footer{display:flex;justify-content:flex-end;align-items:center;gap:10px;padding:16px 24px;background:#f8fafc;border-top:1px solid #e2e8f0;flex-shrink:0}.tc-btn{font-family:Inter,system-ui,sans-serif;font-size:14px;font-weight:600;letter-spacing:.015em;padding:10px 26px;border-radius:5px;border:none;cursor:pointer;transition:background .18s ease,transform .15s ease}.tc-btn.tc-btn-decline{background:#b43026;color:#fff;border:1.5px solid #B43026}.tc-btn.tc-btn-decline:hover{background:#96271f;border-color:#96271f;color:#fff}.tc-btn.tc-btn-agree{background:linear-gradient(135deg,#4077ad 0% 100%);border:1.5px solid transparent;color:#fff}.tc-btn.tc-btn-agree:hover:not(:disabled){background:linear-gradient(135deg,#2d5f8a,#4077ad);transform:translateY(-1px)}.tc-btn.tc-btn-agree:disabled{background:#e2e8f0;color:#94a3b8;box-shadow:none;cursor:not-allowed}ul.term-list-data li{padding-bottom:5px;font-size:13px;font-weight:500;line-height:21px}ol,ul,dl{margin-top:0;margin-bottom:1rem}::ng-deep .modal-content{width:100%;border:none}.hidden-view{display:none}.header-container{position:relative;padding:20px}.view-logo{text-align:center}.logout-button{top:20px;right:20px;position:absolute}.logout-button button{background:none;border:none;font-size:16px;display:flex;align-items:center;cursor:pointer}.logout-button img{margin-right:5px;height:20px}.user-card{align-items:center;color:#4077ad;cursor:pointer}.user-cards-active{background:#4077ad;color:#fff}.save-btn.upload{border:1px solid #4077AD;background-color:#4077ad;color:#fff;border-radius:5px;background:#4077ad;padding:4px 10px;display:inline-flex;align-items:center;gap:6px}.save-btn.upload img{filter:brightness(0) invert(1)}.form-check.agree{display:flex;align-items:flex-start;gap:8px;margin-bottom:8px}.form-check.agree .form-check-input{margin-top:4px;flex-shrink:0}.form-check.agree .form-check-label{line-height:1.4;cursor:pointer;white-space:normal}.spinner-16{width:16px;height:16px}.h6-buttons{display:flex;align-items:center;gap:8px}.form-check.agree{display:flex;align-items:flex-start;margin-bottom:14px}.form-check-input{position:absolute;opacity:0;cursor:pointer}.form-check-label{position:relative;padding-left:28px;cursor:pointer;font-size:14px;line-height:20px;color:#212529;-webkit-user-select:none;user-select:none}.form-check-label:before{content:\"\";position:absolute;left:0;top:8px;width:18px;height:18px;border:2px solid #adb5bd;border-radius:4px;background:#fff;transition:all .2s ease}.form-check-label:after{content:\"\";position:absolute;left:5px;top:10px;width:6px;height:10px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg) scale(0);transition:transform .15s ease}.form-check-input:checked+.form-check-label:before{background-color:#4077ad;border-color:#4077ad}.form-check-input:checked+.form-check-label:after{transform:rotate(45deg) scale(1)}.form-check-label:hover:before{border-color:#4077ad}.form-check-input:focus+.form-check-label:before{box-shadow:0 0 0 3px #4077ad40}.form-check-input.is-invalid+.form-check-label:before{border-color:#dc3545}.form-check-input.is-invalid:checked+.form-check-label:before{background-color:#dc3545}.invalid-feedback{display:block;font-size:12px;margin-left:7px;margin-top:4px}::ng-deep .modal-dialog{max-width:750px}.user-cards-active{background-color:#4077ad;color:#fff;border:2px solid #4077AD}body.modal-open{overflow:hidden!important}.modal{z-index:1055!important}.modal-backdrop{z-index:1050!important}.modal-dialog{margin:auto;pointer-events:auto}.modal-content{position:relative;z-index:1060}.logout-container{display:flex;justify-content:flex-end}.logout-btn{display:inline-flex;align-items:center;gap:7px;padding:7px 16px;border-radius:5px;font-size:14px;font-weight:500;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;background:#f8fafc;border:1.5px solid #e2e8f0;cursor:pointer;transition:color .18s,background .18s,border-color .18s,box-shadow .18s}.logout-btn:hover{color:#dc2626;background:#fff5f5;border-color:#fca5a5}.logout-btn:active{transform:scale(.97)}@media screen and (max-width: 767px){.term-signature{padding-left:3rem;padding-right:0;position:unset;margin:0}.footer-signature{margin-top:0rem}.disabled-btn{position:absolute;bottom:13px;right:24px}.next{height:46px;width:46px;position:absolute;bottom:21px;right:35px}.mob{padding-bottom:4.5rem!important}.checkmark{width:85%}.terms-fixed-modal{width:unset}::ng-deep .privacy-policy-modal .logo-section{margin-bottom:0!important}.add-tab-view{padding:30px 25px 6px;margin-left:0}.user-card{width:96%}.footer .btn-mob{display:flex;align-items:center}.back-btn{position:absolute;bottom:21px;left:10px}.actions{margin:50px 34px 1px}}@media screen and (min-width: 768px) and (max-width: 1024px){.footer-signature{margin-top:3rem}}.v1-welcome{display:flex;align-items:flex-start;gap:16px;padding:28px 32px 20px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.v1-welcome-icon{flex-shrink:0;width:48px;height:48px;border-radius:50%;border:1px solid #cfd2d6;display:flex;align-items:center;justify-content:center;color:#90979d;margin-top:2px}.v1-welcome-title{font-size:18px;font-weight:700;color:#69707d;margin:0 0 6px;line-height:1.25;letter-spacing:-.02em}.v1-brand{color:#4077ad}.v1-welcome-sub{font-size:14px;color:#69707d;line-height:1.65;margin:0}.v1-body{display:grid;grid-template-columns:1fr 1fr;gap:20px;padding:0 32px 20px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v1-body{grid-template-columns:1fr;padding:0 16px 16px}}.v1-agreements{display:flex;flex-direction:column;gap:12px}.v1-agreement-card{display:flex;align-items:center;gap:14px;padding:16px 18px;border-radius:5px;border:1.5px solid #e2e8f0;background:#fff;transition:border-color .2s,box-shadow .2s;box-shadow:0 1px 3px #0000000a}.v1-agreement-card:hover{border-color:#c7d3e2;box-shadow:0 2px 8px #00000012}.v1-agreement-card.v1-card--agreed{border-color:#dde2e7}.v1-agreement-card.v1-card--invalid{border-color:#fecaca;background:#fff5f5}.v1-card-icon{flex-shrink:0;width:38px;height:38px;border-radius:5px;border:1px solid #e2e8f0;display:flex;align-items:center;justify-content:center;color:#4077ad}.v1-card--agreed .v1-card-icon{border-color:#dde2e7;color:#7e8994}.v1-card-body{flex:1 1 auto;min-width:0}.v1-card-title{font-size:14px;font-weight:600;color:#69707d;margin:0 0 2px;line-height:1.3}.v1-card-sub{font-size:12px;color:#6b7280;margin:0}.v1-agree-btn{flex-shrink:0;display:inline-flex;align-items:center;gap:5px;padding:7px 14px;border-radius:5px;font-size:12px;font-weight:600;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;border:1.5px solid #4077AD;color:#4077ad;background:transparent;cursor:pointer;white-space:nowrap;transition:background .18s,color .18s}.v1-agree-btn:hover{background:#4077ad;color:#fff}.v1-agree-btn.v1-agree-btn--done{background:#3e7f50;border-color:#3e7f50;color:#fff}.v1-agree-btn:disabled{opacity:.7;cursor:not-allowed}.v1-agree-btn:disabled:hover{background:transparent;color:#4077ad}.v1-agree-spinner{width:12px;height:12px;border:2px solid currentColor;border-top-color:transparent;border-radius:50%;flex-shrink:0;animation:v1-agree-spin .7s linear infinite}@keyframes v1-agree-spin{to{transform:rotate(360deg)}}.v1-signature{display:flex;flex-direction:column;gap:10px}.v1-sig-header{display:flex;align-items:center;justify-content:space-between}.v1-sig-label{display:inline-flex;align-items:center;gap:7px;font-size:14px;font-weight:600;color:#69707d;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.v1-clear-btn{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:500;color:#6b7280;background:transparent;border:1px solid #e2e8f0;border-radius:5px;padding:4px 10px;cursor:pointer;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;transition:color .18s,border-color .18s}.v1-clear-btn:hover{color:#dc2626;border-color:#fca5a5}.v1-sig-pad{position:relative;border-radius:5px;border:1.5px dashed #cbd5e1;overflow:hidden;min-height:120px}.v1-sig-pad canvas{display:block;cursor:crosshair;width:100%;height:120px}.v1-sig-hint{position:absolute;bottom:8px;left:50%;transform:translate(-50%);font-size:12px;color:#c0cad8;pointer-events:none;margin:0;white-space:nowrap;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.v1-error-msg{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:500;color:#dc2626;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.v1-footer{padding:8px 32px 20px;display:flex;justify-content:flex-end;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v1-footer{padding:8px 16px 20px}}.v1-continue-btn{display:inline-flex;align-items:center;gap:9px;padding:12px 28px;border-radius:5px;font-size:14px;font-weight:600;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:linear-gradient(135deg,#4077ad 0% 100%);border:none;cursor:pointer;transition:transform .15s;min-width:148px;justify-content:center}.v1-continue-btn:hover:not(:disabled){transform:translateY(-1px)}.v1-continue-btn:active:not(:disabled){transform:translateY(0)}.v1-continue-btn:disabled,.v1-continue-btn.disabled{background:#e2e8f0;color:#94a3b8;box-shadow:none;cursor:not-allowed}.v1-spinner{display:inline-block;width:16px;height:16px;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:v1-spin .65s linear infinite}@keyframes v1-spin{to{transform:rotate(360deg)}}@media (max-width: 767px){.v1-welcome{padding:20px 16px 14px;gap:12px}.v1-welcome-icon{width:40px;height:40px}.v1-welcome-title{font-size:16px}}.v2-header{display:flex;align-items:flex-start;gap:16px;padding:28px 32px 20px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v2-header{padding:20px 16px 14px;gap:12px}}.v2-header-icon{flex-shrink:0;width:48px;height:48px;border-radius:50%;border:1px solid #cecece;display:flex;align-items:center;justify-content:center;color:#abb3ba;margin-top:2px}.v2-title{font-size:18px;font-weight:700;color:#69707d;margin:0 0 6px;line-height:1.25;letter-spacing:-.02em}.v2-sub{font-size:14px;color:#69707d;line-height:1.65;margin:0}.v2-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:14px;padding:10px 32px 50px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v2-grid{grid-template-columns:repeat(auto-fill,minmax(110px,1fr));padding:0 16px 20px;gap:10px}}.v2-role-card{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:20px 12px 16px;border-radius:5px;border:1.5px solid #e2e8f0;background:#fff;cursor:pointer;transition:border-color .18s,box-shadow .18s,transform .15s;box-shadow:0 1px 3px #0000000a;text-align:center}.v2-role-card:hover{z-index:30;border-color:#93c5fd;box-shadow:0 4px 16px #4077ad1a;transform:translateY(-2px)}.v2-role-card.v2-role-card--active{border-color:#4077ad;background:#eff6ff;box-shadow:0 0 0 3px #4077ad1f,0 4px 16px #4077ad1f}.v2-role-img-wrap{width:64px;height:64px;border-radius:50%;background:#f8fafc;border:1px solid #e2e8f0;display:flex;align-items:center;justify-content:center;overflow:hidden;transition:background .18s,border-color .18s}.v2-role-img-wrap img{width:44px;height:44px;object-fit:contain;display:block}.v2-role-card--active .v2-role-img-wrap{background:#dbeafe;border-color:#93c5fd}.v2-role-name{font-size:14px;font-weight:600;color:#69707d;line-height:1.3;text-align:center}.v2-role-card--active .v2-role-name{color:#4077ad}.v2-role-subtitle{font-size:11px;font-weight:400;color:#6b7280;line-height:1.3;text-align:center;margin-top:2px}.v2-role-tooltip{position:absolute;top:calc(100% + 10px);left:50%;transform:translate(-50%) translateY(-4px);width:240px;max-width:80vw;background:#4077ad;color:#fff;font-size:12px;font-weight:400;line-height:1.45;text-align:left;padding:10px 12px;border-radius:6px;box-shadow:0 6px 18px #0000002e;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .15s ease,transform .15s ease;z-index:40}.v2-role-tooltip:after{content:\"\";position:absolute;bottom:100%;left:50%;transform:translate(-50%);border-width:6px;border-style:solid;border-color:transparent transparent #4077ad transparent}.v2-role-card:hover .v2-role-tooltip{opacity:1;visibility:visible;transform:translate(-50%) translateY(0)}.v2-role-info-btn{position:absolute;top:8px;right:8px;width:20px;height:20px;border-radius:50%;background:#4077ad;color:#fff;border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;z-index:2;transition:background .15s ease,transform .15s ease}.v2-role-info-btn:hover{background:#345f87;transform:scale(1.08)}.v2-info-overlay{position:fixed;inset:0;background:#0f172a73;display:flex;align-items:center;justify-content:center;z-index:1000}.v2-info-popup{width:560px;max-width:90vw;max-height:80vh;display:flex;flex-direction:column;background:#fff;border-radius:8px;overflow:hidden;box-shadow:0 12px 32px #00000040}.v2-info-popup-header{display:flex;align-items:center;justify-content:space-between;background:#4077ad;padding:14px 16px}.v2-info-popup-title{color:#fff;font-size:15px;font-weight:600}.v2-info-popup-close{background:transparent;border:none;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:2px}.v2-info-popup-body{padding:16px;font-size:13px;line-height:1.6;color:#69707d;white-space:pre-line;overflow-y:auto}.v2-footer{display:flex;align-items:center;justify-content:flex-end;gap:12px;padding:8px 32px 24px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v2-footer{padding:8px 16px 20px}}.v2-back-btn{display:inline-flex;align-items:center;gap:7px;padding:10px 20px;border-radius:5px;font-size:14px;font-weight:500;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:#69707d;border:1.5px solid #69707D;cursor:pointer;transition:color .18s,border-color .18s,background .18s}.v2-back-btn:hover{color:#fff;background:#565c66;border-color:#565c66}.v2-continue-btn{display:inline-flex;align-items:center;gap:9px;padding:10px 24px;border-radius:5px;font-size:14px;font-weight:600;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:linear-gradient(135deg,#4077ad 0% 100%);border:none;cursor:pointer;box-shadow:0 4px 14px #4077ad4d;transition:transform .15s,box-shadow .15s}.v2-continue-btn:hover:not(:disabled){transform:translateY(-1px)}.v2-continue-btn:disabled{background:#e2e8f0;color:#94a3b8;box-shadow:none;cursor:not-allowed}.ip-header{display:flex;align-items:flex-start;gap:16px;padding:28px 32px 16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.ip-header{padding:20px 16px 12px;gap:12px}}.ip-header-icon{flex-shrink:0;width:48px;height:48px;border-radius:50%;border:1px solid #c7c7c7;display:flex;align-items:center;justify-content:center;color:#959191;margin-top:2px}.ip-title{font-size:18px;font-weight:700;color:#69707d;margin:0 0 6px;line-height:1.25;letter-spacing:-.02em;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.ip-sub{font-size:14px;color:#69707d;line-height:1.65;margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.ip-section{margin:0 24px 14px;background:#fff;border:1.5px solid #e2e8f0;border-radius:5px;padding:18px 20px 16px;box-shadow:0 1px 4px #0000000a}@media (max-width: 767px){.ip-section{margin:0 12px 10px;padding:14px}}.ip-section-label{font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:#6b7280;margin:0 0 12px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.ip-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:12px}@media (max-width: 767px){.ip-grid-2{grid-template-columns:1fr}}.ip-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px}@media (max-width: 1024px){.ip-grid-3{grid-template-columns:1fr 1fr}}@media (max-width: 599px){.ip-grid-3{grid-template-columns:1fr}}.ip-grid-4{display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:12px}@media (max-width: 1024px){.ip-grid-4{grid-template-columns:1fr 1fr}}@media (max-width: 599px){.ip-grid-4{grid-template-columns:1fr}}.ip-field{display:flex;flex-direction:column;gap:5px}.ip-label{font-size:12px;font-weight:600;color:#69707d;margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;line-height:1.3}.ip-required{color:#dc2626;margin-left:2px;font-weight:700}.ip-input{width:100%;height:44px;padding:0 14px;border:1.5px solid #e2e8f0;border-radius:5px;font-size:14px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;background:#fff;outline:none;transition:border-color .18s,box-shadow .18s;box-sizing:border-box}.ip-input::placeholder{color:#adb5bd;font-weight:400}.ip-input:focus{border-color:#4077ad;box-shadow:0 0 0 3px #4077ad1a}.ip-input.ip-input--invalid{border-color:#dc2626;background:#fff8f8}.ip-input.ip-input--invalid:focus{box-shadow:0 0 0 3px #dc26261a}.ip-input[readonly]{cursor:pointer;background:#f8fafc}.ip-error{display:flex;align-items:center;gap:4px;font-size:12px;font-weight:500;color:#dc2626;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.ip-upload-wrap{position:relative;display:flex;align-items:center}.ip-upload-icon{position:absolute;right:14px;width:16px;height:16px;cursor:pointer;opacity:.45;transition:opacity .18s}.ip-upload-icon:hover{opacity:.85}.ip-upload-hint{margin-top:6px;font-size:12px}.ip-copy-row{display:flex;align-items:center;gap:10px;margin:0 24px 12px;padding:11px 16px;background:#eff6ff;border:1.5px solid #bfdbfe;border-radius:10px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.ip-copy-row{margin:0 12px 10px}}.ip-copy-check{width:16px;height:16px;accent-color:#4077AD;cursor:pointer;flex-shrink:0}.ip-copy-label{font-size:14px;font-weight:500;color:#69707d;cursor:pointer;margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;-webkit-user-select:none;user-select:none}.ip-footer{display:flex;align-items:center;justify-content:flex-end;gap:12px;padding:8px 24px 28px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.ip-footer{padding:8px 16px 24px}}.ip-back-btn{display:inline-flex;align-items:center;gap:7px;padding:10px 20px;border-radius:5px;font-size:14px;font-weight:500;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:#69707d;border:1.5px solid #69707D;cursor:pointer;transition:color .18s,border-color .18s,background .18s}.ip-back-btn:hover{color:#fff;border-color:#565c66;background:#565c66}.ip-next-btn{display:inline-flex;align-items:center;gap:9px;padding:10px 26px;border-radius:5px;font-size:14px;font-weight:600;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:linear-gradient(135deg,#4077ad 0% 100%);border:none;cursor:pointer;box-shadow:0 4px 14px #4077ad4d;transition:transform .15s,box-shadow .15s}.ip-next-btn:hover:not(:disabled){transform:translateY(-1px)}.ip-next-btn:active:not(:disabled){transform:translateY(0)}.ip-next-btn:disabled{background:#e2e8f0;color:#94a3b8;box-shadow:none;cursor:not-allowed}.v5-wrap{display:flex;flex-direction:column;align-items:center;text-align:center;padding:48px 32px 40px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v5-wrap{padding:36px 20px 32px}}.v5-icon{width:72px;height:72px;border-radius:50%;background:linear-gradient(135deg,#dcfce7,#bbf7d0);border:1.5px solid #86efac;display:flex;align-items:center;justify-content:center;color:#16a34a;margin-bottom:20px;box-shadow:0 0 0 8px #22c55e14}.v5-title{font-size:18px;font-weight:800;color:#69707d;margin:0 0 10px;letter-spacing:-.025em;line-height:1.2}.v5-sub{font-size:14px;color:#69707d;margin:0 0 28px;line-height:1.6;max-width:480px}.v5-cards{display:flex;flex-direction:column;gap:12px;width:100%;max-width:520px;margin-bottom:32px;text-align:left}.v5-card{display:flex;align-items:flex-start;gap:14px;padding:16px 18px;border-radius:12px;border:1.5px solid #e2e8f0;background:#f8fafc;box-shadow:0 1px 3px #0000000a}.v5-card-icon{flex-shrink:0;width:36px;height:36px;border-radius:9px;background:#eff6ff;border:1px solid #bfdbfe;display:flex;align-items:center;justify-content:center;color:#4077ad}.v5-card-icon.v5-card-icon--green{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a}.v5-card-text{font-size:14px;color:#69707d;line-height:1.6;margin:0}.v5-cta{display:inline-flex;align-items:center;gap:10px;padding:13px 32px;border-radius:5px;font-size:14px;font-weight:600;font-family:inherit;color:#fff;background:linear-gradient(135deg,#4077ad 0% 100%);border:none;cursor:pointer;box-shadow:0 4px 16px #4077ad52;transition:transform .15s,box-shadow .15s}.v5-cta:hover{transform:translateY(-2px)}.v5-cta:active{transform:translateY(0)}.cc-select-wrap{margin-bottom:20px}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-select-container{border:1.5px solid #e2e8f0;border-radius:10px;min-height:48px;padding:5px 10px;background:#fff;box-shadow:none;cursor:text;transition:border-color .18s,box-shadow .18s}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-select-container:hover{border-color:#94a3b8}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple.ng-select-focused .ng-select-container{border-color:#4077ad;box-shadow:0 0 0 3px #4077ad1a}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-container{flex-wrap:wrap;gap:6px;padding:2px 0}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value{display:inline-flex;flex-direction:row;align-items:center;gap:5px;background:#eff6ff;border:1px solid #bfdbfe;border-radius:99px;padding:4px 8px 4px 13px;font-size:12px;font-weight:600;color:#4077ad;margin:0;line-height:1}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-label{order:1}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-icon{display:inline-flex;align-items:center;justify-content:center;order:2;width:16px;height:16px;border-radius:50%;font-size:12px;font-weight:700;line-height:1;padding:0;background:#4077ad26;color:#4077ad;cursor:pointer;flex-shrink:0;transition:background .15s,color .15s}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-icon:hover{background:#4077ad;color:#fff}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-icon.right{display:none}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-placeholder{font-size:14px;color:#adb5bd;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-select-container.ng-has-value .ng-placeholder{display:none}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-input>input{font-size:14px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-arrow-wrapper{padding-right:6px}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-arrow-wrapper .ng-arrow{border-color:#94a3b8 transparent transparent;border-width:5px 4px 0}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-clear-wrapper{color:#94a3b8}::ng-deep .ng-dropdown-panel{border:1.5px solid #e2e8f0;border-radius:12px;box-shadow:0 8px 28px #0000001a,0 2px 8px #0000000f;overflow:hidden;margin-top:5px;z-index:9999!important;background:#fff!important}::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items{padding:6px}::ng-deep .ng-dropdown-panel .ng-option{border-radius:8px;padding:10px 13px;font-size:14px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;transition:background .12s}::ng-deep .ng-dropdown-panel .ng-option.ng-option-selected{background:#eff6ff;color:#4077ad;font-weight:600}::ng-deep .ng-dropdown-panel .ng-option.ng-option-marked:not(.ng-option-selected){background:#f8fafc;color:#69707d}::ng-deep .ng-dropdown-panel .ng-option.ng-option-selected.ng-option-marked{background:#dbeafe}.cc-group{margin-bottom:18px;padding-top:4px}.cc-group:last-child{margin-bottom:0}.cc-hidden-check{position:absolute;opacity:0;width:0;height:0;pointer-events:none}.cc-select-all-pill{display:inline-flex;align-items:center;gap:6px;padding:7px 16px;border-radius:99px;border:1.5px solid #e2e8f0;background:#f8fafc;font-size:12px;font-weight:700;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;cursor:pointer;-webkit-user-select:none;user-select:none;margin-bottom:10px;transition:background .18s,border-color .18s,color .18s}.cc-select-all-pill:hover:not(.cc-select-all-pill--on){background:#f1f5f9;border-color:#94a3b8}.cc-select-all-pill.cc-select-all-pill--on{background:#69707d;border-color:#69707d;color:#fff}.cc-sub-pills{display:flex;flex-wrap:wrap;gap:8px}.cc-sub-pill{display:inline-flex;align-items:center;gap:5px;padding:6px 14px;border-radius:99px;border:1.5px solid #e2e8f0;background:#fff;font-size:12px;font-weight:500;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background .15s,border-color .15s,color .15s,box-shadow .15s}.cc-sub-pill:hover:not(.cc-sub-pill--on){background:#f8fafc;border-color:#94a3b8;color:#69707d}.cc-sub-pill.cc-sub-pill--on{background:#eff6ff;border-color:#93c5fd;color:#4077ad;font-weight:600;box-shadow:0 0 0 3px #4077ad12}html,body{overscroll-behavior:none;height:100%;overflow:hidden}\n"], dependencies: [{ kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i7.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i7.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i12.NgSelectComponent, selector: "ng-select", inputs: ["bindLabel", "bindValue", "markFirst", "placeholder", "notFoundText", "typeToSearchText", "addTagText", "loadingText", "clearAllText", "appearance", "dropdownPosition", "appendTo", "loading", "closeOnSelect", "hideSelected", "selectOnTab", "openOnEnter", "maxSelectedItems", "groupBy", "groupValue", "bufferAmount", "virtualScroll", "selectableGroup", "selectableGroupAsModel", "searchFn", "trackByFn", "clearOnBackspace", "labelForId", "inputAttrs", "tabIndex", "readonly", "searchWhileComposing", "minTermLength", "editableSearchTerm", "keyDownFn", "typeahead", "multiple", "addTag", "searchable", "clearable", "isOpen", "items", "compareWith", "clearSearchOnAdd", "deselectOnClick"], outputs: ["blur", "focus", "change", "open", "close", "search", "clear", "add", "remove", "scroll", "scrollToEnd"] }, { kind: "directive", type: MaskedInputDirective, selector: "[textMask]", inputs: ["textMask"], exportAs: ["textMask"] }, { kind: "component", type: AddressVerifyFieldComponent, selector: "im-address-verify-field", inputs: ["placeholder", "options", "maxLength", "inputId", "name", "autocompleteAttr", "inputClass", "invalid", "inputStyle", "initialLat", "initialLng"], outputs: ["addressResolved", "manualEdit"] }, { kind: "component", type: TermsConditionsComponent, selector: "app-terms-conditions", inputs: ["title", "branding", "PrivacyAndTerms"], outputs: ["metaLoaded"] }, { kind: "component", type: PrivacyPolicyComponent, selector: "app-privacy-policy", inputs: ["title", "branding", "PrivacyAndTerms"], outputs: ["metaLoaded"] }, { kind: "component", type: CredentialingComponent, selector: "app-credentialing", inputs: ["signatureFileId", "signatureUrl", "data"], outputs: ["back"] }, { kind: "pipe", type: i1$2.DatePipe, name: "date" }] });
|
|
37050
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: InitialProcessComponent, isStandalone: false, selector: "app-initial-process", inputs: { providerName: "providerName" }, host: { listeners: { "window:beforeunload": "onBeforeUnload($event)" } }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div class=\"container\">\r\n <div *ngIf=\"isInitializing\" class=\"text-center p-5\">\r\n <div class=\"spinner-border text-primary\"></div>\r\n </div>\r\n <ng-container *ngIf=\"!isInitializing\">\r\n <div class=\"mb-4 logout-container\" *ngIf=\"showlogout\">\r\n <button class=\"logout-btn\" (click)=\"logout()\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4\"/>\r\n <polyline points=\"16 17 21 12 16 7\"/>\r\n <line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\"/>\r\n </svg>\r\n Logout\r\n </button>\r\n </div>\r\n <div class=\"card pb-2 mob pr-5\" style=\"margin-bottom: 30px;\">\r\n <div [hidden]=\"view !== 1\">\r\n\r\n <!-- \u2500\u2500 Welcome Banner \u2500\u2500 -->\r\n <div class=\"v1-welcome\">\r\n <div class=\"v1-welcome-icon\">\r\n <svg width=\"26\" height=\"26\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2\"/>\r\n <circle cx=\"9\" cy=\"7\" r=\"4\"/>\r\n <path d=\"M23 21v-2a4 4 0 00-3-3.87\"/>\r\n <path d=\"M16 3.13a4 4 0 010 7.75\"/>\r\n </svg>\r\n </div>\r\n <div class=\"v1-welcome-text\">\r\n <h2 class=\"v1-welcome-title\">Welcome to <span class=\"v1-brand\">{{ branding.displayName }}</span></h2>\r\n <p class=\"v1-welcome-sub\">Our members and service providers rely on accurate info in your profile to connect\r\n you with work that suits your capabilities. Keep your profile complete, skills updated, licenses current,\r\n photos and logos professional, and schedule up to date.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Main Body: agreements + signature \u2500\u2500 -->\r\n <div class=\"v1-body\">\r\n\r\n <!-- Left: agreement cards -->\r\n <div class=\"v1-agreements\">\r\n\r\n <!-- Terms card -->\r\n <div class=\"v1-agreement-card\" [class.v1-card--agreed]=\"model.acceptTerms\"\r\n [class.v1-card--invalid]=\"!model.acceptTerms && validatePage==1\">\r\n <div class=\"v1-card-icon\">\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z\"/>\r\n <polyline points=\"14 2 14 8 20 8\"/>\r\n <line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\"/>\r\n <line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\"/>\r\n </svg>\r\n </div>\r\n <div class=\"v1-card-body\">\r\n <p class=\"v1-card-title\">Terms and Conditions</p>\r\n <p class=\"v1-card-sub\">Read and accept to continue</p>\r\n </div>\r\n <button type=\"button\" class=\"v1-agree-btn\" [class.v1-agree-btn--done]=\"model.acceptTerms\"\r\n [disabled]=\"isTermsLoading\"\r\n (click)=\"openModal(termsAndConditionsModel,'Terms and Conditions',$event)\">\r\n <span class=\"v1-agree-spinner\" *ngIf=\"isTermsLoading\"></span>\r\n <svg *ngIf=\"!isTermsLoading && model.acceptTerms\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n {{ isTermsLoading ? 'Loading...' : (model.acceptTerms ? 'Agreed' : 'Read & Agree') }}\r\n </button>\r\n </div>\r\n\r\n <!-- Privacy card -->\r\n <div class=\"v1-agreement-card\" [class.v1-card--agreed]=\"model.privacy\"\r\n [class.v1-card--invalid]=\"!model.privacy && validatePage==1\">\r\n <div class=\"v1-card-icon\">\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"/>\r\n </svg>\r\n </div>\r\n <div class=\"v1-card-body\">\r\n <p class=\"v1-card-title\">Privacy Statement</p>\r\n <p class=\"v1-card-sub\">Read and accept to continue</p>\r\n </div>\r\n <button type=\"button\" class=\"v1-agree-btn\" [class.v1-agree-btn--done]=\"model.privacy\"\r\n [disabled]=\"isPrivacyLoading\"\r\n (click)=\"openModal(termsAndConditionsModel,'Privacy Statement',$event)\">\r\n <span class=\"v1-agree-spinner\" *ngIf=\"isPrivacyLoading\"></span>\r\n <svg *ngIf=\"!isPrivacyLoading && model.privacy\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n {{ isPrivacyLoading ? 'Loading...' : (model.privacy ? 'Agreed' : 'Read & Agree') }}\r\n </button>\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- Right: signature pad -->\r\n <div class=\"v1-signature\">\r\n <div class=\"v1-sig-header\">\r\n <span class=\"v1-sig-label\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M17 3a2.828 2.828 0 114 4L7.5 20.5 2 22l1.5-5.5L17 3z\"/>\r\n </svg>\r\n Signature\r\n </span>\r\n <button (click)=\"clearPad()\" class=\"v1-clear-btn\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M18 6L6 18M6 6l12 12\"/>\r\n </svg>\r\n Clear\r\n </button>\r\n </div>\r\n <div class=\"v1-sig-pad\">\r\n <div [ngClass]=\"{'d-none': signaturePadData?.publicUrl}\" style=\"width:100%\">\r\n <canvas #canvas></canvas>\r\n </div>\r\n <div [ngClass]=\"{'d-none': !signaturePadData?.publicUrl}\" style=\"width:100%\">\r\n <img [src]=\"signaturePadData?.publicUrl\" alt style=\"width:100%;height:120px;object-fit:contain;display:block;\">\r\n </div>\r\n <p class=\"v1-sig-hint\" *ngIf=\"!signaturePadData?.publicUrl && (!points || !points?.length)\">\r\n Draw your signature here\r\n </p>\r\n </div>\r\n <div *ngIf=\"validatePage==1 && (!points || !points?.length || points.length==0) && !fileData\"\r\n class=\"v1-error-msg\">\r\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/>\r\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>\r\n </svg>\r\n Signature is required\r\n </div>\r\n <div *ngIf=\"uploadError\" class=\"v1-error-msg\">{{ uploadError }}</div>\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- \u2500\u2500 Continue Button \u2500\u2500 -->\r\n <div class=\"v1-footer\">\r\n <button class=\"v1-continue-btn\" (click)=\"next(2)\"\r\n [disabled]=\"((!points || !points?.length || points.length==0) && !fileData && !signaturePadData?.publicUrl) || !model.acceptTerms || !model.privacy\">\r\n <span *ngIf=\"!showLoader\">Continue</span>\r\n <span *ngIf=\"showLoader\" class=\"v1-spinner\"></span>\r\n <svg *ngIf=\"!showLoader\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n </div>\r\n <ng-container *ngIf=\"view == 2\">\r\n\r\n <!-- \u2500\u2500 Role-select header \u2500\u2500 -->\r\n <div class=\"v2-header\">\r\n <div class=\"v2-header-icon\">\r\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"8\" r=\"4\"/>\r\n <path d=\"M6 20v-2a4 4 0 014-4h4a4 4 0 014 4v2\"/>\r\n </svg>\r\n </div>\r\n <div>\r\n <h2 class=\"v2-title\">Choose your role</h2>\r\n <p class=\"v2-sub\">Choose the areas you'd like to be part of \u2014 programs, services, events, or\r\n collaborations. Connect your business to others and prospective clients.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Role cards grid \u2500\u2500 -->\r\n <div class=\"v2-grid\">\r\n <ng-container *ngFor=\"let userType of userViewRoles\">\r\n <div class=\"v2-role-card\" [class.v2-role-card--active]=\"userType.value === selectedRoleValue\"\r\n (click)=\"selectedUserRole(userType); toggleTooltip($event, userType)\">\r\n <button type=\"button\" class=\"v2-role-info-btn\" *ngIf=\"userType.details\"\r\n (click)=\"openInfoPopup($event, userType)\" title=\"More info\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\r\n <line x1=\"12\" y1=\"11\" x2=\"12\" y2=\"16\"/>\r\n <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"/>\r\n </svg>\r\n </button>\r\n <div class=\"v2-role-img-wrap\">\r\n <img [src]=\"userType?.img\" alt=\"\">\r\n </div>\r\n <span class=\"v2-role-name\">{{userType.name}}</span>\r\n <span class=\"v2-role-subtitle\" *ngIf=\"userType.subtitle\">{{userType.subtitle}}</span>\r\n <div class=\"v2-role-tooltip\" *ngIf=\"userType.tooltip\">{{userType.tooltip}}</div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Role tooltip (mobile: centered overlay) \u2500\u2500 -->\r\n <div class=\"v2-tooltip-overlay\" *ngIf=\"activeTooltipRole?.tooltip\" (click)=\"closeTooltip()\">\r\n <div class=\"v2-tooltip-popup\" (click)=\"$event.stopPropagation()\">\r\n {{ activeTooltipRole.tooltip }}\r\n </div>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Role info popup \u2500\u2500 -->\r\n <div class=\"v2-info-overlay\" *ngIf=\"infoPopupRole\" (click)=\"closeInfoPopup()\">\r\n <div class=\"v2-info-popup\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"v2-info-popup-header\">\r\n <span class=\"v2-info-popup-title\">{{ infoPopupRole.name }}</span>\r\n <button type=\"button\" class=\"v2-info-popup-close\" (click)=\"closeInfoPopup()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M18 6L6 18M6 6l12 12\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n <div class=\"v2-info-popup-body\">{{ infoPopupRole.details }}</div>\r\n </div>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Footer: Back + Continue \u2500\u2500 -->\r\n <div class=\"v2-footer\">\r\n <button class=\"v2-back-btn\" (click)=\"previous()\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M19 12H5M12 5l-7 7 7 7\"/>\r\n </svg>\r\n Back\r\n </button>\r\n <button class=\"v2-continue-btn\" (click)=\"next(3)\" [disabled]=\"!isUserSelected || isLoadingSubCategories\">\r\n <span *ngIf=\"isLoadingSubCategories\" class=\"v1-spinner\"></span>\r\n <ng-container *ngIf=\"!isLoadingSubCategories\">\r\n Continue\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </ng-container>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"view == 3\">\r\n\r\n <!-- Header -->\r\n <div class=\"ip-header\">\r\n <div class=\"ip-header-icon\">\r\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z\"/>\r\n <polyline points=\"9 22 9 12 15 12 15 22\"/>\r\n </svg>\r\n </div>\r\n <div>\r\n <h2 class=\"ip-title\">Business Information</h2>\r\n <p class=\"ip-sub\">Tell us about your company so we can connect you with the right work.</p>\r\n </div>\r\n </div>\r\n\r\n <form [formGroup]=\"companyForm\">\r\n\r\n <!-- Company Details -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Company Details</p>\r\n <div class=\"ip-grid-2\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"companyName\">Company Name <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': (f.companyName.errors && validatePage == 3) || providerError}\"\r\n type=\"text\" class=\"ip-input\" id=\"companyName\" placeholder=\"Company Name\"\r\n formControlName=\"companyName\">\r\n <span *ngIf=\"f.companyName.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.companyName.errors.required\">Company Name is required</span>\r\n <span *ngIf=\"f.companyName.errors.minlength\">Minimum 2 characters</span>\r\n <span *ngIf=\"f.companyName.errors.maxLength\">Maximum 100 characters</span>\r\n </span>\r\n <span *ngIf=\"providerError\" class=\"ip-error\">{{ providerError }}</span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"inputPhone\">Phone Number <span class=\"ip-required\">*</span></label>\r\n <input class=\"ip-input\" type=\"text\" name=\"inputPhone\" placeholder=\"Company Phone Number\"\r\n id=\"inputPhone\" autocomplete=\"off\" formControlName=\"phoneNumber\" [maxLength]=\"14\"\r\n (input)=\"formatPhone($event,companyForm)\"\r\n [ngClass]=\"{'ip-input--invalid': (f.phoneNumber.errors && validatePage == 3) || providerError}\">\r\n <span *ngIf=\"f.phoneNumber.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.phoneNumber.errors.required\">Phone Number is required</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Address -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Address</p>\r\n <div class=\"ip-grid-2\" style=\"margin-bottom: 12px;\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"businessAddress\">Address Line 1 <span class=\"ip-required\">*</span></label>\r\n <im-address-verify-field formControlName=\"address1\" inputId=\"businessAddress\" [options]=\"options\"\r\n inputClass=\"\" [inputStyle]=\"addressInputStyle\" placeholder=\"Business Address 1\"\r\n [invalid]=\"f.address1.errors && validatePage == 3\"\r\n [initialLat]=\"f.latitude.value\" [initialLng]=\"f.longitude.value\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"\r\n (manualEdit)=\"onCompanyAddressManualEdit()\"></im-address-verify-field>\r\n <span *ngIf=\"f.address1.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.address1.errors.required\">Business Address 1 is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"businessAddress2\">Address Line 2</label>\r\n <input type=\"text\" class=\"ip-input\" id=\"businessAddress2\" placeholder=\"Business Address 2\">\r\n </div>\r\n </div>\r\n <div class=\"ip-grid-4\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"City\">City <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': f.city.errors && validatePage == 3}\"\r\n type=\"text\" class=\"ip-input\" id=\"City\" placeholder=\"City\" formControlName=\"city\">\r\n <span *ngIf=\"f.city.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.city.errors.required\">City is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"State\">State <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': f.state.errors && validatePage == 3}\"\r\n type=\"text\" class=\"ip-input\" id=\"State\" placeholder=\"State\" formControlName=\"state\">\r\n <span *ngIf=\"f.state.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.state.errors.required\">State is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"Zipcode\">Zipcode <span class=\"ip-required\">*</span></label>\r\n <input [textMask]=\"{ mask: zipcodeMask }\"\r\n [ngClass]=\"{'ip-input--invalid': f.zipcode.errors && validatePage == 3}\"\r\n type=\"text\" class=\"ip-input\" id=\"Zipcode\" placeholder=\"Zipcode\" formControlName=\"zipcode\">\r\n <span *ngIf=\"f.zipcode.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.zipcode.errors.required\">Zipcode is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"Country\">Country <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': f.country.errors && validatePage == 3}\"\r\n type=\"text\" class=\"ip-input\" id=\"Country\" placeholder=\"Country\" formControlName=\"country\">\r\n <span *ngIf=\"f.country.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.country.errors.required\">Country is required</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </form>\r\n\r\n <!-- Company Logo (intentionally outside formGroup) -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Company Logo</p>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\">Company Logo <span class=\"ip-required\">*</span></label>\r\n <div class=\"ip-upload-wrap\">\r\n <input #uploadLogoInput type=\"file\" accept=\".png,.jpg,.jpeg\" (change)=\"uploadLogo($event)\"\r\n class=\"upload-initial-input rounded-circle opacity-0 position-absolute\" />\r\n <input (click)=\"uploadImage2.click()\" [(ngModel)]=\"logoName\" readonly type=\"text\"\r\n class=\"ip-input\" placeholder=\"Click to upload company logo\">\r\n <img #uploadImage2 class=\"ip-upload-icon\" (click)=\"uploadLogoInput.click()\"\r\n src=\"assets/images/icons/upload.svg\" alt=\"Upload\">\r\n </div>\r\n <small class=\"ip-upload-hint text-muted d-block\">Allowed formats: PNG, JPG, JPEG</small>\r\n <span *ngIf=\"isLogoRequired\" class=\"ip-error\">Please upload a company logo</span>\r\n <span *ngIf=\"isneeded\" class=\"ip-error\">Company Logo is required</span>\r\n </div>\r\n </div>\r\n\r\n <!-- Contractor Category -->\r\n <div *ngIf=\"selectedRole?.name == 'Contractor'\" class=\"ip-section\">\r\n <p class=\"ip-section-label\">Contractor Category</p>\r\n\r\n <!-- Category selector \u2014 ng-select logic intact, restyled as pill tag-input -->\r\n <div class=\"cc-select-wrap\">\r\n <ng-select [items]=\"contractorSubCategories\" bindLabel=\"name\" [multiple]=\"true\" [closeOnSelect]=\"false\"\r\n (ngModelChange)=\"changeContractor($event)\" [(ngModel)]=\"selectedContractorCategories\"\r\n >\r\n </ng-select>\r\n </div>\r\n\r\n <!-- Sub-items as pill chips per selected category -->\r\n <ng-container *ngFor=\"let item of selectedContractorCategories; let i=index\">\r\n <div class=\"cc-group\">\r\n\r\n <!-- \"Select all\" toggle pill for this category -->\r\n <label class=\"cc-select-all-pill\" [class.cc-select-all-pill--on]=\"item.selectAll\">\r\n <input type=\"checkbox\" [(ngModel)]=\"item.selectAll\" [name]=\"item?.id\" [id]=\"item?.id\"\r\n (change)=\"selectAll($event,item?.items)\" class=\"cc-hidden-check\">\r\n <svg *ngIf=\"item.selectAll\" width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n {{ item?.name }} \u2014 Select all\r\n </label>\r\n\r\n <!-- Individual sub-item pills -->\r\n <div class=\"cc-sub-pills\">\r\n <label *ngFor=\"let subItem of item?.items\" class=\"cc-sub-pill\"\r\n [class.cc-sub-pill--on]=\"subItem.selected\">\r\n <input type=\"checkbox\" [(ngModel)]=\"subItem.selected\" [name]=\"subItem?.id\" [id]=\"subItem?.id\"\r\n (change)=\"unCheckedEvent($event,item)\" class=\"cc-hidden-check\">\r\n <svg *ngIf=\"subItem.selected\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n {{ subItem?.name }}\r\n </label>\r\n </div>\r\n\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"ip-footer\">\r\n <button class=\"ip-back-btn\" (click)=\"previous()\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M19 12H5M12 5l-7 7 7 7\"/>\r\n </svg>\r\n Back\r\n </button>\r\n <button class=\"ip-next-btn\" (click)=\"next(4)\">\r\n Continue\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"view == 4\">\r\n\r\n <!-- Header -->\r\n <div class=\"ip-header\">\r\n <div class=\"ip-header-icon\">\r\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"8\" r=\"4\"/>\r\n <path d=\"M6 20v-2a4 4 0 014-4h4a4 4 0 014 4v2\"/>\r\n </svg>\r\n </div>\r\n <div>\r\n <h2 class=\"ip-title\">Your Profile</h2>\r\n <p class=\"ip-sub\">We need a few basics and a headshot to complete your profile.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Copy from provider toggle -->\r\n <div *ngIf=\"isBusiness\" class=\"ip-copy-row\">\r\n <input [(ngModel)]=\"isCopy\" type=\"checkbox\" name=\"isCopy\" id=\"isCopy\"\r\n class=\"ip-copy-check\" (change)=\"changeAddressUser()\">\r\n <label for=\"isCopy\" class=\"ip-copy-label\">Copy from Provider Information</label>\r\n </div>\r\n\r\n <form [formGroup]=\"userForm\">\r\n\r\n <!-- Personal Details -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Personal Details</p>\r\n <div class=\"ip-grid-3\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"firstName\">First Name <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.firstName.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" placeholder=\"First Name\" formControlName=\"firstName\" id=\"firstName\">\r\n <span *ngIf=\"u.firstName.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.firstName.errors.required\">First Name is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"lastName\">Last Name <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.lastName.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" placeholder=\"Last Name\" formControlName=\"lastName\" id=\"lastName\">\r\n <span *ngIf=\"u.lastName.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.lastName.errors.required\">Last Name is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"email\">Email <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.email.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" placeholder=\"Email\" formControlName=\"email\" id=\"email\">\r\n <span *ngIf=\"u.email.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.email.errors.required\">Email is required</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Home Address -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Home Address</p>\r\n <div class=\"ip-field\" style=\"margin-bottom: 12px;\">\r\n <label class=\"ip-label\" for=\"address1\">Address Line 1 <span class=\"ip-required\">*</span></label>\r\n <im-address-verify-field formControlName=\"address1\" inputId=\"address1\" [options]=\"options\"\r\n inputClass=\"\" [inputStyle]=\"addressInputStyle\" placeholder=\"Home Address 1\"\r\n [invalid]=\"u.address1.errors && validatePage == 4\"\r\n [initialLat]=\"u.latitude.value\" [initialLng]=\"u.longitude.value\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"\r\n (manualEdit)=\"onUserAddressManualEdit()\"></im-address-verify-field>\r\n <span *ngIf=\"u.address1.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.address1.errors.required\">Home Address 1 is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-grid-3\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"homeAddress2\">Address Line 2</label>\r\n <input type=\"text\" class=\"ip-input\" id=\"homeAddress2\" formControlName=\"address2\"\r\n placeholder=\"Home Address 2\">\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"City\">City <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.city.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" id=\"City\" placeholder=\"City\" formControlName=\"city\">\r\n <span *ngIf=\"u.city.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.city.errors.required\">City is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"State\">State <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.state.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" id=\"State\" placeholder=\"State\" formControlName=\"state\">\r\n <span *ngIf=\"u.state.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.state.errors.required\">State is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"Zipcode\">Zipcode <span class=\"ip-required\">*</span></label>\r\n <input [textMask]=\"{ mask: zipcodeMask }\"\r\n [ngClass]=\"{'ip-input--invalid': u.zipcode.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" id=\"Zipcode\" placeholder=\"Zipcode\" formControlName=\"zipcode\">\r\n <span *ngIf=\"u.zipcode.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.zipcode.errors.required\">Zipcode is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"Country\">Country <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.country.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" id=\"Country\" placeholder=\"Country\" formControlName=\"country\">\r\n <span *ngIf=\"u.country.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.country.errors.required\">Country is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"inputPhone\">Phone Number <span class=\"ip-required\">*</span></label>\r\n <input class=\"ip-input\" type=\"text\" (input)=\"formatPhone($event,userForm)\"\r\n name=\"inputPhone\" placeholder=\"Phone Number\" id=\"inputPhone\" autocomplete=\"off\"\r\n formControlName=\"phoneNumber\" [maxLength]=\"14\"\r\n [ngClass]=\"{'ip-input--invalid': u.phoneNumber.errors && validatePage == 4}\">\r\n <span *ngIf=\"u.phoneNumber.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.phoneNumber.errors.required\">Phone Number is required</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </form>\r\n\r\n <!-- Profile Picture (intentionally outside formGroup) -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Profile Picture</p>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\">Profile Picture <span class=\"ip-required\">*</span></label>\r\n <div class=\"ip-upload-wrap\">\r\n <input #uploadFile type=\"file\" accept=\".png,.jpg,.jpeg\" (change)=\"uploadUserImage($event)\"\r\n class=\"upload-initial-input rounded-circle opacity-0 position-absolute\" />\r\n <input (click)=\"uploadImage1.click()\" [(ngModel)]=\"fileName\" readonly type=\"text\"\r\n class=\"ip-input\" id=\"upload\" accept=\".png,.jpg,.jpeg\" placeholder=\"Click to upload profile picture\">\r\n <img #uploadImage1 class=\"ip-upload-icon\" (click)=\"uploadFile.click()\"\r\n src=\"assets/images/icons/upload.svg\" alt=\"Upload\">\r\n </div>\r\n <small class=\"ip-upload-hint text-muted d-block\">Allowed formats: PNG, JPG, JPEG</small>\r\n <span *ngIf=\"isImageRequired\" class=\"ip-error\">Please upload a profile image</span>\r\n <span *ngIf=\"userError\" class=\"ip-error\">{{ userError }}</span>\r\n </div>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"ip-footer\">\r\n <button class=\"ip-back-btn\" (click)=\"previous()\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M19 12H5M12 5l-7 7 7 7\"/>\r\n </svg>\r\n Back\r\n </button>\r\n <button class=\"ip-next-btn\" (click)=\"next(5)\" [disabled]=\"showLoader\">\r\n <span *ngIf=\"!showLoader\">Continue</span>\r\n <span *ngIf=\"showLoader\" class=\"v1-spinner\"></span>\r\n <svg *ngIf=\"!showLoader\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"view == 5\">\r\n <div class=\"v5-wrap\">\r\n\r\n <!-- Success icon -->\r\n <div class=\"v5-icon\">\r\n <svg width=\"36\" height=\"36\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M22 11.08V12a10 10 0 11-5.93-9.14\"/>\r\n <polyline points=\"22 4 12 14.01 9 11.01\"/>\r\n </svg>\r\n </div>\r\n\r\n <h2 class=\"v5-title\">You're all set!</h2>\r\n <p class=\"v5-sub\">Account created successfully. Next step: complete your profile.</p>\r\n\r\n <!-- Info cards -->\r\n <div class=\"v5-cards\">\r\n <div class=\"v5-card\">\r\n <div class=\"v5-card-icon\">\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\r\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/>\r\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>\r\n </svg>\r\n </div>\r\n <p class=\"v5-card-text\">Profile completion is mandatory to participate in rosters, programs, requests, and platform workflows. Incomplete profiles will have limited access.</p>\r\n </div>\r\n <div class=\"v5-card\">\r\n <div class=\"v5-card-icon v5-card-icon--green\">\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><path d=\"M3 9h18M9 21V9\"/>\r\n </svg>\r\n </div>\r\n <p class=\"v5-card-text\">You may access your dashboard at any time, but full functionality is available only after profile completion.</p>\r\n </div>\r\n </div>\r\n\r\n <button (click)=\"dashboard()\" class=\"v5-cta\">\r\n Go to Dashboard\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </button>\r\n\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"view == 10\">\r\n <app-credentialing (back)=\"onCredentialingBack()\" [data]=\"credentialingData\" [signatureFileId]=\"signatureFileId\"\r\n [signatureUrl]=\"signatureUrl\"></app-credentialing>\r\n </ng-container>\r\n </div>\r\n</ng-container>\r\n</div>\r\n\r\n<ng-template #termsAndConditionsModel>\r\n <div class=\"modal-dialog modal-dialog-centered tc-modal-dialog\">\r\n <div class=\"modal-content tc-modal\">\r\n\r\n <!-- HEADER -->\r\n <div class=\"tc-modal-header\">\r\n \r\n <h4 class=\"tc-modal-title\">{{ termsAndConditionTitle }}</h4>\r\n <span class=\"tc-modal-meta\" *ngIf=\"legalMeta\">Last Modified: {{ legalMeta.createdDate | date:'MMM d, y, h:mm:ss a' }}, {{ legalMeta.versionName }}</span>\r\n </div>\r\n\r\n\r\n <div class=\"tc-scroll-wrapper\">\r\n <div class=\"tc-modal-body\"\r\n (scroll)=\"onTermsScroll($event)\">\r\n <ng-container *ngIf=\"termsAndConditionTitle == 'Terms and Conditions'\">\r\n <app-terms-conditions [PrivacyAndTerms]=\"privacyAndTerms\" [title]=\"title\" [branding]=\"branding\"\r\n (metaLoaded)=\"onLegalMetaLoaded($event)\">\r\n </app-terms-conditions>\r\n </ng-container>\r\n <ng-container *ngIf=\"termsAndConditionTitle != 'Terms and Conditions'\">\r\n <app-privacy-policy [PrivacyAndTerms]=\"privacyAndTerms\" [title]=\"title\" [branding]=\"branding\"\r\n (metaLoaded)=\"onLegalMetaLoaded($event)\">\r\n </app-privacy-policy>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Floating scroll-to-bottom button -->\r\n <button class=\"tc-scroll-fab\" *ngIf=\"!isAgreeEnabled && legalMeta\" (click)=\"scrollToBottomClick($event)\"\r\n title=\"Scroll to bottom\">\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 5v14M5 15l7 7 7-7\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <!-- FOOTER -->\r\n <div class=\"tc-modal-footer\">\r\n <button type=\"button\" class=\"tc-btn tc-btn-decline\"\r\n (click)=\"decline(termsAndConditionTitle); modelRef.hide();\">\r\n Decline\r\n </button>\r\n <button type=\"button\" class=\"tc-btn tc-btn-agree\"\r\n [disabled]=\"!isAgreeEnabled\"\r\n (click)=\"agree(termsAndConditionTitle); modelRef.hide();\">\r\n I Agree\r\n </button>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n</ng-template>", styles: ["@charset \"UTF-8\";.brand-name{font-weight:700;font-size:calc(100% + 4px)}.spinner{width:38px;height:38px;border:dotted white;border-top:2px solid #f6f6f6;border-radius:62%;animation:spin 1.7s linear infinite;margin:-9px 0 0 -28px}@keyframes spin{to{transform:rotate(360deg)}}::ng-deep .backdrop{background-color:transparent!important}.filter-black{filter:brightness(.4)!important}.footer-view{margin-top:3rem;margin-left:0;margin-right:0}.footer-signature{margin-top:9rem}.slider-view{width:11rem;margin-left:1px}.container{margin-top:40px}.container .card{border-radius:5px}.container .header{padding:33px 10px 0}.container .header .logo{width:15%;height:80%}.container .form-control{padding:.75rem 1rem;border-color:#a1a1a1}.container .form-control:focus{color:#000;box-shadow:none;border-color:#a1a1a1!important}.container .form-control::placeholder{font-weight:500;font-size:12px;color:#a1a1a1}.container .link{color:#4077ad}.container .link-signup{font-weight:bolder}.container .form-check-label{margin-bottom:0;padding-top:9px}.container .content-view{margin-top:10%}.container .content-description{margin-top:25%}.container .tag-content{color:#fff9e8;margin-left:9%}.container .tag-content p{color:#fff9e8}.container .form-check-input:checked{background-color:#000;border-color:#000}.container .img-tick{margin:-31px 12px 0 -35px}.container .form-check-input[type=checkbox]{border-radius:2px;border:2px solid #000000}.container .form-check-input:focus{box-shadow:none}.container input[type=checkbox]{accent-color:#000000}.term-list{padding:48px 60px 6px 0;margin-left:30px;color:\"#1f1f1fdb\"}.add-tab{padding:75px 75px 6px 1px;margin-left:50px;color:\"#1f1f1fdb\"}.add-tab-view{padding:75px 75px 6px 1px;margin-left:80px;color:\"#1f1f1fdb\"}.inspect-add{margin-top:3rem}.add-btn{font-size:16px;border-radius:5px;transition:.2s;padding:.25rem .5rem;background:#fff;border:1px solid rgba(148,147,147,.1882352941);color:#444;line-height:48px;box-shadow:0 1px 9px #98a2b3;width:9rem}.add-btn:hover{border:1px solid rgba(148,147,147,.1882352941);box-shadow:none}.agree{padding:0 0 8px 47px}.agree .form-check-input[type=checkbox]{border-radius:2px;border:2px solid #98A2B3;width:14px;height:14px;margin:5px 9px 0 -35px}.agree .form-check-input:focus{box-shadow:none}.agree .form-check-input:checked{background-color:#000;border-color:#000}.agree .invalid-feedback{font-size:10px!important;margin:0 0 0 21px}.checkmark{vertical-align:text-bottom;color:#98a2b3;font-weight:500;font-size:12px}.term-signature{padding-left:16rem;padding-right:65px;position:absolute;margin:150px 0 0 50%}.participate-tab{height:135px;width:142px}.card-design{height:147px;width:147px;padding-left:10px;margin-left:42px;background:#fff0;border:2px solid #98A2B3;box-shadow:0 0 4px #98a2b3;border-radius:27px;margin-bottom:42px}.upload{height:39px;margin-top:-4px;width:126px;font-size:12px}.participate-tab{margin-top:-25px}.slider{width:14rem;margin-left:69px}.btn-clear{background:#d3dae6;color:#98a2b3;font-size:12px;border-radius:5px;transition:.2s;padding:6px;border:none;height:auto;width:46%;line-height:28px}.btn-close{background:#f1f4fa;color:#98a2b3;font-size:17px;border-radius:5px;transition:.2s;padding:6px;border:none;height:auto;font-weight:500;width:116px;color:#737a87;line-height:28px}.view-logo{padding-top:1%;padding-bottom:4%;text-align:center}.back-btn{border-radius:45px;height:41px}.next{background:#4077ad;border-radius:30px;height:60px;width:60px;border:white}.profile-field{margin-top:-10px}.profile-field input{line-height:30px;margin:-10px 3px 3px}.load-page{padding:21px 49px 13px 34px}.sign-img{width:291px;height:95px;border-radius:8px;border:1px solid rgba(179,178,178,.33);margin-top:19px}.upload-image{height:16px;width:16px;position:absolute;margin-left:66rem;margin-top:-39px}.para-comma{font-weight:500}.go-btn{border-radius:45px;height:50px;padding:0 20px;background:#4077ad;border:1px solid #4077ad;color:#fff;line-height:28px;font-size:14px;font-weight:500}.text-label{color:#747b83;font-weight:500}.form{padding:20px;border-radius:5px}.form-control:focus{color:#000;box-shadow:none;border-color:#848484!important}.form-control::placeholder{font-weight:500;font-size:12px;color:#bec1be;padding-left:10px}.btn-primary:active{background-color:#50575e}@media screen and (min-width: 500px) and (max-width: 769px){.content-view{background:#0c1620;width:44rem;margin:31px 0 0!important;padding:28px 32px 17px 71px!important;border-radius:29px}.upload-image{margin-left:25rem!important}}@media screen and (min-width: 768px) and (max-width: 1024px){.back-btn{height:31px;width:82px;position:absolute;margin-left:-53px}.back-tab{position:absolute;margin-left:-87px;height:37px}.go-btn{width:175px;height:44px}.term-signature{padding-left:10px}.upload-image{margin-left:40rem}}@media screen and (min-width: 374px) and (max-width: 426px){.head-logo{width:216px;padding-bottom:16px}.slider{visibility:hidden}.back-btn{height:31px;width:82px;position:absolute;margin-left:73px;margin-top:23px}.go-btn{width:175px;height:44px}.upload-image{margin-left:16rem}.term-signature{margin:84% 0 7px 4%}}@media screen and (min-width: 320px) and (max-width: 426px){.footer-signature{margin-top:20rem}.login .head-logo{padding:16px 2px 0;width:38%!important;height:40%!important}.container{margin-top:5px!important}.card{padding:2px!important}.tag-content{margin:3% 0 0!important;background-color:#121b24;border-radius:13px}.img-tick{margin:3px!important}.slider{visibility:hidden}.load-page{padding:0}.head-logo{width:216px;padding-bottom:16px}.back-btn{height:26px;width:71px;position:absolute;margin-left:-17rem!important;font-size:10px;margin-top:23px}.go-btn{width:142px;height:36px;margin-right:-28px;font-size:10px}.add-tab,.add-tab-view{padding:30px 33px 2px 3px;margin-left:15px}.add-btn{width:6rem}.slider-tab{visibility:hidden}.back-tab{margin-left:-14rem;margin-top:1px;font-size:14px;height:39px}.participate-tab{height:96px;width:87px}.card-design{height:124px;width:125px;padding-left:17px;margin-left:30px}.term-signature{padding:22px 22px 13px 27px}.term-list{padding:43px 10px 10px 3px;margin-left:0;text-align:-webkit-center}}@media screen and (min-width: 320px) and (max-width: 376px){.agree{padding:0 0 8px 25px}.participate-tab{height:96px;width:87px}.card-design{height:109px;width:97px;padding-left:4px;margin-left:10px}.card-design h6{font-size:10px;padding-left:14px;font-weight:600}.sign-img{width:270px}.term-list{padding:20px 20px 6px 4px;margin-left:13px}}@media screen and (min-width: 320px) and (max-width: 350px){.upload-image{height:13px;width:11px;margin-left:10rem;margin-top:-35px}.btn-clear{width:92px}.term-signature{margin:84% 0 7px 4%}}.disabled-btn{cursor:not-allowed!important;background:#4077ad!important;color:#fff!important}.modal-dialog .modal-content{border-radius:12px;background:#fff!important;border:1px solid rgba(128,128,128,.3294117647)!important}.title-popup{font-size:18px;color:#0c1620}.tc-modal-dialog{max-width:min(780px,96vw)}.tc-modal{border-radius:10px!important;border:none!important;overflow:hidden;box-shadow:0 32px 72px #00000038,0 6px 20px #0000001a!important;height:min(720px,90vh);display:flex;flex-direction:column}.tc-modal-header{display:flex;align-items:center;flex-wrap:wrap;gap:6px 12px;padding:10px 28px 14px;background:#4077ad;border-bottom:none;flex-shrink:0}.tc-modal-header .tc-header-icon{width:40px;height:40px;border-radius:11px;display:flex;align-items:center;justify-content:center;color:#fff;flex-shrink:0}.tc-modal-header .tc-modal-title{font-family:Inter,system-ui,sans-serif;font-size:18px;font-weight:700;color:#fff;letter-spacing:-.01em;padding:10px;margin:0;flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tc-modal-header .tc-modal-meta{font-weight:600;font-size:12px;color:#fff;flex-shrink:0;white-space:nowrap}@media screen and (max-width: 767px){.tc-modal-header .tc-modal-header{flex-flow:column;align-items:center;text-align:center}.tc-modal-header .tc-modal-title{flex:1 1 100%;white-space:normal}.tc-modal-header .tc-modal-meta{flex:1 1 100%;opacity:.85}}.tc-scroll-hint{display:flex;align-items:center;gap:7px;padding:9px 28px;background:#f0f9ff;border-bottom:none;font-size:12px;color:#4077ad;font-family:Inter,system-ui,sans-serif;letter-spacing:.01em;flex-shrink:0}.tc-scroll-hint svg{flex-shrink:0}.tc-scroll-hint strong{font-weight:700}.tc-scroll-hint .tc-progress-pill{margin-left:auto;background:#4077ad;color:#fff;font-size:11px;font-weight:700;letter-spacing:.04em;padding:2px 9px;border-radius:99px;min-width:42px;text-align:center;transition:background .2s ease}.tc-progress-bar{height:3px;background:#e0f2fe;flex-shrink:0}.tc-progress-bar .tc-progress-fill{height:100%;background:linear-gradient(90deg,#4077ad,#38bdf8);border-radius:0 99px 99px 0;transition:width .12s ease}.tc-scroll-wrapper{position:relative;flex:1 1 auto;overflow:hidden;display:flex;flex-direction:column}.tc-modal-body{flex:1 1 auto;overflow-y:auto;padding:26px 32px;background:#fff;scrollbar-width:thin;scrollbar-color:#cbd5e1 transparent}.tc-modal-body::-webkit-scrollbar{width:5px}.tc-modal-body::-webkit-scrollbar-track{background:transparent}.tc-modal-body::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:99px}.tc-modal-body::-webkit-scrollbar-thumb:hover{background:#94a3b8}.tc-scroll-fab{position:absolute;bottom:20px;right:20px;width:46px;height:46px;border-radius:50%;background:linear-gradient(135deg,#4077ad 0% 100%);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:10;transition:transform .18s ease,box-shadow .18s ease}.tc-scroll-fab:hover{transform:translateY(-3px) scale(1.1);animation:none}@keyframes tc-fab-bounce{0%,to{transform:translateY(0);box-shadow:0 4px 18px #2563eb80}50%{transform:translateY(5px);box-shadow:0 2px 10px #2563eb59}}.tc-modal-footer{display:flex;justify-content:flex-end;align-items:center;gap:10px;padding:16px 24px;background:#f8fafc;border-top:1px solid #e2e8f0;flex-shrink:0}.tc-btn{font-family:Inter,system-ui,sans-serif;font-size:14px;font-weight:600;letter-spacing:.015em;padding:10px 26px;border-radius:5px;border:none;cursor:pointer;transition:background .18s ease,transform .15s ease}.tc-btn.tc-btn-decline{background:#b43026;color:#fff;border:1.5px solid #B43026}.tc-btn.tc-btn-decline:hover{background:#96271f;border-color:#96271f;color:#fff}.tc-btn.tc-btn-agree{background:linear-gradient(135deg,#4077ad 0% 100%);border:1.5px solid transparent;color:#fff}.tc-btn.tc-btn-agree:hover:not(:disabled){background:linear-gradient(135deg,#2d5f8a,#4077ad);transform:translateY(-1px)}.tc-btn.tc-btn-agree:disabled{background:#e2e8f0;color:#94a3b8;box-shadow:none;cursor:not-allowed}ul.term-list-data li{padding-bottom:5px;font-size:13px;font-weight:500;line-height:21px}ol,ul,dl{margin-top:0;margin-bottom:1rem}::ng-deep .modal-content{width:100%;border:none}.hidden-view{display:none}.header-container{position:relative;padding:20px}.view-logo{text-align:center}.logout-button{top:20px;right:20px;position:absolute}.logout-button button{background:none;border:none;font-size:16px;display:flex;align-items:center;cursor:pointer}.logout-button img{margin-right:5px;height:20px}.user-card{align-items:center;color:#4077ad;cursor:pointer}.user-cards-active{background:#4077ad;color:#fff}.save-btn.upload{border:1px solid #4077AD;background-color:#4077ad;color:#fff;border-radius:5px;background:#4077ad;padding:4px 10px;display:inline-flex;align-items:center;gap:6px}.save-btn.upload img{filter:brightness(0) invert(1)}.form-check.agree{display:flex;align-items:flex-start;gap:8px;margin-bottom:8px}.form-check.agree .form-check-input{margin-top:4px;flex-shrink:0}.form-check.agree .form-check-label{line-height:1.4;cursor:pointer;white-space:normal}.spinner-16{width:16px;height:16px}.h6-buttons{display:flex;align-items:center;gap:8px}.form-check.agree{display:flex;align-items:flex-start;margin-bottom:14px}.form-check-input{position:absolute;opacity:0;cursor:pointer}.form-check-label{position:relative;padding-left:28px;cursor:pointer;font-size:14px;line-height:20px;color:#212529;-webkit-user-select:none;user-select:none}.form-check-label:before{content:\"\";position:absolute;left:0;top:8px;width:18px;height:18px;border:2px solid #adb5bd;border-radius:4px;background:#fff;transition:all .2s ease}.form-check-label:after{content:\"\";position:absolute;left:5px;top:10px;width:6px;height:10px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg) scale(0);transition:transform .15s ease}.form-check-input:checked+.form-check-label:before{background-color:#4077ad;border-color:#4077ad}.form-check-input:checked+.form-check-label:after{transform:rotate(45deg) scale(1)}.form-check-label:hover:before{border-color:#4077ad}.form-check-input:focus+.form-check-label:before{box-shadow:0 0 0 3px #4077ad40}.form-check-input.is-invalid+.form-check-label:before{border-color:#dc3545}.form-check-input.is-invalid:checked+.form-check-label:before{background-color:#dc3545}.invalid-feedback{display:block;font-size:12px;margin-left:7px;margin-top:4px}::ng-deep .modal-dialog{max-width:750px}.user-cards-active{background-color:#4077ad;color:#fff;border:2px solid #4077AD}body.modal-open{overflow:hidden!important}.modal{z-index:1055!important}.modal-backdrop{z-index:1050!important}.modal-dialog{margin:auto;pointer-events:auto}.modal-content{position:relative;z-index:1060}.logout-container{display:flex;justify-content:flex-end}.logout-btn{display:inline-flex;align-items:center;gap:7px;padding:7px 16px;border-radius:5px;font-size:14px;font-weight:500;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;background:#f8fafc;border:1.5px solid #e2e8f0;cursor:pointer;transition:color .18s,background .18s,border-color .18s,box-shadow .18s}.logout-btn:hover{color:#dc2626;background:#fff5f5;border-color:#fca5a5}.logout-btn:active{transform:scale(.97)}@media screen and (max-width: 767px){.term-signature{padding-left:3rem;padding-right:0;position:unset;margin:0}.footer-signature{margin-top:0rem}.disabled-btn{position:absolute;bottom:13px;right:24px}.next{height:46px;width:46px;position:absolute;bottom:21px;right:35px}.mob{padding-bottom:4.5rem!important}.checkmark{width:85%}.terms-fixed-modal{width:unset}::ng-deep .privacy-policy-modal .logo-section{margin-bottom:0!important}.add-tab-view{padding:30px 25px 6px;margin-left:0}.user-card{width:96%}.footer .btn-mob{display:flex;align-items:center}.back-btn{position:absolute;bottom:21px;left:10px}.actions{margin:50px 34px 1px}}@media screen and (min-width: 768px) and (max-width: 1024px){.footer-signature{margin-top:3rem}}.v1-welcome{display:flex;align-items:flex-start;gap:16px;padding:28px 32px 20px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.v1-welcome-icon{flex-shrink:0;width:48px;height:48px;border-radius:50%;border:1px solid #cfd2d6;display:flex;align-items:center;justify-content:center;color:#90979d;margin-top:2px}.v1-welcome-title{font-size:18px;font-weight:700;color:#69707d;margin:0 0 6px;line-height:1.25;letter-spacing:-.02em}.v1-brand{color:#4077ad}.v1-welcome-sub{font-size:14px;color:#69707d;line-height:1.65;margin:0}.v1-body{display:grid;grid-template-columns:1fr 1fr;gap:20px;padding:0 32px 20px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v1-body{grid-template-columns:1fr;padding:0 16px 16px}}.v1-agreements{display:flex;flex-direction:column;gap:12px}.v1-agreement-card{display:flex;align-items:center;gap:14px;padding:16px 18px;border-radius:5px;border:1.5px solid #e2e8f0;background:#fff;transition:border-color .2s,box-shadow .2s;box-shadow:0 1px 3px #0000000a}.v1-agreement-card:hover{border-color:#c7d3e2;box-shadow:0 2px 8px #00000012}.v1-agreement-card.v1-card--agreed{border-color:#dde2e7}.v1-agreement-card.v1-card--invalid{border-color:#fecaca;background:#fff5f5}.v1-card-icon{flex-shrink:0;width:38px;height:38px;border-radius:5px;border:1px solid #e2e8f0;display:flex;align-items:center;justify-content:center;color:#4077ad}.v1-card--agreed .v1-card-icon{border-color:#dde2e7;color:#7e8994}.v1-card-body{flex:1 1 auto;min-width:0}.v1-card-title{font-size:14px;font-weight:600;color:#69707d;margin:0 0 2px;line-height:1.3}.v1-card-sub{font-size:12px;color:#6b7280;margin:0}.v1-agree-btn{flex-shrink:0;display:inline-flex;align-items:center;gap:5px;padding:7px 14px;border-radius:5px;font-size:12px;font-weight:600;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;border:1.5px solid #4077AD;color:#4077ad;background:transparent;cursor:pointer;white-space:nowrap;transition:background .18s,color .18s}.v1-agree-btn:hover{background:#4077ad;color:#fff}.v1-agree-btn.v1-agree-btn--done{background:#3e7f50;border-color:#3e7f50;color:#fff}.v1-agree-btn:disabled{opacity:.7;cursor:not-allowed}.v1-agree-btn:disabled:hover{background:transparent;color:#4077ad}.v1-agree-spinner{width:12px;height:12px;border:2px solid currentColor;border-top-color:transparent;border-radius:50%;flex-shrink:0;animation:v1-agree-spin .7s linear infinite}@keyframes v1-agree-spin{to{transform:rotate(360deg)}}.v1-signature{display:flex;flex-direction:column;gap:10px}.v1-sig-header{display:flex;align-items:center;justify-content:space-between}.v1-sig-label{display:inline-flex;align-items:center;gap:7px;font-size:14px;font-weight:600;color:#69707d;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.v1-clear-btn{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:500;color:#6b7280;background:transparent;border:1px solid #e2e8f0;border-radius:5px;padding:4px 10px;cursor:pointer;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;transition:color .18s,border-color .18s}.v1-clear-btn:hover{color:#dc2626;border-color:#fca5a5}.v1-sig-pad{position:relative;border-radius:5px;border:1.5px dashed #cbd5e1;overflow:hidden;min-height:120px}.v1-sig-pad canvas{display:block;cursor:crosshair;width:100%;height:120px}.v1-sig-hint{position:absolute;bottom:8px;left:50%;transform:translate(-50%);font-size:12px;color:#c0cad8;pointer-events:none;margin:0;white-space:nowrap;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.v1-error-msg{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:500;color:#dc2626;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.v1-footer{padding:8px 32px 20px;display:flex;justify-content:flex-end;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v1-footer{padding:8px 16px 20px}}.v1-continue-btn{display:inline-flex;align-items:center;gap:9px;padding:12px 28px;border-radius:5px;font-size:14px;font-weight:600;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:linear-gradient(135deg,#4077ad 0% 100%);border:none;cursor:pointer;transition:transform .15s;min-width:148px;justify-content:center}.v1-continue-btn:hover:not(:disabled){transform:translateY(-1px)}.v1-continue-btn:active:not(:disabled){transform:translateY(0)}.v1-continue-btn:disabled,.v1-continue-btn.disabled{background:#e2e8f0;color:#94a3b8;box-shadow:none;cursor:not-allowed}.v1-spinner{display:inline-block;width:16px;height:16px;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:v1-spin .65s linear infinite}@keyframes v1-spin{to{transform:rotate(360deg)}}@media (max-width: 767px){.v1-welcome{padding:20px 16px 14px;gap:12px}.v1-welcome-icon{width:40px;height:40px}.v1-welcome-title{font-size:16px}}.v2-header{display:flex;align-items:flex-start;gap:16px;padding:28px 32px 20px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v2-header{padding:20px 16px 14px;gap:12px}}.v2-header-icon{flex-shrink:0;width:48px;height:48px;border-radius:50%;border:1px solid #cecece;display:flex;align-items:center;justify-content:center;color:#abb3ba;margin-top:2px}.v2-title{font-size:18px;font-weight:700;color:#69707d;margin:0 0 6px;line-height:1.25;letter-spacing:-.02em}.v2-sub{font-size:14px;color:#69707d;line-height:1.65;margin:0}.v2-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:14px;padding:10px 32px 50px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v2-grid{grid-template-columns:repeat(auto-fill,minmax(110px,1fr));padding:0 16px 20px;gap:10px}}.v2-role-card{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:20px 12px 16px;border-radius:5px;border:1.5px solid #e2e8f0;background:#fff;cursor:pointer;transition:border-color .18s,box-shadow .18s,transform .15s;box-shadow:0 1px 3px #0000000a;text-align:center}.v2-role-card:hover{z-index:30;border-color:#93c5fd;box-shadow:0 4px 16px #4077ad1a;transform:translateY(-2px)}.v2-role-card.v2-role-card--active{border-color:#4077ad;background:#eff6ff;box-shadow:0 0 0 3px #4077ad1f,0 4px 16px #4077ad1f}.v2-role-img-wrap{width:64px;height:64px;border-radius:50%;background:#f8fafc;border:1px solid #e2e8f0;display:flex;align-items:center;justify-content:center;overflow:hidden;transition:background .18s,border-color .18s}.v2-role-img-wrap img{width:44px;height:44px;object-fit:contain;display:block}.v2-role-card--active .v2-role-img-wrap{background:#dbeafe;border-color:#93c5fd}.v2-role-name{font-size:14px;font-weight:600;color:#69707d;line-height:1.3;text-align:center}.v2-role-card--active .v2-role-name{color:#4077ad}.v2-role-subtitle{font-size:11px;font-weight:400;color:#6b7280;line-height:1.3;text-align:center;margin-top:2px}.v2-role-tooltip{position:absolute;top:calc(100% + 10px);left:50%;transform:translate(-50%) translateY(-4px);width:240px;max-width:80vw;background:#4077ad;color:#fff;font-size:12px;font-weight:400;line-height:1.45;text-align:left;padding:10px 12px;border-radius:6px;box-shadow:0 6px 18px #0000002e;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .15s ease,transform .15s ease;z-index:40}.v2-role-tooltip:after{content:\"\";position:absolute;bottom:100%;left:50%;transform:translate(-50%);border-width:6px;border-style:solid;border-color:transparent transparent #4077ad transparent}.v2-role-card:hover .v2-role-tooltip{opacity:1;visibility:visible;transform:translate(-50%) translateY(0)}@media (max-width: 767px){.v2-role-tooltip{display:none}}.v2-tooltip-overlay{display:none}@media (max-width: 767px){.v2-tooltip-overlay{position:fixed;inset:0;background:#0f172a73;display:flex;align-items:center;justify-content:center;z-index:1000;padding:24px}.v2-tooltip-popup{width:280px;max-width:85vw;background:#4077ad;color:#fff;font-size:13px;font-weight:400;line-height:1.5;text-align:left;padding:16px;border-radius:8px;box-shadow:0 12px 32px #00000040}}.v2-role-info-btn{position:absolute;top:8px;right:8px;width:20px;height:20px;border-radius:50%;background:#4077ad;color:#fff;border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;z-index:2;transition:background .15s ease,transform .15s ease}.v2-role-info-btn:hover{background:#345f87;transform:scale(1.08)}.v2-info-overlay{position:fixed;inset:0;background:#0f172a73;display:flex;align-items:center;justify-content:center;z-index:1000}.v2-info-popup{width:560px;max-width:90vw;max-height:80vh;display:flex;flex-direction:column;background:#fff;border-radius:8px;overflow:hidden;box-shadow:0 12px 32px #00000040}.v2-info-popup-header{display:flex;align-items:center;justify-content:space-between;background:#4077ad;padding:14px 16px}.v2-info-popup-title{color:#fff;font-size:15px;font-weight:600}.v2-info-popup-close{background:transparent;border:none;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:2px}.v2-info-popup-body{padding:16px;font-size:13px;line-height:1.6;color:#69707d;white-space:pre-line;overflow-y:auto}.v2-footer{display:flex;align-items:center;justify-content:flex-end;gap:12px;padding:8px 32px 24px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v2-footer{padding:8px 16px 20px}}.v2-back-btn{display:inline-flex;align-items:center;gap:7px;padding:10px 20px;border-radius:5px;font-size:14px;font-weight:500;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:#69707d;border:1.5px solid #69707D;cursor:pointer;transition:color .18s,border-color .18s,background .18s}.v2-back-btn:hover{color:#fff;background:#565c66;border-color:#565c66}.v2-continue-btn{display:inline-flex;align-items:center;gap:9px;padding:10px 24px;border-radius:5px;font-size:14px;font-weight:600;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:linear-gradient(135deg,#4077ad 0% 100%);border:none;cursor:pointer;box-shadow:0 4px 14px #4077ad4d;transition:transform .15s,box-shadow .15s}.v2-continue-btn:hover:not(:disabled){transform:translateY(-1px)}.v2-continue-btn:disabled{background:#e2e8f0;color:#94a3b8;box-shadow:none;cursor:not-allowed}.ip-header{display:flex;align-items:flex-start;gap:16px;padding:28px 32px 16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.ip-header{padding:20px 16px 12px;gap:12px}}.ip-header-icon{flex-shrink:0;width:48px;height:48px;border-radius:50%;border:1px solid #c7c7c7;display:flex;align-items:center;justify-content:center;color:#959191;margin-top:2px}.ip-title{font-size:18px;font-weight:700;color:#69707d;margin:0 0 6px;line-height:1.25;letter-spacing:-.02em;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.ip-sub{font-size:14px;color:#69707d;line-height:1.65;margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.ip-section{margin:0 24px 14px;background:#fff;border:1.5px solid #e2e8f0;border-radius:5px;padding:18px 20px 16px;box-shadow:0 1px 4px #0000000a}@media (max-width: 767px){.ip-section{margin:0 12px 10px;padding:14px}}.ip-section-label{font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:#6b7280;margin:0 0 12px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.ip-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:12px}@media (max-width: 767px){.ip-grid-2{grid-template-columns:1fr}}.ip-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px}@media (max-width: 1024px){.ip-grid-3{grid-template-columns:1fr 1fr}}@media (max-width: 599px){.ip-grid-3{grid-template-columns:1fr}}.ip-grid-4{display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:12px}@media (max-width: 1024px){.ip-grid-4{grid-template-columns:1fr 1fr}}@media (max-width: 599px){.ip-grid-4{grid-template-columns:1fr}}.ip-field{display:flex;flex-direction:column;gap:5px}.ip-label{font-size:12px;font-weight:600;color:#69707d;margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;line-height:1.3}.ip-required{color:#dc2626;margin-left:2px;font-weight:700}.ip-input{width:100%;height:44px;padding:0 14px;border:1.5px solid #e2e8f0;border-radius:5px;font-size:14px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;background:#fff;outline:none;transition:border-color .18s,box-shadow .18s;box-sizing:border-box}.ip-input::placeholder{color:#adb5bd;font-weight:400}.ip-input:focus{border-color:#4077ad;box-shadow:0 0 0 3px #4077ad1a}.ip-input.ip-input--invalid{border-color:#dc2626;background:#fff8f8}.ip-input.ip-input--invalid:focus{box-shadow:0 0 0 3px #dc26261a}.ip-input[readonly]{cursor:pointer;background:#f8fafc}.ip-error{display:flex;align-items:center;gap:4px;font-size:12px;font-weight:500;color:#dc2626;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.ip-upload-wrap{position:relative;display:flex;align-items:center}.ip-upload-icon{position:absolute;right:14px;width:16px;height:16px;cursor:pointer;opacity:.45;transition:opacity .18s}.ip-upload-icon:hover{opacity:.85}.ip-upload-hint{margin-top:6px;font-size:12px}.ip-copy-row{display:flex;align-items:center;gap:10px;margin:0 24px 12px;padding:11px 16px;background:#eff6ff;border:1.5px solid #bfdbfe;border-radius:10px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.ip-copy-row{margin:0 12px 10px}}.ip-copy-check{width:16px;height:16px;accent-color:#4077AD;cursor:pointer;flex-shrink:0}.ip-copy-label{font-size:14px;font-weight:500;color:#69707d;cursor:pointer;margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;-webkit-user-select:none;user-select:none}.ip-footer{display:flex;align-items:center;justify-content:flex-end;gap:12px;padding:8px 24px 28px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.ip-footer{padding:8px 16px 24px}}.ip-back-btn{display:inline-flex;align-items:center;gap:7px;padding:10px 20px;border-radius:5px;font-size:14px;font-weight:500;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:#69707d;border:1.5px solid #69707D;cursor:pointer;transition:color .18s,border-color .18s,background .18s}.ip-back-btn:hover{color:#fff;border-color:#565c66;background:#565c66}.ip-next-btn{display:inline-flex;align-items:center;gap:9px;padding:10px 26px;border-radius:5px;font-size:14px;font-weight:600;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:linear-gradient(135deg,#4077ad 0% 100%);border:none;cursor:pointer;box-shadow:0 4px 14px #4077ad4d;transition:transform .15s,box-shadow .15s}.ip-next-btn:hover:not(:disabled){transform:translateY(-1px)}.ip-next-btn:active:not(:disabled){transform:translateY(0)}.ip-next-btn:disabled{background:#e2e8f0;color:#94a3b8;box-shadow:none;cursor:not-allowed}.v5-wrap{display:flex;flex-direction:column;align-items:center;text-align:center;padding:48px 32px 40px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v5-wrap{padding:36px 20px 32px}}.v5-icon{width:72px;height:72px;border-radius:50%;background:linear-gradient(135deg,#dcfce7,#bbf7d0);border:1.5px solid #86efac;display:flex;align-items:center;justify-content:center;color:#16a34a;margin-bottom:20px;box-shadow:0 0 0 8px #22c55e14}.v5-title{font-size:18px;font-weight:800;color:#69707d;margin:0 0 10px;letter-spacing:-.025em;line-height:1.2}.v5-sub{font-size:14px;color:#69707d;margin:0 0 28px;line-height:1.6;max-width:480px}.v5-cards{display:flex;flex-direction:column;gap:12px;width:100%;max-width:520px;margin-bottom:32px;text-align:left}.v5-card{display:flex;align-items:flex-start;gap:14px;padding:16px 18px;border-radius:12px;border:1.5px solid #e2e8f0;background:#f8fafc;box-shadow:0 1px 3px #0000000a}.v5-card-icon{flex-shrink:0;width:36px;height:36px;border-radius:9px;background:#eff6ff;border:1px solid #bfdbfe;display:flex;align-items:center;justify-content:center;color:#4077ad}.v5-card-icon.v5-card-icon--green{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a}.v5-card-text{font-size:14px;color:#69707d;line-height:1.6;margin:0}.v5-cta{display:inline-flex;align-items:center;gap:10px;padding:13px 32px;border-radius:5px;font-size:14px;font-weight:600;font-family:inherit;color:#fff;background:linear-gradient(135deg,#4077ad 0% 100%);border:none;cursor:pointer;box-shadow:0 4px 16px #4077ad52;transition:transform .15s,box-shadow .15s}.v5-cta:hover{transform:translateY(-2px)}.v5-cta:active{transform:translateY(0)}.cc-select-wrap{margin-bottom:20px}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-select-container{border:1.5px solid #e2e8f0;border-radius:10px;min-height:48px;padding:5px 10px;background:#fff;box-shadow:none;cursor:text;transition:border-color .18s,box-shadow .18s}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-select-container:hover{border-color:#94a3b8}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple.ng-select-focused .ng-select-container{border-color:#4077ad;box-shadow:0 0 0 3px #4077ad1a}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-container{flex-wrap:wrap;gap:6px;padding:2px 0}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value{display:inline-flex;flex-direction:row;align-items:center;gap:5px;background:#eff6ff;border:1px solid #bfdbfe;border-radius:99px;padding:4px 8px 4px 13px;font-size:12px;font-weight:600;color:#4077ad;margin:0;line-height:1}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-label{order:1}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-icon{display:inline-flex;align-items:center;justify-content:center;order:2;width:16px;height:16px;border-radius:50%;font-size:12px;font-weight:700;line-height:1;padding:0;background:#4077ad26;color:#4077ad;cursor:pointer;flex-shrink:0;transition:background .15s,color .15s}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-icon:hover{background:#4077ad;color:#fff}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-icon.right{display:none}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-placeholder{font-size:14px;color:#adb5bd;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-select-container.ng-has-value .ng-placeholder{display:none}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-input>input{font-size:14px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-arrow-wrapper{padding-right:6px}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-arrow-wrapper .ng-arrow{border-color:#94a3b8 transparent transparent;border-width:5px 4px 0}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-clear-wrapper{color:#94a3b8}::ng-deep .ng-dropdown-panel{border:1.5px solid #e2e8f0;border-radius:12px;box-shadow:0 8px 28px #0000001a,0 2px 8px #0000000f;overflow:hidden;margin-top:5px;z-index:9999!important;background:#fff!important}::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items{padding:6px}::ng-deep .ng-dropdown-panel .ng-option{border-radius:8px;padding:10px 13px;font-size:14px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;transition:background .12s}::ng-deep .ng-dropdown-panel .ng-option.ng-option-selected{background:#eff6ff;color:#4077ad;font-weight:600}::ng-deep .ng-dropdown-panel .ng-option.ng-option-marked:not(.ng-option-selected){background:#f8fafc;color:#69707d}::ng-deep .ng-dropdown-panel .ng-option.ng-option-selected.ng-option-marked{background:#dbeafe}.cc-group{margin-bottom:18px;padding-top:4px}.cc-group:last-child{margin-bottom:0}.cc-hidden-check{position:absolute;opacity:0;width:0;height:0;pointer-events:none}.cc-select-all-pill{display:inline-flex;align-items:center;gap:6px;padding:7px 16px;border-radius:99px;border:1.5px solid #e2e8f0;background:#f8fafc;font-size:12px;font-weight:700;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;cursor:pointer;-webkit-user-select:none;user-select:none;margin-bottom:10px;transition:background .18s,border-color .18s,color .18s}.cc-select-all-pill:hover:not(.cc-select-all-pill--on){background:#f1f5f9;border-color:#94a3b8}.cc-select-all-pill.cc-select-all-pill--on{background:#69707d;border-color:#69707d;color:#fff}.cc-sub-pills{display:flex;flex-wrap:wrap;gap:8px}.cc-sub-pill{display:inline-flex;align-items:center;gap:5px;padding:6px 14px;border-radius:99px;border:1.5px solid #e2e8f0;background:#fff;font-size:12px;font-weight:500;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background .15s,border-color .15s,color .15s,box-shadow .15s}.cc-sub-pill:hover:not(.cc-sub-pill--on){background:#f8fafc;border-color:#94a3b8;color:#69707d}.cc-sub-pill.cc-sub-pill--on{background:#eff6ff;border-color:#93c5fd;color:#4077ad;font-weight:600;box-shadow:0 0 0 3px #4077ad12}html,body{overscroll-behavior:none;height:100%;overflow:hidden}\n"], dependencies: [{ kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i7.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i7.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i12.NgSelectComponent, selector: "ng-select", inputs: ["bindLabel", "bindValue", "markFirst", "placeholder", "notFoundText", "typeToSearchText", "addTagText", "loadingText", "clearAllText", "appearance", "dropdownPosition", "appendTo", "loading", "closeOnSelect", "hideSelected", "selectOnTab", "openOnEnter", "maxSelectedItems", "groupBy", "groupValue", "bufferAmount", "virtualScroll", "selectableGroup", "selectableGroupAsModel", "searchFn", "trackByFn", "clearOnBackspace", "labelForId", "inputAttrs", "tabIndex", "readonly", "searchWhileComposing", "minTermLength", "editableSearchTerm", "keyDownFn", "typeahead", "multiple", "addTag", "searchable", "clearable", "isOpen", "items", "compareWith", "clearSearchOnAdd", "deselectOnClick"], outputs: ["blur", "focus", "change", "open", "close", "search", "clear", "add", "remove", "scroll", "scrollToEnd"] }, { kind: "directive", type: MaskedInputDirective, selector: "[textMask]", inputs: ["textMask"], exportAs: ["textMask"] }, { kind: "component", type: AddressVerifyFieldComponent, selector: "im-address-verify-field", inputs: ["placeholder", "options", "maxLength", "inputId", "name", "autocompleteAttr", "inputClass", "invalid", "inputStyle", "initialLat", "initialLng"], outputs: ["addressResolved", "manualEdit"] }, { kind: "component", type: TermsConditionsComponent, selector: "app-terms-conditions", inputs: ["title", "branding", "PrivacyAndTerms"], outputs: ["metaLoaded"] }, { kind: "component", type: PrivacyPolicyComponent, selector: "app-privacy-policy", inputs: ["title", "branding", "PrivacyAndTerms"], outputs: ["metaLoaded"] }, { kind: "component", type: CredentialingComponent, selector: "app-credentialing", inputs: ["signatureFileId", "signatureUrl", "data"], outputs: ["back"] }, { kind: "pipe", type: i1$2.DatePipe, name: "date" }] });
|
|
36412
37051
|
}
|
|
36413
37052
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: InitialProcessComponent, decorators: [{
|
|
36414
37053
|
type: Component,
|
|
36415
|
-
args: [{ selector: 'app-initial-process', standalone: false, template: "<div class=\"container\">\r\n <div *ngIf=\"isInitializing\" class=\"text-center p-5\">\r\n <div class=\"spinner-border text-primary\"></div>\r\n </div>\r\n <ng-container *ngIf=\"!isInitializing\">\r\n <div class=\"mb-4 logout-container\" *ngIf=\"showlogout\">\r\n <button class=\"logout-btn\" (click)=\"logout()\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4\"/>\r\n <polyline points=\"16 17 21 12 16 7\"/>\r\n <line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\"/>\r\n </svg>\r\n Logout\r\n </button>\r\n </div>\r\n <div class=\"card pb-2 mob pr-5\" style=\"margin-bottom: 30px;\">\r\n <div [hidden]=\"view !== 1\">\r\n\r\n <!-- \u2500\u2500 Welcome Banner \u2500\u2500 -->\r\n <div class=\"v1-welcome\">\r\n <div class=\"v1-welcome-icon\">\r\n <svg width=\"26\" height=\"26\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2\"/>\r\n <circle cx=\"9\" cy=\"7\" r=\"4\"/>\r\n <path d=\"M23 21v-2a4 4 0 00-3-3.87\"/>\r\n <path d=\"M16 3.13a4 4 0 010 7.75\"/>\r\n </svg>\r\n </div>\r\n <div class=\"v1-welcome-text\">\r\n <h2 class=\"v1-welcome-title\">Welcome to <span class=\"v1-brand\">{{ branding.displayName }}</span></h2>\r\n <p class=\"v1-welcome-sub\">Our members and service providers rely on accurate info in your profile to connect\r\n you with work that suits your capabilities. Keep your profile complete, skills updated, licenses current,\r\n photos and logos professional, and schedule up to date.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Main Body: agreements + signature \u2500\u2500 -->\r\n <div class=\"v1-body\">\r\n\r\n <!-- Left: agreement cards -->\r\n <div class=\"v1-agreements\">\r\n\r\n <!-- Terms card -->\r\n <div class=\"v1-agreement-card\" [class.v1-card--agreed]=\"model.acceptTerms\"\r\n [class.v1-card--invalid]=\"!model.acceptTerms && validatePage==1\">\r\n <div class=\"v1-card-icon\">\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z\"/>\r\n <polyline points=\"14 2 14 8 20 8\"/>\r\n <line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\"/>\r\n <line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\"/>\r\n </svg>\r\n </div>\r\n <div class=\"v1-card-body\">\r\n <p class=\"v1-card-title\">Terms and Conditions</p>\r\n <p class=\"v1-card-sub\">Read and accept to continue</p>\r\n </div>\r\n <button type=\"button\" class=\"v1-agree-btn\" [class.v1-agree-btn--done]=\"model.acceptTerms\"\r\n [disabled]=\"isTermsLoading\"\r\n (click)=\"openModal(termsAndConditionsModel,'Terms and Conditions',$event)\">\r\n <span class=\"v1-agree-spinner\" *ngIf=\"isTermsLoading\"></span>\r\n <svg *ngIf=\"!isTermsLoading && model.acceptTerms\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n {{ isTermsLoading ? 'Loading...' : (model.acceptTerms ? 'Agreed' : 'Read & Agree') }}\r\n </button>\r\n </div>\r\n\r\n <!-- Privacy card -->\r\n <div class=\"v1-agreement-card\" [class.v1-card--agreed]=\"model.privacy\"\r\n [class.v1-card--invalid]=\"!model.privacy && validatePage==1\">\r\n <div class=\"v1-card-icon\">\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"/>\r\n </svg>\r\n </div>\r\n <div class=\"v1-card-body\">\r\n <p class=\"v1-card-title\">Privacy Statement</p>\r\n <p class=\"v1-card-sub\">Read and accept to continue</p>\r\n </div>\r\n <button type=\"button\" class=\"v1-agree-btn\" [class.v1-agree-btn--done]=\"model.privacy\"\r\n [disabled]=\"isPrivacyLoading\"\r\n (click)=\"openModal(termsAndConditionsModel,'Privacy Statement',$event)\">\r\n <span class=\"v1-agree-spinner\" *ngIf=\"isPrivacyLoading\"></span>\r\n <svg *ngIf=\"!isPrivacyLoading && model.privacy\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n {{ isPrivacyLoading ? 'Loading...' : (model.privacy ? 'Agreed' : 'Read & Agree') }}\r\n </button>\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- Right: signature pad -->\r\n <div class=\"v1-signature\">\r\n <div class=\"v1-sig-header\">\r\n <span class=\"v1-sig-label\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M17 3a2.828 2.828 0 114 4L7.5 20.5 2 22l1.5-5.5L17 3z\"/>\r\n </svg>\r\n Signature\r\n </span>\r\n <button (click)=\"clearPad()\" class=\"v1-clear-btn\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M18 6L6 18M6 6l12 12\"/>\r\n </svg>\r\n Clear\r\n </button>\r\n </div>\r\n <div class=\"v1-sig-pad\">\r\n <div [ngClass]=\"{'d-none': signaturePadData?.publicUrl}\" style=\"width:100%\">\r\n <canvas #canvas></canvas>\r\n </div>\r\n <div [ngClass]=\"{'d-none': !signaturePadData?.publicUrl}\" style=\"width:100%\">\r\n <img [src]=\"signaturePadData?.publicUrl\" alt style=\"width:100%;height:120px;object-fit:contain;display:block;\">\r\n </div>\r\n <p class=\"v1-sig-hint\" *ngIf=\"!signaturePadData?.publicUrl && (!points || !points?.length)\">\r\n Draw your signature here\r\n </p>\r\n </div>\r\n <div *ngIf=\"validatePage==1 && (!points || !points?.length || points.length==0) && !fileData\"\r\n class=\"v1-error-msg\">\r\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/>\r\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>\r\n </svg>\r\n Signature is required\r\n </div>\r\n <div *ngIf=\"uploadError\" class=\"v1-error-msg\">{{ uploadError }}</div>\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- \u2500\u2500 Continue Button \u2500\u2500 -->\r\n <div class=\"v1-footer\">\r\n <button class=\"v1-continue-btn\" (click)=\"next(2)\"\r\n [disabled]=\"((!points || !points?.length || points.length==0) && !fileData && !signaturePadData?.publicUrl) || !model.acceptTerms || !model.privacy\">\r\n <span *ngIf=\"!showLoader\">Continue</span>\r\n <span *ngIf=\"showLoader\" class=\"v1-spinner\"></span>\r\n <svg *ngIf=\"!showLoader\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n </div>\r\n <ng-container *ngIf=\"view == 2\">\r\n\r\n <!-- \u2500\u2500 Role-select header \u2500\u2500 -->\r\n <div class=\"v2-header\">\r\n <div class=\"v2-header-icon\">\r\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"8\" r=\"4\"/>\r\n <path d=\"M6 20v-2a4 4 0 014-4h4a4 4 0 014 4v2\"/>\r\n </svg>\r\n </div>\r\n <div>\r\n <h2 class=\"v2-title\">Choose your role</h2>\r\n <p class=\"v2-sub\">Choose the areas you'd like to be part of \u2014 programs, services, events, or\r\n collaborations. Connect your business to others and prospective clients.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Role cards grid \u2500\u2500 -->\r\n <div class=\"v2-grid\">\r\n <ng-container *ngFor=\"let userType of userViewRoles\">\r\n <div class=\"v2-role-card\" [class.v2-role-card--active]=\"userType.value === selectedRoleValue\"\r\n (click)=\"selectedUserRole(userType)\">\r\n <button type=\"button\" class=\"v2-role-info-btn\" *ngIf=\"userType.details\"\r\n (click)=\"openInfoPopup($event, userType)\" title=\"More info\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\r\n <line x1=\"12\" y1=\"11\" x2=\"12\" y2=\"16\"/>\r\n <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"/>\r\n </svg>\r\n </button>\r\n <div class=\"v2-role-img-wrap\">\r\n <img [src]=\"userType?.img\" alt=\"\">\r\n </div>\r\n <span class=\"v2-role-name\">{{userType.name}}</span>\r\n <span class=\"v2-role-subtitle\" *ngIf=\"userType.subtitle\">{{userType.subtitle}}</span>\r\n <div class=\"v2-role-tooltip\" *ngIf=\"userType.tooltip\">{{userType.tooltip}}</div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Role info popup \u2500\u2500 -->\r\n <div class=\"v2-info-overlay\" *ngIf=\"infoPopupRole\" (click)=\"closeInfoPopup()\">\r\n <div class=\"v2-info-popup\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"v2-info-popup-header\">\r\n <span class=\"v2-info-popup-title\">{{ infoPopupRole.name }}</span>\r\n <button type=\"button\" class=\"v2-info-popup-close\" (click)=\"closeInfoPopup()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M18 6L6 18M6 6l12 12\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n <div class=\"v2-info-popup-body\">{{ infoPopupRole.details }}</div>\r\n </div>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Footer: Back + Continue \u2500\u2500 -->\r\n <div class=\"v2-footer\">\r\n <button class=\"v2-back-btn\" (click)=\"previous()\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M19 12H5M12 5l-7 7 7 7\"/>\r\n </svg>\r\n Back\r\n </button>\r\n <button class=\"v2-continue-btn\" (click)=\"next(3)\" [disabled]=\"!isUserSelected || isLoadingSubCategories\">\r\n <span *ngIf=\"isLoadingSubCategories\" class=\"v1-spinner\"></span>\r\n <ng-container *ngIf=\"!isLoadingSubCategories\">\r\n Continue\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </ng-container>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"view == 3\">\r\n\r\n <!-- Header -->\r\n <div class=\"ip-header\">\r\n <div class=\"ip-header-icon\">\r\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z\"/>\r\n <polyline points=\"9 22 9 12 15 12 15 22\"/>\r\n </svg>\r\n </div>\r\n <div>\r\n <h2 class=\"ip-title\">Business Information</h2>\r\n <p class=\"ip-sub\">Tell us about your company so we can connect you with the right work.</p>\r\n </div>\r\n </div>\r\n\r\n <form [formGroup]=\"companyForm\">\r\n\r\n <!-- Company Details -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Company Details</p>\r\n <div class=\"ip-grid-2\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"companyName\">Company Name <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': (f.companyName.errors && validatePage == 3) || providerError}\"\r\n type=\"text\" class=\"ip-input\" id=\"companyName\" placeholder=\"Company Name\"\r\n formControlName=\"companyName\">\r\n <span *ngIf=\"f.companyName.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.companyName.errors.required\">Company Name is required</span>\r\n <span *ngIf=\"f.companyName.errors.minlength\">Minimum 2 characters</span>\r\n <span *ngIf=\"f.companyName.errors.maxLength\">Maximum 100 characters</span>\r\n </span>\r\n <span *ngIf=\"providerError\" class=\"ip-error\">{{ providerError }}</span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"inputPhone\">Phone Number <span class=\"ip-required\">*</span></label>\r\n <input class=\"ip-input\" type=\"text\" name=\"inputPhone\" placeholder=\"Company Phone Number\"\r\n id=\"inputPhone\" autocomplete=\"off\" formControlName=\"phoneNumber\" [maxLength]=\"14\"\r\n (input)=\"formatPhone($event,companyForm)\"\r\n [ngClass]=\"{'ip-input--invalid': (f.phoneNumber.errors && validatePage == 3) || providerError}\">\r\n <span *ngIf=\"f.phoneNumber.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.phoneNumber.errors.required\">Phone Number is required</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Address -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Address</p>\r\n <div class=\"ip-grid-2\" style=\"margin-bottom: 12px;\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"businessAddress\">Address Line 1 <span class=\"ip-required\">*</span></label>\r\n <im-address-verify-field formControlName=\"address1\" inputId=\"businessAddress\" [options]=\"options\"\r\n inputClass=\"\" [inputStyle]=\"addressInputStyle\" placeholder=\"Business Address 1\"\r\n [invalid]=\"f.address1.errors && validatePage == 3\"\r\n [initialLat]=\"f.latitude.value\" [initialLng]=\"f.longitude.value\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"\r\n (manualEdit)=\"onCompanyAddressManualEdit()\"></im-address-verify-field>\r\n <span *ngIf=\"f.address1.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.address1.errors.required\">Business Address 1 is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"businessAddress2\">Address Line 2</label>\r\n <input type=\"text\" class=\"ip-input\" id=\"businessAddress2\" placeholder=\"Business Address 2\">\r\n </div>\r\n </div>\r\n <div class=\"ip-grid-4\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"City\">City <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': f.city.errors && validatePage == 3}\"\r\n type=\"text\" class=\"ip-input\" id=\"City\" placeholder=\"City\" formControlName=\"city\">\r\n <span *ngIf=\"f.city.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.city.errors.required\">City is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"State\">State <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': f.state.errors && validatePage == 3}\"\r\n type=\"text\" class=\"ip-input\" id=\"State\" placeholder=\"State\" formControlName=\"state\">\r\n <span *ngIf=\"f.state.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.state.errors.required\">State is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"Zipcode\">Zipcode <span class=\"ip-required\">*</span></label>\r\n <input [textMask]=\"{ mask: zipcodeMask }\"\r\n [ngClass]=\"{'ip-input--invalid': f.zipcode.errors && validatePage == 3}\"\r\n type=\"text\" class=\"ip-input\" id=\"Zipcode\" placeholder=\"Zipcode\" formControlName=\"zipcode\">\r\n <span *ngIf=\"f.zipcode.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.zipcode.errors.required\">Zipcode is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"Country\">Country <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': f.country.errors && validatePage == 3}\"\r\n type=\"text\" class=\"ip-input\" id=\"Country\" placeholder=\"Country\" formControlName=\"country\">\r\n <span *ngIf=\"f.country.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.country.errors.required\">Country is required</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </form>\r\n\r\n <!-- Company Logo (intentionally outside formGroup) -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Company Logo</p>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\">Company Logo <span class=\"ip-required\">*</span></label>\r\n <div class=\"ip-upload-wrap\">\r\n <input #uploadLogoInput type=\"file\" accept=\".png,.jpg,.jpeg\" (change)=\"uploadLogo($event)\"\r\n class=\"upload-initial-input rounded-circle opacity-0 position-absolute\" />\r\n <input (click)=\"uploadImage2.click()\" [(ngModel)]=\"logoName\" readonly type=\"text\"\r\n class=\"ip-input\" placeholder=\"Click to upload company logo\">\r\n <img #uploadImage2 class=\"ip-upload-icon\" (click)=\"uploadLogoInput.click()\"\r\n src=\"assets/images/icons/upload.svg\" alt=\"Upload\">\r\n </div>\r\n <small class=\"ip-upload-hint text-muted d-block\">Allowed formats: PNG, JPG, JPEG</small>\r\n <span *ngIf=\"isLogoRequired\" class=\"ip-error\">Please upload a company logo</span>\r\n <span *ngIf=\"isneeded\" class=\"ip-error\">Company Logo is required</span>\r\n </div>\r\n </div>\r\n\r\n <!-- Contractor Category -->\r\n <div *ngIf=\"selectedRole?.name == 'Contractor'\" class=\"ip-section\">\r\n <p class=\"ip-section-label\">Contractor Category</p>\r\n\r\n <!-- Category selector \u2014 ng-select logic intact, restyled as pill tag-input -->\r\n <div class=\"cc-select-wrap\">\r\n <ng-select [items]=\"contractorSubCategories\" bindLabel=\"name\" [multiple]=\"true\" [closeOnSelect]=\"false\"\r\n (ngModelChange)=\"changeContractor($event)\" [(ngModel)]=\"selectedContractorCategories\"\r\n >\r\n </ng-select>\r\n </div>\r\n\r\n <!-- Sub-items as pill chips per selected category -->\r\n <ng-container *ngFor=\"let item of selectedContractorCategories; let i=index\">\r\n <div class=\"cc-group\">\r\n\r\n <!-- \"Select all\" toggle pill for this category -->\r\n <label class=\"cc-select-all-pill\" [class.cc-select-all-pill--on]=\"item.selectAll\">\r\n <input type=\"checkbox\" [(ngModel)]=\"item.selectAll\" [name]=\"item?.id\" [id]=\"item?.id\"\r\n (change)=\"selectAll($event,item?.items)\" class=\"cc-hidden-check\">\r\n <svg *ngIf=\"item.selectAll\" width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n {{ item?.name }} \u2014 Select all\r\n </label>\r\n\r\n <!-- Individual sub-item pills -->\r\n <div class=\"cc-sub-pills\">\r\n <label *ngFor=\"let subItem of item?.items\" class=\"cc-sub-pill\"\r\n [class.cc-sub-pill--on]=\"subItem.selected\">\r\n <input type=\"checkbox\" [(ngModel)]=\"subItem.selected\" [name]=\"subItem?.id\" [id]=\"subItem?.id\"\r\n (change)=\"unCheckedEvent($event,item)\" class=\"cc-hidden-check\">\r\n <svg *ngIf=\"subItem.selected\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n {{ subItem?.name }}\r\n </label>\r\n </div>\r\n\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"ip-footer\">\r\n <button class=\"ip-back-btn\" (click)=\"previous()\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M19 12H5M12 5l-7 7 7 7\"/>\r\n </svg>\r\n Back\r\n </button>\r\n <button class=\"ip-next-btn\" (click)=\"next(4)\">\r\n Continue\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"view == 4\">\r\n\r\n <!-- Header -->\r\n <div class=\"ip-header\">\r\n <div class=\"ip-header-icon\">\r\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"8\" r=\"4\"/>\r\n <path d=\"M6 20v-2a4 4 0 014-4h4a4 4 0 014 4v2\"/>\r\n </svg>\r\n </div>\r\n <div>\r\n <h2 class=\"ip-title\">Your Profile</h2>\r\n <p class=\"ip-sub\">We need a few basics and a headshot to complete your profile.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Copy from provider toggle -->\r\n <div *ngIf=\"isBusiness\" class=\"ip-copy-row\">\r\n <input [(ngModel)]=\"isCopy\" type=\"checkbox\" name=\"isCopy\" id=\"isCopy\"\r\n class=\"ip-copy-check\" (change)=\"changeAddressUser()\">\r\n <label for=\"isCopy\" class=\"ip-copy-label\">Copy from Provider Information</label>\r\n </div>\r\n\r\n <form [formGroup]=\"userForm\">\r\n\r\n <!-- Personal Details -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Personal Details</p>\r\n <div class=\"ip-grid-3\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"firstName\">First Name <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.firstName.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" placeholder=\"First Name\" formControlName=\"firstName\" id=\"firstName\">\r\n <span *ngIf=\"u.firstName.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.firstName.errors.required\">First Name is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"lastName\">Last Name <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.lastName.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" placeholder=\"Last Name\" formControlName=\"lastName\" id=\"lastName\">\r\n <span *ngIf=\"u.lastName.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.lastName.errors.required\">Last Name is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"email\">Email <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.email.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" placeholder=\"Email\" formControlName=\"email\" id=\"email\">\r\n <span *ngIf=\"u.email.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.email.errors.required\">Email is required</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Home Address -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Home Address</p>\r\n <div class=\"ip-field\" style=\"margin-bottom: 12px;\">\r\n <label class=\"ip-label\" for=\"address1\">Address Line 1 <span class=\"ip-required\">*</span></label>\r\n <im-address-verify-field formControlName=\"address1\" inputId=\"address1\" [options]=\"options\"\r\n inputClass=\"\" [inputStyle]=\"addressInputStyle\" placeholder=\"Home Address 1\"\r\n [invalid]=\"u.address1.errors && validatePage == 4\"\r\n [initialLat]=\"u.latitude.value\" [initialLng]=\"u.longitude.value\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"\r\n (manualEdit)=\"onUserAddressManualEdit()\"></im-address-verify-field>\r\n <span *ngIf=\"u.address1.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.address1.errors.required\">Home Address 1 is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-grid-3\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"homeAddress2\">Address Line 2</label>\r\n <input type=\"text\" class=\"ip-input\" id=\"homeAddress2\" formControlName=\"address2\"\r\n placeholder=\"Home Address 2\">\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"City\">City <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.city.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" id=\"City\" placeholder=\"City\" formControlName=\"city\">\r\n <span *ngIf=\"u.city.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.city.errors.required\">City is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"State\">State <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.state.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" id=\"State\" placeholder=\"State\" formControlName=\"state\">\r\n <span *ngIf=\"u.state.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.state.errors.required\">State is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"Zipcode\">Zipcode <span class=\"ip-required\">*</span></label>\r\n <input [textMask]=\"{ mask: zipcodeMask }\"\r\n [ngClass]=\"{'ip-input--invalid': u.zipcode.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" id=\"Zipcode\" placeholder=\"Zipcode\" formControlName=\"zipcode\">\r\n <span *ngIf=\"u.zipcode.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.zipcode.errors.required\">Zipcode is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"Country\">Country <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.country.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" id=\"Country\" placeholder=\"Country\" formControlName=\"country\">\r\n <span *ngIf=\"u.country.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.country.errors.required\">Country is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"inputPhone\">Phone Number <span class=\"ip-required\">*</span></label>\r\n <input class=\"ip-input\" type=\"text\" (input)=\"formatPhone($event,userForm)\"\r\n name=\"inputPhone\" placeholder=\"Phone Number\" id=\"inputPhone\" autocomplete=\"off\"\r\n formControlName=\"phoneNumber\" [maxLength]=\"14\"\r\n [ngClass]=\"{'ip-input--invalid': u.phoneNumber.errors && validatePage == 4}\">\r\n <span *ngIf=\"u.phoneNumber.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.phoneNumber.errors.required\">Phone Number is required</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </form>\r\n\r\n <!-- Profile Picture (intentionally outside formGroup) -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Profile Picture</p>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\">Profile Picture <span class=\"ip-required\">*</span></label>\r\n <div class=\"ip-upload-wrap\">\r\n <input #uploadFile type=\"file\" accept=\".png,.jpg,.jpeg\" (change)=\"uploadUserImage($event)\"\r\n class=\"upload-initial-input rounded-circle opacity-0 position-absolute\" />\r\n <input (click)=\"uploadImage1.click()\" [(ngModel)]=\"fileName\" readonly type=\"text\"\r\n class=\"ip-input\" id=\"upload\" accept=\".png,.jpg,.jpeg\" placeholder=\"Click to upload profile picture\">\r\n <img #uploadImage1 class=\"ip-upload-icon\" (click)=\"uploadFile.click()\"\r\n src=\"assets/images/icons/upload.svg\" alt=\"Upload\">\r\n </div>\r\n <small class=\"ip-upload-hint text-muted d-block\">Allowed formats: PNG, JPG, JPEG</small>\r\n <span *ngIf=\"isImageRequired\" class=\"ip-error\">Please upload a profile image</span>\r\n <span *ngIf=\"userError\" class=\"ip-error\">{{ userError }}</span>\r\n </div>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"ip-footer\">\r\n <button class=\"ip-back-btn\" (click)=\"previous()\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M19 12H5M12 5l-7 7 7 7\"/>\r\n </svg>\r\n Back\r\n </button>\r\n <button class=\"ip-next-btn\" (click)=\"next(5)\" [disabled]=\"showLoader\">\r\n <span *ngIf=\"!showLoader\">Continue</span>\r\n <span *ngIf=\"showLoader\" class=\"v1-spinner\"></span>\r\n <svg *ngIf=\"!showLoader\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"view == 5\">\r\n <div class=\"v5-wrap\">\r\n\r\n <!-- Success icon -->\r\n <div class=\"v5-icon\">\r\n <svg width=\"36\" height=\"36\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M22 11.08V12a10 10 0 11-5.93-9.14\"/>\r\n <polyline points=\"22 4 12 14.01 9 11.01\"/>\r\n </svg>\r\n </div>\r\n\r\n <h2 class=\"v5-title\">You're all set!</h2>\r\n <p class=\"v5-sub\">Account created successfully. Next step: complete your profile.</p>\r\n\r\n <!-- Info cards -->\r\n <div class=\"v5-cards\">\r\n <div class=\"v5-card\">\r\n <div class=\"v5-card-icon\">\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\r\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/>\r\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>\r\n </svg>\r\n </div>\r\n <p class=\"v5-card-text\">Profile completion is mandatory to participate in rosters, programs, requests, and platform workflows. Incomplete profiles will have limited access.</p>\r\n </div>\r\n <div class=\"v5-card\">\r\n <div class=\"v5-card-icon v5-card-icon--green\">\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><path d=\"M3 9h18M9 21V9\"/>\r\n </svg>\r\n </div>\r\n <p class=\"v5-card-text\">You may access your dashboard at any time, but full functionality is available only after profile completion.</p>\r\n </div>\r\n </div>\r\n\r\n <button (click)=\"dashboard()\" class=\"v5-cta\">\r\n Go to Dashboard\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </button>\r\n\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"view == 10\">\r\n <app-credentialing (back)=\"onCredentialingBack()\" [data]=\"credentialingData\" [signatureFileId]=\"signatureFileId\"\r\n [signatureUrl]=\"signatureUrl\"></app-credentialing>\r\n </ng-container>\r\n </div>\r\n</ng-container>\r\n</div>\r\n\r\n<ng-template #termsAndConditionsModel>\r\n <div class=\"modal-dialog modal-dialog-centered tc-modal-dialog\">\r\n <div class=\"modal-content tc-modal\">\r\n\r\n <!-- HEADER -->\r\n <div class=\"tc-modal-header\">\r\n \r\n <h4 class=\"tc-modal-title\">{{ termsAndConditionTitle }}</h4>\r\n <span class=\"tc-modal-meta\" *ngIf=\"legalMeta\">Last Modified: {{ legalMeta.createdDate | date:'MMM d, y, h:mm:ss a' }}, {{ legalMeta.versionName }}</span>\r\n </div>\r\n\r\n\r\n <div class=\"tc-scroll-wrapper\">\r\n <div class=\"tc-modal-body\"\r\n (scroll)=\"onTermsScroll($event)\">\r\n <ng-container *ngIf=\"termsAndConditionTitle == 'Terms and Conditions'\">\r\n <app-terms-conditions [PrivacyAndTerms]=\"privacyAndTerms\" [title]=\"title\" [branding]=\"branding\"\r\n (metaLoaded)=\"onLegalMetaLoaded($event)\">\r\n </app-terms-conditions>\r\n </ng-container>\r\n <ng-container *ngIf=\"termsAndConditionTitle != 'Terms and Conditions'\">\r\n <app-privacy-policy [PrivacyAndTerms]=\"privacyAndTerms\" [title]=\"title\" [branding]=\"branding\"\r\n (metaLoaded)=\"onLegalMetaLoaded($event)\">\r\n </app-privacy-policy>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Floating scroll-to-bottom button -->\r\n <button class=\"tc-scroll-fab\" *ngIf=\"!isAgreeEnabled && legalMeta\" (click)=\"scrollToBottomClick($event)\"\r\n title=\"Scroll to bottom\">\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 5v14M5 15l7 7 7-7\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <!-- FOOTER -->\r\n <div class=\"tc-modal-footer\">\r\n <button type=\"button\" class=\"tc-btn tc-btn-decline\"\r\n (click)=\"decline(termsAndConditionTitle); modelRef.hide();\">\r\n Decline\r\n </button>\r\n <button type=\"button\" class=\"tc-btn tc-btn-agree\"\r\n [disabled]=\"!isAgreeEnabled\"\r\n (click)=\"agree(termsAndConditionTitle); modelRef.hide();\">\r\n I Agree\r\n </button>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n</ng-template>", styles: ["@charset \"UTF-8\";.brand-name{font-weight:700;font-size:calc(100% + 4px)}.spinner{width:38px;height:38px;border:dotted white;border-top:2px solid #f6f6f6;border-radius:62%;animation:spin 1.7s linear infinite;margin:-9px 0 0 -28px}@keyframes spin{to{transform:rotate(360deg)}}::ng-deep .backdrop{background-color:transparent!important}.filter-black{filter:brightness(.4)!important}.footer-view{margin-top:3rem;margin-left:0;margin-right:0}.footer-signature{margin-top:9rem}.slider-view{width:11rem;margin-left:1px}.container{margin-top:40px}.container .card{border-radius:5px}.container .header{padding:33px 10px 0}.container .header .logo{width:15%;height:80%}.container .form-control{padding:.75rem 1rem;border-color:#a1a1a1}.container .form-control:focus{color:#000;box-shadow:none;border-color:#a1a1a1!important}.container .form-control::placeholder{font-weight:500;font-size:12px;color:#a1a1a1}.container .link{color:#4077ad}.container .link-signup{font-weight:bolder}.container .form-check-label{margin-bottom:0;padding-top:9px}.container .content-view{margin-top:10%}.container .content-description{margin-top:25%}.container .tag-content{color:#fff9e8;margin-left:9%}.container .tag-content p{color:#fff9e8}.container .form-check-input:checked{background-color:#000;border-color:#000}.container .img-tick{margin:-31px 12px 0 -35px}.container .form-check-input[type=checkbox]{border-radius:2px;border:2px solid #000000}.container .form-check-input:focus{box-shadow:none}.container input[type=checkbox]{accent-color:#000000}.term-list{padding:48px 60px 6px 0;margin-left:30px;color:\"#1f1f1fdb\"}.add-tab{padding:75px 75px 6px 1px;margin-left:50px;color:\"#1f1f1fdb\"}.add-tab-view{padding:75px 75px 6px 1px;margin-left:80px;color:\"#1f1f1fdb\"}.inspect-add{margin-top:3rem}.add-btn{font-size:16px;border-radius:5px;transition:.2s;padding:.25rem .5rem;background:#fff;border:1px solid rgba(148,147,147,.1882352941);color:#444;line-height:48px;box-shadow:0 1px 9px #98a2b3;width:9rem}.add-btn:hover{border:1px solid rgba(148,147,147,.1882352941);box-shadow:none}.agree{padding:0 0 8px 47px}.agree .form-check-input[type=checkbox]{border-radius:2px;border:2px solid #98A2B3;width:14px;height:14px;margin:5px 9px 0 -35px}.agree .form-check-input:focus{box-shadow:none}.agree .form-check-input:checked{background-color:#000;border-color:#000}.agree .invalid-feedback{font-size:10px!important;margin:0 0 0 21px}.checkmark{vertical-align:text-bottom;color:#98a2b3;font-weight:500;font-size:12px}.term-signature{padding-left:16rem;padding-right:65px;position:absolute;margin:150px 0 0 50%}.participate-tab{height:135px;width:142px}.card-design{height:147px;width:147px;padding-left:10px;margin-left:42px;background:#fff0;border:2px solid #98A2B3;box-shadow:0 0 4px #98a2b3;border-radius:27px;margin-bottom:42px}.upload{height:39px;margin-top:-4px;width:126px;font-size:12px}.participate-tab{margin-top:-25px}.slider{width:14rem;margin-left:69px}.btn-clear{background:#d3dae6;color:#98a2b3;font-size:12px;border-radius:5px;transition:.2s;padding:6px;border:none;height:auto;width:46%;line-height:28px}.btn-close{background:#f1f4fa;color:#98a2b3;font-size:17px;border-radius:5px;transition:.2s;padding:6px;border:none;height:auto;font-weight:500;width:116px;color:#737a87;line-height:28px}.view-logo{padding-top:1%;padding-bottom:4%;text-align:center}.back-btn{border-radius:45px;height:41px}.next{background:#4077ad;border-radius:30px;height:60px;width:60px;border:white}.profile-field{margin-top:-10px}.profile-field input{line-height:30px;margin:-10px 3px 3px}.load-page{padding:21px 49px 13px 34px}.sign-img{width:291px;height:95px;border-radius:8px;border:1px solid rgba(179,178,178,.33);margin-top:19px}.upload-image{height:16px;width:16px;position:absolute;margin-left:66rem;margin-top:-39px}.para-comma{font-weight:500}.go-btn{border-radius:45px;height:50px;padding:0 20px;background:#4077ad;border:1px solid #4077ad;color:#fff;line-height:28px;font-size:14px;font-weight:500}.text-label{color:#747b83;font-weight:500}.form{padding:20px;border-radius:5px}.form-control:focus{color:#000;box-shadow:none;border-color:#848484!important}.form-control::placeholder{font-weight:500;font-size:12px;color:#bec1be;padding-left:10px}.btn-primary:active{background-color:#50575e}@media screen and (min-width: 500px) and (max-width: 769px){.content-view{background:#0c1620;width:44rem;margin:31px 0 0!important;padding:28px 32px 17px 71px!important;border-radius:29px}.upload-image{margin-left:25rem!important}}@media screen and (min-width: 768px) and (max-width: 1024px){.back-btn{height:31px;width:82px;position:absolute;margin-left:-53px}.back-tab{position:absolute;margin-left:-87px;height:37px}.go-btn{width:175px;height:44px}.term-signature{padding-left:10px}.upload-image{margin-left:40rem}}@media screen and (min-width: 374px) and (max-width: 426px){.head-logo{width:216px;padding-bottom:16px}.slider{visibility:hidden}.back-btn{height:31px;width:82px;position:absolute;margin-left:73px;margin-top:23px}.go-btn{width:175px;height:44px}.upload-image{margin-left:16rem}.term-signature{margin:84% 0 7px 4%}}@media screen and (min-width: 320px) and (max-width: 426px){.footer-signature{margin-top:20rem}.login .head-logo{padding:16px 2px 0;width:38%!important;height:40%!important}.container{margin-top:5px!important}.card{padding:2px!important}.tag-content{margin:3% 0 0!important;background-color:#121b24;border-radius:13px}.img-tick{margin:3px!important}.slider{visibility:hidden}.load-page{padding:0}.head-logo{width:216px;padding-bottom:16px}.back-btn{height:26px;width:71px;position:absolute;margin-left:-17rem!important;font-size:10px;margin-top:23px}.go-btn{width:142px;height:36px;margin-right:-28px;font-size:10px}.add-tab,.add-tab-view{padding:30px 33px 2px 3px;margin-left:15px}.add-btn{width:6rem}.slider-tab{visibility:hidden}.back-tab{margin-left:-14rem;margin-top:1px;font-size:14px;height:39px}.participate-tab{height:96px;width:87px}.card-design{height:124px;width:125px;padding-left:17px;margin-left:30px}.term-signature{padding:22px 22px 13px 27px}.term-list{padding:43px 10px 10px 3px;margin-left:0;text-align:-webkit-center}}@media screen and (min-width: 320px) and (max-width: 376px){.agree{padding:0 0 8px 25px}.participate-tab{height:96px;width:87px}.card-design{height:109px;width:97px;padding-left:4px;margin-left:10px}.card-design h6{font-size:10px;padding-left:14px;font-weight:600}.sign-img{width:270px}.term-list{padding:20px 20px 6px 4px;margin-left:13px}}@media screen and (min-width: 320px) and (max-width: 350px){.upload-image{height:13px;width:11px;margin-left:10rem;margin-top:-35px}.btn-clear{width:92px}.term-signature{margin:84% 0 7px 4%}}.disabled-btn{cursor:not-allowed!important;background:#4077ad!important;color:#fff!important}.modal-dialog .modal-content{border-radius:12px;background:#fff!important;border:1px solid rgba(128,128,128,.3294117647)!important}.title-popup{font-size:18px;color:#0c1620}.tc-modal-dialog{max-width:min(780px,96vw)}.tc-modal{border-radius:10px!important;border:none!important;overflow:hidden;box-shadow:0 32px 72px #00000038,0 6px 20px #0000001a!important;height:min(720px,90vh);display:flex;flex-direction:column}.tc-modal-header{display:flex;align-items:center;flex-wrap:wrap;gap:6px 12px;padding:10px 28px 14px;background:#4077ad;border-bottom:none;flex-shrink:0}.tc-modal-header .tc-header-icon{width:40px;height:40px;border-radius:11px;display:flex;align-items:center;justify-content:center;color:#fff;flex-shrink:0}.tc-modal-header .tc-modal-title{font-family:Inter,system-ui,sans-serif;font-size:18px;font-weight:700;color:#fff;letter-spacing:-.01em;padding:10px;margin:0;flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tc-modal-header .tc-modal-meta{font-weight:600;font-size:12px;color:#fff;flex-shrink:0;white-space:nowrap}@media screen and (max-width: 767px){.tc-modal-header .tc-modal-header{flex-flow:column;align-items:center;text-align:center}.tc-modal-header .tc-modal-title{flex:1 1 100%;white-space:normal}.tc-modal-header .tc-modal-meta{flex:1 1 100%;opacity:.85}}.tc-scroll-hint{display:flex;align-items:center;gap:7px;padding:9px 28px;background:#f0f9ff;border-bottom:none;font-size:12px;color:#4077ad;font-family:Inter,system-ui,sans-serif;letter-spacing:.01em;flex-shrink:0}.tc-scroll-hint svg{flex-shrink:0}.tc-scroll-hint strong{font-weight:700}.tc-scroll-hint .tc-progress-pill{margin-left:auto;background:#4077ad;color:#fff;font-size:11px;font-weight:700;letter-spacing:.04em;padding:2px 9px;border-radius:99px;min-width:42px;text-align:center;transition:background .2s ease}.tc-progress-bar{height:3px;background:#e0f2fe;flex-shrink:0}.tc-progress-bar .tc-progress-fill{height:100%;background:linear-gradient(90deg,#4077ad,#38bdf8);border-radius:0 99px 99px 0;transition:width .12s ease}.tc-scroll-wrapper{position:relative;flex:1 1 auto;overflow:hidden;display:flex;flex-direction:column}.tc-modal-body{flex:1 1 auto;overflow-y:auto;padding:26px 32px;background:#fff;scrollbar-width:thin;scrollbar-color:#cbd5e1 transparent}.tc-modal-body::-webkit-scrollbar{width:5px}.tc-modal-body::-webkit-scrollbar-track{background:transparent}.tc-modal-body::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:99px}.tc-modal-body::-webkit-scrollbar-thumb:hover{background:#94a3b8}.tc-scroll-fab{position:absolute;bottom:20px;right:20px;width:46px;height:46px;border-radius:50%;background:linear-gradient(135deg,#4077ad 0% 100%);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:10;transition:transform .18s ease,box-shadow .18s ease}.tc-scroll-fab:hover{transform:translateY(-3px) scale(1.1);animation:none}@keyframes tc-fab-bounce{0%,to{transform:translateY(0);box-shadow:0 4px 18px #2563eb80}50%{transform:translateY(5px);box-shadow:0 2px 10px #2563eb59}}.tc-modal-footer{display:flex;justify-content:flex-end;align-items:center;gap:10px;padding:16px 24px;background:#f8fafc;border-top:1px solid #e2e8f0;flex-shrink:0}.tc-btn{font-family:Inter,system-ui,sans-serif;font-size:14px;font-weight:600;letter-spacing:.015em;padding:10px 26px;border-radius:5px;border:none;cursor:pointer;transition:background .18s ease,transform .15s ease}.tc-btn.tc-btn-decline{background:#b43026;color:#fff;border:1.5px solid #B43026}.tc-btn.tc-btn-decline:hover{background:#96271f;border-color:#96271f;color:#fff}.tc-btn.tc-btn-agree{background:linear-gradient(135deg,#4077ad 0% 100%);border:1.5px solid transparent;color:#fff}.tc-btn.tc-btn-agree:hover:not(:disabled){background:linear-gradient(135deg,#2d5f8a,#4077ad);transform:translateY(-1px)}.tc-btn.tc-btn-agree:disabled{background:#e2e8f0;color:#94a3b8;box-shadow:none;cursor:not-allowed}ul.term-list-data li{padding-bottom:5px;font-size:13px;font-weight:500;line-height:21px}ol,ul,dl{margin-top:0;margin-bottom:1rem}::ng-deep .modal-content{width:100%;border:none}.hidden-view{display:none}.header-container{position:relative;padding:20px}.view-logo{text-align:center}.logout-button{top:20px;right:20px;position:absolute}.logout-button button{background:none;border:none;font-size:16px;display:flex;align-items:center;cursor:pointer}.logout-button img{margin-right:5px;height:20px}.user-card{align-items:center;color:#4077ad;cursor:pointer}.user-cards-active{background:#4077ad;color:#fff}.save-btn.upload{border:1px solid #4077AD;background-color:#4077ad;color:#fff;border-radius:5px;background:#4077ad;padding:4px 10px;display:inline-flex;align-items:center;gap:6px}.save-btn.upload img{filter:brightness(0) invert(1)}.form-check.agree{display:flex;align-items:flex-start;gap:8px;margin-bottom:8px}.form-check.agree .form-check-input{margin-top:4px;flex-shrink:0}.form-check.agree .form-check-label{line-height:1.4;cursor:pointer;white-space:normal}.spinner-16{width:16px;height:16px}.h6-buttons{display:flex;align-items:center;gap:8px}.form-check.agree{display:flex;align-items:flex-start;margin-bottom:14px}.form-check-input{position:absolute;opacity:0;cursor:pointer}.form-check-label{position:relative;padding-left:28px;cursor:pointer;font-size:14px;line-height:20px;color:#212529;-webkit-user-select:none;user-select:none}.form-check-label:before{content:\"\";position:absolute;left:0;top:8px;width:18px;height:18px;border:2px solid #adb5bd;border-radius:4px;background:#fff;transition:all .2s ease}.form-check-label:after{content:\"\";position:absolute;left:5px;top:10px;width:6px;height:10px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg) scale(0);transition:transform .15s ease}.form-check-input:checked+.form-check-label:before{background-color:#4077ad;border-color:#4077ad}.form-check-input:checked+.form-check-label:after{transform:rotate(45deg) scale(1)}.form-check-label:hover:before{border-color:#4077ad}.form-check-input:focus+.form-check-label:before{box-shadow:0 0 0 3px #4077ad40}.form-check-input.is-invalid+.form-check-label:before{border-color:#dc3545}.form-check-input.is-invalid:checked+.form-check-label:before{background-color:#dc3545}.invalid-feedback{display:block;font-size:12px;margin-left:7px;margin-top:4px}::ng-deep .modal-dialog{max-width:750px}.user-cards-active{background-color:#4077ad;color:#fff;border:2px solid #4077AD}body.modal-open{overflow:hidden!important}.modal{z-index:1055!important}.modal-backdrop{z-index:1050!important}.modal-dialog{margin:auto;pointer-events:auto}.modal-content{position:relative;z-index:1060}.logout-container{display:flex;justify-content:flex-end}.logout-btn{display:inline-flex;align-items:center;gap:7px;padding:7px 16px;border-radius:5px;font-size:14px;font-weight:500;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;background:#f8fafc;border:1.5px solid #e2e8f0;cursor:pointer;transition:color .18s,background .18s,border-color .18s,box-shadow .18s}.logout-btn:hover{color:#dc2626;background:#fff5f5;border-color:#fca5a5}.logout-btn:active{transform:scale(.97)}@media screen and (max-width: 767px){.term-signature{padding-left:3rem;padding-right:0;position:unset;margin:0}.footer-signature{margin-top:0rem}.disabled-btn{position:absolute;bottom:13px;right:24px}.next{height:46px;width:46px;position:absolute;bottom:21px;right:35px}.mob{padding-bottom:4.5rem!important}.checkmark{width:85%}.terms-fixed-modal{width:unset}::ng-deep .privacy-policy-modal .logo-section{margin-bottom:0!important}.add-tab-view{padding:30px 25px 6px;margin-left:0}.user-card{width:96%}.footer .btn-mob{display:flex;align-items:center}.back-btn{position:absolute;bottom:21px;left:10px}.actions{margin:50px 34px 1px}}@media screen and (min-width: 768px) and (max-width: 1024px){.footer-signature{margin-top:3rem}}.v1-welcome{display:flex;align-items:flex-start;gap:16px;padding:28px 32px 20px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.v1-welcome-icon{flex-shrink:0;width:48px;height:48px;border-radius:50%;border:1px solid #cfd2d6;display:flex;align-items:center;justify-content:center;color:#90979d;margin-top:2px}.v1-welcome-title{font-size:18px;font-weight:700;color:#69707d;margin:0 0 6px;line-height:1.25;letter-spacing:-.02em}.v1-brand{color:#4077ad}.v1-welcome-sub{font-size:14px;color:#69707d;line-height:1.65;margin:0}.v1-body{display:grid;grid-template-columns:1fr 1fr;gap:20px;padding:0 32px 20px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v1-body{grid-template-columns:1fr;padding:0 16px 16px}}.v1-agreements{display:flex;flex-direction:column;gap:12px}.v1-agreement-card{display:flex;align-items:center;gap:14px;padding:16px 18px;border-radius:5px;border:1.5px solid #e2e8f0;background:#fff;transition:border-color .2s,box-shadow .2s;box-shadow:0 1px 3px #0000000a}.v1-agreement-card:hover{border-color:#c7d3e2;box-shadow:0 2px 8px #00000012}.v1-agreement-card.v1-card--agreed{border-color:#dde2e7}.v1-agreement-card.v1-card--invalid{border-color:#fecaca;background:#fff5f5}.v1-card-icon{flex-shrink:0;width:38px;height:38px;border-radius:5px;border:1px solid #e2e8f0;display:flex;align-items:center;justify-content:center;color:#4077ad}.v1-card--agreed .v1-card-icon{border-color:#dde2e7;color:#7e8994}.v1-card-body{flex:1 1 auto;min-width:0}.v1-card-title{font-size:14px;font-weight:600;color:#69707d;margin:0 0 2px;line-height:1.3}.v1-card-sub{font-size:12px;color:#6b7280;margin:0}.v1-agree-btn{flex-shrink:0;display:inline-flex;align-items:center;gap:5px;padding:7px 14px;border-radius:5px;font-size:12px;font-weight:600;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;border:1.5px solid #4077AD;color:#4077ad;background:transparent;cursor:pointer;white-space:nowrap;transition:background .18s,color .18s}.v1-agree-btn:hover{background:#4077ad;color:#fff}.v1-agree-btn.v1-agree-btn--done{background:#3e7f50;border-color:#3e7f50;color:#fff}.v1-agree-btn:disabled{opacity:.7;cursor:not-allowed}.v1-agree-btn:disabled:hover{background:transparent;color:#4077ad}.v1-agree-spinner{width:12px;height:12px;border:2px solid currentColor;border-top-color:transparent;border-radius:50%;flex-shrink:0;animation:v1-agree-spin .7s linear infinite}@keyframes v1-agree-spin{to{transform:rotate(360deg)}}.v1-signature{display:flex;flex-direction:column;gap:10px}.v1-sig-header{display:flex;align-items:center;justify-content:space-between}.v1-sig-label{display:inline-flex;align-items:center;gap:7px;font-size:14px;font-weight:600;color:#69707d;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.v1-clear-btn{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:500;color:#6b7280;background:transparent;border:1px solid #e2e8f0;border-radius:5px;padding:4px 10px;cursor:pointer;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;transition:color .18s,border-color .18s}.v1-clear-btn:hover{color:#dc2626;border-color:#fca5a5}.v1-sig-pad{position:relative;border-radius:5px;border:1.5px dashed #cbd5e1;overflow:hidden;min-height:120px}.v1-sig-pad canvas{display:block;cursor:crosshair;width:100%;height:120px}.v1-sig-hint{position:absolute;bottom:8px;left:50%;transform:translate(-50%);font-size:12px;color:#c0cad8;pointer-events:none;margin:0;white-space:nowrap;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.v1-error-msg{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:500;color:#dc2626;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.v1-footer{padding:8px 32px 20px;display:flex;justify-content:flex-end;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v1-footer{padding:8px 16px 20px}}.v1-continue-btn{display:inline-flex;align-items:center;gap:9px;padding:12px 28px;border-radius:5px;font-size:14px;font-weight:600;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:linear-gradient(135deg,#4077ad 0% 100%);border:none;cursor:pointer;transition:transform .15s;min-width:148px;justify-content:center}.v1-continue-btn:hover:not(:disabled){transform:translateY(-1px)}.v1-continue-btn:active:not(:disabled){transform:translateY(0)}.v1-continue-btn:disabled,.v1-continue-btn.disabled{background:#e2e8f0;color:#94a3b8;box-shadow:none;cursor:not-allowed}.v1-spinner{display:inline-block;width:16px;height:16px;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:v1-spin .65s linear infinite}@keyframes v1-spin{to{transform:rotate(360deg)}}@media (max-width: 767px){.v1-welcome{padding:20px 16px 14px;gap:12px}.v1-welcome-icon{width:40px;height:40px}.v1-welcome-title{font-size:16px}}.v2-header{display:flex;align-items:flex-start;gap:16px;padding:28px 32px 20px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v2-header{padding:20px 16px 14px;gap:12px}}.v2-header-icon{flex-shrink:0;width:48px;height:48px;border-radius:50%;border:1px solid #cecece;display:flex;align-items:center;justify-content:center;color:#abb3ba;margin-top:2px}.v2-title{font-size:18px;font-weight:700;color:#69707d;margin:0 0 6px;line-height:1.25;letter-spacing:-.02em}.v2-sub{font-size:14px;color:#69707d;line-height:1.65;margin:0}.v2-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:14px;padding:10px 32px 50px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v2-grid{grid-template-columns:repeat(auto-fill,minmax(110px,1fr));padding:0 16px 20px;gap:10px}}.v2-role-card{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:20px 12px 16px;border-radius:5px;border:1.5px solid #e2e8f0;background:#fff;cursor:pointer;transition:border-color .18s,box-shadow .18s,transform .15s;box-shadow:0 1px 3px #0000000a;text-align:center}.v2-role-card:hover{z-index:30;border-color:#93c5fd;box-shadow:0 4px 16px #4077ad1a;transform:translateY(-2px)}.v2-role-card.v2-role-card--active{border-color:#4077ad;background:#eff6ff;box-shadow:0 0 0 3px #4077ad1f,0 4px 16px #4077ad1f}.v2-role-img-wrap{width:64px;height:64px;border-radius:50%;background:#f8fafc;border:1px solid #e2e8f0;display:flex;align-items:center;justify-content:center;overflow:hidden;transition:background .18s,border-color .18s}.v2-role-img-wrap img{width:44px;height:44px;object-fit:contain;display:block}.v2-role-card--active .v2-role-img-wrap{background:#dbeafe;border-color:#93c5fd}.v2-role-name{font-size:14px;font-weight:600;color:#69707d;line-height:1.3;text-align:center}.v2-role-card--active .v2-role-name{color:#4077ad}.v2-role-subtitle{font-size:11px;font-weight:400;color:#6b7280;line-height:1.3;text-align:center;margin-top:2px}.v2-role-tooltip{position:absolute;top:calc(100% + 10px);left:50%;transform:translate(-50%) translateY(-4px);width:240px;max-width:80vw;background:#4077ad;color:#fff;font-size:12px;font-weight:400;line-height:1.45;text-align:left;padding:10px 12px;border-radius:6px;box-shadow:0 6px 18px #0000002e;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .15s ease,transform .15s ease;z-index:40}.v2-role-tooltip:after{content:\"\";position:absolute;bottom:100%;left:50%;transform:translate(-50%);border-width:6px;border-style:solid;border-color:transparent transparent #4077ad transparent}.v2-role-card:hover .v2-role-tooltip{opacity:1;visibility:visible;transform:translate(-50%) translateY(0)}.v2-role-info-btn{position:absolute;top:8px;right:8px;width:20px;height:20px;border-radius:50%;background:#4077ad;color:#fff;border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;z-index:2;transition:background .15s ease,transform .15s ease}.v2-role-info-btn:hover{background:#345f87;transform:scale(1.08)}.v2-info-overlay{position:fixed;inset:0;background:#0f172a73;display:flex;align-items:center;justify-content:center;z-index:1000}.v2-info-popup{width:560px;max-width:90vw;max-height:80vh;display:flex;flex-direction:column;background:#fff;border-radius:8px;overflow:hidden;box-shadow:0 12px 32px #00000040}.v2-info-popup-header{display:flex;align-items:center;justify-content:space-between;background:#4077ad;padding:14px 16px}.v2-info-popup-title{color:#fff;font-size:15px;font-weight:600}.v2-info-popup-close{background:transparent;border:none;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:2px}.v2-info-popup-body{padding:16px;font-size:13px;line-height:1.6;color:#69707d;white-space:pre-line;overflow-y:auto}.v2-footer{display:flex;align-items:center;justify-content:flex-end;gap:12px;padding:8px 32px 24px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v2-footer{padding:8px 16px 20px}}.v2-back-btn{display:inline-flex;align-items:center;gap:7px;padding:10px 20px;border-radius:5px;font-size:14px;font-weight:500;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:#69707d;border:1.5px solid #69707D;cursor:pointer;transition:color .18s,border-color .18s,background .18s}.v2-back-btn:hover{color:#fff;background:#565c66;border-color:#565c66}.v2-continue-btn{display:inline-flex;align-items:center;gap:9px;padding:10px 24px;border-radius:5px;font-size:14px;font-weight:600;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:linear-gradient(135deg,#4077ad 0% 100%);border:none;cursor:pointer;box-shadow:0 4px 14px #4077ad4d;transition:transform .15s,box-shadow .15s}.v2-continue-btn:hover:not(:disabled){transform:translateY(-1px)}.v2-continue-btn:disabled{background:#e2e8f0;color:#94a3b8;box-shadow:none;cursor:not-allowed}.ip-header{display:flex;align-items:flex-start;gap:16px;padding:28px 32px 16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.ip-header{padding:20px 16px 12px;gap:12px}}.ip-header-icon{flex-shrink:0;width:48px;height:48px;border-radius:50%;border:1px solid #c7c7c7;display:flex;align-items:center;justify-content:center;color:#959191;margin-top:2px}.ip-title{font-size:18px;font-weight:700;color:#69707d;margin:0 0 6px;line-height:1.25;letter-spacing:-.02em;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.ip-sub{font-size:14px;color:#69707d;line-height:1.65;margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.ip-section{margin:0 24px 14px;background:#fff;border:1.5px solid #e2e8f0;border-radius:5px;padding:18px 20px 16px;box-shadow:0 1px 4px #0000000a}@media (max-width: 767px){.ip-section{margin:0 12px 10px;padding:14px}}.ip-section-label{font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:#6b7280;margin:0 0 12px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.ip-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:12px}@media (max-width: 767px){.ip-grid-2{grid-template-columns:1fr}}.ip-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px}@media (max-width: 1024px){.ip-grid-3{grid-template-columns:1fr 1fr}}@media (max-width: 599px){.ip-grid-3{grid-template-columns:1fr}}.ip-grid-4{display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:12px}@media (max-width: 1024px){.ip-grid-4{grid-template-columns:1fr 1fr}}@media (max-width: 599px){.ip-grid-4{grid-template-columns:1fr}}.ip-field{display:flex;flex-direction:column;gap:5px}.ip-label{font-size:12px;font-weight:600;color:#69707d;margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;line-height:1.3}.ip-required{color:#dc2626;margin-left:2px;font-weight:700}.ip-input{width:100%;height:44px;padding:0 14px;border:1.5px solid #e2e8f0;border-radius:5px;font-size:14px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;background:#fff;outline:none;transition:border-color .18s,box-shadow .18s;box-sizing:border-box}.ip-input::placeholder{color:#adb5bd;font-weight:400}.ip-input:focus{border-color:#4077ad;box-shadow:0 0 0 3px #4077ad1a}.ip-input.ip-input--invalid{border-color:#dc2626;background:#fff8f8}.ip-input.ip-input--invalid:focus{box-shadow:0 0 0 3px #dc26261a}.ip-input[readonly]{cursor:pointer;background:#f8fafc}.ip-error{display:flex;align-items:center;gap:4px;font-size:12px;font-weight:500;color:#dc2626;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.ip-upload-wrap{position:relative;display:flex;align-items:center}.ip-upload-icon{position:absolute;right:14px;width:16px;height:16px;cursor:pointer;opacity:.45;transition:opacity .18s}.ip-upload-icon:hover{opacity:.85}.ip-upload-hint{margin-top:6px;font-size:12px}.ip-copy-row{display:flex;align-items:center;gap:10px;margin:0 24px 12px;padding:11px 16px;background:#eff6ff;border:1.5px solid #bfdbfe;border-radius:10px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.ip-copy-row{margin:0 12px 10px}}.ip-copy-check{width:16px;height:16px;accent-color:#4077AD;cursor:pointer;flex-shrink:0}.ip-copy-label{font-size:14px;font-weight:500;color:#69707d;cursor:pointer;margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;-webkit-user-select:none;user-select:none}.ip-footer{display:flex;align-items:center;justify-content:flex-end;gap:12px;padding:8px 24px 28px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.ip-footer{padding:8px 16px 24px}}.ip-back-btn{display:inline-flex;align-items:center;gap:7px;padding:10px 20px;border-radius:5px;font-size:14px;font-weight:500;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:#69707d;border:1.5px solid #69707D;cursor:pointer;transition:color .18s,border-color .18s,background .18s}.ip-back-btn:hover{color:#fff;border-color:#565c66;background:#565c66}.ip-next-btn{display:inline-flex;align-items:center;gap:9px;padding:10px 26px;border-radius:5px;font-size:14px;font-weight:600;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:linear-gradient(135deg,#4077ad 0% 100%);border:none;cursor:pointer;box-shadow:0 4px 14px #4077ad4d;transition:transform .15s,box-shadow .15s}.ip-next-btn:hover:not(:disabled){transform:translateY(-1px)}.ip-next-btn:active:not(:disabled){transform:translateY(0)}.ip-next-btn:disabled{background:#e2e8f0;color:#94a3b8;box-shadow:none;cursor:not-allowed}.v5-wrap{display:flex;flex-direction:column;align-items:center;text-align:center;padding:48px 32px 40px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v5-wrap{padding:36px 20px 32px}}.v5-icon{width:72px;height:72px;border-radius:50%;background:linear-gradient(135deg,#dcfce7,#bbf7d0);border:1.5px solid #86efac;display:flex;align-items:center;justify-content:center;color:#16a34a;margin-bottom:20px;box-shadow:0 0 0 8px #22c55e14}.v5-title{font-size:18px;font-weight:800;color:#69707d;margin:0 0 10px;letter-spacing:-.025em;line-height:1.2}.v5-sub{font-size:14px;color:#69707d;margin:0 0 28px;line-height:1.6;max-width:480px}.v5-cards{display:flex;flex-direction:column;gap:12px;width:100%;max-width:520px;margin-bottom:32px;text-align:left}.v5-card{display:flex;align-items:flex-start;gap:14px;padding:16px 18px;border-radius:12px;border:1.5px solid #e2e8f0;background:#f8fafc;box-shadow:0 1px 3px #0000000a}.v5-card-icon{flex-shrink:0;width:36px;height:36px;border-radius:9px;background:#eff6ff;border:1px solid #bfdbfe;display:flex;align-items:center;justify-content:center;color:#4077ad}.v5-card-icon.v5-card-icon--green{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a}.v5-card-text{font-size:14px;color:#69707d;line-height:1.6;margin:0}.v5-cta{display:inline-flex;align-items:center;gap:10px;padding:13px 32px;border-radius:5px;font-size:14px;font-weight:600;font-family:inherit;color:#fff;background:linear-gradient(135deg,#4077ad 0% 100%);border:none;cursor:pointer;box-shadow:0 4px 16px #4077ad52;transition:transform .15s,box-shadow .15s}.v5-cta:hover{transform:translateY(-2px)}.v5-cta:active{transform:translateY(0)}.cc-select-wrap{margin-bottom:20px}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-select-container{border:1.5px solid #e2e8f0;border-radius:10px;min-height:48px;padding:5px 10px;background:#fff;box-shadow:none;cursor:text;transition:border-color .18s,box-shadow .18s}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-select-container:hover{border-color:#94a3b8}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple.ng-select-focused .ng-select-container{border-color:#4077ad;box-shadow:0 0 0 3px #4077ad1a}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-container{flex-wrap:wrap;gap:6px;padding:2px 0}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value{display:inline-flex;flex-direction:row;align-items:center;gap:5px;background:#eff6ff;border:1px solid #bfdbfe;border-radius:99px;padding:4px 8px 4px 13px;font-size:12px;font-weight:600;color:#4077ad;margin:0;line-height:1}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-label{order:1}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-icon{display:inline-flex;align-items:center;justify-content:center;order:2;width:16px;height:16px;border-radius:50%;font-size:12px;font-weight:700;line-height:1;padding:0;background:#4077ad26;color:#4077ad;cursor:pointer;flex-shrink:0;transition:background .15s,color .15s}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-icon:hover{background:#4077ad;color:#fff}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-icon.right{display:none}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-placeholder{font-size:14px;color:#adb5bd;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-select-container.ng-has-value .ng-placeholder{display:none}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-input>input{font-size:14px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-arrow-wrapper{padding-right:6px}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-arrow-wrapper .ng-arrow{border-color:#94a3b8 transparent transparent;border-width:5px 4px 0}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-clear-wrapper{color:#94a3b8}::ng-deep .ng-dropdown-panel{border:1.5px solid #e2e8f0;border-radius:12px;box-shadow:0 8px 28px #0000001a,0 2px 8px #0000000f;overflow:hidden;margin-top:5px;z-index:9999!important;background:#fff!important}::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items{padding:6px}::ng-deep .ng-dropdown-panel .ng-option{border-radius:8px;padding:10px 13px;font-size:14px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;transition:background .12s}::ng-deep .ng-dropdown-panel .ng-option.ng-option-selected{background:#eff6ff;color:#4077ad;font-weight:600}::ng-deep .ng-dropdown-panel .ng-option.ng-option-marked:not(.ng-option-selected){background:#f8fafc;color:#69707d}::ng-deep .ng-dropdown-panel .ng-option.ng-option-selected.ng-option-marked{background:#dbeafe}.cc-group{margin-bottom:18px;padding-top:4px}.cc-group:last-child{margin-bottom:0}.cc-hidden-check{position:absolute;opacity:0;width:0;height:0;pointer-events:none}.cc-select-all-pill{display:inline-flex;align-items:center;gap:6px;padding:7px 16px;border-radius:99px;border:1.5px solid #e2e8f0;background:#f8fafc;font-size:12px;font-weight:700;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;cursor:pointer;-webkit-user-select:none;user-select:none;margin-bottom:10px;transition:background .18s,border-color .18s,color .18s}.cc-select-all-pill:hover:not(.cc-select-all-pill--on){background:#f1f5f9;border-color:#94a3b8}.cc-select-all-pill.cc-select-all-pill--on{background:#69707d;border-color:#69707d;color:#fff}.cc-sub-pills{display:flex;flex-wrap:wrap;gap:8px}.cc-sub-pill{display:inline-flex;align-items:center;gap:5px;padding:6px 14px;border-radius:99px;border:1.5px solid #e2e8f0;background:#fff;font-size:12px;font-weight:500;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background .15s,border-color .15s,color .15s,box-shadow .15s}.cc-sub-pill:hover:not(.cc-sub-pill--on){background:#f8fafc;border-color:#94a3b8;color:#69707d}.cc-sub-pill.cc-sub-pill--on{background:#eff6ff;border-color:#93c5fd;color:#4077ad;font-weight:600;box-shadow:0 0 0 3px #4077ad12}html,body{overscroll-behavior:none;height:100%;overflow:hidden}\n"] }]
|
|
37054
|
+
args: [{ selector: 'app-initial-process', standalone: false, template: "<div class=\"container\">\r\n <div *ngIf=\"isInitializing\" class=\"text-center p-5\">\r\n <div class=\"spinner-border text-primary\"></div>\r\n </div>\r\n <ng-container *ngIf=\"!isInitializing\">\r\n <div class=\"mb-4 logout-container\" *ngIf=\"showlogout\">\r\n <button class=\"logout-btn\" (click)=\"logout()\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4\"/>\r\n <polyline points=\"16 17 21 12 16 7\"/>\r\n <line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\"/>\r\n </svg>\r\n Logout\r\n </button>\r\n </div>\r\n <div class=\"card pb-2 mob pr-5\" style=\"margin-bottom: 30px;\">\r\n <div [hidden]=\"view !== 1\">\r\n\r\n <!-- \u2500\u2500 Welcome Banner \u2500\u2500 -->\r\n <div class=\"v1-welcome\">\r\n <div class=\"v1-welcome-icon\">\r\n <svg width=\"26\" height=\"26\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2\"/>\r\n <circle cx=\"9\" cy=\"7\" r=\"4\"/>\r\n <path d=\"M23 21v-2a4 4 0 00-3-3.87\"/>\r\n <path d=\"M16 3.13a4 4 0 010 7.75\"/>\r\n </svg>\r\n </div>\r\n <div class=\"v1-welcome-text\">\r\n <h2 class=\"v1-welcome-title\">Welcome to <span class=\"v1-brand\">{{ branding.displayName }}</span></h2>\r\n <p class=\"v1-welcome-sub\">Our members and service providers rely on accurate info in your profile to connect\r\n you with work that suits your capabilities. Keep your profile complete, skills updated, licenses current,\r\n photos and logos professional, and schedule up to date.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Main Body: agreements + signature \u2500\u2500 -->\r\n <div class=\"v1-body\">\r\n\r\n <!-- Left: agreement cards -->\r\n <div class=\"v1-agreements\">\r\n\r\n <!-- Terms card -->\r\n <div class=\"v1-agreement-card\" [class.v1-card--agreed]=\"model.acceptTerms\"\r\n [class.v1-card--invalid]=\"!model.acceptTerms && validatePage==1\">\r\n <div class=\"v1-card-icon\">\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z\"/>\r\n <polyline points=\"14 2 14 8 20 8\"/>\r\n <line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\"/>\r\n <line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\"/>\r\n </svg>\r\n </div>\r\n <div class=\"v1-card-body\">\r\n <p class=\"v1-card-title\">Terms and Conditions</p>\r\n <p class=\"v1-card-sub\">Read and accept to continue</p>\r\n </div>\r\n <button type=\"button\" class=\"v1-agree-btn\" [class.v1-agree-btn--done]=\"model.acceptTerms\"\r\n [disabled]=\"isTermsLoading\"\r\n (click)=\"openModal(termsAndConditionsModel,'Terms and Conditions',$event)\">\r\n <span class=\"v1-agree-spinner\" *ngIf=\"isTermsLoading\"></span>\r\n <svg *ngIf=\"!isTermsLoading && model.acceptTerms\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n {{ isTermsLoading ? 'Loading...' : (model.acceptTerms ? 'Agreed' : 'Read & Agree') }}\r\n </button>\r\n </div>\r\n\r\n <!-- Privacy card -->\r\n <div class=\"v1-agreement-card\" [class.v1-card--agreed]=\"model.privacy\"\r\n [class.v1-card--invalid]=\"!model.privacy && validatePage==1\">\r\n <div class=\"v1-card-icon\">\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"/>\r\n </svg>\r\n </div>\r\n <div class=\"v1-card-body\">\r\n <p class=\"v1-card-title\">Privacy Statement</p>\r\n <p class=\"v1-card-sub\">Read and accept to continue</p>\r\n </div>\r\n <button type=\"button\" class=\"v1-agree-btn\" [class.v1-agree-btn--done]=\"model.privacy\"\r\n [disabled]=\"isPrivacyLoading\"\r\n (click)=\"openModal(termsAndConditionsModel,'Privacy Statement',$event)\">\r\n <span class=\"v1-agree-spinner\" *ngIf=\"isPrivacyLoading\"></span>\r\n <svg *ngIf=\"!isPrivacyLoading && model.privacy\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n {{ isPrivacyLoading ? 'Loading...' : (model.privacy ? 'Agreed' : 'Read & Agree') }}\r\n </button>\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- Right: signature pad -->\r\n <div class=\"v1-signature\">\r\n <div class=\"v1-sig-header\">\r\n <span class=\"v1-sig-label\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M17 3a2.828 2.828 0 114 4L7.5 20.5 2 22l1.5-5.5L17 3z\"/>\r\n </svg>\r\n Signature\r\n </span>\r\n <button (click)=\"clearPad()\" class=\"v1-clear-btn\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M18 6L6 18M6 6l12 12\"/>\r\n </svg>\r\n Clear\r\n </button>\r\n </div>\r\n <div class=\"v1-sig-pad\">\r\n <div [ngClass]=\"{'d-none': signaturePadData?.publicUrl}\" style=\"width:100%\">\r\n <canvas #canvas></canvas>\r\n </div>\r\n <div [ngClass]=\"{'d-none': !signaturePadData?.publicUrl}\" style=\"width:100%\">\r\n <img [src]=\"signaturePadData?.publicUrl\" alt style=\"width:100%;height:120px;object-fit:contain;display:block;\">\r\n </div>\r\n <p class=\"v1-sig-hint\" *ngIf=\"!signaturePadData?.publicUrl && (!points || !points?.length)\">\r\n Draw your signature here\r\n </p>\r\n </div>\r\n <div *ngIf=\"validatePage==1 && (!points || !points?.length || points.length==0) && !fileData\"\r\n class=\"v1-error-msg\">\r\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/>\r\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>\r\n </svg>\r\n Signature is required\r\n </div>\r\n <div *ngIf=\"uploadError\" class=\"v1-error-msg\">{{ uploadError }}</div>\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- \u2500\u2500 Continue Button \u2500\u2500 -->\r\n <div class=\"v1-footer\">\r\n <button class=\"v1-continue-btn\" (click)=\"next(2)\"\r\n [disabled]=\"((!points || !points?.length || points.length==0) && !fileData && !signaturePadData?.publicUrl) || !model.acceptTerms || !model.privacy\">\r\n <span *ngIf=\"!showLoader\">Continue</span>\r\n <span *ngIf=\"showLoader\" class=\"v1-spinner\"></span>\r\n <svg *ngIf=\"!showLoader\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n </div>\r\n <ng-container *ngIf=\"view == 2\">\r\n\r\n <!-- \u2500\u2500 Role-select header \u2500\u2500 -->\r\n <div class=\"v2-header\">\r\n <div class=\"v2-header-icon\">\r\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"8\" r=\"4\"/>\r\n <path d=\"M6 20v-2a4 4 0 014-4h4a4 4 0 014 4v2\"/>\r\n </svg>\r\n </div>\r\n <div>\r\n <h2 class=\"v2-title\">Choose your role</h2>\r\n <p class=\"v2-sub\">Choose the areas you'd like to be part of \u2014 programs, services, events, or\r\n collaborations. Connect your business to others and prospective clients.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Role cards grid \u2500\u2500 -->\r\n <div class=\"v2-grid\">\r\n <ng-container *ngFor=\"let userType of userViewRoles\">\r\n <div class=\"v2-role-card\" [class.v2-role-card--active]=\"userType.value === selectedRoleValue\"\r\n (click)=\"selectedUserRole(userType); toggleTooltip($event, userType)\">\r\n <button type=\"button\" class=\"v2-role-info-btn\" *ngIf=\"userType.details\"\r\n (click)=\"openInfoPopup($event, userType)\" title=\"More info\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\r\n <line x1=\"12\" y1=\"11\" x2=\"12\" y2=\"16\"/>\r\n <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"/>\r\n </svg>\r\n </button>\r\n <div class=\"v2-role-img-wrap\">\r\n <img [src]=\"userType?.img\" alt=\"\">\r\n </div>\r\n <span class=\"v2-role-name\">{{userType.name}}</span>\r\n <span class=\"v2-role-subtitle\" *ngIf=\"userType.subtitle\">{{userType.subtitle}}</span>\r\n <div class=\"v2-role-tooltip\" *ngIf=\"userType.tooltip\">{{userType.tooltip}}</div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Role tooltip (mobile: centered overlay) \u2500\u2500 -->\r\n <div class=\"v2-tooltip-overlay\" *ngIf=\"activeTooltipRole?.tooltip\" (click)=\"closeTooltip()\">\r\n <div class=\"v2-tooltip-popup\" (click)=\"$event.stopPropagation()\">\r\n {{ activeTooltipRole.tooltip }}\r\n </div>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Role info popup \u2500\u2500 -->\r\n <div class=\"v2-info-overlay\" *ngIf=\"infoPopupRole\" (click)=\"closeInfoPopup()\">\r\n <div class=\"v2-info-popup\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"v2-info-popup-header\">\r\n <span class=\"v2-info-popup-title\">{{ infoPopupRole.name }}</span>\r\n <button type=\"button\" class=\"v2-info-popup-close\" (click)=\"closeInfoPopup()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M18 6L6 18M6 6l12 12\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n <div class=\"v2-info-popup-body\">{{ infoPopupRole.details }}</div>\r\n </div>\r\n </div>\r\n\r\n <!-- \u2500\u2500 Footer: Back + Continue \u2500\u2500 -->\r\n <div class=\"v2-footer\">\r\n <button class=\"v2-back-btn\" (click)=\"previous()\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M19 12H5M12 5l-7 7 7 7\"/>\r\n </svg>\r\n Back\r\n </button>\r\n <button class=\"v2-continue-btn\" (click)=\"next(3)\" [disabled]=\"!isUserSelected || isLoadingSubCategories\">\r\n <span *ngIf=\"isLoadingSubCategories\" class=\"v1-spinner\"></span>\r\n <ng-container *ngIf=\"!isLoadingSubCategories\">\r\n Continue\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </ng-container>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"view == 3\">\r\n\r\n <!-- Header -->\r\n <div class=\"ip-header\">\r\n <div class=\"ip-header-icon\">\r\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z\"/>\r\n <polyline points=\"9 22 9 12 15 12 15 22\"/>\r\n </svg>\r\n </div>\r\n <div>\r\n <h2 class=\"ip-title\">Business Information</h2>\r\n <p class=\"ip-sub\">Tell us about your company so we can connect you with the right work.</p>\r\n </div>\r\n </div>\r\n\r\n <form [formGroup]=\"companyForm\">\r\n\r\n <!-- Company Details -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Company Details</p>\r\n <div class=\"ip-grid-2\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"companyName\">Company Name <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': (f.companyName.errors && validatePage == 3) || providerError}\"\r\n type=\"text\" class=\"ip-input\" id=\"companyName\" placeholder=\"Company Name\"\r\n formControlName=\"companyName\">\r\n <span *ngIf=\"f.companyName.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.companyName.errors.required\">Company Name is required</span>\r\n <span *ngIf=\"f.companyName.errors.minlength\">Minimum 2 characters</span>\r\n <span *ngIf=\"f.companyName.errors.maxLength\">Maximum 100 characters</span>\r\n </span>\r\n <span *ngIf=\"providerError\" class=\"ip-error\">{{ providerError }}</span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"inputPhone\">Phone Number <span class=\"ip-required\">*</span></label>\r\n <input class=\"ip-input\" type=\"text\" name=\"inputPhone\" placeholder=\"Company Phone Number\"\r\n id=\"inputPhone\" autocomplete=\"off\" formControlName=\"phoneNumber\" [maxLength]=\"14\"\r\n (input)=\"formatPhone($event,companyForm)\"\r\n [ngClass]=\"{'ip-input--invalid': (f.phoneNumber.errors && validatePage == 3) || providerError}\">\r\n <span *ngIf=\"f.phoneNumber.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.phoneNumber.errors.required\">Phone Number is required</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Address -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Address</p>\r\n <div class=\"ip-grid-2\" style=\"margin-bottom: 12px;\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"businessAddress\">Address Line 1 <span class=\"ip-required\">*</span></label>\r\n <im-address-verify-field formControlName=\"address1\" inputId=\"businessAddress\" [options]=\"options\"\r\n inputClass=\"\" [inputStyle]=\"addressInputStyle\" placeholder=\"Business Address 1\"\r\n [invalid]=\"f.address1.errors && validatePage == 3\"\r\n [initialLat]=\"f.latitude.value\" [initialLng]=\"f.longitude.value\"\r\n (addressResolved)=\"onCompanyAddressResolved($event)\"\r\n (manualEdit)=\"onCompanyAddressManualEdit()\"></im-address-verify-field>\r\n <span *ngIf=\"f.address1.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.address1.errors.required\">Business Address 1 is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"businessAddress2\">Address Line 2</label>\r\n <input type=\"text\" class=\"ip-input\" id=\"businessAddress2\" placeholder=\"Business Address 2\">\r\n </div>\r\n </div>\r\n <div class=\"ip-grid-4\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"City\">City <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': f.city.errors && validatePage == 3}\"\r\n type=\"text\" class=\"ip-input\" id=\"City\" placeholder=\"City\" formControlName=\"city\">\r\n <span *ngIf=\"f.city.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.city.errors.required\">City is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"State\">State <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': f.state.errors && validatePage == 3}\"\r\n type=\"text\" class=\"ip-input\" id=\"State\" placeholder=\"State\" formControlName=\"state\">\r\n <span *ngIf=\"f.state.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.state.errors.required\">State is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"Zipcode\">Zipcode <span class=\"ip-required\">*</span></label>\r\n <input [textMask]=\"{ mask: zipcodeMask }\"\r\n [ngClass]=\"{'ip-input--invalid': f.zipcode.errors && validatePage == 3}\"\r\n type=\"text\" class=\"ip-input\" id=\"Zipcode\" placeholder=\"Zipcode\" formControlName=\"zipcode\">\r\n <span *ngIf=\"f.zipcode.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.zipcode.errors.required\">Zipcode is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"Country\">Country <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': f.country.errors && validatePage == 3}\"\r\n type=\"text\" class=\"ip-input\" id=\"Country\" placeholder=\"Country\" formControlName=\"country\">\r\n <span *ngIf=\"f.country.errors && validatePage == 3\" class=\"ip-error\">\r\n <span *ngIf=\"f.country.errors.required\">Country is required</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </form>\r\n\r\n <!-- Company Logo (intentionally outside formGroup) -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Company Logo</p>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\">Company Logo <span class=\"ip-required\">*</span></label>\r\n <div class=\"ip-upload-wrap\">\r\n <input #uploadLogoInput type=\"file\" accept=\".png,.jpg,.jpeg\" (change)=\"uploadLogo($event)\"\r\n class=\"upload-initial-input rounded-circle opacity-0 position-absolute\" />\r\n <input (click)=\"uploadImage2.click()\" [(ngModel)]=\"logoName\" readonly type=\"text\"\r\n class=\"ip-input\" placeholder=\"Click to upload company logo\">\r\n <img #uploadImage2 class=\"ip-upload-icon\" (click)=\"uploadLogoInput.click()\"\r\n src=\"assets/images/icons/upload.svg\" alt=\"Upload\">\r\n </div>\r\n <small class=\"ip-upload-hint text-muted d-block\">Allowed formats: PNG, JPG, JPEG</small>\r\n <span *ngIf=\"isLogoRequired\" class=\"ip-error\">Please upload a company logo</span>\r\n <span *ngIf=\"isneeded\" class=\"ip-error\">Company Logo is required</span>\r\n </div>\r\n </div>\r\n\r\n <!-- Contractor Category -->\r\n <div *ngIf=\"selectedRole?.name == 'Contractor'\" class=\"ip-section\">\r\n <p class=\"ip-section-label\">Contractor Category</p>\r\n\r\n <!-- Category selector \u2014 ng-select logic intact, restyled as pill tag-input -->\r\n <div class=\"cc-select-wrap\">\r\n <ng-select [items]=\"contractorSubCategories\" bindLabel=\"name\" [multiple]=\"true\" [closeOnSelect]=\"false\"\r\n (ngModelChange)=\"changeContractor($event)\" [(ngModel)]=\"selectedContractorCategories\"\r\n >\r\n </ng-select>\r\n </div>\r\n\r\n <!-- Sub-items as pill chips per selected category -->\r\n <ng-container *ngFor=\"let item of selectedContractorCategories; let i=index\">\r\n <div class=\"cc-group\">\r\n\r\n <!-- \"Select all\" toggle pill for this category -->\r\n <label class=\"cc-select-all-pill\" [class.cc-select-all-pill--on]=\"item.selectAll\">\r\n <input type=\"checkbox\" [(ngModel)]=\"item.selectAll\" [name]=\"item?.id\" [id]=\"item?.id\"\r\n (change)=\"selectAll($event,item?.items)\" class=\"cc-hidden-check\">\r\n <svg *ngIf=\"item.selectAll\" width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n {{ item?.name }} \u2014 Select all\r\n </label>\r\n\r\n <!-- Individual sub-item pills -->\r\n <div class=\"cc-sub-pills\">\r\n <label *ngFor=\"let subItem of item?.items\" class=\"cc-sub-pill\"\r\n [class.cc-sub-pill--on]=\"subItem.selected\">\r\n <input type=\"checkbox\" [(ngModel)]=\"subItem.selected\" [name]=\"subItem?.id\" [id]=\"subItem?.id\"\r\n (change)=\"unCheckedEvent($event,item)\" class=\"cc-hidden-check\">\r\n <svg *ngIf=\"subItem.selected\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n {{ subItem?.name }}\r\n </label>\r\n </div>\r\n\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"ip-footer\">\r\n <button class=\"ip-back-btn\" (click)=\"previous()\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M19 12H5M12 5l-7 7 7 7\"/>\r\n </svg>\r\n Back\r\n </button>\r\n <button class=\"ip-next-btn\" (click)=\"next(4)\">\r\n Continue\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"view == 4\">\r\n\r\n <!-- Header -->\r\n <div class=\"ip-header\">\r\n <div class=\"ip-header-icon\">\r\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"8\" r=\"4\"/>\r\n <path d=\"M6 20v-2a4 4 0 014-4h4a4 4 0 014 4v2\"/>\r\n </svg>\r\n </div>\r\n <div>\r\n <h2 class=\"ip-title\">Your Profile</h2>\r\n <p class=\"ip-sub\">We need a few basics and a headshot to complete your profile.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Copy from provider toggle -->\r\n <div *ngIf=\"isBusiness\" class=\"ip-copy-row\">\r\n <input [(ngModel)]=\"isCopy\" type=\"checkbox\" name=\"isCopy\" id=\"isCopy\"\r\n class=\"ip-copy-check\" (change)=\"changeAddressUser()\">\r\n <label for=\"isCopy\" class=\"ip-copy-label\">Copy from Provider Information</label>\r\n </div>\r\n\r\n <form [formGroup]=\"userForm\">\r\n\r\n <!-- Personal Details -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Personal Details</p>\r\n <div class=\"ip-grid-3\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"firstName\">First Name <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.firstName.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" placeholder=\"First Name\" formControlName=\"firstName\" id=\"firstName\">\r\n <span *ngIf=\"u.firstName.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.firstName.errors.required\">First Name is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"lastName\">Last Name <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.lastName.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" placeholder=\"Last Name\" formControlName=\"lastName\" id=\"lastName\">\r\n <span *ngIf=\"u.lastName.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.lastName.errors.required\">Last Name is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"email\">Email <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.email.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" placeholder=\"Email\" formControlName=\"email\" id=\"email\">\r\n <span *ngIf=\"u.email.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.email.errors.required\">Email is required</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Home Address -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Home Address</p>\r\n <div class=\"ip-field\" style=\"margin-bottom: 12px;\">\r\n <label class=\"ip-label\" for=\"address1\">Address Line 1 <span class=\"ip-required\">*</span></label>\r\n <im-address-verify-field formControlName=\"address1\" inputId=\"address1\" [options]=\"options\"\r\n inputClass=\"\" [inputStyle]=\"addressInputStyle\" placeholder=\"Home Address 1\"\r\n [invalid]=\"u.address1.errors && validatePage == 4\"\r\n [initialLat]=\"u.latitude.value\" [initialLng]=\"u.longitude.value\"\r\n (addressResolved)=\"onUserAddressResolved($event)\"\r\n (manualEdit)=\"onUserAddressManualEdit()\"></im-address-verify-field>\r\n <span *ngIf=\"u.address1.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.address1.errors.required\">Home Address 1 is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-grid-3\">\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"homeAddress2\">Address Line 2</label>\r\n <input type=\"text\" class=\"ip-input\" id=\"homeAddress2\" formControlName=\"address2\"\r\n placeholder=\"Home Address 2\">\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"City\">City <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.city.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" id=\"City\" placeholder=\"City\" formControlName=\"city\">\r\n <span *ngIf=\"u.city.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.city.errors.required\">City is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"State\">State <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.state.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" id=\"State\" placeholder=\"State\" formControlName=\"state\">\r\n <span *ngIf=\"u.state.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.state.errors.required\">State is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"Zipcode\">Zipcode <span class=\"ip-required\">*</span></label>\r\n <input [textMask]=\"{ mask: zipcodeMask }\"\r\n [ngClass]=\"{'ip-input--invalid': u.zipcode.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" id=\"Zipcode\" placeholder=\"Zipcode\" formControlName=\"zipcode\">\r\n <span *ngIf=\"u.zipcode.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.zipcode.errors.required\">Zipcode is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"Country\">Country <span class=\"ip-required\">*</span></label>\r\n <input [ngClass]=\"{'ip-input--invalid': u.country.errors && validatePage == 4}\"\r\n type=\"text\" class=\"ip-input\" id=\"Country\" placeholder=\"Country\" formControlName=\"country\">\r\n <span *ngIf=\"u.country.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.country.errors.required\">Country is required</span>\r\n </span>\r\n </div>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\" for=\"inputPhone\">Phone Number <span class=\"ip-required\">*</span></label>\r\n <input class=\"ip-input\" type=\"text\" (input)=\"formatPhone($event,userForm)\"\r\n name=\"inputPhone\" placeholder=\"Phone Number\" id=\"inputPhone\" autocomplete=\"off\"\r\n formControlName=\"phoneNumber\" [maxLength]=\"14\"\r\n [ngClass]=\"{'ip-input--invalid': u.phoneNumber.errors && validatePage == 4}\">\r\n <span *ngIf=\"u.phoneNumber.errors && validatePage == 4\" class=\"ip-error\">\r\n <span *ngIf=\"u.phoneNumber.errors.required\">Phone Number is required</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </form>\r\n\r\n <!-- Profile Picture (intentionally outside formGroup) -->\r\n <div class=\"ip-section\">\r\n <p class=\"ip-section-label\">Profile Picture</p>\r\n <div class=\"ip-field\">\r\n <label class=\"ip-label\">Profile Picture <span class=\"ip-required\">*</span></label>\r\n <div class=\"ip-upload-wrap\">\r\n <input #uploadFile type=\"file\" accept=\".png,.jpg,.jpeg\" (change)=\"uploadUserImage($event)\"\r\n class=\"upload-initial-input rounded-circle opacity-0 position-absolute\" />\r\n <input (click)=\"uploadImage1.click()\" [(ngModel)]=\"fileName\" readonly type=\"text\"\r\n class=\"ip-input\" id=\"upload\" accept=\".png,.jpg,.jpeg\" placeholder=\"Click to upload profile picture\">\r\n <img #uploadImage1 class=\"ip-upload-icon\" (click)=\"uploadFile.click()\"\r\n src=\"assets/images/icons/upload.svg\" alt=\"Upload\">\r\n </div>\r\n <small class=\"ip-upload-hint text-muted d-block\">Allowed formats: PNG, JPG, JPEG</small>\r\n <span *ngIf=\"isImageRequired\" class=\"ip-error\">Please upload a profile image</span>\r\n <span *ngIf=\"userError\" class=\"ip-error\">{{ userError }}</span>\r\n </div>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"ip-footer\">\r\n <button class=\"ip-back-btn\" (click)=\"previous()\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M19 12H5M12 5l-7 7 7 7\"/>\r\n </svg>\r\n Back\r\n </button>\r\n <button class=\"ip-next-btn\" (click)=\"next(5)\" [disabled]=\"showLoader\">\r\n <span *ngIf=\"!showLoader\">Continue</span>\r\n <span *ngIf=\"showLoader\" class=\"v1-spinner\"></span>\r\n <svg *ngIf=\"!showLoader\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"view == 5\">\r\n <div class=\"v5-wrap\">\r\n\r\n <!-- Success icon -->\r\n <div class=\"v5-icon\">\r\n <svg width=\"36\" height=\"36\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M22 11.08V12a10 10 0 11-5.93-9.14\"/>\r\n <polyline points=\"22 4 12 14.01 9 11.01\"/>\r\n </svg>\r\n </div>\r\n\r\n <h2 class=\"v5-title\">You're all set!</h2>\r\n <p class=\"v5-sub\">Account created successfully. Next step: complete your profile.</p>\r\n\r\n <!-- Info cards -->\r\n <div class=\"v5-cards\">\r\n <div class=\"v5-card\">\r\n <div class=\"v5-card-icon\">\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\r\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/>\r\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>\r\n </svg>\r\n </div>\r\n <p class=\"v5-card-text\">Profile completion is mandatory to participate in rosters, programs, requests, and platform workflows. Incomplete profiles will have limited access.</p>\r\n </div>\r\n <div class=\"v5-card\">\r\n <div class=\"v5-card-icon v5-card-icon--green\">\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><path d=\"M3 9h18M9 21V9\"/>\r\n </svg>\r\n </div>\r\n <p class=\"v5-card-text\">You may access your dashboard at any time, but full functionality is available only after profile completion.</p>\r\n </div>\r\n </div>\r\n\r\n <button (click)=\"dashboard()\" class=\"v5-cta\">\r\n Go to Dashboard\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M5 12h14M12 5l7 7-7 7\"/>\r\n </svg>\r\n </button>\r\n\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"view == 10\">\r\n <app-credentialing (back)=\"onCredentialingBack()\" [data]=\"credentialingData\" [signatureFileId]=\"signatureFileId\"\r\n [signatureUrl]=\"signatureUrl\"></app-credentialing>\r\n </ng-container>\r\n </div>\r\n</ng-container>\r\n</div>\r\n\r\n<ng-template #termsAndConditionsModel>\r\n <div class=\"modal-dialog modal-dialog-centered tc-modal-dialog\">\r\n <div class=\"modal-content tc-modal\">\r\n\r\n <!-- HEADER -->\r\n <div class=\"tc-modal-header\">\r\n \r\n <h4 class=\"tc-modal-title\">{{ termsAndConditionTitle }}</h4>\r\n <span class=\"tc-modal-meta\" *ngIf=\"legalMeta\">Last Modified: {{ legalMeta.createdDate | date:'MMM d, y, h:mm:ss a' }}, {{ legalMeta.versionName }}</span>\r\n </div>\r\n\r\n\r\n <div class=\"tc-scroll-wrapper\">\r\n <div class=\"tc-modal-body\"\r\n (scroll)=\"onTermsScroll($event)\">\r\n <ng-container *ngIf=\"termsAndConditionTitle == 'Terms and Conditions'\">\r\n <app-terms-conditions [PrivacyAndTerms]=\"privacyAndTerms\" [title]=\"title\" [branding]=\"branding\"\r\n (metaLoaded)=\"onLegalMetaLoaded($event)\">\r\n </app-terms-conditions>\r\n </ng-container>\r\n <ng-container *ngIf=\"termsAndConditionTitle != 'Terms and Conditions'\">\r\n <app-privacy-policy [PrivacyAndTerms]=\"privacyAndTerms\" [title]=\"title\" [branding]=\"branding\"\r\n (metaLoaded)=\"onLegalMetaLoaded($event)\">\r\n </app-privacy-policy>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Floating scroll-to-bottom button -->\r\n <button class=\"tc-scroll-fab\" *ngIf=\"!isAgreeEnabled && legalMeta\" (click)=\"scrollToBottomClick($event)\"\r\n title=\"Scroll to bottom\">\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 5v14M5 15l7 7 7-7\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <!-- FOOTER -->\r\n <div class=\"tc-modal-footer\">\r\n <button type=\"button\" class=\"tc-btn tc-btn-decline\"\r\n (click)=\"decline(termsAndConditionTitle); modelRef.hide();\">\r\n Decline\r\n </button>\r\n <button type=\"button\" class=\"tc-btn tc-btn-agree\"\r\n [disabled]=\"!isAgreeEnabled\"\r\n (click)=\"agree(termsAndConditionTitle); modelRef.hide();\">\r\n I Agree\r\n </button>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n</ng-template>", styles: ["@charset \"UTF-8\";.brand-name{font-weight:700;font-size:calc(100% + 4px)}.spinner{width:38px;height:38px;border:dotted white;border-top:2px solid #f6f6f6;border-radius:62%;animation:spin 1.7s linear infinite;margin:-9px 0 0 -28px}@keyframes spin{to{transform:rotate(360deg)}}::ng-deep .backdrop{background-color:transparent!important}.filter-black{filter:brightness(.4)!important}.footer-view{margin-top:3rem;margin-left:0;margin-right:0}.footer-signature{margin-top:9rem}.slider-view{width:11rem;margin-left:1px}.container{margin-top:40px}.container .card{border-radius:5px}.container .header{padding:33px 10px 0}.container .header .logo{width:15%;height:80%}.container .form-control{padding:.75rem 1rem;border-color:#a1a1a1}.container .form-control:focus{color:#000;box-shadow:none;border-color:#a1a1a1!important}.container .form-control::placeholder{font-weight:500;font-size:12px;color:#a1a1a1}.container .link{color:#4077ad}.container .link-signup{font-weight:bolder}.container .form-check-label{margin-bottom:0;padding-top:9px}.container .content-view{margin-top:10%}.container .content-description{margin-top:25%}.container .tag-content{color:#fff9e8;margin-left:9%}.container .tag-content p{color:#fff9e8}.container .form-check-input:checked{background-color:#000;border-color:#000}.container .img-tick{margin:-31px 12px 0 -35px}.container .form-check-input[type=checkbox]{border-radius:2px;border:2px solid #000000}.container .form-check-input:focus{box-shadow:none}.container input[type=checkbox]{accent-color:#000000}.term-list{padding:48px 60px 6px 0;margin-left:30px;color:\"#1f1f1fdb\"}.add-tab{padding:75px 75px 6px 1px;margin-left:50px;color:\"#1f1f1fdb\"}.add-tab-view{padding:75px 75px 6px 1px;margin-left:80px;color:\"#1f1f1fdb\"}.inspect-add{margin-top:3rem}.add-btn{font-size:16px;border-radius:5px;transition:.2s;padding:.25rem .5rem;background:#fff;border:1px solid rgba(148,147,147,.1882352941);color:#444;line-height:48px;box-shadow:0 1px 9px #98a2b3;width:9rem}.add-btn:hover{border:1px solid rgba(148,147,147,.1882352941);box-shadow:none}.agree{padding:0 0 8px 47px}.agree .form-check-input[type=checkbox]{border-radius:2px;border:2px solid #98A2B3;width:14px;height:14px;margin:5px 9px 0 -35px}.agree .form-check-input:focus{box-shadow:none}.agree .form-check-input:checked{background-color:#000;border-color:#000}.agree .invalid-feedback{font-size:10px!important;margin:0 0 0 21px}.checkmark{vertical-align:text-bottom;color:#98a2b3;font-weight:500;font-size:12px}.term-signature{padding-left:16rem;padding-right:65px;position:absolute;margin:150px 0 0 50%}.participate-tab{height:135px;width:142px}.card-design{height:147px;width:147px;padding-left:10px;margin-left:42px;background:#fff0;border:2px solid #98A2B3;box-shadow:0 0 4px #98a2b3;border-radius:27px;margin-bottom:42px}.upload{height:39px;margin-top:-4px;width:126px;font-size:12px}.participate-tab{margin-top:-25px}.slider{width:14rem;margin-left:69px}.btn-clear{background:#d3dae6;color:#98a2b3;font-size:12px;border-radius:5px;transition:.2s;padding:6px;border:none;height:auto;width:46%;line-height:28px}.btn-close{background:#f1f4fa;color:#98a2b3;font-size:17px;border-radius:5px;transition:.2s;padding:6px;border:none;height:auto;font-weight:500;width:116px;color:#737a87;line-height:28px}.view-logo{padding-top:1%;padding-bottom:4%;text-align:center}.back-btn{border-radius:45px;height:41px}.next{background:#4077ad;border-radius:30px;height:60px;width:60px;border:white}.profile-field{margin-top:-10px}.profile-field input{line-height:30px;margin:-10px 3px 3px}.load-page{padding:21px 49px 13px 34px}.sign-img{width:291px;height:95px;border-radius:8px;border:1px solid rgba(179,178,178,.33);margin-top:19px}.upload-image{height:16px;width:16px;position:absolute;margin-left:66rem;margin-top:-39px}.para-comma{font-weight:500}.go-btn{border-radius:45px;height:50px;padding:0 20px;background:#4077ad;border:1px solid #4077ad;color:#fff;line-height:28px;font-size:14px;font-weight:500}.text-label{color:#747b83;font-weight:500}.form{padding:20px;border-radius:5px}.form-control:focus{color:#000;box-shadow:none;border-color:#848484!important}.form-control::placeholder{font-weight:500;font-size:12px;color:#bec1be;padding-left:10px}.btn-primary:active{background-color:#50575e}@media screen and (min-width: 500px) and (max-width: 769px){.content-view{background:#0c1620;width:44rem;margin:31px 0 0!important;padding:28px 32px 17px 71px!important;border-radius:29px}.upload-image{margin-left:25rem!important}}@media screen and (min-width: 768px) and (max-width: 1024px){.back-btn{height:31px;width:82px;position:absolute;margin-left:-53px}.back-tab{position:absolute;margin-left:-87px;height:37px}.go-btn{width:175px;height:44px}.term-signature{padding-left:10px}.upload-image{margin-left:40rem}}@media screen and (min-width: 374px) and (max-width: 426px){.head-logo{width:216px;padding-bottom:16px}.slider{visibility:hidden}.back-btn{height:31px;width:82px;position:absolute;margin-left:73px;margin-top:23px}.go-btn{width:175px;height:44px}.upload-image{margin-left:16rem}.term-signature{margin:84% 0 7px 4%}}@media screen and (min-width: 320px) and (max-width: 426px){.footer-signature{margin-top:20rem}.login .head-logo{padding:16px 2px 0;width:38%!important;height:40%!important}.container{margin-top:5px!important}.card{padding:2px!important}.tag-content{margin:3% 0 0!important;background-color:#121b24;border-radius:13px}.img-tick{margin:3px!important}.slider{visibility:hidden}.load-page{padding:0}.head-logo{width:216px;padding-bottom:16px}.back-btn{height:26px;width:71px;position:absolute;margin-left:-17rem!important;font-size:10px;margin-top:23px}.go-btn{width:142px;height:36px;margin-right:-28px;font-size:10px}.add-tab,.add-tab-view{padding:30px 33px 2px 3px;margin-left:15px}.add-btn{width:6rem}.slider-tab{visibility:hidden}.back-tab{margin-left:-14rem;margin-top:1px;font-size:14px;height:39px}.participate-tab{height:96px;width:87px}.card-design{height:124px;width:125px;padding-left:17px;margin-left:30px}.term-signature{padding:22px 22px 13px 27px}.term-list{padding:43px 10px 10px 3px;margin-left:0;text-align:-webkit-center}}@media screen and (min-width: 320px) and (max-width: 376px){.agree{padding:0 0 8px 25px}.participate-tab{height:96px;width:87px}.card-design{height:109px;width:97px;padding-left:4px;margin-left:10px}.card-design h6{font-size:10px;padding-left:14px;font-weight:600}.sign-img{width:270px}.term-list{padding:20px 20px 6px 4px;margin-left:13px}}@media screen and (min-width: 320px) and (max-width: 350px){.upload-image{height:13px;width:11px;margin-left:10rem;margin-top:-35px}.btn-clear{width:92px}.term-signature{margin:84% 0 7px 4%}}.disabled-btn{cursor:not-allowed!important;background:#4077ad!important;color:#fff!important}.modal-dialog .modal-content{border-radius:12px;background:#fff!important;border:1px solid rgba(128,128,128,.3294117647)!important}.title-popup{font-size:18px;color:#0c1620}.tc-modal-dialog{max-width:min(780px,96vw)}.tc-modal{border-radius:10px!important;border:none!important;overflow:hidden;box-shadow:0 32px 72px #00000038,0 6px 20px #0000001a!important;height:min(720px,90vh);display:flex;flex-direction:column}.tc-modal-header{display:flex;align-items:center;flex-wrap:wrap;gap:6px 12px;padding:10px 28px 14px;background:#4077ad;border-bottom:none;flex-shrink:0}.tc-modal-header .tc-header-icon{width:40px;height:40px;border-radius:11px;display:flex;align-items:center;justify-content:center;color:#fff;flex-shrink:0}.tc-modal-header .tc-modal-title{font-family:Inter,system-ui,sans-serif;font-size:18px;font-weight:700;color:#fff;letter-spacing:-.01em;padding:10px;margin:0;flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tc-modal-header .tc-modal-meta{font-weight:600;font-size:12px;color:#fff;flex-shrink:0;white-space:nowrap}@media screen and (max-width: 767px){.tc-modal-header .tc-modal-header{flex-flow:column;align-items:center;text-align:center}.tc-modal-header .tc-modal-title{flex:1 1 100%;white-space:normal}.tc-modal-header .tc-modal-meta{flex:1 1 100%;opacity:.85}}.tc-scroll-hint{display:flex;align-items:center;gap:7px;padding:9px 28px;background:#f0f9ff;border-bottom:none;font-size:12px;color:#4077ad;font-family:Inter,system-ui,sans-serif;letter-spacing:.01em;flex-shrink:0}.tc-scroll-hint svg{flex-shrink:0}.tc-scroll-hint strong{font-weight:700}.tc-scroll-hint .tc-progress-pill{margin-left:auto;background:#4077ad;color:#fff;font-size:11px;font-weight:700;letter-spacing:.04em;padding:2px 9px;border-radius:99px;min-width:42px;text-align:center;transition:background .2s ease}.tc-progress-bar{height:3px;background:#e0f2fe;flex-shrink:0}.tc-progress-bar .tc-progress-fill{height:100%;background:linear-gradient(90deg,#4077ad,#38bdf8);border-radius:0 99px 99px 0;transition:width .12s ease}.tc-scroll-wrapper{position:relative;flex:1 1 auto;overflow:hidden;display:flex;flex-direction:column}.tc-modal-body{flex:1 1 auto;overflow-y:auto;padding:26px 32px;background:#fff;scrollbar-width:thin;scrollbar-color:#cbd5e1 transparent}.tc-modal-body::-webkit-scrollbar{width:5px}.tc-modal-body::-webkit-scrollbar-track{background:transparent}.tc-modal-body::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:99px}.tc-modal-body::-webkit-scrollbar-thumb:hover{background:#94a3b8}.tc-scroll-fab{position:absolute;bottom:20px;right:20px;width:46px;height:46px;border-radius:50%;background:linear-gradient(135deg,#4077ad 0% 100%);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:10;transition:transform .18s ease,box-shadow .18s ease}.tc-scroll-fab:hover{transform:translateY(-3px) scale(1.1);animation:none}@keyframes tc-fab-bounce{0%,to{transform:translateY(0);box-shadow:0 4px 18px #2563eb80}50%{transform:translateY(5px);box-shadow:0 2px 10px #2563eb59}}.tc-modal-footer{display:flex;justify-content:flex-end;align-items:center;gap:10px;padding:16px 24px;background:#f8fafc;border-top:1px solid #e2e8f0;flex-shrink:0}.tc-btn{font-family:Inter,system-ui,sans-serif;font-size:14px;font-weight:600;letter-spacing:.015em;padding:10px 26px;border-radius:5px;border:none;cursor:pointer;transition:background .18s ease,transform .15s ease}.tc-btn.tc-btn-decline{background:#b43026;color:#fff;border:1.5px solid #B43026}.tc-btn.tc-btn-decline:hover{background:#96271f;border-color:#96271f;color:#fff}.tc-btn.tc-btn-agree{background:linear-gradient(135deg,#4077ad 0% 100%);border:1.5px solid transparent;color:#fff}.tc-btn.tc-btn-agree:hover:not(:disabled){background:linear-gradient(135deg,#2d5f8a,#4077ad);transform:translateY(-1px)}.tc-btn.tc-btn-agree:disabled{background:#e2e8f0;color:#94a3b8;box-shadow:none;cursor:not-allowed}ul.term-list-data li{padding-bottom:5px;font-size:13px;font-weight:500;line-height:21px}ol,ul,dl{margin-top:0;margin-bottom:1rem}::ng-deep .modal-content{width:100%;border:none}.hidden-view{display:none}.header-container{position:relative;padding:20px}.view-logo{text-align:center}.logout-button{top:20px;right:20px;position:absolute}.logout-button button{background:none;border:none;font-size:16px;display:flex;align-items:center;cursor:pointer}.logout-button img{margin-right:5px;height:20px}.user-card{align-items:center;color:#4077ad;cursor:pointer}.user-cards-active{background:#4077ad;color:#fff}.save-btn.upload{border:1px solid #4077AD;background-color:#4077ad;color:#fff;border-radius:5px;background:#4077ad;padding:4px 10px;display:inline-flex;align-items:center;gap:6px}.save-btn.upload img{filter:brightness(0) invert(1)}.form-check.agree{display:flex;align-items:flex-start;gap:8px;margin-bottom:8px}.form-check.agree .form-check-input{margin-top:4px;flex-shrink:0}.form-check.agree .form-check-label{line-height:1.4;cursor:pointer;white-space:normal}.spinner-16{width:16px;height:16px}.h6-buttons{display:flex;align-items:center;gap:8px}.form-check.agree{display:flex;align-items:flex-start;margin-bottom:14px}.form-check-input{position:absolute;opacity:0;cursor:pointer}.form-check-label{position:relative;padding-left:28px;cursor:pointer;font-size:14px;line-height:20px;color:#212529;-webkit-user-select:none;user-select:none}.form-check-label:before{content:\"\";position:absolute;left:0;top:8px;width:18px;height:18px;border:2px solid #adb5bd;border-radius:4px;background:#fff;transition:all .2s ease}.form-check-label:after{content:\"\";position:absolute;left:5px;top:10px;width:6px;height:10px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg) scale(0);transition:transform .15s ease}.form-check-input:checked+.form-check-label:before{background-color:#4077ad;border-color:#4077ad}.form-check-input:checked+.form-check-label:after{transform:rotate(45deg) scale(1)}.form-check-label:hover:before{border-color:#4077ad}.form-check-input:focus+.form-check-label:before{box-shadow:0 0 0 3px #4077ad40}.form-check-input.is-invalid+.form-check-label:before{border-color:#dc3545}.form-check-input.is-invalid:checked+.form-check-label:before{background-color:#dc3545}.invalid-feedback{display:block;font-size:12px;margin-left:7px;margin-top:4px}::ng-deep .modal-dialog{max-width:750px}.user-cards-active{background-color:#4077ad;color:#fff;border:2px solid #4077AD}body.modal-open{overflow:hidden!important}.modal{z-index:1055!important}.modal-backdrop{z-index:1050!important}.modal-dialog{margin:auto;pointer-events:auto}.modal-content{position:relative;z-index:1060}.logout-container{display:flex;justify-content:flex-end}.logout-btn{display:inline-flex;align-items:center;gap:7px;padding:7px 16px;border-radius:5px;font-size:14px;font-weight:500;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;background:#f8fafc;border:1.5px solid #e2e8f0;cursor:pointer;transition:color .18s,background .18s,border-color .18s,box-shadow .18s}.logout-btn:hover{color:#dc2626;background:#fff5f5;border-color:#fca5a5}.logout-btn:active{transform:scale(.97)}@media screen and (max-width: 767px){.term-signature{padding-left:3rem;padding-right:0;position:unset;margin:0}.footer-signature{margin-top:0rem}.disabled-btn{position:absolute;bottom:13px;right:24px}.next{height:46px;width:46px;position:absolute;bottom:21px;right:35px}.mob{padding-bottom:4.5rem!important}.checkmark{width:85%}.terms-fixed-modal{width:unset}::ng-deep .privacy-policy-modal .logo-section{margin-bottom:0!important}.add-tab-view{padding:30px 25px 6px;margin-left:0}.user-card{width:96%}.footer .btn-mob{display:flex;align-items:center}.back-btn{position:absolute;bottom:21px;left:10px}.actions{margin:50px 34px 1px}}@media screen and (min-width: 768px) and (max-width: 1024px){.footer-signature{margin-top:3rem}}.v1-welcome{display:flex;align-items:flex-start;gap:16px;padding:28px 32px 20px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.v1-welcome-icon{flex-shrink:0;width:48px;height:48px;border-radius:50%;border:1px solid #cfd2d6;display:flex;align-items:center;justify-content:center;color:#90979d;margin-top:2px}.v1-welcome-title{font-size:18px;font-weight:700;color:#69707d;margin:0 0 6px;line-height:1.25;letter-spacing:-.02em}.v1-brand{color:#4077ad}.v1-welcome-sub{font-size:14px;color:#69707d;line-height:1.65;margin:0}.v1-body{display:grid;grid-template-columns:1fr 1fr;gap:20px;padding:0 32px 20px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v1-body{grid-template-columns:1fr;padding:0 16px 16px}}.v1-agreements{display:flex;flex-direction:column;gap:12px}.v1-agreement-card{display:flex;align-items:center;gap:14px;padding:16px 18px;border-radius:5px;border:1.5px solid #e2e8f0;background:#fff;transition:border-color .2s,box-shadow .2s;box-shadow:0 1px 3px #0000000a}.v1-agreement-card:hover{border-color:#c7d3e2;box-shadow:0 2px 8px #00000012}.v1-agreement-card.v1-card--agreed{border-color:#dde2e7}.v1-agreement-card.v1-card--invalid{border-color:#fecaca;background:#fff5f5}.v1-card-icon{flex-shrink:0;width:38px;height:38px;border-radius:5px;border:1px solid #e2e8f0;display:flex;align-items:center;justify-content:center;color:#4077ad}.v1-card--agreed .v1-card-icon{border-color:#dde2e7;color:#7e8994}.v1-card-body{flex:1 1 auto;min-width:0}.v1-card-title{font-size:14px;font-weight:600;color:#69707d;margin:0 0 2px;line-height:1.3}.v1-card-sub{font-size:12px;color:#6b7280;margin:0}.v1-agree-btn{flex-shrink:0;display:inline-flex;align-items:center;gap:5px;padding:7px 14px;border-radius:5px;font-size:12px;font-weight:600;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;border:1.5px solid #4077AD;color:#4077ad;background:transparent;cursor:pointer;white-space:nowrap;transition:background .18s,color .18s}.v1-agree-btn:hover{background:#4077ad;color:#fff}.v1-agree-btn.v1-agree-btn--done{background:#3e7f50;border-color:#3e7f50;color:#fff}.v1-agree-btn:disabled{opacity:.7;cursor:not-allowed}.v1-agree-btn:disabled:hover{background:transparent;color:#4077ad}.v1-agree-spinner{width:12px;height:12px;border:2px solid currentColor;border-top-color:transparent;border-radius:50%;flex-shrink:0;animation:v1-agree-spin .7s linear infinite}@keyframes v1-agree-spin{to{transform:rotate(360deg)}}.v1-signature{display:flex;flex-direction:column;gap:10px}.v1-sig-header{display:flex;align-items:center;justify-content:space-between}.v1-sig-label{display:inline-flex;align-items:center;gap:7px;font-size:14px;font-weight:600;color:#69707d;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.v1-clear-btn{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:500;color:#6b7280;background:transparent;border:1px solid #e2e8f0;border-radius:5px;padding:4px 10px;cursor:pointer;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;transition:color .18s,border-color .18s}.v1-clear-btn:hover{color:#dc2626;border-color:#fca5a5}.v1-sig-pad{position:relative;border-radius:5px;border:1.5px dashed #cbd5e1;overflow:hidden;min-height:120px}.v1-sig-pad canvas{display:block;cursor:crosshair;width:100%;height:120px}.v1-sig-hint{position:absolute;bottom:8px;left:50%;transform:translate(-50%);font-size:12px;color:#c0cad8;pointer-events:none;margin:0;white-space:nowrap;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.v1-error-msg{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:500;color:#dc2626;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.v1-footer{padding:8px 32px 20px;display:flex;justify-content:flex-end;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v1-footer{padding:8px 16px 20px}}.v1-continue-btn{display:inline-flex;align-items:center;gap:9px;padding:12px 28px;border-radius:5px;font-size:14px;font-weight:600;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:linear-gradient(135deg,#4077ad 0% 100%);border:none;cursor:pointer;transition:transform .15s;min-width:148px;justify-content:center}.v1-continue-btn:hover:not(:disabled){transform:translateY(-1px)}.v1-continue-btn:active:not(:disabled){transform:translateY(0)}.v1-continue-btn:disabled,.v1-continue-btn.disabled{background:#e2e8f0;color:#94a3b8;box-shadow:none;cursor:not-allowed}.v1-spinner{display:inline-block;width:16px;height:16px;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:v1-spin .65s linear infinite}@keyframes v1-spin{to{transform:rotate(360deg)}}@media (max-width: 767px){.v1-welcome{padding:20px 16px 14px;gap:12px}.v1-welcome-icon{width:40px;height:40px}.v1-welcome-title{font-size:16px}}.v2-header{display:flex;align-items:flex-start;gap:16px;padding:28px 32px 20px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v2-header{padding:20px 16px 14px;gap:12px}}.v2-header-icon{flex-shrink:0;width:48px;height:48px;border-radius:50%;border:1px solid #cecece;display:flex;align-items:center;justify-content:center;color:#abb3ba;margin-top:2px}.v2-title{font-size:18px;font-weight:700;color:#69707d;margin:0 0 6px;line-height:1.25;letter-spacing:-.02em}.v2-sub{font-size:14px;color:#69707d;line-height:1.65;margin:0}.v2-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:14px;padding:10px 32px 50px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v2-grid{grid-template-columns:repeat(auto-fill,minmax(110px,1fr));padding:0 16px 20px;gap:10px}}.v2-role-card{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:20px 12px 16px;border-radius:5px;border:1.5px solid #e2e8f0;background:#fff;cursor:pointer;transition:border-color .18s,box-shadow .18s,transform .15s;box-shadow:0 1px 3px #0000000a;text-align:center}.v2-role-card:hover{z-index:30;border-color:#93c5fd;box-shadow:0 4px 16px #4077ad1a;transform:translateY(-2px)}.v2-role-card.v2-role-card--active{border-color:#4077ad;background:#eff6ff;box-shadow:0 0 0 3px #4077ad1f,0 4px 16px #4077ad1f}.v2-role-img-wrap{width:64px;height:64px;border-radius:50%;background:#f8fafc;border:1px solid #e2e8f0;display:flex;align-items:center;justify-content:center;overflow:hidden;transition:background .18s,border-color .18s}.v2-role-img-wrap img{width:44px;height:44px;object-fit:contain;display:block}.v2-role-card--active .v2-role-img-wrap{background:#dbeafe;border-color:#93c5fd}.v2-role-name{font-size:14px;font-weight:600;color:#69707d;line-height:1.3;text-align:center}.v2-role-card--active .v2-role-name{color:#4077ad}.v2-role-subtitle{font-size:11px;font-weight:400;color:#6b7280;line-height:1.3;text-align:center;margin-top:2px}.v2-role-tooltip{position:absolute;top:calc(100% + 10px);left:50%;transform:translate(-50%) translateY(-4px);width:240px;max-width:80vw;background:#4077ad;color:#fff;font-size:12px;font-weight:400;line-height:1.45;text-align:left;padding:10px 12px;border-radius:6px;box-shadow:0 6px 18px #0000002e;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .15s ease,transform .15s ease;z-index:40}.v2-role-tooltip:after{content:\"\";position:absolute;bottom:100%;left:50%;transform:translate(-50%);border-width:6px;border-style:solid;border-color:transparent transparent #4077ad transparent}.v2-role-card:hover .v2-role-tooltip{opacity:1;visibility:visible;transform:translate(-50%) translateY(0)}@media (max-width: 767px){.v2-role-tooltip{display:none}}.v2-tooltip-overlay{display:none}@media (max-width: 767px){.v2-tooltip-overlay{position:fixed;inset:0;background:#0f172a73;display:flex;align-items:center;justify-content:center;z-index:1000;padding:24px}.v2-tooltip-popup{width:280px;max-width:85vw;background:#4077ad;color:#fff;font-size:13px;font-weight:400;line-height:1.5;text-align:left;padding:16px;border-radius:8px;box-shadow:0 12px 32px #00000040}}.v2-role-info-btn{position:absolute;top:8px;right:8px;width:20px;height:20px;border-radius:50%;background:#4077ad;color:#fff;border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;z-index:2;transition:background .15s ease,transform .15s ease}.v2-role-info-btn:hover{background:#345f87;transform:scale(1.08)}.v2-info-overlay{position:fixed;inset:0;background:#0f172a73;display:flex;align-items:center;justify-content:center;z-index:1000}.v2-info-popup{width:560px;max-width:90vw;max-height:80vh;display:flex;flex-direction:column;background:#fff;border-radius:8px;overflow:hidden;box-shadow:0 12px 32px #00000040}.v2-info-popup-header{display:flex;align-items:center;justify-content:space-between;background:#4077ad;padding:14px 16px}.v2-info-popup-title{color:#fff;font-size:15px;font-weight:600}.v2-info-popup-close{background:transparent;border:none;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:2px}.v2-info-popup-body{padding:16px;font-size:13px;line-height:1.6;color:#69707d;white-space:pre-line;overflow-y:auto}.v2-footer{display:flex;align-items:center;justify-content:flex-end;gap:12px;padding:8px 32px 24px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v2-footer{padding:8px 16px 20px}}.v2-back-btn{display:inline-flex;align-items:center;gap:7px;padding:10px 20px;border-radius:5px;font-size:14px;font-weight:500;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:#69707d;border:1.5px solid #69707D;cursor:pointer;transition:color .18s,border-color .18s,background .18s}.v2-back-btn:hover{color:#fff;background:#565c66;border-color:#565c66}.v2-continue-btn{display:inline-flex;align-items:center;gap:9px;padding:10px 24px;border-radius:5px;font-size:14px;font-weight:600;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:linear-gradient(135deg,#4077ad 0% 100%);border:none;cursor:pointer;box-shadow:0 4px 14px #4077ad4d;transition:transform .15s,box-shadow .15s}.v2-continue-btn:hover:not(:disabled){transform:translateY(-1px)}.v2-continue-btn:disabled{background:#e2e8f0;color:#94a3b8;box-shadow:none;cursor:not-allowed}.ip-header{display:flex;align-items:flex-start;gap:16px;padding:28px 32px 16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.ip-header{padding:20px 16px 12px;gap:12px}}.ip-header-icon{flex-shrink:0;width:48px;height:48px;border-radius:50%;border:1px solid #c7c7c7;display:flex;align-items:center;justify-content:center;color:#959191;margin-top:2px}.ip-title{font-size:18px;font-weight:700;color:#69707d;margin:0 0 6px;line-height:1.25;letter-spacing:-.02em;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.ip-sub{font-size:14px;color:#69707d;line-height:1.65;margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.ip-section{margin:0 24px 14px;background:#fff;border:1.5px solid #e2e8f0;border-radius:5px;padding:18px 20px 16px;box-shadow:0 1px 4px #0000000a}@media (max-width: 767px){.ip-section{margin:0 12px 10px;padding:14px}}.ip-section-label{font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:#6b7280;margin:0 0 12px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.ip-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:12px}@media (max-width: 767px){.ip-grid-2{grid-template-columns:1fr}}.ip-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px}@media (max-width: 1024px){.ip-grid-3{grid-template-columns:1fr 1fr}}@media (max-width: 599px){.ip-grid-3{grid-template-columns:1fr}}.ip-grid-4{display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:12px}@media (max-width: 1024px){.ip-grid-4{grid-template-columns:1fr 1fr}}@media (max-width: 599px){.ip-grid-4{grid-template-columns:1fr}}.ip-field{display:flex;flex-direction:column;gap:5px}.ip-label{font-size:12px;font-weight:600;color:#69707d;margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;line-height:1.3}.ip-required{color:#dc2626;margin-left:2px;font-weight:700}.ip-input{width:100%;height:44px;padding:0 14px;border:1.5px solid #e2e8f0;border-radius:5px;font-size:14px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;background:#fff;outline:none;transition:border-color .18s,box-shadow .18s;box-sizing:border-box}.ip-input::placeholder{color:#adb5bd;font-weight:400}.ip-input:focus{border-color:#4077ad;box-shadow:0 0 0 3px #4077ad1a}.ip-input.ip-input--invalid{border-color:#dc2626;background:#fff8f8}.ip-input.ip-input--invalid:focus{box-shadow:0 0 0 3px #dc26261a}.ip-input[readonly]{cursor:pointer;background:#f8fafc}.ip-error{display:flex;align-items:center;gap:4px;font-size:12px;font-weight:500;color:#dc2626;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.ip-upload-wrap{position:relative;display:flex;align-items:center}.ip-upload-icon{position:absolute;right:14px;width:16px;height:16px;cursor:pointer;opacity:.45;transition:opacity .18s}.ip-upload-icon:hover{opacity:.85}.ip-upload-hint{margin-top:6px;font-size:12px}.ip-copy-row{display:flex;align-items:center;gap:10px;margin:0 24px 12px;padding:11px 16px;background:#eff6ff;border:1.5px solid #bfdbfe;border-radius:10px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.ip-copy-row{margin:0 12px 10px}}.ip-copy-check{width:16px;height:16px;accent-color:#4077AD;cursor:pointer;flex-shrink:0}.ip-copy-label{font-size:14px;font-weight:500;color:#69707d;cursor:pointer;margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;-webkit-user-select:none;user-select:none}.ip-footer{display:flex;align-items:center;justify-content:flex-end;gap:12px;padding:8px 24px 28px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.ip-footer{padding:8px 16px 24px}}.ip-back-btn{display:inline-flex;align-items:center;gap:7px;padding:10px 20px;border-radius:5px;font-size:14px;font-weight:500;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:#69707d;border:1.5px solid #69707D;cursor:pointer;transition:color .18s,border-color .18s,background .18s}.ip-back-btn:hover{color:#fff;border-color:#565c66;background:#565c66}.ip-next-btn{display:inline-flex;align-items:center;gap:9px;padding:10px 26px;border-radius:5px;font-size:14px;font-weight:600;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#fff;background:linear-gradient(135deg,#4077ad 0% 100%);border:none;cursor:pointer;box-shadow:0 4px 14px #4077ad4d;transition:transform .15s,box-shadow .15s}.ip-next-btn:hover:not(:disabled){transform:translateY(-1px)}.ip-next-btn:active:not(:disabled){transform:translateY(0)}.ip-next-btn:disabled{background:#e2e8f0;color:#94a3b8;box-shadow:none;cursor:not-allowed}.v5-wrap{display:flex;flex-direction:column;align-items:center;text-align:center;padding:48px 32px 40px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}@media (max-width: 767px){.v5-wrap{padding:36px 20px 32px}}.v5-icon{width:72px;height:72px;border-radius:50%;background:linear-gradient(135deg,#dcfce7,#bbf7d0);border:1.5px solid #86efac;display:flex;align-items:center;justify-content:center;color:#16a34a;margin-bottom:20px;box-shadow:0 0 0 8px #22c55e14}.v5-title{font-size:18px;font-weight:800;color:#69707d;margin:0 0 10px;letter-spacing:-.025em;line-height:1.2}.v5-sub{font-size:14px;color:#69707d;margin:0 0 28px;line-height:1.6;max-width:480px}.v5-cards{display:flex;flex-direction:column;gap:12px;width:100%;max-width:520px;margin-bottom:32px;text-align:left}.v5-card{display:flex;align-items:flex-start;gap:14px;padding:16px 18px;border-radius:12px;border:1.5px solid #e2e8f0;background:#f8fafc;box-shadow:0 1px 3px #0000000a}.v5-card-icon{flex-shrink:0;width:36px;height:36px;border-radius:9px;background:#eff6ff;border:1px solid #bfdbfe;display:flex;align-items:center;justify-content:center;color:#4077ad}.v5-card-icon.v5-card-icon--green{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a}.v5-card-text{font-size:14px;color:#69707d;line-height:1.6;margin:0}.v5-cta{display:inline-flex;align-items:center;gap:10px;padding:13px 32px;border-radius:5px;font-size:14px;font-weight:600;font-family:inherit;color:#fff;background:linear-gradient(135deg,#4077ad 0% 100%);border:none;cursor:pointer;box-shadow:0 4px 16px #4077ad52;transition:transform .15s,box-shadow .15s}.v5-cta:hover{transform:translateY(-2px)}.v5-cta:active{transform:translateY(0)}.cc-select-wrap{margin-bottom:20px}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-select-container{border:1.5px solid #e2e8f0;border-radius:10px;min-height:48px;padding:5px 10px;background:#fff;box-shadow:none;cursor:text;transition:border-color .18s,box-shadow .18s}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-select-container:hover{border-color:#94a3b8}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple.ng-select-focused .ng-select-container{border-color:#4077ad;box-shadow:0 0 0 3px #4077ad1a}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-container{flex-wrap:wrap;gap:6px;padding:2px 0}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value{display:inline-flex;flex-direction:row;align-items:center;gap:5px;background:#eff6ff;border:1px solid #bfdbfe;border-radius:99px;padding:4px 8px 4px 13px;font-size:12px;font-weight:600;color:#4077ad;margin:0;line-height:1}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-label{order:1}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-icon{display:inline-flex;align-items:center;justify-content:center;order:2;width:16px;height:16px;border-radius:50%;font-size:12px;font-weight:700;line-height:1;padding:0;background:#4077ad26;color:#4077ad;cursor:pointer;flex-shrink:0;transition:background .15s,color .15s}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-icon:hover{background:#4077ad;color:#fff}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-value-icon.right{display:none}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-placeholder{font-size:14px;color:#adb5bd;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-select-container.ng-has-value .ng-placeholder{display:none}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-input>input{font-size:14px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-arrow-wrapper{padding-right:6px}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-arrow-wrapper .ng-arrow{border-color:#94a3b8 transparent transparent;border-width:5px 4px 0}.cc-select-wrap ::ng-deep .ng-select.ng-select-multiple .ng-clear-wrapper{color:#94a3b8}::ng-deep .ng-dropdown-panel{border:1.5px solid #e2e8f0;border-radius:12px;box-shadow:0 8px 28px #0000001a,0 2px 8px #0000000f;overflow:hidden;margin-top:5px;z-index:9999!important;background:#fff!important}::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items{padding:6px}::ng-deep .ng-dropdown-panel .ng-option{border-radius:8px;padding:10px 13px;font-size:14px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;transition:background .12s}::ng-deep .ng-dropdown-panel .ng-option.ng-option-selected{background:#eff6ff;color:#4077ad;font-weight:600}::ng-deep .ng-dropdown-panel .ng-option.ng-option-marked:not(.ng-option-selected){background:#f8fafc;color:#69707d}::ng-deep .ng-dropdown-panel .ng-option.ng-option-selected.ng-option-marked{background:#dbeafe}.cc-group{margin-bottom:18px;padding-top:4px}.cc-group:last-child{margin-bottom:0}.cc-hidden-check{position:absolute;opacity:0;width:0;height:0;pointer-events:none}.cc-select-all-pill{display:inline-flex;align-items:center;gap:6px;padding:7px 16px;border-radius:99px;border:1.5px solid #e2e8f0;background:#f8fafc;font-size:12px;font-weight:700;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;cursor:pointer;-webkit-user-select:none;user-select:none;margin-bottom:10px;transition:background .18s,border-color .18s,color .18s}.cc-select-all-pill:hover:not(.cc-select-all-pill--on){background:#f1f5f9;border-color:#94a3b8}.cc-select-all-pill.cc-select-all-pill--on{background:#69707d;border-color:#69707d;color:#fff}.cc-sub-pills{display:flex;flex-wrap:wrap;gap:8px}.cc-sub-pill{display:inline-flex;align-items:center;gap:5px;padding:6px 14px;border-radius:99px;border:1.5px solid #e2e8f0;background:#fff;font-size:12px;font-weight:500;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;color:#69707d;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background .15s,border-color .15s,color .15s,box-shadow .15s}.cc-sub-pill:hover:not(.cc-sub-pill--on){background:#f8fafc;border-color:#94a3b8;color:#69707d}.cc-sub-pill.cc-sub-pill--on{background:#eff6ff;border-color:#93c5fd;color:#4077ad;font-weight:600;box-shadow:0 0 0 3px #4077ad12}html,body{overscroll-behavior:none;height:100%;overflow:hidden}\n"] }]
|
|
36416
37055
|
}], ctorParameters: () => [{ type: i2.Router }, { type: i2.ActivatedRoute }, { type: UserDetailService }, { type: i7.FormBuilder }, { type: FileService }, { type: ProvidersService }, { type: RolesService }, { type: i1$1.BsModalService }, { type: ProviderContractorSubCategoryService }, { type: ProviderContractorSubCategoryService }, { type: i9.AuthService }, { type: i1$4.TokenService }, { type: i1$4.RoleContextService }, { type: i1$4.AuthLogoutService }, { type: CredentialingStore }, { type: undefined, decorators: [{
|
|
36417
37056
|
type: Inject,
|
|
36418
37057
|
args: [LIBRARY_CONFIG]
|