require('./vaultPage.less'); const React = require('react'); const { useState, useEffect, useRef } = React; const Nav = require('naturalcrit/nav/nav.jsx'); const Navbar = require('../../navbar/navbar.jsx'); const RecentNavItem = require('../../navbar/recent.navitem.jsx').both; const Account = require('../../navbar/account.navitem.jsx'); const NewBrew = require('../../navbar/newbrew.navitem.jsx'); const HelpNavItem = require('../../navbar/help.navitem.jsx'); const BrewItem = require('../basePages/listPage/brewItem/brewItem.jsx'); const SplitPane = require('../../../../shared/naturalcrit/splitPane/splitPane.jsx'); const request = require('../../utils/request-middleware.js'); const VaultPage = (props) => { const [title, setTitle] = useState(props.query.title || ''); //state author const [author, setAuthor] = useState(props.query.author || ''); const [legacy, setLegacy] = useState(props.query.legacy !== 'false'); const [v3, setV3] = useState(props.query.v3 !== 'false'); const [count, setCount] = useState(props.query.count || 20); const [page, setPage] = useState(parseInt(props.query.page) || 1); const [brewCollection, setBrewCollection] = useState(null); const [totalBrews, setTotalBrews] = useState(null); const [searching, setSearching] = useState(false); const [error, setError] = useState(null); const titleRef = useRef(null); const authorRef = useRef(null); const countRef = useRef(null); const v3Ref = useRef(null); const legacyRef = useRef(null); const submitButtonRef = useRef(null); useEffect(() => { disableSubmitIfFormInvalid(); loadPage(page, false, true); }, []); const updateStateWithBrews = (brews, page) => { setBrewCollection(brews || null); setPage(parseInt(page) || 1); setSearching(false); }; const updateUrl = (title, author, count, v3, legacy, page) => { const url = new URL(window.location.href); const urlParams = new URLSearchParams(); Object.entries({ title, author, count, v3, legacy, page, }).forEach(([key, value]) => urlParams.set(key, value)); url.search = urlParams.toString(); window.history.replaceState(null, null, url); }; const performSearch = async ({ title, author, count, v3, legacy }) => { updateUrl(title, author, count, v3, legacy, page); console.log(title, author, count, v3, legacy); if ((title || author) && (v3 || legacy)) { const response = await request.get( `/api/vault?title=${title}&author=${author}&v3=${v3}&legacy=${legacy}&count=${count}&page=${page}` ).catch((error)=>{ console.log('error at loadPage: ', error); setError(`${error.response ? error.response.status : error.message}` ); updateStateWithBrews([], 1); }); if (response.ok) updateStateWithBrews(response.body.brews, page); } else { setError('404'); } }; const loadTotal = async ({ title, v3, legacy }) => { setTotalBrews(null); setError(null); if ((title || author) && (v3 || legacy)) { const response = await request.get( `/api/vault/total?title=${title}&author=${author}&v3=${v3}&legacy=${legacy}` ).catch((error)=>{ console.log('error at loadTotal: ', error); setError(`${error.response ? error.response.status : error.message}` ); }); if (response.ok) updateStateWithBrews(response.body.brews, page); } }; const loadPage = async (page, update, total) => { //Different searches use the update or total props to make only the necessary queries and functions if (!validateForm()) { return; } setSearching(true); setError(null); const title = titleRef.current.value || ''; const author = authorRef.current.value || ''; const count = countRef.current.value || 10; const v3 = v3Ref.current.checked != false; const legacy = legacyRef.current.checked != false; console.log(title); if (update) { setTitle(title); setAuthor(author); setCount(count); setV3(v3); setLegacy(legacy); } // Perform search with the latest input values, because state is not fast enough performSearch({ title, author, count, v3, legacy }); if (total) { loadTotal({ title, author, v3, legacy }); } }; const renderNavItems = () => ( Vault: Search for brews ); const validateForm = () => { //form validity: title or author must be written, and at least one renderer set const isTitleValid = titleRef.current.validity.valid && titleRef.current.value; const isAuthorValid = authorRef.current.validity.valid && authorRef.current.value; const isCheckboxChecked = legacyRef.current.checked || v3Ref.current.checked; const isFormValid = (isTitleValid || isAuthorValid) && isCheckboxChecked; return isFormValid; }; const disableSubmitIfFormInvalid = () => { submitButtonRef.current.disabled = !validateForm(); }; const renderForm = () => (

Brew Lookup

Tips and tricks

  • Only published brews are searchable via this tool
  • Usernames are case sensitive, make sure you are writing it correctly
  • Use "word" to match an exact string, and - to exclude words (at least one word must not be negated).
  • Some common words like "a", "after", "through", "itself", "here", etc., are ignored in searches. The full list can be found   here
); const renderPaginationControls = () => { if (!totalBrews) return null; const countInt = parseInt(count); const totalPages = Math.ceil(totalBrews / countInt); let startPage, endPage; if (page <= 6) { startPage = 1; endPage = Math.min(totalPages, 10); } else if (page + 4 >= totalPages) { startPage = Math.max(1, totalPages - 9); endPage = totalPages; } else { startPage = page - 5; endPage = page + 4; } const pagesAroundCurrent = new Array(endPage - startPage + 1) .fill() .map((_, index) => ( loadPage(startPage + index, false, false)} > {startPage + index} )); return (
    {startPage > 1 && ( loadPage(1, false, false)} > 1 ... )} {pagesAroundCurrent} {endPage < totalPages && ( loadPage(totalPages, false, false)} > ... {totalPages} )}
); }; const renderFoundBrews = () => { if (searching) { return (

Searching

); } if (error) { console.log('render Error: ', error); let errorMessage; switch (error.errorCode) { case '404': errorMessage = "404 - We didn't find any brew"; break; case '503': errorMessage = '503 - Service Unavailable, try again later, sorry.'; break; case '500': errorMessage = "500 - We don't know what happened, go ahead and contact the mods or report as a mistake."; break; default: errorMessage = 'An unexpected error occurred'; } return (

Error: {errorMessage}

); } if (!brewCollection) { return (

No search yet

); } if (brewCollection.length === 0) { return (

No brews found

); } return (
{`Brews found: `} {totalBrews} {brewCollection.map((brew, index) => { const processedAuthors = brew.authors.map(author => author.includes('@') ? 'hidden' : author ); return ( ); })} {renderPaginationControls()}
); }; return (
{renderNavItems()}
{renderForm()}
{renderFoundBrews()}
); }; module.exports = VaultPage;