diff --git a/apps/frontend/src/app/components/admin/admin-suggestions.component.ts b/apps/frontend/src/app/components/admin/admin-suggestions.component.ts index 6790f3e..317aaa4 100644 --- a/apps/frontend/src/app/components/admin/admin-suggestions.component.ts +++ b/apps/frontend/src/app/components/admin/admin-suggestions.component.ts @@ -4,17 +4,18 @@ * @author Naomi Carrigan */ -import { Component, OnInit, inject, signal } from '@angular/core'; +import { Component, OnInit, inject, signal, computed } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { SuggestionService } from '../../services/suggestion.service'; import { AuthService } from '../../services/auth.service'; +import { PaginationComponent } from '../shared/pagination.component'; import { Suggestion, SuggestionStatus, SuggestionEntity } from '@library/shared-types'; @Component({ selector: 'app-admin-suggestions', standalone: true, - imports: [CommonModule, FormsModule], + imports: [CommonModule, FormsModule, PaginationComponent], template: `
@@ -65,8 +66,16 @@ import { Suggestion, SuggestionStatus, SuggestionEntity } from '@library/shared-

No suggestions found.

} @else { + +
- @for (suggestion of filteredSuggestions(); track suggestion.id) { + @for (suggestion of paginatedSuggestions(); track suggestion.id) {
@@ -185,6 +194,14 @@ import { Suggestion, SuggestionStatus, SuggestionEntity } from '@library/shared-
}
+ + } } @@ -532,19 +549,32 @@ export class AdminSuggestionsComponent implements OnInit { decliningsuggestion = signal(null); declineReason = ''; + // Pagination state + currentPage = signal(1); + pageSize = signal(25); + SuggestionStatus = SuggestionStatus; unreviewedCount = () => this.suggestions().filter(s => s.status === SuggestionStatus.UNREVIEWED).length; acceptedCount = () => this.suggestions().filter(s => s.status === SuggestionStatus.ACCEPTED).length; declinedCount = () => this.suggestions().filter(s => s.status === SuggestionStatus.DECLINED).length; - filteredSuggestions = () => { + filteredSuggestions = computed(() => { const filter = this.statusFilter(); if (filter === 'all') { return this.suggestions(); } return this.suggestions().filter(s => s.status === filter); - }; + }); + + paginatedSuggestions = computed(() => { + const suggestions = this.filteredSuggestions(); + const start = (this.currentPage() - 1) * this.pageSize(); + const end = start + this.pageSize(); + return suggestions.slice(start, end); + }); + + totalFilteredSuggestions = computed(() => this.filteredSuggestions().length); ngOnInit() { if (this.authService.isAdmin()) { @@ -568,6 +598,19 @@ export class AdminSuggestionsComponent implements OnInit { setFilter(filter: 'all' | SuggestionStatus) { this.statusFilter.set(filter); + this.currentPage.set(1); // Reset to first page when filter changes + } + + onPageChange(page: number) { + this.currentPage.set(page); + } + + onPageSizeChange(pageSize: number) { + this.pageSize.set(pageSize); + // Calculate new current page to stay on approximately the same content + const firstItemIndex = (this.currentPage() - 1) * this.pageSize(); + const newPage = Math.floor(firstItemIndex / pageSize) + 1; + this.currentPage.set(newPage); } getStatusLabel(status: SuggestionStatus): string { diff --git a/apps/frontend/src/app/components/admin/admin-users.component.ts b/apps/frontend/src/app/components/admin/admin-users.component.ts index 23d43d3..a066f57 100644 --- a/apps/frontend/src/app/components/admin/admin-users.component.ts +++ b/apps/frontend/src/app/components/admin/admin-users.component.ts @@ -4,17 +4,18 @@ * @author Naomi Carrigan */ -import { Component, OnInit, inject, signal } from '@angular/core'; +import { Component, OnInit, inject, signal, computed } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Router } from '@angular/router'; import { UserService } from '../../services/user.service'; import { AuthService } from '../../services/auth.service'; +import { PaginationComponent } from '../shared/pagination.component'; import { User } from '@library/shared-types'; @Component({ selector: 'app-admin-users', standalone: true, - imports: [CommonModule], + imports: [CommonModule, PaginationComponent], template: `

User Management

@@ -24,8 +25,16 @@ import { User } from '@library/shared-types'; } @else if (error()) {

{{ error() }}

} @else { + +
- @for (user of users(); track user.id) { + @for (user of paginatedUsers(); track user.id) {
+ + }
`, @@ -270,6 +287,18 @@ export class AdminUsersComponent implements OnInit { loading = signal(true); error = signal(null); + // Pagination state + currentPage = signal(1); + pageSize = signal(25); + + paginatedUsers = computed(() => { + const start = (this.currentPage() - 1) * this.pageSize(); + const end = start + this.pageSize(); + return this.users().slice(start, end); + }); + + totalUsers = computed(() => this.users().length); + ngOnInit(): void { if (!this.authService.isAdmin()) { this.router.navigate(['/']); @@ -320,4 +349,16 @@ export class AdminUsersComponent implements OnInit { } }); } + + onPageChange(page: number): void { + this.currentPage.set(page); + } + + onPageSizeChange(pageSize: number): void { + this.pageSize.set(pageSize); + // Calculate new current page to stay on approximately the same content + const firstItemIndex = (this.currentPage() - 1) * this.pageSize(); + const newPage = Math.floor(firstItemIndex / pageSize) + 1; + this.currentPage.set(newPage); + } } diff --git a/apps/frontend/src/app/components/art/art-gallery.component.ts b/apps/frontend/src/app/components/art/art-gallery.component.ts index b6ff755..6e05d62 100644 --- a/apps/frontend/src/app/components/art/art-gallery.component.ts +++ b/apps/frontend/src/app/components/art/art-gallery.component.ts @@ -4,7 +4,7 @@ * @author Naomi Carrigan */ -import { Component, OnInit, inject, signal } from '@angular/core'; +import { Component, OnInit, inject, signal, computed } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { ArtService } from '../../services/art.service'; @@ -12,12 +12,13 @@ import { AuthService } from '../../services/auth.service'; import { CommentsService } from '../../services/comments.service'; import { SanitizeService } from '../../services/sanitize.service'; import { SuggestionService } from '../../services/suggestion.service'; +import { PaginationComponent } from '../shared/pagination.component'; import { Art, CreateArtDto, UpdateArtDto, Comment, SuggestionEntity, Link } from '@library/shared-types'; @Component({ selector: 'app-art-gallery', standalone: true, - imports: [CommonModule, FormsModule], + imports: [CommonModule, FormsModule, PaginationComponent], template: `
@@ -337,8 +338,16 @@ import { Art, CreateArtDto, UpdateArtDto, Comment, SuggestionEntity, Link } from

No artwork in the gallery yet.

} @else { + +