From 2b0fbca335ea86c0af82c815ba2175f8c19ebe5f Mon Sep 17 00:00:00 2001 From: Kayo Tusthler Date: Wed, 25 Mar 2026 02:53:26 -0300 Subject: [PATCH 1/4] feat: add favorite function --- .gitignore | 3 + .nvmrc | 1 + assets/icons/heart.png | Bin 0 -> 17200 bytes assets/scripts/index.ts | 58 +++ assets/scss/index.scss | 19 + dist/index.css | 19 + dist/index.css.map | 1 + dist/index.js | 769 +++++++++++++++++++++++++++++++ dist/index.js.map | 1 + index.ts | 2 + package.json | 16 + src/dbHandler.php | 56 +++ src/restHandler.php | 115 +++++ wordpress-back-end-challenge.php | 83 ++++ 14 files changed, 1143 insertions(+) create mode 100644 .gitignore create mode 100644 .nvmrc create mode 100644 assets/icons/heart.png create mode 100644 assets/scripts/index.ts create mode 100644 assets/scss/index.scss create mode 100644 dist/index.css create mode 100644 dist/index.css.map create mode 100644 dist/index.js create mode 100644 dist/index.js.map create mode 100644 index.ts create mode 100644 package.json create mode 100644 src/dbHandler.php create mode 100644 src/restHandler.php create mode 100644 wordpress-back-end-challenge.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..85badb3b --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +*.lock +.parcel-cache/ \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..5afafd98 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v23.11.0 diff --git a/assets/icons/heart.png b/assets/icons/heart.png new file mode 100644 index 0000000000000000000000000000000000000000..07dad0f038351c914d2ee52e467de2109f304f60 GIT binary patch literal 17200 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 literal 0 HcmV?d00001 diff --git a/assets/scripts/index.ts b/assets/scripts/index.ts new file mode 100644 index 00000000..198dce8d --- /dev/null +++ b/assets/scripts/index.ts @@ -0,0 +1,58 @@ +const favoritePosts = { + init() { + if (!this.component) return; + + this.addEventListeners(); + }, + + addEventListeners() { + this.component.addEventListener('click', this.handleClick.bind(this)); + }, + + async getUserId() { + // @ts-ignore + return fetch(wpApiSettings.root + 'wp/v2/users/me', { + method: 'GET', + headers: { + // @ts-ignore + 'X-WP-Nonce': wpApiSettings.nonce + } + }) + .then(response => response.json()) + .then(user => user.id) + .catch(error => { + console.error('Erro:', error); + return null; + }); + }, + + async handleClick() { + const userId = await this.getUserId(); + if (!userId) return; + + // @ts-ignore + fetch(wpApiSettings.root + wpApiSettings.rest_namespace + '/favorite-posts', { + method: 'POST', + body: JSON.stringify({ + post_id: this.component.dataset.postId, + user_id: userId + }), + headers: { + 'Content-Type': 'application/json', + // @ts-ignore + 'X-WP-Nonce': wpApiSettings.nonce + } + }) + .then(response => response.json()) + .then(data => { + console.log(data); + }) + .catch(error => { + console.error('Erro:', error); + }); + }, + + component: document.querySelector('.favorite-post-button'), +} + +favoritePosts.init(); diff --git a/assets/scss/index.scss b/assets/scss/index.scss new file mode 100644 index 00000000..907611e5 --- /dev/null +++ b/assets/scss/index.scss @@ -0,0 +1,19 @@ +.favorite-post-button { + background: none; + border: none; + cursor: pointer; + display: block; + opacity: 0.5; + padding: 0; + transition: opacity 0.3s ease; + + &:hover, + &.is-favorite { + opacity: 1; + } + + img { + height: 32px; + pointer-events: none; + } +} \ No newline at end of file diff --git a/dist/index.css b/dist/index.css new file mode 100644 index 00000000..b549c123 --- /dev/null +++ b/dist/index.css @@ -0,0 +1,19 @@ +.favorite-post-button { + cursor: pointer; + opacity: .5; + background: none; + border: none; + padding: 0; + transition: opacity .3s; + display: block; +} + +.favorite-post-button:hover, .favorite-post-button.is-favorite { + opacity: 1; +} + +.favorite-post-button img { + pointer-events: none; + height: 32px; +} +/*# sourceMappingURL=index.css.map */ diff --git a/dist/index.css.map b/dist/index.css.map new file mode 100644 index 00000000..ee35f84f --- /dev/null +++ b/dist/index.css.map @@ -0,0 +1 @@ +{"mappings":"AAAA;;;;;;;;;;AASI;;;;AAKA","sources":["assets/scss/index.scss"],"sourcesContent":[".favorite-post-button {\n background: none;\n border: none;\n cursor: pointer;\n display: block;\n opacity: 0.5;\n padding: 0;\n transition: opacity 0.3s ease;\n\n &:hover,\n &.is-favorite {\n opacity: 1;\n }\n\n img {\n height: 32px;\n pointer-events: none;\n }\n}"],"names":[],"version":3,"file":"index.css.map","sourceRoot":"../"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 00000000..8e6169fa --- /dev/null +++ b/dist/index.js @@ -0,0 +1,769 @@ +// modules are defined as an array +// [ module function, map of requires ] +// +// map of requires is short require name -> numeric require +// +// anything defined in a previous bundle is accessed via the +// orig method which is the require for previous bundles + +(function ( + modules, + entry, + mainEntry, + parcelRequireName, + externals, + distDir, + publicUrl, + devServer +) { + /* eslint-disable no-undef */ + var globalObject = + typeof globalThis !== 'undefined' + ? globalThis + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : typeof global !== 'undefined' + ? global + : {}; + /* eslint-enable no-undef */ + + // Save the require from previous bundle to this closure if any + var previousRequire = + typeof globalObject[parcelRequireName] === 'function' && + globalObject[parcelRequireName]; + + var importMap = previousRequire.i || {}; + var cache = previousRequire.cache || {}; + // Do not use `require` to prevent Webpack from trying to bundle this call + var nodeRequire = + typeof module !== 'undefined' && + typeof module.require === 'function' && + module.require.bind(module); + + function newRequire(name, jumped) { + if (!cache[name]) { + if (!modules[name]) { + if (externals[name]) { + return externals[name]; + } + // if we cannot find the module within our internal map or + // cache jump to the current global require ie. the last bundle + // that was added to the page. + var currentRequire = + typeof globalObject[parcelRequireName] === 'function' && + globalObject[parcelRequireName]; + if (!jumped && currentRequire) { + return currentRequire(name, true); + } + + // If there are other bundles on this page the require from the + // previous one is saved to 'previousRequire'. Repeat this as + // many times as there are bundles until the module is found or + // we exhaust the require chain. + if (previousRequire) { + return previousRequire(name, true); + } + + // Try the node require function if it exists. + if (nodeRequire && typeof name === 'string') { + return nodeRequire(name); + } + + var err = new Error("Cannot find module '" + name + "'"); + err.code = 'MODULE_NOT_FOUND'; + throw err; + } + + localRequire.resolve = resolve; + localRequire.cache = {}; + + var module = (cache[name] = new newRequire.Module(name)); + + modules[name][0].call( + module.exports, + localRequire, + module, + module.exports, + globalObject + ); + } + + return cache[name].exports; + + function localRequire(x) { + var res = localRequire.resolve(x); + if (res === false) { + return {}; + } + // Synthesize a module to follow re-exports. + if (Array.isArray(res)) { + var m = {__esModule: true}; + res.forEach(function (v) { + var key = v[0]; + var id = v[1]; + var exp = v[2] || v[0]; + var x = newRequire(id); + if (key === '*') { + Object.keys(x).forEach(function (key) { + if ( + key === 'default' || + key === '__esModule' || + Object.prototype.hasOwnProperty.call(m, key) + ) { + return; + } + + Object.defineProperty(m, key, { + enumerable: true, + get: function () { + return x[key]; + }, + }); + }); + } else if (exp === '*') { + Object.defineProperty(m, key, { + enumerable: true, + value: x, + }); + } else { + Object.defineProperty(m, key, { + enumerable: true, + get: function () { + if (exp === 'default') { + return x.__esModule ? x.default : x; + } + return x[exp]; + }, + }); + } + }); + return m; + } + return newRequire(res); + } + + function resolve(x) { + var id = modules[name][1][x]; + return id != null ? id : x; + } + } + + function Module(moduleName) { + this.id = moduleName; + this.bundle = newRequire; + this.require = nodeRequire; + this.exports = {}; + } + + newRequire.isParcelRequire = true; + newRequire.Module = Module; + newRequire.modules = modules; + newRequire.cache = cache; + newRequire.parent = previousRequire; + newRequire.distDir = distDir; + newRequire.publicUrl = publicUrl; + newRequire.devServer = devServer; + newRequire.i = importMap; + newRequire.register = function (id, exports) { + modules[id] = [ + function (require, module) { + module.exports = exports; + }, + {}, + ]; + }; + + // Only insert newRequire.load when it is actually used. + // The code in this file is linted against ES5, so dynamic import is not allowed. + // INSERT_LOAD_HERE + + Object.defineProperty(newRequire, 'root', { + get: function () { + return globalObject[parcelRequireName]; + }, + }); + + globalObject[parcelRequireName] = newRequire; + + for (var i = 0; i < entry.length; i++) { + newRequire(entry[i]); + } + + if (mainEntry) { + // Expose entry point to Node, AMD or browser globals + // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js + var mainExports = newRequire(mainEntry); + + // CommonJS + if (typeof exports === 'object' && typeof module !== 'undefined') { + module.exports = mainExports; + + // RequireJS + } else if (typeof define === 'function' && define.amd) { + define(function () { + return mainExports; + }); + } + } +})({"1Mq6V":[function(require,module,exports,__globalThis) { +var global = arguments[3]; +var HMR_HOST = null; +var HMR_PORT = 1234; +var HMR_SERVER_PORT = 1234; +var HMR_SECURE = false; +var HMR_ENV_HASH = "d6ea1d42532a7575"; +var HMR_USE_SSE = false; +module.bundle.HMR_BUNDLE_ID = "78fcd0ac8e9bd240"; +"use strict"; +/* global HMR_HOST, HMR_PORT, HMR_SERVER_PORT, HMR_ENV_HASH, HMR_SECURE, HMR_USE_SSE, chrome, browser, __parcel__import__, __parcel__importScripts__, ServiceWorkerGlobalScope */ /*:: +import type { + HMRAsset, + HMRMessage, +} from '@parcel/reporter-dev-server/src/HMRServer.js'; +interface ParcelRequire { + (string): mixed; + cache: {|[string]: ParcelModule|}; + hotData: {|[string]: mixed|}; + Module: any; + parent: ?ParcelRequire; + isParcelRequire: true; + modules: {|[string]: [Function, {|[string]: string|}]|}; + HMR_BUNDLE_ID: string; + root: ParcelRequire; +} +interface ParcelModule { + hot: {| + data: mixed, + accept(cb: (Function) => void): void, + dispose(cb: (mixed) => void): void, + // accept(deps: Array | string, cb: (Function) => void): void, + // decline(): void, + _acceptCallbacks: Array<(Function) => void>, + _disposeCallbacks: Array<(mixed) => void>, + |}; +} +interface ExtensionContext { + runtime: {| + reload(): void, + getURL(url: string): string; + getManifest(): {manifest_version: number, ...}; + |}; +} +declare var module: {bundle: ParcelRequire, ...}; +declare var HMR_HOST: string; +declare var HMR_PORT: string; +declare var HMR_SERVER_PORT: string; +declare var HMR_ENV_HASH: string; +declare var HMR_SECURE: boolean; +declare var HMR_USE_SSE: boolean; +declare var chrome: ExtensionContext; +declare var browser: ExtensionContext; +declare var __parcel__import__: (string) => Promise; +declare var __parcel__importScripts__: (string) => Promise; +declare var globalThis: typeof self; +declare var ServiceWorkerGlobalScope: Object; +*/ var OVERLAY_ID = '__parcel__error__overlay__'; +var OldModule = module.bundle.Module; +function Module(moduleName) { + OldModule.call(this, moduleName); + this.hot = { + data: module.bundle.hotData[moduleName], + _acceptCallbacks: [], + _disposeCallbacks: [], + accept: function(fn) { + this._acceptCallbacks.push(fn || function() {}); + }, + dispose: function(fn) { + this._disposeCallbacks.push(fn); + } + }; + module.bundle.hotData[moduleName] = undefined; +} +module.bundle.Module = Module; +module.bundle.hotData = {}; +var checkedAssets /*: {|[string]: boolean|} */ , disposedAssets /*: {|[string]: boolean|} */ , assetsToDispose /*: Array<[ParcelRequire, string]> */ , assetsToAccept /*: Array<[ParcelRequire, string]> */ , bundleNotFound = false; +function getHostname() { + return HMR_HOST || (typeof location !== 'undefined' && location.protocol.indexOf('http') === 0 ? location.hostname : 'localhost'); +} +function getPort() { + return HMR_PORT || (typeof location !== 'undefined' ? location.port : HMR_SERVER_PORT); +} +// eslint-disable-next-line no-redeclare +let WebSocket = globalThis.WebSocket; +if (!WebSocket && typeof module.bundle.root === 'function') try { + // eslint-disable-next-line no-global-assign + WebSocket = module.bundle.root('ws'); +} catch { +// ignore. +} +var hostname = getHostname(); +var port = getPort(); +var protocol = HMR_SECURE || typeof location !== 'undefined' && location.protocol === 'https:' && ![ + 'localhost', + '127.0.0.1', + '0.0.0.0' +].includes(hostname) ? 'wss' : 'ws'; +// eslint-disable-next-line no-redeclare +var parent = module.bundle.parent; +if (!parent || !parent.isParcelRequire) { + // Web extension context + var extCtx = typeof browser === 'undefined' ? typeof chrome === 'undefined' ? null : chrome : browser; + // Safari doesn't support sourceURL in error stacks. + // eval may also be disabled via CSP, so do a quick check. + var supportsSourceURL = false; + try { + (0, eval)('throw new Error("test"); //# sourceURL=test.js'); + } catch (err) { + supportsSourceURL = err.stack.includes('test.js'); + } + var ws; + if (HMR_USE_SSE) ws = new EventSource('/__parcel_hmr'); + else try { + // If we're running in the dev server's node runner, listen for messages on the parent port. + let { workerData, parentPort } = module.bundle.root('node:worker_threads') /*: any*/ ; + if (workerData !== null && workerData !== void 0 && workerData.__parcel) { + parentPort.on('message', async (message)=>{ + try { + await handleMessage(message); + parentPort.postMessage('updated'); + } catch { + parentPort.postMessage('restart'); + } + }); + // After the bundle has finished running, notify the dev server that the HMR update is complete. + queueMicrotask(()=>parentPort.postMessage('ready')); + } + } catch { + if (typeof WebSocket !== 'undefined') try { + ws = new WebSocket(protocol + '://' + hostname + (port ? ':' + port : '') + '/'); + } catch (err) { + // Ignore cloudflare workers error. + if (err.message && !err.message.includes('Disallowed operation called within global scope')) console.error(err.message); + } + } + if (ws) { + // $FlowFixMe + ws.onmessage = async function(event /*: {data: string, ...} */ ) { + var data /*: HMRMessage */ = JSON.parse(event.data); + await handleMessage(data); + }; + if (ws instanceof WebSocket) { + ws.onerror = function(e) { + if (e.message) console.error(e.message); + }; + ws.onclose = function() { + console.warn("[parcel] \uD83D\uDEA8 Connection to the HMR server was lost"); + }; + } + } +} +async function handleMessage(data /*: HMRMessage */ ) { + checkedAssets = {} /*: {|[string]: boolean|} */ ; + disposedAssets = {} /*: {|[string]: boolean|} */ ; + assetsToAccept = []; + assetsToDispose = []; + bundleNotFound = false; + if (data.type === 'reload') fullReload(); + else if (data.type === 'update') { + // Remove error overlay if there is one + if (typeof document !== 'undefined') removeErrorOverlay(); + let assets = data.assets; + // Handle HMR Update + let handled = assets.every((asset)=>{ + return asset.type === 'css' || asset.type === 'js' && hmrAcceptCheck(module.bundle.root, asset.id, asset.depsByBundle); + }); + // Dispatch a custom event in case a bundle was not found. This might mean + // an asset on the server changed and we should reload the page. This event + // gives the client an opportunity to refresh without losing state + // (e.g. via React Server Components). If e.preventDefault() is not called, + // we will trigger a full page reload. + if (handled && bundleNotFound && assets.some((a)=>a.envHash !== HMR_ENV_HASH) && typeof window !== 'undefined' && typeof CustomEvent !== 'undefined') handled = !window.dispatchEvent(new CustomEvent('parcelhmrreload', { + cancelable: true + })); + if (handled) { + console.clear(); + // Dispatch custom event so other runtimes (e.g React Refresh) are aware. + if (typeof window !== 'undefined' && typeof CustomEvent !== 'undefined') window.dispatchEvent(new CustomEvent('parcelhmraccept')); + await hmrApplyUpdates(assets); + hmrDisposeQueue(); + // Run accept callbacks. This will also re-execute other disposed assets in topological order. + let processedAssets = {}; + for(let i = 0; i < assetsToAccept.length; i++){ + let id = assetsToAccept[i][1]; + if (!processedAssets[id]) { + hmrAccept(assetsToAccept[i][0], id); + processedAssets[id] = true; + } + } + } else fullReload(); + } + if (data.type === 'error') { + // Log parcel errors to console + for (let ansiDiagnostic of data.diagnostics.ansi){ + let stack = ansiDiagnostic.codeframe ? ansiDiagnostic.codeframe : ansiDiagnostic.stack; + console.error("\uD83D\uDEA8 [parcel]: " + ansiDiagnostic.message + '\n' + stack + '\n\n' + ansiDiagnostic.hints.join('\n')); + } + if (typeof document !== 'undefined') { + // Render the fancy html overlay + removeErrorOverlay(); + var overlay = createErrorOverlay(data.diagnostics.html); + // $FlowFixMe + document.body.appendChild(overlay); + } + } +} +function removeErrorOverlay() { + var overlay = document.getElementById(OVERLAY_ID); + if (overlay) { + overlay.remove(); + console.log("[parcel] \u2728 Error resolved"); + } +} +function createErrorOverlay(diagnostics) { + var overlay = document.createElement('div'); + overlay.id = OVERLAY_ID; + let errorHTML = '
'; + for (let diagnostic of diagnostics){ + let stack = diagnostic.frames.length ? diagnostic.frames.reduce((p, frame)=>{ + return `${p} +${frame.location} +${frame.code}`; + }, '') : diagnostic.stack; + errorHTML += ` +
+
+ \u{1F6A8} ${diagnostic.message} +
+
${stack}
+
+ ${diagnostic.hints.map((hint)=>"
\uD83D\uDCA1 " + hint + '
').join('')} +
+ ${diagnostic.documentation ? `
\u{1F4DD} Learn more
` : ''} +
+ `; + } + errorHTML += '
'; + overlay.innerHTML = errorHTML; + return overlay; +} +function fullReload() { + if (typeof location !== 'undefined' && 'reload' in location) location.reload(); + else if (typeof extCtx !== 'undefined' && extCtx && extCtx.runtime && extCtx.runtime.reload) extCtx.runtime.reload(); + else try { + let { workerData, parentPort } = module.bundle.root('node:worker_threads') /*: any*/ ; + if (workerData !== null && workerData !== void 0 && workerData.__parcel) parentPort.postMessage('restart'); + } catch (err) { + console.error("[parcel] \u26A0\uFE0F An HMR update was not accepted. Please restart the process."); + } +} +function getParents(bundle, id) /*: Array<[ParcelRequire, string]> */ { + var modules = bundle.modules; + if (!modules) return []; + var parents = []; + var k, d, dep; + for(k in modules)for(d in modules[k][1]){ + dep = modules[k][1][d]; + if (dep === id || Array.isArray(dep) && dep[dep.length - 1] === id) parents.push([ + bundle, + k + ]); + } + if (bundle.parent) parents = parents.concat(getParents(bundle.parent, id)); + return parents; +} +function updateLink(link) { + var href = link.getAttribute('href'); + if (!href) return; + var newLink = link.cloneNode(); + newLink.onload = function() { + if (link.parentNode !== null) // $FlowFixMe + link.parentNode.removeChild(link); + }; + newLink.setAttribute('href', // $FlowFixMe + href.split('?')[0] + '?' + Date.now()); + // $FlowFixMe + link.parentNode.insertBefore(newLink, link.nextSibling); +} +var cssTimeout = null; +function reloadCSS() { + if (cssTimeout || typeof document === 'undefined') return; + cssTimeout = setTimeout(function() { + var links = document.querySelectorAll('link[rel="stylesheet"]'); + for(var i = 0; i < links.length; i++){ + // $FlowFixMe[incompatible-type] + var href /*: string */ = links[i].getAttribute('href'); + var hostname = getHostname(); + var servedFromHMRServer = hostname === 'localhost' ? new RegExp('^(https?:\\/\\/(0.0.0.0|127.0.0.1)|localhost):' + getPort()).test(href) : href.indexOf(hostname + ':' + getPort()); + var absolute = /^https?:\/\//i.test(href) && href.indexOf(location.origin) !== 0 && !servedFromHMRServer; + if (!absolute) updateLink(links[i]); + } + cssTimeout = null; + }, 50); +} +function hmrDownload(asset) { + if (asset.type === 'js') { + if (typeof document !== 'undefined') { + let script = document.createElement('script'); + script.src = asset.url + '?t=' + Date.now(); + if (asset.outputFormat === 'esmodule') script.type = 'module'; + return new Promise((resolve, reject)=>{ + var _document$head; + script.onload = ()=>resolve(script); + script.onerror = reject; + (_document$head = document.head) === null || _document$head === void 0 || _document$head.appendChild(script); + }); + } else if (typeof importScripts === 'function') { + // Worker scripts + if (asset.outputFormat === 'esmodule') return import(asset.url + '?t=' + Date.now()); + else return new Promise((resolve, reject)=>{ + try { + importScripts(asset.url + '?t=' + Date.now()); + resolve(); + } catch (err) { + reject(err); + } + }); + } + } +} +async function hmrApplyUpdates(assets) { + global.parcelHotUpdate = Object.create(null); + let scriptsToRemove; + try { + // If sourceURL comments aren't supported in eval, we need to load + // the update from the dev server over HTTP so that stack traces + // are correct in errors/logs. This is much slower than eval, so + // we only do it if needed (currently just Safari). + // https://bugs.webkit.org/show_bug.cgi?id=137297 + // This path is also taken if a CSP disallows eval. + if (!supportsSourceURL) { + let promises = assets.map((asset)=>{ + var _hmrDownload; + return (_hmrDownload = hmrDownload(asset)) === null || _hmrDownload === void 0 ? void 0 : _hmrDownload.catch((err)=>{ + // Web extension fix + if (extCtx && extCtx.runtime && extCtx.runtime.getManifest().manifest_version == 3 && typeof ServiceWorkerGlobalScope != 'undefined' && global instanceof ServiceWorkerGlobalScope) { + extCtx.runtime.reload(); + return; + } + throw err; + }); + }); + scriptsToRemove = await Promise.all(promises); + } + assets.forEach(function(asset) { + hmrApply(module.bundle.root, asset); + }); + } finally{ + delete global.parcelHotUpdate; + if (scriptsToRemove) scriptsToRemove.forEach((script)=>{ + if (script) { + var _document$head2; + (_document$head2 = document.head) === null || _document$head2 === void 0 || _document$head2.removeChild(script); + } + }); + } +} +function hmrApply(bundle /*: ParcelRequire */ , asset /*: HMRAsset */ ) { + var modules = bundle.modules; + if (!modules) return; + if (asset.type === 'css') reloadCSS(); + else if (asset.type === 'js') { + let deps = asset.depsByBundle[bundle.HMR_BUNDLE_ID]; + if (deps) { + if (modules[asset.id]) { + // Remove dependencies that are removed and will become orphaned. + // This is necessary so that if the asset is added back again, the cache is gone, and we prevent a full page reload. + let oldDeps = modules[asset.id][1]; + for(let dep in oldDeps)if (!deps[dep] || deps[dep] !== oldDeps[dep]) { + let id = oldDeps[dep]; + let parents = getParents(module.bundle.root, id); + if (parents.length === 1) hmrDelete(module.bundle.root, id); + } + } + if (supportsSourceURL) // Global eval. We would use `new Function` here but browser + // support for source maps is better with eval. + (0, eval)(asset.output); + // $FlowFixMe + let fn = global.parcelHotUpdate[asset.id]; + modules[asset.id] = [ + fn, + deps + ]; + } + // Always traverse to the parent bundle, even if we already replaced the asset in this bundle. + // This is required in case modules are duplicated. We need to ensure all instances have the updated code. + if (bundle.parent) hmrApply(bundle.parent, asset); + } +} +function hmrDelete(bundle, id) { + let modules = bundle.modules; + if (!modules) return; + if (modules[id]) { + // Collect dependencies that will become orphaned when this module is deleted. + let deps = modules[id][1]; + let orphans = []; + for(let dep in deps){ + let parents = getParents(module.bundle.root, deps[dep]); + if (parents.length === 1) orphans.push(deps[dep]); + } + // Delete the module. This must be done before deleting dependencies in case of circular dependencies. + delete modules[id]; + delete bundle.cache[id]; + // Now delete the orphans. + orphans.forEach((id)=>{ + hmrDelete(module.bundle.root, id); + }); + } else if (bundle.parent) hmrDelete(bundle.parent, id); +} +function hmrAcceptCheck(bundle /*: ParcelRequire */ , id /*: string */ , depsByBundle /*: ?{ [string]: { [string]: string } }*/ ) { + checkedAssets = {}; + if (hmrAcceptCheckOne(bundle, id, depsByBundle)) return true; + // Traverse parents breadth first. All possible ancestries must accept the HMR update, or we'll reload. + let parents = getParents(module.bundle.root, id); + let accepted = false; + while(parents.length > 0){ + let v = parents.shift(); + let a = hmrAcceptCheckOne(v[0], v[1], null); + if (a) // If this parent accepts, stop traversing upward, but still consider siblings. + accepted = true; + else if (a !== null) { + // Otherwise, queue the parents in the next level upward. + let p = getParents(module.bundle.root, v[1]); + if (p.length === 0) { + // If there are no parents, then we've reached an entry without accepting. Reload. + accepted = false; + break; + } + parents.push(...p); + } + } + return accepted; +} +function hmrAcceptCheckOne(bundle /*: ParcelRequire */ , id /*: string */ , depsByBundle /*: ?{ [string]: { [string]: string } }*/ ) { + var modules = bundle.modules; + if (!modules) return; + if (depsByBundle && !depsByBundle[bundle.HMR_BUNDLE_ID]) { + // If we reached the root bundle without finding where the asset should go, + // there's nothing to do. Mark as "accepted" so we don't reload the page. + if (!bundle.parent) { + bundleNotFound = true; + return true; + } + return hmrAcceptCheckOne(bundle.parent, id, depsByBundle); + } + if (checkedAssets[id]) return null; + checkedAssets[id] = true; + var cached = bundle.cache[id]; + if (!cached) return true; + assetsToDispose.push([ + bundle, + id + ]); + if (cached && cached.hot && cached.hot._acceptCallbacks.length) { + assetsToAccept.push([ + bundle, + id + ]); + return true; + } + return false; +} +function hmrDisposeQueue() { + // Dispose all old assets. + for(let i = 0; i < assetsToDispose.length; i++){ + let id = assetsToDispose[i][1]; + if (!disposedAssets[id]) { + hmrDispose(assetsToDispose[i][0], id); + disposedAssets[id] = true; + } + } + assetsToDispose = []; +} +function hmrDispose(bundle /*: ParcelRequire */ , id /*: string */ ) { + var cached = bundle.cache[id]; + bundle.hotData[id] = {}; + if (cached && cached.hot) cached.hot.data = bundle.hotData[id]; + if (cached && cached.hot && cached.hot._disposeCallbacks.length) cached.hot._disposeCallbacks.forEach(function(cb) { + cb(bundle.hotData[id]); + }); + delete bundle.cache[id]; +} +function hmrAccept(bundle /*: ParcelRequire */ , id /*: string */ ) { + // Execute the module. + bundle(id); + // Run the accept callbacks in the new version of the module. + var cached = bundle.cache[id]; + if (cached && cached.hot && cached.hot._acceptCallbacks.length) { + let assetsToAlsoAccept = []; + cached.hot._acceptCallbacks.forEach(function(cb) { + let additionalAssets = cb(function() { + return getParents(module.bundle.root, id); + }); + if (Array.isArray(additionalAssets) && additionalAssets.length) assetsToAlsoAccept.push(...additionalAssets); + }); + if (assetsToAlsoAccept.length) { + let handled = assetsToAlsoAccept.every(function(a) { + return hmrAcceptCheck(a[0], a[1]); + }); + if (!handled) return fullReload(); + hmrDisposeQueue(); + } + } +} + +},{}],"1jwFz":[function(require,module,exports,__globalThis) { +var _indexTs = require("./assets/scripts/index.ts"); +var _indexScss = require("./assets/scss/index.scss"); + +},{"./assets/scripts/index.ts":"cmXY9","./assets/scss/index.scss":"6ebKA"}],"cmXY9":[function(require,module,exports,__globalThis) { +const favoritePosts = { + init () { + if (!this.component) return; + this.addEventListeners(); + }, + addEventListeners () { + this.component.addEventListener('click', this.handleClick.bind(this)); + }, + async getUserId () { + // @ts-ignore + return fetch(wpApiSettings.root + 'wp/v2/users/me', { + method: 'GET', + headers: { + // @ts-ignore + 'X-WP-Nonce': wpApiSettings.nonce + } + }).then((response)=>response.json()).then((user)=>user.id).catch((error)=>{ + console.error('Erro:', error); + return null; + }); + }, + async handleClick () { + const userId = await this.getUserId(); + if (!userId) return; + // @ts-ignore + fetch(wpApiSettings.root + wpApiSettings.rest_namespace + '/favorite-posts', { + method: 'POST', + body: JSON.stringify({ + post_id: this.component.dataset.postId, + user_id: userId + }), + headers: { + 'Content-Type': 'application/json', + // @ts-ignore + 'X-WP-Nonce': wpApiSettings.nonce + } + }).then((response)=>response.json()).then((data)=>{ + console.log(data); + }).catch((error)=>{ + console.error('Erro:', error); + }); + }, + component: document.querySelector('.favorite-post-button') +}; +favoritePosts.init(); + +},{}],"6ebKA":[function() {},{}]},["1Mq6V","1jwFz"], "1jwFz", "parcelRequire2f3a", {}) + +//# sourceMappingURL=index.js.map diff --git a/dist/index.js.map b/dist/index.js.map new file mode 100644 index 00000000..2238f480 --- /dev/null +++ b/dist/index.js.map @@ -0,0 +1 @@ +{"mappings":"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","sources":["node_modules/@parcel/runtime-browser-hmr/lib/runtime-92f870de140ddc88.js","index.ts","assets/scripts/index.ts"],"sourcesContent":["var HMR_HOST = null;var HMR_PORT = 1234;var HMR_SERVER_PORT = 1234;var HMR_SECURE = false;var HMR_ENV_HASH = \"d6ea1d42532a7575\";var HMR_USE_SSE = false;module.bundle.HMR_BUNDLE_ID = \"78fcd0ac8e9bd240\";\"use strict\";\n\n/* global HMR_HOST, HMR_PORT, HMR_SERVER_PORT, HMR_ENV_HASH, HMR_SECURE, HMR_USE_SSE, chrome, browser, __parcel__import__, __parcel__importScripts__, ServiceWorkerGlobalScope */\n/*::\nimport type {\n HMRAsset,\n HMRMessage,\n} from '@parcel/reporter-dev-server/src/HMRServer.js';\ninterface ParcelRequire {\n (string): mixed;\n cache: {|[string]: ParcelModule|};\n hotData: {|[string]: mixed|};\n Module: any;\n parent: ?ParcelRequire;\n isParcelRequire: true;\n modules: {|[string]: [Function, {|[string]: string|}]|};\n HMR_BUNDLE_ID: string;\n root: ParcelRequire;\n}\ninterface ParcelModule {\n hot: {|\n data: mixed,\n accept(cb: (Function) => void): void,\n dispose(cb: (mixed) => void): void,\n // accept(deps: Array | string, cb: (Function) => void): void,\n // decline(): void,\n _acceptCallbacks: Array<(Function) => void>,\n _disposeCallbacks: Array<(mixed) => void>,\n |};\n}\ninterface ExtensionContext {\n runtime: {|\n reload(): void,\n getURL(url: string): string;\n getManifest(): {manifest_version: number, ...};\n |};\n}\ndeclare var module: {bundle: ParcelRequire, ...};\ndeclare var HMR_HOST: string;\ndeclare var HMR_PORT: string;\ndeclare var HMR_SERVER_PORT: string;\ndeclare var HMR_ENV_HASH: string;\ndeclare var HMR_SECURE: boolean;\ndeclare var HMR_USE_SSE: boolean;\ndeclare var chrome: ExtensionContext;\ndeclare var browser: ExtensionContext;\ndeclare var __parcel__import__: (string) => Promise;\ndeclare var __parcel__importScripts__: (string) => Promise;\ndeclare var globalThis: typeof self;\ndeclare var ServiceWorkerGlobalScope: Object;\n*/\nvar OVERLAY_ID = '__parcel__error__overlay__';\nvar OldModule = module.bundle.Module;\nfunction Module(moduleName) {\n OldModule.call(this, moduleName);\n this.hot = {\n data: module.bundle.hotData[moduleName],\n _acceptCallbacks: [],\n _disposeCallbacks: [],\n accept: function (fn) {\n this._acceptCallbacks.push(fn || function () {});\n },\n dispose: function (fn) {\n this._disposeCallbacks.push(fn);\n }\n };\n module.bundle.hotData[moduleName] = undefined;\n}\nmodule.bundle.Module = Module;\nmodule.bundle.hotData = {};\nvar checkedAssets /*: {|[string]: boolean|} */,\n disposedAssets /*: {|[string]: boolean|} */,\n assetsToDispose /*: Array<[ParcelRequire, string]> */,\n assetsToAccept /*: Array<[ParcelRequire, string]> */,\n bundleNotFound = false;\nfunction getHostname() {\n return HMR_HOST || (typeof location !== 'undefined' && location.protocol.indexOf('http') === 0 ? location.hostname : 'localhost');\n}\nfunction getPort() {\n return HMR_PORT || (typeof location !== 'undefined' ? location.port : HMR_SERVER_PORT);\n}\n\n// eslint-disable-next-line no-redeclare\nlet WebSocket = globalThis.WebSocket;\nif (!WebSocket && typeof module.bundle.root === 'function') {\n try {\n // eslint-disable-next-line no-global-assign\n WebSocket = module.bundle.root('ws');\n } catch {\n // ignore.\n }\n}\nvar hostname = getHostname();\nvar port = getPort();\nvar protocol = HMR_SECURE || typeof location !== 'undefined' && location.protocol === 'https:' && !['localhost', '127.0.0.1', '0.0.0.0'].includes(hostname) ? 'wss' : 'ws';\n\n// eslint-disable-next-line no-redeclare\nvar parent = module.bundle.parent;\nif (!parent || !parent.isParcelRequire) {\n // Web extension context\n var extCtx = typeof browser === 'undefined' ? typeof chrome === 'undefined' ? null : chrome : browser;\n\n // Safari doesn't support sourceURL in error stacks.\n // eval may also be disabled via CSP, so do a quick check.\n var supportsSourceURL = false;\n try {\n (0, eval)('throw new Error(\"test\"); //# sourceURL=test.js');\n } catch (err) {\n supportsSourceURL = err.stack.includes('test.js');\n }\n var ws;\n if (HMR_USE_SSE) {\n ws = new EventSource('/__parcel_hmr');\n } else {\n try {\n // If we're running in the dev server's node runner, listen for messages on the parent port.\n let {\n workerData,\n parentPort\n } = module.bundle.root('node:worker_threads') /*: any*/;\n if (workerData !== null && workerData !== void 0 && workerData.__parcel) {\n parentPort.on('message', async message => {\n try {\n await handleMessage(message);\n parentPort.postMessage('updated');\n } catch {\n parentPort.postMessage('restart');\n }\n });\n\n // After the bundle has finished running, notify the dev server that the HMR update is complete.\n queueMicrotask(() => parentPort.postMessage('ready'));\n }\n } catch {\n if (typeof WebSocket !== 'undefined') {\n try {\n ws = new WebSocket(protocol + '://' + hostname + (port ? ':' + port : '') + '/');\n } catch (err) {\n // Ignore cloudflare workers error.\n if (err.message && !err.message.includes('Disallowed operation called within global scope')) {\n console.error(err.message);\n }\n }\n }\n }\n }\n if (ws) {\n // $FlowFixMe\n ws.onmessage = async function (event /*: {data: string, ...} */) {\n var data /*: HMRMessage */ = JSON.parse(event.data);\n await handleMessage(data);\n };\n if (ws instanceof WebSocket) {\n ws.onerror = function (e) {\n if (e.message) {\n console.error(e.message);\n }\n };\n ws.onclose = function () {\n console.warn('[parcel] 🚨 Connection to the HMR server was lost');\n };\n }\n }\n}\nasync function handleMessage(data /*: HMRMessage */) {\n checkedAssets = {} /*: {|[string]: boolean|} */;\n disposedAssets = {} /*: {|[string]: boolean|} */;\n assetsToAccept = [];\n assetsToDispose = [];\n bundleNotFound = false;\n if (data.type === 'reload') {\n fullReload();\n } else if (data.type === 'update') {\n // Remove error overlay if there is one\n if (typeof document !== 'undefined') {\n removeErrorOverlay();\n }\n let assets = data.assets;\n\n // Handle HMR Update\n let handled = assets.every(asset => {\n return asset.type === 'css' || asset.type === 'js' && hmrAcceptCheck(module.bundle.root, asset.id, asset.depsByBundle);\n });\n\n // Dispatch a custom event in case a bundle was not found. This might mean\n // an asset on the server changed and we should reload the page. This event\n // gives the client an opportunity to refresh without losing state\n // (e.g. via React Server Components). If e.preventDefault() is not called,\n // we will trigger a full page reload.\n if (handled && bundleNotFound && assets.some(a => a.envHash !== HMR_ENV_HASH) && typeof window !== 'undefined' && typeof CustomEvent !== 'undefined') {\n handled = !window.dispatchEvent(new CustomEvent('parcelhmrreload', {\n cancelable: true\n }));\n }\n if (handled) {\n console.clear();\n\n // Dispatch custom event so other runtimes (e.g React Refresh) are aware.\n if (typeof window !== 'undefined' && typeof CustomEvent !== 'undefined') {\n window.dispatchEvent(new CustomEvent('parcelhmraccept'));\n }\n await hmrApplyUpdates(assets);\n hmrDisposeQueue();\n\n // Run accept callbacks. This will also re-execute other disposed assets in topological order.\n let processedAssets = {};\n for (let i = 0; i < assetsToAccept.length; i++) {\n let id = assetsToAccept[i][1];\n if (!processedAssets[id]) {\n hmrAccept(assetsToAccept[i][0], id);\n processedAssets[id] = true;\n }\n }\n } else fullReload();\n }\n if (data.type === 'error') {\n // Log parcel errors to console\n for (let ansiDiagnostic of data.diagnostics.ansi) {\n let stack = ansiDiagnostic.codeframe ? ansiDiagnostic.codeframe : ansiDiagnostic.stack;\n console.error('🚨 [parcel]: ' + ansiDiagnostic.message + '\\n' + stack + '\\n\\n' + ansiDiagnostic.hints.join('\\n'));\n }\n if (typeof document !== 'undefined') {\n // Render the fancy html overlay\n removeErrorOverlay();\n var overlay = createErrorOverlay(data.diagnostics.html);\n // $FlowFixMe\n document.body.appendChild(overlay);\n }\n }\n}\nfunction removeErrorOverlay() {\n var overlay = document.getElementById(OVERLAY_ID);\n if (overlay) {\n overlay.remove();\n console.log('[parcel] ✨ Error resolved');\n }\n}\nfunction createErrorOverlay(diagnostics) {\n var overlay = document.createElement('div');\n overlay.id = OVERLAY_ID;\n let errorHTML = '
';\n for (let diagnostic of diagnostics) {\n let stack = diagnostic.frames.length ? diagnostic.frames.reduce((p, frame) => {\n return `${p}\n${frame.location}\n${frame.code}`;\n }, '') : diagnostic.stack;\n errorHTML += `\n
\n
\n 🚨 ${diagnostic.message}\n
\n
${stack}
\n
\n ${diagnostic.hints.map(hint => '
💡 ' + hint + '
').join('')}\n
\n ${diagnostic.documentation ? `` : ''}\n
\n `;\n }\n errorHTML += '
';\n overlay.innerHTML = errorHTML;\n return overlay;\n}\nfunction fullReload() {\n if (typeof location !== 'undefined' && 'reload' in location) {\n location.reload();\n } else if (typeof extCtx !== 'undefined' && extCtx && extCtx.runtime && extCtx.runtime.reload) {\n extCtx.runtime.reload();\n } else {\n try {\n let {\n workerData,\n parentPort\n } = module.bundle.root('node:worker_threads') /*: any*/;\n if (workerData !== null && workerData !== void 0 && workerData.__parcel) {\n parentPort.postMessage('restart');\n }\n } catch (err) {\n console.error('[parcel] ⚠️ An HMR update was not accepted. Please restart the process.');\n }\n }\n}\nfunction getParents(bundle, id) /*: Array<[ParcelRequire, string]> */{\n var modules = bundle.modules;\n if (!modules) {\n return [];\n }\n var parents = [];\n var k, d, dep;\n for (k in modules) {\n for (d in modules[k][1]) {\n dep = modules[k][1][d];\n if (dep === id || Array.isArray(dep) && dep[dep.length - 1] === id) {\n parents.push([bundle, k]);\n }\n }\n }\n if (bundle.parent) {\n parents = parents.concat(getParents(bundle.parent, id));\n }\n return parents;\n}\nfunction updateLink(link) {\n var href = link.getAttribute('href');\n if (!href) {\n return;\n }\n var newLink = link.cloneNode();\n newLink.onload = function () {\n if (link.parentNode !== null) {\n // $FlowFixMe\n link.parentNode.removeChild(link);\n }\n };\n newLink.setAttribute('href',\n // $FlowFixMe\n href.split('?')[0] + '?' + Date.now());\n // $FlowFixMe\n link.parentNode.insertBefore(newLink, link.nextSibling);\n}\nvar cssTimeout = null;\nfunction reloadCSS() {\n if (cssTimeout || typeof document === 'undefined') {\n return;\n }\n cssTimeout = setTimeout(function () {\n var links = document.querySelectorAll('link[rel=\"stylesheet\"]');\n for (var i = 0; i < links.length; i++) {\n // $FlowFixMe[incompatible-type]\n var href /*: string */ = links[i].getAttribute('href');\n var hostname = getHostname();\n var servedFromHMRServer = hostname === 'localhost' ? new RegExp('^(https?:\\\\/\\\\/(0.0.0.0|127.0.0.1)|localhost):' + getPort()).test(href) : href.indexOf(hostname + ':' + getPort());\n var absolute = /^https?:\\/\\//i.test(href) && href.indexOf(location.origin) !== 0 && !servedFromHMRServer;\n if (!absolute) {\n updateLink(links[i]);\n }\n }\n cssTimeout = null;\n }, 50);\n}\nfunction hmrDownload(asset) {\n if (asset.type === 'js') {\n if (typeof document !== 'undefined') {\n let script = document.createElement('script');\n script.src = asset.url + '?t=' + Date.now();\n if (asset.outputFormat === 'esmodule') {\n script.type = 'module';\n }\n return new Promise((resolve, reject) => {\n var _document$head;\n script.onload = () => resolve(script);\n script.onerror = reject;\n (_document$head = document.head) === null || _document$head === void 0 || _document$head.appendChild(script);\n });\n } else if (typeof importScripts === 'function') {\n // Worker scripts\n if (asset.outputFormat === 'esmodule') {\n return __parcel__import__(asset.url + '?t=' + Date.now());\n } else {\n return new Promise((resolve, reject) => {\n try {\n __parcel__importScripts__(asset.url + '?t=' + Date.now());\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n }\n }\n }\n}\nasync function hmrApplyUpdates(assets) {\n global.parcelHotUpdate = Object.create(null);\n let scriptsToRemove;\n try {\n // If sourceURL comments aren't supported in eval, we need to load\n // the update from the dev server over HTTP so that stack traces\n // are correct in errors/logs. This is much slower than eval, so\n // we only do it if needed (currently just Safari).\n // https://bugs.webkit.org/show_bug.cgi?id=137297\n // This path is also taken if a CSP disallows eval.\n if (!supportsSourceURL) {\n let promises = assets.map(asset => {\n var _hmrDownload;\n return (_hmrDownload = hmrDownload(asset)) === null || _hmrDownload === void 0 ? void 0 : _hmrDownload.catch(err => {\n // Web extension fix\n if (extCtx && extCtx.runtime && extCtx.runtime.getManifest().manifest_version == 3 && typeof ServiceWorkerGlobalScope != 'undefined' && global instanceof ServiceWorkerGlobalScope) {\n extCtx.runtime.reload();\n return;\n }\n throw err;\n });\n });\n scriptsToRemove = await Promise.all(promises);\n }\n assets.forEach(function (asset) {\n hmrApply(module.bundle.root, asset);\n });\n } finally {\n delete global.parcelHotUpdate;\n if (scriptsToRemove) {\n scriptsToRemove.forEach(script => {\n if (script) {\n var _document$head2;\n (_document$head2 = document.head) === null || _document$head2 === void 0 || _document$head2.removeChild(script);\n }\n });\n }\n }\n}\nfunction hmrApply(bundle /*: ParcelRequire */, asset /*: HMRAsset */) {\n var modules = bundle.modules;\n if (!modules) {\n return;\n }\n if (asset.type === 'css') {\n reloadCSS();\n } else if (asset.type === 'js') {\n let deps = asset.depsByBundle[bundle.HMR_BUNDLE_ID];\n if (deps) {\n if (modules[asset.id]) {\n // Remove dependencies that are removed and will become orphaned.\n // This is necessary so that if the asset is added back again, the cache is gone, and we prevent a full page reload.\n let oldDeps = modules[asset.id][1];\n for (let dep in oldDeps) {\n if (!deps[dep] || deps[dep] !== oldDeps[dep]) {\n let id = oldDeps[dep];\n let parents = getParents(module.bundle.root, id);\n if (parents.length === 1) {\n hmrDelete(module.bundle.root, id);\n }\n }\n }\n }\n if (supportsSourceURL) {\n // Global eval. We would use `new Function` here but browser\n // support for source maps is better with eval.\n (0, eval)(asset.output);\n }\n\n // $FlowFixMe\n let fn = global.parcelHotUpdate[asset.id];\n modules[asset.id] = [fn, deps];\n }\n\n // Always traverse to the parent bundle, even if we already replaced the asset in this bundle.\n // This is required in case modules are duplicated. We need to ensure all instances have the updated code.\n if (bundle.parent) {\n hmrApply(bundle.parent, asset);\n }\n }\n}\nfunction hmrDelete(bundle, id) {\n let modules = bundle.modules;\n if (!modules) {\n return;\n }\n if (modules[id]) {\n // Collect dependencies that will become orphaned when this module is deleted.\n let deps = modules[id][1];\n let orphans = [];\n for (let dep in deps) {\n let parents = getParents(module.bundle.root, deps[dep]);\n if (parents.length === 1) {\n orphans.push(deps[dep]);\n }\n }\n\n // Delete the module. This must be done before deleting dependencies in case of circular dependencies.\n delete modules[id];\n delete bundle.cache[id];\n\n // Now delete the orphans.\n orphans.forEach(id => {\n hmrDelete(module.bundle.root, id);\n });\n } else if (bundle.parent) {\n hmrDelete(bundle.parent, id);\n }\n}\nfunction hmrAcceptCheck(bundle /*: ParcelRequire */, id /*: string */, depsByBundle /*: ?{ [string]: { [string]: string } }*/) {\n checkedAssets = {};\n if (hmrAcceptCheckOne(bundle, id, depsByBundle)) {\n return true;\n }\n\n // Traverse parents breadth first. All possible ancestries must accept the HMR update, or we'll reload.\n let parents = getParents(module.bundle.root, id);\n let accepted = false;\n while (parents.length > 0) {\n let v = parents.shift();\n let a = hmrAcceptCheckOne(v[0], v[1], null);\n if (a) {\n // If this parent accepts, stop traversing upward, but still consider siblings.\n accepted = true;\n } else if (a !== null) {\n // Otherwise, queue the parents in the next level upward.\n let p = getParents(module.bundle.root, v[1]);\n if (p.length === 0) {\n // If there are no parents, then we've reached an entry without accepting. Reload.\n accepted = false;\n break;\n }\n parents.push(...p);\n }\n }\n return accepted;\n}\nfunction hmrAcceptCheckOne(bundle /*: ParcelRequire */, id /*: string */, depsByBundle /*: ?{ [string]: { [string]: string } }*/) {\n var modules = bundle.modules;\n if (!modules) {\n return;\n }\n if (depsByBundle && !depsByBundle[bundle.HMR_BUNDLE_ID]) {\n // If we reached the root bundle without finding where the asset should go,\n // there's nothing to do. Mark as \"accepted\" so we don't reload the page.\n if (!bundle.parent) {\n bundleNotFound = true;\n return true;\n }\n return hmrAcceptCheckOne(bundle.parent, id, depsByBundle);\n }\n if (checkedAssets[id]) {\n return null;\n }\n checkedAssets[id] = true;\n var cached = bundle.cache[id];\n if (!cached) {\n return true;\n }\n assetsToDispose.push([bundle, id]);\n if (cached && cached.hot && cached.hot._acceptCallbacks.length) {\n assetsToAccept.push([bundle, id]);\n return true;\n }\n return false;\n}\nfunction hmrDisposeQueue() {\n // Dispose all old assets.\n for (let i = 0; i < assetsToDispose.length; i++) {\n let id = assetsToDispose[i][1];\n if (!disposedAssets[id]) {\n hmrDispose(assetsToDispose[i][0], id);\n disposedAssets[id] = true;\n }\n }\n assetsToDispose = [];\n}\nfunction hmrDispose(bundle /*: ParcelRequire */, id /*: string */) {\n var cached = bundle.cache[id];\n bundle.hotData[id] = {};\n if (cached && cached.hot) {\n cached.hot.data = bundle.hotData[id];\n }\n if (cached && cached.hot && cached.hot._disposeCallbacks.length) {\n cached.hot._disposeCallbacks.forEach(function (cb) {\n cb(bundle.hotData[id]);\n });\n }\n delete bundle.cache[id];\n}\nfunction hmrAccept(bundle /*: ParcelRequire */, id /*: string */) {\n // Execute the module.\n bundle(id);\n\n // Run the accept callbacks in the new version of the module.\n var cached = bundle.cache[id];\n if (cached && cached.hot && cached.hot._acceptCallbacks.length) {\n let assetsToAlsoAccept = [];\n cached.hot._acceptCallbacks.forEach(function (cb) {\n let additionalAssets = cb(function () {\n return getParents(module.bundle.root, id);\n });\n if (Array.isArray(additionalAssets) && additionalAssets.length) {\n assetsToAlsoAccept.push(...additionalAssets);\n }\n });\n if (assetsToAlsoAccept.length) {\n let handled = assetsToAlsoAccept.every(function (a) {\n return hmrAcceptCheck(a[0], a[1]);\n });\n if (!handled) {\n return fullReload();\n }\n hmrDisposeQueue();\n }\n }\n}","import './assets/scripts/index.ts';\nimport './assets/scss/index.scss';\n","const favoritePosts = {\n init() {\n if (!this.component) return;\n\n this.addEventListeners();\n },\n\n addEventListeners() {\n this.component.addEventListener('click', this.handleClick.bind(this));\n },\n\n async getUserId() {\n // @ts-ignore\n return fetch(wpApiSettings.root + 'wp/v2/users/me', {\n method: 'GET',\n headers: {\n // @ts-ignore\n 'X-WP-Nonce': wpApiSettings.nonce\n }\n })\n .then(response => response.json())\n .then(user => user.id)\n .catch(error => {\n console.error('Erro:', error);\n return null;\n });\n },\n\n async handleClick() {\n const userId = await this.getUserId();\n if (!userId) return;\n\n // @ts-ignore\n fetch(wpApiSettings.root + wpApiSettings.rest_namespace + '/favorite-posts', {\n method: 'POST',\n body: JSON.stringify({\n post_id: this.component.dataset.postId,\n user_id: userId\n }),\n headers: {\n 'Content-Type': 'application/json',\n // @ts-ignore\n 'X-WP-Nonce': wpApiSettings.nonce\n }\n })\n .then(response => response.json())\n .then(data => {\n console.log(data);\n })\n .catch(error => {\n console.error('Erro:', error);\n });\n },\n\n component: document.querySelector('.favorite-post-button'),\n}\n\nfavoritePosts.init();\n"],"names":[],"version":3,"file":"index.js.map","sourceRoot":"../"} \ No newline at end of file diff --git a/index.ts b/index.ts new file mode 100644 index 00000000..7d9c2a4e --- /dev/null +++ b/index.ts @@ -0,0 +1,2 @@ +import './assets/scripts/index.ts'; +import './assets/scss/index.scss'; diff --git a/package.json b/package.json new file mode 100644 index 00000000..6157007b --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "wordpress-back-end-challenge", + "version": "1.0.0", + "source": "index.ts", + "repository": "git@github.com:Apiki/wordpress-back-end-challenge.git", + "author": "Kayo Tusthler ", + "license": "MIT", + "devDependencies": { + "@parcel/transformer-sass": "2.16.4", + "parcel": "2.16.4" + }, + "scripts": { + "dev": "parcel watch index.ts", + "build": "parcel build index.ts" + } +} diff --git a/src/dbHandler.php b/src/dbHandler.php new file mode 100644 index 00000000..bb27f1ad --- /dev/null +++ b/src/dbHandler.php @@ -0,0 +1,56 @@ +wpdb = $wpdb; + $this->table_name = $this->wpdb->prefix . 'favorite_posts'; + } + + public function createTable() { + $this->wpdb->query("CREATE TABLE IF NOT EXISTS $this->table_name ( + id INT AUTO_INCREMENT PRIMARY KEY, + user_id INT NOT NULL, + post_id INT NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT UQ_user_id_post_id UNIQUE (user_id, post_id) + )"); + } + + private function dropTable() { + $this->wpdb->query("DROP TABLE IF EXISTS $this->table_name"); + } + + public function getAllFavoritesByUserId($user_id) { + $query = $this->wpdb->prepare("SELECT * FROM $this->table_name WHERE user_id = %d", $user_id); + return $this->wpdb->get_results($query); + } + + public function getFavoriteByUserAndPost($user_id, $post_id) { + $query = $this->wpdb->prepare("SELECT * FROM $this->table_name WHERE user_id = %d AND post_id = %d", $user_id, $post_id); + return $this->wpdb->get_results($query); + } + + public function addFavorite($user_id, $post_id) { + $existing = $this->getFavoriteByUserAndPost($user_id, $post_id); + + if (!empty($existing)) : + return (int) $existing[0]->id; + endif; + + $result = $this->wpdb->insert($this->table_name, ['user_id' => $user_id, 'post_id' => $post_id]); + + return $this->wpdb->insert_id; + } + + public function removeFavorite($user_id, $post_id) { + return $this->wpdb->delete($this->table_name, ['user_id' => $user_id, 'post_id' => $post_id]); + } +} \ No newline at end of file diff --git a/src/restHandler.php b/src/restHandler.php new file mode 100644 index 00000000..c110e36b --- /dev/null +++ b/src/restHandler.php @@ -0,0 +1,115 @@ +dbHandler = new DbHandler(); + $this->restNamespace = self::getRestNamespace(); + + add_action('rest_api_init', [$this, 'registerRoutes']); + } + + public static function getRestNamespace() { + return 'wordpress-back-end-challenge/v1'; + } + + public function registerRoutes() { + register_rest_route($this->restNamespace, '/favorite-posts', [ + 'methods' => 'GET', + 'callback' => [$this, 'getFavoritePosts'], + ]); + + register_rest_route($this->restNamespace, '/favorite-posts', [ + 'methods' => 'POST', + 'callback' => [$this, 'addFavoritePost'], + ]); + } + + public function getFavoritePosts($request) { + $user_id = $request->get_param('user_id'); + + $favorites = $this->dbHandler->getAllFavoritesByUserId($user_id); + + if ($favorites) { + return new \WP_REST_Response([ + 'code' => 'favorite_posts_fetched', + 'status' => 'success', + 'message' => 'Favorite posts fetched', + 'data' => $favorites + ], 200); + } + + return new \WP_REST_Response([ + 'code' => 'failed_to_fetch_favorite_posts', + 'status' => 'error', + 'message' => 'Failed to fetch favorite posts', + 'data' => null + ], 500); + } + + public function addFavoritePost($request) { + $params = $request->get_json_params(); + + $user_id = isset($params['user_id']) ? absint($params['user_id']) : absint($request->get_param('user_id')); + $post_id = isset($params['post_id']) ? absint($params['post_id']) : absint($request->get_param('post_id')); + + if (!$user_id || !$post_id) { + return new \WP_REST_Response([ + 'code' => 'invalid_favorite_post_params', + 'status' => 'error', + 'message' => 'Invalid user_id or post_id', + 'data' => null + ], 400); + } + + $result = $this->dbHandler->addFavorite($user_id, $post_id); + + if ($result) { + return new \WP_REST_Response([ + 'code' => 'favorite_post_added', + 'status' => 'success', + 'message' => 'Favorite post added', + 'data' => [ + 'user_id' => $user_id, + 'post_id' => $post_id + ] + ], 200); + } + + return new \WP_REST_Response([ + 'code' => 'failed_to_add_favorite_post', + 'status' => 'error', + 'message' => 'Failed to add favorite post', + 'data' => null + ], 500); + } + + public function removeFavoritePost($request) { + $user_id = $request->get_param('user_id'); + $post_id = $request->get_param('post_id'); + + $result = $this->dbHandler->removeFavorite($user_id, $post_id); + + if ($result) { + return new \WP_REST_Response([ + 'code' => 'favorite_post_removed', + 'status' => 'success', + 'message' => 'Favorite post removed', + 'data' => null + ], 200); + } + + return new \WP_REST_Response([ + 'code' => 'failed_to_remove_favorite_post', + 'status' => 'error', + 'message' => 'Failed to remove favorite post', + 'data' => null + ], 500); + } +} diff --git a/wordpress-back-end-challenge.php b/wordpress-back-end-challenge.php new file mode 100644 index 00000000..7f527402 --- /dev/null +++ b/wordpress-back-end-challenge.php @@ -0,0 +1,83 @@ +createTable(); +} + +register_activation_hook(__FILE__, __NAMESPACE__ . '\\favorite_posts_plugin_activate'); + + +class WordPressBackEndChallenge { + private $dbHandler; + + public function __construct() { + $this->dbHandler = new DbHandler(); + new RestHandler(); + + add_filter( 'the_content', [$this, 'addFavoritePostIcon'] ); + add_action( 'wp_enqueue_scripts', [$this, 'enqueueScripts'] ); + } + + public function addFavoritePostIcon( $content ) + { + if ( !is_singular() || !in_the_loop() || !is_main_query() || !is_user_logged_in() ) : + return $content; + endif; + + $is_favorite = $this->dbHandler->getFavoriteByUserAndPost(get_current_user_id(), get_the_ID()); + + $custom_content = ""; + + $content = $custom_content . $content; + + return $content; + } + + public function enqueueScripts() { + wp_enqueue_script( + 'wordpress-back-end-challenge', + plugin_dir_url( __FILE__ ) . 'dist/index.js', + [], + filemtime(plugin_dir_path( __FILE__ ) . 'dist/index.js'), + [ + 'in_footer' => true, + 'strategy' => 'async' + ] + ); + + wp_localize_script( + 'wordpress-back-end-challenge', + 'wpApiSettings', + [ + 'rest_namespace' => RestHandler::getRestNamespace(), + 'root' => esc_url_raw(rest_url()), + 'nonce' => wp_create_nonce('wp_rest'), + ] + ); + + wp_enqueue_style( + 'wordpress-back-end-challenge', + plugin_dir_url( __FILE__ ) . 'dist/index.css', + [], + filemtime(plugin_dir_path( __FILE__ ) . 'dist/index.css') + ); + } +} + +new WordPressBackEndChallenge(); From 92b71a5801e27f282c5ea6220321307cde6f5630 Mon Sep 17 00:00:00 2001 From: Kayo Tusthler Date: Wed, 25 Mar 2026 02:59:23 -0300 Subject: [PATCH 2/4] feat: add remove favorite post --- assets/scripts/index.ts | 37 +++++++++++++++++++++++++++++++++++-- assets/scss/index.scss | 4 +++- dist/index.css | 4 +++- dist/index.css.map | 2 +- dist/index.js | 29 +++++++++++++++++++++++++++-- dist/index.js.map | 2 +- src/restHandler.php | 29 ++++++++++++++--------------- 7 files changed, 84 insertions(+), 23 deletions(-) diff --git a/assets/scripts/index.ts b/assets/scripts/index.ts index 198dce8d..90d52861 100644 --- a/assets/scripts/index.ts +++ b/assets/scripts/index.ts @@ -26,7 +26,7 @@ const favoritePosts = { }); }, - async handleClick() { + async favoritePost() { const userId = await this.getUserId(); if (!userId) return; @@ -45,13 +45,46 @@ const favoritePosts = { }) .then(response => response.json()) .then(data => { - console.log(data); + this.component.classList.toggle('is-favorite', data.code === 'favorite_post_added'); }) .catch(error => { console.error('Erro:', error); }); }, + async handleClick() { + if (this.component.classList.contains('is-favorite')) { + await this.removeFavoritePost(); + } else { + await this.favoritePost(); + } + }, + + async removeFavoritePost() { + const userId = await this.getUserId(); + if (!userId) return; + + // @ts-ignore + fetch(wpApiSettings.root + wpApiSettings.rest_namespace + '/favorite-posts', { + method: 'DELETE', + body: JSON.stringify({ + post_id: this.component.dataset.postId, + user_id: userId + }), + headers: { + 'Content-Type': 'application/json', + // @ts-ignore + 'X-WP-Nonce': wpApiSettings.nonce + } + }) + .then(response => response.json()) + .then(data => { + this.component.classList.toggle('is-favorite', data.code === 'favorite_post_removed'); + }) + .catch(error => { + console.error('Erro:', error); + }); + }, component: document.querySelector('.favorite-post-button'), } diff --git a/assets/scss/index.scss b/assets/scss/index.scss index 907611e5..d848b287 100644 --- a/assets/scss/index.scss +++ b/assets/scss/index.scss @@ -3,13 +3,15 @@ border: none; cursor: pointer; display: block; + outline: none; opacity: 0.5; padding: 0; - transition: opacity 0.3s ease; + transition: all 0.3s ease-in-out; &:hover, &.is-favorite { opacity: 1; + transform: scale(2); } img { diff --git a/dist/index.css b/dist/index.css index b549c123..202e0216 100644 --- a/dist/index.css +++ b/dist/index.css @@ -3,13 +3,15 @@ opacity: .5; background: none; border: none; + outline: none; padding: 0; - transition: opacity .3s; + transition: all .3s ease-in-out; display: block; } .favorite-post-button:hover, .favorite-post-button.is-favorite { opacity: 1; + transform: scale(2); } .favorite-post-button img { diff --git a/dist/index.css.map b/dist/index.css.map index ee35f84f..cc1488ed 100644 --- a/dist/index.css.map +++ b/dist/index.css.map @@ -1 +1 @@ -{"mappings":"AAAA;;;;;;;;;;AASI;;;;AAKA","sources":["assets/scss/index.scss"],"sourcesContent":[".favorite-post-button {\n background: none;\n border: none;\n cursor: pointer;\n display: block;\n opacity: 0.5;\n padding: 0;\n transition: opacity 0.3s ease;\n\n &:hover,\n &.is-favorite {\n opacity: 1;\n }\n\n img {\n height: 32px;\n pointer-events: none;\n }\n}"],"names":[],"version":3,"file":"index.css.map","sourceRoot":"../"} \ No newline at end of file +{"mappings":"AAAA;;;;;;;;;;;AAUI;;;;;AAMA","sources":["assets/scss/index.scss"],"sourcesContent":[".favorite-post-button {\n background: none;\n border: none;\n cursor: pointer;\n display: block;\n outline: none;\n opacity: 0.5;\n padding: 0;\n transition: all 0.3s ease-in-out;\n\n &:hover,\n &.is-favorite {\n opacity: 1;\n transform: scale(2);\n }\n\n img {\n height: 32px;\n pointer-events: none;\n }\n}"],"names":[],"version":3,"file":"index.css.map","sourceRoot":"../"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 8e6169fa..a8de6048 100644 --- a/dist/index.js +++ b/dist/index.js @@ -739,7 +739,7 @@ const favoritePosts = { return null; }); }, - async handleClick () { + async favoritePost () { const userId = await this.getUserId(); if (!userId) return; // @ts-ignore @@ -755,7 +755,32 @@ const favoritePosts = { 'X-WP-Nonce': wpApiSettings.nonce } }).then((response)=>response.json()).then((data)=>{ - console.log(data); + this.component.classList.toggle('is-favorite', data.code === 'favorite_post_added'); + }).catch((error)=>{ + console.error('Erro:', error); + }); + }, + async handleClick () { + if (this.component.classList.contains('is-favorite')) await this.removeFavoritePost(); + else await this.favoritePost(); + }, + async removeFavoritePost () { + const userId = await this.getUserId(); + if (!userId) return; + // @ts-ignore + fetch(wpApiSettings.root + wpApiSettings.rest_namespace + '/favorite-posts', { + method: 'DELETE', + body: JSON.stringify({ + post_id: this.component.dataset.postId, + user_id: userId + }), + headers: { + 'Content-Type': 'application/json', + // @ts-ignore + 'X-WP-Nonce': wpApiSettings.nonce + } + }).then((response)=>response.json()).then((data)=>{ + this.component.classList.toggle('is-favorite', data.code === 'favorite_post_removed'); }).catch((error)=>{ console.error('Erro:', error); }); diff --git a/dist/index.js.map b/dist/index.js.map index 2238f480..d5243922 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"mappings":"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","sources":["node_modules/@parcel/runtime-browser-hmr/lib/runtime-92f870de140ddc88.js","index.ts","assets/scripts/index.ts"],"sourcesContent":["var HMR_HOST = null;var HMR_PORT = 1234;var HMR_SERVER_PORT = 1234;var HMR_SECURE = false;var HMR_ENV_HASH = \"d6ea1d42532a7575\";var HMR_USE_SSE = false;module.bundle.HMR_BUNDLE_ID = \"78fcd0ac8e9bd240\";\"use strict\";\n\n/* global HMR_HOST, HMR_PORT, HMR_SERVER_PORT, HMR_ENV_HASH, HMR_SECURE, HMR_USE_SSE, chrome, browser, __parcel__import__, __parcel__importScripts__, ServiceWorkerGlobalScope */\n/*::\nimport type {\n HMRAsset,\n HMRMessage,\n} from '@parcel/reporter-dev-server/src/HMRServer.js';\ninterface ParcelRequire {\n (string): mixed;\n cache: {|[string]: ParcelModule|};\n hotData: {|[string]: mixed|};\n Module: any;\n parent: ?ParcelRequire;\n isParcelRequire: true;\n modules: {|[string]: [Function, {|[string]: string|}]|};\n HMR_BUNDLE_ID: string;\n root: ParcelRequire;\n}\ninterface ParcelModule {\n hot: {|\n data: mixed,\n accept(cb: (Function) => void): void,\n dispose(cb: (mixed) => void): void,\n // accept(deps: Array | string, cb: (Function) => void): void,\n // decline(): void,\n _acceptCallbacks: Array<(Function) => void>,\n _disposeCallbacks: Array<(mixed) => void>,\n |};\n}\ninterface ExtensionContext {\n runtime: {|\n reload(): void,\n getURL(url: string): string;\n getManifest(): {manifest_version: number, ...};\n |};\n}\ndeclare var module: {bundle: ParcelRequire, ...};\ndeclare var HMR_HOST: string;\ndeclare var HMR_PORT: string;\ndeclare var HMR_SERVER_PORT: string;\ndeclare var HMR_ENV_HASH: string;\ndeclare var HMR_SECURE: boolean;\ndeclare var HMR_USE_SSE: boolean;\ndeclare var chrome: ExtensionContext;\ndeclare var browser: ExtensionContext;\ndeclare var __parcel__import__: (string) => Promise;\ndeclare var __parcel__importScripts__: (string) => Promise;\ndeclare var globalThis: typeof self;\ndeclare var ServiceWorkerGlobalScope: Object;\n*/\nvar OVERLAY_ID = '__parcel__error__overlay__';\nvar OldModule = module.bundle.Module;\nfunction Module(moduleName) {\n OldModule.call(this, moduleName);\n this.hot = {\n data: module.bundle.hotData[moduleName],\n _acceptCallbacks: [],\n _disposeCallbacks: [],\n accept: function (fn) {\n this._acceptCallbacks.push(fn || function () {});\n },\n dispose: function (fn) {\n this._disposeCallbacks.push(fn);\n }\n };\n module.bundle.hotData[moduleName] = undefined;\n}\nmodule.bundle.Module = Module;\nmodule.bundle.hotData = {};\nvar checkedAssets /*: {|[string]: boolean|} */,\n disposedAssets /*: {|[string]: boolean|} */,\n assetsToDispose /*: Array<[ParcelRequire, string]> */,\n assetsToAccept /*: Array<[ParcelRequire, string]> */,\n bundleNotFound = false;\nfunction getHostname() {\n return HMR_HOST || (typeof location !== 'undefined' && location.protocol.indexOf('http') === 0 ? location.hostname : 'localhost');\n}\nfunction getPort() {\n return HMR_PORT || (typeof location !== 'undefined' ? location.port : HMR_SERVER_PORT);\n}\n\n// eslint-disable-next-line no-redeclare\nlet WebSocket = globalThis.WebSocket;\nif (!WebSocket && typeof module.bundle.root === 'function') {\n try {\n // eslint-disable-next-line no-global-assign\n WebSocket = module.bundle.root('ws');\n } catch {\n // ignore.\n }\n}\nvar hostname = getHostname();\nvar port = getPort();\nvar protocol = HMR_SECURE || typeof location !== 'undefined' && location.protocol === 'https:' && !['localhost', '127.0.0.1', '0.0.0.0'].includes(hostname) ? 'wss' : 'ws';\n\n// eslint-disable-next-line no-redeclare\nvar parent = module.bundle.parent;\nif (!parent || !parent.isParcelRequire) {\n // Web extension context\n var extCtx = typeof browser === 'undefined' ? typeof chrome === 'undefined' ? null : chrome : browser;\n\n // Safari doesn't support sourceURL in error stacks.\n // eval may also be disabled via CSP, so do a quick check.\n var supportsSourceURL = false;\n try {\n (0, eval)('throw new Error(\"test\"); //# sourceURL=test.js');\n } catch (err) {\n supportsSourceURL = err.stack.includes('test.js');\n }\n var ws;\n if (HMR_USE_SSE) {\n ws = new EventSource('/__parcel_hmr');\n } else {\n try {\n // If we're running in the dev server's node runner, listen for messages on the parent port.\n let {\n workerData,\n parentPort\n } = module.bundle.root('node:worker_threads') /*: any*/;\n if (workerData !== null && workerData !== void 0 && workerData.__parcel) {\n parentPort.on('message', async message => {\n try {\n await handleMessage(message);\n parentPort.postMessage('updated');\n } catch {\n parentPort.postMessage('restart');\n }\n });\n\n // After the bundle has finished running, notify the dev server that the HMR update is complete.\n queueMicrotask(() => parentPort.postMessage('ready'));\n }\n } catch {\n if (typeof WebSocket !== 'undefined') {\n try {\n ws = new WebSocket(protocol + '://' + hostname + (port ? ':' + port : '') + '/');\n } catch (err) {\n // Ignore cloudflare workers error.\n if (err.message && !err.message.includes('Disallowed operation called within global scope')) {\n console.error(err.message);\n }\n }\n }\n }\n }\n if (ws) {\n // $FlowFixMe\n ws.onmessage = async function (event /*: {data: string, ...} */) {\n var data /*: HMRMessage */ = JSON.parse(event.data);\n await handleMessage(data);\n };\n if (ws instanceof WebSocket) {\n ws.onerror = function (e) {\n if (e.message) {\n console.error(e.message);\n }\n };\n ws.onclose = function () {\n console.warn('[parcel] 🚨 Connection to the HMR server was lost');\n };\n }\n }\n}\nasync function handleMessage(data /*: HMRMessage */) {\n checkedAssets = {} /*: {|[string]: boolean|} */;\n disposedAssets = {} /*: {|[string]: boolean|} */;\n assetsToAccept = [];\n assetsToDispose = [];\n bundleNotFound = false;\n if (data.type === 'reload') {\n fullReload();\n } else if (data.type === 'update') {\n // Remove error overlay if there is one\n if (typeof document !== 'undefined') {\n removeErrorOverlay();\n }\n let assets = data.assets;\n\n // Handle HMR Update\n let handled = assets.every(asset => {\n return asset.type === 'css' || asset.type === 'js' && hmrAcceptCheck(module.bundle.root, asset.id, asset.depsByBundle);\n });\n\n // Dispatch a custom event in case a bundle was not found. This might mean\n // an asset on the server changed and we should reload the page. This event\n // gives the client an opportunity to refresh without losing state\n // (e.g. via React Server Components). If e.preventDefault() is not called,\n // we will trigger a full page reload.\n if (handled && bundleNotFound && assets.some(a => a.envHash !== HMR_ENV_HASH) && typeof window !== 'undefined' && typeof CustomEvent !== 'undefined') {\n handled = !window.dispatchEvent(new CustomEvent('parcelhmrreload', {\n cancelable: true\n }));\n }\n if (handled) {\n console.clear();\n\n // Dispatch custom event so other runtimes (e.g React Refresh) are aware.\n if (typeof window !== 'undefined' && typeof CustomEvent !== 'undefined') {\n window.dispatchEvent(new CustomEvent('parcelhmraccept'));\n }\n await hmrApplyUpdates(assets);\n hmrDisposeQueue();\n\n // Run accept callbacks. This will also re-execute other disposed assets in topological order.\n let processedAssets = {};\n for (let i = 0; i < assetsToAccept.length; i++) {\n let id = assetsToAccept[i][1];\n if (!processedAssets[id]) {\n hmrAccept(assetsToAccept[i][0], id);\n processedAssets[id] = true;\n }\n }\n } else fullReload();\n }\n if (data.type === 'error') {\n // Log parcel errors to console\n for (let ansiDiagnostic of data.diagnostics.ansi) {\n let stack = ansiDiagnostic.codeframe ? ansiDiagnostic.codeframe : ansiDiagnostic.stack;\n console.error('🚨 [parcel]: ' + ansiDiagnostic.message + '\\n' + stack + '\\n\\n' + ansiDiagnostic.hints.join('\\n'));\n }\n if (typeof document !== 'undefined') {\n // Render the fancy html overlay\n removeErrorOverlay();\n var overlay = createErrorOverlay(data.diagnostics.html);\n // $FlowFixMe\n document.body.appendChild(overlay);\n }\n }\n}\nfunction removeErrorOverlay() {\n var overlay = document.getElementById(OVERLAY_ID);\n if (overlay) {\n overlay.remove();\n console.log('[parcel] ✨ Error resolved');\n }\n}\nfunction createErrorOverlay(diagnostics) {\n var overlay = document.createElement('div');\n overlay.id = OVERLAY_ID;\n let errorHTML = '
';\n for (let diagnostic of diagnostics) {\n let stack = diagnostic.frames.length ? diagnostic.frames.reduce((p, frame) => {\n return `${p}\n${frame.location}\n${frame.code}`;\n }, '') : diagnostic.stack;\n errorHTML += `\n
\n
\n 🚨 ${diagnostic.message}\n
\n
${stack}
\n
\n ${diagnostic.hints.map(hint => '
💡 ' + hint + '
').join('')}\n
\n ${diagnostic.documentation ? `` : ''}\n
\n `;\n }\n errorHTML += '
';\n overlay.innerHTML = errorHTML;\n return overlay;\n}\nfunction fullReload() {\n if (typeof location !== 'undefined' && 'reload' in location) {\n location.reload();\n } else if (typeof extCtx !== 'undefined' && extCtx && extCtx.runtime && extCtx.runtime.reload) {\n extCtx.runtime.reload();\n } else {\n try {\n let {\n workerData,\n parentPort\n } = module.bundle.root('node:worker_threads') /*: any*/;\n if (workerData !== null && workerData !== void 0 && workerData.__parcel) {\n parentPort.postMessage('restart');\n }\n } catch (err) {\n console.error('[parcel] ⚠️ An HMR update was not accepted. Please restart the process.');\n }\n }\n}\nfunction getParents(bundle, id) /*: Array<[ParcelRequire, string]> */{\n var modules = bundle.modules;\n if (!modules) {\n return [];\n }\n var parents = [];\n var k, d, dep;\n for (k in modules) {\n for (d in modules[k][1]) {\n dep = modules[k][1][d];\n if (dep === id || Array.isArray(dep) && dep[dep.length - 1] === id) {\n parents.push([bundle, k]);\n }\n }\n }\n if (bundle.parent) {\n parents = parents.concat(getParents(bundle.parent, id));\n }\n return parents;\n}\nfunction updateLink(link) {\n var href = link.getAttribute('href');\n if (!href) {\n return;\n }\n var newLink = link.cloneNode();\n newLink.onload = function () {\n if (link.parentNode !== null) {\n // $FlowFixMe\n link.parentNode.removeChild(link);\n }\n };\n newLink.setAttribute('href',\n // $FlowFixMe\n href.split('?')[0] + '?' + Date.now());\n // $FlowFixMe\n link.parentNode.insertBefore(newLink, link.nextSibling);\n}\nvar cssTimeout = null;\nfunction reloadCSS() {\n if (cssTimeout || typeof document === 'undefined') {\n return;\n }\n cssTimeout = setTimeout(function () {\n var links = document.querySelectorAll('link[rel=\"stylesheet\"]');\n for (var i = 0; i < links.length; i++) {\n // $FlowFixMe[incompatible-type]\n var href /*: string */ = links[i].getAttribute('href');\n var hostname = getHostname();\n var servedFromHMRServer = hostname === 'localhost' ? new RegExp('^(https?:\\\\/\\\\/(0.0.0.0|127.0.0.1)|localhost):' + getPort()).test(href) : href.indexOf(hostname + ':' + getPort());\n var absolute = /^https?:\\/\\//i.test(href) && href.indexOf(location.origin) !== 0 && !servedFromHMRServer;\n if (!absolute) {\n updateLink(links[i]);\n }\n }\n cssTimeout = null;\n }, 50);\n}\nfunction hmrDownload(asset) {\n if (asset.type === 'js') {\n if (typeof document !== 'undefined') {\n let script = document.createElement('script');\n script.src = asset.url + '?t=' + Date.now();\n if (asset.outputFormat === 'esmodule') {\n script.type = 'module';\n }\n return new Promise((resolve, reject) => {\n var _document$head;\n script.onload = () => resolve(script);\n script.onerror = reject;\n (_document$head = document.head) === null || _document$head === void 0 || _document$head.appendChild(script);\n });\n } else if (typeof importScripts === 'function') {\n // Worker scripts\n if (asset.outputFormat === 'esmodule') {\n return __parcel__import__(asset.url + '?t=' + Date.now());\n } else {\n return new Promise((resolve, reject) => {\n try {\n __parcel__importScripts__(asset.url + '?t=' + Date.now());\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n }\n }\n }\n}\nasync function hmrApplyUpdates(assets) {\n global.parcelHotUpdate = Object.create(null);\n let scriptsToRemove;\n try {\n // If sourceURL comments aren't supported in eval, we need to load\n // the update from the dev server over HTTP so that stack traces\n // are correct in errors/logs. This is much slower than eval, so\n // we only do it if needed (currently just Safari).\n // https://bugs.webkit.org/show_bug.cgi?id=137297\n // This path is also taken if a CSP disallows eval.\n if (!supportsSourceURL) {\n let promises = assets.map(asset => {\n var _hmrDownload;\n return (_hmrDownload = hmrDownload(asset)) === null || _hmrDownload === void 0 ? void 0 : _hmrDownload.catch(err => {\n // Web extension fix\n if (extCtx && extCtx.runtime && extCtx.runtime.getManifest().manifest_version == 3 && typeof ServiceWorkerGlobalScope != 'undefined' && global instanceof ServiceWorkerGlobalScope) {\n extCtx.runtime.reload();\n return;\n }\n throw err;\n });\n });\n scriptsToRemove = await Promise.all(promises);\n }\n assets.forEach(function (asset) {\n hmrApply(module.bundle.root, asset);\n });\n } finally {\n delete global.parcelHotUpdate;\n if (scriptsToRemove) {\n scriptsToRemove.forEach(script => {\n if (script) {\n var _document$head2;\n (_document$head2 = document.head) === null || _document$head2 === void 0 || _document$head2.removeChild(script);\n }\n });\n }\n }\n}\nfunction hmrApply(bundle /*: ParcelRequire */, asset /*: HMRAsset */) {\n var modules = bundle.modules;\n if (!modules) {\n return;\n }\n if (asset.type === 'css') {\n reloadCSS();\n } else if (asset.type === 'js') {\n let deps = asset.depsByBundle[bundle.HMR_BUNDLE_ID];\n if (deps) {\n if (modules[asset.id]) {\n // Remove dependencies that are removed and will become orphaned.\n // This is necessary so that if the asset is added back again, the cache is gone, and we prevent a full page reload.\n let oldDeps = modules[asset.id][1];\n for (let dep in oldDeps) {\n if (!deps[dep] || deps[dep] !== oldDeps[dep]) {\n let id = oldDeps[dep];\n let parents = getParents(module.bundle.root, id);\n if (parents.length === 1) {\n hmrDelete(module.bundle.root, id);\n }\n }\n }\n }\n if (supportsSourceURL) {\n // Global eval. We would use `new Function` here but browser\n // support for source maps is better with eval.\n (0, eval)(asset.output);\n }\n\n // $FlowFixMe\n let fn = global.parcelHotUpdate[asset.id];\n modules[asset.id] = [fn, deps];\n }\n\n // Always traverse to the parent bundle, even if we already replaced the asset in this bundle.\n // This is required in case modules are duplicated. We need to ensure all instances have the updated code.\n if (bundle.parent) {\n hmrApply(bundle.parent, asset);\n }\n }\n}\nfunction hmrDelete(bundle, id) {\n let modules = bundle.modules;\n if (!modules) {\n return;\n }\n if (modules[id]) {\n // Collect dependencies that will become orphaned when this module is deleted.\n let deps = modules[id][1];\n let orphans = [];\n for (let dep in deps) {\n let parents = getParents(module.bundle.root, deps[dep]);\n if (parents.length === 1) {\n orphans.push(deps[dep]);\n }\n }\n\n // Delete the module. This must be done before deleting dependencies in case of circular dependencies.\n delete modules[id];\n delete bundle.cache[id];\n\n // Now delete the orphans.\n orphans.forEach(id => {\n hmrDelete(module.bundle.root, id);\n });\n } else if (bundle.parent) {\n hmrDelete(bundle.parent, id);\n }\n}\nfunction hmrAcceptCheck(bundle /*: ParcelRequire */, id /*: string */, depsByBundle /*: ?{ [string]: { [string]: string } }*/) {\n checkedAssets = {};\n if (hmrAcceptCheckOne(bundle, id, depsByBundle)) {\n return true;\n }\n\n // Traverse parents breadth first. All possible ancestries must accept the HMR update, or we'll reload.\n let parents = getParents(module.bundle.root, id);\n let accepted = false;\n while (parents.length > 0) {\n let v = parents.shift();\n let a = hmrAcceptCheckOne(v[0], v[1], null);\n if (a) {\n // If this parent accepts, stop traversing upward, but still consider siblings.\n accepted = true;\n } else if (a !== null) {\n // Otherwise, queue the parents in the next level upward.\n let p = getParents(module.bundle.root, v[1]);\n if (p.length === 0) {\n // If there are no parents, then we've reached an entry without accepting. Reload.\n accepted = false;\n break;\n }\n parents.push(...p);\n }\n }\n return accepted;\n}\nfunction hmrAcceptCheckOne(bundle /*: ParcelRequire */, id /*: string */, depsByBundle /*: ?{ [string]: { [string]: string } }*/) {\n var modules = bundle.modules;\n if (!modules) {\n return;\n }\n if (depsByBundle && !depsByBundle[bundle.HMR_BUNDLE_ID]) {\n // If we reached the root bundle without finding where the asset should go,\n // there's nothing to do. Mark as \"accepted\" so we don't reload the page.\n if (!bundle.parent) {\n bundleNotFound = true;\n return true;\n }\n return hmrAcceptCheckOne(bundle.parent, id, depsByBundle);\n }\n if (checkedAssets[id]) {\n return null;\n }\n checkedAssets[id] = true;\n var cached = bundle.cache[id];\n if (!cached) {\n return true;\n }\n assetsToDispose.push([bundle, id]);\n if (cached && cached.hot && cached.hot._acceptCallbacks.length) {\n assetsToAccept.push([bundle, id]);\n return true;\n }\n return false;\n}\nfunction hmrDisposeQueue() {\n // Dispose all old assets.\n for (let i = 0; i < assetsToDispose.length; i++) {\n let id = assetsToDispose[i][1];\n if (!disposedAssets[id]) {\n hmrDispose(assetsToDispose[i][0], id);\n disposedAssets[id] = true;\n }\n }\n assetsToDispose = [];\n}\nfunction hmrDispose(bundle /*: ParcelRequire */, id /*: string */) {\n var cached = bundle.cache[id];\n bundle.hotData[id] = {};\n if (cached && cached.hot) {\n cached.hot.data = bundle.hotData[id];\n }\n if (cached && cached.hot && cached.hot._disposeCallbacks.length) {\n cached.hot._disposeCallbacks.forEach(function (cb) {\n cb(bundle.hotData[id]);\n });\n }\n delete bundle.cache[id];\n}\nfunction hmrAccept(bundle /*: ParcelRequire */, id /*: string */) {\n // Execute the module.\n bundle(id);\n\n // Run the accept callbacks in the new version of the module.\n var cached = bundle.cache[id];\n if (cached && cached.hot && cached.hot._acceptCallbacks.length) {\n let assetsToAlsoAccept = [];\n cached.hot._acceptCallbacks.forEach(function (cb) {\n let additionalAssets = cb(function () {\n return getParents(module.bundle.root, id);\n });\n if (Array.isArray(additionalAssets) && additionalAssets.length) {\n assetsToAlsoAccept.push(...additionalAssets);\n }\n });\n if (assetsToAlsoAccept.length) {\n let handled = assetsToAlsoAccept.every(function (a) {\n return hmrAcceptCheck(a[0], a[1]);\n });\n if (!handled) {\n return fullReload();\n }\n hmrDisposeQueue();\n }\n }\n}","import './assets/scripts/index.ts';\nimport './assets/scss/index.scss';\n","const favoritePosts = {\n init() {\n if (!this.component) return;\n\n this.addEventListeners();\n },\n\n addEventListeners() {\n this.component.addEventListener('click', this.handleClick.bind(this));\n },\n\n async getUserId() {\n // @ts-ignore\n return fetch(wpApiSettings.root + 'wp/v2/users/me', {\n method: 'GET',\n headers: {\n // @ts-ignore\n 'X-WP-Nonce': wpApiSettings.nonce\n }\n })\n .then(response => response.json())\n .then(user => user.id)\n .catch(error => {\n console.error('Erro:', error);\n return null;\n });\n },\n\n async handleClick() {\n const userId = await this.getUserId();\n if (!userId) return;\n\n // @ts-ignore\n fetch(wpApiSettings.root + wpApiSettings.rest_namespace + '/favorite-posts', {\n method: 'POST',\n body: JSON.stringify({\n post_id: this.component.dataset.postId,\n user_id: userId\n }),\n headers: {\n 'Content-Type': 'application/json',\n // @ts-ignore\n 'X-WP-Nonce': wpApiSettings.nonce\n }\n })\n .then(response => response.json())\n .then(data => {\n console.log(data);\n })\n .catch(error => {\n console.error('Erro:', error);\n });\n },\n\n component: document.querySelector('.favorite-post-button'),\n}\n\nfavoritePosts.init();\n"],"names":[],"version":3,"file":"index.js.map","sourceRoot":"../"} \ No newline at end of file +{"mappings":"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","sources":["node_modules/@parcel/runtime-browser-hmr/lib/runtime-92f870de140ddc88.js","index.ts","assets/scripts/index.ts"],"sourcesContent":["var HMR_HOST = null;var HMR_PORT = 1234;var HMR_SERVER_PORT = 1234;var HMR_SECURE = false;var HMR_ENV_HASH = \"d6ea1d42532a7575\";var HMR_USE_SSE = false;module.bundle.HMR_BUNDLE_ID = \"78fcd0ac8e9bd240\";\"use strict\";\n\n/* global HMR_HOST, HMR_PORT, HMR_SERVER_PORT, HMR_ENV_HASH, HMR_SECURE, HMR_USE_SSE, chrome, browser, __parcel__import__, __parcel__importScripts__, ServiceWorkerGlobalScope */\n/*::\nimport type {\n HMRAsset,\n HMRMessage,\n} from '@parcel/reporter-dev-server/src/HMRServer.js';\ninterface ParcelRequire {\n (string): mixed;\n cache: {|[string]: ParcelModule|};\n hotData: {|[string]: mixed|};\n Module: any;\n parent: ?ParcelRequire;\n isParcelRequire: true;\n modules: {|[string]: [Function, {|[string]: string|}]|};\n HMR_BUNDLE_ID: string;\n root: ParcelRequire;\n}\ninterface ParcelModule {\n hot: {|\n data: mixed,\n accept(cb: (Function) => void): void,\n dispose(cb: (mixed) => void): void,\n // accept(deps: Array | string, cb: (Function) => void): void,\n // decline(): void,\n _acceptCallbacks: Array<(Function) => void>,\n _disposeCallbacks: Array<(mixed) => void>,\n |};\n}\ninterface ExtensionContext {\n runtime: {|\n reload(): void,\n getURL(url: string): string;\n getManifest(): {manifest_version: number, ...};\n |};\n}\ndeclare var module: {bundle: ParcelRequire, ...};\ndeclare var HMR_HOST: string;\ndeclare var HMR_PORT: string;\ndeclare var HMR_SERVER_PORT: string;\ndeclare var HMR_ENV_HASH: string;\ndeclare var HMR_SECURE: boolean;\ndeclare var HMR_USE_SSE: boolean;\ndeclare var chrome: ExtensionContext;\ndeclare var browser: ExtensionContext;\ndeclare var __parcel__import__: (string) => Promise;\ndeclare var __parcel__importScripts__: (string) => Promise;\ndeclare var globalThis: typeof self;\ndeclare var ServiceWorkerGlobalScope: Object;\n*/\nvar OVERLAY_ID = '__parcel__error__overlay__';\nvar OldModule = module.bundle.Module;\nfunction Module(moduleName) {\n OldModule.call(this, moduleName);\n this.hot = {\n data: module.bundle.hotData[moduleName],\n _acceptCallbacks: [],\n _disposeCallbacks: [],\n accept: function (fn) {\n this._acceptCallbacks.push(fn || function () {});\n },\n dispose: function (fn) {\n this._disposeCallbacks.push(fn);\n }\n };\n module.bundle.hotData[moduleName] = undefined;\n}\nmodule.bundle.Module = Module;\nmodule.bundle.hotData = {};\nvar checkedAssets /*: {|[string]: boolean|} */,\n disposedAssets /*: {|[string]: boolean|} */,\n assetsToDispose /*: Array<[ParcelRequire, string]> */,\n assetsToAccept /*: Array<[ParcelRequire, string]> */,\n bundleNotFound = false;\nfunction getHostname() {\n return HMR_HOST || (typeof location !== 'undefined' && location.protocol.indexOf('http') === 0 ? location.hostname : 'localhost');\n}\nfunction getPort() {\n return HMR_PORT || (typeof location !== 'undefined' ? location.port : HMR_SERVER_PORT);\n}\n\n// eslint-disable-next-line no-redeclare\nlet WebSocket = globalThis.WebSocket;\nif (!WebSocket && typeof module.bundle.root === 'function') {\n try {\n // eslint-disable-next-line no-global-assign\n WebSocket = module.bundle.root('ws');\n } catch {\n // ignore.\n }\n}\nvar hostname = getHostname();\nvar port = getPort();\nvar protocol = HMR_SECURE || typeof location !== 'undefined' && location.protocol === 'https:' && !['localhost', '127.0.0.1', '0.0.0.0'].includes(hostname) ? 'wss' : 'ws';\n\n// eslint-disable-next-line no-redeclare\nvar parent = module.bundle.parent;\nif (!parent || !parent.isParcelRequire) {\n // Web extension context\n var extCtx = typeof browser === 'undefined' ? typeof chrome === 'undefined' ? null : chrome : browser;\n\n // Safari doesn't support sourceURL in error stacks.\n // eval may also be disabled via CSP, so do a quick check.\n var supportsSourceURL = false;\n try {\n (0, eval)('throw new Error(\"test\"); //# sourceURL=test.js');\n } catch (err) {\n supportsSourceURL = err.stack.includes('test.js');\n }\n var ws;\n if (HMR_USE_SSE) {\n ws = new EventSource('/__parcel_hmr');\n } else {\n try {\n // If we're running in the dev server's node runner, listen for messages on the parent port.\n let {\n workerData,\n parentPort\n } = module.bundle.root('node:worker_threads') /*: any*/;\n if (workerData !== null && workerData !== void 0 && workerData.__parcel) {\n parentPort.on('message', async message => {\n try {\n await handleMessage(message);\n parentPort.postMessage('updated');\n } catch {\n parentPort.postMessage('restart');\n }\n });\n\n // After the bundle has finished running, notify the dev server that the HMR update is complete.\n queueMicrotask(() => parentPort.postMessage('ready'));\n }\n } catch {\n if (typeof WebSocket !== 'undefined') {\n try {\n ws = new WebSocket(protocol + '://' + hostname + (port ? ':' + port : '') + '/');\n } catch (err) {\n // Ignore cloudflare workers error.\n if (err.message && !err.message.includes('Disallowed operation called within global scope')) {\n console.error(err.message);\n }\n }\n }\n }\n }\n if (ws) {\n // $FlowFixMe\n ws.onmessage = async function (event /*: {data: string, ...} */) {\n var data /*: HMRMessage */ = JSON.parse(event.data);\n await handleMessage(data);\n };\n if (ws instanceof WebSocket) {\n ws.onerror = function (e) {\n if (e.message) {\n console.error(e.message);\n }\n };\n ws.onclose = function () {\n console.warn('[parcel] 🚨 Connection to the HMR server was lost');\n };\n }\n }\n}\nasync function handleMessage(data /*: HMRMessage */) {\n checkedAssets = {} /*: {|[string]: boolean|} */;\n disposedAssets = {} /*: {|[string]: boolean|} */;\n assetsToAccept = [];\n assetsToDispose = [];\n bundleNotFound = false;\n if (data.type === 'reload') {\n fullReload();\n } else if (data.type === 'update') {\n // Remove error overlay if there is one\n if (typeof document !== 'undefined') {\n removeErrorOverlay();\n }\n let assets = data.assets;\n\n // Handle HMR Update\n let handled = assets.every(asset => {\n return asset.type === 'css' || asset.type === 'js' && hmrAcceptCheck(module.bundle.root, asset.id, asset.depsByBundle);\n });\n\n // Dispatch a custom event in case a bundle was not found. This might mean\n // an asset on the server changed and we should reload the page. This event\n // gives the client an opportunity to refresh without losing state\n // (e.g. via React Server Components). If e.preventDefault() is not called,\n // we will trigger a full page reload.\n if (handled && bundleNotFound && assets.some(a => a.envHash !== HMR_ENV_HASH) && typeof window !== 'undefined' && typeof CustomEvent !== 'undefined') {\n handled = !window.dispatchEvent(new CustomEvent('parcelhmrreload', {\n cancelable: true\n }));\n }\n if (handled) {\n console.clear();\n\n // Dispatch custom event so other runtimes (e.g React Refresh) are aware.\n if (typeof window !== 'undefined' && typeof CustomEvent !== 'undefined') {\n window.dispatchEvent(new CustomEvent('parcelhmraccept'));\n }\n await hmrApplyUpdates(assets);\n hmrDisposeQueue();\n\n // Run accept callbacks. This will also re-execute other disposed assets in topological order.\n let processedAssets = {};\n for (let i = 0; i < assetsToAccept.length; i++) {\n let id = assetsToAccept[i][1];\n if (!processedAssets[id]) {\n hmrAccept(assetsToAccept[i][0], id);\n processedAssets[id] = true;\n }\n }\n } else fullReload();\n }\n if (data.type === 'error') {\n // Log parcel errors to console\n for (let ansiDiagnostic of data.diagnostics.ansi) {\n let stack = ansiDiagnostic.codeframe ? ansiDiagnostic.codeframe : ansiDiagnostic.stack;\n console.error('🚨 [parcel]: ' + ansiDiagnostic.message + '\\n' + stack + '\\n\\n' + ansiDiagnostic.hints.join('\\n'));\n }\n if (typeof document !== 'undefined') {\n // Render the fancy html overlay\n removeErrorOverlay();\n var overlay = createErrorOverlay(data.diagnostics.html);\n // $FlowFixMe\n document.body.appendChild(overlay);\n }\n }\n}\nfunction removeErrorOverlay() {\n var overlay = document.getElementById(OVERLAY_ID);\n if (overlay) {\n overlay.remove();\n console.log('[parcel] ✨ Error resolved');\n }\n}\nfunction createErrorOverlay(diagnostics) {\n var overlay = document.createElement('div');\n overlay.id = OVERLAY_ID;\n let errorHTML = '
';\n for (let diagnostic of diagnostics) {\n let stack = diagnostic.frames.length ? diagnostic.frames.reduce((p, frame) => {\n return `${p}\n${frame.location}\n${frame.code}`;\n }, '') : diagnostic.stack;\n errorHTML += `\n
\n
\n 🚨 ${diagnostic.message}\n
\n
${stack}
\n
\n ${diagnostic.hints.map(hint => '
💡 ' + hint + '
').join('')}\n
\n ${diagnostic.documentation ? `` : ''}\n
\n `;\n }\n errorHTML += '
';\n overlay.innerHTML = errorHTML;\n return overlay;\n}\nfunction fullReload() {\n if (typeof location !== 'undefined' && 'reload' in location) {\n location.reload();\n } else if (typeof extCtx !== 'undefined' && extCtx && extCtx.runtime && extCtx.runtime.reload) {\n extCtx.runtime.reload();\n } else {\n try {\n let {\n workerData,\n parentPort\n } = module.bundle.root('node:worker_threads') /*: any*/;\n if (workerData !== null && workerData !== void 0 && workerData.__parcel) {\n parentPort.postMessage('restart');\n }\n } catch (err) {\n console.error('[parcel] ⚠️ An HMR update was not accepted. Please restart the process.');\n }\n }\n}\nfunction getParents(bundle, id) /*: Array<[ParcelRequire, string]> */{\n var modules = bundle.modules;\n if (!modules) {\n return [];\n }\n var parents = [];\n var k, d, dep;\n for (k in modules) {\n for (d in modules[k][1]) {\n dep = modules[k][1][d];\n if (dep === id || Array.isArray(dep) && dep[dep.length - 1] === id) {\n parents.push([bundle, k]);\n }\n }\n }\n if (bundle.parent) {\n parents = parents.concat(getParents(bundle.parent, id));\n }\n return parents;\n}\nfunction updateLink(link) {\n var href = link.getAttribute('href');\n if (!href) {\n return;\n }\n var newLink = link.cloneNode();\n newLink.onload = function () {\n if (link.parentNode !== null) {\n // $FlowFixMe\n link.parentNode.removeChild(link);\n }\n };\n newLink.setAttribute('href',\n // $FlowFixMe\n href.split('?')[0] + '?' + Date.now());\n // $FlowFixMe\n link.parentNode.insertBefore(newLink, link.nextSibling);\n}\nvar cssTimeout = null;\nfunction reloadCSS() {\n if (cssTimeout || typeof document === 'undefined') {\n return;\n }\n cssTimeout = setTimeout(function () {\n var links = document.querySelectorAll('link[rel=\"stylesheet\"]');\n for (var i = 0; i < links.length; i++) {\n // $FlowFixMe[incompatible-type]\n var href /*: string */ = links[i].getAttribute('href');\n var hostname = getHostname();\n var servedFromHMRServer = hostname === 'localhost' ? new RegExp('^(https?:\\\\/\\\\/(0.0.0.0|127.0.0.1)|localhost):' + getPort()).test(href) : href.indexOf(hostname + ':' + getPort());\n var absolute = /^https?:\\/\\//i.test(href) && href.indexOf(location.origin) !== 0 && !servedFromHMRServer;\n if (!absolute) {\n updateLink(links[i]);\n }\n }\n cssTimeout = null;\n }, 50);\n}\nfunction hmrDownload(asset) {\n if (asset.type === 'js') {\n if (typeof document !== 'undefined') {\n let script = document.createElement('script');\n script.src = asset.url + '?t=' + Date.now();\n if (asset.outputFormat === 'esmodule') {\n script.type = 'module';\n }\n return new Promise((resolve, reject) => {\n var _document$head;\n script.onload = () => resolve(script);\n script.onerror = reject;\n (_document$head = document.head) === null || _document$head === void 0 || _document$head.appendChild(script);\n });\n } else if (typeof importScripts === 'function') {\n // Worker scripts\n if (asset.outputFormat === 'esmodule') {\n return __parcel__import__(asset.url + '?t=' + Date.now());\n } else {\n return new Promise((resolve, reject) => {\n try {\n __parcel__importScripts__(asset.url + '?t=' + Date.now());\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n }\n }\n }\n}\nasync function hmrApplyUpdates(assets) {\n global.parcelHotUpdate = Object.create(null);\n let scriptsToRemove;\n try {\n // If sourceURL comments aren't supported in eval, we need to load\n // the update from the dev server over HTTP so that stack traces\n // are correct in errors/logs. This is much slower than eval, so\n // we only do it if needed (currently just Safari).\n // https://bugs.webkit.org/show_bug.cgi?id=137297\n // This path is also taken if a CSP disallows eval.\n if (!supportsSourceURL) {\n let promises = assets.map(asset => {\n var _hmrDownload;\n return (_hmrDownload = hmrDownload(asset)) === null || _hmrDownload === void 0 ? void 0 : _hmrDownload.catch(err => {\n // Web extension fix\n if (extCtx && extCtx.runtime && extCtx.runtime.getManifest().manifest_version == 3 && typeof ServiceWorkerGlobalScope != 'undefined' && global instanceof ServiceWorkerGlobalScope) {\n extCtx.runtime.reload();\n return;\n }\n throw err;\n });\n });\n scriptsToRemove = await Promise.all(promises);\n }\n assets.forEach(function (asset) {\n hmrApply(module.bundle.root, asset);\n });\n } finally {\n delete global.parcelHotUpdate;\n if (scriptsToRemove) {\n scriptsToRemove.forEach(script => {\n if (script) {\n var _document$head2;\n (_document$head2 = document.head) === null || _document$head2 === void 0 || _document$head2.removeChild(script);\n }\n });\n }\n }\n}\nfunction hmrApply(bundle /*: ParcelRequire */, asset /*: HMRAsset */) {\n var modules = bundle.modules;\n if (!modules) {\n return;\n }\n if (asset.type === 'css') {\n reloadCSS();\n } else if (asset.type === 'js') {\n let deps = asset.depsByBundle[bundle.HMR_BUNDLE_ID];\n if (deps) {\n if (modules[asset.id]) {\n // Remove dependencies that are removed and will become orphaned.\n // This is necessary so that if the asset is added back again, the cache is gone, and we prevent a full page reload.\n let oldDeps = modules[asset.id][1];\n for (let dep in oldDeps) {\n if (!deps[dep] || deps[dep] !== oldDeps[dep]) {\n let id = oldDeps[dep];\n let parents = getParents(module.bundle.root, id);\n if (parents.length === 1) {\n hmrDelete(module.bundle.root, id);\n }\n }\n }\n }\n if (supportsSourceURL) {\n // Global eval. We would use `new Function` here but browser\n // support for source maps is better with eval.\n (0, eval)(asset.output);\n }\n\n // $FlowFixMe\n let fn = global.parcelHotUpdate[asset.id];\n modules[asset.id] = [fn, deps];\n }\n\n // Always traverse to the parent bundle, even if we already replaced the asset in this bundle.\n // This is required in case modules are duplicated. We need to ensure all instances have the updated code.\n if (bundle.parent) {\n hmrApply(bundle.parent, asset);\n }\n }\n}\nfunction hmrDelete(bundle, id) {\n let modules = bundle.modules;\n if (!modules) {\n return;\n }\n if (modules[id]) {\n // Collect dependencies that will become orphaned when this module is deleted.\n let deps = modules[id][1];\n let orphans = [];\n for (let dep in deps) {\n let parents = getParents(module.bundle.root, deps[dep]);\n if (parents.length === 1) {\n orphans.push(deps[dep]);\n }\n }\n\n // Delete the module. This must be done before deleting dependencies in case of circular dependencies.\n delete modules[id];\n delete bundle.cache[id];\n\n // Now delete the orphans.\n orphans.forEach(id => {\n hmrDelete(module.bundle.root, id);\n });\n } else if (bundle.parent) {\n hmrDelete(bundle.parent, id);\n }\n}\nfunction hmrAcceptCheck(bundle /*: ParcelRequire */, id /*: string */, depsByBundle /*: ?{ [string]: { [string]: string } }*/) {\n checkedAssets = {};\n if (hmrAcceptCheckOne(bundle, id, depsByBundle)) {\n return true;\n }\n\n // Traverse parents breadth first. All possible ancestries must accept the HMR update, or we'll reload.\n let parents = getParents(module.bundle.root, id);\n let accepted = false;\n while (parents.length > 0) {\n let v = parents.shift();\n let a = hmrAcceptCheckOne(v[0], v[1], null);\n if (a) {\n // If this parent accepts, stop traversing upward, but still consider siblings.\n accepted = true;\n } else if (a !== null) {\n // Otherwise, queue the parents in the next level upward.\n let p = getParents(module.bundle.root, v[1]);\n if (p.length === 0) {\n // If there are no parents, then we've reached an entry without accepting. Reload.\n accepted = false;\n break;\n }\n parents.push(...p);\n }\n }\n return accepted;\n}\nfunction hmrAcceptCheckOne(bundle /*: ParcelRequire */, id /*: string */, depsByBundle /*: ?{ [string]: { [string]: string } }*/) {\n var modules = bundle.modules;\n if (!modules) {\n return;\n }\n if (depsByBundle && !depsByBundle[bundle.HMR_BUNDLE_ID]) {\n // If we reached the root bundle without finding where the asset should go,\n // there's nothing to do. Mark as \"accepted\" so we don't reload the page.\n if (!bundle.parent) {\n bundleNotFound = true;\n return true;\n }\n return hmrAcceptCheckOne(bundle.parent, id, depsByBundle);\n }\n if (checkedAssets[id]) {\n return null;\n }\n checkedAssets[id] = true;\n var cached = bundle.cache[id];\n if (!cached) {\n return true;\n }\n assetsToDispose.push([bundle, id]);\n if (cached && cached.hot && cached.hot._acceptCallbacks.length) {\n assetsToAccept.push([bundle, id]);\n return true;\n }\n return false;\n}\nfunction hmrDisposeQueue() {\n // Dispose all old assets.\n for (let i = 0; i < assetsToDispose.length; i++) {\n let id = assetsToDispose[i][1];\n if (!disposedAssets[id]) {\n hmrDispose(assetsToDispose[i][0], id);\n disposedAssets[id] = true;\n }\n }\n assetsToDispose = [];\n}\nfunction hmrDispose(bundle /*: ParcelRequire */, id /*: string */) {\n var cached = bundle.cache[id];\n bundle.hotData[id] = {};\n if (cached && cached.hot) {\n cached.hot.data = bundle.hotData[id];\n }\n if (cached && cached.hot && cached.hot._disposeCallbacks.length) {\n cached.hot._disposeCallbacks.forEach(function (cb) {\n cb(bundle.hotData[id]);\n });\n }\n delete bundle.cache[id];\n}\nfunction hmrAccept(bundle /*: ParcelRequire */, id /*: string */) {\n // Execute the module.\n bundle(id);\n\n // Run the accept callbacks in the new version of the module.\n var cached = bundle.cache[id];\n if (cached && cached.hot && cached.hot._acceptCallbacks.length) {\n let assetsToAlsoAccept = [];\n cached.hot._acceptCallbacks.forEach(function (cb) {\n let additionalAssets = cb(function () {\n return getParents(module.bundle.root, id);\n });\n if (Array.isArray(additionalAssets) && additionalAssets.length) {\n assetsToAlsoAccept.push(...additionalAssets);\n }\n });\n if (assetsToAlsoAccept.length) {\n let handled = assetsToAlsoAccept.every(function (a) {\n return hmrAcceptCheck(a[0], a[1]);\n });\n if (!handled) {\n return fullReload();\n }\n hmrDisposeQueue();\n }\n }\n}","import './assets/scripts/index.ts';\nimport './assets/scss/index.scss';\n","const favoritePosts = {\n init() {\n if (!this.component) return;\n\n this.addEventListeners();\n },\n\n addEventListeners() {\n this.component.addEventListener('click', this.handleClick.bind(this));\n },\n\n async getUserId() {\n // @ts-ignore\n return fetch(wpApiSettings.root + 'wp/v2/users/me', {\n method: 'GET',\n headers: {\n // @ts-ignore\n 'X-WP-Nonce': wpApiSettings.nonce\n }\n })\n .then(response => response.json())\n .then(user => user.id)\n .catch(error => {\n console.error('Erro:', error);\n return null;\n });\n },\n\n async favoritePost() {\n const userId = await this.getUserId();\n if (!userId) return;\n\n // @ts-ignore\n fetch(wpApiSettings.root + wpApiSettings.rest_namespace + '/favorite-posts', {\n method: 'POST',\n body: JSON.stringify({\n post_id: this.component.dataset.postId,\n user_id: userId\n }),\n headers: {\n 'Content-Type': 'application/json',\n // @ts-ignore\n 'X-WP-Nonce': wpApiSettings.nonce\n }\n })\n .then(response => response.json())\n .then(data => {\n this.component.classList.toggle('is-favorite', data.code === 'favorite_post_added');\n })\n .catch(error => {\n console.error('Erro:', error);\n });\n },\n\n async handleClick() {\n if (this.component.classList.contains('is-favorite')) {\n await this.removeFavoritePost();\n } else {\n await this.favoritePost();\n }\n },\n\n async removeFavoritePost() {\n const userId = await this.getUserId();\n if (!userId) return;\n\n // @ts-ignore\n fetch(wpApiSettings.root + wpApiSettings.rest_namespace + '/favorite-posts', {\n method: 'DELETE',\n body: JSON.stringify({\n post_id: this.component.dataset.postId,\n user_id: userId\n }),\n headers: {\n 'Content-Type': 'application/json',\n // @ts-ignore\n 'X-WP-Nonce': wpApiSettings.nonce\n }\n })\n .then(response => response.json())\n .then(data => {\n this.component.classList.toggle('is-favorite', data.code === 'favorite_post_removed');\n })\n .catch(error => {\n console.error('Erro:', error);\n });\n },\n component: document.querySelector('.favorite-post-button'),\n}\n\nfavoritePosts.init();\n"],"names":[],"version":3,"file":"index.js.map","sourceRoot":"../"} \ No newline at end of file diff --git a/src/restHandler.php b/src/restHandler.php index c110e36b..cea613b5 100644 --- a/src/restHandler.php +++ b/src/restHandler.php @@ -29,6 +29,11 @@ public function registerRoutes() { 'methods' => 'POST', 'callback' => [$this, 'addFavoritePost'], ]); + + register_rest_route($this->restNamespace, '/favorite-posts', [ + 'methods' => 'DELETE', + 'callback' => [$this, 'removeFavoritePost'], + ]); } public function getFavoritePosts($request) { @@ -91,25 +96,19 @@ public function addFavoritePost($request) { } public function removeFavoritePost($request) { - $user_id = $request->get_param('user_id'); - $post_id = $request->get_param('post_id'); - - $result = $this->dbHandler->removeFavorite($user_id, $post_id); + $params = $request->get_json_params(); + $user_id = isset($params['user_id']) ? absint($params['user_id']) : absint($request->get_param('user_id')); + $post_id = isset($params['post_id']) ? absint($params['post_id']) : absint($request->get_param('post_id')); - if ($result) { + if (!$user_id || !$post_id) { return new \WP_REST_Response([ - 'code' => 'favorite_post_removed', - 'status' => 'success', - 'message' => 'Favorite post removed', + 'code' => 'invalid_favorite_post_params', + 'status' => 'error', + 'message' => 'Invalid user_id or post_id', 'data' => null - ], 200); + ], 400); } - return new \WP_REST_Response([ - 'code' => 'failed_to_remove_favorite_post', - 'status' => 'error', - 'message' => 'Failed to remove favorite post', - 'data' => null - ], 500); + return $this->dbHandler->removeFavorite($user_id, $post_id); } } From 6899daee3ece7f40a3a99721adf7d9c63b1a0fe7 Mon Sep 17 00:00:00 2001 From: Kayo Tusthler Date: Wed, 25 Mar 2026 16:20:38 -0300 Subject: [PATCH 3/4] feat: add dialog loader for favorite post actions --- assets/scripts/index.ts | 5 + assets/scss/index.scss | 40 ++ assets/scss/loader.scss | 25 + dist/index.css | 21 +- dist/index.css.map | 1 - dist/index.js | 794 +------------------------------ dist/index.js.map | 1 - wordpress-back-end-challenge.php | 5 + 8 files changed, 77 insertions(+), 815 deletions(-) create mode 100644 assets/scss/loader.scss delete mode 100644 dist/index.css.map delete mode 100644 dist/index.js.map diff --git a/assets/scripts/index.ts b/assets/scripts/index.ts index 90d52861..828e2f34 100644 --- a/assets/scripts/index.ts +++ b/assets/scripts/index.ts @@ -53,11 +53,15 @@ const favoritePosts = { }, async handleClick() { + !!this.dialogLoader && this.dialogLoader.showModal(); + if (this.component.classList.contains('is-favorite')) { await this.removeFavoritePost(); } else { await this.favoritePost(); } + + !!this.dialogLoader && this.dialogLoader.close(); }, async removeFavoritePost() { @@ -86,6 +90,7 @@ const favoritePosts = { }); }, component: document.querySelector('.favorite-post-button'), + dialogLoader: document.querySelector('#dialog-loader'), } favoritePosts.init(); diff --git a/assets/scss/index.scss b/assets/scss/index.scss index d848b287..ae81e4fa 100644 --- a/assets/scss/index.scss +++ b/assets/scss/index.scss @@ -1,3 +1,5 @@ +@import './loader.scss'; + .favorite-post-button { background: none; border: none; @@ -18,4 +20,42 @@ height: 32px; pointer-events: none; } +} + +#dialog-loader { + background-color: transparent; + border: none; + opacity: 0; + padding: 150px; + transform: scaleY(0); + transition: opacity 0.7s ease-out, + transform 0.7s ease-out, + overlay 0.7s ease-out allow-discrete, + display 0.7s ease-out allow-discrete; + + &:open { + opacity: 1; + transform: scaleY(1); + } + + /* Styles the *starting point* of the open state */ + /* Must come AFTER the dialog:open rule due to equal specificity */ + @starting-style { + &:open { + opacity: 0; + transform: scaleY(0); + } + } + + &::backdrop { + background-color: rgba(255, 255, 255, 0); + transition: background-color 0.7s ease-out allow-discrete; + } + + &:open::backdrop { + background-color: rgba(255, 255, 255, 0.5); + backdrop-filter: blur(10px); + } + + .loader { width: 96px; } } \ No newline at end of file diff --git a/assets/scss/loader.scss b/assets/scss/loader.scss new file mode 100644 index 00000000..df7f3335 --- /dev/null +++ b/assets/scss/loader.scss @@ -0,0 +1,25 @@ +/* HTML:
*/ +.loader { + width: 50px; + aspect-ratio: 1; + color:#dc1818; + background: + radial-gradient(circle at 60% 65%, currentColor 62%, #0000 65%) top left, + radial-gradient(circle at 40% 65%, currentColor 62%, #0000 65%) top right, + linear-gradient(to bottom left, currentColor 42%,#0000 43%) bottom left , + linear-gradient(to bottom right,currentColor 42%,#0000 43%) bottom right; + background-size: 50% 50%; + background-repeat: no-repeat; + position: relative; +} +.loader:after { + content: ""; + position: absolute; + inset: 0; + background: inherit; + opacity: 0.4; + animation: l3 1s infinite; +} +@keyframes l3 { + to {transform:scale(1.8);opacity:0} +} \ No newline at end of file diff --git a/dist/index.css b/dist/index.css index 202e0216..766f793f 100644 --- a/dist/index.css +++ b/dist/index.css @@ -1,21 +1,2 @@ -.favorite-post-button { - cursor: pointer; - opacity: .5; - background: none; - border: none; - outline: none; - padding: 0; - transition: all .3s ease-in-out; - display: block; -} - -.favorite-post-button:hover, .favorite-post-button.is-favorite { - opacity: 1; - transform: scale(2); -} - -.favorite-post-button img { - pointer-events: none; - height: 32px; -} +.loader{aspect-ratio:1;color:#dc1818;background-color:#0000;background-image:radial-gradient(circle at 60% 65%,currentColor 62%,#0000 65%),radial-gradient(circle at 40% 65%,currentColor 62%,#0000 65%),linear-gradient(to bottom left,currentColor 42%,#0000 43%),linear-gradient(to bottom right,currentColor 42%,#0000 43%);background-position:0 0,100% 0,0 100%,100% 100%;background-repeat:no-repeat;background-size:50% 50%;background-attachment:scroll,scroll,scroll,scroll;background-origin:padding-box,padding-box,padding-box,padding-box;background-clip:border-box,border-box,border-box,border-box;width:50px;position:relative}.loader:after{content:"";background:inherit;opacity:.4;animation:1s infinite l3;position:absolute;inset:0}@keyframes l3{to{opacity:0;transform:scale(1.8)}}.favorite-post-button{cursor:pointer;opacity:.5;background:0 0;border:none;outline:none;padding:0;transition:all .3s ease-in-out;display:block}.favorite-post-button:hover,.favorite-post-button.is-favorite{opacity:1;transform:scale(2)}.favorite-post-button img{pointer-events:none;height:32px}#dialog-loader{opacity:0;transition:opacity .7s ease-out, transform .7s ease-out, overlay .7s ease-out allow-discrete, display .7s ease-out allow-discrete;background-color:#0000;border:none;padding:150px;transform:scaleY(0)}#dialog-loader:open{opacity:1;transform:scaleY(1)}@starting-style{#dialog-loader:open{opacity:0;transform:scaleY(0)}}#dialog-loader::backdrop{transition:background-color .7s ease-out allow-discrete;background-color:#fff0}#dialog-loader:open::backdrop{backdrop-filter:blur(10px);background-color:#ffffff80}#dialog-loader .loader{width:96px} /*# sourceMappingURL=index.css.map */ diff --git a/dist/index.css.map b/dist/index.css.map deleted file mode 100644 index cc1488ed..00000000 --- a/dist/index.css.map +++ /dev/null @@ -1 +0,0 @@ -{"mappings":"AAAA;;;;;;;;;;;AAUI;;;;;AAMA","sources":["assets/scss/index.scss"],"sourcesContent":[".favorite-post-button {\n background: none;\n border: none;\n cursor: pointer;\n display: block;\n outline: none;\n opacity: 0.5;\n padding: 0;\n transition: all 0.3s ease-in-out;\n\n &:hover,\n &.is-favorite {\n opacity: 1;\n transform: scale(2);\n }\n\n img {\n height: 32px;\n pointer-events: none;\n }\n}"],"names":[],"version":3,"file":"index.css.map","sourceRoot":"../"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index a8de6048..854e0446 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,794 +1,2 @@ -// modules are defined as an array -// [ module function, map of requires ] -// -// map of requires is short require name -> numeric require -// -// anything defined in a previous bundle is accessed via the -// orig method which is the require for previous bundles - -(function ( - modules, - entry, - mainEntry, - parcelRequireName, - externals, - distDir, - publicUrl, - devServer -) { - /* eslint-disable no-undef */ - var globalObject = - typeof globalThis !== 'undefined' - ? globalThis - : typeof self !== 'undefined' - ? self - : typeof window !== 'undefined' - ? window - : typeof global !== 'undefined' - ? global - : {}; - /* eslint-enable no-undef */ - - // Save the require from previous bundle to this closure if any - var previousRequire = - typeof globalObject[parcelRequireName] === 'function' && - globalObject[parcelRequireName]; - - var importMap = previousRequire.i || {}; - var cache = previousRequire.cache || {}; - // Do not use `require` to prevent Webpack from trying to bundle this call - var nodeRequire = - typeof module !== 'undefined' && - typeof module.require === 'function' && - module.require.bind(module); - - function newRequire(name, jumped) { - if (!cache[name]) { - if (!modules[name]) { - if (externals[name]) { - return externals[name]; - } - // if we cannot find the module within our internal map or - // cache jump to the current global require ie. the last bundle - // that was added to the page. - var currentRequire = - typeof globalObject[parcelRequireName] === 'function' && - globalObject[parcelRequireName]; - if (!jumped && currentRequire) { - return currentRequire(name, true); - } - - // If there are other bundles on this page the require from the - // previous one is saved to 'previousRequire'. Repeat this as - // many times as there are bundles until the module is found or - // we exhaust the require chain. - if (previousRequire) { - return previousRequire(name, true); - } - - // Try the node require function if it exists. - if (nodeRequire && typeof name === 'string') { - return nodeRequire(name); - } - - var err = new Error("Cannot find module '" + name + "'"); - err.code = 'MODULE_NOT_FOUND'; - throw err; - } - - localRequire.resolve = resolve; - localRequire.cache = {}; - - var module = (cache[name] = new newRequire.Module(name)); - - modules[name][0].call( - module.exports, - localRequire, - module, - module.exports, - globalObject - ); - } - - return cache[name].exports; - - function localRequire(x) { - var res = localRequire.resolve(x); - if (res === false) { - return {}; - } - // Synthesize a module to follow re-exports. - if (Array.isArray(res)) { - var m = {__esModule: true}; - res.forEach(function (v) { - var key = v[0]; - var id = v[1]; - var exp = v[2] || v[0]; - var x = newRequire(id); - if (key === '*') { - Object.keys(x).forEach(function (key) { - if ( - key === 'default' || - key === '__esModule' || - Object.prototype.hasOwnProperty.call(m, key) - ) { - return; - } - - Object.defineProperty(m, key, { - enumerable: true, - get: function () { - return x[key]; - }, - }); - }); - } else if (exp === '*') { - Object.defineProperty(m, key, { - enumerable: true, - value: x, - }); - } else { - Object.defineProperty(m, key, { - enumerable: true, - get: function () { - if (exp === 'default') { - return x.__esModule ? x.default : x; - } - return x[exp]; - }, - }); - } - }); - return m; - } - return newRequire(res); - } - - function resolve(x) { - var id = modules[name][1][x]; - return id != null ? id : x; - } - } - - function Module(moduleName) { - this.id = moduleName; - this.bundle = newRequire; - this.require = nodeRequire; - this.exports = {}; - } - - newRequire.isParcelRequire = true; - newRequire.Module = Module; - newRequire.modules = modules; - newRequire.cache = cache; - newRequire.parent = previousRequire; - newRequire.distDir = distDir; - newRequire.publicUrl = publicUrl; - newRequire.devServer = devServer; - newRequire.i = importMap; - newRequire.register = function (id, exports) { - modules[id] = [ - function (require, module) { - module.exports = exports; - }, - {}, - ]; - }; - - // Only insert newRequire.load when it is actually used. - // The code in this file is linted against ES5, so dynamic import is not allowed. - // INSERT_LOAD_HERE - - Object.defineProperty(newRequire, 'root', { - get: function () { - return globalObject[parcelRequireName]; - }, - }); - - globalObject[parcelRequireName] = newRequire; - - for (var i = 0; i < entry.length; i++) { - newRequire(entry[i]); - } - - if (mainEntry) { - // Expose entry point to Node, AMD or browser globals - // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js - var mainExports = newRequire(mainEntry); - - // CommonJS - if (typeof exports === 'object' && typeof module !== 'undefined') { - module.exports = mainExports; - - // RequireJS - } else if (typeof define === 'function' && define.amd) { - define(function () { - return mainExports; - }); - } - } -})({"1Mq6V":[function(require,module,exports,__globalThis) { -var global = arguments[3]; -var HMR_HOST = null; -var HMR_PORT = 1234; -var HMR_SERVER_PORT = 1234; -var HMR_SECURE = false; -var HMR_ENV_HASH = "d6ea1d42532a7575"; -var HMR_USE_SSE = false; -module.bundle.HMR_BUNDLE_ID = "78fcd0ac8e9bd240"; -"use strict"; -/* global HMR_HOST, HMR_PORT, HMR_SERVER_PORT, HMR_ENV_HASH, HMR_SECURE, HMR_USE_SSE, chrome, browser, __parcel__import__, __parcel__importScripts__, ServiceWorkerGlobalScope */ /*:: -import type { - HMRAsset, - HMRMessage, -} from '@parcel/reporter-dev-server/src/HMRServer.js'; -interface ParcelRequire { - (string): mixed; - cache: {|[string]: ParcelModule|}; - hotData: {|[string]: mixed|}; - Module: any; - parent: ?ParcelRequire; - isParcelRequire: true; - modules: {|[string]: [Function, {|[string]: string|}]|}; - HMR_BUNDLE_ID: string; - root: ParcelRequire; -} -interface ParcelModule { - hot: {| - data: mixed, - accept(cb: (Function) => void): void, - dispose(cb: (mixed) => void): void, - // accept(deps: Array | string, cb: (Function) => void): void, - // decline(): void, - _acceptCallbacks: Array<(Function) => void>, - _disposeCallbacks: Array<(mixed) => void>, - |}; -} -interface ExtensionContext { - runtime: {| - reload(): void, - getURL(url: string): string; - getManifest(): {manifest_version: number, ...}; - |}; -} -declare var module: {bundle: ParcelRequire, ...}; -declare var HMR_HOST: string; -declare var HMR_PORT: string; -declare var HMR_SERVER_PORT: string; -declare var HMR_ENV_HASH: string; -declare var HMR_SECURE: boolean; -declare var HMR_USE_SSE: boolean; -declare var chrome: ExtensionContext; -declare var browser: ExtensionContext; -declare var __parcel__import__: (string) => Promise; -declare var __parcel__importScripts__: (string) => Promise; -declare var globalThis: typeof self; -declare var ServiceWorkerGlobalScope: Object; -*/ var OVERLAY_ID = '__parcel__error__overlay__'; -var OldModule = module.bundle.Module; -function Module(moduleName) { - OldModule.call(this, moduleName); - this.hot = { - data: module.bundle.hotData[moduleName], - _acceptCallbacks: [], - _disposeCallbacks: [], - accept: function(fn) { - this._acceptCallbacks.push(fn || function() {}); - }, - dispose: function(fn) { - this._disposeCallbacks.push(fn); - } - }; - module.bundle.hotData[moduleName] = undefined; -} -module.bundle.Module = Module; -module.bundle.hotData = {}; -var checkedAssets /*: {|[string]: boolean|} */ , disposedAssets /*: {|[string]: boolean|} */ , assetsToDispose /*: Array<[ParcelRequire, string]> */ , assetsToAccept /*: Array<[ParcelRequire, string]> */ , bundleNotFound = false; -function getHostname() { - return HMR_HOST || (typeof location !== 'undefined' && location.protocol.indexOf('http') === 0 ? location.hostname : 'localhost'); -} -function getPort() { - return HMR_PORT || (typeof location !== 'undefined' ? location.port : HMR_SERVER_PORT); -} -// eslint-disable-next-line no-redeclare -let WebSocket = globalThis.WebSocket; -if (!WebSocket && typeof module.bundle.root === 'function') try { - // eslint-disable-next-line no-global-assign - WebSocket = module.bundle.root('ws'); -} catch { -// ignore. -} -var hostname = getHostname(); -var port = getPort(); -var protocol = HMR_SECURE || typeof location !== 'undefined' && location.protocol === 'https:' && ![ - 'localhost', - '127.0.0.1', - '0.0.0.0' -].includes(hostname) ? 'wss' : 'ws'; -// eslint-disable-next-line no-redeclare -var parent = module.bundle.parent; -if (!parent || !parent.isParcelRequire) { - // Web extension context - var extCtx = typeof browser === 'undefined' ? typeof chrome === 'undefined' ? null : chrome : browser; - // Safari doesn't support sourceURL in error stacks. - // eval may also be disabled via CSP, so do a quick check. - var supportsSourceURL = false; - try { - (0, eval)('throw new Error("test"); //# sourceURL=test.js'); - } catch (err) { - supportsSourceURL = err.stack.includes('test.js'); - } - var ws; - if (HMR_USE_SSE) ws = new EventSource('/__parcel_hmr'); - else try { - // If we're running in the dev server's node runner, listen for messages on the parent port. - let { workerData, parentPort } = module.bundle.root('node:worker_threads') /*: any*/ ; - if (workerData !== null && workerData !== void 0 && workerData.__parcel) { - parentPort.on('message', async (message)=>{ - try { - await handleMessage(message); - parentPort.postMessage('updated'); - } catch { - parentPort.postMessage('restart'); - } - }); - // After the bundle has finished running, notify the dev server that the HMR update is complete. - queueMicrotask(()=>parentPort.postMessage('ready')); - } - } catch { - if (typeof WebSocket !== 'undefined') try { - ws = new WebSocket(protocol + '://' + hostname + (port ? ':' + port : '') + '/'); - } catch (err) { - // Ignore cloudflare workers error. - if (err.message && !err.message.includes('Disallowed operation called within global scope')) console.error(err.message); - } - } - if (ws) { - // $FlowFixMe - ws.onmessage = async function(event /*: {data: string, ...} */ ) { - var data /*: HMRMessage */ = JSON.parse(event.data); - await handleMessage(data); - }; - if (ws instanceof WebSocket) { - ws.onerror = function(e) { - if (e.message) console.error(e.message); - }; - ws.onclose = function() { - console.warn("[parcel] \uD83D\uDEA8 Connection to the HMR server was lost"); - }; - } - } -} -async function handleMessage(data /*: HMRMessage */ ) { - checkedAssets = {} /*: {|[string]: boolean|} */ ; - disposedAssets = {} /*: {|[string]: boolean|} */ ; - assetsToAccept = []; - assetsToDispose = []; - bundleNotFound = false; - if (data.type === 'reload') fullReload(); - else if (data.type === 'update') { - // Remove error overlay if there is one - if (typeof document !== 'undefined') removeErrorOverlay(); - let assets = data.assets; - // Handle HMR Update - let handled = assets.every((asset)=>{ - return asset.type === 'css' || asset.type === 'js' && hmrAcceptCheck(module.bundle.root, asset.id, asset.depsByBundle); - }); - // Dispatch a custom event in case a bundle was not found. This might mean - // an asset on the server changed and we should reload the page. This event - // gives the client an opportunity to refresh without losing state - // (e.g. via React Server Components). If e.preventDefault() is not called, - // we will trigger a full page reload. - if (handled && bundleNotFound && assets.some((a)=>a.envHash !== HMR_ENV_HASH) && typeof window !== 'undefined' && typeof CustomEvent !== 'undefined') handled = !window.dispatchEvent(new CustomEvent('parcelhmrreload', { - cancelable: true - })); - if (handled) { - console.clear(); - // Dispatch custom event so other runtimes (e.g React Refresh) are aware. - if (typeof window !== 'undefined' && typeof CustomEvent !== 'undefined') window.dispatchEvent(new CustomEvent('parcelhmraccept')); - await hmrApplyUpdates(assets); - hmrDisposeQueue(); - // Run accept callbacks. This will also re-execute other disposed assets in topological order. - let processedAssets = {}; - for(let i = 0; i < assetsToAccept.length; i++){ - let id = assetsToAccept[i][1]; - if (!processedAssets[id]) { - hmrAccept(assetsToAccept[i][0], id); - processedAssets[id] = true; - } - } - } else fullReload(); - } - if (data.type === 'error') { - // Log parcel errors to console - for (let ansiDiagnostic of data.diagnostics.ansi){ - let stack = ansiDiagnostic.codeframe ? ansiDiagnostic.codeframe : ansiDiagnostic.stack; - console.error("\uD83D\uDEA8 [parcel]: " + ansiDiagnostic.message + '\n' + stack + '\n\n' + ansiDiagnostic.hints.join('\n')); - } - if (typeof document !== 'undefined') { - // Render the fancy html overlay - removeErrorOverlay(); - var overlay = createErrorOverlay(data.diagnostics.html); - // $FlowFixMe - document.body.appendChild(overlay); - } - } -} -function removeErrorOverlay() { - var overlay = document.getElementById(OVERLAY_ID); - if (overlay) { - overlay.remove(); - console.log("[parcel] \u2728 Error resolved"); - } -} -function createErrorOverlay(diagnostics) { - var overlay = document.createElement('div'); - overlay.id = OVERLAY_ID; - let errorHTML = '
'; - for (let diagnostic of diagnostics){ - let stack = diagnostic.frames.length ? diagnostic.frames.reduce((p, frame)=>{ - return `${p} -${frame.location} -${frame.code}`; - }, '') : diagnostic.stack; - errorHTML += ` -
-
- \u{1F6A8} ${diagnostic.message} -
-
${stack}
-
- ${diagnostic.hints.map((hint)=>"
\uD83D\uDCA1 " + hint + '
').join('')} -
- ${diagnostic.documentation ? `
\u{1F4DD} Learn more
` : ''} -
- `; - } - errorHTML += '
'; - overlay.innerHTML = errorHTML; - return overlay; -} -function fullReload() { - if (typeof location !== 'undefined' && 'reload' in location) location.reload(); - else if (typeof extCtx !== 'undefined' && extCtx && extCtx.runtime && extCtx.runtime.reload) extCtx.runtime.reload(); - else try { - let { workerData, parentPort } = module.bundle.root('node:worker_threads') /*: any*/ ; - if (workerData !== null && workerData !== void 0 && workerData.__parcel) parentPort.postMessage('restart'); - } catch (err) { - console.error("[parcel] \u26A0\uFE0F An HMR update was not accepted. Please restart the process."); - } -} -function getParents(bundle, id) /*: Array<[ParcelRequire, string]> */ { - var modules = bundle.modules; - if (!modules) return []; - var parents = []; - var k, d, dep; - for(k in modules)for(d in modules[k][1]){ - dep = modules[k][1][d]; - if (dep === id || Array.isArray(dep) && dep[dep.length - 1] === id) parents.push([ - bundle, - k - ]); - } - if (bundle.parent) parents = parents.concat(getParents(bundle.parent, id)); - return parents; -} -function updateLink(link) { - var href = link.getAttribute('href'); - if (!href) return; - var newLink = link.cloneNode(); - newLink.onload = function() { - if (link.parentNode !== null) // $FlowFixMe - link.parentNode.removeChild(link); - }; - newLink.setAttribute('href', // $FlowFixMe - href.split('?')[0] + '?' + Date.now()); - // $FlowFixMe - link.parentNode.insertBefore(newLink, link.nextSibling); -} -var cssTimeout = null; -function reloadCSS() { - if (cssTimeout || typeof document === 'undefined') return; - cssTimeout = setTimeout(function() { - var links = document.querySelectorAll('link[rel="stylesheet"]'); - for(var i = 0; i < links.length; i++){ - // $FlowFixMe[incompatible-type] - var href /*: string */ = links[i].getAttribute('href'); - var hostname = getHostname(); - var servedFromHMRServer = hostname === 'localhost' ? new RegExp('^(https?:\\/\\/(0.0.0.0|127.0.0.1)|localhost):' + getPort()).test(href) : href.indexOf(hostname + ':' + getPort()); - var absolute = /^https?:\/\//i.test(href) && href.indexOf(location.origin) !== 0 && !servedFromHMRServer; - if (!absolute) updateLink(links[i]); - } - cssTimeout = null; - }, 50); -} -function hmrDownload(asset) { - if (asset.type === 'js') { - if (typeof document !== 'undefined') { - let script = document.createElement('script'); - script.src = asset.url + '?t=' + Date.now(); - if (asset.outputFormat === 'esmodule') script.type = 'module'; - return new Promise((resolve, reject)=>{ - var _document$head; - script.onload = ()=>resolve(script); - script.onerror = reject; - (_document$head = document.head) === null || _document$head === void 0 || _document$head.appendChild(script); - }); - } else if (typeof importScripts === 'function') { - // Worker scripts - if (asset.outputFormat === 'esmodule') return import(asset.url + '?t=' + Date.now()); - else return new Promise((resolve, reject)=>{ - try { - importScripts(asset.url + '?t=' + Date.now()); - resolve(); - } catch (err) { - reject(err); - } - }); - } - } -} -async function hmrApplyUpdates(assets) { - global.parcelHotUpdate = Object.create(null); - let scriptsToRemove; - try { - // If sourceURL comments aren't supported in eval, we need to load - // the update from the dev server over HTTP so that stack traces - // are correct in errors/logs. This is much slower than eval, so - // we only do it if needed (currently just Safari). - // https://bugs.webkit.org/show_bug.cgi?id=137297 - // This path is also taken if a CSP disallows eval. - if (!supportsSourceURL) { - let promises = assets.map((asset)=>{ - var _hmrDownload; - return (_hmrDownload = hmrDownload(asset)) === null || _hmrDownload === void 0 ? void 0 : _hmrDownload.catch((err)=>{ - // Web extension fix - if (extCtx && extCtx.runtime && extCtx.runtime.getManifest().manifest_version == 3 && typeof ServiceWorkerGlobalScope != 'undefined' && global instanceof ServiceWorkerGlobalScope) { - extCtx.runtime.reload(); - return; - } - throw err; - }); - }); - scriptsToRemove = await Promise.all(promises); - } - assets.forEach(function(asset) { - hmrApply(module.bundle.root, asset); - }); - } finally{ - delete global.parcelHotUpdate; - if (scriptsToRemove) scriptsToRemove.forEach((script)=>{ - if (script) { - var _document$head2; - (_document$head2 = document.head) === null || _document$head2 === void 0 || _document$head2.removeChild(script); - } - }); - } -} -function hmrApply(bundle /*: ParcelRequire */ , asset /*: HMRAsset */ ) { - var modules = bundle.modules; - if (!modules) return; - if (asset.type === 'css') reloadCSS(); - else if (asset.type === 'js') { - let deps = asset.depsByBundle[bundle.HMR_BUNDLE_ID]; - if (deps) { - if (modules[asset.id]) { - // Remove dependencies that are removed and will become orphaned. - // This is necessary so that if the asset is added back again, the cache is gone, and we prevent a full page reload. - let oldDeps = modules[asset.id][1]; - for(let dep in oldDeps)if (!deps[dep] || deps[dep] !== oldDeps[dep]) { - let id = oldDeps[dep]; - let parents = getParents(module.bundle.root, id); - if (parents.length === 1) hmrDelete(module.bundle.root, id); - } - } - if (supportsSourceURL) // Global eval. We would use `new Function` here but browser - // support for source maps is better with eval. - (0, eval)(asset.output); - // $FlowFixMe - let fn = global.parcelHotUpdate[asset.id]; - modules[asset.id] = [ - fn, - deps - ]; - } - // Always traverse to the parent bundle, even if we already replaced the asset in this bundle. - // This is required in case modules are duplicated. We need to ensure all instances have the updated code. - if (bundle.parent) hmrApply(bundle.parent, asset); - } -} -function hmrDelete(bundle, id) { - let modules = bundle.modules; - if (!modules) return; - if (modules[id]) { - // Collect dependencies that will become orphaned when this module is deleted. - let deps = modules[id][1]; - let orphans = []; - for(let dep in deps){ - let parents = getParents(module.bundle.root, deps[dep]); - if (parents.length === 1) orphans.push(deps[dep]); - } - // Delete the module. This must be done before deleting dependencies in case of circular dependencies. - delete modules[id]; - delete bundle.cache[id]; - // Now delete the orphans. - orphans.forEach((id)=>{ - hmrDelete(module.bundle.root, id); - }); - } else if (bundle.parent) hmrDelete(bundle.parent, id); -} -function hmrAcceptCheck(bundle /*: ParcelRequire */ , id /*: string */ , depsByBundle /*: ?{ [string]: { [string]: string } }*/ ) { - checkedAssets = {}; - if (hmrAcceptCheckOne(bundle, id, depsByBundle)) return true; - // Traverse parents breadth first. All possible ancestries must accept the HMR update, or we'll reload. - let parents = getParents(module.bundle.root, id); - let accepted = false; - while(parents.length > 0){ - let v = parents.shift(); - let a = hmrAcceptCheckOne(v[0], v[1], null); - if (a) // If this parent accepts, stop traversing upward, but still consider siblings. - accepted = true; - else if (a !== null) { - // Otherwise, queue the parents in the next level upward. - let p = getParents(module.bundle.root, v[1]); - if (p.length === 0) { - // If there are no parents, then we've reached an entry without accepting. Reload. - accepted = false; - break; - } - parents.push(...p); - } - } - return accepted; -} -function hmrAcceptCheckOne(bundle /*: ParcelRequire */ , id /*: string */ , depsByBundle /*: ?{ [string]: { [string]: string } }*/ ) { - var modules = bundle.modules; - if (!modules) return; - if (depsByBundle && !depsByBundle[bundle.HMR_BUNDLE_ID]) { - // If we reached the root bundle without finding where the asset should go, - // there's nothing to do. Mark as "accepted" so we don't reload the page. - if (!bundle.parent) { - bundleNotFound = true; - return true; - } - return hmrAcceptCheckOne(bundle.parent, id, depsByBundle); - } - if (checkedAssets[id]) return null; - checkedAssets[id] = true; - var cached = bundle.cache[id]; - if (!cached) return true; - assetsToDispose.push([ - bundle, - id - ]); - if (cached && cached.hot && cached.hot._acceptCallbacks.length) { - assetsToAccept.push([ - bundle, - id - ]); - return true; - } - return false; -} -function hmrDisposeQueue() { - // Dispose all old assets. - for(let i = 0; i < assetsToDispose.length; i++){ - let id = assetsToDispose[i][1]; - if (!disposedAssets[id]) { - hmrDispose(assetsToDispose[i][0], id); - disposedAssets[id] = true; - } - } - assetsToDispose = []; -} -function hmrDispose(bundle /*: ParcelRequire */ , id /*: string */ ) { - var cached = bundle.cache[id]; - bundle.hotData[id] = {}; - if (cached && cached.hot) cached.hot.data = bundle.hotData[id]; - if (cached && cached.hot && cached.hot._disposeCallbacks.length) cached.hot._disposeCallbacks.forEach(function(cb) { - cb(bundle.hotData[id]); - }); - delete bundle.cache[id]; -} -function hmrAccept(bundle /*: ParcelRequire */ , id /*: string */ ) { - // Execute the module. - bundle(id); - // Run the accept callbacks in the new version of the module. - var cached = bundle.cache[id]; - if (cached && cached.hot && cached.hot._acceptCallbacks.length) { - let assetsToAlsoAccept = []; - cached.hot._acceptCallbacks.forEach(function(cb) { - let additionalAssets = cb(function() { - return getParents(module.bundle.root, id); - }); - if (Array.isArray(additionalAssets) && additionalAssets.length) assetsToAlsoAccept.push(...additionalAssets); - }); - if (assetsToAlsoAccept.length) { - let handled = assetsToAlsoAccept.every(function(a) { - return hmrAcceptCheck(a[0], a[1]); - }); - if (!handled) return fullReload(); - hmrDisposeQueue(); - } - } -} - -},{}],"1jwFz":[function(require,module,exports,__globalThis) { -var _indexTs = require("./assets/scripts/index.ts"); -var _indexScss = require("./assets/scss/index.scss"); - -},{"./assets/scripts/index.ts":"cmXY9","./assets/scss/index.scss":"6ebKA"}],"cmXY9":[function(require,module,exports,__globalThis) { -const favoritePosts = { - init () { - if (!this.component) return; - this.addEventListeners(); - }, - addEventListeners () { - this.component.addEventListener('click', this.handleClick.bind(this)); - }, - async getUserId () { - // @ts-ignore - return fetch(wpApiSettings.root + 'wp/v2/users/me', { - method: 'GET', - headers: { - // @ts-ignore - 'X-WP-Nonce': wpApiSettings.nonce - } - }).then((response)=>response.json()).then((user)=>user.id).catch((error)=>{ - console.error('Erro:', error); - return null; - }); - }, - async favoritePost () { - const userId = await this.getUserId(); - if (!userId) return; - // @ts-ignore - fetch(wpApiSettings.root + wpApiSettings.rest_namespace + '/favorite-posts', { - method: 'POST', - body: JSON.stringify({ - post_id: this.component.dataset.postId, - user_id: userId - }), - headers: { - 'Content-Type': 'application/json', - // @ts-ignore - 'X-WP-Nonce': wpApiSettings.nonce - } - }).then((response)=>response.json()).then((data)=>{ - this.component.classList.toggle('is-favorite', data.code === 'favorite_post_added'); - }).catch((error)=>{ - console.error('Erro:', error); - }); - }, - async handleClick () { - if (this.component.classList.contains('is-favorite')) await this.removeFavoritePost(); - else await this.favoritePost(); - }, - async removeFavoritePost () { - const userId = await this.getUserId(); - if (!userId) return; - // @ts-ignore - fetch(wpApiSettings.root + wpApiSettings.rest_namespace + '/favorite-posts', { - method: 'DELETE', - body: JSON.stringify({ - post_id: this.component.dataset.postId, - user_id: userId - }), - headers: { - 'Content-Type': 'application/json', - // @ts-ignore - 'X-WP-Nonce': wpApiSettings.nonce - } - }).then((response)=>response.json()).then((data)=>{ - this.component.classList.toggle('is-favorite', data.code === 'favorite_post_removed'); - }).catch((error)=>{ - console.error('Erro:', error); - }); - }, - component: document.querySelector('.favorite-post-button') -}; -favoritePosts.init(); - -},{}],"6ebKA":[function() {},{}]},["1Mq6V","1jwFz"], "1jwFz", "parcelRequire2f3a", {}) - +({init(){this.component&&this.addEventListeners()},addEventListeners(){this.component.addEventListener("click",this.handleClick.bind(this))},getUserId:async()=>fetch(wpApiSettings.root+"wp/v2/users/me",{method:"GET",headers:{"X-WP-Nonce":wpApiSettings.nonce}}).then(t=>t.json()).then(t=>t.id).catch(t=>(console.error("Erro:",t),null)),async favoritePost(){let t=await this.getUserId();t&&fetch(wpApiSettings.root+wpApiSettings.rest_namespace+"/favorite-posts",{method:"POST",body:JSON.stringify({post_id:this.component.dataset.postId,user_id:t}),headers:{"Content-Type":"application/json","X-WP-Nonce":wpApiSettings.nonce}}).then(t=>t.json()).then(t=>{this.component.classList.toggle("is-favorite","favorite_post_added"===t.code)}).catch(t=>{console.error("Erro:",t)})},async handleClick(){this.dialogLoader&&this.dialogLoader.showModal(),this.component.classList.contains("is-favorite")?await this.removeFavoritePost():await this.favoritePost(),this.dialogLoader&&this.dialogLoader.close()},async removeFavoritePost(){let t=await this.getUserId();t&&fetch(wpApiSettings.root+wpApiSettings.rest_namespace+"/favorite-posts",{method:"DELETE",body:JSON.stringify({post_id:this.component.dataset.postId,user_id:t}),headers:{"Content-Type":"application/json","X-WP-Nonce":wpApiSettings.nonce}}).then(t=>t.json()).then(t=>{this.component.classList.toggle("is-favorite","favorite_post_removed"===t.code)}).catch(t=>{console.error("Erro:",t)})},component:document.querySelector(".favorite-post-button"),dialogLoader:document.querySelector("#dialog-loader")}).init(); //# sourceMappingURL=index.js.map diff --git a/dist/index.js.map b/dist/index.js.map deleted file mode 100644 index d5243922..00000000 --- a/dist/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"mappings":"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","sources":["node_modules/@parcel/runtime-browser-hmr/lib/runtime-92f870de140ddc88.js","index.ts","assets/scripts/index.ts"],"sourcesContent":["var HMR_HOST = null;var HMR_PORT = 1234;var HMR_SERVER_PORT = 1234;var HMR_SECURE = false;var HMR_ENV_HASH = \"d6ea1d42532a7575\";var HMR_USE_SSE = false;module.bundle.HMR_BUNDLE_ID = \"78fcd0ac8e9bd240\";\"use strict\";\n\n/* global HMR_HOST, HMR_PORT, HMR_SERVER_PORT, HMR_ENV_HASH, HMR_SECURE, HMR_USE_SSE, chrome, browser, __parcel__import__, __parcel__importScripts__, ServiceWorkerGlobalScope */\n/*::\nimport type {\n HMRAsset,\n HMRMessage,\n} from '@parcel/reporter-dev-server/src/HMRServer.js';\ninterface ParcelRequire {\n (string): mixed;\n cache: {|[string]: ParcelModule|};\n hotData: {|[string]: mixed|};\n Module: any;\n parent: ?ParcelRequire;\n isParcelRequire: true;\n modules: {|[string]: [Function, {|[string]: string|}]|};\n HMR_BUNDLE_ID: string;\n root: ParcelRequire;\n}\ninterface ParcelModule {\n hot: {|\n data: mixed,\n accept(cb: (Function) => void): void,\n dispose(cb: (mixed) => void): void,\n // accept(deps: Array | string, cb: (Function) => void): void,\n // decline(): void,\n _acceptCallbacks: Array<(Function) => void>,\n _disposeCallbacks: Array<(mixed) => void>,\n |};\n}\ninterface ExtensionContext {\n runtime: {|\n reload(): void,\n getURL(url: string): string;\n getManifest(): {manifest_version: number, ...};\n |};\n}\ndeclare var module: {bundle: ParcelRequire, ...};\ndeclare var HMR_HOST: string;\ndeclare var HMR_PORT: string;\ndeclare var HMR_SERVER_PORT: string;\ndeclare var HMR_ENV_HASH: string;\ndeclare var HMR_SECURE: boolean;\ndeclare var HMR_USE_SSE: boolean;\ndeclare var chrome: ExtensionContext;\ndeclare var browser: ExtensionContext;\ndeclare var __parcel__import__: (string) => Promise;\ndeclare var __parcel__importScripts__: (string) => Promise;\ndeclare var globalThis: typeof self;\ndeclare var ServiceWorkerGlobalScope: Object;\n*/\nvar OVERLAY_ID = '__parcel__error__overlay__';\nvar OldModule = module.bundle.Module;\nfunction Module(moduleName) {\n OldModule.call(this, moduleName);\n this.hot = {\n data: module.bundle.hotData[moduleName],\n _acceptCallbacks: [],\n _disposeCallbacks: [],\n accept: function (fn) {\n this._acceptCallbacks.push(fn || function () {});\n },\n dispose: function (fn) {\n this._disposeCallbacks.push(fn);\n }\n };\n module.bundle.hotData[moduleName] = undefined;\n}\nmodule.bundle.Module = Module;\nmodule.bundle.hotData = {};\nvar checkedAssets /*: {|[string]: boolean|} */,\n disposedAssets /*: {|[string]: boolean|} */,\n assetsToDispose /*: Array<[ParcelRequire, string]> */,\n assetsToAccept /*: Array<[ParcelRequire, string]> */,\n bundleNotFound = false;\nfunction getHostname() {\n return HMR_HOST || (typeof location !== 'undefined' && location.protocol.indexOf('http') === 0 ? location.hostname : 'localhost');\n}\nfunction getPort() {\n return HMR_PORT || (typeof location !== 'undefined' ? location.port : HMR_SERVER_PORT);\n}\n\n// eslint-disable-next-line no-redeclare\nlet WebSocket = globalThis.WebSocket;\nif (!WebSocket && typeof module.bundle.root === 'function') {\n try {\n // eslint-disable-next-line no-global-assign\n WebSocket = module.bundle.root('ws');\n } catch {\n // ignore.\n }\n}\nvar hostname = getHostname();\nvar port = getPort();\nvar protocol = HMR_SECURE || typeof location !== 'undefined' && location.protocol === 'https:' && !['localhost', '127.0.0.1', '0.0.0.0'].includes(hostname) ? 'wss' : 'ws';\n\n// eslint-disable-next-line no-redeclare\nvar parent = module.bundle.parent;\nif (!parent || !parent.isParcelRequire) {\n // Web extension context\n var extCtx = typeof browser === 'undefined' ? typeof chrome === 'undefined' ? null : chrome : browser;\n\n // Safari doesn't support sourceURL in error stacks.\n // eval may also be disabled via CSP, so do a quick check.\n var supportsSourceURL = false;\n try {\n (0, eval)('throw new Error(\"test\"); //# sourceURL=test.js');\n } catch (err) {\n supportsSourceURL = err.stack.includes('test.js');\n }\n var ws;\n if (HMR_USE_SSE) {\n ws = new EventSource('/__parcel_hmr');\n } else {\n try {\n // If we're running in the dev server's node runner, listen for messages on the parent port.\n let {\n workerData,\n parentPort\n } = module.bundle.root('node:worker_threads') /*: any*/;\n if (workerData !== null && workerData !== void 0 && workerData.__parcel) {\n parentPort.on('message', async message => {\n try {\n await handleMessage(message);\n parentPort.postMessage('updated');\n } catch {\n parentPort.postMessage('restart');\n }\n });\n\n // After the bundle has finished running, notify the dev server that the HMR update is complete.\n queueMicrotask(() => parentPort.postMessage('ready'));\n }\n } catch {\n if (typeof WebSocket !== 'undefined') {\n try {\n ws = new WebSocket(protocol + '://' + hostname + (port ? ':' + port : '') + '/');\n } catch (err) {\n // Ignore cloudflare workers error.\n if (err.message && !err.message.includes('Disallowed operation called within global scope')) {\n console.error(err.message);\n }\n }\n }\n }\n }\n if (ws) {\n // $FlowFixMe\n ws.onmessage = async function (event /*: {data: string, ...} */) {\n var data /*: HMRMessage */ = JSON.parse(event.data);\n await handleMessage(data);\n };\n if (ws instanceof WebSocket) {\n ws.onerror = function (e) {\n if (e.message) {\n console.error(e.message);\n }\n };\n ws.onclose = function () {\n console.warn('[parcel] 🚨 Connection to the HMR server was lost');\n };\n }\n }\n}\nasync function handleMessage(data /*: HMRMessage */) {\n checkedAssets = {} /*: {|[string]: boolean|} */;\n disposedAssets = {} /*: {|[string]: boolean|} */;\n assetsToAccept = [];\n assetsToDispose = [];\n bundleNotFound = false;\n if (data.type === 'reload') {\n fullReload();\n } else if (data.type === 'update') {\n // Remove error overlay if there is one\n if (typeof document !== 'undefined') {\n removeErrorOverlay();\n }\n let assets = data.assets;\n\n // Handle HMR Update\n let handled = assets.every(asset => {\n return asset.type === 'css' || asset.type === 'js' && hmrAcceptCheck(module.bundle.root, asset.id, asset.depsByBundle);\n });\n\n // Dispatch a custom event in case a bundle was not found. This might mean\n // an asset on the server changed and we should reload the page. This event\n // gives the client an opportunity to refresh without losing state\n // (e.g. via React Server Components). If e.preventDefault() is not called,\n // we will trigger a full page reload.\n if (handled && bundleNotFound && assets.some(a => a.envHash !== HMR_ENV_HASH) && typeof window !== 'undefined' && typeof CustomEvent !== 'undefined') {\n handled = !window.dispatchEvent(new CustomEvent('parcelhmrreload', {\n cancelable: true\n }));\n }\n if (handled) {\n console.clear();\n\n // Dispatch custom event so other runtimes (e.g React Refresh) are aware.\n if (typeof window !== 'undefined' && typeof CustomEvent !== 'undefined') {\n window.dispatchEvent(new CustomEvent('parcelhmraccept'));\n }\n await hmrApplyUpdates(assets);\n hmrDisposeQueue();\n\n // Run accept callbacks. This will also re-execute other disposed assets in topological order.\n let processedAssets = {};\n for (let i = 0; i < assetsToAccept.length; i++) {\n let id = assetsToAccept[i][1];\n if (!processedAssets[id]) {\n hmrAccept(assetsToAccept[i][0], id);\n processedAssets[id] = true;\n }\n }\n } else fullReload();\n }\n if (data.type === 'error') {\n // Log parcel errors to console\n for (let ansiDiagnostic of data.diagnostics.ansi) {\n let stack = ansiDiagnostic.codeframe ? ansiDiagnostic.codeframe : ansiDiagnostic.stack;\n console.error('🚨 [parcel]: ' + ansiDiagnostic.message + '\\n' + stack + '\\n\\n' + ansiDiagnostic.hints.join('\\n'));\n }\n if (typeof document !== 'undefined') {\n // Render the fancy html overlay\n removeErrorOverlay();\n var overlay = createErrorOverlay(data.diagnostics.html);\n // $FlowFixMe\n document.body.appendChild(overlay);\n }\n }\n}\nfunction removeErrorOverlay() {\n var overlay = document.getElementById(OVERLAY_ID);\n if (overlay) {\n overlay.remove();\n console.log('[parcel] ✨ Error resolved');\n }\n}\nfunction createErrorOverlay(diagnostics) {\n var overlay = document.createElement('div');\n overlay.id = OVERLAY_ID;\n let errorHTML = '
';\n for (let diagnostic of diagnostics) {\n let stack = diagnostic.frames.length ? diagnostic.frames.reduce((p, frame) => {\n return `${p}\n${frame.location}\n${frame.code}`;\n }, '') : diagnostic.stack;\n errorHTML += `\n
\n
\n 🚨 ${diagnostic.message}\n
\n
${stack}
\n
\n ${diagnostic.hints.map(hint => '
💡 ' + hint + '
').join('')}\n
\n ${diagnostic.documentation ? `` : ''}\n
\n `;\n }\n errorHTML += '
';\n overlay.innerHTML = errorHTML;\n return overlay;\n}\nfunction fullReload() {\n if (typeof location !== 'undefined' && 'reload' in location) {\n location.reload();\n } else if (typeof extCtx !== 'undefined' && extCtx && extCtx.runtime && extCtx.runtime.reload) {\n extCtx.runtime.reload();\n } else {\n try {\n let {\n workerData,\n parentPort\n } = module.bundle.root('node:worker_threads') /*: any*/;\n if (workerData !== null && workerData !== void 0 && workerData.__parcel) {\n parentPort.postMessage('restart');\n }\n } catch (err) {\n console.error('[parcel] ⚠️ An HMR update was not accepted. Please restart the process.');\n }\n }\n}\nfunction getParents(bundle, id) /*: Array<[ParcelRequire, string]> */{\n var modules = bundle.modules;\n if (!modules) {\n return [];\n }\n var parents = [];\n var k, d, dep;\n for (k in modules) {\n for (d in modules[k][1]) {\n dep = modules[k][1][d];\n if (dep === id || Array.isArray(dep) && dep[dep.length - 1] === id) {\n parents.push([bundle, k]);\n }\n }\n }\n if (bundle.parent) {\n parents = parents.concat(getParents(bundle.parent, id));\n }\n return parents;\n}\nfunction updateLink(link) {\n var href = link.getAttribute('href');\n if (!href) {\n return;\n }\n var newLink = link.cloneNode();\n newLink.onload = function () {\n if (link.parentNode !== null) {\n // $FlowFixMe\n link.parentNode.removeChild(link);\n }\n };\n newLink.setAttribute('href',\n // $FlowFixMe\n href.split('?')[0] + '?' + Date.now());\n // $FlowFixMe\n link.parentNode.insertBefore(newLink, link.nextSibling);\n}\nvar cssTimeout = null;\nfunction reloadCSS() {\n if (cssTimeout || typeof document === 'undefined') {\n return;\n }\n cssTimeout = setTimeout(function () {\n var links = document.querySelectorAll('link[rel=\"stylesheet\"]');\n for (var i = 0; i < links.length; i++) {\n // $FlowFixMe[incompatible-type]\n var href /*: string */ = links[i].getAttribute('href');\n var hostname = getHostname();\n var servedFromHMRServer = hostname === 'localhost' ? new RegExp('^(https?:\\\\/\\\\/(0.0.0.0|127.0.0.1)|localhost):' + getPort()).test(href) : href.indexOf(hostname + ':' + getPort());\n var absolute = /^https?:\\/\\//i.test(href) && href.indexOf(location.origin) !== 0 && !servedFromHMRServer;\n if (!absolute) {\n updateLink(links[i]);\n }\n }\n cssTimeout = null;\n }, 50);\n}\nfunction hmrDownload(asset) {\n if (asset.type === 'js') {\n if (typeof document !== 'undefined') {\n let script = document.createElement('script');\n script.src = asset.url + '?t=' + Date.now();\n if (asset.outputFormat === 'esmodule') {\n script.type = 'module';\n }\n return new Promise((resolve, reject) => {\n var _document$head;\n script.onload = () => resolve(script);\n script.onerror = reject;\n (_document$head = document.head) === null || _document$head === void 0 || _document$head.appendChild(script);\n });\n } else if (typeof importScripts === 'function') {\n // Worker scripts\n if (asset.outputFormat === 'esmodule') {\n return __parcel__import__(asset.url + '?t=' + Date.now());\n } else {\n return new Promise((resolve, reject) => {\n try {\n __parcel__importScripts__(asset.url + '?t=' + Date.now());\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n }\n }\n }\n}\nasync function hmrApplyUpdates(assets) {\n global.parcelHotUpdate = Object.create(null);\n let scriptsToRemove;\n try {\n // If sourceURL comments aren't supported in eval, we need to load\n // the update from the dev server over HTTP so that stack traces\n // are correct in errors/logs. This is much slower than eval, so\n // we only do it if needed (currently just Safari).\n // https://bugs.webkit.org/show_bug.cgi?id=137297\n // This path is also taken if a CSP disallows eval.\n if (!supportsSourceURL) {\n let promises = assets.map(asset => {\n var _hmrDownload;\n return (_hmrDownload = hmrDownload(asset)) === null || _hmrDownload === void 0 ? void 0 : _hmrDownload.catch(err => {\n // Web extension fix\n if (extCtx && extCtx.runtime && extCtx.runtime.getManifest().manifest_version == 3 && typeof ServiceWorkerGlobalScope != 'undefined' && global instanceof ServiceWorkerGlobalScope) {\n extCtx.runtime.reload();\n return;\n }\n throw err;\n });\n });\n scriptsToRemove = await Promise.all(promises);\n }\n assets.forEach(function (asset) {\n hmrApply(module.bundle.root, asset);\n });\n } finally {\n delete global.parcelHotUpdate;\n if (scriptsToRemove) {\n scriptsToRemove.forEach(script => {\n if (script) {\n var _document$head2;\n (_document$head2 = document.head) === null || _document$head2 === void 0 || _document$head2.removeChild(script);\n }\n });\n }\n }\n}\nfunction hmrApply(bundle /*: ParcelRequire */, asset /*: HMRAsset */) {\n var modules = bundle.modules;\n if (!modules) {\n return;\n }\n if (asset.type === 'css') {\n reloadCSS();\n } else if (asset.type === 'js') {\n let deps = asset.depsByBundle[bundle.HMR_BUNDLE_ID];\n if (deps) {\n if (modules[asset.id]) {\n // Remove dependencies that are removed and will become orphaned.\n // This is necessary so that if the asset is added back again, the cache is gone, and we prevent a full page reload.\n let oldDeps = modules[asset.id][1];\n for (let dep in oldDeps) {\n if (!deps[dep] || deps[dep] !== oldDeps[dep]) {\n let id = oldDeps[dep];\n let parents = getParents(module.bundle.root, id);\n if (parents.length === 1) {\n hmrDelete(module.bundle.root, id);\n }\n }\n }\n }\n if (supportsSourceURL) {\n // Global eval. We would use `new Function` here but browser\n // support for source maps is better with eval.\n (0, eval)(asset.output);\n }\n\n // $FlowFixMe\n let fn = global.parcelHotUpdate[asset.id];\n modules[asset.id] = [fn, deps];\n }\n\n // Always traverse to the parent bundle, even if we already replaced the asset in this bundle.\n // This is required in case modules are duplicated. We need to ensure all instances have the updated code.\n if (bundle.parent) {\n hmrApply(bundle.parent, asset);\n }\n }\n}\nfunction hmrDelete(bundle, id) {\n let modules = bundle.modules;\n if (!modules) {\n return;\n }\n if (modules[id]) {\n // Collect dependencies that will become orphaned when this module is deleted.\n let deps = modules[id][1];\n let orphans = [];\n for (let dep in deps) {\n let parents = getParents(module.bundle.root, deps[dep]);\n if (parents.length === 1) {\n orphans.push(deps[dep]);\n }\n }\n\n // Delete the module. This must be done before deleting dependencies in case of circular dependencies.\n delete modules[id];\n delete bundle.cache[id];\n\n // Now delete the orphans.\n orphans.forEach(id => {\n hmrDelete(module.bundle.root, id);\n });\n } else if (bundle.parent) {\n hmrDelete(bundle.parent, id);\n }\n}\nfunction hmrAcceptCheck(bundle /*: ParcelRequire */, id /*: string */, depsByBundle /*: ?{ [string]: { [string]: string } }*/) {\n checkedAssets = {};\n if (hmrAcceptCheckOne(bundle, id, depsByBundle)) {\n return true;\n }\n\n // Traverse parents breadth first. All possible ancestries must accept the HMR update, or we'll reload.\n let parents = getParents(module.bundle.root, id);\n let accepted = false;\n while (parents.length > 0) {\n let v = parents.shift();\n let a = hmrAcceptCheckOne(v[0], v[1], null);\n if (a) {\n // If this parent accepts, stop traversing upward, but still consider siblings.\n accepted = true;\n } else if (a !== null) {\n // Otherwise, queue the parents in the next level upward.\n let p = getParents(module.bundle.root, v[1]);\n if (p.length === 0) {\n // If there are no parents, then we've reached an entry without accepting. Reload.\n accepted = false;\n break;\n }\n parents.push(...p);\n }\n }\n return accepted;\n}\nfunction hmrAcceptCheckOne(bundle /*: ParcelRequire */, id /*: string */, depsByBundle /*: ?{ [string]: { [string]: string } }*/) {\n var modules = bundle.modules;\n if (!modules) {\n return;\n }\n if (depsByBundle && !depsByBundle[bundle.HMR_BUNDLE_ID]) {\n // If we reached the root bundle without finding where the asset should go,\n // there's nothing to do. Mark as \"accepted\" so we don't reload the page.\n if (!bundle.parent) {\n bundleNotFound = true;\n return true;\n }\n return hmrAcceptCheckOne(bundle.parent, id, depsByBundle);\n }\n if (checkedAssets[id]) {\n return null;\n }\n checkedAssets[id] = true;\n var cached = bundle.cache[id];\n if (!cached) {\n return true;\n }\n assetsToDispose.push([bundle, id]);\n if (cached && cached.hot && cached.hot._acceptCallbacks.length) {\n assetsToAccept.push([bundle, id]);\n return true;\n }\n return false;\n}\nfunction hmrDisposeQueue() {\n // Dispose all old assets.\n for (let i = 0; i < assetsToDispose.length; i++) {\n let id = assetsToDispose[i][1];\n if (!disposedAssets[id]) {\n hmrDispose(assetsToDispose[i][0], id);\n disposedAssets[id] = true;\n }\n }\n assetsToDispose = [];\n}\nfunction hmrDispose(bundle /*: ParcelRequire */, id /*: string */) {\n var cached = bundle.cache[id];\n bundle.hotData[id] = {};\n if (cached && cached.hot) {\n cached.hot.data = bundle.hotData[id];\n }\n if (cached && cached.hot && cached.hot._disposeCallbacks.length) {\n cached.hot._disposeCallbacks.forEach(function (cb) {\n cb(bundle.hotData[id]);\n });\n }\n delete bundle.cache[id];\n}\nfunction hmrAccept(bundle /*: ParcelRequire */, id /*: string */) {\n // Execute the module.\n bundle(id);\n\n // Run the accept callbacks in the new version of the module.\n var cached = bundle.cache[id];\n if (cached && cached.hot && cached.hot._acceptCallbacks.length) {\n let assetsToAlsoAccept = [];\n cached.hot._acceptCallbacks.forEach(function (cb) {\n let additionalAssets = cb(function () {\n return getParents(module.bundle.root, id);\n });\n if (Array.isArray(additionalAssets) && additionalAssets.length) {\n assetsToAlsoAccept.push(...additionalAssets);\n }\n });\n if (assetsToAlsoAccept.length) {\n let handled = assetsToAlsoAccept.every(function (a) {\n return hmrAcceptCheck(a[0], a[1]);\n });\n if (!handled) {\n return fullReload();\n }\n hmrDisposeQueue();\n }\n }\n}","import './assets/scripts/index.ts';\nimport './assets/scss/index.scss';\n","const favoritePosts = {\n init() {\n if (!this.component) return;\n\n this.addEventListeners();\n },\n\n addEventListeners() {\n this.component.addEventListener('click', this.handleClick.bind(this));\n },\n\n async getUserId() {\n // @ts-ignore\n return fetch(wpApiSettings.root + 'wp/v2/users/me', {\n method: 'GET',\n headers: {\n // @ts-ignore\n 'X-WP-Nonce': wpApiSettings.nonce\n }\n })\n .then(response => response.json())\n .then(user => user.id)\n .catch(error => {\n console.error('Erro:', error);\n return null;\n });\n },\n\n async favoritePost() {\n const userId = await this.getUserId();\n if (!userId) return;\n\n // @ts-ignore\n fetch(wpApiSettings.root + wpApiSettings.rest_namespace + '/favorite-posts', {\n method: 'POST',\n body: JSON.stringify({\n post_id: this.component.dataset.postId,\n user_id: userId\n }),\n headers: {\n 'Content-Type': 'application/json',\n // @ts-ignore\n 'X-WP-Nonce': wpApiSettings.nonce\n }\n })\n .then(response => response.json())\n .then(data => {\n this.component.classList.toggle('is-favorite', data.code === 'favorite_post_added');\n })\n .catch(error => {\n console.error('Erro:', error);\n });\n },\n\n async handleClick() {\n if (this.component.classList.contains('is-favorite')) {\n await this.removeFavoritePost();\n } else {\n await this.favoritePost();\n }\n },\n\n async removeFavoritePost() {\n const userId = await this.getUserId();\n if (!userId) return;\n\n // @ts-ignore\n fetch(wpApiSettings.root + wpApiSettings.rest_namespace + '/favorite-posts', {\n method: 'DELETE',\n body: JSON.stringify({\n post_id: this.component.dataset.postId,\n user_id: userId\n }),\n headers: {\n 'Content-Type': 'application/json',\n // @ts-ignore\n 'X-WP-Nonce': wpApiSettings.nonce\n }\n })\n .then(response => response.json())\n .then(data => {\n this.component.classList.toggle('is-favorite', data.code === 'favorite_post_removed');\n })\n .catch(error => {\n console.error('Erro:', error);\n });\n },\n component: document.querySelector('.favorite-post-button'),\n}\n\nfavoritePosts.init();\n"],"names":[],"version":3,"file":"index.js.map","sourceRoot":"../"} \ No newline at end of file diff --git a/wordpress-back-end-challenge.php b/wordpress-back-end-challenge.php index 7f527402..d3f93d09 100644 --- a/wordpress-back-end-challenge.php +++ b/wordpress-back-end-challenge.php @@ -30,6 +30,11 @@ public function __construct() { add_filter( 'the_content', [$this, 'addFavoritePostIcon'] ); add_action( 'wp_enqueue_scripts', [$this, 'enqueueScripts'] ); + add_action( 'wp_footer', [$this, 'addDialogLoader'] ); + } + + public function addDialogLoader() { + echo '
'; } public function addFavoritePostIcon( $content ) From 6e9eaa8dec5b238a2e3188e93085517387b6154d Mon Sep 17 00:00:00 2001 From: Kayo Tusthler Date: Wed, 25 Mar 2026 19:02:50 -0300 Subject: [PATCH 4/4] feat: enhance favorite post functionality with Toastify notifications and improve database schema --- .gitignore | 4 +- assets/scripts/index.ts | 57 +- dist/index.css | 87 ++- dist/index.js | 1120 +++++++++++++++++++++++++++++- package.json | 3 + src/dbHandler.php | 22 +- src/restHandler.php | 88 ++- wordpress-back-end-challenge.php | 26 +- 8 files changed, 1337 insertions(+), 70 deletions(-) diff --git a/.gitignore b/.gitignore index 85badb3b..5f32c576 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ node_modules/ *.lock -.parcel-cache/ \ No newline at end of file +.parcel-cache/ +*.css.map +*.js.map \ No newline at end of file diff --git a/assets/scripts/index.ts b/assets/scripts/index.ts index 828e2f34..bb9a5d26 100644 --- a/assets/scripts/index.ts +++ b/assets/scripts/index.ts @@ -1,3 +1,5 @@ +import Toastify from 'toastify-js'; + const favoritePosts = { init() { if (!this.component) return; @@ -9,33 +11,12 @@ const favoritePosts = { this.component.addEventListener('click', this.handleClick.bind(this)); }, - async getUserId() { - // @ts-ignore - return fetch(wpApiSettings.root + 'wp/v2/users/me', { - method: 'GET', - headers: { - // @ts-ignore - 'X-WP-Nonce': wpApiSettings.nonce - } - }) - .then(response => response.json()) - .then(user => user.id) - .catch(error => { - console.error('Erro:', error); - return null; - }); - }, - async favoritePost() { - const userId = await this.getUserId(); - if (!userId) return; - // @ts-ignore fetch(wpApiSettings.root + wpApiSettings.rest_namespace + '/favorite-posts', { method: 'POST', body: JSON.stringify({ - post_id: this.component.dataset.postId, - user_id: userId + post_id: this.component.dataset.postId }), headers: { 'Content-Type': 'application/json', @@ -45,10 +26,18 @@ const favoritePosts = { }) .then(response => response.json()) .then(data => { - this.component.classList.toggle('is-favorite', data.code === 'favorite_post_added'); + Toastify({ text: data.message }).showToast(); + + this.component.classList.add('is-favorite'); }) .catch(error => { - console.error('Erro:', error); + Toastify({ + text: 'Failed to add favorite post', + className: 'error', + style: { + background: 'linear-gradient(to right, #ff0000, #ff4747)', + } + }).showToast(); }); }, @@ -65,15 +54,11 @@ const favoritePosts = { }, async removeFavoritePost() { - const userId = await this.getUserId(); - if (!userId) return; - // @ts-ignore fetch(wpApiSettings.root + wpApiSettings.rest_namespace + '/favorite-posts', { method: 'DELETE', body: JSON.stringify({ - post_id: this.component.dataset.postId, - user_id: userId + post_id: this.component.dataset.postId }), headers: { 'Content-Type': 'application/json', @@ -83,14 +68,24 @@ const favoritePosts = { }) .then(response => response.json()) .then(data => { - this.component.classList.toggle('is-favorite', data.code === 'favorite_post_removed'); + Toastify({ text: data.message }).showToast(); + + this.component.classList.remove('is-favorite'); }) .catch(error => { - console.error('Erro:', error); + Toastify({ + text: 'Failed to remove favorite post', + className: 'error', + style: { + background: 'linear-gradient(to right, #ff0000, #ff4747)', + } + }).showToast(); }); }, + component: document.querySelector('.favorite-post-button'), dialogLoader: document.querySelector('#dialog-loader'), + favoritePostsPopover: document.querySelector('#favorite-posts-popover'), } favoritePosts.init(); diff --git a/dist/index.css b/dist/index.css index 766f793f..39c92818 100644 --- a/dist/index.css +++ b/dist/index.css @@ -1,2 +1,87 @@ -.loader{aspect-ratio:1;color:#dc1818;background-color:#0000;background-image:radial-gradient(circle at 60% 65%,currentColor 62%,#0000 65%),radial-gradient(circle at 40% 65%,currentColor 62%,#0000 65%),linear-gradient(to bottom left,currentColor 42%,#0000 43%),linear-gradient(to bottom right,currentColor 42%,#0000 43%);background-position:0 0,100% 0,0 100%,100% 100%;background-repeat:no-repeat;background-size:50% 50%;background-attachment:scroll,scroll,scroll,scroll;background-origin:padding-box,padding-box,padding-box,padding-box;background-clip:border-box,border-box,border-box,border-box;width:50px;position:relative}.loader:after{content:"";background:inherit;opacity:.4;animation:1s infinite l3;position:absolute;inset:0}@keyframes l3{to{opacity:0;transform:scale(1.8)}}.favorite-post-button{cursor:pointer;opacity:.5;background:0 0;border:none;outline:none;padding:0;transition:all .3s ease-in-out;display:block}.favorite-post-button:hover,.favorite-post-button.is-favorite{opacity:1;transform:scale(2)}.favorite-post-button img{pointer-events:none;height:32px}#dialog-loader{opacity:0;transition:opacity .7s ease-out, transform .7s ease-out, overlay .7s ease-out allow-discrete, display .7s ease-out allow-discrete;background-color:#0000;border:none;padding:150px;transform:scaleY(0)}#dialog-loader:open{opacity:1;transform:scaleY(1)}@starting-style{#dialog-loader:open{opacity:0;transform:scaleY(0)}}#dialog-loader::backdrop{transition:background-color .7s ease-out allow-discrete;background-color:#fff0}#dialog-loader:open::backdrop{backdrop-filter:blur(10px);background-color:#ffffff80}#dialog-loader .loader{width:96px} +.loader { + aspect-ratio: 1; + color: #dc1818; + background-color: #0000; + background-image: radial-gradient(circle at 60% 65%, currentColor 62%, #0000 65%), radial-gradient(circle at 40% 65%, currentColor 62%, #0000 65%), linear-gradient(to bottom left, currentColor 42%, #0000 43%), linear-gradient(to bottom right, currentColor 42%, #0000 43%); + background-position: 0 0, 100% 0, 0 100%, 100% 100%; + background-repeat: no-repeat; + background-size: 50% 50%; + background-attachment: scroll, scroll, scroll, scroll; + background-origin: padding-box, padding-box, padding-box, padding-box; + background-clip: border-box, border-box, border-box, border-box; + width: 50px; + position: relative; +} + +.loader:after { + content: ""; + background: inherit; + opacity: .4; + animation: 1s infinite l3; + position: absolute; + inset: 0; +} + +@keyframes l3 { + to { + opacity: 0; + transform: scale(1.8); + } +} + +.favorite-post-button { + cursor: pointer; + opacity: .5; + background: none; + border: none; + outline: none; + padding: 0; + transition: all .3s ease-in-out; + display: block; +} + +.favorite-post-button:hover, .favorite-post-button.is-favorite { + opacity: 1; + transform: scale(2); +} + +.favorite-post-button img { + pointer-events: none; + height: 32px; +} + +#dialog-loader { + opacity: 0; + transition: opacity .7s ease-out, transform .7s ease-out, overlay .7s ease-out allow-discrete, display .7s ease-out allow-discrete; + background-color: #0000; + border: none; + padding: 150px; + transform: scaleY(0); +} + +#dialog-loader:open { + opacity: 1; + transform: scaleY(1); +} + +@starting-style { + #dialog-loader:open { + opacity: 0; + transform: scaleY(0); + } +} + +#dialog-loader::backdrop { + transition: background-color .7s ease-out allow-discrete; + background-color: #fff0; +} + +#dialog-loader:open::backdrop { + backdrop-filter: blur(10px); + background-color: #ffffff80; +} + +#dialog-loader .loader { + width: 96px; +} /*# sourceMappingURL=index.css.map */ diff --git a/dist/index.js b/dist/index.js index 854e0446..62b86687 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,2 +1,1120 @@ -({init(){this.component&&this.addEventListeners()},addEventListeners(){this.component.addEventListener("click",this.handleClick.bind(this))},getUserId:async()=>fetch(wpApiSettings.root+"wp/v2/users/me",{method:"GET",headers:{"X-WP-Nonce":wpApiSettings.nonce}}).then(t=>t.json()).then(t=>t.id).catch(t=>(console.error("Erro:",t),null)),async favoritePost(){let t=await this.getUserId();t&&fetch(wpApiSettings.root+wpApiSettings.rest_namespace+"/favorite-posts",{method:"POST",body:JSON.stringify({post_id:this.component.dataset.postId,user_id:t}),headers:{"Content-Type":"application/json","X-WP-Nonce":wpApiSettings.nonce}}).then(t=>t.json()).then(t=>{this.component.classList.toggle("is-favorite","favorite_post_added"===t.code)}).catch(t=>{console.error("Erro:",t)})},async handleClick(){this.dialogLoader&&this.dialogLoader.showModal(),this.component.classList.contains("is-favorite")?await this.removeFavoritePost():await this.favoritePost(),this.dialogLoader&&this.dialogLoader.close()},async removeFavoritePost(){let t=await this.getUserId();t&&fetch(wpApiSettings.root+wpApiSettings.rest_namespace+"/favorite-posts",{method:"DELETE",body:JSON.stringify({post_id:this.component.dataset.postId,user_id:t}),headers:{"Content-Type":"application/json","X-WP-Nonce":wpApiSettings.nonce}}).then(t=>t.json()).then(t=>{this.component.classList.toggle("is-favorite","favorite_post_removed"===t.code)}).catch(t=>{console.error("Erro:",t)})},component:document.querySelector(".favorite-post-button"),dialogLoader:document.querySelector("#dialog-loader")}).init(); +// modules are defined as an array +// [ module function, map of requires ] +// +// map of requires is short require name -> numeric require +// +// anything defined in a previous bundle is accessed via the +// orig method which is the require for previous bundles + +(function ( + modules, + entry, + mainEntry, + parcelRequireName, + externals, + distDir, + publicUrl, + devServer +) { + /* eslint-disable no-undef */ + var globalObject = + typeof globalThis !== 'undefined' + ? globalThis + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : typeof global !== 'undefined' + ? global + : {}; + /* eslint-enable no-undef */ + + // Save the require from previous bundle to this closure if any + var previousRequire = + typeof globalObject[parcelRequireName] === 'function' && + globalObject[parcelRequireName]; + + var importMap = previousRequire.i || {}; + var cache = previousRequire.cache || {}; + // Do not use `require` to prevent Webpack from trying to bundle this call + var nodeRequire = + typeof module !== 'undefined' && + typeof module.require === 'function' && + module.require.bind(module); + + function newRequire(name, jumped) { + if (!cache[name]) { + if (!modules[name]) { + if (externals[name]) { + return externals[name]; + } + // if we cannot find the module within our internal map or + // cache jump to the current global require ie. the last bundle + // that was added to the page. + var currentRequire = + typeof globalObject[parcelRequireName] === 'function' && + globalObject[parcelRequireName]; + if (!jumped && currentRequire) { + return currentRequire(name, true); + } + + // If there are other bundles on this page the require from the + // previous one is saved to 'previousRequire'. Repeat this as + // many times as there are bundles until the module is found or + // we exhaust the require chain. + if (previousRequire) { + return previousRequire(name, true); + } + + // Try the node require function if it exists. + if (nodeRequire && typeof name === 'string') { + return nodeRequire(name); + } + + var err = new Error("Cannot find module '" + name + "'"); + err.code = 'MODULE_NOT_FOUND'; + throw err; + } + + localRequire.resolve = resolve; + localRequire.cache = {}; + + var module = (cache[name] = new newRequire.Module(name)); + + modules[name][0].call( + module.exports, + localRequire, + module, + module.exports, + globalObject + ); + } + + return cache[name].exports; + + function localRequire(x) { + var res = localRequire.resolve(x); + if (res === false) { + return {}; + } + // Synthesize a module to follow re-exports. + if (Array.isArray(res)) { + var m = {__esModule: true}; + res.forEach(function (v) { + var key = v[0]; + var id = v[1]; + var exp = v[2] || v[0]; + var x = newRequire(id); + if (key === '*') { + Object.keys(x).forEach(function (key) { + if ( + key === 'default' || + key === '__esModule' || + Object.prototype.hasOwnProperty.call(m, key) + ) { + return; + } + + Object.defineProperty(m, key, { + enumerable: true, + get: function () { + return x[key]; + }, + }); + }); + } else if (exp === '*') { + Object.defineProperty(m, key, { + enumerable: true, + value: x, + }); + } else { + Object.defineProperty(m, key, { + enumerable: true, + get: function () { + if (exp === 'default') { + return x.__esModule ? x.default : x; + } + return x[exp]; + }, + }); + } + }); + return m; + } + return newRequire(res); + } + + function resolve(x) { + var id = modules[name][1][x]; + return id != null ? id : x; + } + } + + function Module(moduleName) { + this.id = moduleName; + this.bundle = newRequire; + this.require = nodeRequire; + this.exports = {}; + } + + newRequire.isParcelRequire = true; + newRequire.Module = Module; + newRequire.modules = modules; + newRequire.cache = cache; + newRequire.parent = previousRequire; + newRequire.distDir = distDir; + newRequire.publicUrl = publicUrl; + newRequire.devServer = devServer; + newRequire.i = importMap; + newRequire.register = function (id, exports) { + modules[id] = [ + function (require, module) { + module.exports = exports; + }, + {}, + ]; + }; + + // Only insert newRequire.load when it is actually used. + // The code in this file is linted against ES5, so dynamic import is not allowed. + // INSERT_LOAD_HERE + + Object.defineProperty(newRequire, 'root', { + get: function () { + return globalObject[parcelRequireName]; + }, + }); + + globalObject[parcelRequireName] = newRequire; + + for (var i = 0; i < entry.length; i++) { + newRequire(entry[i]); + } + + if (mainEntry) { + // Expose entry point to Node, AMD or browser globals + // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js + var mainExports = newRequire(mainEntry); + + // CommonJS + if (typeof exports === 'object' && typeof module !== 'undefined') { + module.exports = mainExports; + + // RequireJS + } else if (typeof define === 'function' && define.amd) { + define(function () { + return mainExports; + }); + } + } +})({"1Mq6V":[function(require,module,exports,__globalThis) { +var global = arguments[3]; +var HMR_HOST = null; +var HMR_PORT = 1234; +var HMR_SERVER_PORT = 1234; +var HMR_SECURE = false; +var HMR_ENV_HASH = "d6ea1d42532a7575"; +var HMR_USE_SSE = false; +module.bundle.HMR_BUNDLE_ID = "78fcd0ac8e9bd240"; +"use strict"; +/* global HMR_HOST, HMR_PORT, HMR_SERVER_PORT, HMR_ENV_HASH, HMR_SECURE, HMR_USE_SSE, chrome, browser, __parcel__import__, __parcel__importScripts__, ServiceWorkerGlobalScope */ /*:: +import type { + HMRAsset, + HMRMessage, +} from '@parcel/reporter-dev-server/src/HMRServer.js'; +interface ParcelRequire { + (string): mixed; + cache: {|[string]: ParcelModule|}; + hotData: {|[string]: mixed|}; + Module: any; + parent: ?ParcelRequire; + isParcelRequire: true; + modules: {|[string]: [Function, {|[string]: string|}]|}; + HMR_BUNDLE_ID: string; + root: ParcelRequire; +} +interface ParcelModule { + hot: {| + data: mixed, + accept(cb: (Function) => void): void, + dispose(cb: (mixed) => void): void, + // accept(deps: Array | string, cb: (Function) => void): void, + // decline(): void, + _acceptCallbacks: Array<(Function) => void>, + _disposeCallbacks: Array<(mixed) => void>, + |}; +} +interface ExtensionContext { + runtime: {| + reload(): void, + getURL(url: string): string; + getManifest(): {manifest_version: number, ...}; + |}; +} +declare var module: {bundle: ParcelRequire, ...}; +declare var HMR_HOST: string; +declare var HMR_PORT: string; +declare var HMR_SERVER_PORT: string; +declare var HMR_ENV_HASH: string; +declare var HMR_SECURE: boolean; +declare var HMR_USE_SSE: boolean; +declare var chrome: ExtensionContext; +declare var browser: ExtensionContext; +declare var __parcel__import__: (string) => Promise; +declare var __parcel__importScripts__: (string) => Promise; +declare var globalThis: typeof self; +declare var ServiceWorkerGlobalScope: Object; +*/ var OVERLAY_ID = '__parcel__error__overlay__'; +var OldModule = module.bundle.Module; +function Module(moduleName) { + OldModule.call(this, moduleName); + this.hot = { + data: module.bundle.hotData[moduleName], + _acceptCallbacks: [], + _disposeCallbacks: [], + accept: function(fn) { + this._acceptCallbacks.push(fn || function() {}); + }, + dispose: function(fn) { + this._disposeCallbacks.push(fn); + } + }; + module.bundle.hotData[moduleName] = undefined; +} +module.bundle.Module = Module; +module.bundle.hotData = {}; +var checkedAssets /*: {|[string]: boolean|} */ , disposedAssets /*: {|[string]: boolean|} */ , assetsToDispose /*: Array<[ParcelRequire, string]> */ , assetsToAccept /*: Array<[ParcelRequire, string]> */ , bundleNotFound = false; +function getHostname() { + return HMR_HOST || (typeof location !== 'undefined' && location.protocol.indexOf('http') === 0 ? location.hostname : 'localhost'); +} +function getPort() { + return HMR_PORT || (typeof location !== 'undefined' ? location.port : HMR_SERVER_PORT); +} +// eslint-disable-next-line no-redeclare +let WebSocket = globalThis.WebSocket; +if (!WebSocket && typeof module.bundle.root === 'function') try { + // eslint-disable-next-line no-global-assign + WebSocket = module.bundle.root('ws'); +} catch { +// ignore. +} +var hostname = getHostname(); +var port = getPort(); +var protocol = HMR_SECURE || typeof location !== 'undefined' && location.protocol === 'https:' && ![ + 'localhost', + '127.0.0.1', + '0.0.0.0' +].includes(hostname) ? 'wss' : 'ws'; +// eslint-disable-next-line no-redeclare +var parent = module.bundle.parent; +if (!parent || !parent.isParcelRequire) { + // Web extension context + var extCtx = typeof browser === 'undefined' ? typeof chrome === 'undefined' ? null : chrome : browser; + // Safari doesn't support sourceURL in error stacks. + // eval may also be disabled via CSP, so do a quick check. + var supportsSourceURL = false; + try { + (0, eval)('throw new Error("test"); //# sourceURL=test.js'); + } catch (err) { + supportsSourceURL = err.stack.includes('test.js'); + } + var ws; + if (HMR_USE_SSE) ws = new EventSource('/__parcel_hmr'); + else try { + // If we're running in the dev server's node runner, listen for messages on the parent port. + let { workerData, parentPort } = module.bundle.root('node:worker_threads') /*: any*/ ; + if (workerData !== null && workerData !== void 0 && workerData.__parcel) { + parentPort.on('message', async (message)=>{ + try { + await handleMessage(message); + parentPort.postMessage('updated'); + } catch { + parentPort.postMessage('restart'); + } + }); + // After the bundle has finished running, notify the dev server that the HMR update is complete. + queueMicrotask(()=>parentPort.postMessage('ready')); + } + } catch { + if (typeof WebSocket !== 'undefined') try { + ws = new WebSocket(protocol + '://' + hostname + (port ? ':' + port : '') + '/'); + } catch (err) { + // Ignore cloudflare workers error. + if (err.message && !err.message.includes('Disallowed operation called within global scope')) console.error(err.message); + } + } + if (ws) { + // $FlowFixMe + ws.onmessage = async function(event /*: {data: string, ...} */ ) { + var data /*: HMRMessage */ = JSON.parse(event.data); + await handleMessage(data); + }; + if (ws instanceof WebSocket) { + ws.onerror = function(e) { + if (e.message) console.error(e.message); + }; + ws.onclose = function() { + console.warn("[parcel] \uD83D\uDEA8 Connection to the HMR server was lost"); + }; + } + } +} +async function handleMessage(data /*: HMRMessage */ ) { + checkedAssets = {} /*: {|[string]: boolean|} */ ; + disposedAssets = {} /*: {|[string]: boolean|} */ ; + assetsToAccept = []; + assetsToDispose = []; + bundleNotFound = false; + if (data.type === 'reload') fullReload(); + else if (data.type === 'update') { + // Remove error overlay if there is one + if (typeof document !== 'undefined') removeErrorOverlay(); + let assets = data.assets; + // Handle HMR Update + let handled = assets.every((asset)=>{ + return asset.type === 'css' || asset.type === 'js' && hmrAcceptCheck(module.bundle.root, asset.id, asset.depsByBundle); + }); + // Dispatch a custom event in case a bundle was not found. This might mean + // an asset on the server changed and we should reload the page. This event + // gives the client an opportunity to refresh without losing state + // (e.g. via React Server Components). If e.preventDefault() is not called, + // we will trigger a full page reload. + if (handled && bundleNotFound && assets.some((a)=>a.envHash !== HMR_ENV_HASH) && typeof window !== 'undefined' && typeof CustomEvent !== 'undefined') handled = !window.dispatchEvent(new CustomEvent('parcelhmrreload', { + cancelable: true + })); + if (handled) { + console.clear(); + // Dispatch custom event so other runtimes (e.g React Refresh) are aware. + if (typeof window !== 'undefined' && typeof CustomEvent !== 'undefined') window.dispatchEvent(new CustomEvent('parcelhmraccept')); + await hmrApplyUpdates(assets); + hmrDisposeQueue(); + // Run accept callbacks. This will also re-execute other disposed assets in topological order. + let processedAssets = {}; + for(let i = 0; i < assetsToAccept.length; i++){ + let id = assetsToAccept[i][1]; + if (!processedAssets[id]) { + hmrAccept(assetsToAccept[i][0], id); + processedAssets[id] = true; + } + } + } else fullReload(); + } + if (data.type === 'error') { + // Log parcel errors to console + for (let ansiDiagnostic of data.diagnostics.ansi){ + let stack = ansiDiagnostic.codeframe ? ansiDiagnostic.codeframe : ansiDiagnostic.stack; + console.error("\uD83D\uDEA8 [parcel]: " + ansiDiagnostic.message + '\n' + stack + '\n\n' + ansiDiagnostic.hints.join('\n')); + } + if (typeof document !== 'undefined') { + // Render the fancy html overlay + removeErrorOverlay(); + var overlay = createErrorOverlay(data.diagnostics.html); + // $FlowFixMe + document.body.appendChild(overlay); + } + } +} +function removeErrorOverlay() { + var overlay = document.getElementById(OVERLAY_ID); + if (overlay) { + overlay.remove(); + console.log("[parcel] \u2728 Error resolved"); + } +} +function createErrorOverlay(diagnostics) { + var overlay = document.createElement('div'); + overlay.id = OVERLAY_ID; + let errorHTML = '
'; + for (let diagnostic of diagnostics){ + let stack = diagnostic.frames.length ? diagnostic.frames.reduce((p, frame)=>{ + return `${p} +${frame.location} +${frame.code}`; + }, '') : diagnostic.stack; + errorHTML += ` +
+
+ \u{1F6A8} ${diagnostic.message} +
+
${stack}
+
+ ${diagnostic.hints.map((hint)=>"
\uD83D\uDCA1 " + hint + '
').join('')} +
+ ${diagnostic.documentation ? `
\u{1F4DD} Learn more
` : ''} +
+ `; + } + errorHTML += '
'; + overlay.innerHTML = errorHTML; + return overlay; +} +function fullReload() { + if (typeof location !== 'undefined' && 'reload' in location) location.reload(); + else if (typeof extCtx !== 'undefined' && extCtx && extCtx.runtime && extCtx.runtime.reload) extCtx.runtime.reload(); + else try { + let { workerData, parentPort } = module.bundle.root('node:worker_threads') /*: any*/ ; + if (workerData !== null && workerData !== void 0 && workerData.__parcel) parentPort.postMessage('restart'); + } catch (err) { + console.error("[parcel] \u26A0\uFE0F An HMR update was not accepted. Please restart the process."); + } +} +function getParents(bundle, id) /*: Array<[ParcelRequire, string]> */ { + var modules = bundle.modules; + if (!modules) return []; + var parents = []; + var k, d, dep; + for(k in modules)for(d in modules[k][1]){ + dep = modules[k][1][d]; + if (dep === id || Array.isArray(dep) && dep[dep.length - 1] === id) parents.push([ + bundle, + k + ]); + } + if (bundle.parent) parents = parents.concat(getParents(bundle.parent, id)); + return parents; +} +function updateLink(link) { + var href = link.getAttribute('href'); + if (!href) return; + var newLink = link.cloneNode(); + newLink.onload = function() { + if (link.parentNode !== null) // $FlowFixMe + link.parentNode.removeChild(link); + }; + newLink.setAttribute('href', // $FlowFixMe + href.split('?')[0] + '?' + Date.now()); + // $FlowFixMe + link.parentNode.insertBefore(newLink, link.nextSibling); +} +var cssTimeout = null; +function reloadCSS() { + if (cssTimeout || typeof document === 'undefined') return; + cssTimeout = setTimeout(function() { + var links = document.querySelectorAll('link[rel="stylesheet"]'); + for(var i = 0; i < links.length; i++){ + // $FlowFixMe[incompatible-type] + var href /*: string */ = links[i].getAttribute('href'); + var hostname = getHostname(); + var servedFromHMRServer = hostname === 'localhost' ? new RegExp('^(https?:\\/\\/(0.0.0.0|127.0.0.1)|localhost):' + getPort()).test(href) : href.indexOf(hostname + ':' + getPort()); + var absolute = /^https?:\/\//i.test(href) && href.indexOf(location.origin) !== 0 && !servedFromHMRServer; + if (!absolute) updateLink(links[i]); + } + cssTimeout = null; + }, 50); +} +function hmrDownload(asset) { + if (asset.type === 'js') { + if (typeof document !== 'undefined') { + let script = document.createElement('script'); + script.src = asset.url + '?t=' + Date.now(); + if (asset.outputFormat === 'esmodule') script.type = 'module'; + return new Promise((resolve, reject)=>{ + var _document$head; + script.onload = ()=>resolve(script); + script.onerror = reject; + (_document$head = document.head) === null || _document$head === void 0 || _document$head.appendChild(script); + }); + } else if (typeof importScripts === 'function') { + // Worker scripts + if (asset.outputFormat === 'esmodule') return import(asset.url + '?t=' + Date.now()); + else return new Promise((resolve, reject)=>{ + try { + importScripts(asset.url + '?t=' + Date.now()); + resolve(); + } catch (err) { + reject(err); + } + }); + } + } +} +async function hmrApplyUpdates(assets) { + global.parcelHotUpdate = Object.create(null); + let scriptsToRemove; + try { + // If sourceURL comments aren't supported in eval, we need to load + // the update from the dev server over HTTP so that stack traces + // are correct in errors/logs. This is much slower than eval, so + // we only do it if needed (currently just Safari). + // https://bugs.webkit.org/show_bug.cgi?id=137297 + // This path is also taken if a CSP disallows eval. + if (!supportsSourceURL) { + let promises = assets.map((asset)=>{ + var _hmrDownload; + return (_hmrDownload = hmrDownload(asset)) === null || _hmrDownload === void 0 ? void 0 : _hmrDownload.catch((err)=>{ + // Web extension fix + if (extCtx && extCtx.runtime && extCtx.runtime.getManifest().manifest_version == 3 && typeof ServiceWorkerGlobalScope != 'undefined' && global instanceof ServiceWorkerGlobalScope) { + extCtx.runtime.reload(); + return; + } + throw err; + }); + }); + scriptsToRemove = await Promise.all(promises); + } + assets.forEach(function(asset) { + hmrApply(module.bundle.root, asset); + }); + } finally{ + delete global.parcelHotUpdate; + if (scriptsToRemove) scriptsToRemove.forEach((script)=>{ + if (script) { + var _document$head2; + (_document$head2 = document.head) === null || _document$head2 === void 0 || _document$head2.removeChild(script); + } + }); + } +} +function hmrApply(bundle /*: ParcelRequire */ , asset /*: HMRAsset */ ) { + var modules = bundle.modules; + if (!modules) return; + if (asset.type === 'css') reloadCSS(); + else if (asset.type === 'js') { + let deps = asset.depsByBundle[bundle.HMR_BUNDLE_ID]; + if (deps) { + if (modules[asset.id]) { + // Remove dependencies that are removed and will become orphaned. + // This is necessary so that if the asset is added back again, the cache is gone, and we prevent a full page reload. + let oldDeps = modules[asset.id][1]; + for(let dep in oldDeps)if (!deps[dep] || deps[dep] !== oldDeps[dep]) { + let id = oldDeps[dep]; + let parents = getParents(module.bundle.root, id); + if (parents.length === 1) hmrDelete(module.bundle.root, id); + } + } + if (supportsSourceURL) // Global eval. We would use `new Function` here but browser + // support for source maps is better with eval. + (0, eval)(asset.output); + // $FlowFixMe + let fn = global.parcelHotUpdate[asset.id]; + modules[asset.id] = [ + fn, + deps + ]; + } + // Always traverse to the parent bundle, even if we already replaced the asset in this bundle. + // This is required in case modules are duplicated. We need to ensure all instances have the updated code. + if (bundle.parent) hmrApply(bundle.parent, asset); + } +} +function hmrDelete(bundle, id) { + let modules = bundle.modules; + if (!modules) return; + if (modules[id]) { + // Collect dependencies that will become orphaned when this module is deleted. + let deps = modules[id][1]; + let orphans = []; + for(let dep in deps){ + let parents = getParents(module.bundle.root, deps[dep]); + if (parents.length === 1) orphans.push(deps[dep]); + } + // Delete the module. This must be done before deleting dependencies in case of circular dependencies. + delete modules[id]; + delete bundle.cache[id]; + // Now delete the orphans. + orphans.forEach((id)=>{ + hmrDelete(module.bundle.root, id); + }); + } else if (bundle.parent) hmrDelete(bundle.parent, id); +} +function hmrAcceptCheck(bundle /*: ParcelRequire */ , id /*: string */ , depsByBundle /*: ?{ [string]: { [string]: string } }*/ ) { + checkedAssets = {}; + if (hmrAcceptCheckOne(bundle, id, depsByBundle)) return true; + // Traverse parents breadth first. All possible ancestries must accept the HMR update, or we'll reload. + let parents = getParents(module.bundle.root, id); + let accepted = false; + while(parents.length > 0){ + let v = parents.shift(); + let a = hmrAcceptCheckOne(v[0], v[1], null); + if (a) // If this parent accepts, stop traversing upward, but still consider siblings. + accepted = true; + else if (a !== null) { + // Otherwise, queue the parents in the next level upward. + let p = getParents(module.bundle.root, v[1]); + if (p.length === 0) { + // If there are no parents, then we've reached an entry without accepting. Reload. + accepted = false; + break; + } + parents.push(...p); + } + } + return accepted; +} +function hmrAcceptCheckOne(bundle /*: ParcelRequire */ , id /*: string */ , depsByBundle /*: ?{ [string]: { [string]: string } }*/ ) { + var modules = bundle.modules; + if (!modules) return; + if (depsByBundle && !depsByBundle[bundle.HMR_BUNDLE_ID]) { + // If we reached the root bundle without finding where the asset should go, + // there's nothing to do. Mark as "accepted" so we don't reload the page. + if (!bundle.parent) { + bundleNotFound = true; + return true; + } + return hmrAcceptCheckOne(bundle.parent, id, depsByBundle); + } + if (checkedAssets[id]) return null; + checkedAssets[id] = true; + var cached = bundle.cache[id]; + if (!cached) return true; + assetsToDispose.push([ + bundle, + id + ]); + if (cached && cached.hot && cached.hot._acceptCallbacks.length) { + assetsToAccept.push([ + bundle, + id + ]); + return true; + } + return false; +} +function hmrDisposeQueue() { + // Dispose all old assets. + for(let i = 0; i < assetsToDispose.length; i++){ + let id = assetsToDispose[i][1]; + if (!disposedAssets[id]) { + hmrDispose(assetsToDispose[i][0], id); + disposedAssets[id] = true; + } + } + assetsToDispose = []; +} +function hmrDispose(bundle /*: ParcelRequire */ , id /*: string */ ) { + var cached = bundle.cache[id]; + bundle.hotData[id] = {}; + if (cached && cached.hot) cached.hot.data = bundle.hotData[id]; + if (cached && cached.hot && cached.hot._disposeCallbacks.length) cached.hot._disposeCallbacks.forEach(function(cb) { + cb(bundle.hotData[id]); + }); + delete bundle.cache[id]; +} +function hmrAccept(bundle /*: ParcelRequire */ , id /*: string */ ) { + // Execute the module. + bundle(id); + // Run the accept callbacks in the new version of the module. + var cached = bundle.cache[id]; + if (cached && cached.hot && cached.hot._acceptCallbacks.length) { + let assetsToAlsoAccept = []; + cached.hot._acceptCallbacks.forEach(function(cb) { + let additionalAssets = cb(function() { + return getParents(module.bundle.root, id); + }); + if (Array.isArray(additionalAssets) && additionalAssets.length) assetsToAlsoAccept.push(...additionalAssets); + }); + if (assetsToAlsoAccept.length) { + let handled = assetsToAlsoAccept.every(function(a) { + return hmrAcceptCheck(a[0], a[1]); + }); + if (!handled) return fullReload(); + hmrDisposeQueue(); + } + } +} + +},{}],"1jwFz":[function(require,module,exports,__globalThis) { +var _indexTs = require("./assets/scripts/index.ts"); +var _indexScss = require("./assets/scss/index.scss"); + +},{"./assets/scripts/index.ts":"cmXY9","./assets/scss/index.scss":"6ebKA"}],"cmXY9":[function(require,module,exports,__globalThis) { +var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); +var _toastifyJs = require("toastify-js"); +var _toastifyJsDefault = parcelHelpers.interopDefault(_toastifyJs); +const favoritePosts = { + init () { + if (!this.component) return; + this.addEventListeners(); + }, + addEventListeners () { + this.component.addEventListener('click', this.handleClick.bind(this)); + }, + async favoritePost () { + // @ts-ignore + fetch(wpApiSettings.root + wpApiSettings.rest_namespace + '/favorite-posts', { + method: 'POST', + body: JSON.stringify({ + post_id: this.component.dataset.postId + }), + headers: { + 'Content-Type': 'application/json', + // @ts-ignore + 'X-WP-Nonce': wpApiSettings.nonce + } + }).then((response)=>response.json()).then((data)=>{ + (0, _toastifyJsDefault.default)({ + text: data.message + }).showToast(); + this.component.classList.add('is-favorite'); + }).catch((error)=>{ + (0, _toastifyJsDefault.default)({ + text: 'Failed to add favorite post', + className: 'error', + style: { + background: 'linear-gradient(to right, #ff0000, #ff4747)' + } + }).showToast(); + }); + }, + async handleClick () { + !!this.dialogLoader && this.dialogLoader.showModal(); + if (this.component.classList.contains('is-favorite')) await this.removeFavoritePost(); + else await this.favoritePost(); + !!this.dialogLoader && this.dialogLoader.close(); + }, + async removeFavoritePost () { + // @ts-ignore + fetch(wpApiSettings.root + wpApiSettings.rest_namespace + '/favorite-posts', { + method: 'DELETE', + body: JSON.stringify({ + post_id: this.component.dataset.postId + }), + headers: { + 'Content-Type': 'application/json', + // @ts-ignore + 'X-WP-Nonce': wpApiSettings.nonce + } + }).then((response)=>response.json()).then((data)=>{ + (0, _toastifyJsDefault.default)({ + text: data.message + }).showToast(); + this.component.classList.remove('is-favorite'); + }).catch((error)=>{ + (0, _toastifyJsDefault.default)({ + text: 'Failed to remove favorite post', + className: 'error', + style: { + background: 'linear-gradient(to right, #ff0000, #ff4747)' + } + }).showToast(); + }); + }, + component: document.querySelector('.favorite-post-button'), + dialogLoader: document.querySelector('#dialog-loader'), + favoritePostsPopover: document.querySelector('#favorite-posts-popover') +}; +favoritePosts.init(); + +},{"toastify-js":"96k49","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"96k49":[function(require,module,exports,__globalThis) { +/*! + * Toastify js 1.12.0 + * https://github.com/apvarun/toastify-js + * @license MIT licensed + * + * Copyright (C) 2018 Varun A P + */ (function(root, factory) { + if (module.exports) module.exports = factory(); + else root.Toastify = factory(); +})(this, function(global) { + // Object initialization + var Toastify = function(options) { + // Returning a new init object + return new Toastify.lib.init(options); + }, // Library version + version = "1.12.0"; + // Set the default global options + Toastify.defaults = { + oldestFirst: true, + text: "Toastify is awesome!", + node: undefined, + duration: 3000, + selector: undefined, + callback: function() {}, + destination: undefined, + newWindow: false, + close: false, + gravity: "toastify-top", + positionLeft: false, + position: '', + backgroundColor: '', + avatar: "", + className: "", + stopOnFocus: true, + onClick: function() {}, + offset: { + x: 0, + y: 0 + }, + escapeMarkup: true, + ariaLive: 'polite', + style: { + background: '' + } + }; + // Defining the prototype of the object + Toastify.lib = Toastify.prototype = { + toastify: version, + constructor: Toastify, + // Initializing the object with required parameters + init: function(options) { + // Verifying and validating the input object + if (!options) options = {}; + // Creating the options object + this.options = {}; + this.toastElement = null; + // Validating the options + this.options.text = options.text || Toastify.defaults.text; // Display message + this.options.node = options.node || Toastify.defaults.node; // Display content as node + this.options.duration = options.duration === 0 ? 0 : options.duration || Toastify.defaults.duration; // Display duration + this.options.selector = options.selector || Toastify.defaults.selector; // Parent selector + this.options.callback = options.callback || Toastify.defaults.callback; // Callback after display + this.options.destination = options.destination || Toastify.defaults.destination; // On-click destination + this.options.newWindow = options.newWindow || Toastify.defaults.newWindow; // Open destination in new window + this.options.close = options.close || Toastify.defaults.close; // Show toast close icon + this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : Toastify.defaults.gravity; // toast position - top or bottom + this.options.positionLeft = options.positionLeft || Toastify.defaults.positionLeft; // toast position - left or right + this.options.position = options.position || Toastify.defaults.position; // toast position - left or right + this.options.backgroundColor = options.backgroundColor || Toastify.defaults.backgroundColor; // toast background color + this.options.avatar = options.avatar || Toastify.defaults.avatar; // img element src - url or a path + this.options.className = options.className || Toastify.defaults.className; // additional class names for the toast + this.options.stopOnFocus = options.stopOnFocus === undefined ? Toastify.defaults.stopOnFocus : options.stopOnFocus; // stop timeout on focus + this.options.onClick = options.onClick || Toastify.defaults.onClick; // Callback after click + this.options.offset = options.offset || Toastify.defaults.offset; // toast offset + this.options.escapeMarkup = options.escapeMarkup !== undefined ? options.escapeMarkup : Toastify.defaults.escapeMarkup; + this.options.ariaLive = options.ariaLive || Toastify.defaults.ariaLive; + this.options.style = options.style || Toastify.defaults.style; + if (options.backgroundColor) this.options.style.background = options.backgroundColor; + // Returning the current object for chaining functions + return this; + }, + // Building the DOM element + buildToast: function() { + // Validating if the options are defined + if (!this.options) throw "Toastify is not initialized"; + // Creating the DOM object + var divElement = document.createElement("div"); + divElement.className = "toastify on " + this.options.className; + // Positioning toast to left or right or center + if (!!this.options.position) divElement.className += " toastify-" + this.options.position; + else // To be depreciated in further versions + if (this.options.positionLeft === true) { + divElement.className += " toastify-left"; + console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.'); + } else // Default position + divElement.className += " toastify-right"; + // Assigning gravity of element + divElement.className += " " + this.options.gravity; + if (this.options.backgroundColor) // This is being deprecated in favor of using the style HTML DOM property + console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.'); + // Loop through our style object and apply styles to divElement + for(var property in this.options.style)divElement.style[property] = this.options.style[property]; + // Announce the toast to screen readers + if (this.options.ariaLive) divElement.setAttribute('aria-live', this.options.ariaLive); + // Adding the toast message/node + if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) // If we have a valid node, we insert it + divElement.appendChild(this.options.node); + else { + if (this.options.escapeMarkup) divElement.innerText = this.options.text; + else divElement.innerHTML = this.options.text; + if (this.options.avatar !== "") { + var avatarElement = document.createElement("img"); + avatarElement.src = this.options.avatar; + avatarElement.className = "toastify-avatar"; + if (this.options.position == "left" || this.options.positionLeft === true) // Adding close icon on the left of content + divElement.appendChild(avatarElement); + else // Adding close icon on the right of content + divElement.insertAdjacentElement("afterbegin", avatarElement); + } + } + // Adding a close icon to the toast + if (this.options.close === true) { + // Create a span for close element + var closeElement = document.createElement("button"); + closeElement.type = "button"; + closeElement.setAttribute("aria-label", "Close"); + closeElement.className = "toast-close"; + closeElement.innerHTML = "✖"; + // Triggering the removal of toast from DOM on close click + closeElement.addEventListener("click", (function(event) { + event.stopPropagation(); + this.removeElement(this.toastElement); + window.clearTimeout(this.toastElement.timeOutValue); + }).bind(this)); + //Calculating screen width + var width = window.innerWidth > 0 ? window.innerWidth : screen.width; + // Adding the close icon to the toast element + // Display on the right if screen width is less than or equal to 360px + if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) // Adding close icon on the left of content + divElement.insertAdjacentElement("afterbegin", closeElement); + else // Adding close icon on the right of content + divElement.appendChild(closeElement); + } + // Clear timeout while toast is focused + if (this.options.stopOnFocus && this.options.duration > 0) { + var self = this; + // stop countdown + divElement.addEventListener("mouseover", function(event) { + window.clearTimeout(divElement.timeOutValue); + }); + // add back the timeout + divElement.addEventListener("mouseleave", function() { + divElement.timeOutValue = window.setTimeout(function() { + // Remove the toast from DOM + self.removeElement(divElement); + }, self.options.duration); + }); + } + // Adding an on-click destination path + if (typeof this.options.destination !== "undefined") divElement.addEventListener("click", (function(event) { + event.stopPropagation(); + if (this.options.newWindow === true) window.open(this.options.destination, "_blank"); + else window.location = this.options.destination; + }).bind(this)); + if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") divElement.addEventListener("click", (function(event) { + event.stopPropagation(); + this.options.onClick(); + }).bind(this)); + // Adding offset + if (typeof this.options.offset === "object") { + var x = getAxisOffsetAValue("x", this.options); + var y = getAxisOffsetAValue("y", this.options); + var xOffset = this.options.position == "left" ? x : "-" + x; + var yOffset = this.options.gravity == "toastify-top" ? y : "-" + y; + divElement.style.transform = "translate(" + xOffset + "," + yOffset + ")"; + } + // Returning the generated element + return divElement; + }, + // Displaying the toast + showToast: function() { + // Creating the DOM object for the toast + this.toastElement = this.buildToast(); + // Getting the root element to with the toast needs to be added + var rootElement; + if (typeof this.options.selector === "string") rootElement = document.getElementById(this.options.selector); + else if (this.options.selector instanceof HTMLElement || typeof ShadowRoot !== 'undefined' && this.options.selector instanceof ShadowRoot) rootElement = this.options.selector; + else rootElement = document.body; + // Validating if root element is present in DOM + if (!rootElement) throw "Root element is not defined"; + // Adding the DOM element + var elementToInsert = Toastify.defaults.oldestFirst ? rootElement.firstChild : rootElement.lastChild; + rootElement.insertBefore(this.toastElement, elementToInsert); + // Repositioning the toasts in case multiple toasts are present + Toastify.reposition(); + if (this.options.duration > 0) this.toastElement.timeOutValue = window.setTimeout((function() { + // Remove the toast from DOM + this.removeElement(this.toastElement); + }).bind(this), this.options.duration); // Binding `this` for function invocation + // Supporting function chaining + return this; + }, + hideToast: function() { + if (this.toastElement.timeOutValue) clearTimeout(this.toastElement.timeOutValue); + this.removeElement(this.toastElement); + }, + // Removing the element from the DOM + removeElement: function(toastElement) { + // Hiding the element + // toastElement.classList.remove("on"); + toastElement.className = toastElement.className.replace(" on", ""); + // Removing the element from DOM after transition end + window.setTimeout((function() { + // remove options node if any + if (this.options.node && this.options.node.parentNode) this.options.node.parentNode.removeChild(this.options.node); + // Remove the element from the DOM, only when the parent node was not removed before. + if (toastElement.parentNode) toastElement.parentNode.removeChild(toastElement); + // Calling the callback function + this.options.callback.call(toastElement); + // Repositioning the toasts again + Toastify.reposition(); + }).bind(this), 400); // Binding `this` for function invocation + } + }; + // Positioning the toasts on the DOM + Toastify.reposition = function() { + // Top margins with gravity + var topLeftOffsetSize = { + top: 15, + bottom: 15 + }; + var topRightOffsetSize = { + top: 15, + bottom: 15 + }; + var offsetSize = { + top: 15, + bottom: 15 + }; + // Get all toast messages on the DOM + var allToasts = document.getElementsByClassName("toastify"); + var classUsed; + // Modifying the position of each toast element + for(var i = 0; i < allToasts.length; i++){ + // Getting the applied gravity + if (containsClass(allToasts[i], "toastify-top") === true) classUsed = "toastify-top"; + else classUsed = "toastify-bottom"; + var height = allToasts[i].offsetHeight; + classUsed = classUsed.substr(9, classUsed.length - 1); + // Spacing between toasts + var offset = 15; + var width = window.innerWidth > 0 ? window.innerWidth : screen.width; + // Show toast in center if screen with less than or equal to 360px + if (width <= 360) { + // Setting the position + allToasts[i].style[classUsed] = offsetSize[classUsed] + "px"; + offsetSize[classUsed] += height + offset; + } else if (containsClass(allToasts[i], "toastify-left") === true) { + // Setting the position + allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px"; + topLeftOffsetSize[classUsed] += height + offset; + } else { + // Setting the position + allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px"; + topRightOffsetSize[classUsed] += height + offset; + } + } + // Supporting function chaining + return this; + }; + // Helper function to get offset. + function getAxisOffsetAValue(axis, options) { + if (options.offset[axis]) { + if (isNaN(options.offset[axis])) return options.offset[axis]; + else return options.offset[axis] + 'px'; + } + return '0px'; + } + function containsClass(elem, yourClass) { + if (!elem || typeof yourClass !== "string") return false; + else if (elem.className && elem.className.trim().split(/\s+/gi).indexOf(yourClass) > -1) return true; + else return false; + } + // Setting up the prototype for the init object + Toastify.lib.init.prototype = Toastify.lib; + // Returning the Toastify function to be assigned to the window object/module + return Toastify; +}); + +},{}],"gkKU3":[function(require,module,exports,__globalThis) { +exports.interopDefault = function(a) { + return a && a.__esModule ? a : { + default: a + }; +}; +exports.defineInteropFlag = function(a) { + Object.defineProperty(a, '__esModule', { + value: true + }); +}; +exports.exportAll = function(source, dest) { + Object.keys(source).forEach(function(key) { + if (key === 'default' || key === '__esModule' || Object.prototype.hasOwnProperty.call(dest, key)) return; + Object.defineProperty(dest, key, { + enumerable: true, + get: function() { + return source[key]; + } + }); + }); + return dest; +}; +exports.export = function(dest, destName, get) { + Object.defineProperty(dest, destName, { + enumerable: true, + get: get + }); +}; + +},{}],"6ebKA":[function() {},{}]},["1Mq6V","1jwFz"], "1jwFz", "parcelRequire2f3a", {}) + //# sourceMappingURL=index.js.map diff --git a/package.json b/package.json index 6157007b..afcdea77 100644 --- a/package.json +++ b/package.json @@ -12,5 +12,8 @@ "scripts": { "dev": "parcel watch index.ts", "build": "parcel build index.ts" + }, + "dependencies": { + "toastify-js": "^1.12.0" } } diff --git a/src/dbHandler.php b/src/dbHandler.php index bb27f1ad..4c5f7eb9 100644 --- a/src/dbHandler.php +++ b/src/dbHandler.php @@ -15,13 +15,21 @@ public function __construct() { } public function createTable() { - $this->wpdb->query("CREATE TABLE IF NOT EXISTS $this->table_name ( - id INT AUTO_INCREMENT PRIMARY KEY, - user_id INT NOT NULL, - post_id INT NOT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - CONSTRAINT UQ_user_id_post_id UNIQUE (user_id, post_id) - )"); + $table = $this->table_name; + $charset_collate = $this->wpdb->get_charset_collate(); + + $sql = "CREATE TABLE $table ( + id bigint(20) unsigned NOT NULL AUTO_INCREMENT, + user_id bigint(20) unsigned NOT NULL, + post_id bigint(20) unsigned NOT NULL, + created_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY user_id_post_id (user_id, post_id) + ) $charset_collate;"; + + require_once ABSPATH . 'wp-admin/includes/upgrade.php'; + + dbDelta($sql); } private function dropTable() { diff --git a/src/restHandler.php b/src/restHandler.php index cea613b5..15f3771c 100644 --- a/src/restHandler.php +++ b/src/restHandler.php @@ -23,23 +23,44 @@ public function registerRoutes() { register_rest_route($this->restNamespace, '/favorite-posts', [ 'methods' => 'GET', 'callback' => [$this, 'getFavoritePosts'], + 'permission_callback' => function () { + return is_user_logged_in() ? true : new WP_Error( 'rest_not_logged_in', 'You must be logged in to access this endpoint.', array( 'status' => 401 ) ); + }, ]); register_rest_route($this->restNamespace, '/favorite-posts', [ 'methods' => 'POST', 'callback' => [$this, 'addFavoritePost'], + 'permission_callback' => function () { + return is_user_logged_in() ? true : new WP_Error( 'rest_not_logged_in', 'You must be logged in to access this endpoint.', array( 'status' => 401 ) ); + }, + 'args' => [ + 'post_id' => [ + 'type' => 'integer', + 'required' => true, + 'sanitize_callback' => 'absint', + ] + ], ]); register_rest_route($this->restNamespace, '/favorite-posts', [ 'methods' => 'DELETE', 'callback' => [$this, 'removeFavoritePost'], + 'permission_callback' => function () { + return is_user_logged_in() ? true : new WP_Error( 'rest_not_logged_in', 'You must be logged in to access this endpoint.', array( 'status' => 401 ) ); + }, + 'args' => [ + 'post_id' => [ + 'type' => 'integer', + 'required' => true, + 'sanitize_callback' => 'absint', + ] + ], ]); } public function getFavoritePosts($request) { - $user_id = $request->get_param('user_id'); - - $favorites = $this->dbHandler->getAllFavoritesByUserId($user_id); + $favorites = $this->dbHandler->getAllFavoritesByUserId(get_current_user_id()); if ($favorites) { return new \WP_REST_Response([ @@ -54,61 +75,74 @@ public function getFavoritePosts($request) { 'code' => 'failed_to_fetch_favorite_posts', 'status' => 'error', 'message' => 'Failed to fetch favorite posts', - 'data' => null - ], 500); + 'data' => [] + ], 200); } public function addFavoritePost($request) { $params = $request->get_json_params(); - $user_id = isset($params['user_id']) ? absint($params['user_id']) : absint($request->get_param('user_id')); $post_id = isset($params['post_id']) ? absint($params['post_id']) : absint($request->get_param('post_id')); - if (!$user_id || !$post_id) { + if (!$post_id) { return new \WP_REST_Response([ - 'code' => 'invalid_favorite_post_params', - 'status' => 'error', - 'message' => 'Invalid user_id or post_id', - 'data' => null + 'code' => 'invalid_favorite_post_params', + 'data' => [], + 'message' => 'Invalid post_id', + 'status' => 'error' ], 400); } - $result = $this->dbHandler->addFavorite($user_id, $post_id); + $result = $this->dbHandler->addFavorite(get_current_user_id(), $post_id); if ($result) { return new \WP_REST_Response([ 'code' => 'favorite_post_added', - 'status' => 'success', - 'message' => 'Favorite post added', 'data' => [ - 'user_id' => $user_id, 'post_id' => $post_id - ] + ], + 'message' => 'Favorite post added', + 'status' => 'success' ], 200); } return new \WP_REST_Response([ - 'code' => 'failed_to_add_favorite_post', - 'status' => 'error', + 'code' => 'failed_to_add_favorite_post', + 'data' => [], 'message' => 'Failed to add favorite post', - 'data' => null - ], 500); + 'status' => 'error', + ], 400); } public function removeFavoritePost($request) { $params = $request->get_json_params(); - $user_id = isset($params['user_id']) ? absint($params['user_id']) : absint($request->get_param('user_id')); $post_id = isset($params['post_id']) ? absint($params['post_id']) : absint($request->get_param('post_id')); - if (!$user_id || !$post_id) { + if (!$post_id) { return new \WP_REST_Response([ - 'code' => 'invalid_favorite_post_params', - 'status' => 'error', - 'message' => 'Invalid user_id or post_id', - 'data' => null + 'code' => 'invalid_favorite_post_params', + 'data' => [], + 'message' => 'Invalid post_id', + 'status' => 'error' ], 400); } - return $this->dbHandler->removeFavorite($user_id, $post_id); + $result = $this->dbHandler->removeFavorite(get_current_user_id(), $post_id); + + if ($result) { + return new \WP_REST_Response([ + 'code' => 'favorite_post_removed', + 'data' => [], + 'status' => 'success', + 'message' => 'Favorite post removed', + ], 200); + } + + return new \WP_REST_Response([ + 'code' => 'failed_to_remove_favorite_post', + 'data' => [], + 'status' => 'error', + 'message' => 'Failed to remove favorite post' + ], 400); } } diff --git a/wordpress-back-end-challenge.php b/wordpress-back-end-challenge.php index d3f93d09..9b7dfa60 100644 --- a/wordpress-back-end-challenge.php +++ b/wordpress-back-end-challenge.php @@ -34,7 +34,7 @@ public function __construct() { } public function addDialogLoader() { - echo '
'; + echo '
'; } public function addFavoritePostIcon( $content ) @@ -45,7 +45,7 @@ public function addFavoritePostIcon( $content ) $is_favorite = $this->dbHandler->getFavoriteByUserAndPost(get_current_user_id(), get_the_ID()); - $custom_content = ""; @@ -55,6 +55,21 @@ public function addFavoritePostIcon( $content ) } public function enqueueScripts() { + if (!is_user_logged_in() || !is_singular()) : + return; + endif; + + wp_enqueue_script( + 'toastify', + 'https://cdn.jsdelivr.net/npm/toastify-js', + [], + '1.12.0', + [ + 'in_footer' => true, + 'strategy' => 'async' + ] + ); + wp_enqueue_script( 'wordpress-back-end-challenge', plugin_dir_url( __FILE__ ) . 'dist/index.js', @@ -82,6 +97,13 @@ public function enqueueScripts() { [], filemtime(plugin_dir_path( __FILE__ ) . 'dist/index.css') ); + + wp_enqueue_style( + 'toastify', + 'https://cdn.jsdelivr.net/npm/toastify-js/src/toastify.min.css', + [], + '1.12.0' + ); } }