3 Commits

Author SHA1 Message Date
ca893507c6 feat: add logout button and update title in header 2025-01-23 12:59:59 +01:00
64d8ce5837 add no data found messages (#49)
Reviewed-on: http://git.simonis.lol/angular/ems-frontend/pulls/49
Reviewed-by: Constantin Simonis <constantin@simonis.lol>
Co-authored-by: Jan-Marlon Leibl <jleibl@proton.me>
Co-committed-by: Jan-Marlon Leibl <jleibl@proton.me>
2025-01-23 11:46:45 +00:00
eac3d9c834 remove unused css files and styleUrl properties from components (#48)
Reviewed-on: http://git.simonis.lol/angular/ems-frontend/pulls/48
Co-authored-by: Jan-Marlon Leibl <jleibl@proton.me>
Co-committed-by: Jan-Marlon Leibl <jleibl@proton.me>
2025-01-23 11:39:26 +00:00
29 changed files with 78 additions and 104 deletions

View File

@ -1,4 +1,10 @@
<main class="container mx-auto px-4 py-8 max-w-6xl">
<h1 class="text-3xl font-bold text-gray-900 mb-8">{{ title }}</h1>
<div class="flex justify-between items-center mb-8">
<h1 class="text-3xl font-extrabold text-gray-900">{{ title }}</h1>
<button mat-flat-button class="!bg-red-600 !text-white" (click)="logout()">
<mat-icon>logout</mat-icon>
<span class="ml-1">Logout</span>
</button>
</div>
<router-outlet></router-outlet>
</main>

View File

@ -1,14 +1,22 @@
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterOutlet } from '@angular/router';
import { AuthService } from './services/auth.service';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
@Component({
selector: 'app-root',
imports: [CommonModule, RouterOutlet],
imports: [CommonModule, RouterOutlet, MatButtonModule, MatIconModule],
templateUrl: './app.component.html',
standalone: true,
styleUrl: './app.component.css',
})
export class AppComponent {
title = 'Employee Management System';
constructor(private authService: AuthService) {}
logout(): void {
this.authService.logout();
}
}

View File

@ -46,7 +46,6 @@ import { debounceTime } from 'rxjs';
],
templateUrl: './create.component.html',
standalone: true,
styleUrl: './create.component.css',
})
export class CreateComponent implements OnInit {
employeeForm!: FormGroup;

View File

@ -24,7 +24,6 @@ import EmployeeApiService from '../../services/employee-api.service';
],
templateUrl: './delete.component.html',
standalone: true,
styleUrl: './delete.component.css',
})
export class DeleteComponent {
private apiService: EmployeeApiService = inject(EmployeeApiService);

View File

@ -14,7 +14,6 @@ import { DialogRef } from '@angular/cdk/dialog';
imports: [MatDialogTitle, MatDialogContent, MatButton, MatDialogActions],
templateUrl: './details.component.html',
standalone: true,
styleUrl: './details.component.css',
})
export class DetailsComponent {
employee: Employee = inject(MAT_DIALOG_DATA);

View File

@ -46,7 +46,6 @@ import { debounceTime } from 'rxjs';
],
templateUrl: './edit.component.html',
standalone: true,
styleUrl: './edit.component.css',
})
export class EditComponent implements OnInit {
employeeForm!: FormGroup;

View File

@ -1,73 +0,0 @@
:host ::ng-deep {
.mat-mdc-card {
--mdc-elevated-card-container-color: transparent;
@apply !shadow-none !rounded-xl;
}
.mat-mdc-button-base {
--mat-mdc-button-persistent-ripple-color: currentColor;
@apply !rounded-lg;
}
.mat-mdc-progress-spinner {
--mdc-circular-progress-active-indicator-color: #2563eb;
}
.mdc-data-table__header-cell {
@apply !text-gray-600 !font-semibold !text-sm !py-4 !px-6;
}
.mat-mdc-table {
@apply !bg-transparent !border-separate !border-spacing-y-2;
.mat-mdc-row {
@apply !bg-white !rounded-xl !shadow-sm !transition-all !duration-200;
&:hover {
@apply !bg-gray-50 !shadow-md !transform !scale-[1.01];
}
.mat-mdc-cell {
@apply !border-b-0 !py-4 !px-6 first:!rounded-l-xl last:!rounded-r-xl;
}
}
.mat-mdc-header-row {
@apply !bg-transparent;
.mat-mdc-header-cell {
@apply !border-b-0;
}
}
}
.mat-mdc-menu-panel {
@apply !rounded-xl !shadow-lg;
}
.mat-mdc-menu-item {
@apply !rounded-lg !mx-1 !my-0.5;
}
.mdc-button {
@apply !font-medium;
&.mat-primary {
@apply !bg-blue-600 !text-white hover:!bg-blue-700;
}
&.mat-warn {
@apply !bg-red-600 !text-white hover:!bg-red-700;
}
}
.mat-mdc-snack-bar-container {
&.error-snackbar {
@apply !rounded-xl;
.mdc-snackbar__surface {
@apply !bg-red-50 !text-red-900 !border !border-red-100;
}
}
}
}

View File

@ -40,7 +40,34 @@
</button>
</div>
@if (employees) {
@if (!employees || employees.length === 0) {
<div class="!bg-gray-50 !rounded-lg !p-8">
<div class="!text-center !max-w-sm !mx-auto">
<div
class="!bg-blue-100 !rounded-full !w-16 !h-16 !flex !items-center !justify-center !mx-auto !mb-4"
>
<mat-icon class="!text-blue-600 !w-8 !h-8 !text-3xl"
>people</mat-icon
>
</div>
<h3 class="!text-gray-900 !font-medium !text-lg !mb-2">
No employees found
</h3>
<p class="!text-gray-600 !mb-6">
Get started by adding your first employee to the directory.
</p>
<button
mat-flat-button
color="primary"
class="!bg-blue-600 !text-white"
(click)="showCreateEmployeeModal()"
>
<mat-icon class="!mr-2">add</mat-icon>
Add Employee
</button>
</div>
</div>
} @else {
<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">
@ -112,13 +139,6 @@
<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">people</mat-icon>
<p class="!text-gray-600">No employees found</p>
</mat-card-content>
</mat-card>
}
</div>
}

View File

@ -51,7 +51,6 @@ import { ErrorHandlerService } from '../../services/error.handler.service';
MatInputModule,
],
templateUrl: './table.component.html',
styleUrl: './table.component.css',
})
export class TableComponent implements OnInit {
private readonly apiService: EmployeeApiService = inject(EmployeeApiService);

View File

@ -6,6 +6,5 @@ import { QualificationsComponent } from '../qualification/table/table.component'
selector: 'app-home',
imports: [TableComponent, QualificationsComponent],
templateUrl: './home.component.html',
styleUrl: './home.component.css',
})
export class HomeComponent {}

View File

@ -37,7 +37,6 @@ import { MatIcon } from '@angular/material/icon';
MatIcon,
],
templateUrl: './create.component.html',
styleUrl: './create.component.css',
})
export class CreateComponent {
private formBuilder: FormBuilder = inject(FormBuilder);

View File

@ -25,7 +25,6 @@ import { MatIcon } from '@angular/material/icon';
],
templateUrl: './delete.component.html',
standalone: true,
styleUrl: './delete.component.css',
})
export class DeleteComponent {
public id: number = inject(MAT_DIALOG_DATA);

View File

@ -26,7 +26,6 @@ import { MatIcon } from '@angular/material/icon';
MatIcon,
],
templateUrl: './details.component.html',
styleUrl: './details.component.css',
})
export class DetailsComponent {
private qualificationService = inject(QualificationService);

View File

@ -45,7 +45,6 @@ import { MatIcon } from '@angular/material/icon';
MatIcon,
],
templateUrl: './edit.component.html',
styleUrl: './edit.component.css',
})
export class EditComponent {
public apiErrorMessage = '';

View File

@ -40,7 +40,34 @@
</button>
</div>
@if (qualifications) {
@if (!qualifications || qualifications.length === 0) {
<div class="!bg-gray-50 !rounded-lg !p-8">
<div class="!text-center !max-w-sm !mx-auto">
<div
class="!bg-blue-100 !rounded-full !w-16 !h-16 !flex !items-center !justify-center !mx-auto !mb-4"
>
<mat-icon class="!text-blue-600 !w-8 !h-8 !text-3xl"
>school</mat-icon
>
</div>
<h3 class="!text-gray-900 !font-medium !text-lg !mb-2">
No qualifications found
</h3>
<p class="!text-gray-600 !mb-6">
Get started by adding your first qualification to the directory.
</p>
<button
mat-flat-button
color="primary"
class="!bg-blue-600 !text-white"
(click)="openCreateModal()"
>
<mat-icon class="!mr-2">add</mat-icon>
Add Qualification
</button>
</div>
</div>
} @else {
<div class="!overflow-x-auto !rounded-lg !bg-gray-50 !p-4">
<table
mat-table
@ -119,13 +146,6 @@
<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>
}

View File

@ -50,7 +50,6 @@ import { ErrorHandlerService } from '../../services/error.handler.service';
MatInputModule,
],
templateUrl: './table.component.html',
styleUrl: './table.component.css',
})
export class QualificationsComponent implements OnInit {
private readonly qualificationService: QualificationService =

View File

@ -16,4 +16,8 @@ export class AuthService {
return false;
}
public logout(): void {
this.keycloakService.logout();
}
}

View File

@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Lf10StarterNew</title>
<title>Employee Management System</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />