student-info/src/app/overview.component.ts
Gal Podlipnik 54b779390e fixes
2025-08-05 12:44:47 +02:00

259 lines
6.2 KiB
TypeScript

import { CommonModule } from '@angular/common';
import { Component, computed, inject } from '@angular/core';
import { Router } from '@angular/router';
import { ButtonModule } from 'primeng/button';
import { TableModule } from 'primeng/table';
import { StudentService } from './student.service';
import { LocaleStore } from './translations/locale.service';
import { AppTranslatePipe } from './translations/translate.pipe';
@Component({
selector: 'app-overview',
standalone: true,
imports: [CommonModule, TableModule, ButtonModule, AppTranslatePipe],
template: `
<div>
<div class="header-actions">
<h2 class="page-title">{{ 'app.studentOverview' | translate }}</h2>
<div class="action-buttons-header">
<button
pButton
type="button"
label="Add New Student"
icon="pi pi-plus"
class="p-button-primary"
(click)="goToAdd()"
></button>
<button
pButton
type="button"
label="Generate Mock Data"
icon="pi pi-refresh"
class="p-button-secondary"
(click)="generateMock()"
[disabled]="students().length > 0"
></button>
</div>
</div>
<p-table
[value]="students()"
[paginator]="true"
[rows]="10"
[rowsPerPageOptions]="[10, 20, 30]"
[showCurrentPageReport]="true"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} students"
[stripedRows]="true"
styleClass="p-datatable-rounded"
[responsiveLayout]="'stack'"
>
<ng-template pTemplate="header">
<tr>
<th>Name</th>
<th>Email</th>
<th>Courses</th>
<th style="width: 150px">Actions</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-st>
<tr>
<td><span class="p-column-title">Name</span>{{ st.name }}</td>
<td><span class="p-column-title">Email</span>{{ st.email }}</td>
<td>
<span class="p-column-title">Courses</span
>{{ st.courses.join(', ') }}
</td>
<td>
<span class="p-column-title">Actions</span>
<div class="action-buttons">
<button
pButton
icon="pi pi-pencil"
class="p-button-rounded p-button-text"
tooltipPosition="top"
pTooltip="Edit Student"
(click)="editStudent(st.id)"
></button>
<button
pButton
icon="pi pi-trash"
class="p-button-rounded p-button-text p-button-danger"
tooltipPosition="top"
pTooltip="Delete Student"
(click)="deleteStudent(st.id)"
></button>
</div>
</td>
</tr>
</ng-template>
<ng-template pTemplate="emptymessage">
<tr>
<td colspan="4" class="text-center">
No students found. Add your first student!
</td>
</tr>
</ng-template>
</p-table>
</div>
`,
styles: [
`
.header-actions {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1.5rem;
gap: 1rem;
}
.action-buttons-header {
display: flex;
gap: 1rem;
}
.page-title {
margin-bottom: 0;
}
.action-buttons {
display: flex;
gap: 0.5rem;
justify-content: center;
}
:host ::ng-deep {
.p-datatable {
border-radius: var(--border-radius);
overflow: hidden;
box-shadow: var(--card-shadow);
background-color: var(--card-background);
.p-datatable-header {
background-color: var(--card-background) !important;
border: none;
padding: 1.25rem 1.5rem;
}
.p-datatable-thead > tr > th {
background-color: var(--table-header-bg) !important;
color: var(--text-color) !important;
padding: 1rem 1.5rem;
font-weight: 700;
border-width: 0 0 1px 0;
border-color: var(--table-border-color);
}
.p-datatable-tbody > tr {
background-color: var(--table-row-bg) !important;
color: var(--text-color) !important;
&:hover {
background-color: var(--table-row-hover-bg) !important;
}
> td {
background-color: transparent !important;
color: var(--text-color) !important;
padding: 1rem 1.5rem;
border-width: 0 0 1px 0;
border-color: var(--table-border-color);
}
&:last-child > td {
border-bottom: none;
}
}
.p-paginator {
border-width: 0;
padding: 1.25rem;
background-color: var(--card-background) !important;
.p-paginator-page {
&:hover:not(.p-highlight) {
background-color: var(--paginator-button-hover-bg) !important;
}
&.p-highlight {
background-color: #000000 !important;
color: #ffffff !important;
border-color: #000000 !important;
font-weight: 600;
}
}
}
.p-column-title {
display: none;
}
.p-datatable-emptymessage td {
color: var(--text-color) !important;
background-color: var(--table-row-bg) !important;
}
}
.p-button {
border-radius: var(--input-radius);
font-weight: 600;
letter-spacing: 0.2px;
transition: background 0.2s, color 0.2s, box-shadow 0.2s;
box-shadow: none;
}
}
@media screen and (max-width: 768px) {
.header-actions {
flex-direction: column;
align-items: stretch;
gap: 1rem;
}
:host ::ng-deep {
.p-datatable {
.p-datatable-tbody > tr > td {
padding: 1rem;
background-color: transparent !important;
.p-column-title {
display: inline-block;
font-weight: bold;
margin-right: 0.5rem;
color: var(--text-color);
}
}
}
}
}
`,
],
})
export class OverviewComponent {
private readonly router = inject(Router);
private readonly studentsService = inject(StudentService);
private readonly localeStore = inject(LocaleStore);
protected readonly students = computed(() => this.studentsService.students());
protected generateMock = () => this.studentsService.generateMockData();
goToAdd() {
this.router.navigate([
`/${this.localeStore.getCurrentLocale()}/students/add`,
]);
}
editStudent(id: number) {
this.router.navigate(
[`/${this.localeStore.getCurrentLocale()}/students/edit`],
{
queryParams: {
id,
},
}
);
}
deleteStudent(id: string) {
this.studentsService.deleteSutdent(id);
}
}