|
|
<div class="professional-page">
|
|
|
|
|
|
<div class="loader-overlay" *ngIf="isLoading">
|
|
|
<div class="loader-container">
|
|
|
<img src="assets/Loader.gif" alt="Loading..." style="width: 90%; height: 90%; display: block; margin: 0 auto 25px; " />
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div class="text-input-popup-overlay" *ngIf="showTextInputPopup && isAdditionalRemarksField()" (click)="closeTextInputPopup()">
|
|
|
<div class="text-input-popup-container" (click)="$event.stopPropagation()">
|
|
|
<div class="text-input-popup-header">
|
|
|
<h3>{{ popupQuestion?.label }}</h3>
|
|
|
<button class="text-input-popup-close" (click)="closeTextInputPopup()">
|
|
|
<i class="fas fa-times"></i>
|
|
|
</button>
|
|
|
</div>
|
|
|
<div class="text-input-popup-body">
|
|
|
<textarea class="text-input-popup-field"
|
|
|
[(ngModel)]="popupTextValue"
|
|
|
[placeholder]="popupQuestion ? getPlaceholder(popupQuestion) : 'Enter your answer'"
|
|
|
(input)="onTextareaInput($event)"
|
|
|
rows="1"></textarea>
|
|
|
|
|
|
<div class="text-input-popup-actions">
|
|
|
<button class="btn btn-secondary" (click)="closeTextInputPopup()">
|
|
|
Cancel
|
|
|
</button>
|
|
|
<button class="btn btn-primary" (click)="saveTextInputPopup()">
|
|
|
Save
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="container">
|
|
|
|
|
|
<div class="header">
|
|
|
<h1>{{ selectedOption ? (toTitleCase(selectedOption) + ' Profile') : 'Personal Details' }}</h1>
|
|
|
|
|
|
<div class="progress-section">
|
|
|
<div class="progress-bar">
|
|
|
<div class="progress-bar-line" [style.width.%]="getProgressBarWidth()"></div>
|
|
|
|
|
|
<div *ngFor="let cat of categoriesMeta; let i = index"
|
|
|
class="step"
|
|
|
[class.active]="selectedCategory === cat.key"
|
|
|
[class.completed]="getCategoryAnsweredCount(cat.key) === getCategoryRequiredCount(cat.key) && getCategoryRequiredCount(cat.key) > 0"
|
|
|
(click)="selectCategory(cat.key)">
|
|
|
<span class="step-icon">
|
|
|
<i class="fas {{ getCategoryIcon(cat.key) }}"></i>
|
|
|
</span>
|
|
|
<span class="step-label">{{ getStepLabel(cat.title) }}</span>
|
|
|
</div>
|
|
|
<div class="step"
|
|
|
[class.active]="selectedCategory === 'review'"
|
|
|
[class.completed]="allFieldsAnswered"
|
|
|
(click)="selectCategory('review')">
|
|
|
<span class="step-icon">
|
|
|
<i class="fas fa-check"></i>
|
|
|
</span>
|
|
|
<span class="step-label">Review</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div class="content-area">
|
|
|
|
|
|
<div class="category-header">
|
|
|
<div class="category-info">
|
|
|
<i class="fas {{ getCurrentCategoryIcon() }} category-header-icon"></i>
|
|
|
<div class="category-details">
|
|
|
<h3>{{ getCurrentCategoryTitle() }}</h3>
|
|
|
<p>{{ getCurrentCategoryDescription() }}</p>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div *ngIf="selectedCategory !== 'review'" class="category-progress-indicator">
|
|
|
<div class="progress-bar-mini">
|
|
|
<div class="progress-fill" [style.width.%]="getCategoryPercent(selectedCategory)"></div>
|
|
|
</div>
|
|
|
<span class="progress-text">{{ getCategoryPercent(selectedCategory) }}% Complete</span>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div *ngIf="selectedCategory === 'review'" class="completion-status" [class.complete]="allFieldsAnswered">
|
|
|
<span class="status-icon">{{ allFieldsAnswered ? '✓' : '!' }}</span>
|
|
|
<span class="status-text">
|
|
|
{{ allFieldsAnswered ? 'All fields completed' : (unansweredCount + ' field(s) remaining') }}
|
|
|
</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div class="form-container" [class.review-mode]="selectedCategory === 'review'">
|
|
|
|
|
|
<div class="success-modal-overlay" *ngIf="showSubmissionPopup && isSubmissionSuccess">
|
|
|
<div class="success-modal-container">
|
|
|
<div class="success-modal-header">
|
|
|
<button class="success-modal-close" (click)="showSubmissionPopup = false">
|
|
|
<i class="fas fa-times"></i>
|
|
|
</button>
|
|
|
<div class="success-modal-icon">
|
|
|
<i class="fas fa-check-circle"></i>
|
|
|
</div>
|
|
|
<h2 class="success-modal-title">
|
|
|
{{ isEditingExistingProfile ? 'Profile Updated!' : 'Profile Submitted!' }}
|
|
|
</h2>
|
|
|
</div>
|
|
|
|
|
|
<div class="success-modal-body">
|
|
|
<p class="success-modal-message">
|
|
|
Your {{ selectedOption }} profile has been
|
|
|
{{ isEditingExistingProfile ? 'updated' : 'submitted' }} successfully!
|
|
|
</p>
|
|
|
|
|
|
<div class="success-modal-stats">
|
|
|
<p>
|
|
|
<i class="fas fa-check"></i>
|
|
|
All required fields have been completed.
|
|
|
</p>
|
|
|
</div>
|
|
|
|
|
|
<div class="success-modal-actions">
|
|
|
<button class="success-modal-btn success-modal-btn-secondary" (click)="redirectToHome()">
|
|
|
<i class="fas fa-home"></i>
|
|
|
Go to Home
|
|
|
</button>
|
|
|
<button class="success-modal-btn success-modal-btn-primary" (click)="redirectToPreferences()">
|
|
|
<i class="fas fa-sliders-h"></i>
|
|
|
Set Preferences
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<section *ngFor="let cat of categoriesMeta"
|
|
|
class="tab"
|
|
|
[class.active]="selectedCategory === cat.key"
|
|
|
[class.blur-background]="showSubmissionPopup && isSubmissionSuccess || showTextInputPopup">
|
|
|
|
|
|
<div class="tab-content">
|
|
|
<div class="form-grid">
|
|
|
<div *ngFor="let question of getCategoryQuestions(cat.key); trackBy: trackQuestion"
|
|
|
class="form-group"
|
|
|
[class.required]="question.required"
|
|
|
[class.invalid]="showError(question)"
|
|
|
[id]="'q-' + question.column_key">
|
|
|
|
|
|
<label [attr.for]="'answer' + question.column_key">
|
|
|
{{ question.label }}
|
|
|
<span *ngIf="question.required" class="required-asterisk">*</span>
|
|
|
</label>
|
|
|
|
|
|
<ng-container [ngSwitch]="question.input_type">
|
|
|
|
|
|
|
|
|
<div *ngSwitchCase="'text'" class="text-input-container">
|
|
|
|
|
|
<div *ngIf="isAdditionalRemarksField(question)"
|
|
|
class="text-input-preview"
|
|
|
(click)="openTextInputPopup(question)"
|
|
|
[class.has-value]="answers[question.column_key]">
|
|
|
{{ answers[question.column_key] || getPlaceholder(question) }}
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<input *ngIf="!isAdditionalRemarksField(question)"
|
|
|
type="text"
|
|
|
class="form-control"
|
|
|
[id]="'answer' + question.column_key"
|
|
|
[(ngModel)]="answers[question.column_key]"
|
|
|
[name]="'answer' + question.column_key"
|
|
|
(ngModelChange)="onAnswerChange(question.column_key, $event)"
|
|
|
[placeholder]="getPlaceholder(question)"
|
|
|
[required]="question.required || false" />
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div *ngSwitchCase="'textarea'" class="text-input-container">
|
|
|
|
|
|
<div *ngIf="isAdditionalRemarksField(question)"
|
|
|
class="text-input-preview"
|
|
|
(click)="openTextInputPopup(question)"
|
|
|
[class.has-value]="answers[question.column_key]">
|
|
|
{{ (answers[question.column_key] || getPlaceholder(question)) | truncate:100 }}
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<textarea *ngIf="!isAdditionalRemarksField(question)"
|
|
|
class="form-control"
|
|
|
[id]="'answer' + question.column_key"
|
|
|
[(ngModel)]="answers[question.column_key]"
|
|
|
[name]="'answer' + question.column_key"
|
|
|
(ngModelChange)="onAnswerChange(question.column_key, $event)"
|
|
|
[placeholder]="getPlaceholder(question)"
|
|
|
[required]="question.required || false"
|
|
|
rows="3"></textarea>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<input *ngSwitchCase="'date'"
|
|
|
type="date"
|
|
|
class="form-control"
|
|
|
[id]="'answer' + question.column_key"
|
|
|
[(ngModel)]="answers[question.column_key]"
|
|
|
[name]="'answer' + question.column_key"
|
|
|
(ngModelChange)="onAnswerChange(question.column_key, $event)"
|
|
|
[required]="question.required || false" />
|
|
|
|
|
|
|
|
|
<select *ngSwitchCase="'select'"
|
|
|
class="form-control"
|
|
|
[id]="'answer' + question.column_key"
|
|
|
[(ngModel)]="answers[question.column_key]"
|
|
|
[name]="'answer' + question.column_key"
|
|
|
(ngModelChange)="onAnswerChange(question.column_key, $event)"
|
|
|
[required]="question.required || false">
|
|
|
<option value="" disabled selected>{{ getPlaceholder(question) }}</option>
|
|
|
<option *ngFor="let opt of question.options" [value]="opt">{{ opt }}</option>
|
|
|
</select>
|
|
|
|
|
|
|
|
|
<div *ngSwitchCase="'multiselect'" class="multiselect-dropdown-checkbox">
|
|
|
<div class="dropdown-toggle"
|
|
|
(click)="toggleDropdown(question.column_key)"
|
|
|
[class.dropdown-open]="isDropdownOpen(question.column_key)">
|
|
|
<span class="selected-text">
|
|
|
{{ getSelectedOptionsText(question.column_key) || getPlaceholder(question) }}
|
|
|
</span>
|
|
|
<i class="fas fa-chevron-down dropdown-arrow"></i>
|
|
|
</div>
|
|
|
|
|
|
<div class="dropdown-options" [class.show]="isDropdownOpen(question.column_key)">
|
|
|
<div class="dropdown-options-container">
|
|
|
|
|
|
<div class="dropdown-option select-all" *ngIf="getMultiselectOptions(question).length > 1">
|
|
|
<input type="checkbox"
|
|
|
class="checkbox-input"
|
|
|
[id]="'select_all_' + question.column_key"
|
|
|
[checked]="areAllOptionsSelected(question)"
|
|
|
(change)="toggleSelectAll(question)" />
|
|
|
<label [for]="'select_all_' + question.column_key"
|
|
|
class="checkbox-label select-all-label">
|
|
|
Select All
|
|
|
</label>
|
|
|
</div>
|
|
|
<div class="dropdown-divider" *ngIf="getMultiselectOptions(question).length > 1"></div>
|
|
|
|
|
|
|
|
|
<div *ngFor="let option of getMultiselectOptions(question)"
|
|
|
class="dropdown-option">
|
|
|
<input type="checkbox"
|
|
|
class="checkbox-input"
|
|
|
[id]="'dropdown_' + question.column_key + '_' + option"
|
|
|
[value]="option"
|
|
|
(change)="onMultiselectChange($event, question.column_key)"
|
|
|
[checked]="isMultiselectSelected(question.column_key, option)" />
|
|
|
<label [for]="'dropdown_' + question.column_key + '_' + option"
|
|
|
class="checkbox-label">
|
|
|
{{ option }}
|
|
|
</label>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div *ngSwitchCase="'radio'" class="radio-group">
|
|
|
<div *ngFor="let opt of question.options" class="radio-option">
|
|
|
<input type="radio"
|
|
|
class="radio-input"
|
|
|
[id]="'radio_' + question.column_key + '_' + opt"
|
|
|
[name]="'radio_' + question.column_key"
|
|
|
[value]="opt"
|
|
|
[checked]="isRadioSelected(question.column_key, opt)"
|
|
|
(change)="onRadioChange(question.column_key, opt)" />
|
|
|
<label [for]="'radio_' + question.column_key + '_' + opt"
|
|
|
class="radio-label">
|
|
|
{{ opt }}
|
|
|
</label>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div *ngSwitchCase="'checkbox'" class="checkbox-single">
|
|
|
<input type="checkbox"
|
|
|
class="checkbox-input"
|
|
|
[id]="'checkbox_' + question.column_key"
|
|
|
[checked]="answers[question.column_key]"
|
|
|
(change)="onAnswerChange(question.column_key, ($any($event.target)).checked)" />
|
|
|
<label [for]="'checkbox_' + question.column_key"
|
|
|
class="checkbox-label">
|
|
|
{{ question.label }}
|
|
|
</label>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div *ngSwitchCase="'textarea'" class="text-input-container">
|
|
|
<div class="text-input-preview"
|
|
|
(click)="openTextInputPopup(question)"
|
|
|
[class.has-value]="answers[question.column_key]">
|
|
|
{{ (answers[question.column_key] || getPlaceholder(question)) | truncate:100 }}
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<input *ngSwitchCase="'number'"
|
|
|
type="number"
|
|
|
class="form-control"
|
|
|
[id]="'answer' + question.column_key"
|
|
|
[(ngModel)]="answers[question.column_key]"
|
|
|
[name]="'answer' + question.column_key"
|
|
|
(ngModelChange)="onAnswerChange(question.column_key, $event)"
|
|
|
[placeholder]="getPlaceholder(question)"
|
|
|
[required]="question.required || false" />
|
|
|
|
|
|
|
|
|
<div *ngSwitchDefault class="text-input-container">
|
|
|
|
|
|
<div *ngIf="isAdditionalRemarksField(question)"
|
|
|
class="text-input-preview"
|
|
|
(click)="openTextInputPopup(question)"
|
|
|
[class.has-value]="answers[question.column_key]">
|
|
|
{{ answers[question.column_key] || getPlaceholder(question) }}
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<input *ngIf="!isAdditionalRemarksField(question)"
|
|
|
type="text"
|
|
|
class="form-control"
|
|
|
[id]="'answer' + question.column_key"
|
|
|
[(ngModel)]="answers[question.column_key]"
|
|
|
[name]="'answer' + question.column_key"
|
|
|
(ngModelChange)="onAnswerChange(question.column_key, $event)"
|
|
|
[placeholder]="getPlaceholder(question)"
|
|
|
[required]="question.required || false" />
|
|
|
</div>
|
|
|
</ng-container>
|
|
|
|
|
|
<div class="field-error" *ngIf="showError(question)">
|
|
|
This field is required.
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="tab-footer">
|
|
|
<div class="button-group">
|
|
|
<button *ngIf="selectedCategory !== categoriesMeta[0].key"
|
|
|
type="button"
|
|
|
class="btn btn-prev"
|
|
|
(click)="goToPreviousCategory(cat.key)">
|
|
|
<i class="fas fa-arrow-left"></i> Previous
|
|
|
</button>
|
|
|
|
|
|
<button *ngIf="selectedCategory !== 'review'"
|
|
|
type="button"
|
|
|
class="btn btn-next"
|
|
|
(click)="goToNextCategory(cat.key)">
|
|
|
Next <i class="fas fa-arrow-right"></i>
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section class="tab review-tab"
|
|
|
[class.active]="selectedCategory === 'review'"
|
|
|
[class.blur-background]="showSubmissionPopup && isSubmissionSuccess || showTextInputPopup">
|
|
|
|
|
|
<div class="tab-content">
|
|
|
<div class="review-section">
|
|
|
<div class="review-tab-content">
|
|
|
|
|
|
<div class="review-sidebar">
|
|
|
<div class="review-category-tabs">
|
|
|
<div *ngFor="let cat of categoriesMeta"
|
|
|
class="review-category-tab"
|
|
|
[class.active]="selectedReviewCategory === cat.key"
|
|
|
(click)="selectReviewCategory(cat.key)">
|
|
|
<span class="category-name">{{ cat.title }}</span>
|
|
|
<span class="category-progress">
|
|
|
{{ getCategoryAnsweredCount(cat.key) }}/{{ getCategoryRequiredCount(cat.key) }}
|
|
|
</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div class="review-content">
|
|
|
<div *ngIf="selectedReviewCategory" class="review-category-content">
|
|
|
|
|
|
<div class="review-category-header">
|
|
|
<h3 class="review-category-title">
|
|
|
{{ getReviewCategoryTitle(selectedReviewCategory) }}
|
|
|
</h3>
|
|
|
<div class="review-category-stats">
|
|
|
<span>{{ getCategoryAnsweredCountByKey(selectedReviewCategory) }}/{{ getCategoryRequiredCountByKey(selectedReviewCategory) }} answered</span>
|
|
|
<button type="button"
|
|
|
class="btn btn-secondary"
|
|
|
(click)="selectCategory(selectedReviewCategory)">
|
|
|
Edit Details
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div class="review-answers">
|
|
|
<div *ngFor="let question of getCategoryQuestions(selectedReviewCategory)"
|
|
|
class="review-answer-item">
|
|
|
<span class="review-answer-label">{{ question.label }}:</span>
|
|
|
<span class="review-answer-value" [class.missing]="!isAnswered(question)">
|
|
|
{{ isAnswered(question) ? getAnswerDisplay(question) : '(Not answered)' }}
|
|
|
</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div *ngIf="!selectedReviewCategory" class="review-empty-state">
|
|
|
<div style="text-align: center; padding: 60px 20px;">
|
|
|
<i class="fas fa-folder-open" style="font-size: 3rem; color: #bdc3c7; margin-bottom: 20px;"></i>
|
|
|
<h3 style="color: #2c3e50; margin-bottom: 10px;">Select a Category</h3>
|
|
|
<p style="color: #7f8c8d;">Choose a category from the left sidebar to review your answers.</p>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="tab-footer">
|
|
|
<div class="button-group">
|
|
|
<button type="button"
|
|
|
class="btn btn-prev"
|
|
|
(click)="goToPreviousCategory('review')">
|
|
|
<i class="fas fa-arrow-left"></i> Previous
|
|
|
</button>
|
|
|
|
|
|
<button type="button"
|
|
|
class="btn btn-submit"
|
|
|
(click)="submitAnswers()"
|
|
|
[disabled]="isSubmitting || !allFieldsAnswered">
|
|
|
{{ isSubmitting ? 'Submitting...' : 'Submit' }} <i class="fas fa-check"></i>
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</section>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div class="submission-popup-overlay" *ngIf="showSubmissionPopup && !isSubmissionSuccess">
|
|
|
<div class="submission-popup">
|
|
|
<div class="popup-header error">
|
|
|
<div class="popup-icon">⚠</div>
|
|
|
<h3 class="popup-title">Submission Failed</h3>
|
|
|
</div>
|
|
|
<div class="popup-body">
|
|
|
<p class="popup-message">{{ submissionMessage }}</p>
|
|
|
</div>
|
|
|
<div class="popup-footer">
|
|
|
<button class="btn btn-primary" (click)="showSubmissionPopup = false">
|
|
|
Try Again
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|