|
|
<section class="signup-popup ai-bg-animate"> |
|
|
<div class="ai-particle-bg"></div> |
|
|
<div class="signup-header"> |
|
|
<div class="signup-logo"> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="auth-card"> |
|
|
<div class="card-inner"> |
|
|
|
|
|
<div class="card-front"> |
|
|
<button class="signin-close" type="button" (click)="closePopup()" aria-label="Close">×</button> |
|
|
|
|
|
<div class="card-content"> |
|
|
<div class="side-panel side-left"> |
|
|
<div class="signup-panel-left"> |
|
|
|
|
|
</div> |
|
|
<div class="main-panel"> |
|
|
<h2 class="signup-title center-title">Create An Account</h2> |
|
|
|
|
|
<form [formGroup]="form" (ngSubmit)="submit()" class="create-form" novalidate> |
|
|
<div class="form-row"> |
|
|
<div class="form-field"> |
|
|
<label for="firstName">First Name</label> |
|
|
<input id="firstName" type="text" placeholder="First Name" formControlName="name" [attr.aria-invalid]="controlHasError('name')" /> |
|
|
<small *ngIf="controlHasError('name','required') && form.get('name')?.touched" class="error">First name is required.</small> |
|
|
<small *ngIf="controlHasError('name','minlength') && form.get('name')?.touched" class="error">Enter at least 2 characters.</small> |
|
|
<small *ngIf="controlHasError('name','invalidName') && form.get('name')?.touched" class="error">Only alphabets and spaces allowed.</small> |
|
|
</div> |
|
|
<div class="form-field"> |
|
|
<label for="lastName">Last Name</label> |
|
|
<input id="lastName" type="text" placeholder="Last Name" formControlName="lastName" [attr.aria-invalid]="controlHasError('lastName')" /> |
|
|
<small *ngIf="controlHasError('lastName','required') && form.get('lastName')?.touched" class="error">Last name is required.</small> |
|
|
<small *ngIf="controlHasError('lastName','minlength') && form.get('lastName')?.touched" class="error">Enter at least 2 characters.</small> |
|
|
<small *ngIf="controlHasError('lastName','invalidName') && form.get('lastName')?.touched" class="error">Only alphabets and spaces allowed.</small> |
|
|
</div> |
|
|
</div> |
|
|
<div class="form-row"> |
|
|
<div class="form-field"> |
|
|
<label for="email">Email</label> |
|
|
<input id="email" type="text" placeholder="email@gmail.com" formControlName="email" [attr.aria-invalid]="controlHasError('email')" /> |
|
|
<small *ngIf="controlHasError('email','required') && form.get('email')?.touched" class="error">Email is required.</small> |
|
|
<small *ngIf="controlHasError('email','pattern') && form.get('email')?.touched" class="error">Enter a valid email/phone.</small> |
|
|
</div> |
|
|
<div class="form-field role-field-wrapper"> |
|
|
<label for="role"> |
|
|
Role |
|
|
<button class="info-btn" type="button" (click)="showInfo = true">i</button> |
|
|
</label> |
|
|
<select id="role" formControlName="role" [attr.aria-invalid]="controlHasError('role')"> |
|
|
<option value="">-- Select Role --</option> |
|
|
<option value="admin">Admin</option> |
|
|
<option value="teachers">Teachers</option> |
|
|
<option value="student">Student</option> |
|
|
|
|
|
<option value="others">Others</option> |
|
|
</select> |
|
|
<small *ngIf="controlHasError('role','required') && form.get('role')?.touched" class="error">Role is required.</small> |
|
|
</div> |
|
|
</div> |
|
|
<div class="form-row"> |
|
|
<div class="form-field" style="position:relative;"> |
|
|
<label for="password">Create Password</label> |
|
|
<input id="password" [type]="showPassword ? 'text' : 'password'" placeholder="••••••••" formControlName="password" [attr.aria-invalid]="controlHasError('password')" /> |
|
|
<button type="button" class="eye-toggle" (click)="toggleConfirmPasswordVisibility()" tabindex="-1" aria-label="Show/Hide confirm password"> |
|
|
</button> |
|
|
<small *ngIf="controlHasError('password','required') && form.get('password')?.touched" class="error">Password is required.</small> |
|
|
<small *ngIf="controlHasError('password','minlength') && form.get('password')?.touched" class="error">Use at least 8 characters.</small> |
|
|
<small *ngIf="form.get('password')?.hasError('passwordPolicy') && form.get('password')?.touched" class="policy-info"> |
|
|
Create a strong password with at least 8 characters using letters, numbers, and special symbols. |
|
|
</small> |
|
|
</div> |
|
|
|
|
|
<div class="form-field" style="position:relative;"> |
|
|
<label for="confirmPassword">Confirm Password</label> |
|
|
<input id="confirmPassword" [type]="showConfirmPassword ? 'text' : 'password'" placeholder="••••••••" formControlName="confirmPassword" [attr.aria-invalid]="showPwdMismatch()" /> |
|
|
<button type="button" class="eye-toggle" (click)="toggleConfirmPasswordVisibility()" tabindex="-1" aria-label="Show/Hide confirm password"> |
|
|
</button> |
|
|
<small *ngIf="controlHasError('confirmPassword','required') && form.get('confirmPassword')?.touched" class="error">Confirm password is required.</small> |
|
|
<small *ngIf="showPwdMismatch() && form.get('confirmPassword')?.touched" class="error">Passwords do not match.</small> |
|
|
</div> |
|
|
</div> |
|
|
<div class="form-checkbox"> |
|
|
<input type="checkbox" id="terms" formControlName="terms" /> |
|
|
<label for="terms">Creating your account and you accepting <a href="#">Terms & Conditions.</a></label> |
|
|
</div> |
|
|
<div *ngIf="submitted && !form.get('terms')?.value" class="terms-info"> |
|
|
Please accept Terms & Conditions. |
|
|
</div> |
|
|
<button class="create-btn ai-pulse" type="submit" [disabled]="loading"> |
|
|
<ng-container *ngIf="!loading; else creatingAccount"> |
|
|
Create Account |
|
|
</ng-container> |
|
|
<ng-template #creatingAccount> |
|
|
<span class="spinner"></span> Creating Account... |
|
|
</ng-template> |
|
|
</button> |
|
|
|
|
|
|
|
|
|
|
|
<div class="google-signup-row"> |
|
|
<div id="google-signup-btn-div"> |
|
|
<div class="g-signin2" data-width="240" data-height="50" data-longtitle="true"></div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="create-footer"> |
|
|
<b> |
|
|
© {{ brand.name === 'Py-Learn' ? 'Pykara Technologies' : 'Majemaförlaget' }}, 2025. All rights reserved. |
|
|
</b> |
|
|
</div> |
|
|
</form> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div *ngIf="showInfo" class="info-popup-bg"> |
|
|
<div class="info-popup"> |
|
|
<button class="info-close" type="button" (click)="showInfo = false">×</button> |
|
|
<div class="info-title">Role Information</div> |
|
|
<div class="info-text"> |
|
|
<ul> |
|
|
<li><strong>Admin:</strong> Full control: users, roles, system settings.</li> |
|
|
<li><strong>Teachers:</strong> Run assessments / training evaluations.</li> |
|
|
<li><strong>Student:</strong> Access learning modules, exercises.</li> |
|
|
|
|
|
<li><strong>Others:</strong> General or limited access usage.</li> |
|
|
</ul> |
|
|
<p>Not sure? Select Others; an Admin can upgrade your role later.</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|