import { ChangeDetectionStrategy, Component, computed, HostListener, inject, input, output, } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms'; import { passwordMatchValidator, PasswordPolicy, } from './change-password-modal.validators'; export type ChangePasswordMode = 'self' | 'admin-reset'; export interface ChangePasswordSubmitPayload { oldPassword: string; newPassword: string; confirmNewPassword: string; } const DEFAULT_POLICY: PasswordPolicy = { minLength: 12, requireMixed: true, description: 'At least 12 characters with upper, lower, digit and symbol', }; @Component({ selector: 'app-change-password-modal', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, ReactiveFormsModule], styles: [` .modal-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.9); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; z-index: 1200; padding: 16px; } .modal-card { background: #000000; color: #ffffff; border: 3px solid var(--neon-red); padding: 28px 24px; width: min(440px, 94vw); position: relative; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.9), 0 0 25px rgba(255, 0, 51, 0.35); } h2 { font-family: var(--font-heading, 'Chakra Petch', sans-serif); font-size: 2rem; font-weight: 900; font-style: italic; text-transform: uppercase; color: #ffffff; margin-bottom: 20px; letter-spacing: 0.5px; } .field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; text-align: left; } .field span { font-family: var(--font-mono); font-size: 0.75rem; font-weight: 800; color: #888899; text-transform: uppercase; letter-spacing: 1px; } .field input { font-family: var(--font-mono); background-color: #000000; color: #ffffff; border: 2px solid var(--neon-purple); padding: 12px 14px; font-size: 0.95rem; outline: none; width: 100%; } .field input:focus { border-color: var(--neon-cyan); box-shadow: 0 0 10px var(--neon-cyan-glow); } .error { color: var(--neon-red); font-family: var(--font-mono); font-size: 0.85rem; font-weight: bold; } .hint { color: #777788; font-family: var(--font-mono); font-size: 0.75rem; margin-bottom: 20px; } .actions { display: flex; justify-content: flex-end; gap: 12px; margin-top: 10px; } .actions button { font-family: var(--font-mono); font-weight: 800; text-transform: uppercase; padding: 10px 20px; font-size: 0.9rem; cursor: pointer; } .btn-cancel { background: #000000; color: var(--neon-purple); border: 2px solid var(--neon-purple); } .btn-cancel:hover:not([disabled]) { background: var(--neon-purple); color: #000000; } .btn-ok { background: var(--neon-red); color: #000000; border: 2px solid var(--neon-red); } .btn-ok:hover:not([disabled]) { background: #000000; color: var(--neon-red); box-shadow: 0 0 15px rgba(255, 0, 51, 0.4); } `], template: ` @if (open()) {
} `, }) export class ChangePasswordModalComponent { private readonly fb = inject(FormBuilder); readonly open = input