feat(ui): storefront filters and admin category/tag management (#23)
SonarQube Analysis / sonarqube (pull_request) Successful in 2m49s
Tests / backend-unit (pull_request) Successful in 37s
Tests / backend-integration (pull_request) Failing after 3h2m23s
Tests / frontend-e2e (pull_request) Failing after 3m54s

Storefront gains a Filters drawer holding the category tree, colour-coded
tag pills, and a price range, with applied filters shown as removable
chips. Filter state lives in the URL query string, so a filtered view is
shareable and the back button works. Item cards now show their category
and tags.

Admin gains Categories and Tags tabs, and the item form gains a category
TreeSelect plus a tags Select that creates new tags on the fly.

The admin category tree tracks expansion in state rather than using
defaultExpandAll: that prop is evaluated once at mount, so a branch added
afterwards rendered collapsed and its children were unreachable. Creating
or moving a node now expands its parent. Caught by the new admin e2e spec.

The chip row is marked as a named group so its "Clear all" stays
distinguishable from the drawer's.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-17 09:34:37 -05:00
co-authored by Claude Opus 5
parent 9222e97deb
commit d28fb5634a
13 changed files with 1374 additions and 22 deletions
+43 -1
View File
@@ -72,4 +72,46 @@ body { margin: 0; }
padding-right: 10px;
font-size: 13px;
}
}
}
/* Filter bar: the Filters button sits inline with the active-filter chips on
desktop; on a narrow screen the chips wrap onto their own line beneath it. */
.filter-bar {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
margin-bottom: 16px;
}
.active-filter-chips {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 4px;
}
.active-filter-chips .ant-tag {
margin-inline-end: 0;
}
.item-category {
display: block;
font-size: 12px;
margin-bottom: 6px;
}
.item-tags {
display: flex;
flex-wrap: wrap;
gap: 4px 0;
margin: 8px 0 4px;
}
@media (max-width: 575px) {
.filter-bar {
align-items: flex-start;
}
.filter-bar > .ant-btn {
width: 100%;
}
}