From b4e4c2aa9b2dffc1067f75fe31fe722cce629c34 Mon Sep 17 00:00:00 2001 From: Tautvydas Derzinskas Date: Wed, 9 Sep 2026 00:02:09 +0200 Subject: [PATCH] feat: add category banned and update ui for sorting --- .../src/pages/CollectionDetailPage/index.tsx | 4 +- .../src/pages/ModelsPage/CategoryBanner.tsx | 35 ++++++ frontend/src/pages/ModelsPage/SortTabs.tsx | 3 +- frontend/src/pages/ModelsPage/index.tsx | 110 ++++++++++-------- 4 files changed, 99 insertions(+), 53 deletions(-) create mode 100644 frontend/src/pages/ModelsPage/CategoryBanner.tsx diff --git a/frontend/src/pages/CollectionDetailPage/index.tsx b/frontend/src/pages/CollectionDetailPage/index.tsx index 088932c..683eb1e 100644 --- a/frontend/src/pages/CollectionDetailPage/index.tsx +++ b/frontend/src/pages/CollectionDetailPage/index.tsx @@ -139,7 +139,9 @@ export default function CollectionDetailPage({ theme, previewMode, onUnauthorize {collection.description && ( {collection.description} )} - + + + {items.length ? ( diff --git a/frontend/src/pages/ModelsPage/CategoryBanner.tsx b/frontend/src/pages/ModelsPage/CategoryBanner.tsx new file mode 100644 index 0000000..f789921 --- /dev/null +++ b/frontend/src/pages/ModelsPage/CategoryBanner.tsx @@ -0,0 +1,35 @@ +import Box from "@mui/material/Box"; +import Typography from "@mui/material/Typography"; +import { alpha } from "@mui/material/styles"; +import { type Folder } from "../../api/folders"; + +type Props = { + folder: Folder; +}; + +/** The rounded title+description banner shown above the grid when the selected category has + * admin-set meta text (Folder.metaTitle/metaDescription, edited via CategoryMetaDialog) -- + * mirrors MakerWorld's category banner, a light rounded box with the category's display title + * and blurb sitting above its model grid. Models page only: a plain Collection has no + * analogous meta text today. Renders nothing without a title -- the description alone isn't + * worth a banner. */ +export default function CategoryBanner({ folder }: Props) { + if (!folder.meta_title) return null; + return ( + alpha(theme.palette.primary.main, 0.08), + }} + > + {folder.meta_title} + {folder.meta_description && ( + + {folder.meta_description} + + )} + + ); +} diff --git a/frontend/src/pages/ModelsPage/SortTabs.tsx b/frontend/src/pages/ModelsPage/SortTabs.tsx index 32881fc..f0d4e9b 100644 --- a/frontend/src/pages/ModelsPage/SortTabs.tsx +++ b/frontend/src/pages/ModelsPage/SortTabs.tsx @@ -25,7 +25,8 @@ export default function SortTabs({ value, onChange }: Props) { onClick={() => onChange(mode)} sx={{ cursor: "pointer", - fontWeight: value === mode ? 700 : 400, + fontSize: 14, + fontWeight: value === mode ? 700 : 500, color: value === mode ? "primary.main" : "text.secondary", "&:hover": { color: "primary.main" }, }} diff --git a/frontend/src/pages/ModelsPage/index.tsx b/frontend/src/pages/ModelsPage/index.tsx index a79eafe..bad6005 100644 --- a/frontend/src/pages/ModelsPage/index.tsx +++ b/frontend/src/pages/ModelsPage/index.tsx @@ -13,6 +13,7 @@ import { type ResolvedTheme } from "../../constants/settingsOptions"; import { usePageHeader } from "../../components/Layout/PageHeaderContext"; import { useInfiniteScroll } from "../../hooks/useInfiniteScroll"; import CategoriesPanel from "./CategoriesPanel"; +import CategoryBanner from "./CategoryBanner"; import ModelCard from "./ModelCard"; import SortTabs from "./SortTabs"; @@ -185,58 +186,65 @@ export default function ModelsPage({ folderId, onSelectFolder, foldersVersion, o }; return ( - - - - - - - {loading ? ( - - - - ) : items.length ? ( - - - {items.map(item => ( - setItems(prev => prev.filter(i => i.id !== deletedId))} - onFavoriteChange={updated => setItems(prev => prev.map(i => (i.id === updated.id ? updated : i)))} - onUnauthorized={onUnauthorized} - /> - ))} - - {hasMore && ( - - {loadingMore && ( - - - {t("models:grid.loadingMore")} - - )} - - )} - - ) : ( - - {t("models:grid.empty")} - - )} + + + + + + + {selectedFolder?.meta_title && ( + + + + )} + {loading ? ( + + + + ) : items.length ? ( + + + {items.map(item => ( + setItems(prev => prev.filter(i => i.id !== deletedId))} + onFavoriteChange={updated => setItems(prev => prev.map(i => (i.id === updated.id ? updated : i)))} + onUnauthorized={onUnauthorized} + /> + ))} + + {hasMore && ( + + {loadingMore && ( + + + {t("models:grid.loadingMore")} + + )} + + )} + + ) : ( + + {t("models:grid.empty")} + + )} + + ); }