diff --git a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less index aa7625301..4b3751ca3 100644 --- a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less +++ b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less @@ -335,7 +335,7 @@ } //these media queries are just for the list layout and could be moved inside it, not sure it is a good idea -@media screen and (max-width : 1400px) { +@container (max-width : 1400px) { .brewCollection .brewGroup.list { .brewItem:not(.detailsOpen) { .info { @@ -361,7 +361,7 @@ } } } -@media screen and (max-width : 1200px) { +@container (max-width : 1200px) { .brewCollection .brewGroup.list { .brewItem:not(.detailsOpen) { grid-template-columns : 35% 3fr 150px; @@ -388,7 +388,7 @@ } } } -@media screen and (max-width : 800px) { +@container (max-width : 800px) { .brewCollection .brewGroup.list { .brewItem:not(.detailsOpen) { .info { @@ -443,7 +443,7 @@ } } } -@media screen and (max-width : 650px) { +@container (max-width : 650px) { .brewCollection .brewGroup.list { .brewItem:not(.detailsOpen) { grid-template-columns : 3fr 2fr; diff --git a/client/homebrew/pages/basePages/listPage/listPage.less b/client/homebrew/pages/basePages/listPage/listPage.less index 389c83abf..7a9286914 100644 --- a/client/homebrew/pages/basePages/listPage/listPage.less +++ b/client/homebrew/pages/basePages/listPage/listPage.less @@ -21,15 +21,16 @@ .sitePage.listPage { --bg-clr : white; + container-type: inline-size; .content { - padding : clamp(20px, 5vh, 200px) clamp(20px, 20vw, 200px); + padding : clamp(20px, 5vh, 200px) clamp(20px, 20cqi, 200px); overflow-y : scroll; scrollbar-gutter : stable; - @media screen and (max-width : 1200px) { - padding : clamp(20px, 5vh, 200px) clamp(20px, 10vw, 200px); + @container (max-width : 1200px) { + padding : clamp(20px, 5vh, 200px) clamp(20px, 10cqi, 200px); } - @media screen and (max-width : 800px) { - padding : clamp(20px, 5vh, 200px) clamp(20px, 5vw, 200px); + @container (max-width : 800px) { + padding : clamp(20px, 5vh, 200px) clamp(20px, 5cqi, 200px); } &::-webkit-scrollbar { @@ -53,6 +54,7 @@ color : white; } .brewCollection { + h1 { width : fit-content; margin-bottom : 20px; @@ -97,9 +99,9 @@ gap : 20px; justify-items : center; - @media screen and (max-width : 1700px) {--columns : 3;} - @media screen and (max-width : 1400px) {--columns : 2;} - @media screen and (max-width : 900px) {--columns : 1;} + @container (max-width : 1700px) {--columns : 3;} + @container (max-width : 1400px) {--columns : 2;} + @container (max-width : 900px) {--columns : 1;} h1 { position : absolute; } &:not(:has(.brewItem:last-child:nth-child(3n))) { diff --git a/client/homebrew/pages/vaultPage/vaultPage.jsx b/client/homebrew/pages/vaultPage/vaultPage.jsx index c76505c7b..b64517083 100644 --- a/client/homebrew/pages/vaultPage/vaultPage.jsx +++ b/client/homebrew/pages/vaultPage/vaultPage.jsx @@ -16,6 +16,13 @@ import ErrorIndex from '../errorPage/errors/errorIndex.js'; import request from '../../utils/request-middleware.js'; +const DEFAULT_SORT_TYPE = 'alpha'; +const DEFAULT_SORT_DIR = 'asc'; +const DEFAULT_LAYOUT_MODE = 'grid'; +const DEFAULT_THEME_MODE = 'light'; +const USERPAGE_LAYOUT_MODE = 'HB_listPage_layout_mode'; +const USERPAGE_THEME_MODE = 'HB_listPage_theme_mode'; + const VaultPage = (props)=>{ const [pageState, setPageState] = useState(parseInt(props.query.page) || 1); @@ -27,6 +34,8 @@ const VaultPage = (props)=>{ const [totalBrews, setTotalBrews] = useState(null); const [searching, setSearching] = useState(false); const [error, setError] = useState(null); + const [layoutMode, setLayoutMode] = useState(DEFAULT_LAYOUT_MODE); + const [themeMode, setThemeMode] = useState(DEFAULT_THEME_MODE); const titleRef = useRef(null); const authorRef = useRef(null); @@ -37,6 +46,13 @@ const VaultPage = (props)=>{ useEffect(()=>{ disableSubmitIfFormInvalid(); + + const newLayoutMode = localStorage.getItem(USERPAGE_LAYOUT_MODE) || DEFAULT_LAYOUT_MODE; + const newThemeMode = localStorage.getItem(USERPAGE_THEME_MODE) || DEFAULT_THEME_MODE; + + setLayoutMode(newLayoutMode); + setThemeMode(newThemeMode); + loadPage(pageState, true, props.query.sort, props.query.dir); }, []); @@ -83,7 +99,8 @@ const VaultPage = (props)=>{ const response = await request.get(`/api/vault/total?title=${title}&author=${author}&v3=${v3}&legacy=${legacy}`) .catch((error)=>{ - console.log('error at loadTotal: ', error); + console.log('error at loadTotal: '); + console.error(error); setError(error); updateStateWithBrews([], 1); }); @@ -261,7 +278,7 @@ const VaultPage = (props)=>{ const oppositeDir = dirState === 'asc' ? 'desc' : 'asc'; return ( -
+
@@ -272,10 +289,10 @@ const VaultPage = (props)=>{ ); }; - const renderSortBar = ()=>{ + const renderSortOptions = ()=>{ return ( -
+
{renderSortOption('Title', 'title', props.query.dir)} {renderSortOption('Created Date', 'createdAt', props.query.dir)} {renderSortOption('Updated Date', 'updatedAt', props.query.dir)} @@ -284,6 +301,64 @@ const VaultPage = (props)=>{ ); }; + const handleLayoutChange = (e, mode)=>{ + setLayoutMode(e.target.checked ? mode : DEFAULT_LAYOUT_MODE); + localStorage.setItem(USERPAGE_LAYOUT_MODE, e.target.checked ? mode : DEFAULT_LAYOUT_MODE); + return; + }; + const renderLayoutModeOptions = ()=>{ + return ( +
+
View:
+ + + +
+ ); + }; + const handleThemeChange = (e, mode)=>{ + setThemeMode(e.target.checked ? mode : DEFAULT_THEME_MODE); + localStorage.setItem(USERPAGE_THEME_MODE, e.target.checked ? mode : DEFAULT_THEME_MODE); + return; + }; + + const renderThemePicker = ()=>{ + return ( +
+
Theme:
+ + +
+ ) + }; + + + const renderNav = () =>{ + return ( +
+ {renderLayoutModeOptions()} + {renderThemePicker()} + {renderSortOptions()} +
+ ); + + } + const renderPaginationControls = ()=>{ if(!totalBrews || totalBrews < 10) return null; @@ -367,7 +442,7 @@ const VaultPage = (props)=>{ if(error.HBErrorCode === undefined) { return (
-

{error.toString()}

+

Error: Unknown error

) } else { @@ -400,22 +475,26 @@ const VaultPage = (props)=>{ } return ( -
+
{`Brews found: `} {totalBrews} {brewCollection.length > 10 && renderPaginationControls()} - {brewCollection.map((brew, index)=>{ - return ( - - ); - })} +
+
+ {brewCollection.map((brew, index)=>{ + return ( + + ); + })} +
+
{renderPaginationControls()}
); @@ -430,7 +509,7 @@ const VaultPage = (props)=>{
{renderForm()}
- {renderSortBar()} + {renderNav()} {renderFoundBrews()}
diff --git a/client/homebrew/pages/vaultPage/vaultPage.less b/client/homebrew/pages/vaultPage/vaultPage.less index a685893c2..85eabe7a0 100644 --- a/client/homebrew/pages/vaultPage/vaultPage.less +++ b/client/homebrew/pages/vaultPage/vaultPage.less @@ -117,69 +117,40 @@ height : 100%; overflow-y : auto; font-size : 0.34cm; - - h3 { - font-family : 'Open Sans'; - font-weight : 900; - color : white; - } - - .sort-container { - display : flex; - flex-wrap : wrap; - column-gap : 15px; - justify-content : center; - height : 30px; - color : white; - background-color : #555555; - border-top : 1px solid #666666; - border-bottom : 1px solid #666666; - - .sort-option { - display : flex; - align-items : center; - padding : 0 8px; - - &:hover { background-color : #444444; } - - &.active { - background-color : #333333; - - button { - font-weight : 800; - color : white; - - & + .sortDir { padding-left : 5px; } - } - } - - button { - padding : 0; - font-size : 11px; - font-weight : normal; - color : #CCCCCC; - text-transform : uppercase; - background-color : transparent; - - &:hover { background : none; } - } - } - } + container-type : inline-size; .foundBrews { - position : relative; - width : 100%; - height : 100%; - max-height : 100%; - padding : 70px 50px; - container-type : inline-size; + display:flex; + flex-direction: column; + gap:20px; + padding : clamp(20px, 5vh, 200px) clamp(20px, 20vw, 200px); overflow-y : scroll; + scrollbar-gutter : stable; + @container (max-width : 1200px) { + padding : clamp(20px, 5vh, 200px) clamp(20px, 10vw, 200px); + } + @container (max-width : 800px) { + padding : clamp(20px, 5vh, 200px) clamp(20px, 5vw, 200px); + } - h3 { font-size : 25px; } + &::-webkit-scrollbar { + width : 15px; + &:horizontal { + width : auto; + height : 20px; + } + &-thumb { + background : linear-gradient(90deg, var(--bg-clr) 12px, #00000000 12px); + &:horizontal { background : linear-gradient(0deg, var(--bg-clr) 15px, #00000000 15px); } + } + &-corner { visibility : hidden; } + } &.noBrews { - display : grid; - place-items : center; + margin : 10px 0px; + font-size : 25px; + font-style : italic; + font-weight : 900; color : white; } @@ -202,6 +173,64 @@ } } + + .brewCollection { + h1 { + width : fit-content; + margin-bottom : 20px; + font-size : 25px; + color : #DDDDDD; + + &.active::before, + &.inactive::before { + padding-right : 0.5em; + font-family : 'Font Awesome 6 Free'; + font-size : 0.6cm; + font-weight : 900; + } + &.active { + color : white; + &::before { content : '\f107'; } + } + &.inactive::before { content : '\f105'; } + } + h1:hover { cursor : pointer; } + + .brewGroup { + margin-bottom : 20px; + &.grid { + display : flex; + flex-wrap : wrap; + gap : 20px; + justify-content : center; + width : fit-content; + min-width : 200px; + } + + &.list { + display : flex; + flex-direction : column; + gap : 2px; + } + &.card { + --columns : 4; + display : grid; + grid-template-columns : repeat(var(--columns), 1fr); + gap : 20px; + justify-items : center; + + @container (max-width : 1700px) {--columns : 3;} + @container (max-width : 1400px) {--columns : 2;} + @container (max-width : 900px) {--columns : 1;} + h1 { position : absolute; } + + &:not(:has(.brewItem:last-child:nth-child(3n))) { + .brewItem:last-child { margin-right : auto; } + } + } + } + } + .totalBrews { position : fixed; right : 0; @@ -233,66 +262,15 @@ } } - .brewItem { - width : 47%; - margin-right : 40px; - color : black; - isolation : isolate; - transition : width 0.5s; - - &::after { - position : absolute; - inset : 0; - z-index : -2; - display : block; - content : ''; - background-image : url('/assets/parchmentBackground.jpg'); - } - - &:nth-child(even of .brewItem) { margin-right : 0; } - - h2 { - font-family : 'MrEavesRemake'; - font-size : 0.75cm; - font-weight : 800; - line-height : 0.988em; - color : var(--HB_Color_HeaderText); - } - .info { - position : relative; - z-index : 2; - font-family : 'ScalySansRemake'; - font-size : 1.2em; - - >span { - margin-right : 12px; - line-height : 1.5em; - } - } - .links { z-index : 2; } - - hr { - visibility : hidden; - margin : 0px; - } - - .thumbnail { z-index : -1; } - } - .paginationControls { - position : absolute; - top : 35px; - left : 50%; display : grid; grid-template-areas : 'previousPage currentPage nextPage'; grid-template-columns : 50px 1fr 50px; gap : 20px; place-items : center; - width : auto; + width : fit-content; + margin-inline:auto; font-size : 15px; - translate : -50%; - - &:last-child { top : unset; } .pages { display : flex; @@ -314,8 +292,11 @@ text-underline-position : under; cursor : pointer; - &.currentPage { + &:hover { color : gold; + } + &.currentPage { + color:@yellow; text-decoration : underline; pointer-events : none; } @@ -339,6 +320,77 @@ } } } + + .listPageNav { + position : relative; + display : flex; + flex-wrap : wrap; + row-gap : 10px; + column-gap : 20px; + align-items : center; + justify-content : center; + width : 100%; + height : fit-content; + font-family : 'Open Sans', sans-serif; + color : white; + background : #555555; + border-top : 1px solid #666666; + border-bottom : 1px solid #666666; + row-rule : 1px solid #666666; + + > div { + width : fit-content; + height : 30px; + padding-inline : 10px; + } + + .radio-toggle { + z-index : 1; + display : flex; + flex-wrap : wrap; + row-gap : 5px; + align-items : center; + justify-content : center; + text-align : center; + h6 { + margin-right : 5px; + font-size : 14px; + } + + .option { + display : flex; + align-items : center; + height : 100%; + padding : 0 8px; + color : #CCCCCC; + + input[type='radio'] { display : none; } + + button { + padding : 0; + font-size : 11px; + font-weight : normal; + text-transform : uppercase; + background-color : transparent; + } + &:hover { background-color : #444444; } + + &.active, &:has(input:checked) { + font-weight : bold; + color : white; + background-color : #333333; + + button { + height : 100%; + font-weight : 800; + & + .sortDir { padding-left : 5px; } + } + } + } + } + + + } } @keyframes trailingDots { @@ -351,16 +403,4 @@ 66%, 100% { content : ' ...'; } -} - -@container (width < 670px) { - .vaultPage { - - .dataGroup.form .brewLookup { padding : 1px 20px 20px 10px; } - - .dataGroup.resultsContainer .foundBrews .brewItem { - width : 100%; - margin-inline : auto; - } - } -} +} \ No newline at end of file