mirror of
https://github.com/ThisIsBenny/wishlist-app.git
synced 2025-06-07 05:57:41 +00:00
#3 Login page added to set api key
Signed-off-by: Benny Samir Hierl <bennysamir@posteo.de>
This commit is contained in:
parent
a362b67ec6
commit
c15b97d08a
12 changed files with 342 additions and 22 deletions
139
package-lock.json
generated
139
package-lock.json
generated
|
@ -17,9 +17,11 @@
|
||||||
"fastify-helmet": "^7.0.1",
|
"fastify-helmet": "^7.0.1",
|
||||||
"fastify-static": "^4.5.0",
|
"fastify-static": "^4.5.0",
|
||||||
"open-graph-scraper": "^4.11.0",
|
"open-graph-scraper": "^4.11.0",
|
||||||
|
"vee-validate": "^4.5.8",
|
||||||
"vue": "^3.2.27",
|
"vue": "^3.2.27",
|
||||||
"vue-i18n": "^9.2.0-beta.30",
|
"vue-i18n": "^9.2.0-beta.30",
|
||||||
"vue-router": "^4.0.12"
|
"vue-router": "^4.0.12",
|
||||||
|
"yup": "^0.32.11"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rushstack/eslint-patch": "^1.1.0",
|
"@rushstack/eslint-patch": "^1.1.0",
|
||||||
|
@ -158,6 +160,17 @@
|
||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@babel/runtime": {
|
||||||
|
"version": "7.17.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz",
|
||||||
|
"integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==",
|
||||||
|
"dependencies": {
|
||||||
|
"regenerator-runtime": "^0.13.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@babel/types": {
|
"node_modules/@babel/types": {
|
||||||
"version": "7.16.8",
|
"version": "7.16.8",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz",
|
||||||
|
@ -534,6 +547,11 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/lodash": {
|
||||||
|
"version": "4.14.178",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz",
|
||||||
|
"integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw=="
|
||||||
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "16.11.21",
|
"version": "16.11.21",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.21.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.21.tgz",
|
||||||
|
@ -4473,8 +4491,12 @@
|
||||||
"node_modules/lodash": {
|
"node_modules/lodash": {
|
||||||
"version": "4.17.21",
|
"version": "4.17.21",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
"dev": true
|
},
|
||||||
|
"node_modules/lodash-es": {
|
||||||
|
"version": "4.17.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||||
|
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
|
||||||
},
|
},
|
||||||
"node_modules/lodash.merge": {
|
"node_modules/lodash.merge": {
|
||||||
"version": "4.6.2",
|
"version": "4.6.2",
|
||||||
|
@ -4640,6 +4662,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
},
|
},
|
||||||
|
"node_modules/nanoclone": {
|
||||||
|
"version": "0.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz",
|
||||||
|
"integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA=="
|
||||||
|
},
|
||||||
"node_modules/nanoid": {
|
"node_modules/nanoid": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
|
||||||
|
@ -5459,6 +5486,11 @@
|
||||||
"asap": "~2.0.3"
|
"asap": "~2.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/property-expr": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA=="
|
||||||
|
},
|
||||||
"node_modules/proxy-addr": {
|
"node_modules/proxy-addr": {
|
||||||
"version": "2.0.7",
|
"version": "2.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||||
|
@ -5743,6 +5775,11 @@
|
||||||
"node": ">=8.10.0"
|
"node": ">=8.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/regenerator-runtime": {
|
||||||
|
"version": "0.13.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
|
||||||
|
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
|
||||||
|
},
|
||||||
"node_modules/regexpp": {
|
"node_modules/regexpp": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
|
||||||
|
@ -6436,6 +6473,11 @@
|
||||||
"integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=",
|
"integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/toposort": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
|
||||||
|
"integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA="
|
||||||
|
},
|
||||||
"node_modules/touch": {
|
"node_modules/touch": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
|
||||||
|
@ -6754,6 +6796,17 @@
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vee-validate": {
|
||||||
|
"version": "4.5.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-4.5.8.tgz",
|
||||||
|
"integrity": "sha512-XZx2J93rlET49CdIIoxG9R6wQNoT3RxUUw9ar3QbIhczpzbtlm4BQ+TpCA9DoYHKFlApcXnE28WU7m4quoPsCA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@vue/devtools-api": "^6.0.0-beta.15"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vue": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "2.7.13",
|
"version": "2.7.13",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-2.7.13.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-2.7.13.tgz",
|
||||||
|
@ -7374,6 +7427,23 @@
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yup": {
|
||||||
|
"version": "0.32.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz",
|
||||||
|
"integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.15.4",
|
||||||
|
"@types/lodash": "^4.14.175",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
|
"nanoclone": "^0.2.1",
|
||||||
|
"property-expr": "^2.0.4",
|
||||||
|
"toposort": "^2.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -7456,6 +7526,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.10.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.10.tgz",
|
||||||
"integrity": "sha512-Sm/S9Or6nN8uiFsQU1yodyDW3MWXQhFeqzMPM+t8MJjM+pLsnFVxFZzkpXKvUXh+Gz9cbMoYYs484+Jw/NTEFQ=="
|
"integrity": "sha512-Sm/S9Or6nN8uiFsQU1yodyDW3MWXQhFeqzMPM+t8MJjM+pLsnFVxFZzkpXKvUXh+Gz9cbMoYYs484+Jw/NTEFQ=="
|
||||||
},
|
},
|
||||||
|
"@babel/runtime": {
|
||||||
|
"version": "7.17.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz",
|
||||||
|
"integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==",
|
||||||
|
"requires": {
|
||||||
|
"regenerator-runtime": "^0.13.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@babel/types": {
|
"@babel/types": {
|
||||||
"version": "7.16.8",
|
"version": "7.16.8",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz",
|
||||||
|
@ -7765,6 +7843,11 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/lodash": {
|
||||||
|
"version": "4.14.178",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz",
|
||||||
|
"integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw=="
|
||||||
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "16.11.21",
|
"version": "16.11.21",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.21.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.21.tgz",
|
||||||
|
@ -10675,8 +10758,12 @@
|
||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "4.17.21",
|
"version": "4.17.21",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
"dev": true
|
},
|
||||||
|
"lodash-es": {
|
||||||
|
"version": "4.17.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||||
|
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
|
||||||
},
|
},
|
||||||
"lodash.merge": {
|
"lodash.merge": {
|
||||||
"version": "4.6.2",
|
"version": "4.6.2",
|
||||||
|
@ -10799,6 +10886,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
},
|
},
|
||||||
|
"nanoclone": {
|
||||||
|
"version": "0.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz",
|
||||||
|
"integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA=="
|
||||||
|
},
|
||||||
"nanoid": {
|
"nanoid": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
|
||||||
|
@ -11400,6 +11492,11 @@
|
||||||
"asap": "~2.0.3"
|
"asap": "~2.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"property-expr": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA=="
|
||||||
|
},
|
||||||
"proxy-addr": {
|
"proxy-addr": {
|
||||||
"version": "2.0.7",
|
"version": "2.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||||
|
@ -11642,6 +11739,11 @@
|
||||||
"picomatch": "^2.2.1"
|
"picomatch": "^2.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"regenerator-runtime": {
|
||||||
|
"version": "0.13.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
|
||||||
|
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
|
||||||
|
},
|
||||||
"regexpp": {
|
"regexpp": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
|
||||||
|
@ -12160,6 +12262,11 @@
|
||||||
"integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=",
|
"integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"toposort": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
|
||||||
|
"integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA="
|
||||||
|
},
|
||||||
"touch": {
|
"touch": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
|
||||||
|
@ -12390,6 +12497,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||||
},
|
},
|
||||||
|
"vee-validate": {
|
||||||
|
"version": "4.5.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-4.5.8.tgz",
|
||||||
|
"integrity": "sha512-XZx2J93rlET49CdIIoxG9R6wQNoT3RxUUw9ar3QbIhczpzbtlm4BQ+TpCA9DoYHKFlApcXnE28WU7m4quoPsCA==",
|
||||||
|
"requires": {
|
||||||
|
"@vue/devtools-api": "^6.0.0-beta.15"
|
||||||
|
}
|
||||||
|
},
|
||||||
"vite": {
|
"vite": {
|
||||||
"version": "2.7.13",
|
"version": "2.7.13",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-2.7.13.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-2.7.13.tgz",
|
||||||
|
@ -12844,6 +12959,20 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||||
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
|
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
|
||||||
|
},
|
||||||
|
"yup": {
|
||||||
|
"version": "0.32.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz",
|
||||||
|
"integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.15.4",
|
||||||
|
"@types/lodash": "^4.14.175",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
|
"nanoclone": "^0.2.1",
|
||||||
|
"property-expr": "^2.0.4",
|
||||||
|
"toposort": "^2.0.2"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,11 @@
|
||||||
"fastify-helmet": "^7.0.1",
|
"fastify-helmet": "^7.0.1",
|
||||||
"fastify-static": "^4.5.0",
|
"fastify-static": "^4.5.0",
|
||||||
"open-graph-scraper": "^4.11.0",
|
"open-graph-scraper": "^4.11.0",
|
||||||
|
"vee-validate": "^4.5.8",
|
||||||
"vue": "^3.2.27",
|
"vue": "^3.2.27",
|
||||||
"vue-i18n": "^9.2.0-beta.30",
|
"vue-i18n": "^9.2.0-beta.30",
|
||||||
"vue-router": "^4.0.12"
|
"vue-router": "^4.0.12",
|
||||||
|
"yup": "^0.32.11"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rushstack/eslint-patch": "^1.1.0",
|
"@rushstack/eslint-patch": "^1.1.0",
|
||||||
|
|
|
@ -1,11 +1,24 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
defineProps<{
|
defineProps({
|
||||||
icon?: any
|
icon: {
|
||||||
}>()
|
type: Object,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: 'secondary',
|
||||||
|
},
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<button
|
<button
|
||||||
class="inline-flex w-fit flex-row items-center justify-center rounded-md border-2 border-stone-200 py-1 px-2 text-stone-500 hover:bg-stone-100 dark:border-stone-700 dark:text-white/70 dark:hover:bg-stone-700"
|
class="inline-flex w-fit flex-row items-center justify-center rounded-md border-2 py-1 px-2 disabled:cursor-not-allowed disabled:opacity-60"
|
||||||
|
:class="{
|
||||||
|
'border-0 bg-cyan-600 text-white disabled:bg-cyan-600 disabled:hover:bg-cyan-600 dark:bg-cyan-600 dark:hover:bg-cyan-600 dark:disabled:hover:bg-cyan-600':
|
||||||
|
mode === 'primary',
|
||||||
|
'border-stone-200 text-stone-500 hover:bg-stone-100 disabled:hover:bg-white dark:border-stone-700 dark:text-white/70 dark:hover:bg-stone-700 disabled:hover:dark:bg-stone-900':
|
||||||
|
mode === 'secondary',
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
<component v-if="icon" :is="icon" class="mr-1 h-4 w-4" />
|
<component v-if="icon" :is="icon" class="mr-1 h-4 w-4" />
|
||||||
<span>
|
<span>
|
||||||
|
|
56
src/components/TextInput.vue
Normal file
56
src/components/TextInput.vue
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<template>
|
||||||
|
<div class="relative mb-8">
|
||||||
|
<label class="mb-1 block w-full" :for="name">{{ label }}</label>
|
||||||
|
<input
|
||||||
|
class="h-12 w-full rounded-md border-2 border-solid border-stone-300 bg-transparent px-2 outline-none dark:border-stone-700"
|
||||||
|
:class="{ 'border-rose-500': !!errorMessage }"
|
||||||
|
:name="name"
|
||||||
|
:id="name"
|
||||||
|
:type="type"
|
||||||
|
:value="inputValue"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
@input="handleChange"
|
||||||
|
@blur="handleBlur"
|
||||||
|
v-bind="$attrs"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<p class="absolute mt-2 text-sm text-rose-500" v-show="errorMessage">
|
||||||
|
{{ errorMessage }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useField } from 'vee-validate'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'text',
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const {
|
||||||
|
value: inputValue,
|
||||||
|
errorMessage,
|
||||||
|
handleBlur,
|
||||||
|
handleChange,
|
||||||
|
} = useField(props.name, undefined, {
|
||||||
|
initialValue: props.value,
|
||||||
|
})
|
||||||
|
</script>
|
15
src/composables/useAuth.ts
Normal file
15
src/composables/useAuth.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { readonly } from 'vue'
|
||||||
|
import { useStorage } from '@vueuse/core'
|
||||||
|
|
||||||
|
const state = useStorage('auth-token', '')
|
||||||
|
|
||||||
|
const setToken = (token: string): void => {
|
||||||
|
state.value = token
|
||||||
|
}
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
return {
|
||||||
|
setToken,
|
||||||
|
token: readonly(state),
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,17 @@
|
||||||
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios'
|
import axios, {
|
||||||
|
AxiosError,
|
||||||
|
AxiosInstance,
|
||||||
|
AxiosRequestConfig,
|
||||||
|
AxiosResponse,
|
||||||
|
} from 'axios'
|
||||||
import { apiConfig } from '@/config'
|
import { apiConfig } from '@/config'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import router from '../router'
|
import router from '../router'
|
||||||
|
import useAuth from './useAuth'
|
||||||
|
|
||||||
|
const { token } = useAuth()
|
||||||
const isLoading = ref(false)
|
const isLoading = ref(false)
|
||||||
const error = ref(null)
|
const error = ref<any | null>(null)
|
||||||
|
|
||||||
const config: AxiosRequestConfig = {
|
const config: AxiosRequestConfig = {
|
||||||
baseURL: apiConfig.baseURL,
|
baseURL: apiConfig.baseURL,
|
||||||
|
@ -13,12 +20,20 @@ const config: AxiosRequestConfig = {
|
||||||
const client: AxiosInstance = axios.create(config)
|
const client: AxiosInstance = axios.create(config)
|
||||||
|
|
||||||
export const requestInterceptor = client.interceptors.request.use(
|
export const requestInterceptor = client.interceptors.request.use(
|
||||||
function (config) {
|
(config: AxiosRequestConfig): AxiosRequestConfig => {
|
||||||
|
if (!config) {
|
||||||
|
config = {}
|
||||||
|
}
|
||||||
|
if (!config.headers) {
|
||||||
|
config.headers = {}
|
||||||
|
}
|
||||||
isLoading.value = true
|
isLoading.value = true
|
||||||
error.value = null
|
error.value = null
|
||||||
|
config.headers.Authorization = token.value ? `Bearer ${token.value}` : ''
|
||||||
|
|
||||||
return config
|
return config
|
||||||
},
|
},
|
||||||
function (err) {
|
(err: AxiosError): Promise<AxiosError> => {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
error.value = err
|
error.value = err
|
||||||
return Promise.reject(err)
|
return Promise.reject(err)
|
||||||
|
@ -26,11 +41,11 @@ export const requestInterceptor = client.interceptors.request.use(
|
||||||
)
|
)
|
||||||
|
|
||||||
export const responseInterceptor = client.interceptors.response.use(
|
export const responseInterceptor = client.interceptors.response.use(
|
||||||
function (response) {
|
(response: AxiosResponse): AxiosResponse => {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
return response
|
return response
|
||||||
},
|
},
|
||||||
function (err) {
|
(err: AxiosError): Promise<AxiosError> => {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
if (err.response?.status === 404) {
|
if (err.response?.status === 404) {
|
||||||
router.push({ name: 'notFound' })
|
router.push({ name: 'notFound' })
|
||||||
|
|
|
@ -16,6 +16,19 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"pages": {
|
"pages": {
|
||||||
|
"login-view": {
|
||||||
|
"main": {
|
||||||
|
"title": {
|
||||||
|
"text": "Anmelden"
|
||||||
|
},
|
||||||
|
"form": {
|
||||||
|
"api-key": {
|
||||||
|
"placeholder": "API-Key",
|
||||||
|
"error-requried": "API-Key wird benötigt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"detail-view": {
|
"detail-view": {
|
||||||
"main": {
|
"main": {
|
||||||
"empty-list": {
|
"empty-list": {
|
||||||
|
|
|
@ -16,6 +16,19 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"pages": {
|
"pages": {
|
||||||
|
"login-view": {
|
||||||
|
"main": {
|
||||||
|
"title": {
|
||||||
|
"text": "Login"
|
||||||
|
},
|
||||||
|
"form": {
|
||||||
|
"api-key": {
|
||||||
|
"placeholder": "API-Key",
|
||||||
|
"error-requried": "API-Key is required"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"detail-view": {
|
"detail-view": {
|
||||||
"main": {
|
"main": {
|
||||||
"empty-list": {
|
"empty-list": {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
import HomeView from '@/views/HomeView.vue'
|
import HomeView from '@/views/HomeView.vue'
|
||||||
|
import LoginView from '@/views/LoginView.vue'
|
||||||
import DetailView from '@/views/DetailView.vue'
|
import DetailView from '@/views/DetailView.vue'
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
|
@ -10,6 +11,11 @@ const router = createRouter({
|
||||||
name: 'home',
|
name: 'home',
|
||||||
component: HomeView,
|
component: HomeView,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/login',
|
||||||
|
name: 'login',
|
||||||
|
component: LoginView,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/:slug',
|
path: '/:slug',
|
||||||
name: 'detail',
|
name: 'detail',
|
||||||
|
@ -18,7 +24,7 @@ const router = createRouter({
|
||||||
{
|
{
|
||||||
name: 'notFound',
|
name: 'notFound',
|
||||||
path: '/:pathMatch(.*)*',
|
path: '/:pathMatch(.*)*',
|
||||||
component: () => import('@/views/NotFound.vue'),
|
component: () => import('@/views/NotFoundView.vue'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
|
@ -69,6 +69,7 @@ const bought = async (item: WishlistItemType): Promise<void> => {
|
||||||
class="flex flex-col flex-wrap items-center justify-center text-center text-xl text-gray-600/75 dark:text-white/70 sm:flex-row sm:space-x-2 sm:text-left"
|
class="flex flex-col flex-wrap items-center justify-center text-center text-xl text-gray-600/75 dark:text-white/70 sm:flex-row sm:space-x-2 sm:text-left"
|
||||||
>
|
>
|
||||||
<IconNoGift class="h-10 w-10" />
|
<IconNoGift class="h-10 w-10" />
|
||||||
|
|
||||||
<span>{{ t('pages.detail-view.main.empty-list.text') }}</span>
|
<span>{{ t('pages.detail-view.main.empty-list.text') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
56
src/views/LoginView.vue
Normal file
56
src/views/LoginView.vue
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { Form } from 'vee-validate'
|
||||||
|
import { object, string } from 'yup'
|
||||||
|
import useAuth from '@/composables/useAuth'
|
||||||
|
import BaseButton from '@/components/BaseButton.vue'
|
||||||
|
import TextInput from '@/components/TextInput.vue'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const { setToken } = useAuth()
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const schema = object({
|
||||||
|
'api-key': string().required(
|
||||||
|
t('pages.login-view.main.form.api-key.error-requried')
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
const onSubmit = (values: any): void => {
|
||||||
|
setToken(values['api-key'])
|
||||||
|
router.push('/')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="flex h-full">
|
||||||
|
<div
|
||||||
|
class="m-auto w-1/2 rounded-md border-2 border-stone-200 px-6 py-10 dark:border-stone-700"
|
||||||
|
>
|
||||||
|
<h1 class="text-semibold mb-8 text-center text-3xl">
|
||||||
|
{{ t('pages.login-view.main.title.text') }}
|
||||||
|
</h1>
|
||||||
|
<Form
|
||||||
|
@submit="onSubmit"
|
||||||
|
:validation-schema="schema"
|
||||||
|
v-slot="{ meta }"
|
||||||
|
class="w-full flex-col space-y-3"
|
||||||
|
>
|
||||||
|
<TextInput
|
||||||
|
name="api-key"
|
||||||
|
type="text"
|
||||||
|
:label="t('pages.login-view.main.form.api-key.placeholder')"
|
||||||
|
autocomplete="off"
|
||||||
|
/>
|
||||||
|
<BaseButton
|
||||||
|
class="h-12 w-full"
|
||||||
|
mode="primary"
|
||||||
|
:disabled="!meta.dirty || !meta.valid"
|
||||||
|
>Submit</BaseButton
|
||||||
|
>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -1,3 +1,9 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { IconCloudQuestion } from '@/components/icons'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
const { t } = useI18n()
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="mt-20 flex flex-col flex-wrap items-center justify-center text-center text-xl sm:flex-row sm:space-x-2 sm:text-left"
|
class="mt-20 flex flex-col flex-wrap items-center justify-center text-center text-xl sm:flex-row sm:space-x-2 sm:text-left"
|
||||||
|
@ -6,8 +12,3 @@
|
||||||
<h1>{{ t('errors.not-found.text') }}</h1>
|
<h1>{{ t('errors.not-found.text') }}</h1>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
|
||||||
import { IconCloudQuestion } from '@/components/icons'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
const { t } = useI18n()
|
|
||||||
</script>
|
|
Loading…
Add table
Reference in a new issue