py-match / src /app /auth /sign-up /sign-up.component.html
pykara's picture
Upload 5840 files
38fa174 verified
<section class="auth-page">
<div class="auth-box" role="dialog" aria-labelledby="suTitle">
<!-- Left (form) -->
<div class="panel-left">
<!-- Success Animation Overlay -->
<div class="success-overlay" *ngIf="showSuccessAnimation">
<div class="success-animation">
<div class="success-checkmark">
<div class="check-icon">
<span class="icon-line line-tip"></span>
<span class="icon-line line-long"></span>
</div>
</div>
</div>
<div class="success-message">Account Created Successfully!</div>
</div>
<div class="topTitle">
<img class="brand-mark" src="/assets/pykara-logo.png" alt="Brand" />
<p class="topHeader"><b>Let's get started!</b></p>
</div>
<h2 id="suTitle" class="title">Create an account</h2>
<form class="form" [formGroup]="form" (ngSubmit)="submit()" novalidate>
<!-- Name -->
<div class="field">
<label for="name">
Name<span *ngIf="controlHasError('name','required')" class="error">*</span>
</label>
<input id="name" type="text" placeholder="John"
formControlName="name" [attr.aria-invalid]="controlHasError('name')" />
<small *ngIf="controlHasError('name','minlength')" class="error">Enter at least 2 characters.</small>
</div>
<!-- Email/Phone (contact) -->
<div class="field">
<label for="contact">
Email<span *ngIf="controlHasError('contact','required')" class="error">*</span>
</label>
<input id="contact" type="text" placeholder="hello@gmail.com"
formControlName="contact" [attr.aria-invalid]="controlHasError('contact')" />
<small *ngIf="controlHasError('contact','pattern')" class="error">Enter a valid email/phone.</small>
</div>
<!-- Password -->
<div class="field">
<label for="password">
Password<span *ngIf="controlHasError('password','required')" class="error">*</span>
</label>
<div class="password-input-container">
<input id="password" [type]="showPassword ? 'text' : 'password'" placeholder="••••••••"
formControlName="password" [attr.aria-invalid]="controlHasError('password')"
(focus)="onPasswordFocus()"
(blur)="onPasswordBlur()" />
<!-- Eye icon for password visibility -->
<span class="password-toggle" *ngIf="control('password')?.value"
(click)="togglePasswordVisibility()"
[class.visible]="showPassword">
👁️
</span>
<!-- Password Requirements Tooltip -->
<div class="password-tooltip" *ngIf="showPasswordTooltip">
<div class="tooltip-content">
<div class="tooltip-layout">
<!-- Left side: Requirements -->
<div class="tooltip-left">
<small class="requirement-title">Password must contain:</small>
<ul class="requirement-list">
<li [class.valid]="getPasswordRequirementStatus().length">At least 8 characters</li>
<li [class.valid]="getPasswordRequirementStatus().upperCase">One uppercase letter (A-Z)</li>
<li [class.valid]="getPasswordRequirementStatus().lowerCase">One lowercase letter (a-z)</li>
<li [class.valid]="getPasswordRequirementStatus().number">One number (0-9)</li>
<li [class.valid]="getPasswordRequirementStatus().specialChar">One special character (e.g., @, #, $, %)</li>
<li [class.valid]="getPasswordRequirementStatus().noSpaces">No spaces</li>
</ul>
</div>
<!-- Right side: Strength & Errors -->
<div class="tooltip-right">
<!-- Password Strength Indicator -->
<div *ngIf="control('password')?.value" class="password-strength">
<div class="strength-bar" [class]="passwordStrength">
<div class="strength-fill"></div>
</div>
<small class="strength-text" [class]="passwordStrength">
Password strength: {{ passwordStrength | titlecase }}
</small>
</div>
<!-- Individual error messages -->
<div class="error-messages" *ngIf="control('password')?.invalid">
<small *ngIf="controlHasError('password','minlength')" class="error">• Use at least 8 characters</small>
<small *ngIf="controlHasError('password','missingUpperCase')" class="error">• Add an uppercase letter</small>
<small *ngIf="controlHasError('password','missingLowerCase')" class="error">• Add a lowercase letter</small>
<small *ngIf="controlHasError('password','missingNumber')" class="error">• Add a number</small>
<small *ngIf="controlHasError('password','missingSpecialChar')" class="error">• Add a special character</small>
<small *ngIf="controlHasError('password','hasSpaces')" class="error">• Remove spaces</small>
<small *ngIf="controlHasError('password','hasSequentialChars')" class="error">• Avoid sequential characters</small>
<small *ngIf="controlHasError('password','hasRepeatedChars')" class="error">• Avoid repeated characters</small>
<small *ngIf="controlHasError('password','hasCommonWord')" class="error">• Avoid common words</small>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Confirm password -->
<div class="field">
<label for="confirmPassword">
Confirm password
<span *ngIf="controlHasError('confirmPassword','required')" class="error">*</span>
<!-- Moved error message outside label -->
<span *ngIf="showPwdMismatch() && control('confirmPassword')?.touched && control('password')?.touched" class="error">
Passwords do not match.
</span>
</label>
<div class="password-input-container">
<input id="confirmPassword" [type]="showConfirmPassword ? 'text' : 'password'" placeholder="••••••••"
formControlName="confirmPassword" [attr.aria-invalid]="showPwdMismatch()" />
<!-- Eye icon for confirm password visibility -->
<span class="password-toggle" *ngIf="control('confirmPassword')?.value"
(click)="toggleConfirmPasswordVisibility()"
[class.visible]="showConfirmPassword">
👁️
</span>
</div>
</div>
<!-- Add this after the form closing tag but before the panel-left closing div -->
<div *ngIf="errorMessage()" class="error-message">
{{ errorMessage() }}
</div>
<button class="btn btn-primary" type="submit"
[disabled]="form.invalid || submitting()" [attr.aria-busy]="submitting()">
Sign up
</button>
</form>
</div>
<!-- Right (image) -->
<div class="panel-right">
<div class="right-image">
<img src="/assets/user.png" alt="Decorative" />
<!-- Footnote Container -->
<div class="footnote-container">
<p class="footnote">
Already have an account?
<!-- Use click handler instead of routerLink -->
<a href="#" (click)="goToLogin(); $event.preventDefault()" [class.pulse]="showSignInPulse()">Sign in</a>
</p>
</div>
</div>
</div>
</div>
</section>