style: format code and improve readability across files
This commit is contained in:
@ -1,118 +1,170 @@
|
||||
<section class="!space-y-6 mb-6">
|
||||
@defer {
|
||||
@if (qualifications$ | async; as qualifications) {
|
||||
<div class="!space-y-6">
|
||||
<div class="!flex !justify-between !items-center">
|
||||
<div class="!flex !items-center !gap-4">
|
||||
<h2 class="!text-2xl !font-semibold !text-gray-900 !shrink-0">Qualifications</h2>
|
||||
<mat-form-field class="!m-0" subscriptSizing="dynamic">
|
||||
<mat-icon matPrefix class="!text-gray-400 !mr-2">search</mat-icon>
|
||||
<input matInput
|
||||
type="text"
|
||||
placeholder="Search qualifications..."
|
||||
(keyup)="filterQualifications($event)">
|
||||
<div matSuffix class="!w-[24px] !h-[24px] !ml-2 !flex !items-center !justify-center">
|
||||
<mat-progress-spinner [diameter]="20" mode="indeterminate"
|
||||
[class.!opacity-0]="!isSearching"
|
||||
[class.!opacity-100]="isSearching"
|
||||
class="!transition-opacity"></mat-progress-spinner>
|
||||
</div>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<button mat-flat-button color="primary" class="!bg-blue-600 !text-white !shrink-0"
|
||||
(click)="openCreateModal()">
|
||||
<mat-icon class="!mr-2">add</mat-icon>
|
||||
Add Qualification
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@if (qualifications) {
|
||||
<div class="!overflow-x-auto !rounded-lg !bg-gray-50 !p-4">
|
||||
<table mat-table [dataSource]="qualifications" matSort class="!w-full">
|
||||
<ng-container matColumnDef="skill">
|
||||
<th mat-header-cell *matHeaderCellDef class="!text-left !w-full">Skill</th>
|
||||
<td mat-cell *matCellDef="let qualification" 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">
|
||||
<span class="!text-blue-600 !font-medium">
|
||||
{{ qualification.skill[0]?.toUpperCase() }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<a class="!text-blue-600 hover:!underline cursor-pointer"
|
||||
[matTooltip]="'Click to view qualification details'"
|
||||
(click)="openDetailsModal(qualification)">
|
||||
{{ qualification.skill }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef class="!text-right !w-[120px]">Actions</th>
|
||||
<td mat-cell *matCellDef="let qualification" class="!text-right !py-4 !whitespace-nowrap">
|
||||
<div class="!flex !justify-end !items-center !gap-1">
|
||||
<button mat-icon-button
|
||||
color="primary"
|
||||
[matTooltip]="'Edit qualification'"
|
||||
(click)="openEditModal(qualification)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button
|
||||
color="warn"
|
||||
[matTooltip]="'Delete qualification'"
|
||||
(click)="openDeleteModal(qualification.id)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
</div>
|
||||
} @else {
|
||||
<mat-card class="!text-center !py-8">
|
||||
<mat-card-content>
|
||||
<mat-icon class="!w-8 !h-8 !text-gray-400 !mb-4">school</mat-icon>
|
||||
<p class="!text-gray-600">No qualifications found</p>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
} @placeholder {
|
||||
<div class="!space-y-6">
|
||||
<div class="!animate-pulse">
|
||||
<div class="!flex !justify-between !items-center !mb-8">
|
||||
<div class="!h-8 !bg-gray-200 !rounded !w-1/4"></div>
|
||||
<div class="!h-10 !bg-gray-200 !rounded !w-32"></div>
|
||||
</div>
|
||||
<div class="!bg-gray-50 !p-4 !rounded-lg">
|
||||
<div class="!space-y-4">
|
||||
<div class="!h-10 !bg-gray-200 !rounded"></div>
|
||||
@for (i of [1, 2, 3]; track i) {
|
||||
<div class="!h-16 !bg-white !rounded-lg !shadow-sm"></div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
} @error {
|
||||
<div class="bg-red-50 p-3 md:p-4 rounded-lg border border-red-200">
|
||||
<div class="flex items-start space-x-2 md:space-x-3">
|
||||
<mat-icon class="text-red-600 text-xl md:text-2xl !w-8 !h-8">error</mat-icon>
|
||||
<div>
|
||||
<p class="text-gray-800 font-medium text-sm md:text-base">There was an error loading the qualifications.</p>
|
||||
<p class="text-gray-600 mt-1 text-xs md:text-sm">Please try refreshing the page.</p>
|
||||
@defer {
|
||||
@if (qualifications$ | async; as qualifications) {
|
||||
<div class="!space-y-6">
|
||||
<div class="!flex !justify-between !items-center">
|
||||
<div class="!flex !items-center !gap-4">
|
||||
<h2 class="!text-2xl !font-semibold !text-gray-900 !shrink-0">
|
||||
Qualifications
|
||||
</h2>
|
||||
<mat-form-field class="!m-0" subscriptSizing="dynamic">
|
||||
<mat-icon matPrefix class="!text-gray-400 !mr-2">search</mat-icon>
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
placeholder="Search qualifications..."
|
||||
(keyup)="filterQualifications($event)"
|
||||
/>
|
||||
<div
|
||||
matSuffix
|
||||
class="!w-[24px] !h-[24px] !ml-2 !flex !items-center !justify-center"
|
||||
>
|
||||
<mat-progress-spinner
|
||||
[diameter]="20"
|
||||
mode="indeterminate"
|
||||
[class.!opacity-0]="!isSearching"
|
||||
[class.!opacity-100]="isSearching"
|
||||
class="!transition-opacity"
|
||||
></mat-progress-spinner>
|
||||
</div>
|
||||
</div>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
} @loading {
|
||||
<div class="!flex !justify-center !items-center !py-12">
|
||||
<mat-spinner diameter="48" class="!text-blue-600"></mat-spinner>
|
||||
<button
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
class="!bg-blue-600 !text-white !shrink-0"
|
||||
(click)="openCreateModal()"
|
||||
>
|
||||
<mat-icon class="!mr-2">add</mat-icon>
|
||||
Add Qualification
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@if (qualifications) {
|
||||
<div class="!overflow-x-auto !rounded-lg !bg-gray-50 !p-4">
|
||||
<table
|
||||
mat-table
|
||||
[dataSource]="qualifications"
|
||||
matSort
|
||||
class="!w-full"
|
||||
>
|
||||
<ng-container matColumnDef="skill">
|
||||
<th
|
||||
mat-header-cell
|
||||
*matHeaderCellDef
|
||||
class="!text-left !w-full"
|
||||
>
|
||||
Skill
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let qualification" 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"
|
||||
>
|
||||
<span class="!text-blue-600 !font-medium">
|
||||
{{ qualification.skill[0]?.toUpperCase() }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
class="text-blue-600 hover:underline cursor-pointer"
|
||||
[matTooltip]="'View qualification details'"
|
||||
(click)="openDetailsModal(qualification)"
|
||||
(keydown.enter)="openDetailsModal(qualification)"
|
||||
>
|
||||
{{ qualification.skill }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th
|
||||
mat-header-cell
|
||||
*matHeaderCellDef
|
||||
class="!text-right !w-[120px]"
|
||||
>
|
||||
Actions
|
||||
</th>
|
||||
<td
|
||||
mat-cell
|
||||
*matCellDef="let qualification"
|
||||
class="!text-right !py-4 !whitespace-nowrap"
|
||||
>
|
||||
<div class="!flex !justify-end !items-center !gap-1">
|
||||
<button
|
||||
mat-icon-button
|
||||
color="primary"
|
||||
[matTooltip]="'Edit qualification'"
|
||||
(click)="openEditModal(qualification)"
|
||||
(keydown.enter)="openEditModal(qualification)"
|
||||
>
|
||||
<mat-icon>edit</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
mat-icon-button
|
||||
color="warn"
|
||||
[matTooltip]="'Delete qualification'"
|
||||
(click)="openDeleteModal(qualification.id)"
|
||||
(keydown.enter)="openDeleteModal(qualification.id)"
|
||||
>
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
} @else {
|
||||
<mat-card class="!text-center !py-8">
|
||||
<mat-card-content>
|
||||
<mat-icon class="!w-8 !h-8 !text-gray-400 !mb-4">school</mat-icon>
|
||||
<p class="!text-gray-600">No qualifications found</p>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
} @placeholder {
|
||||
<div class="!space-y-6">
|
||||
<div class="!animate-pulse">
|
||||
<div class="!flex !justify-between !items-center !mb-8">
|
||||
<div class="!h-8 !bg-gray-200 !rounded !w-1/4"></div>
|
||||
<div class="!h-10 !bg-gray-200 !rounded !w-32"></div>
|
||||
</div>
|
||||
<div class="!bg-gray-50 !p-4 !rounded-lg">
|
||||
<div class="!space-y-4">
|
||||
<div class="!h-10 !bg-gray-200 !rounded"></div>
|
||||
@for (i of [1, 2, 3]; track i) {
|
||||
<div class="!h-16 !bg-white !rounded-lg !shadow-sm"></div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
} @error {
|
||||
<div class="bg-red-50 p-3 md:p-4 rounded-lg border border-red-200">
|
||||
<div class="flex items-start space-x-2 md:space-x-3">
|
||||
<mat-icon class="text-red-600 text-xl md:text-2xl !w-8 !h-8"
|
||||
>error</mat-icon
|
||||
>
|
||||
<div>
|
||||
<p class="text-gray-800 font-medium text-sm md:text-base">
|
||||
There was an error loading the qualifications.
|
||||
</p>
|
||||
<p class="text-gray-600 mt-1 text-xs md:text-sm">
|
||||
Please try refreshing the page.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
} @loading {
|
||||
<div class="!flex !justify-center !items-center !py-12">
|
||||
<mat-spinner diameter="48" class="!text-blue-600"></mat-spinner>
|
||||
</div>
|
||||
}
|
||||
</section>
|
||||
|
Reference in New Issue
Block a user