{"version":3,"file":"savedEntries-9836b456.js","sources":["../../../src/js/modules/saved-entries.js"],"sourcesContent":["import FetchWrapper from './fetch-wrapper.js';\n\nconst API = new FetchWrapper( window.origin );\n\n// To use this, you'll need to add a button to any entry you want saveable:\n// \n// \tSave\n// \n//\n// You'll also need to add the JS and CSS to any page that needs it:\n// {{ craft.vite.script('src/js/modules/saved-entries.js', false) }}\n//\n// In the screen.pcss file:\n// @import \"components/saved-entries.pcss\";\n\nfunction initialiseSaveButtons() { // Sets the state etc for all save buttons on the page\n\tconst saveButtons = document.querySelectorAll('button[data-save-button]');\n\tlet savedEntryIds = [];\n\n\tif ( localStorage.getItem('savedEntryIds') ) {\n\t\tsavedEntryIds = JSON.parse( localStorage.getItem('savedEntryIds') );\n\t}\n\n\tsaveButtons.forEach(saveButton => {\n\t\tif(!saveButton.dataset.entryId) {\n\t\t\tconsole.error(`Button is missing a data-entry-id parameter value`);\n\t\t\treturn null;\n\t\t}\n\n\t\tconsole.log({savedEntryIds, saveButton});\n\n\t\tif (savedEntryIds.includes( saveButton.dataset.entryId )) {\n\t\t\t// The button we're looking at already has its associated entry in localStorage\n\t\t\tsaveButton.dataset.state = 'saved';\n\t\t\tsaveButton.setAttribute('aria-label', 'Remove this');\n\t\t\tsaveButton.querySelector('span').textContent = 'Remove this';\n\t\t} else {\n\t\t\tsaveButton.dataset.state = null;\n\t\t\tsaveButton.setAttribute('aria-label', 'Save this');\n\t\t\tsaveButton.querySelector('span').textContent = 'Save this';\n\t\t}\n\n\t\tsaveButton.addEventListener('click', handleSaveButtonClick);\n\t});\n}\n\nfunction handleSaveButtonClick( event ) { // Hand off to the correct action function when clicked\n\tconst clickedButton = event.currentTarget;\n\n\tif(!clickedButton.dataset.state || !clickedButton.dataset.entryId) {\n\t\tconsole.error( `Button missing required data attributes` );\n\t\treturn false;\n\t}\n\n\tif (clickedButton.dataset.state === 'saved') {\n\t\tunsave( clickedButton );\n\t} else {\n\t\tsave( clickedButton );\n\t}\n\n\t// The state has changed, so lets refresh the drawer contents\n\tconsole.log('please repopulate...');\n\tpopulateMySavedDrawer();\n}\n\nfunction save( clickedButton ) {\n\t// Do what we need when a button is clicked to store a \"save/like\"\n\t// we know the button has the attributes we need as the handleSaveClick function has enforced that\n\n\tconst candidateEntryId = clickedButton.dataset.entryId;\n\tlet savedEntries = [];\n\n\tif ( localStorage.getItem('savedEntryIds') ) {\n\t\tsavedEntries = JSON.parse( localStorage.getItem('savedEntryIds') );\n\t}\n\n\tif( savedEntries.includes( candidateEntryId ) ) {\n\t\tconsole.error(`Entry is already saved`);\n\t\treturn false;\n\t}\n\n\tsavedEntries.push( candidateEntryId );\n\tlocalStorage.setItem('savedEntryIds', JSON.stringify( savedEntries ) );\n\n\tclickedButton.dataset.state = 'saved';\n\tclickedButton.setAttribute('aria-label', `Remove this`);\n\tclickedButton.querySelector('span').textContent = 'Remove this';\n\n\tlocalStorage.setItem('mySavedEntriesStatus', 'stale');\n}\n\nfunction unsave( clickedButton ) {\n\t// Do what we need when a button is clicked to remove a \"like\"\n\t// we know the button has the attributes we need as the handleLikeClick function has enforced that\n\n\tconst candidateEntryId = clickedButton.dataset.entryId;\n\tlet savedEntries = [];\n\n\tif ( localStorage.getItem('savedEntryIds') ) {\n\t\tsavedEntries = JSON.parse( localStorage.getItem('savedEntryIds') );\n\t}\n\n\tif( ! savedEntries.includes( candidateEntryId ) ) {\n\t\tconsole.error(`Entry is not in the saved list`);\n\t\treturn false;\n\t}\n\n\tsavedEntries.splice( savedEntries.indexOf( candidateEntryId ), 1 );\n\tlocalStorage.setItem('savedEntryIds', JSON.stringify( savedEntries) );\n\n\tclickedButton.dataset.state = null;\n\tclickedButton.setAttribute('aria-label', `Save this`);\n\tclickedButton.querySelector('span').textContent = 'Save this';\n\n\t/* Find any other buttons for this same element on the page which are waiting for an \"unsave\" click, and update those */\n\tdocument.querySelectorAll(`button[data-entry-id='${candidateEntryId}'][data-state='saved']`).forEach( otherButton => {\n\t\totherButton.dataset.state = null;\n\t\totherButton.setAttribute('aria-label', `Save this`);\n\t\totherButton.querySelector('span').textContent = 'Save this';\n\t});\n\n\tlet parent = clickedButton.closest('.cardListing');\n\tparent?.classList?.add('js-justRemoved');\n\n\tlocalStorage.setItem('mySavedEntriesStatus', 'stale');\n}\n\nfunction populateMySavedDrawer() {\n\tlet entryIds = JSON.parse( localStorage.getItem('savedEntryIds') ).join(',');\n\tconsole.log(`/saved-entries?entryIds=${entryIds}`);\n\n\tif (!entryIds) {\n\t\tconsole.log('No entries in local storage');\n\t\tdocument.querySelector('#mySavedEntries .theSavedEntries').innerHTML = `

There are no saved items.

`;\n\t\treturn;\n\t}\n\n\tAPI.getHtml(`/saved-entries?entryIds=${entryIds}`).then(response => {\n\t\tlet responseAsDOM = document.createRange().createContextualFragment(response);\n\t\tdocument.querySelector('#mySavedEntries .theSavedEntries').replaceChildren(responseAsDOM);\n\n\t\tinitialiseSaveButtons(); // Re-initialise, because the loaded content can itself have like buttons inside\n\t\tlocalStorage.setItem('mySavedEntriesStatus', 'fresh');\n\t});\n}\n\nfunction toggleMySavedDrawer() {\n\tlet myFavRow = document.querySelector('#mySavedEntries');\n\tmyFavRow.classList.toggle('active');\n}\n\nfunction initialiseMySavedDrawer() {\n\t// First, build and add the drawer to the mark-up\n\tconst drawer = `\n\t\t
\n\t\t\t
\n\t\t\t\t\n\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

There are no saved items.

\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t
\n\t\t
`;\n\tdocument.querySelector('body').insertAdjacentHTML('beforeend', drawer);\n\n\t// They want another toggle in the header now too\n\tconst headerToggle =\n\t\t`
  • \n\t\t\t\n\t\t
  • `;\n\tdocument.querySelector('header .sm ul').insertAdjacentHTML('afterbegin', headerToggle);\n\n\t// as this is the initial load, ensure state management knows we have no items dynamically loaded into the drawer yet\n\tlocalStorage.setItem('mySavedEntriesStatus', 'stale');\n\n\tconst showHideToggles = document.querySelectorAll('button.toggleMySavedEntries');\n\n\tshowHideToggles.forEach( toggle => {\n\t\ttoggle.addEventListener('click', handleMySavedButtonClick);\n\t});\n}\n\nfunction handleMySavedButtonClick() {\n\tlet savedEntries = [];\n\n\tif (localStorage.getItem('savedEntryIds')) {\n\t\tsavedEntries = JSON.parse(localStorage.getItem('savedEntryIds'));\n\t}\n\n\tif (\n\t\tsavedEntries.length > 0\n\t\t&&\n\t\tlocalStorage.getItem('mySavedEntriesStatus') !== 'fresh'\n\t) {\n\t\tconsole.log('You have items saved, but they need to be loaded via fetch');\n\n\t\t// Replace default drawer message with \"Loading message\"\n\t\tdocument.querySelector('#mySavedEntries .theSavedEntries').innerHTML = `

    Loading

    `;\n\n\t\tpopulateMySavedDrawer();\n\t\ttoggleMySavedDrawer();\n\t} else {\n\t\tconsole.log('just show/hide whatever content is in the div at the moment');\n\n\t\ttoggleMySavedDrawer();\n\t}\n}\n\ninitialiseMySavedDrawer(); // create the panel full of saved items\ninitialiseSaveButtons(); // the heart toggles on various Entry listing items\n"],"names":["API","FetchWrapper","initialiseSaveButtons","saveButtons","savedEntryIds","saveButton","handleSaveButtonClick","event","clickedButton","unsave","save","populateMySavedDrawer","candidateEntryId","savedEntries","otherButton","parent","_a","entryIds","response","responseAsDOM","toggleMySavedDrawer","initialiseMySavedDrawer","drawer","headerToggle","toggle","handleMySavedButtonClick"],"mappings":"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"}