//html <div class="register-wrapper d-flex justify-content-center align-items-center"> <div class="card box"> <div class="card-header text-center"> <h4 class="card-title">Sign-up</h4> </div> <form class="form" [formGroup]="registerFormGroup" (ngSubmit)="RegisterUser()"> <div class="card-body"> <div class="row"> <div class="col-md-6"> <div class="form-group"> <label for="name" class="form-label">Name</label> <input type="text" class="form-control" id="name" placeholder="Enter your Name" formControlName="name"> <div *ngIf="registerFormGroup.controls['name'].invalid && (registerFormGroup.controls['name'].dirty || registerFormGroup.controls['name'].touched)" class="text-danger"> <div *ngIf="registerFormGroup.controls['name'].errors?.['required']">Name is required.</div> <div *ngIf="registerFormGroup.controls['name'].errors?.['minlength']">Name must be at least 2 characters long.</div> <div *ngIf="registerFormGroup.controls['name'].errors?.['maxlength']">Name must be at most 20 characters long.</div> </div> </div> <div class="form-group"> <label for="surname" class="form-label">Surname</label> <input type="text" class="form-control" id="surname" placeholder="Enter your Surname" formControlName="surname"> <div *ngIf="registerFormGroup.controls['surname'].invalid && (registerFormGroup.controls['surname'].dirty || registerFormGroup.controls['surname'].touched)" class="text-danger"> <div *ngIf="registerFormGroup.controls['surname'].errors?.['required']">Surname is required.</div> <div *ngIf="registerFormGroup.controls['surname'].errors?.['minlength']">Surname must be at least 2 characters long.</div> <div *ngIf="registerFormGroup.controls['surname'].errors?.['maxlength']">Surname must be at most 20 characters long.</div> </div> </div> <div class="form-group"> <label for="email" class="form-label">Email Address</label> <input type="email" class="form-control" id="email" placeholder="Enter a valid Email address" formControlName="email"> <div *ngIf="registerFormGroup.controls['email'].invalid && (registerFormGroup.controls['email'].dirty || registerFormGroup.controls['email'].touched)" class="text-danger"> <div *ngIf="registerFormGroup.controls['email'].errors?.['required']">Email is required.</div> <div *ngIf="registerFormGroup.controls['email'].errors?.['email']">Email is invalid.</div> </div> </div> <div class="form-group"> <label for="password" class="form-label">Password</label> <input type="password" class="form-control" id="password" placeholder="Enter between 8 to 15 characters" formControlName="password"> <div *ngIf="registerFormGroup.controls['password'].invalid && (registerFormGroup.controls['password'].dirty || registerFormGroup.controls['password'].touched)" class="text-danger"> <div *ngIf="registerFormGroup.controls['password'].errors?.['required']">Password is required.</div> <div *ngIf="registerFormGroup.controls['password'].errors?.['minlength']">Password must be at least 8 characters.</div> <div *ngIf="registerFormGroup.controls['password'].errors?.['maxlength']">Password cannot be more than 15 characters.</div> </div> </div> <div class="form-group"> <label for="PhoneNumber" class="form-label">Phone Number</label> <input type="text" class="form-control" id="PhoneNumber" placeholder="Enter your Phone Number" formControlName="PhoneNumber"> <div *ngIf="registerFormGroup.controls['PhoneNumber'].invalid && (registerFormGroup.controls['PhoneNumber'].dirty || registerFormGroup.controls['PhoneNumber'].touched)" class="text-danger"> <div *ngIf="registerFormGroup.controls['PhoneNumber'].errors?.['required']">Phone Number is required.</div> <div *ngIf="registerFormGroup.controls['PhoneNumber'].errors?.['minlength']">Phone Number must be 10 digits.</div> <div *ngIf="registerFormGroup.controls['PhoneNumber'].errors?.['maxlength']">Phone Number must be 10 digits.</div> </div> </div> </div> <div class="col-md-6"> <div class="form-group"> <label for="Date_of_Birth" class="form-label">Date of Birth</label> <input type="date" class="form-control" id="Date_of_Birth" placeholder="Enter your Date of Birth" formControlName="Date_of_Birth"> <div *ngIf="registerFormGroup.controls['Date_of_Birth'].invalid && (registerFormGroup.controls['Date_of_Birth'].dirty || registerFormGroup.controls['Date_of_Birth'].touched)" class="text-danger"> <div *ngIf="registerFormGroup.controls['Date_of_Birth'].errors?.['required']">Date of Birth is required.</div> <div *ngIf="registerFormGroup.controls['Date_of_Birth'].errors?.['futureDate']">Date of birth cannot be a future date.</div> <div *ngIf="registerFormGroup.controls['Date_of_Birth'].errors?.['olderThan100']">Date of birth cannot be more than 100 years ago.</div> <div *ngIf="registerFormGroup.controls['Date_of_Birth'].errors?.['futureYear']">User cannot be younger than 16.</div> </div> </div> <div class="form-group"> <label for="Id_Number" class="form-label">ID Number</label> <input type="text" class="form-control" id="Id_Number" placeholder="Enter your ID Number" formControlName="Id_Number"> <div *ngIf="registerFormGroup.controls['Id_Number'].invalid && (registerFormGroup.controls['Id_Number'].dirty || registerFormGroup.controls['Id_Number'].touched)" class="text-danger"> <div *ngIf="registerFormGroup.controls['Id_Number'].errors?.['required']">ID Number is required.</div> <div *ngIf="registerFormGroup.controls['Id_Number'].errors?.['minlength']">ID Number must be 13 digits.</div> <div *ngIf="registerFormGroup.controls['Id_Number'].errors?.['maxlength']">ID Number must be 13 digits.</div> </div> </div> <div class="form-group"> <label for="Physical_Address" class="form-label">Physical Address</label> <input type="text" class="form-control" id="Physical_Address" placeholder="Enter your Physical Address" formControlName="Physical_Address"> <div *ngIf="registerFormGroup.controls['Physical_Address'].invalid && (registerFormGroup.controls['Physical_Address'].dirty || registerFormGroup.controls['Physical_Address'].touched)" class="text-danger"> <div *ngIf="registerFormGroup.controls['Physical_Address'].errors?.['required']">Physical Address is required.</div> <div *ngIf="registerFormGroup.controls['Physical_Address'].errors?.['minlength']">Physical Address must be at least 7 characters long.</div> <div *ngIf="registerFormGroup.controls['Physical_Address'].errors?.['maxlength']">Physical Address must be at most 100 characters long.</div> </div> </div> <div class="form-group"> <label for="Photo" class="form-label">Photo</label> <input type="file" class="form-control" id="Photo" (change)="onFileSelected($event)"> <div *ngIf="registerFormGroup.controls['Photo'].invalid && (registerFormGroup.controls['Photo'].dirty || registerFormGroup.controls['Photo'].touched)" class="text-danger"> <div *ngIf="registerFormGroup.controls['Photo'].errors?.['required']">Photo is required.</div> </div> </div> <div class="form-group"> <label for="User_Type_ID" class="form-label">User Type</label> <select class="form-control" id="User_Type_ID" formControlName="User_Type_ID"> <option value="1">Owner</option> <option value="2">Employee</option> <option value="3">Member</option> </select> <div *ngIf="registerFormGroup.controls['User_Type_ID'].invalid && (registerFormGroup.controls['User_Type_ID'].dirty || registerFormGroup.controls['User_Type_ID'].touched)" class="text-danger"> <div *ngIf="registerFormGroup.controls['User_Type_ID'].errors?.['required']">User Type is required.</div> </div> </div> </div> </div> </div> <div class="card-footer d-flex justify-content-between"> <button type="submit" class="btn btn-primary">Sign-up</button> <button type="button" class="btn btn-secondary" (click)="resetForm()">Cancel</button> </div> </form> </div> </div> //ts import { Component } from '@angular/core'; import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { Router } from '@angular/router'; import { MatSnackBar } from '@angular/material/snack-bar'; import { UserService } from '../../Services/userprofile.service'; import { FlexLayoutModule } from '@angular/flex-layout'; import { CommonModule } from '@angular/common'; @Component({ selector: 'app-register', standalone: true, imports: [ReactiveFormsModule, CommonModule, FlexLayoutModule], templateUrl: './register.component.html', styleUrls: ['./register.component.css'] }) export class RegisterComponent { submitted = false; registerFormGroup: FormGroup; selectedFile: File | null = null; constructor( private router: Router, private userService: UserService, private fb: FormBuilder, private snackBar: MatSnackBar ) { this.registerFormGroup = this.fb.group({ // email: ['', [Validators.required, Validators.email, Validators.pattern(/^[a-z0-9._%+-]+@gmail\.com$/), Validators.minLength(3), Validators.maxLength(50)]], email: ['', [Validators.required, Validators.email]], password: ['', [Validators.required, Validators.minLength(8), Validators.maxLength(15)]], name: ['', [Validators.required, Validators.minLength(2), Validators.maxLength(20)]], surname: ['', [Validators.required, Validators.minLength(2), Validators.maxLength(20)]], // PhoneNumber: ['', [Validators.required, Validators.pattern(/^0\d{9}$/)]], PhoneNumber: ['', [Validators.required, Validators.minLength(10), Validators.maxLength(10)]], Date_of_Birth: ['', [Validators.required, this.validateDateOfBirth]], // Id_Number: ['', [Validators.required, Validators.pattern(/^\d{2}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])\d{7}$/)]], Id_Number: ['', [Validators.required, Validators.minLength(13), Validators.maxLength(13)]], Physical_Address: ['', [Validators.required, Validators.minLength(7), Validators.maxLength(100)]], Photo: ['', Validators.required], // User_Status_ID: [1, [Validators.required, Validators.min(1), Validators.max(2)]], // User_Type_ID: ['', [Validators.required, Validators.min(1), Validators.max(3)]] User_Status_ID: [1, Validators.required], User_Type_ID: ['', Validators.required] }); } ngOnInit() { } validateDateOfBirth(control: any): { [key: string]: any } | null { const selectedDate = new Date(control.value); const currentDate = new Date(); const minDate = new Date(currentDate.getFullYear() - 100, currentDate.getMonth(), currentDate.getDate()); const maxDate = new Date(currentDate.getFullYear() - 16, currentDate.getMonth(), currentDate.getDate()); if (selectedDate > currentDate) { return { 'futureDate': true }; } if (selectedDate < minDate) { return { 'olderThan100': true }; } if (selectedDate > maxDate) { return { 'futureYear': true }; } return null; } onFileSelected(event: any) { const file = event.target.files[0]; if (file) { this.selectedFile = file; this.registerFormGroup.patchValue({ Photo: file }); } else { this.selectedFile = null; } } RegisterUser() { this.submitted = true; if (this.registerFormGroup.valid && this.selectedFile) { console.log('Form is valid'); console.log('Selected file:', this.selectedFile); const emailLowerCase = this.registerFormGroup.value.email.toLowerCase(); this.registerFormGroup.patchValue({ email: emailLowerCase }); const formData: FormData = new FormData(); formData.append('name', this.registerFormGroup.value.name); formData.append('surname', this.registerFormGroup.value.surname); formData.append('email', this.registerFormGroup.value.email); formData.append('password', this.registerFormGroup.value.password); formData.append('PhoneNumber', this.registerFormGroup.value.PhoneNumber); formData.append('Date_of_Birth', this.registerFormGroup.value.Date_of_Birth); formData.append('Id_Number', this.registerFormGroup.value.Id_Number); formData.append('Physical_Address', this.registerFormGroup.value.Physical_Address); formData.append('Photo', this.selectedFile, this.selectedFile.name); formData.append('User_Status_ID', this.registerFormGroup.value.User_Status_ID); formData.append('User_Type_ID', this.registerFormGroup.value.User_Type_ID); this.userService.RegisterUser(formData).subscribe({ next: (response) => { console.log('Registration Success:', response); this.registerFormGroup.reset(); this.openSnackbar('Your user profile has been created', 'success'); this.router.navigate(['/login']); }, error: (error) => { console.log('Registration Error:', error); let errorMessage = 'Registration failed: '; if (error.error === 'DuplicateEmail') { errorMessage += 'This email address is already registered.'; } else if (error.error === 'DuplicatePhoneNumber') { errorMessage += 'This phone number is already registered.'; } else if (error.error === 'DuplicateDateOfBirth') { errorMessage += 'This date of birth is already registered.'; } else if (error.error === 'DuplicateIdNumber') { errorMessage += 'This ID number is already registered.'; } else if (error.error === 'DuplicatePhoto') { errorMessage += 'This photo is already associated with another user.'; } else { errorMessage += 'Unknown error. Please try again later.'; } this.openSnackbar(errorMessage, 'danger'); } }); } else { console.log('Form is not valid or file is not selected'); console.log(this.registerFormGroup.errors); console.log(this.registerFormGroup.controls); this.openSnackbar('Form is not filled in correctly', 'danger'); } } openSnackbar(message: string, type: 'success' | 'danger') { this.snackBar.open(message, 'Close', { duration: 5000, panelClass: type === 'success' ? 'snackbar-success' : 'snackbar-danger' }); } get f() { return this.registerFormGroup.controls; } resetForm() { this.registerFormGroup.reset({ user_status_id: 1 // Reset user_status_id to default value of 1 (Active) }); this.router.navigate(['/login']); } } //css .register-wrapper { height: 100%; display: flex; justify-content: center; align-items: center; background: #f0f4f7; /* Light blue background */ } .box { padding: 60px 50px 40px; width: 100%; max-width: 800px; background: #fff; border-radius: 10px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); } .card-header { text-align: center; font-weight: 700; color: #000; /* Blue color for header text */ } .card-title { font-size: 30px; margin: 0; } .form-group label { color: #000; /* Blue color for form labels */ } .form-control { border: 1px solid #ccc; padding: 10px; border-radius: 5px; transition: border-color 0.3s ease-in-out; } .form-control:focus { border-color: #000; /* Blue border on focus */ box-shadow: 0 0 5px rgba(63, 81, 181, 0.2); /* Light blue shadow on focus */ } .text-danger { color: #f44336; /* Red color for error messages */ } .btn-primary { background-color: #4caf50; /* Green background for primary button */ border-color: #4caf50; /* Green border for primary button */ color: #fff; /* White text for primary button */ } .btn-secondary { background-color: #f44336; /* Red background for secondary button */ border-color: #f44336; /* Red border for secondary button */ color: #fff; /* White text for secondary button */ } .card-footer { display: flex; justify-content: space-between; padding: 20px; } .card-footer .btn { width: 48%; } /* Snackbar Styles */ .snackbar { visibility: visible; min-width: 250px; margin-left: -125px; background-color: #333; color: #fff; text-align: center; border-radius: 2px; padding: 16px; position: fixed; z-index: 1; left: 50%; bottom: 30px; font-size: 17px; } .snackbar-success { background-color: #4caf50; /* Green for success */ } .snackbar-danger { background-color: #f44336; /* Red for error */ } .close-snackbar { color: white; font-weight: bold; float: right; font-size: 22px; line-height: 20px; cursor: pointer; background: none; border: none; }
Preview:
downloadDownload PNG
downloadDownload JPEG
downloadDownload SVG
Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!
Click to optimize width for Twitter