Py-detect / src /app /infopage /infopage.component.html
pykara's picture
fix
73566f6
raw
history blame
17.3 kB
<!-- AI-Enhanced Remote Tech Jobs Style Header -->
<div class="site-header">
<div class="header-inner">
<div class="logo-cluster">
<span [routerLink]="'/'" style="cursor:pointer;display:flex;align-items:center;">
<img src="/assets/pykara-logo.png" alt="PyDetect Logo" class="logo-img-header" />
</span>
<div class="py-detect-title-header">
<span class="py-letter p">P</span>
<span class="py-letter y">Y</span>
<span class="py-shape"></span>
<span class="py-letter d">D</span>
<span class="py-letter e">E</span>
<span class="py-letter t">T</span>
<span class="py-letter e2">E</span>
<span class="py-letter c">C</span>
<span class="py-letter t2">T</span>
</div>
</div>
<div class="header-progress">
<span class="pykara-analysis-label">Progress:</span>
<div class="pykara-progress-bar">
<div class="pykara-progress-bar-inner" [style.width.%]="progressPercentage"></div>
</div>
<span class="pykara-progress-percentage">{{ progressPercentage }}%</span>
</div>
<div class="header-actions autosave-right">
<div class="autosave-indicator" [class.saving]="isAutoSaving">
<i class="fas fa-save"></i>
<span>{{ autoSaveStatus }}</span>
</div>
<!-- View Records Button -->
<div class="view-records-btn" style="margin-left: 16px; vertical-align: middle; color: #fff; font-size: 1.5em; width: 2em; height: 2em; display: flex; align-items: center; justify-content: center; cursor: pointer; position: relative; margin-bottom: 15px;"
type="button"
(click)="goToRecords()"
(mouseenter)="showViewRecordsTooltip = true"
(mouseleave)="showViewRecordsTooltip = false">
<i class="fas fa-folder-open"></i>
<span *ngIf="showViewRecordsTooltip" style="position:absolute;top:100%;left:0%;transform:translateX(-50%);background:#222;color:#fff;padding:4px 12px;border-radius:6px;font-size:0.6em;white-space:nowrap;z-index:10;box-shadow:0 2px 8px rgba(0,0,0,0.12);">View Records</span>
</div>
</div>
</div>
</div>
<!-- AI-Enhanced Tech Jobs Style Section Navigation -->
<div class="section-navigation" [@fadeIn]>
<div class="ai-neural-bg"></div>
<div class="section-pills">
<button class="section-pill main-section-pill ai-enhanced"
*ngFor="let section of sectionKeys; let i = index"
[class.active]="currentSection === section"
[class.completed]="isSectionCompleted(section)"
[attr.data-step]="i + 1"
(click)="showSection(section)"
[attr.tabindex]="0">
<div class="pill-neural-core"></div>
<i [class]="sectionIcons[section]"></i>
<span>{{ sections[section].title }}</span>
<div class="ai-completion-orb" *ngIf="isSectionCompleted(section)">
<div class="orb-pulse"></div>
<i class="fas fa-check"></i>
</div>
<div class="pill-scanner"></div>
</button>
</div>
<div class="section-ai-grid"></div>
</div>
<!-- AI-Enhanced Job Category Style Subgroup Navigation with Section-Specific Styling -->
<div class="subgroup-pills"
[class.crime-section]="currentSection === 'crime'"
[class.suspect-section]="currentSection === 'suspect'"
[class.notes-section]="currentSection === 'notes'"
[@fadeIn]>
<div class="neural-mesh"></div>
<div class="pill ai-subgroup-pill"
*ngFor="let key of getSubgroups(); let i = index"
[class.active]="key === currentSubgroup"
[class.completed]="isSubgroupCompleted(key)"
(click)="setSubgroup(key)"
[attr.tabindex]="0">
<div class="pill-ai-core"></div>
<i [class]="subgroupIcons[key] || 'fas fa-circle'"></i>
<span>{{ key }}</span>
<div class="ai-completion-badge" *ngIf="isSubgroupCompleted(key)">
<div class="badge-glow"></div>
<i class="fas fa-check-circle"></i>
</div>
<div class="pill-ai-scanner"></div>
</div>
</div>
<!-- Job Cards Style Layout - Universal Single Card Layout for All Pages -->
<div class="investigation-container">
<!-- Universal Single Investigation Card -->
<div class="form-card primary-card" [@cardSlide] #formCard1>
<div class="card-header compact-card-header">
<div class="card-header-main">
<h2 class="compact-title">
<i [class]="subgroupIcons[currentSubgroup] || 'fas fa-circle'"></i>
{{ currentSubgroup }}
<span class="field-counter compact-field-counter">{{ getSelectedFieldCount() }} of {{ getTotalAvailableFieldsCount() }}</span>
</h2>
</div>
<div class="modern-field-selector-btn compact-selector-btn" style="position:relative;">
<button class="field-selector-btn modern-selector-animated compact-selector-btn-inner"
[class.active]="showFieldSelector === (currentSection + '-' + currentSubgroup)"
(click)="toggleFieldSelector($event)"
type="button"
title="Select fields to display">
<i class="fas fa-list-check"></i>
<span class="field-selector-counter">{{ getSelectedFieldCount() }}/{{ getDynamicMaxSelectable() }}</span>
</button>
<!-- Field Selector Popup: floating, anchored to button -->
<div class="modern-field-selector-popup"
*ngIf="showFieldSelector === (currentSection + '-' + currentSubgroup)"
(click)="$event.stopPropagation()">
<div class="popup-header">
<span><i class="fas fa-list-check"></i> Select Fields to Display</span>
<button class="popup-close-btn" (click)="closeFieldSelector()" type="button">
<i class="fas fa-times"></i>
</button>
</div>
<div class="popup-fields-list">
<div *ngFor="let field of getAvailableFields(); trackBy: trackByField" class="popup-field-row">
<label class="popup-field-label">
<input type="checkbox"
[checked]="isFieldSelected(field)"
(click)="$event.stopPropagation()"
(change)="toggleFieldSelection(field, $event)" />
<span class="popup-field-text">{{ field }}</span>
</label>
</div>
</div>
<div class="popup-actions">
<button class="popup-action-btn clear-btn" (click)="resetFieldSelection($event)" type="button">
<i class="fas fa-times-circle"></i> Clear All
</button>
<button class="popup-action-btn selectall-btn" (click)="selectAllFields($event)" type="button">
<i class="fas fa-check-double"></i> Select All
</button>
<button class="popup-action-btn save-btn" (click)="closeFieldSelector()" type="button">
<i class="fas fa-save"></i> Save
</button>
</div>
</div>
</div>
</div>
<div class="card-content" [class.minimized]="isCardMinimized.primary">
<div class="section-description" [@fadeIn]>
<strong>{{ sections[currentSection].title }} - {{ currentSubgroup }}:</strong> {{ getSectionDescription(currentSection) }}
</div>
<div class="fields-grid">
<div *ngFor="let field of getPrimaryFields(); let i = index; trackBy: trackByField"
class="field-container"
[class.filled]="formData[field] && formData[field].toString().trim() !== ''"
[attr.data-field]="field"
[@fieldAnimation]>
<label class="field-label">
{{ field }}
<span class="required-indicator" *ngIf="isFieldRequired(field)">*</span>
<button type="button"
class="info-btn glossy-info-btn"
(click)="toggleFieldInfo(field, $event)"
[attr.aria-label]="'Info for ' + field">
<i class="fas fa-info"></i>
</button>
<!-- Microphone icon for Remark field -->
<ng-container *ngIf="field === 'Remark'">
<span style="display:inline-flex;align-items:center;position:relative;">
<button type="button"
(mouseenter)="showMicPopup = true"
(mouseleave)="showMicPopup = false"
(click)="toggleRecording()"
style="background:none;border:none;outline:none;cursor:pointer;padding:0;margin-left:6px;">
<i class="fas fa-microphone"
[ngStyle]="{
color: isRecording ? '#e74c3c' : '#3498db',
animation: 'micPulse 1s infinite',
fontSize: '1.2em',
transition: 'color 0.2s'
}"
style="transition:color 0.2s;">
</i>
</button>
<!-- Popup on hover -->
<div *ngIf="showMicPopup"
style="position:absolute;top:120%;left:0;z-index:10;background:#fff;border:1px solid #ccc;padding:8px 12px;border-radius:6px;box-shadow:0 2px 8px rgba(0,0,0,0.12);white-space:nowrap;min-width:160px;">
Click to record your remark.<br>Release to stop.<br>Recording is {{ isRecording ? 'ON' : 'OFF' }}.
</div>
<!-- Inline animation keyframes -->
<style>
@keyframes micPulse {
0% {
transform: scale(1);
filter: drop-shadow(0 0 0 #e74c3c);
}
50% {
transform: scale(1.2);
filter: drop-shadow(0 0 8px #e74c3c);
}
100% {
transform: scale(1);
filter: drop-shadow(0 0 0 #e74c3c);
}
}
</style>
</span>
</ng-container>
</label>
<!-- Dynamic Field Rendering -->
<div class="input-container">
<!-- File Upload Fields -->
<div *ngIf="fileFields.has(field); else nonFileField" class="file-upload-block">
<div class="file-drop-zone"
(dragover)="onDragOver($event)"
(dragleave)="onDragLeave($event)"
(drop)="onFileDrop(field, $event)"
[class.drag-over]="isDragOver">
<input type="file"
(change)="onFileChange(field, $event)"
multiple
[accept]="getAcceptedFileTypes(field)"
class="file-input" />
<div class="drop-zone-content">
<i class="fas fa-cloud-upload-alt"></i>
<p>Drop files here or click to browse</p>
</div>
</div>
<div class="file-list" *ngIf="uploadedFiles[field]?.length">
<div *ngFor="let f of uploadedFiles[field]" class="file-chip">
<i [class]="getFileIcon(f.name)"></i>
<span [title]="f.name">{{ f.name | slice:0:15 }}{{ f.name.length > 15 ? '...' : '' }}</span>
<button class="remove-file" (click)="removeFile(field, f)">
<i class="fas fa-times"></i>
</button>
</div>
</div>
</div>
<ng-template #nonFileField>
<!-- Date/Time Fields -->
<ng-container *ngIf="dateTimeFields.has(field); else nonDateTime">
<input type="datetime-local"
class="field-input"
[class.compact]="isCompactField(field)"
[(ngModel)]="formData[field]"
(input)="onFieldChange(field)" />
</ng-container>
<ng-template #nonDateTime>
<ng-container *ngIf="dateFields.has(field); else nonDate">
<input type="date"
class="field-input"
[class.compact]="isCompactField(field)"
[(ngModel)]="formData[field]"
(input)="onFieldChange(field)" />
</ng-container>
<ng-template #nonDate>
<!-- Cascading Dropdowns -->
<ng-container *ngIf="field === 'Country' || field === 'State' || field === 'District'; else standardField">
<select class="field-input"
[class.compact]="isCompactField(field)"
[(ngModel)]="formData[field]"
(change)="onSelectChange(field, $event)">
<option value="">-- Select {{ field }} --</option>
<option *ngFor="let opt of getOptions(field)" [value]="opt">{{ opt }}</option>
</select>
</ng-container>
<ng-template #standardField>
<!-- Standard Select or Text Input -->
<select *ngIf="getOptions(field)?.length; else textInput"
class="field-input"
[class.compact]="isCompactField(field)"
[(ngModel)]="formData[field]"
(change)="onSelectChange(field, $event)">
<option value="">-- Select Option --</option>
<option *ngFor="let opt of getOptions(field)" [value]="opt">{{ opt }}</option>
</select>
<ng-template #textInput>
<!-- Description fields as textarea -->
<textarea *ngIf="field.toLowerCase().includes('description') || field === 'Remark'; else regularInput"
class="field-input auto-scroll-textarea"
[class.compact]="isCompactField(field)"
[(ngModel)]="formData[field]"
(input)="onFieldChange(field)"
[placeholder]="getFieldPlaceholder(field)"
[attr.maxlength]="field === 'Brief Description' ? null : getMaxLength(field)"
rows="3"></textarea>
<!-- Recording status for Remark -->
<div *ngIf="field === 'Remark' && isRecording" style="margin-top:4px;color:#e74c3c;font-size:0.95em;">
Recording... Speak now.
</div>
<ng-template #regularInput>
<input [type]="getInputType(field)"
class="field-input"
[class.compact]="isCompactField(field)"
[(ngModel)]="formData[field]"
(input)="onFieldChange(field)"
[placeholder]="getFieldPlaceholder(field)"
[maxlength]="getMaxLength(field)" />
</ng-template>
</ng-template>
</ng-template>
</ng-template>
</ng-template>
</ng-template>
</div>
<!-- Field Help Popover -->
<div class="field-help" *ngIf="showHelpFor === field" [@helpAnimation]>
<strong>Field Information:</strong><br>
{{ fieldDescriptions[field] || 'Additional details for this field are being prepared.' }}
</div>
</div>
</div>
</div>
<!-- Removed modern-nav-btns from here to prevent scrolls -->
</div>
</div>
<!-- Floating Modern Navigation Button (fixed, no scroll) -->
<div class="modern-floating-nav-btn">
<!-- Next button appears on all pages except the last Remark page under notes -->
<button *ngIf="!(isLastSubgroup() && currentSection === 'notes' && currentSubgroup === 'Remark')" type="button" class="modern-round-btn next-btn-animated" (click)="nextSubgroup()" [disabled]="!canNextSubgroup()" title="Next">
<i class="fas fa-arrow-right"></i>
</button>
<!-- Submit button only on last Remark page under notes -->
<button *ngIf="isLastSubgroup() && currentSection === 'notes' && currentSubgroup === 'Remark'" type="button" class="modern-round-btn submit-btn-animated" (click)="submitCurrentSection()" title="Submit">
<i class="fas fa-paper-plane"></i>
</button>
</div>
<!-- Submission Success Popup - Enhanced with Clickable Background and Navigation on Close -->
<div *ngIf="showSubmitPopup" class="submit-popup-backdrop">
<div class="submit-popup-modal">
<div class="submit-popup-content" (click)="onSubmitPopupClose()" style="cursor:pointer;">
<i class="fas fa-check-circle submit-popup-icon"></i>
<h3>Submission Successful!</h3>
<p>Your information has been submitted.</p>
<button class="submit-popup-btn">OK</button>
</div>
</div>
</div>
<!-- Footer from provided design -->
<footer>
<p>© 2025 Pykara Technologies Pvt. Ltd. All rights reserved.</p>
</footer>