0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-07 14:12:43 +00:00

indent with tabs

This commit is contained in:
Víctor Losada Hernández
2024-08-31 22:11:43 +02:00
parent 8d2a9ed9cb
commit 19102db23a
3 changed files with 506 additions and 501 deletions

View File

@@ -2,11 +2,16 @@ const React = require('react');
const Nav = require('naturalcrit/nav/nav.jsx'); const Nav = require('naturalcrit/nav/nav.jsx');
module.exports = function(props){ module.exports = function (props) {
return<Nav.item color='purple' icon='fas fa-dungeon' return (
href='/vault' <Nav.item
color="purple"
icon="fas fa-dungeon"
href="/vault"
newTab={false} newTab={false}
rel='noopener noreferrer'> rel="noopener noreferrer"
>
Vault Vault
</Nav.item> </Nav.item>
);
}; };

View File

@@ -16,458 +16,458 @@ const SplitPane = require('../../../../shared/naturalcrit/splitPane/splitPane.js
const request = require('../../utils/request-middleware.js'); const request = require('../../utils/request-middleware.js');
const VaultPage = (props) => { const VaultPage = (props) => {
const [title, setTitle] = useState(props.query.title || ''); const [title, setTitle] = useState(props.query.title || '');
//state author //state author
const [author, setAuthor] = useState(props.query.author || ''); const [author, setAuthor] = useState(props.query.author || '');
const [legacy, setLegacy] = useState(props.query.legacy !== 'false'); const [legacy, setLegacy] = useState(props.query.legacy !== 'false');
const [v3, setV3] = useState(props.query.v3 !== 'false'); const [v3, setV3] = useState(props.query.v3 !== 'false');
const [count, setCount] = useState(props.query.count || 20); const [count, setCount] = useState(props.query.count || 20);
const [page, setPage] = useState(parseInt(props.query.page) || 1); const [page, setPage] = useState(parseInt(props.query.page) || 1);
const [brewCollection, setBrewCollection] = useState(null); const [brewCollection, setBrewCollection] = useState(null);
const [totalBrews, setTotalBrews] = useState(null); const [totalBrews, setTotalBrews] = useState(null);
const [searching, setSearching] = useState(false); const [searching, setSearching] = useState(false);
const [error, setError] = useState(null); const [error, setError] = useState(null);
const titleRef = useRef(null); const titleRef = useRef(null);
const authorRef = useRef(null); const authorRef = useRef(null);
const countRef = useRef(null); const countRef = useRef(null);
const v3Ref = useRef(null); const v3Ref = useRef(null);
const legacyRef = useRef(null); const legacyRef = useRef(null);
const searchButtonRef = useRef(null); const searchButtonRef = useRef(null);
useEffect(() => { useEffect(() => {
disableSubmitIfFormInvalid(); disableSubmitIfFormInvalid();
loadPage(page, false, true); loadPage(page, false, true);
}, []); }, []);
const updateStateWithBrews = (brews, page) => { const updateStateWithBrews = (brews, page) => {
setBrewCollection(brews || null); setBrewCollection(brews || null);
setPage(parseInt(page) || 1); setPage(parseInt(page) || 1);
setSearching(false); setSearching(false);
}; };
const updateUrl = (title, author, count, v3, legacy, page) => { const updateUrl = (title, author, count, v3, legacy, page) => {
const url = new URL(window.location.href); const url = new URL(window.location.href);
const urlParams = new URLSearchParams(); const urlParams = new URLSearchParams();
Object.entries({ Object.entries({
title, title,
author, author,
count, count,
v3, v3,
legacy, legacy,
page, page,
}).forEach(([key, value]) => urlParams.set(key, value)); }).forEach(([key, value]) => urlParams.set(key, value));
url.search = urlParams.toString(); url.search = urlParams.toString();
window.history.replaceState(null, null, url); window.history.replaceState(null, null, url);
}; };
const loadPage = async (page, update, total) => { const loadPage = async (page, update, total) => {
//Different searches use the update or total props to make only the necessary queries and functions //Different searches use the update or total props to make only the necessary queries and functions
if (!validateForm()) { if (!validateForm()) {
return; return;
} }
setSearching(true); setSearching(true);
setError(null); setError(null);
const performSearch = async ({ title, author, count, v3, legacy }) => { const performSearch = async ({ title, author, count, v3, legacy }) => {
updateUrl(title, author, count, v3, legacy, page); updateUrl(title, author, count, v3, legacy, page);
console.log(title, author, count, v3, legacy); console.log(title, author, count, v3, legacy);
if ((title || author) && (v3 || legacy)) { if ((title || author) && (v3 || legacy)) {
try { try {
const response = await request.get( const response = await request.get(
`/api/vault?title=${title}&author=${author}&v3=${v3}&legacy=${legacy}&count=${count}&page=${page}` `/api/vault?title=${title}&author=${author}&v3=${v3}&legacy=${legacy}&count=${count}&page=${page}`
); );
if (response.ok) { if (response.ok) {
updateStateWithBrews(response.body.brews, page); updateStateWithBrews(response.body.brews, page);
} else { } else {
throw new Error(`Error: ${response.status}`); throw new Error(`Error: ${response.status}`);
} }
} catch (error) { } catch (error) {
console.log('error at loadPage: ', error); console.log('error at loadPage: ', error);
setError( setError(
`${ `${
error.response error.response
? error.response.status ? error.response.status
: error.message : error.message
}` }`
); );
updateStateWithBrews([], 1); updateStateWithBrews([], 1);
} }
} else { } else {
setError('404'); setError('404');
} }
}; };
const loadTotal = async ({ title, v3, legacy }) => { const loadTotal = async ({ title, v3, legacy }) => {
setTotalBrews(null); setTotalBrews(null);
setError(null); setError(null);
if ((title || author) && (v3 || legacy)) { if ((title || author) && (v3 || legacy)) {
try { try {
const response = await request.get( const response = await request.get(
`/api/vault/total?title=${title}&author=${author}&v3=${v3}&legacy=${legacy}` `/api/vault/total?title=${title}&author=${author}&v3=${v3}&legacy=${legacy}`
); );
if (response.ok) { if (response.ok) {
setTotalBrews(response.body.totalBrews); setTotalBrews(response.body.totalBrews);
} else { } else {
throw new Error( throw new Error(
`Failed to load total brews: ${response.statusText}` `Failed to load total brews: ${response.statusText}`
); );
} }
} catch (error) { } catch (error) {
console.log('error at loadTotal: ', error); console.log('error at loadTotal: ', error);
setError(`${error.response.status}`); setError(`${error.response.status}`);
updateStateWithBrews([], 1); updateStateWithBrews([], 1);
} }
} }
}; };
const title = titleRef.current.value || ''; const title = titleRef.current.value || '';
const author = authorRef.current.value || ''; const author = authorRef.current.value || '';
const count = countRef.current.value || 10; const count = countRef.current.value || 10;
const v3 = v3Ref.current.checked != false; const v3 = v3Ref.current.checked != false;
const legacy = legacyRef.current.checked != false; const legacy = legacyRef.current.checked != false;
console.log(title); console.log(title);
if (update) { if (update) {
setTitle(title); setTitle(title);
setAuthor(author); setAuthor(author);
setCount(count); setCount(count);
setV3(v3); setV3(v3);
setLegacy(legacy); setLegacy(legacy);
} }
// Perform search with the latest input values, because state is not fast enough // Perform search with the latest input values, because state is not fast enough
performSearch({ title, author, count, v3, legacy }); performSearch({ title, author, count, v3, legacy });
if (total) { if (total) {
loadTotal({ title, author, v3, legacy }); loadTotal({ title, author, v3, legacy });
} }
}; };
const renderNavItems = () => ( const renderNavItems = () => (
<Navbar> <Navbar>
<Nav.section> <Nav.section>
<Nav.item className="brewTitle"> <Nav.item className="brewTitle">
Vault: Search for brews Vault: Search for brews
</Nav.item> </Nav.item>
</Nav.section> </Nav.section>
<Nav.section> <Nav.section>
<NewBrew /> <NewBrew />
<HelpNavItem /> <HelpNavItem />
<RecentNavItem /> <RecentNavItem />
<Account /> <Account />
</Nav.section> </Nav.section>
</Navbar> </Navbar>
); );
const validateForm = () => { const validateForm = () => {
//form validity: title or author must be written, and at least one renderer set //form validity: title or author must be written, and at least one renderer set
const { current: titleInput } = titleRef; const { current: titleInput } = titleRef;
const { current: legacyCheckbox } = legacyRef; const { current: legacyCheckbox } = legacyRef;
const { current: v3Checkbox } = v3Ref; const { current: v3Checkbox } = v3Ref;
const { current: authorInput } = authorRef; const { current: authorInput } = authorRef;
const isTitleValid = titleInput.validity.valid && titleInput.value; const isTitleValid = titleInput.validity.valid && titleInput.value;
//because a pattern attr is set in the input, title must be over 2 chars long //because a pattern attr is set in the input, title must be over 2 chars long
const isAuthorValid = authorInput.validity.valid && authorInput.value; const isAuthorValid = authorInput.validity.valid && authorInput.value;
const isCheckboxChecked = legacyCheckbox.checked || v3Checkbox.checked; const isCheckboxChecked = legacyCheckbox.checked || v3Checkbox.checked;
const isFormValid = const isFormValid =
(isTitleValid || isAuthorValid) && isCheckboxChecked; (isTitleValid || isAuthorValid) && isCheckboxChecked;
return isFormValid; return isFormValid;
}; };
const disableSubmitIfFormInvalid = () => { const disableSubmitIfFormInvalid = () => {
const { current: submitButton } = searchButtonRef; const { current: submitButton } = searchButtonRef;
submitButton.disabled = !validateForm(); submitButton.disabled = !validateForm();
}; };
const renderForm = () => ( const renderForm = () => (
<div className="brewLookup"> <div className="brewLookup">
<h2 className="formTitle">Brew Lookup</h2> <h2 className="formTitle">Brew Lookup</h2>
<div className="formContents"> <div className="formContents">
<label> <label>
Title of the brew Title of the brew
<input <input
ref={titleRef} ref={titleRef}
type="text" type="text"
name="title" name="title"
defaultValue={title} defaultValue={title}
onKeyUp={disableSubmitIfFormInvalid} onKeyUp={disableSubmitIfFormInvalid}
pattern=".{3,}" pattern=".{3,}"
title="At least 3 characters" title="At least 3 characters"
onKeyDown={(e) => { onKeyDown={(e) => {
if (e.key === 'Enter') { if (e.key === 'Enter') {
if (!searchButtonRef.current.disabled) { if (!searchButtonRef.current.disabled) {
loadPage(1, true, true); loadPage(1, true, true);
} }
} }
}} }}
placeholder="v3 Reference Document" placeholder="v3 Reference Document"
/> />
</label> </label>
<label> <label>
Author of the brew Author of the brew
<input <input
ref={authorRef} ref={authorRef}
type="text" type="text"
name="author" name="author"
pattern=".{1,}" pattern=".{1,}"
defaultValue={author} defaultValue={author}
onKeyUp={disableSubmitIfFormInvalid} onKeyUp={disableSubmitIfFormInvalid}
onKeyDown={(e) => { onKeyDown={(e) => {
if (e.key === 'Enter') { if (e.key === 'Enter') {
if (!searchButtonRef.current.disabled) { if (!searchButtonRef.current.disabled) {
loadPage(1, true, true); loadPage(1, true, true);
} }
} }
}} }}
placeholder="Gazook89" placeholder="Gazook89"
/> />
</label> </label>
<label> <label>
Results per page Results per page
<select ref={countRef} name="count" defaultValue={count}> <select ref={countRef} name="count" defaultValue={count}>
<option value="10">10</option> <option value="10">10</option>
<option value="20">20</option> <option value="20">20</option>
<option value="40">40</option> <option value="40">40</option>
<option value="60">60</option> <option value="60">60</option>
</select> </select>
</label> </label>
<label> <label>
<input <input
className="renderer" className="renderer"
ref={v3Ref} ref={v3Ref}
type="checkbox" type="checkbox"
defaultChecked={v3} defaultChecked={v3}
onChange={disableSubmitIfFormInvalid} onChange={disableSubmitIfFormInvalid}
/> />
Search for v3 brews Search for v3 brews
</label> </label>
<label> <label>
<input <input
className="renderer" className="renderer"
ref={legacyRef} ref={legacyRef}
type="checkbox" type="checkbox"
defaultChecked={legacy} defaultChecked={legacy}
onChange={disableSubmitIfFormInvalid} onChange={disableSubmitIfFormInvalid}
/> />
Search for legacy brews Search for legacy brews
</label> </label>
<button <button
id="searchButton" id="searchButton"
ref={searchButtonRef} ref={searchButtonRef}
onClick={() => { onClick={() => {
loadPage(1, true, true); loadPage(1, true, true);
}} }}
> >
Search Search
<i <i
className={cx('fas', { className={cx('fas', {
'fa-search': !searching, 'fa-search': !searching,
'fa-spin fa-spinner': searching, 'fa-spin fa-spinner': searching,
})} })}
/> />
</button> </button>
</div> </div>
<legend> <legend>
<h3>Tips and tricks</h3> <h3>Tips and tricks</h3>
<ul> <ul>
<li> <li>
You can only search brews with this tool if they are You can only search brews with this tool if they are
published published
</li> </li>
<li> <li>
Usernames are case sensitive, make sure you are writing Usernames are case sensitive, make sure you are writing
it correctly it correctly
</li> </li>
<li> <li>
You can use <code>-</code> to negate words, assuming You can use <code>-</code> to negate words, assuming
there is any word not negated, and <code>"word"</code> there is any word not negated, and <code>"word"</code>
to specify an exact string. to specify an exact string.
</li> </li>
<li> <li>
Some words like a, after, through, itself, or here, are Some words like a, after, through, itself, or here, are
ignored in searches, make sure your search has relevant ignored in searches, make sure your search has relevant
words. The full list can be found &nbsp; words. The full list can be found &nbsp;
<a href="https://github.com/mongodb/mongo/blob/0e3b3ca8480ddddf5d0105d11a94bd4698335312/src/mongo/db/fts/stop_words_english.txt"> <a href="https://github.com/mongodb/mongo/blob/0e3b3ca8480ddddf5d0105d11a94bd4698335312/src/mongo/db/fts/stop_words_english.txt">
here here
</a> </a>
</li> </li>
</ul> </ul>
</legend> </legend>
<small></small> <small></small>
</div> </div>
); );
const renderPaginationControls = () => { const renderPaginationControls = () => {
if (!totalBrews) return null; if (!totalBrews) return null;
const countInt = parseInt(count); const countInt = parseInt(count);
const totalPages = Math.ceil(totalBrews / countInt); const totalPages = Math.ceil(totalBrews / countInt);
let startPage, endPage; let startPage, endPage;
if (page <= 6) { if (page <= 6) {
startPage = 1; startPage = 1;
endPage = Math.min(totalPages, 10); endPage = Math.min(totalPages, 10);
} else if (page + 4 >= totalPages) { } else if (page + 4 >= totalPages) {
startPage = Math.max(1, totalPages - 9); startPage = Math.max(1, totalPages - 9);
endPage = totalPages; endPage = totalPages;
} else { } else {
startPage = page - 5; startPage = page - 5;
endPage = page + 4; endPage = page + 4;
} }
const pagesAroundCurrent = new Array(endPage - startPage + 1) const pagesAroundCurrent = new Array(endPage - startPage + 1)
.fill() .fill()
.map((_, index) => ( .map((_, index) => (
<a <a
key={startPage + index} key={startPage + index}
className={`pageNumber ${ className={`pageNumber ${
page === startPage + index ? 'currentPage' : '' page === startPage + index ? 'currentPage' : ''
}`} }`}
onClick={() => loadPage(startPage + index, false, false)} onClick={() => loadPage(startPage + index, false, false)}
> >
{startPage + index} {startPage + index}
</a> </a>
)); ));
return ( return (
<div className="paginationControls"> <div className="paginationControls">
<button <button
className="previousPage" className="previousPage"
onClick={() => loadPage(page - 1, false, false)} onClick={() => loadPage(page - 1, false, false)}
disabled={page === startPage} disabled={page === startPage}
> >
<i className="fa-solid fa-chevron-left"></i> <i className="fa-solid fa-chevron-left"></i>
</button> </button>
<ol className="pages"> <ol className="pages">
{startPage > 1 && ( {startPage > 1 && (
<a <a
className="pageNumber firstPage" className="pageNumber firstPage"
onClick={() => loadPage(1, false, false)} onClick={() => loadPage(1, false, false)}
> >
1 ... 1 ...
</a> </a>
)} )}
{pagesAroundCurrent} {pagesAroundCurrent}
{endPage < totalPages && ( {endPage < totalPages && (
<a <a
className="pageNumber lastPage" className="pageNumber lastPage"
onClick={() => loadPage(totalPages, false, false)} onClick={() => loadPage(totalPages, false, false)}
> >
... {totalPages} ... {totalPages}
</a> </a>
)} )}
</ol> </ol>
<button <button
className="nextPage" className="nextPage"
onClick={() => loadPage(page + 1, false, false)} onClick={() => loadPage(page + 1, false, false)}
disabled={page === totalPages} disabled={page === totalPages}
> >
<i className="fa-solid fa-chevron-right"></i> <i className="fa-solid fa-chevron-right"></i>
</button> </button>
</div> </div>
); );
}; };
const renderFoundBrews = () => { const renderFoundBrews = () => {
if (searching) { if (searching) {
return ( return (
<div className="foundBrews searching"> <div className="foundBrews searching">
<h3 className="searchAnim">Searching</h3> <h3 className="searchAnim">Searching</h3>
</div> </div>
); );
} }
if (error) { if (error) {
console.log('render Error: ', error); console.log('render Error: ', error);
let errorMessage; let errorMessage;
switch (error.errorCode) { switch (error.errorCode) {
case '404': case '404':
errorMessage = "404 - We didn't find any brew"; errorMessage = "404 - We didn't find any brew";
break; break;
case '503': case '503':
errorMessage = errorMessage =
'503 - Service Unavailable, try again later, sorry.'; '503 - Service Unavailable, try again later, sorry.';
break; break;
case '500': case '500':
errorMessage = errorMessage =
"500 - We don't know what happened, go ahead and contact the mods or report as a mistake."; "500 - We don't know what happened, go ahead and contact the mods or report as a mistake.";
break; break;
default: default:
errorMessage = 'An unexpected error occurred'; errorMessage = 'An unexpected error occurred';
} }
return ( return (
<div className="foundBrews noBrews"> <div className="foundBrews noBrews">
<h3>Error: {errorMessage}</h3> <h3>Error: {errorMessage}</h3>
</div> </div>
); );
} }
if (!brewCollection) { if (!brewCollection) {
return ( return (
<div className="foundBrews noBrews"> <div className="foundBrews noBrews">
<h3>No search yet</h3> <h3>No search yet</h3>
</div> </div>
); );
} }
if (brewCollection.length === 0) { if (brewCollection.length === 0) {
return ( return (
<div className="foundBrews noBrews"> <div className="foundBrews noBrews">
<h3>No brews found</h3> <h3>No brews found</h3>
</div> </div>
); );
} }
return ( return (
<div className="foundBrews"> <div className="foundBrews">
<span className="totalBrews"> <span className="totalBrews">
{`Brews found: `} {`Brews found: `}
<span>{totalBrews}</span> <span>{totalBrews}</span>
</span> </span>
{brewCollection.map((brew, index) => ( {brewCollection.map((brew, index) => (
<BrewItem <BrewItem
brew={brew} brew={brew}
key={index} key={index}
reportError={props.reportError} reportError={props.reportError}
/> />
))} ))}
{renderPaginationControls()} {renderPaginationControls()}
</div> </div>
); );
}; };
return ( return (
<div className="vaultPage"> <div className="vaultPage">
<link href="/themes/V3/Blank/style.css" rel="stylesheet" /> <link href="/themes/V3/Blank/style.css" rel="stylesheet" />
<link href="/themes/V3/5ePHB/style.css" rel="stylesheet" /> <link href="/themes/V3/5ePHB/style.css" rel="stylesheet" />
{renderNavItems()} {renderNavItems()}
<div className="content"> <div className="content">
<SplitPane hideMoveArrows> <SplitPane hideMoveArrows>
<div className="form dataGroup">{renderForm()}</div> <div className="form dataGroup">{renderForm()}</div>
<div className="resultsContainer dataGroup"> <div className="resultsContainer dataGroup">
{renderFoundBrews()} {renderFoundBrews()}
</div> </div>
</SplitPane> </SplitPane>
</div> </div>
</div> </div>
); );
}; };
module.exports = VaultPage; module.exports = VaultPage;

View File

@@ -5,121 +5,121 @@ const HomebrewModel = require('./homebrew.model.js').model;
const router = express.Router(); const router = express.Router();
const buildTitleConditions = (title) => { const buildTitleConditions = (title) => {
if (!title) return {}; if (!title) return {};
return { return {
$text: { $text: {
$search: title, $search: title,
$caseSensitive: false, $caseSensitive: false,
}, },
}; };
}; };
const buildAuthorConditions = (author) => { const buildAuthorConditions = (author) => {
if (!author) return {}; if (!author) return {};
return { authors: author }; return { authors: author };
}; };
//"$and": [ {"published": true}, {"$text": { "$search": "titleString", "$caseSensitive": false } }, { "authors" : "authorString"}] //"$and": [ {"published": true}, {"$text": { "$search": "titleString", "$caseSensitive": false } }, { "authors" : "authorString"}]
//is a good example of a query constructed with this function //is a good example of a query constructed with this function
const handleErrorResponse = (res, error, functionName) => { const handleErrorResponse = (res, error, functionName) => {
const status = error.response?.status || 500; const status = error.response?.status || 500;
const message = const message =
status === 503 ? 'Service Unavailable' : 'Internal Server Error'; status === 503 ? 'Service Unavailable' : 'Internal Server Error';
console.error(`Error in ${functionName}:`, error); console.error(`Error in ${functionName}:`, error);
return res.status(status).json({ return res.status(status).json({
errorCode: status.toString(), errorCode: status.toString(),
message: `Error in function ${functionName}: ${message}`, message: `Error in function ${functionName}: ${message}`,
}); });
}; };
const buildBrewsQuery = (legacy, v3) => { const buildBrewsQuery = (legacy, v3) => {
const brewsQuery = { published: true }; const brewsQuery = { published: true };
if (legacy === 'true' && v3 === 'true') return { published: true }; if (legacy === 'true' && v3 === 'true') return { published: true };
if (legacy === 'true' && v3 !== 'true') { if (legacy === 'true' && v3 !== 'true') {
brewsQuery.renderer = 'legacy'; brewsQuery.renderer = 'legacy';
} else if (v3 === 'true' && legacy !== 'true') { } else if (v3 === 'true' && legacy !== 'true') {
brewsQuery.renderer = 'V3'; brewsQuery.renderer = 'V3';
} }
return brewsQuery; return brewsQuery;
}; };
const vault = { const vault = {
findBrews: async (req, res) => { findBrews: async (req, res) => {
try { try {
const title = req.query.title || ''; const title = req.query.title || '';
const author = req.query.author || ''; const author = req.query.author || '';
const page = Math.max(parseInt(req.query.page) || 1, 1); const page = Math.max(parseInt(req.query.page) || 1, 1);
const mincount = 10; const mincount = 10;
const count = Math.max(parseInt(req.query.count) || 20, mincount); const count = Math.max(parseInt(req.query.count) || 20, mincount);
const skip = (page - 1) * count; const skip = (page - 1) * count;
const brewsQuery = buildBrewsQuery(req.query.legacy, req.query.v3); const brewsQuery = buildBrewsQuery(req.query.legacy, req.query.v3);
const titleConditions = buildTitleConditions(title); const titleConditions = buildTitleConditions(title);
const authorConditions = buildAuthorConditions(author); const authorConditions = buildAuthorConditions(author);
const combinedQuery = { const combinedQuery = {
$and: [brewsQuery, titleConditions, authorConditions], $and: [brewsQuery, titleConditions, authorConditions],
}; };
const projection = { const projection = {
editId: 0, editId: 0,
googleId: 0, googleId: 0,
text: 0, text: 0,
textBin: 0, textBin: 0,
version: 0, version: 0,
thumbnail: 0, thumbnail: 0,
}; };
const brews = await HomebrewModel.find(combinedQuery, projection) const brews = await HomebrewModel.find(combinedQuery, projection)
.skip(skip) .skip(skip)
.limit(count) .limit(count)
.maxTimeMS(5000) .maxTimeMS(5000)
.exec(); .exec();
console.log( console.log(
'Query in findBrews: ', 'Query in findBrews: ',
JSON.stringify(combinedQuery, null, 2) JSON.stringify(combinedQuery, null, 2)
); );
return res.json({ brews, page }); return res.json({ brews, page });
} catch (error) { } catch (error) {
console.error(error); console.error(error);
return handleErrorResponse(res, error, 'findBrews'); return handleErrorResponse(res, error, 'findBrews');
} }
}, },
findTotal: async (req, res) => { findTotal: async (req, res) => {
try { try {
const title = req.query.title || ''; const title = req.query.title || '';
const author = req.query.author || ''; const author = req.query.author || '';
const brewsQuery = buildBrewsQuery(req.query.legacy, req.query.v3); const brewsQuery = buildBrewsQuery(req.query.legacy, req.query.v3);
const titleConditions = buildTitleConditions(title); const titleConditions = buildTitleConditions(title);
const authorConditions = buildAuthorConditions(author); const authorConditions = buildAuthorConditions(author);
const combinedQuery = { const combinedQuery = {
$and: [brewsQuery, titleConditions, authorConditions], $and: [brewsQuery, titleConditions, authorConditions],
}; };
const totalBrews = await HomebrewModel.countDocuments( const totalBrews = await HomebrewModel.countDocuments(
combinedQuery combinedQuery
); );
console.log( console.log(
'when returning, the total of brews is ', 'when returning, the total of brews is ',
totalBrews, totalBrews,
'for the query', 'for the query',
JSON.stringify(combinedQuery) JSON.stringify(combinedQuery)
); );
return res.json({ totalBrews }); return res.json({ totalBrews });
} catch (error) { } catch (error) {
console.error(error); console.error(error);
return handleErrorResponse(res, error, 'findTotal'); return handleErrorResponse(res, error, 'findTotal');
} }
}, },
}; };
router.get('/api/vault/total', asyncHandler(vault.findTotal)); router.get('/api/vault/total', asyncHandler(vault.findTotal));