diff --git a/apps/frontend/project.json b/apps/frontend/project.json
index 2d72fba..ea4900a 100644
--- a/apps/frontend/project.json
+++ b/apps/frontend/project.json
@@ -33,8 +33,8 @@
},
{
"type": "anyComponentStyle",
- "maximumWarning": "4kb",
- "maximumError": "8kb"
+ "maximumWarning": "8kb",
+ "maximumError": "12kb"
}
],
"outputHashing": "all",
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 6e05d62..d8d876f 100644
--- a/apps/frontend/src/app/components/art/art-gallery.component.ts
+++ b/apps/frontend/src/app/components/art/art-gallery.component.ts
@@ -331,11 +331,56 @@ import { Art, CreateArtDto, UpdateArtDto, Comment, SuggestionEntity, Link } from
}
+
+
+
+ @if (searchQuery() || selectedTags().length > 0) {
+
+ }
+
+
+ @if (showFilters()) {
+
+ }
+
@if (loading()) {
Loading gallery...
- } @else if (artPieces().length === 0) {
+ } @else if (filteredArtPieces().length === 0) {
-
No artwork in the gallery yet.
+
No artwork found with these filters.
} @else {
([]);
+ showFilters = signal(false);
+
// Comments state
comments = signal>({});
commentsLoading = signal>({});
@@ -1104,15 +1230,47 @@ export class ArtGalleryComponent implements OnInit {
editLinkTitle = '';
editLinkUrl = '';
- // Computed properties for pagination
+ // Computed properties
+ allTags = computed(() => {
+ const tagsSet = new Set();
+ this.artPieces().forEach(art => {
+ art.tags?.forEach(tag => tagsSet.add(tag));
+ });
+ return Array.from(tagsSet).sort();
+ });
+
+ filteredArtPieces = computed(() => {
+ let artPieces = this.artPieces();
+
+ // Apply search filter
+ const searchQuery = this.searchQuery().toLowerCase().trim();
+ if (searchQuery) {
+ artPieces = artPieces.filter(art =>
+ art.title.toLowerCase().includes(searchQuery) ||
+ art.artist.toLowerCase().includes(searchQuery) ||
+ art.description?.toLowerCase().includes(searchQuery)
+ );
+ }
+
+ // Apply tag filter
+ const selectedTags = this.selectedTags();
+ if (selectedTags.length > 0) {
+ artPieces = artPieces.filter(art =>
+ selectedTags.every(tag => art.tags?.includes(tag))
+ );
+ }
+
+ return artPieces;
+ });
+
paginatedArtPieces = computed(() => {
- const artPieces = this.artPieces();
+ const artPieces = this.filteredArtPieces();
const start = (this.currentPage() - 1) * this.pageSize();
const end = start + this.pageSize();
return artPieces.slice(start, end);
});
- totalArtPieces = computed(() => this.artPieces().length);
+ totalArtPieces = computed(() => this.filteredArtPieces().length);
ngOnInit() {
this.loadArt();
@@ -1431,4 +1589,24 @@ export class ArtGalleryComponent implements OnInit {
const newPage = Math.floor(firstItemIndex / pageSize) + 1;
this.currentPage.set(newPage);
}
+
+ toggleTag(tag: string) {
+ const current = this.selectedTags();
+ if (current.includes(tag)) {
+ this.selectedTags.set(current.filter(t => t !== tag));
+ } else {
+ this.selectedTags.set([...current, tag]);
+ }
+ this.currentPage.set(1); // Reset to first page when tags change
+ }
+
+ clearFilters() {
+ this.searchQuery.set('');
+ this.selectedTags.set([]);
+ this.currentPage.set(1);
+ }
+
+ toggleFilters() {
+ this.showFilters.update(v => !v);
+ }
}
diff --git a/apps/frontend/src/app/components/books/books-list.component.ts b/apps/frontend/src/app/components/books/books-list.component.ts
index 68cc5ea..10d3fd2 100644
--- a/apps/frontend/src/app/components/books/books-list.component.ts
+++ b/apps/frontend/src/app/components/books/books-list.component.ts
@@ -397,6 +397,54 @@ import { Book, BookStatus, CreateBookDto, UpdateBookDto, Comment, SuggestionEnti
}
+
+
+
+
+
+ @if (showFilters()) {
+
+
+
+
+ @if (selectedTags().length > 0) {
+
+ }
+
+
+ }
+