From 00c207e86e32fe4df42f974a3ffd257214b2f12e Mon Sep 17 00:00:00 2001 From: Naddybs <144009698+Naddybs@users.noreply.github.com> Date: Fri, 17 May 2024 02:05:00 +0200 Subject: [PATCH 1/7] Eerste opzet server --- helpers/fetch-json.js | 20 + package-lock.json | 1164 +++++++++++++++++++++++++++++++++++++++ package.json | 6 +- server.js | 34 +- views/index.ejs | 8 + views/partials/head.ejs | 9 + 6 files changed, 1239 insertions(+), 2 deletions(-) create mode 100644 helpers/fetch-json.js create mode 100644 package-lock.json create mode 100644 views/index.ejs create mode 100644 views/partials/head.ejs diff --git a/helpers/fetch-json.js b/helpers/fetch-json.js new file mode 100644 index 000000000..17c6eb451 --- /dev/null +++ b/helpers/fetch-json.js @@ -0,0 +1,20 @@ +/** + * An asynchronous helper function that wraps the standard node.js fetch API. + * This function calls an API url passed as the first and mandatory parameter, + * there is an optional payload parameter to send a json object, eg. a filter. + * It then calls the API and returns the response body parsed as a json object. + * @example fetchJson as returning function using the await keyword + * const data = await fetchJson('https://api-url.com/endpoint/') + * @example fetchJson as oneliner using the then() structure. + * fetchJson('https://api-url.com/endpoint/').then((data)=>{ + * // use data... + * }) + * @param {string} url the api endpoint to address + * @param {object} [payload] the payload to send to the API + * @returns the response from the API endpoint parsed as a json object + */ +export default async function fetchJson(url, payload = {}) { + return await fetch(url, payload) + .then((response) => response.json()) + .catch((error) => error) + } diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..449052616 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1164 @@ +{ + "name": "pleasurable-ui", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "pleasurable-ui", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "ejs": "^3.1.10", + "express": "^4.19.2" + }, + "devDependencies": { + "nodemon": "^3.1.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/jake": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz", + "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nodemon": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.0.tgz", + "integrity": "sha512-xqlktYlDMCepBJd43ZQhjWwMw2obW/JRvkrLxq5RCNcuDDX1DbcPT+qT1IlIIdf+DhnWs90JpTMe+Y5KxOchvA==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "dev": true, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + } + } +} diff --git a/package.json b/package.json index a09003bcc..7045cc469 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "doc": "docs" }, "scripts": { - "start": "node server.js" + "start": "node server.js", + "develop": "nodemon server.js" }, "repository": { "type": "git", @@ -28,5 +29,8 @@ "dependencies": { "ejs": "^3.1.10", "express": "^4.19.2" + }, + "devDependencies": { + "nodemon": "^3.1.0" } } diff --git a/server.js b/server.js index 562d97a21..460290c04 100644 --- a/server.js +++ b/server.js @@ -1 +1,33 @@ -console.log('Hier komt jullie server') \ No newline at end of file +console.log('Hier komt jullie server') + +// Dit houdt in dat je de express module importeert en deze vervolgens gebruikt om een nieuwe express applicatie te maken. Deze applicatie wordt opgeslagen in de variabele app. +// Daarnaast wordt de poort waarop de server moet luisteren opgeslagen in de variabele port. +import express from 'express' +const app = express() +const port = 3000 +console.log('server opent op poort 3000') + +// Dit houdt in dat je de fetchJson functie importeert vanuit het bestand fetch-json.js en deze vervolgens gebruikt om data op te halen van de server. +import fetchJson from './helpers/fetch-json.js' +console.log(fetchJson) + +// Dit zet de view engine van de express applicatie op ejs en zorgt ervoor dat de views in de map views worden opgeslagen. +// Daarnaast wordt de public map statisch gemaakt zodat de bestanden in deze map kunnen worden opgehaald. +// Ook wordt de express.urlencoded middleware gebruikt om het werken met request data makkelijker te maken. +app.set('view engine', 'ejs') +app.set('views', 'views') +app.use(express.static('public')) + +// dit zorgt ervoor dat het werken met request data makkelijker wordt +app.use(express.urlencoded({extended: true})) + +// Dit zorgt ervoor dat de server de index.ejs file rendert wanneer er een get request wordt gedaan op de root van de server. +app.get('/', async (req, res) => { + res.render('index') +}); + +//Dit houdt in dat de server start op poort 3000 en dat er een bericht wordt gelogd in de console wanneer de server is gestart. +app.set('port', process.env.PORT || 3000) +app.listen(app.get('port'), function () { + console.log(`Application started on http://localhost:${app.get('port')}`) + }) \ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs new file mode 100644 index 000000000..da1de4cad --- /dev/null +++ b/views/index.ejs @@ -0,0 +1,8 @@ +<%- include('./partials/head') %> + +

hallo wereld

+ + + + + \ No newline at end of file diff --git a/views/partials/head.ejs b/views/partials/head.ejs new file mode 100644 index 000000000..de5b65d80 --- /dev/null +++ b/views/partials/head.ejs @@ -0,0 +1,9 @@ + + + + + + Funda favorieten redesign + + + From 74ef086a87380882088db524bb125258612f9bdd Mon Sep 17 00:00:00 2001 From: Naddybs <144009698+Naddybs@users.noreply.github.com> Date: Wed, 22 May 2024 11:19:17 +0200 Subject: [PATCH 2/7] Data opgehaald --- public/assets/02-funda-Blue.png | Bin 0 -> 40706 bytes public/styles/style.css | 164 ++++++++++++++++++++++++++++++++ server.js | 50 ++++++---- views/index.ejs | 48 +++++++++- views/partials/head.ejs | 13 ++- 5 files changed, 254 insertions(+), 21 deletions(-) create mode 100644 public/assets/02-funda-Blue.png create mode 100644 public/styles/style.css diff --git a/public/assets/02-funda-Blue.png b/public/assets/02-funda-Blue.png new file mode 100644 index 0000000000000000000000000000000000000000..77342f3ecbb8807213b1b3af3bc02645ca080e2e GIT binary patch literal 40706 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 { - res.render('index') +// Hiermee definieer je de url van de API die je wilt benaderen. In dit geval is dat de API van de directus app die we gebruiken voor Funda. +const apiUrl = `https://fdnd-agency.directus.app/items/f_list/${9}?fields=*.*.*`; +console.log(apiUrl) + + +// ... +// Dit zorgt ervoor dat de fetchJson functie wordt aangeroepen met de apiUrl als parameter. Een parameter is een waarde die je meegeeft aan een functie. +// Dit houdt in dat de apiUrl wordt gebruikt om data op te halen van de server. +fetchJson(apiUrl).then((apiData) => { + console.log(apiData); + + // Hiermee zet je de view engine van de express applicatie op ejs en zorg je ervoor dat de views in de map views worden opgeslagen. + // Daarnaast maak je de public map statisch zodat de bestanden in deze map kunnen worden opgehaald. + // Ook gebruik je de express.urlencoded middleware om het werken met request data makkelijker te maken. + app.set('view engine', 'ejs'); + app.set('views', 'views'); + app.use(express.static('public')); + app.use(express.urlencoded({ extended: true })); + + // Dit zorgt ervoor dat de server de index.ejs file rendert wanneer er een get request wordt gedaan op de root van de server. + // Vervolgens wordt de data van de API meegegeven aan de view zodat deze kan worden gebruikt in de ejs file. + // houses: apiData.data.houses is de data die wordt meegegeven aan de view. Deze data is afkomstig van de API. + app.get('/', async (req, res) => { + res.render('index', { houses: apiData.data.houses }); + }); + + // Dit zorgt ervoor dat de server start op poort 3000 en dat er een bericht wordt gelogd in de console wanneer de server is gestart. + app.set('port', process.env.PORT || 3000); + app.listen(app.get('port'), function () { + console.log(`Application started on http://localhost:${app.get('port')}`); + }); }); -//Dit houdt in dat de server start op poort 3000 en dat er een bericht wordt gelogd in de console wanneer de server is gestart. -app.set('port', process.env.PORT || 3000) -app.listen(app.get('port'), function () { - console.log(`Application started on http://localhost:${app.get('port')}`) - }) \ No newline at end of file +// ... \ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs index da1de4cad..e2a6457fa 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -1,8 +1,52 @@ -<%- include('./partials/head') %> +<%- include('./partials/head') %> -

hallo wereld

+ +
+ + +

Gedeelde favorieten

+

In dit overzicht vind je al je favoriete huizen terug in je aangemaakte lijst. Maak het jezelf makkelijker door huizen te bewaren en beoordelingen toe te voegen en te delen over het huis, de buurt en andere belangrijke details voor je zoektocht.

+

+ +

Eerste woning

+ +
+ <% houses.forEach(function(house) { %> +
+ Afbeelding van een huis +
    +
  • +

    <%= house.f_houses_id.street %> <%= house.f_houses_id.house_nr %> <%= house.f_houses_id.nr_addition %>

    +
  • +
  • +

    <%= house.f_houses_id.postal_code %>

    +

    <%= house.f_houses_id.city %>

    +
  • +
  • +

    €<%= house.f_houses_id.price %>K.K.

    +
  • +
  • +

    <%= house.f_houses_id.m2 %> m2/<%= house.f_houses_id.rooms %> kamers

    +
  • +
+ + +
+ <% }) %> +
\ No newline at end of file diff --git a/views/partials/head.ejs b/views/partials/head.ejs index de5b65d80..5cb9584be 100644 --- a/views/partials/head.ejs +++ b/views/partials/head.ejs @@ -4,6 +4,17 @@ Funda favorieten redesign + - +
+ +
+ \ No newline at end of file From 276a9ecc9ec465657fdb7ae8d9e07e9c011fe5ea Mon Sep 17 00:00:00 2001 From: rileyesther <144009597+rileyesther@users.noreply.github.com> Date: Wed, 22 May 2024 11:56:09 +0200 Subject: [PATCH 3/7] rating versie 1 --- public/scripts/script.js | 44 ++++++++++++++++++++++++++++ public/styles/style.css | 62 +++++++++++++++++++++++++++++++++++++++- views/index.ejs | 17 +++++++++++ 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 public/scripts/script.js diff --git a/public/scripts/script.js b/public/scripts/script.js new file mode 100644 index 000000000..139084815 --- /dev/null +++ b/public/scripts/script.js @@ -0,0 +1,44 @@ +const fiveStarWrapper = document.querySelector("fieldset:nth-of-type(4) label:nth-of-type(5)"); +const fiveStarRadio = fiveStarWrapper.querySelector("input"); +const popAudio = document.querySelector("audio"); + +const yathzeeMetDeZessen = () => { + popAudio.play(); + + // create 1000 dots + for (let i = 0; i < 1000; i++) { + let dot = document.createElement("div"); + fiveStarWrapper.appendChild(dot); + + gsap + .timeline() + .set(dot, { + scale: "random(.5, 1)", + backgroundColor: "random([lime,white,deeppink,white,dodgerblue])", + }) + .to(dot, { + duration: 2, + delay: "random(0, .3)", + rotate:"random(-2160,2160)", + physics2D: { + velocity: "random(200, 600)", + angle: "random(250, 290)", + gravity: 600, + }, + scale: "random(1, 2)", + onComplete: removeDot, + onCompleteParams:[dot], + }) + .to(dot, { + duration: 1, + opacity:0, + },"<+=1"); + } +} + +removeDot = dot => { + // remove the dot when done + dot.remove(); +} + +fiveStarRadio.onchange = yathzeeMetDeZessen; \ No newline at end of file diff --git a/public/styles/style.css b/public/styles/style.css index 2004825bf..0b46f1d8e 100644 --- a/public/styles/style.css +++ b/public/styles/style.css @@ -121,6 +121,7 @@ h2{ & img{ max-width: 20em; } + & h3, p{ text-align: center; display: flex; @@ -129,7 +130,7 @@ h2{ & li{ list-style: none; } -} + } & button{ background-color: var(--primary-dk-blue); color: white; @@ -161,4 +162,63 @@ h2{ img{ max-width: 20em; +} + + +fieldset:nth-of-type(1) { + label { + // vierkant + width:1.2em; + aspect-ratio:1; + line-height:1; + // ster in het midden + display:grid; + place-items:center; + } + + // sterretje in label + label::after { + content:"★"; + } + + // default kleur voor sterretje + label { + color:var(--clr-star-default); + } + + // input foetsie + // niet helemaal netjes + input { + position:absolute; + left:-9999em; + } + + // randje om de fieldset als een input in the fieldset focus-visible heeft + &:has(:focus-visible) { + outline:solid .1em var(--border-fieldset-focus); + } + + // label na checked radio krijgt checked kleur + input:checked + label { + color:var(--clr-star-checked); + } + + // alle labels voor checked radio krijgen checked kleur + label:has(~ :checked) { + color:var(--clr-star-checked); + } + + // cursor van label wordt pointer bij hover// + // maar niet het label na een checked radio// + // en kleur wijzigt in hover kleur// + label:hover:not( input:checked + label ) { + cursor:pointer; + color:var(--clr-star-hover); + } + + // kleur van label wordt hover kleur bij hover over label na label + // maar niet het label na een checked radio + label:has(~ label:hover):not( input:checked + label ) { + color:var(--clr-star-hover); + } } \ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs index e2a6457fa..c71a189bf 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -48,5 +48,22 @@ <% }) %> + +
+ rating + + + + + + + + + + + +
+ + \ No newline at end of file From 435c85decbb13c7c2b8e5730dcd35bd03c051154 Mon Sep 17 00:00:00 2001 From: Naddybs <144009698+Naddybs@users.noreply.github.com> Date: Thu, 23 May 2024 21:04:47 +0200 Subject: [PATCH 4/7] Verbeterde vormgeving + ranking section toegevoegd --- public/scripts/script.js | 66 +++++++++++ public/styles/style.css | 242 +++++++++++++++++++++++++++++--------- views/index.ejs | 64 ++++------ views/partials/rating.ejs | 111 +++++++++++++++++ 4 files changed, 387 insertions(+), 96 deletions(-) create mode 100644 public/scripts/script.js create mode 100644 views/partials/rating.ejs diff --git a/public/scripts/script.js b/public/scripts/script.js new file mode 100644 index 000000000..ac7504e64 --- /dev/null +++ b/public/scripts/script.js @@ -0,0 +1,66 @@ + +const fiveStarWrapper = document.querySelector("fieldset:nth-of-type(4) label:nth-of-type(5)"); +const fiveStarRadio = fiveStarWrapper.querySelector("input"); +const popAudio = document.querySelector("audio"); + +const yathzeeMetDeZessen = () => { + popAudio.play(); + + // create 1000 dots + for (let i = 0; i < 1000; i++) { + let dot = document.createElement("div"); + fiveStarWrapper.appendChild(dot); + + gsap + .timeline() + .set(dot, { + scale: "random(.5, 1)", + backgroundColor: "random([lime,white,deeppink,white,dodgerblue])", + }) + .to(dot, { + duration: 2, + delay: "random(0, .3)", + rotate:"random(-2160,2160)", + physics2D: { + velocity: "random(200, 600)", + angle: "random(250, 290)", + gravity: 600, + }, + scale: "random(1, 2)", + onComplete: removeDot, + onCompleteParams:[dot], + }) + .to(dot, { + duration: 1, + opacity:0, + },"<+=1"); + } +} + +removeDot = dot => { + // remove the dot when done + dot.remove(); +} + +fiveStarRadio.onchange = yathzeeMetDeZessen; + + + + document.querySelectorAll('.close-button').forEach(button => { + button.addEventListener('click', (event) => { + event.preventDefault(); + const popup = button.closest('.review-popup'); + popup.style.display = 'none'; + history.pushState("", document.title, window.location.pathname + window.location.search); + }); + }); + + window.addEventListener('hashchange', () => { + const hash = window.location.hash; + if (!hash) { + document.querySelectorAll('.review-popup').forEach(popup => { + popup.style.display = 'none'; + }); + } + }); + diff --git a/public/styles/style.css b/public/styles/style.css index 2004825bf..999aca732 100644 --- a/public/styles/style.css +++ b/public/styles/style.css @@ -82,83 +82,211 @@ nav{ padding-left: 1em; } } -.breadcrumbs{ - background-color: var(--primary-lt-blue); - margin: 0; - color: var(--primary-orange); - align-items: center; - & a{ - color: var(--primary-dk-blue); - text-align: center; - - } - & svg{ - align-items: center; - - } - -} /* -----------------------------intro section end--------------------------------- */ /* -----------------------------house list section------------------------------------ */ h2{ text-align: center; - padding: 1em; + padding: 1em 2em; font-size: 1.7em; - color: var(--primary-orange); + &::after{ + content: ""; + display: block; + width: 80%; + height: 5px; + background-color: var(--primary-orange); + margin: 0 auto; + } } -.house{ +.list-name{ + background-color: #f7a10061; + border-radius: .5em; display: flex; flex-direction: column; + justify-content: space-between; align-items: center; - margin: 1em; - padding: 1em; - border-bottom: solid 5px var(--primary-orange); - border-radius: .5em; - background-color: var(--primary-lt-blue); - position: relative; - & img{ - max-width: 20em; - } - & h3, p{ - text-align: center; - display: flex; - flex-direction: column; + & a{ + color: #4096dc; + text-decoration: none; } - & li{ - list-style: none; + & a::after{ + content: ""; + display: block; + width: 30%; + height: 5px; + background-color: var(--primary-orange); + margin: 0 auto; } -} & button{ - background-color: var(--primary-dk-blue); - color: white; - padding: .5em 1em; - border: solid 5px var(--primary-orange); - border-radius: .5em; - margin: 1em; - position: absolute; - bottom: 1em; - right: 1em; - font-size: 17px; -} -& button:hover{ - background-color: var(--primary-orange); -} -& span{ - font-size: 2.5em; - color: var(--primary-orange); - position: absolute; - top: 1em; - right: 1em; + background-color: #4096dc; + color: white; + border: none; + border-radius: 5px; + padding: 0.75em 1.5em; + cursor: pointer; + align-self: stretch; + margin: 1.2em 1em; + } + & button:hover{ + background-color: var(--primary-orange); + transition: background-color 0.3s; + transform: scale(1.1); + } } -.house-list{ +.house-list { display: flex; flex-wrap: wrap; justify-content: center; + gap: 1.5em; + padding: 2em; + background-color: #f5f5f5; } img{ max-width: 20em; -} \ No newline at end of file +} +.house-card { + background: white; + border-radius: 10px; + overflow: hidden; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + max-width: 300px; + display: flex; + flex-direction: column; + transition: transform 0.3s; + & img { + width: 100%; + height: auto; + } +} + +.house-card:hover { + transform: translateY(-15px); +} + +.house-details { + padding: 1em; + display: flex; + flex-direction: column; + align-items: flex-start; +} + +.house-details .house-title { + font-size: 1.5em; + color: #333; +} + +.house-details .house-location, +.house-details .house-price, +.house-details .house-size { + font-size: 1em; + margin: 0.5em 0; +} + +.house-details .house-location { + color: #777; +} + +.house-details .house-price { + font-size: 1.2em; + color: #f59f00; +} + +.house-details .house-size { + color: #555; +} + +.beoordeling-button { + background-color: #f59f00; + color: white; + border: none; + border-radius: 5px; + padding: 0.75em 1.5em; + margin-top: 1em; + cursor: pointer; + transition: background-color 0.3s; + align-self: stretch; /* Dit zorgt ervoor dat de knop de volledige breedte inneemt */ + text-align: center; +} + +.beoordeling-button:hover { + background-color: var(--primary-dk-blue); +} +/* -----------------------------house list section end------------------------------------ */ + +/* -----------------------------rating section------------------------------------ */ + +.beoordeling { + max-width: 600px; + margin: auto; + padding: 2em; + background-color: var(--primary-lt-blue); + border-radius: 10px; +} + +.rating-group { + margin-bottom: 1em; + display: flex; + justify-content: space-between; + align-items: center; +} + +.rating-title { + flex: 1; + font-size: 1.2em; +} + +.rating { + display: flex; + flex-direction: row-reverse; + justify-content: flex-end; + position: relative; + margin-left: 1em; +} + +.rating input[type="radio"] { + display: none; +} + +.rating label { + font-size: 2em; + color: #ccc; + cursor: pointer; + transition: color 0.3s; +} + +.rating label:hover, +.rating label:hover ~ label, +.rating input[type="radio"]:checked ~ label { + color: #f59f00; +} + +.rating-value { + font-size: 1.5em; + margin-left: 10px; + color: #333; + font-weight: bold; + line-height: 2.2em; +} + +.submit-ranking { + background-color: #f59f00; + color: white; + border: none; + border-radius: 5px; + padding: 0.75em 1.5em; + cursor: pointer; + transition: background-color 0.3s; + display: block; + width: 100%; + text-align: center; +} + +.submit-ranking:hover { + background-color: var(--primary-dk-blue); +} + + +/* -----------------------------rating section end------------------------------------ */ diff --git a/views/index.ejs b/views/index.ejs index e2a6457fa..f8f6ec870 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -1,52 +1,38 @@ <%- include('./partials/head') %> - +
- -

Gedeelde favorieten

In dit overzicht vind je al je favoriete huizen terug in je aangemaakte lijst. Maak het jezelf makkelijker door huizen te bewaren en beoordelingen toe te voegen en te delen over het huis, de buurt en andere belangrijke details voor je zoektocht.

+ -

Eerste woning

- +
+
+

Eerste woning

+ + +
<% houses.forEach(function(house) { %> -
- Afbeelding van een huis -
    -
  • -

    <%= house.f_houses_id.street %> <%= house.f_houses_id.house_nr %> <%= house.f_houses_id.nr_addition %>

    -
  • -
  • -

    <%= house.f_houses_id.postal_code %>

    -

    <%= house.f_houses_id.city %>

    -
  • -
  • -

    €<%= house.f_houses_id.price %>K.K.

    -
  • -
  • -

    <%= house.f_houses_id.m2 %> m2/<%= house.f_houses_id.rooms %> kamers

    -
  • -
- - -
- <% }) %> +
+ Afbeelding van een huis +
+

<%= house.f_houses_id.street %> <%= house.f_houses_id.house_nr %> <%= house.f_houses_id.nr_addition %>

+

<%= house.f_houses_id.postal_code %> <%= house.f_houses_id.city %>

+

€<%= house.f_houses_id.price %> K.K.

+

<%= house.f_houses_id.m2 %> m² / <%= house.f_houses_id.rooms %> kamers

+ +
+
+ + + + +<%- include('./partials/rating', { house: house }) %> + <% }) %>
+ \ No newline at end of file diff --git a/views/partials/rating.ejs b/views/partials/rating.ejs new file mode 100644 index 000000000..2c35fad16 --- /dev/null +++ b/views/partials/rating.ejs @@ -0,0 +1,111 @@ +
+

Beoordeel dit huis

+
+
+ Algemene beoordeling +
+ + + + + + + + + + +
+ 0 +
+ + +
+ Locatie +
+ + + + + + + + + + +
+ 0 +
+ +
+ Prijs +
+ + + + + + + + + + +
+ 0 +
+ +
+ Oppervlakte +
+ + + + + + + + + + +
+ 0 +
+ +
+ Ligging +
+ + + + + + + + + + +
+ 0 +
+ +
+ Kamers +
+ + + + + + + + + + +
+ 0 +
+ + + +
+ + \ No newline at end of file From 5b7eb6dc5a7c177f129e639fc5d0e7a5b2083c45 Mon Sep 17 00:00:00 2001 From: Naddybs <144009698+Naddybs@users.noreply.github.com> Date: Fri, 24 May 2024 09:46:31 +0200 Subject: [PATCH 5/7] Posten sterren beoordeling --- public/scripts/script.js | 66 --------------------------------------- public/styles/style.css | 10 +++--- server.js | 44 ++++++++++++++++++++++++-- views/index.ejs | 2 +- views/partials/rating.ejs | 22 ++----------- 5 files changed, 48 insertions(+), 96 deletions(-) diff --git a/public/scripts/script.js b/public/scripts/script.js index ac7504e64..e69de29bb 100644 --- a/public/scripts/script.js +++ b/public/scripts/script.js @@ -1,66 +0,0 @@ - -const fiveStarWrapper = document.querySelector("fieldset:nth-of-type(4) label:nth-of-type(5)"); -const fiveStarRadio = fiveStarWrapper.querySelector("input"); -const popAudio = document.querySelector("audio"); - -const yathzeeMetDeZessen = () => { - popAudio.play(); - - // create 1000 dots - for (let i = 0; i < 1000; i++) { - let dot = document.createElement("div"); - fiveStarWrapper.appendChild(dot); - - gsap - .timeline() - .set(dot, { - scale: "random(.5, 1)", - backgroundColor: "random([lime,white,deeppink,white,dodgerblue])", - }) - .to(dot, { - duration: 2, - delay: "random(0, .3)", - rotate:"random(-2160,2160)", - physics2D: { - velocity: "random(200, 600)", - angle: "random(250, 290)", - gravity: 600, - }, - scale: "random(1, 2)", - onComplete: removeDot, - onCompleteParams:[dot], - }) - .to(dot, { - duration: 1, - opacity:0, - },"<+=1"); - } -} - -removeDot = dot => { - // remove the dot when done - dot.remove(); -} - -fiveStarRadio.onchange = yathzeeMetDeZessen; - - - - document.querySelectorAll('.close-button').forEach(button => { - button.addEventListener('click', (event) => { - event.preventDefault(); - const popup = button.closest('.review-popup'); - popup.style.display = 'none'; - history.pushState("", document.title, window.location.pathname + window.location.search); - }); - }); - - window.addEventListener('hashchange', () => { - const hash = window.location.hash; - if (!hash) { - document.querySelectorAll('.review-popup').forEach(popup => { - popup.style.display = 'none'; - }); - } - }); - diff --git a/public/styles/style.css b/public/styles/style.css index 999aca732..55ca61ca2 100644 --- a/public/styles/style.css +++ b/public/styles/style.css @@ -198,7 +198,7 @@ img{ color: #555; } -.beoordeling-button { +.rating-button { background-color: #f59f00; color: white; border: none; @@ -211,7 +211,7 @@ img{ text-align: center; } -.beoordeling-button:hover { +.rating-button:hover { background-color: var(--primary-dk-blue); } /* -----------------------------house list section end------------------------------------ */ @@ -271,7 +271,7 @@ img{ line-height: 2.2em; } -.submit-ranking { +.submit-rating { background-color: #f59f00; color: white; border: none; @@ -284,9 +284,7 @@ img{ text-align: center; } -.submit-ranking:hover { +.submit-rating:hover { background-color: var(--primary-dk-blue); } - - /* -----------------------------rating section end------------------------------------ */ diff --git a/server.js b/server.js index 5db6c35e4..8dddea53e 100644 --- a/server.js +++ b/server.js @@ -30,18 +30,56 @@ fetchJson(apiUrl).then((apiData) => { app.use(express.static('public')); app.use(express.urlencoded({ extended: true })); + // Dit zijn arrays die worden gebruikt om de beoordelingen van de gebruiker op te slaan. + // arrays zijn een soort lijsten waarin je meerdere waarden kunt opslaan. In dit geval worden de beoordelingen van de gebruiker opgeslagen in de arrays. + const algemeen = []; + const locatie = []; + const prijs= []; + const oppervlakte = []; + const ligging = []; + const kamers = []; + // Dit zorgt ervoor dat de server de index.ejs file rendert wanneer er een get request wordt gedaan op de root van de server. // Vervolgens wordt de data van de API meegegeven aan de view zodat deze kan worden gebruikt in de ejs file. // houses: apiData.data.houses is de data die wordt meegegeven aan de view. Deze data is afkomstig van de API. + // algemeen, locatie, prijs, oppervlakte, ligging en kamers zijn de arrays die worden meegegeven aan de index.ejs file. + // Deze arrays bevatten de beoordelingen van de gebruiker. Die worden met de get request opgehaald en vervolgens meegegeven aan de index.ejs file. app.get('/', async (req, res) => { - res.render('index', { houses: apiData.data.houses }); + res.render('index', + { houses: apiData.data.houses, + algemeen: algemeen, + locatie: locatie, + prijs: prijs, + oppervlakte: oppervlakte, + ligging: ligging, + kamers: kamers}); }); + // Dit zorgt ervoor dat de server de submit-rating route afhandelt wanneer er een post request wordt gedaan op de /submit-rating route. + // De push methode wordt gebruikt om een nieuwe waarde toe te voegen aan een array. + // Tot slot wordt er een redirect gedaan naar de homepagina. + + app.post('/submit-rating', (req, res) => { + const ratings = req.body; + + console.log(ratings); + + // Dit voegt de gegevens toe aan de juiste arrays, dus de beoordelingen van de gebruiker worden hier opgeslagen in de arrays. + algemeen.push(ratings.algemeneBeoordeling); + locatie.push(ratings.locatie); + prijs.push(ratings.prijs); + oppervlakte.push(ratings.oppervlakte); + ligging.push(ratings.ligging); + kamers.push(ratings.kamers); + + // Stuur een response terug naar de client + res.redirect('/'); + }); + + // Dit zorgt ervoor dat de server start op poort 3000 en dat er een bericht wordt gelogd in de console wanneer de server is gestart. app.set('port', process.env.PORT || 3000); app.listen(app.get('port'), function () { console.log(`Application started on http://localhost:${app.get('port')}`); }); }); - -// ... \ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs index f8f6ec870..d850b234a 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -23,7 +23,7 @@

<%= house.f_houses_id.postal_code %> <%= house.f_houses_id.city %>

€<%= house.f_houses_id.price %> K.K.

<%= house.f_houses_id.m2 %> m² / <%= house.f_houses_id.rooms %> kamers

- + diff --git a/views/partials/rating.ejs b/views/partials/rating.ejs index 2c35fad16..e226d3a59 100644 --- a/views/partials/rating.ejs +++ b/views/partials/rating.ejs @@ -1,6 +1,6 @@

Beoordeel dit huis

-
+
Algemene beoordeling
@@ -18,7 +18,6 @@ 0
-
Locatie
@@ -87,24 +86,7 @@ 0
-
- Kamers -
- - - - - - - - - - -
- 0 -
- - +
From 803db01ffaa3f6143f2edbc47b2ca0d0c96c98ec Mon Sep 17 00:00:00 2001 From: Naddybs <144009698+Naddybs@users.noreply.github.com> Date: Sun, 26 May 2024 20:46:38 +0200 Subject: [PATCH 6/7] Rating section, vormgeving sterren verbeterd Animaties toegevoegd, sterren veranderd, schaduw effecten toegevoegd, gebruiker krijgt feedforward door kleurovergang --- public/scripts/script.js | 43 --------- public/styles/style.css | 186 +++++++++++++++++++++++++++++++++++++- server.js | 1 + views/partials/rating.ejs | 51 ++++++----- 4 files changed, 212 insertions(+), 69 deletions(-) diff --git a/public/scripts/script.js b/public/scripts/script.js index 139084815..8b1378917 100644 --- a/public/scripts/script.js +++ b/public/scripts/script.js @@ -1,44 +1 @@ -const fiveStarWrapper = document.querySelector("fieldset:nth-of-type(4) label:nth-of-type(5)"); -const fiveStarRadio = fiveStarWrapper.querySelector("input"); -const popAudio = document.querySelector("audio"); -const yathzeeMetDeZessen = () => { - popAudio.play(); - - // create 1000 dots - for (let i = 0; i < 1000; i++) { - let dot = document.createElement("div"); - fiveStarWrapper.appendChild(dot); - - gsap - .timeline() - .set(dot, { - scale: "random(.5, 1)", - backgroundColor: "random([lime,white,deeppink,white,dodgerblue])", - }) - .to(dot, { - duration: 2, - delay: "random(0, .3)", - rotate:"random(-2160,2160)", - physics2D: { - velocity: "random(200, 600)", - angle: "random(250, 290)", - gravity: 600, - }, - scale: "random(1, 2)", - onComplete: removeDot, - onCompleteParams:[dot], - }) - .to(dot, { - duration: 1, - opacity:0, - },"<+=1"); - } -} - -removeDot = dot => { - // remove the dot when done - dot.remove(); -} - -fiveStarRadio.onchange = yathzeeMetDeZessen; \ No newline at end of file diff --git a/public/styles/style.css b/public/styles/style.css index eb4f9d2ba..db0c024fd 100644 --- a/public/styles/style.css +++ b/public/styles/style.css @@ -131,7 +131,7 @@ h2{ transition: background-color 0.3s; transform: scale(1.1); } -} + .house-list { display: flex; @@ -145,3 +145,187 @@ h2{ img{ max-width: 20em; } +.house-card { + background: white; + border-radius: 10px; + overflow: hidden; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + max-width: 300px; + display: flex; + flex-direction: column; + transition: transform 0.3s; + & img { + width: 100%; + height: auto; + } +} + +.house-card:hover { + transform: translateY(-15px); +} + +.house-details { + padding: 1em; + display: flex; + flex-direction: column; + align-items: flex-start; +} + +.house-details .house-title { + font-size: 1.5em; + color: #333; +} + +.house-details .house-location, +.house-details .house-price, +.house-details .house-size { + font-size: 1em; + margin: 0.5em 0; +} + +.house-details .house-location { + color: #777; +} + +.house-details .house-price { + font-size: 1.2em; + color: #f59f00; +} + +.house-details .house-size { + color: #555; +} + +.beoordeling-button { + background-color: #f59f00; + color: white; + border: none; + border-radius: 5px; + padding: 0.75em 1.5em; + margin-top: 1em; + cursor: pointer; + transition: background-color 0.3s; + align-self: stretch; /* Dit zorgt ervoor dat de knop de volledige breedte inneemt */ + text-align: center; +} + +.beoordeling-button:hover { + background-color: var(--primary-dk-blue); +} +/* -----------------------------house list section end------------------------------------ */ + +/* -----------------------------rating section------------------------------------ */ + +/* Algemene stijl voor de beoordelingssectie */ +.beoordeling { + max-width: 600px; + margin: auto; + padding: 2em; + background-color: var(--primary-lt-blue); + border-radius: 10px; +} + +/* Stijl voor de groep van beoordelingen */ +.rating-group { + margin-bottom: 1em; + display: flex; + justify-content: space-between; + align-items: center; +} + +/* Stijl voor de titel van de beoordeling */ +.rating-title { + flex: 1; + font-size: 1.2em; +} + +/* Stijl voor de sterren */ +.rating { + display: flex; + flex-direction: row-reverse; + justify-content: flex-end; + position: relative; + margin-left: 1em; +} + +/* Verbergt de standaard radioknoppen */ +.rating input[type="radio"] { + display: none; +} + +/* Stijl voor de labels van de sterren */ +.rating label { + font-size: 2em; + color: #ccc; + cursor: pointer; + transition: color 0.3s, transform 0.3s; + text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); /* Voegt een schaduweffect toe aan de tekst van de sterren */ +} + +/* Kleur van de sterren bij hover en selectie */ +.rating label:hover, +.rating input[type="radio"]:checked ~ label { + color: #f59f00; /* Verandert de kleur van de sterren bij hover of selectie */ + transform: scale(1.2); /* Maakt de sterren groter bij hover of selectie */ +} + +/* Kleurstijlen voor de checked sterren */ +.rating input[type="radio"]:nth-of-type(5):checked ~ label { + color: hsl(354, 92%, 46%); /* Rood */ +} + +.rating input[type="radio"]:nth-of-type(4):checked ~ label { + color: hsl(27, 88%, 42%); /* Oranje */ +} + +.rating input[type="radio"]:nth-of-type(3):checked ~ label { + color: hwb(53 33% 10%); /* Geel */ +} + +.rating input[type="radio"]:nth-of-type(2):checked ~ label { + color: hwb(85 4% 24%); /* Groen-geel */ +} + +.rating input[type="radio"]:nth-of-type(1):checked ~ label { + color: hsl(120, 88%, 65%); /* Groen */ +} + +/* Stijl voor de beoordelingswaarde */ +.rating-value { + font-size: 1.5em; + margin-left: 10px; + color: #333; + font-weight: bold; + line-height: 2.2em; +} + +/* Stijl voor de knop voor het indienen van de beoordeling */ +.submit-ranking { + background-color: #f59f00; + color: white; + border: none; + border-radius: 5px; + padding: 0.75em 1.5em; + cursor: pointer; + transition: background-color 0.3s; + display: block; + width: 100%; + text-align: center; +} + +/* Animatie voor het veranderen van kleur en grootte van de sterren */ +.rating label:hover, +.rating input[type="radio"]:checked ~ label { + animation: pulse 0.5s ease; /* Dit voegt een pulse animatie toe aan de sterren bij hover of selectie */ +} + +/* Keyframes voor de pulse animatie, groter worden */ +@keyframes pulse { + 0%, 100% { + transform: scale(1); + } + 50% { + transform: scale(1.2); + } +} +/* -----------------------------rating section end------------------------------------ \ No newline at end of file diff --git a/server.js b/server.js index 8dddea53e..631528d8a 100644 --- a/server.js +++ b/server.js @@ -29,6 +29,7 @@ fetchJson(apiUrl).then((apiData) => { app.set('views', 'views'); app.use(express.static('public')); app.use(express.urlencoded({ extended: true })); + app.use(bodyParser.json()); // Dit zijn arrays die worden gebruikt om de beoordelingen van de gebruiker op te slaan. // arrays zijn een soort lijsten waarin je meerdere waarden kunt opslaan. In dit geval worden de beoordelingen van de gebruiker opgeslagen in de arrays. diff --git a/views/partials/rating.ejs b/views/partials/rating.ejs index e226d3a59..8d78ce340 100644 --- a/views/partials/rating.ejs +++ b/views/partials/rating.ejs @@ -5,15 +5,15 @@ Algemene beoordeling
- + - + - + - + - +
0 @@ -22,15 +22,15 @@ Locatie
- + - + - + - + - +
0 @@ -39,15 +39,15 @@ Prijs
- + - + - + - + - +
0 @@ -56,15 +56,15 @@ Oppervlakte
- + - + - + - + - +
0 @@ -73,20 +73,21 @@ Ligging
- + - + - + - + - +
0 + From 08d7f6b0ed25f7732bdf52eaee91c97ef406b2b2 Mon Sep 17 00:00:00 2001 From: Naddybs <144009698+Naddybs@users.noreply.github.com> Date: Mon, 27 May 2024 12:24:07 +0200 Subject: [PATCH 7/7] Standaard form gedrag aangepast, succesvol posten --- package-lock.json | 87 ++++++++++++++++++++++++++++++++++++++- package.json | 4 +- public/scripts/script.js | 76 ++++++++++++++++++++++++++++++++++ public/styles/style.css | 46 ++++++++++++++++++++- server.js | 20 +++++---- views/partials/head.ejs | 1 + views/partials/rating.ejs | 3 +- 7 files changed, 223 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 449052616..892bf419c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,10 @@ "version": "1.0.0", "license": "MIT", "dependencies": { + "body": "^5.1.0", "ejs": "^3.1.10", - "express": "^4.19.2" + "express": "^4.19.2", + "parser": "^0.1.4" }, "devDependencies": { "nodemon": "^3.1.0" @@ -82,6 +84,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/body": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", + "integrity": "sha512-chUsBxGRtuElD6fmw1gHLpvnKdVLK302peeFa9ZqAEk8TyzZ3fygLyUEDDPTJvL9+Bor0dIwn6ePOsRM2y0zQQ==", + "dependencies": { + "continuable-cache": "^0.3.1", + "error": "^7.0.0", + "raw-body": "~1.1.0", + "safe-json-parse": "~1.0.1" + } + }, "node_modules/body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", @@ -105,6 +118,23 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/body/node_modules/bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", + "integrity": "sha512-/x68VkHLeTl3/Ll8IvxdwzhrT+IyKc52e/oyHhA2RwqPqswSnjVbSddfPRwAsJtbilMAPSRWwAlpxdYsSWOTKQ==" + }, + "node_modules/body/node_modules/raw-body": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", + "integrity": "sha512-WmJJU2e9Y6M5UzTOkHaM7xJGAPQD8PNzx3bAd2+uhZAim6wDk6dAZxPVYLF67XhbR4hmKGh33Lpmh4XWrCH5Mg==", + "dependencies": { + "bytes": "1", + "string_decoder": "0.10" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -231,6 +261,11 @@ "node": ">= 0.6" } }, + "node_modules/continuable-cache": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", + "integrity": "sha512-TF30kpKhTH8AGCG3dut0rdd/19B7Z+qCnrMoBLpyQu/2drZdNrrpcjPEoJeSVsQM+8KmWG5O56oPDjSSUsuTyA==" + }, "node_modules/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", @@ -285,6 +320,11 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/disect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/disect/-/disect-1.1.1.tgz", + "integrity": "sha512-rr2Ym8FSAoqAJ1KfpUiQ/Io01HP0LZPHBuppbFsHozmSNf+YwrvyD5pm5tMTUApJFNwD7HeWJ5DGldSugScukA==" + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -312,6 +352,14 @@ "node": ">= 0.8" } }, + "node_modules/error": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz", + "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==", + "dependencies": { + "string-template": "~0.2.1" + } + }, "node_modules/es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", @@ -851,6 +899,17 @@ "node": ">= 0.8" } }, + "node_modules/parser": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/parser/-/parser-0.1.4.tgz", + "integrity": "sha512-f6EM/mBtPzmIh96MpcbePfhkBOYRmLYWuOukJqMysMlvjp4s2MQSSQnFEekd9GV4JGTnDJ2uFt3Ztcqc9wCMJg==", + "dependencies": { + "tokenizer": "*" + }, + "engines": { + "node": "0.4-0.9" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -961,6 +1020,11 @@ } ] }, + "node_modules/safe-json-parse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", + "integrity": "sha512-o0JmTu17WGUaUOHa1l0FPGXKBfijbxK6qoHzlkihsDXxzBHvJcA7zgviKR92Xs841rX9pK16unfphLq0/KqX7A==" + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -1078,6 +1142,16 @@ "node": ">= 0.8" } }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, + "node_modules/string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -1109,6 +1183,17 @@ "node": ">=0.6" } }, + "node_modules/tokenizer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/tokenizer/-/tokenizer-1.1.2.tgz", + "integrity": "sha512-c/EYsBwEW/EX28q44UaSrJ9o5M2aI+N/xdJJ4Zl7dNq76OmWQHhmXH0T8DJQNjVYPc7NclV2CZQfyeUMfnEu/A==", + "dependencies": { + "disect": "~1.1.0" + }, + "engines": { + "node": "0.10.x" + } + }, "node_modules/touch": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", diff --git a/package.json b/package.json index 7045cc469..e296bc298 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,10 @@ }, "homepage": "https://github.com/fdnd-task/pleasurable-ui#readme", "dependencies": { + "body": "^5.1.0", "ejs": "^3.1.10", - "express": "^4.19.2" + "express": "^4.19.2", + "parser": "^0.1.4" }, "devDependencies": { "nodemon": "^3.1.0" diff --git a/public/scripts/script.js b/public/scripts/script.js index 8b1378917..64b320127 100644 --- a/public/scripts/script.js +++ b/public/scripts/script.js @@ -1 +1,77 @@ +// De domcontentloaded event listener zorgt ervoor dat de code wordt uitgevoerd wanneer de DOM is geladen. +// De querySelectorAll functie zoekt naar alle formulieren die beginnen met de id scoreForm-. + +// De forEach methode wordt gebruikt om door elk formulier te loopen. +// In de forEach methode wordt een event listener toegevoegd aan elk formulier. +// De querySelectorAll functie zoekt naar alle radio buttons binnen de rating-group. + +// De forEach methode wordt gebruikt om door elke radio button te loopen. +// De addEventListener methode wordt gebruikt om een event listener toe te voegen aan elke radio button. +// De change event wordt gebruikt om te controleren of de waarde van de radio button is veranderd. +// De textContent eigenschap wordt gebruikt om de waarde van de radio button weer te geven in de rating-value div. + +document.addEventListener('DOMContentLoaded', function() { + const forms = document.querySelectorAll('form[id^="scoreForm-"]'); + + forms.forEach(form => { + const ratingGroups = form.querySelectorAll('.rating-group'); + + ratingGroups.forEach(group => { + const radios = group.querySelectorAll('input[type="radio"]'); + const ratingValue = group.querySelector('.rating-value'); + + radios.forEach(radio => { + radio.addEventListener('change', function() { + ratingValue.textContent = this.value; + }); + }); + }); + }); +}); + +// Selecteer alle formulieren +let forms = document.querySelectorAll('.scoreForm'); + +// Loop door alle formulieren +forms.forEach(function (form) { + // Luister naar het submit event + form.addEventListener('submit', function (event) { + + // Het this object refereert hier naar het formulier zelf + // Lees de data van het formulier in + let data = new FormData(this); + + // Voeg een extra eigenschap aan de formulierdata toe + // Deze gaan we server-side gebruiken om iets anders terug te sturen + data.append('enhanced', true); + + // Console.log om te controleren of de beoordelingsgegevens correct worden opgehaald + console.log(data.get('beoordeling')); + + // Gebruik een client-side fetch om een POST te doen naar de server + fetch(this.action, { + // Gebruik de juiste method (waarschijnlijk POST) + method: this.method, + // Geef de data van het formulier mee als body + body: new URLSearchParams(data), + }) + .then(function (response) { + // Als de server een antwoord geeft, krijgen we een stream terug + // We willen hiervan de text gebruiken, wat in dit geval HTML teruggeeft + return response.text(); + }) + .then(function (responseHTML) { + // Update de DOM met de ontvangen HTML + document.querySelector('.showResults').innerHTML = responseHTML; + }) + .catch(function (error) { + // Handel eventuele fouten af + console.error('Error:', error); + }); + + // Voorkom het standaardgedrag van het formulier (pagina herladen) + event.preventDefault(); + }); +}); + diff --git a/public/styles/style.css b/public/styles/style.css index db0c024fd..d63c86a16 100644 --- a/public/styles/style.css +++ b/public/styles/style.css @@ -300,7 +300,7 @@ img{ } /* Stijl voor de knop voor het indienen van de beoordeling */ -.submit-ranking { +/* .submit-ranking { background-color: #f59f00; color: white; border: none; @@ -311,8 +311,38 @@ img{ display: block; width: 100%; text-align: center; +} */ +/* Standaardstijl voor de knop */ +.submit-rating { + background-color: #f59f00; + color: white; + border: none; + border-radius: 5px; + padding: 0.75em 1.5em; + cursor: pointer; + transition: background-color 0.3s, transform 0.3s; + display: block; + width: 100%; + text-align: center; +} + +/* Stijl voor hover-state van de knop */ +.submit-rating:hover { + background-color: #e68a00; /* Donkerdere tint van de primaire kleur */ +} + +/* Stijl voor active-state van de knop */ +.submit-rating:active { + transform: translateY(1px); /* Geef een subtiele klikanimatie */ } +/* Stijl voor focus-state van de knop */ +.submit-rating:focus { + outline: none; /* Verwijder de standaard focus-ring */ + box-shadow: 0 0 0 3px rgba(255, 153, 0, 0.5); /* Voeg een gloed toe rond de knop bij focus */ +} + + /* Animatie voor het veranderen van kleur en grootte van de sterren */ .rating label:hover, .rating input[type="radio"]:checked ~ label { @@ -328,4 +358,16 @@ img{ transform: scale(1.2); } } -/* -----------------------------rating section end------------------------------------ \ No newline at end of file + +/* .beoordeling { + display: none; +} + +.beoordeling.show-hide-ranking { + display: block; +} */ + +/* -----------------------------rating section end------------------------------------/ */ + + + diff --git a/server.js b/server.js index 631528d8a..0923bb52e 100644 --- a/server.js +++ b/server.js @@ -6,6 +6,7 @@ import express from 'express' const app = express() const port = 3000 console.log('server opent op poort 3000') +// const bodyParser = require('body-parser'); // Dit houdt in dat je de fetchJson functie importeert vanuit het bestand fetch-json.js en deze vervolgens gebruikt om data op te halen van de server. import fetchJson from './helpers/fetch-json.js' @@ -16,21 +17,22 @@ const apiUrl = `https://fdnd-agency.directus.app/items/f_list/${9}?fields=*.*.*` console.log(apiUrl) +// Hiermee zet je de view engine van de express applicatie op ejs en zorg je ervoor dat de views in de map views worden opgeslagen. +// Daarnaast maak je de public map statisch zodat de bestanden in deze map kunnen worden opgehaald. +// Ook gebruik je de express.urlencoded middleware om het werken met request data makkelijker te maken. +app.set('view engine', 'ejs'); +app.set('views', 'views'); +app.use(express.static('public')); +app.use(express.urlencoded({ extended: true })); +// app.use(bodyParser.json()); + + // ... // Dit zorgt ervoor dat de fetchJson functie wordt aangeroepen met de apiUrl als parameter. Een parameter is een waarde die je meegeeft aan een functie. // Dit houdt in dat de apiUrl wordt gebruikt om data op te halen van de server. fetchJson(apiUrl).then((apiData) => { console.log(apiData); - // Hiermee zet je de view engine van de express applicatie op ejs en zorg je ervoor dat de views in de map views worden opgeslagen. - // Daarnaast maak je de public map statisch zodat de bestanden in deze map kunnen worden opgehaald. - // Ook gebruik je de express.urlencoded middleware om het werken met request data makkelijker te maken. - app.set('view engine', 'ejs'); - app.set('views', 'views'); - app.use(express.static('public')); - app.use(express.urlencoded({ extended: true })); - app.use(bodyParser.json()); - // Dit zijn arrays die worden gebruikt om de beoordelingen van de gebruiker op te slaan. // arrays zijn een soort lijsten waarin je meerdere waarden kunt opslaan. In dit geval worden de beoordelingen van de gebruiker opgeslagen in de arrays. const algemeen = []; diff --git a/views/partials/head.ejs b/views/partials/head.ejs index 5cb9584be..9ddb19ab4 100644 --- a/views/partials/head.ejs +++ b/views/partials/head.ejs @@ -5,6 +5,7 @@ Funda favorieten redesign +
diff --git a/views/partials/rating.ejs b/views/partials/rating.ejs index 8d78ce340..6a7640322 100644 --- a/views/partials/rating.ejs +++ b/views/partials/rating.ejs @@ -1,6 +1,6 @@

Beoordeel dit huis

-
+
Algemene beoordeling
@@ -89,6 +89,7 @@ +
\ No newline at end of file