Preview:
//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]="registerForm" (ngSubmit)="RegisterEmployee()">
        <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="registerForm.controls['Name'].invalid && (registerForm.controls['Name'].dirty || registerForm.controls['Name'].touched)" class="text-danger">
                  <div *ngIf="registerForm.controls['Name'].errors?.['required']">Name is required.</div>
                  <div *ngIf="registerForm.controls['Name'].errors?.['minlength']">Name must be at least 2 characters long.</div>
                  <div *ngIf="registerForm.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="registerForm.controls['Surname'].invalid && (registerForm.controls['Surname'].dirty || registerForm.controls['Surname'].touched)" class="text-danger">
                  <div *ngIf="registerForm.controls['Surname'].errors?.['required']">Surname is required.</div>
                  <div *ngIf="registerForm.controls['Surname'].errors?.['minlength']">Surname must be at least 2 characters long.</div>
                  <div *ngIf="registerForm.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="registerForm.controls['Email'].invalid && (registerForm.controls['Email'].dirty || registerForm.controls['Email'].touched)" class="text-danger">
                  <div *ngIf="registerForm.controls['Email'].errors?.['required']">Email is required.</div>
                  <div *ngIf="registerForm.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="registerForm.controls['Password'].invalid && (registerForm.controls['Password'].dirty || registerForm.controls['Password'].touched)" class="text-danger">
                  <div *ngIf="registerForm.controls['Password'].errors?.['required']">Password is required.</div>
                  <div *ngIf="registerForm.controls['Password'].errors?.['minlength']">Password must be at least 8 characters.</div>
                  <div *ngIf="registerForm.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="registerForm.controls['PhoneNumber'].invalid && (registerForm.controls['PhoneNumber'].dirty || registerForm.controls['PhoneNumber'].touched)" class="text-danger">
                  <div *ngIf="registerForm.controls['PhoneNumber'].errors?.['required']">Phone Number is required.</div>
                  <div *ngIf="registerForm.controls['PhoneNumber'].errors?.['pattern']">Phone Number format invalid.</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="registerForm.controls['Date_of_Birth'].invalid && (registerForm.controls['Date_of_Birth'].dirty || registerForm.controls['Date_of_Birth'].touched)" class="text-danger">
                  <div *ngIf="registerForm.controls['Date_of_Birth'].errors?.['required']">Date of Birth is required.</div>
                  <div *ngIf="registerForm.controls['Date_of_Birth'].errors?.['futureDate']">Date of birth cannot be a future date.</div>
                  <div *ngIf="registerForm.controls['Date_of_Birth'].errors?.['olderThan100']">Date of birth cannot be more than 100 years ago.</div>
                  <div *ngIf="registerForm.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="registerForm.controls['Id_Number'].invalid && (registerForm.controls['Id_Number'].dirty || registerForm.controls['Id_Number'].touched)" class="text-danger">
                  <div *ngIf="registerForm.controls['Id_Number'].errors?.['required']">ID Number is required.</div>
                  <div *ngIf="registerForm.controls['Id_Number'].errors?.['pattern']">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="registerForm.controls['Physical_Address'].invalid && (registerForm.controls['Physical_Address'].dirty || registerForm.controls['Physical_Address'].touched)" class="text-danger">
                  <div *ngIf="registerForm.controls['Physical_Address'].errors?.['required']">Physical Address is required.</div>
                  <div *ngIf="registerForm.controls['Physical_Address'].errors?.['minlength']">Physical Address must be at least 7 characters long.</div>
                  <div *ngIf="registerForm.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)="onFileChange($event)">
              </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">Cancel</button>
        </div>
      </form>
    </div>
  </div>
//ts
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { FlexLayoutModule } from '@angular/flex-layout';
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { MatSnackBar } from '@angular/material/snack-bar';
import { Router } from '@angular/router';
import { UserService } from '../Services/userprofile.service';

@Component({
  selector: 'app-register-employee',
  standalone: true,
  imports: [ReactiveFormsModule, CommonModule, FlexLayoutModule],
  templateUrl: './register-employee.component.html',
  styleUrl: './register-employee.component.css'
})
export class RegisterEmployeeComponent {
  registerForm: FormGroup;
  selectedFile: File | null = null;

  constructor(
    private router: Router,
    private userService: UserService,
    private fb: FormBuilder,
    private snackBar: MatSnackBar
  ) {
    this.registerForm = this.fb.group({
      Name: ['', [Validators.required, Validators.minLength(2), Validators.maxLength(20)]],
      Surname: ['', [Validators.required, Validators.minLength(2), Validators.maxLength(20)]],
      Email: ['', [Validators.required, Validators.email]],
      Physical_Address: ['', [Validators.required, Validators.minLength(7), Validators.maxLength(100)]],
      PhoneNumber: ['', [Validators.required, Validators.pattern('^\\d{10}$')]],
      Password: ['', [Validators.required, Validators.minLength(8), Validators.maxLength(15)]],
      Id_Number: ['', [Validators.required, Validators.pattern('^\\d{13}$')]],
      Date_of_Birth: ['', [Validators.required, this.validateDateOfBirth]],
      User_Status_ID: [1, Validators.required],
      User_Type_ID: [2, Validators.required],
      Employment_Date: [new Date(), Validators.required],
      Hours_Worked: [0, Validators.required],
      Employee_Type_ID: [1, Validators.required],
      Shift_ID: [null]
    });    
  }

  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;
  }
  

  onFileChange(event: any) {
    this.selectedFile = event.target.files[0];
  }

  RegisterEmployee() {
    if (this.registerForm.invalid) {
      return;
    }

    if (!this.selectedFile) {
      this.snackBar.open('Photo is required', 'Close', { duration: 3000 });
      return;
    }

    const formValues = this.registerForm.value;
    formValues.Date_of_Birth = new Date(formValues.Date_of_Birth).toISOString();

    this.userService.registerEmployee(this.registerForm.value, this.selectedFile).subscribe({
      next: (response) => {
        console.log('Registration Success:', response);
        this.snackBar.open('Employee registered successfully', 'Close', { duration: 3000 });
        this.registerForm.reset();
        this.selectedFile = null;
        this.router.navigate(['/login']);
      },
      error: (error) => {
        console.log('Registration Error:', error);
        this.snackBar.open('Failed to register employee', 'Close', { duration: 3000 });
      }
    });
  }
}

//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;
  }
  
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