0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-07 16:22:42 +00:00

Merge branch 'master' into pr/2320

This commit is contained in:
Trevor Buckner
2022-09-02 23:55:34 -04:00
3 changed files with 93 additions and 11 deletions

View File

@@ -104,6 +104,13 @@ const BrewItem = createClass({
</div> </div>
<hr /> <hr />
<div className='info'> <div className='info'>
{brew.tags ? <>
<span className='brewTags' title={`Tags:\n${brew.tags.join('\n')}`}>
<i className='fas fa-tags'/> {brew.tags.join(', ')}
</span>
<br />
</> : <></>
}
<span title={`Authors:\n${brew.authors?.join('\n')}`}> <span title={`Authors:\n${brew.authors?.join('\n')}`}>
<i className='fas fa-user'/> {brew.authors?.join(', ')} <i className='fas fa-user'/> {brew.authors?.join(', ')}
</span> </span>

View File

@@ -6,6 +6,8 @@ const moment = require('moment');
const BrewItem = require('./brewItem/brewItem.jsx'); const BrewItem = require('./brewItem/brewItem.jsx');
const USERPAGE_KEY_PREFIX = 'HOMEBREWERY-LISTPAGE-VISIBILITY';
const ListPage = createClass({ const ListPage = createClass({
displayName : 'ListPage', displayName : 'ListPage',
getDefaultProps : function() { getDefaultProps : function() {
@@ -21,14 +23,47 @@ const ListPage = createClass({
}; };
}, },
getInitialState : function() { getInitialState : function() {
// HIDE ALL GROUPS UNTIL LOADED
const brewCollection = this.props.brewCollection.map((brewGroup)=>{
brewGroup.visible = false;
return brewGroup;
});
return { return {
sortType : 'alpha',
sortDir : 'asc',
filterString : this.props.query?.filter || '', filterString : this.props.query?.filter || '',
query : this.props.query sortType : this.props.query?.sort || 'alpha',
sortDir : this.props.query?.dir || 'asc',
query : this.props.query,
brewCollection : brewCollection
}; };
}, },
componentDidMount : function() {
// SAVE TO LOCAL STORAGE WHEN LEAVING PAGE
window.onbeforeunload = this.saveToLocalStorage;
// LOAD FROM LOCAL STORAGE
if(typeof window !== 'undefined') {
const brewCollection = this.props.brewCollection.map((brewGroup)=>{
brewGroup.visible = (localStorage.getItem(`${USERPAGE_KEY_PREFIX}-${brewGroup.class}`) ?? 'true')=='true';
return brewGroup;
});
this.setState({
brewCollection : brewCollection
});
};
},
componentWillUnmount : function() {
window.onbeforeunload = function(){};
},
saveToLocalStorage : function() {
this.state.brewCollection.map((brewGroup)=>{
localStorage.setItem(`${USERPAGE_KEY_PREFIX}-${brewGroup.class}`, `${brewGroup.visible}`);
});
},
renderBrews : function(brews){ renderBrews : function(brews){
if(!brews || !brews.length) return <div className='noBrews'>No Brews.</div>; if(!brews || !brews.length) return <div className='noBrews'>No Brews.</div>;
@@ -50,14 +85,18 @@ const ListPage = createClass({
}, },
handleSortOptionChange : function(event){ handleSortOptionChange : function(event){
this.updateUrl(this.state.filterString, event.target.value, this.state.sortDir);
this.setState({ this.setState({
sortType : event.target.value sortType : event.target.value
}); });
}, },
handleSortDirChange : function(event){ handleSortDirChange : function(event){
const newDir = this.state.sortDir == 'asc' ? 'desc' : 'asc';
this.updateUrl(this.state.filterString, this.state.sortType, newDir);
this.setState({ this.setState({
sortDir : `${(this.state.sortDir == 'asc' ? 'desc' : 'asc')}` sortDir : newDir
}); });
}, },
@@ -77,19 +116,22 @@ const ListPage = createClass({
this.setState({ this.setState({
filterString : e.target.value, filterString : e.target.value,
}); });
this.updateUrl(e.target.value); this.updateUrl(e.target.value, this.state.sortType, this.state.sortDir);
return; return;
}, },
updateUrl : function(filterTerm){ updateUrl : function(filterTerm, sortType, sortDir){
const url = new URL(window.location.href); const url = new URL(window.location.href);
const urlParams = new URLSearchParams(url.search); const urlParams = new URLSearchParams(url.search);
if(urlParams.get('filter') == filterTerm)
return; urlParams.set('sort', sortType);
urlParams.set('dir', sortDir);
if(!filterTerm) if(!filterTerm)
urlParams.delete('filter'); urlParams.delete('filter');
else else
urlParams.set('filter', filterTerm); urlParams.set('filter', filterTerm);
url.search = urlParams; url.search = urlParams;
window.history.replaceState(null, null, url); window.history.replaceState(null, null, url);
}, },
@@ -158,11 +200,22 @@ const ListPage = createClass({
return _.orderBy(brews, (brew)=>{ return this.sortBrewOrder(brew); }, this.state.sortDir); return _.orderBy(brews, (brew)=>{ return this.sortBrewOrder(brew); }, this.state.sortDir);
}, },
toggleBrewCollectionState : function(brewGroupClass) {
this.setState((prevState)=>({
brewCollection : prevState.brewCollection.map(
(brewGroup)=>brewGroup.class === brewGroupClass ? { ...brewGroup, visible: !brewGroup.visible } : brewGroup
)
}));
},
renderBrewCollection : function(brewCollection){ renderBrewCollection : function(brewCollection){
if(brewCollection == []) return <div className='brewCollection'>
<h1>No Brews</h1>
</div>;
return _.map(brewCollection, (brewGroup, idx)=>{ return _.map(brewCollection, (brewGroup, idx)=>{
return <div key={idx} className={`brewCollection ${brewGroup.class ?? ''}`}> return <div key={idx} className={`brewCollection ${brewGroup.class ?? ''}`}>
<h1>{brewGroup.title || 'No Title'}</h1> <h1 className={brewGroup.visible ? 'active' : 'inactive'} onClick={()=>{this.toggleBrewCollectionState(brewGroup.class);}}>{brewGroup.title || 'No Title'}</h1>
{this.renderBrews(this.getSortedBrews(brewGroup.brews))} {brewGroup.visible ? this.renderBrews(this.getSortedBrews(brewGroup.brews)) : <></>}
</div>; </div>;
}); });
}, },
@@ -175,7 +228,7 @@ const ListPage = createClass({
<div className='content V3'> <div className='content V3'>
<div className='phb page'> <div className='phb page'>
{this.renderSortOptions()} {this.renderSortOptions()}
{this.renderBrewCollection(this.props.brewCollection)} {this.renderBrewCollection(this.state.brewCollection)}
</div> </div>
</div> </div>
</div>; </div>;

View File

@@ -74,4 +74,26 @@
} }
} }
} }
h1 {
cursor: pointer;
&.active {
color: #58180D;
}
&.inactive {
color: #707070;
}
&.active::before, &.inactive::before {
font-family: 'Font Awesome 5 Free';
font-weight: 900;
font-size: 0.6cm;
padding-right: 0.5em;
}
&.active::before {
content: '\f107';
}
&.inactive::before {
content: '\f105';
}
}
} }