Enhance employee and qualification forms with hints and improved layouts
- Added hints to input fields in create and edit employee forms for better user guidance. - Updated the layout of dialog actions in employee and qualification forms for improved usability. - Enhanced delete confirmation dialogs for qualifications and employees with better styling and error handling. - Improved the display of employee details and qualifications with better formatting and structure. These changes aim to improve user experience and accessibility across the application.
This commit is contained in:
@ -6,12 +6,14 @@
|
||||
<mat-form-field class="!w-full">
|
||||
<mat-label>First Name</mat-label>
|
||||
<input matInput formControlName="firstName" required>
|
||||
<mat-hint>Enter the first name</mat-hint>
|
||||
<mat-error *ngIf="errors['firstName']">{{errors['firstName']}}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="!w-full">
|
||||
<mat-label>Last Name</mat-label>
|
||||
<input matInput formControlName="lastName" required>
|
||||
<mat-hint>Enter the last name</mat-hint>
|
||||
<mat-error *ngIf="errors['lastName']">{{errors['lastName']}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
@ -19,6 +21,7 @@
|
||||
<mat-form-field class="!w-full">
|
||||
<mat-label>Street</mat-label>
|
||||
<input matInput formControlName="street" required>
|
||||
<mat-hint>Enter the street address</mat-hint>
|
||||
<mat-error *ngIf="errors['street']">{{errors['street']}}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
@ -26,12 +29,14 @@
|
||||
<mat-form-field class="!w-full">
|
||||
<mat-label>City</mat-label>
|
||||
<input matInput formControlName="city" required>
|
||||
<mat-hint>Enter the city</mat-hint>
|
||||
<mat-error *ngIf="errors['city']">{{errors['city']}}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="!w-1/2">
|
||||
<mat-label>Postcode</mat-label>
|
||||
<input matInput formControlName="postcode" minlength="5" maxlength="5" type="number" required>
|
||||
<mat-hint>Enter postcode</mat-hint>
|
||||
<mat-error *ngIf="errors['postcode']">{{errors['postcode']}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
@ -39,11 +44,13 @@
|
||||
<mat-form-field class="!w-full">
|
||||
<mat-label>Phone</mat-label>
|
||||
<input matInput formControlName="phone" required>
|
||||
<mat-hint>Enter the phone number</mat-hint>
|
||||
<mat-error *ngIf="errors['phone']">{{errors['phone']}}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="!w-full">
|
||||
<mat-label>Qualifications</mat-label>
|
||||
<mat-hint>Select the qualifications</mat-hint>
|
||||
<mat-select formControlName="qualifications" multiple>
|
||||
<mat-option *ngFor="let qualification of qualifications" [value]="qualification.id">
|
||||
{{qualification.skill}}
|
||||
@ -52,9 +59,18 @@
|
||||
<mat-error *ngIf="errors['qualifications']">{{errors['qualifications']}}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-dialog-actions align="end">
|
||||
<button mat-button mat-dialog-close>Cancel</button>
|
||||
<button mat-flat-button color="primary" type="submit">Submit</button>
|
||||
<mat-dialog-actions align="end" class="!px-0 !mb-0 flex flex-col sm:flex-row w-full gap-3">
|
||||
<button mat-button
|
||||
mat-dialog-close
|
||||
class="text-sm md:text-base hover:bg-gray-100 py-2 px-6 rounded-md w-full sm:flex-1">
|
||||
Cancel
|
||||
</button>
|
||||
<button mat-flat-button
|
||||
color="primary"
|
||||
type="submit"
|
||||
class="!ml-0 text-sm md:text-base py-2 px-6 rounded-md w-full sm:flex-1">
|
||||
Submit
|
||||
</button>
|
||||
</mat-dialog-actions>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {Component, inject, OnInit} from '@angular/core';
|
||||
import {AbstractControl, FormBuilder, FormGroup, ReactiveFormsModule, Validators} from "@angular/forms";
|
||||
import {MatFormField, MatLabel} from "@angular/material/form-field";
|
||||
import {MatFormField, MatHint, MatLabel} from "@angular/material/form-field";
|
||||
import {MatError, MatInput} from "@angular/material/input";
|
||||
import {MatButton} from "@angular/material/button";
|
||||
import {
|
||||
@ -36,6 +36,7 @@ import {debounceTime} from "rxjs";
|
||||
MatSelect,
|
||||
NgForOf,
|
||||
MatError,
|
||||
MatHint
|
||||
],
|
||||
templateUrl: './create.component.html',
|
||||
standalone: true,
|
||||
|
@ -1,6 +1,33 @@
|
||||
<h2 mat-dialog-title>Delete {{employee.firstName}} {{employee.lastName}}</h2>
|
||||
<mat-dialog-content>Are you sure you want to delete {{employee.firstName}} {{employee.lastName}}? This cant be undone.</mat-dialog-content>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button [mat-dialog-close]="false">Cancel</button>
|
||||
<button mat-button mat-dialog-close (click)="deleteEmployee(employee.id ?? 0)" cdkFocusInitial>Delete</button>
|
||||
</mat-dialog-actions>
|
||||
<h2 mat-dialog-title class="text-xl md:text-2xl font-semibold text-gray-800 mb-3 md:mb-4">Delete Employee</h2>
|
||||
|
||||
<mat-dialog-content class="!px-3 md:!px-6">
|
||||
<div class="w-full min-w-[280px] md:min-w-[400px] space-y-4 md:space-y-6">
|
||||
<div class="bg-amber-50 p-3 md:p-4 rounded-lg border border-amber-200">
|
||||
<div class="flex items-start space-x-2 md:space-x-3">
|
||||
<mat-icon class="text-amber-600 text-xl md:text-2xl">warning</mat-icon>
|
||||
<div>
|
||||
<p class="text-gray-800 font-medium text-sm md:text-base">
|
||||
Are you sure you want to delete {{employee.firstName}} {{employee.lastName}}?
|
||||
</p>
|
||||
<p class="text-gray-600 mt-1 text-xs md:text-sm">This action cannot be undone.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-dialog-actions align="end" class="!px-0 !mb-0 flex flex-col sm:flex-row w-full gap-3">
|
||||
<button mat-button
|
||||
[mat-dialog-close]="false"
|
||||
class="text-sm md:text-base hover:bg-gray-100 py-2 px-6 rounded-md w-full sm:flex-1">
|
||||
Cancel
|
||||
</button>
|
||||
<button mat-flat-button
|
||||
color="warn"
|
||||
(click)="deleteEmployee(employee.id ?? 0)"
|
||||
mat-dialog-close
|
||||
class="!ml-0 text-sm md:text-base py-2 px-6 rounded-md w-full sm:flex-1"
|
||||
cdkFocusInitial>
|
||||
Delete
|
||||
</button>
|
||||
</mat-dialog-actions>
|
||||
</div>
|
||||
</mat-dialog-content>
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
MatDialogTitle
|
||||
} from "@angular/material/dialog";
|
||||
import {MatButton} from "@angular/material/button";
|
||||
import {MatIcon} from "@angular/material/icon";
|
||||
import EmployeeApiService from "../../services/employee-api.service";
|
||||
|
||||
@Component({
|
||||
@ -17,7 +18,8 @@ import EmployeeApiService from "../../services/employee-api.service";
|
||||
MatDialogTitle,
|
||||
MatDialogActions,
|
||||
MatButton,
|
||||
MatDialogClose
|
||||
MatDialogClose,
|
||||
MatIcon
|
||||
],
|
||||
templateUrl: './delete.component.html',
|
||||
standalone: true,
|
||||
|
@ -1,27 +1,68 @@
|
||||
<h2 mat-dialog-title>{{ employee.firstName }} {{ employee.lastName }}</h2>
|
||||
<h2 mat-dialog-title class="text-2xl font-semibold text-gray-800 mb-4">Employee Details</h2>
|
||||
|
||||
<mat-dialog-content>
|
||||
<div class="flex">
|
||||
<div class="flex-1">
|
||||
<p><strong>ID:</strong> {{ employee.id }}</p>
|
||||
<p><strong>First Name:</strong> {{ employee.firstName }}</p>
|
||||
<p><strong>Last Name:</strong> {{ employee.lastName }}</p>
|
||||
<p><strong>Phone:</strong> {{ employee.phone }}</p>
|
||||
<p><strong>Postcode:</strong> {{ employee.postcode }}</p>
|
||||
<p><strong>Street:</strong> {{ employee.street }}</p>
|
||||
<p><strong>City:</strong> {{ employee.city }}</p>
|
||||
<p><strong>Skills:</strong></p>
|
||||
<ul>
|
||||
@for (skill of employee.skillSet; track null) {
|
||||
<li> <strong>•</strong> {{skill.skill}}</li>
|
||||
<mat-dialog-content class="!px-4 sm:!px-6">
|
||||
<div class="w-full min-w-[280px] sm:min-w-[500px] space-y-6 sm:space-y-8">
|
||||
<div class="flex flex-col sm:flex-row items-center sm:items-start text-center sm:text-left space-y-4 sm:space-y-0 sm:space-x-4">
|
||||
<div class="h-20 w-20 sm:h-16 sm:w-16 rounded-full bg-blue-100 flex items-center justify-center flex-shrink-0">
|
||||
<span class="text-blue-600 text-2xl sm:text-xl font-medium">
|
||||
{{ employee.firstName?.charAt(0) ?? '' }}{{ employee.lastName?.charAt(0) ?? '' }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-xl font-medium text-gray-900">{{ employee.firstName }} {{ employee.lastName }}</h3>
|
||||
<p class="text-gray-500">ID: {{ employee.id }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3 sm:space-y-4">
|
||||
<h4 class="text-lg font-medium text-gray-900 mb-2 sm:mb-3">Contact Information</h4>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div class="space-y-1">
|
||||
<p class="text-sm text-gray-500">Phone</p>
|
||||
<p class="text-gray-900 break-all">{{ employee.phone }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3 sm:space-y-4">
|
||||
<h4 class="text-lg font-medium text-gray-900 mb-2 sm:mb-3">Address</h4>
|
||||
<div class="bg-gray-50 p-3 sm:p-4 rounded-lg space-y-3">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
|
||||
<div class="space-y-1">
|
||||
<p class="text-sm text-gray-500">Street</p>
|
||||
<p class="text-gray-900 break-words">{{ employee.street }}</p>
|
||||
</div>
|
||||
<div class="space-y-1">
|
||||
<p class="text-sm text-gray-500">City</p>
|
||||
<p class="text-gray-900">{{ employee.city }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-1">
|
||||
<p class="text-sm text-gray-500">Postcode</p>
|
||||
<p class="text-gray-900">{{ employee.postcode }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3 sm:space-y-4">
|
||||
<h4 class="text-lg font-medium text-gray-900 mb-2 sm:mb-3">Qualifications</h4>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
@for (skill of employee.skillSet; track skill.id) {
|
||||
<div class="bg-blue-50 text-blue-700 px-3 py-1 rounded-full text-sm font-medium">
|
||||
{{skill.skill}}
|
||||
</div>
|
||||
} @empty {
|
||||
<li><strong>-</strong></li>
|
||||
<p class="text-gray-500 italic">No qualifications added</p>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-dialog-content>
|
||||
|
||||
<mat-dialog-actions align="end" class="mt-4">
|
||||
<button mat-button (click)="closeModal()">Close</button>
|
||||
<mat-dialog-actions align="end" class="!px-4 sm:!px-6 !py-4 !mt-4 border-t">
|
||||
<button mat-button
|
||||
(click)="closeModal()"
|
||||
class="text-sm md:text-base hover:bg-gray-100 py-2 px-6 rounded-md w-full">
|
||||
Close
|
||||
</button>
|
||||
</mat-dialog-actions>
|
||||
|
@ -6,34 +6,40 @@
|
||||
<mat-form-field class="!w-full">
|
||||
<mat-label>First Name</mat-label>
|
||||
<input matInput formControlName="firstName" required>
|
||||
<mat-hint>Enter the first name</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="!w-full">
|
||||
<mat-label>Last Name</mat-label>
|
||||
<input matInput formControlName="lastName" required>
|
||||
<mat-hint>Enter the last name</mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<mat-form-field class="!w-full">
|
||||
<mat-label>Street</mat-label>
|
||||
<input matInput formControlName="street" required>
|
||||
<mat-hint>Enter the street address</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="flex gap-x-4">
|
||||
<mat-form-field class="!w-full">
|
||||
<mat-label>City</mat-label>
|
||||
<input matInput formControlName="city" required>
|
||||
<mat-hint>Enter the city</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="!w-1/2">
|
||||
<mat-label>Postcode</mat-label>
|
||||
<input matInput formControlName="postcode" minlength="5" maxlength="5" type="number" required>
|
||||
<mat-hint>Enter postcode</mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<mat-form-field class="!w-full">
|
||||
<mat-label>Phone</mat-label>
|
||||
<input matInput formControlName="phone" required>
|
||||
<mat-hint>Enter phone number</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="!w-full">
|
||||
@ -43,11 +49,21 @@
|
||||
{{qualification.skill}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-hint>Select qualifications</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-dialog-actions align="end">
|
||||
<button mat-button mat-dialog-close>Cancel</button>
|
||||
<button mat-flat-button color="primary" type="submit">Submit</button>
|
||||
<mat-dialog-actions align="end" class="!px-0 !mb-0 flex flex-col sm:flex-row w-full gap-3">
|
||||
<button mat-button
|
||||
mat-dialog-close
|
||||
class="text-sm md:text-base hover:bg-gray-100 py-2 px-6 rounded-md w-full sm:flex-1">
|
||||
Cancel
|
||||
</button>
|
||||
<button mat-flat-button
|
||||
color="primary"
|
||||
type="submit"
|
||||
class="!ml-0 text-sm md:text-base py-2 px-6 rounded-md w-full sm:flex-1">
|
||||
Submit
|
||||
</button>
|
||||
</mat-dialog-actions>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
MatDialogTitle
|
||||
} from "@angular/material/dialog";
|
||||
import {NgForOf, NgIf} from "@angular/common";
|
||||
import {MatFormField} from "@angular/material/form-field";
|
||||
import {MatFormField, MatHint} from "@angular/material/form-field";
|
||||
import {MatInput, MatLabel} from "@angular/material/input";
|
||||
import {MatButton} from "@angular/material/button";
|
||||
import {Employee} from "../Employee";
|
||||
@ -33,7 +33,8 @@ import {MatOption, MatSelect} from "@angular/material/select";
|
||||
MatLabel,
|
||||
MatSelect,
|
||||
MatOption,
|
||||
NgForOf
|
||||
NgForOf,
|
||||
MatHint
|
||||
],
|
||||
templateUrl: './edit.component.html',
|
||||
standalone: true,
|
||||
|
@ -14,7 +14,7 @@
|
||||
<div class="!overflow-x-auto !rounded-lg !bg-gray-50 !p-4">
|
||||
<table mat-table [dataSource]="employees" matSort class="!w-full">
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef class="!text-left"> Name</th>
|
||||
<th mat-header-cell *matHeaderCellDef class="!text-left !w-full"> Name</th>
|
||||
<td mat-cell *matCellDef="let employee" class="!py-4">
|
||||
<div class="!flex !items-center">
|
||||
<div class="!h-10 !w-10 !rounded-full !bg-blue-100 !flex !items-center !justify-center !mr-3">
|
||||
@ -35,16 +35,22 @@
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef class="!text-right"> Actions</th>
|
||||
<td mat-cell *matCellDef="let employee" class="!text-right !py-4">
|
||||
<button mat-icon-button color="primary" [matTooltip]="'Edit employee'" class="!mr-2"
|
||||
(click)="showEditEmployeeModal(employee)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button color="warn" [matTooltip]="'Delete employee'"
|
||||
(click)="openDeleteDialogue(employee)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
<th mat-header-cell *matHeaderCellDef class="!text-right !w-[120px]"> Actions</th>
|
||||
<td mat-cell *matCellDef="let employee" class="!text-right !py-4 !whitespace-nowrap">
|
||||
<div class="!flex !justify-end !items-center !gap-1">
|
||||
<button mat-icon-button
|
||||
color="primary"
|
||||
[matTooltip]="'Edit employee'"
|
||||
(click)="showEditEmployeeModal(employee)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button
|
||||
color="warn"
|
||||
[matTooltip]="'Delete employee'"
|
||||
(click)="openDeleteDialogue(employee)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
Reference in New Issue
Block a user