mirror of
https://github.com/BradNut/boredgame
synced 2025-09-08 17:40:22 +00:00
commit
9f640c2543
13 changed files with 646 additions and 552 deletions
11
package.json
11
package.json
|
|
@ -20,21 +20,21 @@
|
||||||
"@sveltejs/kit": "1.0.0-next.480",
|
"@sveltejs/kit": "1.0.0-next.480",
|
||||||
"@types/cookie": "^0.5.1",
|
"@types/cookie": "^0.5.1",
|
||||||
"@types/node": "^18.11.9",
|
"@types/node": "^18.11.9",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.42.0",
|
"@typescript-eslint/eslint-plugin": "^5.42.1",
|
||||||
"@typescript-eslint/parser": "^5.42.0",
|
"@typescript-eslint/parser": "^5.42.1",
|
||||||
"eslint": "^8.26.0",
|
"eslint": "^8.27.0",
|
||||||
"eslint-config-prettier": "^8.1.0",
|
"eslint-config-prettier": "^8.1.0",
|
||||||
"eslint-plugin-svelte3": "^4.0.0",
|
"eslint-plugin-svelte3": "^4.0.0",
|
||||||
"just-debounce-it": "^3.1.1",
|
"just-debounce-it": "^3.1.1",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.7.1",
|
||||||
"prettier-plugin-svelte": "^2.8.0",
|
"prettier-plugin-svelte": "^2.8.0",
|
||||||
"sass": "^1.55.0",
|
"sass": "^1.56.0",
|
||||||
"svelte": "^3.52.0",
|
"svelte": "^3.52.0",
|
||||||
"svelte-check": "^2.9.2",
|
"svelte-check": "^2.9.2",
|
||||||
"svelte-preprocess": "^4.10.7",
|
"svelte-preprocess": "^4.10.7",
|
||||||
"tslib": "^2.4.1",
|
"tslib": "^2.4.1",
|
||||||
"typescript": "^4.8.4",
|
"typescript": "^4.8.4",
|
||||||
"vite": "^3.2.2"
|
"vite": "^3.2.3"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -45,6 +45,7 @@
|
||||||
"@types/feather-icons": "^4.7.0",
|
"@types/feather-icons": "^4.7.0",
|
||||||
"cookie": "^0.5.0",
|
"cookie": "^0.5.0",
|
||||||
"feather-icons": "^4.29.0",
|
"feather-icons": "^4.29.0",
|
||||||
|
"svelte-lazy-loader": "^1.0.0",
|
||||||
"svelte-media-query-store": "^1.0.0",
|
"svelte-media-query-store": "^1.0.0",
|
||||||
"zod": "^3.19.1",
|
"zod": "^3.19.1",
|
||||||
"zod-to-json-schema": "^3.18.1"
|
"zod-to-json-schema": "^3.18.1"
|
||||||
|
|
|
||||||
162
pnpm-lock.yaml
162
pnpm-lock.yaml
|
|
@ -13,24 +13,25 @@ specifiers:
|
||||||
'@types/cookie': ^0.5.1
|
'@types/cookie': ^0.5.1
|
||||||
'@types/feather-icons': ^4.7.0
|
'@types/feather-icons': ^4.7.0
|
||||||
'@types/node': ^18.11.9
|
'@types/node': ^18.11.9
|
||||||
'@typescript-eslint/eslint-plugin': ^5.42.0
|
'@typescript-eslint/eslint-plugin': ^5.42.1
|
||||||
'@typescript-eslint/parser': ^5.42.0
|
'@typescript-eslint/parser': ^5.42.1
|
||||||
cookie: ^0.5.0
|
cookie: ^0.5.0
|
||||||
eslint: ^8.26.0
|
eslint: ^8.27.0
|
||||||
eslint-config-prettier: ^8.1.0
|
eslint-config-prettier: ^8.1.0
|
||||||
eslint-plugin-svelte3: ^4.0.0
|
eslint-plugin-svelte3: ^4.0.0
|
||||||
feather-icons: ^4.29.0
|
feather-icons: ^4.29.0
|
||||||
just-debounce-it: ^3.1.1
|
just-debounce-it: ^3.1.1
|
||||||
prettier: ^2.7.1
|
prettier: ^2.7.1
|
||||||
prettier-plugin-svelte: ^2.8.0
|
prettier-plugin-svelte: ^2.8.0
|
||||||
sass: ^1.55.0
|
sass: ^1.56.0
|
||||||
svelte: ^3.52.0
|
svelte: ^3.52.0
|
||||||
svelte-check: ^2.9.2
|
svelte-check: ^2.9.2
|
||||||
|
svelte-lazy-loader: ^1.0.0
|
||||||
svelte-media-query-store: ^1.0.0
|
svelte-media-query-store: ^1.0.0
|
||||||
svelte-preprocess: ^4.10.7
|
svelte-preprocess: ^4.10.7
|
||||||
tslib: ^2.4.1
|
tslib: ^2.4.1
|
||||||
typescript: ^4.8.4
|
typescript: ^4.8.4
|
||||||
vite: ^3.2.2
|
vite: ^3.2.3
|
||||||
zod: ^3.19.1
|
zod: ^3.19.1
|
||||||
zod-to-json-schema: ^3.18.1
|
zod-to-json-schema: ^3.18.1
|
||||||
|
|
||||||
|
|
@ -42,6 +43,7 @@ dependencies:
|
||||||
'@types/feather-icons': 4.7.0
|
'@types/feather-icons': 4.7.0
|
||||||
cookie: 0.5.0
|
cookie: 0.5.0
|
||||||
feather-icons: 4.29.0
|
feather-icons: 4.29.0
|
||||||
|
svelte-lazy-loader: 1.0.0
|
||||||
svelte-media-query-store: 1.0.0
|
svelte-media-query-store: 1.0.0
|
||||||
zod: 3.19.1
|
zod: 3.19.1
|
||||||
zod-to-json-schema: 3.18.1_zod@3.19.1
|
zod-to-json-schema: 3.18.1_zod@3.19.1
|
||||||
|
|
@ -51,24 +53,24 @@ devDependencies:
|
||||||
'@rgossiaux/svelte-headlessui': 1.0.2_svelte@3.52.0
|
'@rgossiaux/svelte-headlessui': 1.0.2_svelte@3.52.0
|
||||||
'@rgossiaux/svelte-heroicons': 0.1.2_svelte@3.52.0
|
'@rgossiaux/svelte-heroicons': 0.1.2_svelte@3.52.0
|
||||||
'@sveltejs/adapter-auto': 1.0.0-next.72
|
'@sveltejs/adapter-auto': 1.0.0-next.72
|
||||||
'@sveltejs/kit': 1.0.0-next.480_svelte@3.52.0+vite@3.2.2
|
'@sveltejs/kit': 1.0.0-next.480_svelte@3.52.0+vite@3.2.3
|
||||||
'@types/cookie': 0.5.1
|
'@types/cookie': 0.5.1
|
||||||
'@types/node': 18.11.9
|
'@types/node': 18.11.9
|
||||||
'@typescript-eslint/eslint-plugin': 5.42.0_6xw5wg2354iw4zujk2f3vyfrzu
|
'@typescript-eslint/eslint-plugin': 5.42.1_2udltptbznfmezdozpdoa2aemq
|
||||||
'@typescript-eslint/parser': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m
|
'@typescript-eslint/parser': 5.42.1_rmayb2veg2btbq6mbmnyivgasy
|
||||||
eslint: 8.26.0
|
eslint: 8.27.0
|
||||||
eslint-config-prettier: 8.5.0_eslint@8.26.0
|
eslint-config-prettier: 8.5.0_eslint@8.27.0
|
||||||
eslint-plugin-svelte3: 4.0.0_l6ppk7eerpslmlsqymzic46t24
|
eslint-plugin-svelte3: 4.0.0_3mj2dxwqqdwhca3fosrxvrsvse
|
||||||
just-debounce-it: 3.1.1
|
just-debounce-it: 3.1.1
|
||||||
prettier: 2.7.1
|
prettier: 2.7.1
|
||||||
prettier-plugin-svelte: 2.8.0_lrllcp5xtrkmmdzifit4hd52ze
|
prettier-plugin-svelte: 2.8.0_lrllcp5xtrkmmdzifit4hd52ze
|
||||||
sass: 1.55.0
|
sass: 1.56.0
|
||||||
svelte: 3.52.0
|
svelte: 3.52.0
|
||||||
svelte-check: 2.9.2_sass@1.55.0+svelte@3.52.0
|
svelte-check: 2.9.2_sass@1.56.0+svelte@3.52.0
|
||||||
svelte-preprocess: 4.10.7_q7oepo4r57y5enzswpidbbgzsy
|
svelte-preprocess: 4.10.7_ngwexh7rjq5fmatf3fnjcyc3qm
|
||||||
tslib: 2.4.1
|
tslib: 2.4.1
|
||||||
typescript: 4.8.4
|
typescript: 4.8.4
|
||||||
vite: 3.2.2_sass@1.55.0
|
vite: 3.2.3_ybfrah5imrtywho25u564barp4
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
|
|
@ -300,7 +302,7 @@ packages:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@sveltejs/kit/1.0.0-next.480_svelte@3.52.0+vite@3.2.2:
|
/@sveltejs/kit/1.0.0-next.480_svelte@3.52.0+vite@3.2.3:
|
||||||
resolution: {integrity: sha512-RnltVDZFksAkeIZ0wgMQDr4POz3WZxSDy6D/ycIjrz3VXMDYWxKRqmTEI7Yl7TxPgUabeYHGRm/qI+nSXOb/Yw==}
|
resolution: {integrity: sha512-RnltVDZFksAkeIZ0wgMQDr4POz3WZxSDy6D/ycIjrz3VXMDYWxKRqmTEI7Yl7TxPgUabeYHGRm/qI+nSXOb/Yw==}
|
||||||
engines: {node: '>=16.14'}
|
engines: {node: '>=16.14'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
@ -309,7 +311,7 @@ packages:
|
||||||
svelte: ^3.44.0
|
svelte: ^3.44.0
|
||||||
vite: ^3.1.0
|
vite: ^3.1.0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@sveltejs/vite-plugin-svelte': 1.0.5_svelte@3.52.0+vite@3.2.2
|
'@sveltejs/vite-plugin-svelte': 1.0.5_svelte@3.52.0+vite@3.2.3
|
||||||
cookie: 0.5.0
|
cookie: 0.5.0
|
||||||
devalue: 3.1.3
|
devalue: 3.1.3
|
||||||
kleur: 4.1.5
|
kleur: 4.1.5
|
||||||
|
|
@ -322,13 +324,13 @@ packages:
|
||||||
svelte: 3.52.0
|
svelte: 3.52.0
|
||||||
tiny-glob: 0.2.9
|
tiny-glob: 0.2.9
|
||||||
undici: 5.10.0
|
undici: 5.10.0
|
||||||
vite: 3.2.2_sass@1.55.0
|
vite: 3.2.3_ybfrah5imrtywho25u564barp4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- diff-match-patch
|
- diff-match-patch
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@sveltejs/vite-plugin-svelte/1.0.5_svelte@3.52.0+vite@3.2.2:
|
/@sveltejs/vite-plugin-svelte/1.0.5_svelte@3.52.0+vite@3.2.3:
|
||||||
resolution: {integrity: sha512-CmSdSow0Dr5ua1A11BQMtreWnE0JZmkVIcRU/yG3PKbycKUpXjNdgYTWFSbStLB0vdlGnBbm2+Y4sBVj+C+TIw==}
|
resolution: {integrity: sha512-CmSdSow0Dr5ua1A11BQMtreWnE0JZmkVIcRU/yG3PKbycKUpXjNdgYTWFSbStLB0vdlGnBbm2+Y4sBVj+C+TIw==}
|
||||||
engines: {node: ^14.18.0 || >= 16}
|
engines: {node: ^14.18.0 || >= 16}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
@ -346,7 +348,7 @@ packages:
|
||||||
magic-string: 0.26.3
|
magic-string: 0.26.3
|
||||||
svelte: 3.52.0
|
svelte: 3.52.0
|
||||||
svelte-hmr: 0.14.12_svelte@3.52.0
|
svelte-hmr: 0.14.12_svelte@3.52.0
|
||||||
vite: 3.2.2_sass@1.55.0
|
vite: 3.2.3_ybfrah5imrtywho25u564barp4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
@ -381,8 +383,8 @@ packages:
|
||||||
resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==}
|
resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/eslint-plugin/5.42.0_6xw5wg2354iw4zujk2f3vyfrzu:
|
/@typescript-eslint/eslint-plugin/5.42.1_2udltptbznfmezdozpdoa2aemq:
|
||||||
resolution: {integrity: sha512-5TJh2AgL6+wpL8H/GTSjNb4WrjKoR2rqvFxR/DDTqYNk6uXn8BJMEcncLSpMbf/XV1aS0jAjYwn98uvVCiAywQ==}
|
resolution: {integrity: sha512-LyR6x784JCiJ1j6sH5Y0K6cdExqCCm8DJUTcwG5ThNXJj/G8o5E56u5EdG4SLy+bZAwZBswC+GYn3eGdttBVCg==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@typescript-eslint/parser': ^5.0.0
|
'@typescript-eslint/parser': ^5.0.0
|
||||||
|
|
@ -392,12 +394,12 @@ packages:
|
||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/parser': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m
|
'@typescript-eslint/parser': 5.42.1_rmayb2veg2btbq6mbmnyivgasy
|
||||||
'@typescript-eslint/scope-manager': 5.42.0
|
'@typescript-eslint/scope-manager': 5.42.1
|
||||||
'@typescript-eslint/type-utils': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m
|
'@typescript-eslint/type-utils': 5.42.1_rmayb2veg2btbq6mbmnyivgasy
|
||||||
'@typescript-eslint/utils': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m
|
'@typescript-eslint/utils': 5.42.1_rmayb2veg2btbq6mbmnyivgasy
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
eslint: 8.26.0
|
eslint: 8.27.0
|
||||||
ignore: 5.2.0
|
ignore: 5.2.0
|
||||||
natural-compare-lite: 1.4.0
|
natural-compare-lite: 1.4.0
|
||||||
regexpp: 3.2.0
|
regexpp: 3.2.0
|
||||||
|
|
@ -408,8 +410,8 @@ packages:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/parser/5.42.0_wyqvi574yv7oiwfeinomdzmc3m:
|
/@typescript-eslint/parser/5.42.1_rmayb2veg2btbq6mbmnyivgasy:
|
||||||
resolution: {integrity: sha512-Ixh9qrOTDRctFg3yIwrLkgf33AHyEIn6lhyf5cCfwwiGtkWhNpVKlEZApi3inGQR/barWnY7qY8FbGKBO7p3JA==}
|
resolution: {integrity: sha512-kAV+NiNBWVQDY9gDJDToTE/NO8BHi4f6b7zTsVAJoTkmB/zlfOpiEVBzHOKtlgTndCKe8vj9F/PuolemZSh50Q==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||||
|
|
@ -418,26 +420,26 @@ packages:
|
||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/scope-manager': 5.42.0
|
'@typescript-eslint/scope-manager': 5.42.1
|
||||||
'@typescript-eslint/types': 5.42.0
|
'@typescript-eslint/types': 5.42.1
|
||||||
'@typescript-eslint/typescript-estree': 5.42.0_typescript@4.8.4
|
'@typescript-eslint/typescript-estree': 5.42.1_typescript@4.8.4
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
eslint: 8.26.0
|
eslint: 8.27.0
|
||||||
typescript: 4.8.4
|
typescript: 4.8.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/scope-manager/5.42.0:
|
/@typescript-eslint/scope-manager/5.42.1:
|
||||||
resolution: {integrity: sha512-l5/3IBHLH0Bv04y+H+zlcLiEMEMjWGaCX6WyHE5Uk2YkSGAMlgdUPsT/ywTSKgu9D1dmmKMYgYZijObfA39Wow==}
|
resolution: {integrity: sha512-QAZY/CBP1Emx4rzxurgqj3rUinfsh/6mvuKbLNMfJMMKYLRBfweus8brgXF8f64ABkIZ3zdj2/rYYtF8eiuksQ==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 5.42.0
|
'@typescript-eslint/types': 5.42.1
|
||||||
'@typescript-eslint/visitor-keys': 5.42.0
|
'@typescript-eslint/visitor-keys': 5.42.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/type-utils/5.42.0_wyqvi574yv7oiwfeinomdzmc3m:
|
/@typescript-eslint/type-utils/5.42.1_rmayb2veg2btbq6mbmnyivgasy:
|
||||||
resolution: {integrity: sha512-HW14TXC45dFVZxnVW8rnUGnvYyRC0E/vxXShFCthcC9VhVTmjqOmtqj6H5rm9Zxv+ORxKA/1aLGD7vmlLsdlOg==}
|
resolution: {integrity: sha512-WWiMChneex5w4xPIX56SSnQQo0tEOy5ZV2dqmj8Z371LJ0E+aymWD25JQ/l4FOuuX+Q49A7pzh/CGIQflxMVXg==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: '*'
|
eslint: '*'
|
||||||
|
|
@ -446,23 +448,23 @@ packages:
|
||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/typescript-estree': 5.42.0_typescript@4.8.4
|
'@typescript-eslint/typescript-estree': 5.42.1_typescript@4.8.4
|
||||||
'@typescript-eslint/utils': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m
|
'@typescript-eslint/utils': 5.42.1_rmayb2veg2btbq6mbmnyivgasy
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
eslint: 8.26.0
|
eslint: 8.27.0
|
||||||
tsutils: 3.21.0_typescript@4.8.4
|
tsutils: 3.21.0_typescript@4.8.4
|
||||||
typescript: 4.8.4
|
typescript: 4.8.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/types/5.42.0:
|
/@typescript-eslint/types/5.42.1:
|
||||||
resolution: {integrity: sha512-t4lzO9ZOAUcHY6bXQYRuu+3SSYdD9TS8ooApZft4WARt4/f2Cj/YpvbTe8A4GuhT4bNW72goDMOy7SW71mZwGw==}
|
resolution: {integrity: sha512-Qrco9dsFF5lhalz+lLFtxs3ui1/YfC6NdXu+RAGBa8uSfn01cjO7ssCsjIsUs484vny9Xm699FSKwpkCcqwWwA==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/typescript-estree/5.42.0_typescript@4.8.4:
|
/@typescript-eslint/typescript-estree/5.42.1_typescript@4.8.4:
|
||||||
resolution: {integrity: sha512-2O3vSq794x3kZGtV7i4SCWZWCwjEtkWfVqX4m5fbUBomOsEOyd6OAD1qU2lbvV5S8tgy/luJnOYluNyYVeOTTg==}
|
resolution: {integrity: sha512-qElc0bDOuO0B8wDhhW4mYVgi/LZL+igPwXtV87n69/kYC/7NG3MES0jHxJNCr4EP7kY1XVsRy8C/u3DYeTKQmw==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '*'
|
typescript: '*'
|
||||||
|
|
@ -470,8 +472,8 @@ packages:
|
||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 5.42.0
|
'@typescript-eslint/types': 5.42.1
|
||||||
'@typescript-eslint/visitor-keys': 5.42.0
|
'@typescript-eslint/visitor-keys': 5.42.1
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
globby: 11.1.0
|
globby: 11.1.0
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
|
|
@ -482,31 +484,31 @@ packages:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/utils/5.42.0_wyqvi574yv7oiwfeinomdzmc3m:
|
/@typescript-eslint/utils/5.42.1_rmayb2veg2btbq6mbmnyivgasy:
|
||||||
resolution: {integrity: sha512-JZ++3+h1vbeG1NUECXQZE3hg0kias9kOtcQr3+JVQ3whnjvKuMyktJAAIj6743OeNPnGBmjj7KEmiDL7qsdnCQ==}
|
resolution: {integrity: sha512-Gxvf12xSp3iYZd/fLqiQRD4uKZjDNR01bQ+j8zvhPjpsZ4HmvEFL/tC4amGNyxN9Rq+iqvpHLhlqx6KTxz9ZyQ==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/json-schema': 7.0.11
|
'@types/json-schema': 7.0.11
|
||||||
'@types/semver': 7.3.13
|
'@types/semver': 7.3.13
|
||||||
'@typescript-eslint/scope-manager': 5.42.0
|
'@typescript-eslint/scope-manager': 5.42.1
|
||||||
'@typescript-eslint/types': 5.42.0
|
'@typescript-eslint/types': 5.42.1
|
||||||
'@typescript-eslint/typescript-estree': 5.42.0_typescript@4.8.4
|
'@typescript-eslint/typescript-estree': 5.42.1_typescript@4.8.4
|
||||||
eslint: 8.26.0
|
eslint: 8.27.0
|
||||||
eslint-scope: 5.1.1
|
eslint-scope: 5.1.1
|
||||||
eslint-utils: 3.0.0_eslint@8.26.0
|
eslint-utils: 3.0.0_eslint@8.27.0
|
||||||
semver: 7.3.7
|
semver: 7.3.7
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
- typescript
|
- typescript
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/visitor-keys/5.42.0:
|
/@typescript-eslint/visitor-keys/5.42.1:
|
||||||
resolution: {integrity: sha512-QHbu5Hf/2lOEOwy+IUw0GoSCuAzByTAWWrOTKzTzsotiUnWFpuKnXcAhC9YztAf2EElQ0VvIK+pHJUPkM0q7jg==}
|
resolution: {integrity: sha512-LOQtSF4z+hejmpUvitPlc4hA7ERGoj2BVkesOcG91HCn8edLGUXbTrErmutmPbl8Bo9HjAvOO/zBKQHExXNA2A==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 5.42.0
|
'@typescript-eslint/types': 5.42.1
|
||||||
eslint-visitor-keys: 3.3.0
|
eslint-visitor-keys: 3.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
|
@ -1213,22 +1215,22 @@ packages:
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/eslint-config-prettier/8.5.0_eslint@8.26.0:
|
/eslint-config-prettier/8.5.0_eslint@8.27.0:
|
||||||
resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==}
|
resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: '>=7.0.0'
|
eslint: '>=7.0.0'
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 8.26.0
|
eslint: 8.27.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/eslint-plugin-svelte3/4.0.0_l6ppk7eerpslmlsqymzic46t24:
|
/eslint-plugin-svelte3/4.0.0_3mj2dxwqqdwhca3fosrxvrsvse:
|
||||||
resolution: {integrity: sha512-OIx9lgaNzD02+MDFNLw0GEUbuovNcglg+wnd/UY0fbZmlQSz7GlQiQ1f+yX0XvC07XPcDOnFcichqI3xCwp71g==}
|
resolution: {integrity: sha512-OIx9lgaNzD02+MDFNLw0GEUbuovNcglg+wnd/UY0fbZmlQSz7GlQiQ1f+yX0XvC07XPcDOnFcichqI3xCwp71g==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: '>=8.0.0'
|
eslint: '>=8.0.0'
|
||||||
svelte: ^3.2.0
|
svelte: ^3.2.0
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 8.26.0
|
eslint: 8.27.0
|
||||||
svelte: 3.52.0
|
svelte: 3.52.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
|
@ -1248,13 +1250,13 @@ packages:
|
||||||
estraverse: 5.3.0
|
estraverse: 5.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/eslint-utils/3.0.0_eslint@8.26.0:
|
/eslint-utils/3.0.0_eslint@8.27.0:
|
||||||
resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==}
|
resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==}
|
||||||
engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0}
|
engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: '>=5'
|
eslint: '>=5'
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 8.26.0
|
eslint: 8.27.0
|
||||||
eslint-visitor-keys: 2.1.0
|
eslint-visitor-keys: 2.1.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
|
@ -1268,8 +1270,8 @@ packages:
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/eslint/8.26.0:
|
/eslint/8.27.0:
|
||||||
resolution: {integrity: sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==}
|
resolution: {integrity: sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -1284,7 +1286,7 @@ packages:
|
||||||
doctrine: 3.0.0
|
doctrine: 3.0.0
|
||||||
escape-string-regexp: 4.0.0
|
escape-string-regexp: 4.0.0
|
||||||
eslint-scope: 7.1.1
|
eslint-scope: 7.1.1
|
||||||
eslint-utils: 3.0.0_eslint@8.26.0
|
eslint-utils: 3.0.0_eslint@8.27.0
|
||||||
eslint-visitor-keys: 3.3.0
|
eslint-visitor-keys: 3.3.0
|
||||||
espree: 9.4.0
|
espree: 9.4.0
|
||||||
esquery: 1.4.0
|
esquery: 1.4.0
|
||||||
|
|
@ -2110,8 +2112,8 @@ packages:
|
||||||
rimraf: 2.7.1
|
rimraf: 2.7.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/sass/1.55.0:
|
/sass/1.56.0:
|
||||||
resolution: {integrity: sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==}
|
resolution: {integrity: sha512-WFJ9XrpkcnqZcYuLRJh5qiV6ibQOR4AezleeEjTjMsCocYW59dEG19U3fwTTXxzi2Ed3yjPBp727hbbj53pHFw==}
|
||||||
engines: {node: '>=12.0.0'}
|
engines: {node: '>=12.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -2244,7 +2246,7 @@ packages:
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/svelte-check/2.9.2_sass@1.55.0+svelte@3.52.0:
|
/svelte-check/2.9.2_sass@1.56.0+svelte@3.52.0:
|
||||||
resolution: {integrity: sha512-DRi8HhnCiqiGR2YF9ervPGvtoYrheE09cXieCTEqeTPOTJzfoa54Py8rovIBv4bH4n5HgZYIyTQ3DDLHQLl2uQ==}
|
resolution: {integrity: sha512-DRi8HhnCiqiGR2YF9ervPGvtoYrheE09cXieCTEqeTPOTJzfoa54Py8rovIBv4bH4n5HgZYIyTQ3DDLHQLl2uQ==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
@ -2257,7 +2259,7 @@ packages:
|
||||||
picocolors: 1.0.0
|
picocolors: 1.0.0
|
||||||
sade: 1.8.1
|
sade: 1.8.1
|
||||||
svelte: 3.52.0
|
svelte: 3.52.0
|
||||||
svelte-preprocess: 4.10.7_q7oepo4r57y5enzswpidbbgzsy
|
svelte-preprocess: 4.10.7_ngwexh7rjq5fmatf3fnjcyc3qm
|
||||||
typescript: 4.8.4
|
typescript: 4.8.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@babel/core'
|
- '@babel/core'
|
||||||
|
|
@ -2281,6 +2283,10 @@ packages:
|
||||||
svelte: 3.52.0
|
svelte: 3.52.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/svelte-lazy-loader/1.0.0:
|
||||||
|
resolution: {integrity: sha512-AZD6R60vksyojn21FgXLglmBiBB9K5Dkdu0hdGrLbCaRCYT68IsWkZfRUqKhMx1IfzqWcZQ8X9y/f+Ih0oNQkQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/svelte-media-query-store/0.0.3:
|
/svelte-media-query-store/0.0.3:
|
||||||
resolution: {integrity: sha512-LxM2AEyE4BqVHNdEb8aZOwcSf5oyJcZWSRlSkQPxnQyp6ytGwQs3gsmaZ1udEBeL7jHldWwNrbaFwAG5W7eTXw==}
|
resolution: {integrity: sha512-LxM2AEyE4BqVHNdEb8aZOwcSf5oyJcZWSRlSkQPxnQyp6ytGwQs3gsmaZ1udEBeL7jHldWwNrbaFwAG5W7eTXw==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
@ -2291,7 +2297,7 @@ packages:
|
||||||
svelte-media-query-store: 0.0.3
|
svelte-media-query-store: 0.0.3
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/svelte-preprocess/4.10.7_q7oepo4r57y5enzswpidbbgzsy:
|
/svelte-preprocess/4.10.7_ngwexh7rjq5fmatf3fnjcyc3qm:
|
||||||
resolution: {integrity: sha512-sNPBnqYD6FnmdBrUmBCaqS00RyCsCpj2BG58A1JBswNF7b0OKviwxqVrOL/CKyJrLSClrSeqQv5BXNg2RUbPOw==}
|
resolution: {integrity: sha512-sNPBnqYD6FnmdBrUmBCaqS00RyCsCpj2BG58A1JBswNF7b0OKviwxqVrOL/CKyJrLSClrSeqQv5BXNg2RUbPOw==}
|
||||||
engines: {node: '>= 9.11.2'}
|
engines: {node: '>= 9.11.2'}
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
|
@ -2336,7 +2342,7 @@ packages:
|
||||||
'@types/sass': 1.43.1
|
'@types/sass': 1.43.1
|
||||||
detect-indent: 6.1.0
|
detect-indent: 6.1.0
|
||||||
magic-string: 0.25.9
|
magic-string: 0.25.9
|
||||||
sass: 1.55.0
|
sass: 1.56.0
|
||||||
sorcery: 0.10.0
|
sorcery: 0.10.0
|
||||||
strip-indent: 3.0.0
|
strip-indent: 3.0.0
|
||||||
svelte: 3.52.0
|
svelte: 3.52.0
|
||||||
|
|
@ -2438,17 +2444,20 @@ packages:
|
||||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vite/3.2.2_sass@1.55.0:
|
/vite/3.2.3_ybfrah5imrtywho25u564barp4:
|
||||||
resolution: {integrity: sha512-pLrhatFFOWO9kS19bQ658CnRYzv0WLbsPih6R+iFeEEhDOuYgYCX2rztUViMz/uy/V8cLCJvLFeiOK7RJEzHcw==}
|
resolution: {integrity: sha512-h8jl1TZ76eGs3o2dIBSsvXDLb1m/Ec1iej8ZMdz+PsaFUsftZeWe2CZOI3qogEsMNaywc17gu0q6cQDzh/weCQ==}
|
||||||
engines: {node: ^14.18.0 || >=16.0.0}
|
engines: {node: ^14.18.0 || >=16.0.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
'@types/node': '>= 14'
|
||||||
less: '*'
|
less: '*'
|
||||||
sass: '*'
|
sass: '*'
|
||||||
stylus: '*'
|
stylus: '*'
|
||||||
sugarss: '*'
|
sugarss: '*'
|
||||||
terser: ^5.4.0
|
terser: ^5.4.0
|
||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
|
'@types/node':
|
||||||
|
optional: true
|
||||||
less:
|
less:
|
||||||
optional: true
|
optional: true
|
||||||
sass:
|
sass:
|
||||||
|
|
@ -2460,11 +2469,12 @@ packages:
|
||||||
terser:
|
terser:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@types/node': 18.11.9
|
||||||
esbuild: 0.15.10
|
esbuild: 0.15.10
|
||||||
postcss: 8.4.18
|
postcss: 8.4.18
|
||||||
resolve: 1.22.1
|
resolve: 1.22.1
|
||||||
rollup: 2.79.1
|
rollup: 2.79.1
|
||||||
sass: 1.55.0
|
sass: 1.56.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
import { Image } from 'svelte-lazy-loader';
|
||||||
import { fade } from 'svelte/transition';
|
import { fade } from 'svelte/transition';
|
||||||
import { MinusCircleIcon, PlusCircleIcon } from '@rgossiaux/svelte-heroicons/outline';
|
import { MinusCircleIcon, PlusCircleIcon } from '@rgossiaux/svelte-heroicons/outline';
|
||||||
import type { GameType, SavedGameType } from '$lib/types';
|
import type { GameType, SavedGameType } from '$lib/types';
|
||||||
|
|
@ -46,8 +47,14 @@
|
||||||
|
|
||||||
<article class="game-container" transition:fade>
|
<article class="game-container" transition:fade>
|
||||||
<h2>{game.name}</h2>
|
<h2>{game.name}</h2>
|
||||||
<a class="thumbnail" href={`/game/${game.id}`}>
|
<a
|
||||||
<img src={game.thumb_url} alt={`Image of ${game.name}`} />
|
class="thumbnail"
|
||||||
|
href={`/game/${game.id}`}
|
||||||
|
title={`View ${game.name}`}
|
||||||
|
data-sveltekit-prefetch
|
||||||
|
>
|
||||||
|
<Image src={game.thumb_url} alt={`Image of ${game.name}`} />
|
||||||
|
<!-- <img src={game.thumb_url} alt={`Image of ${game.name}`} /> -->
|
||||||
<!-- loading="lazy" decoding="async" -->
|
<!-- loading="lazy" decoding="async" -->
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,151 +1,212 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher } from 'svelte';
|
// Based on https://carbon-components-svelte.onrender.com/components/Pagination
|
||||||
import { fade } from 'svelte/transition';
|
import { afterUpdate, createEventDispatcher } from 'svelte';
|
||||||
import {
|
import { fade } from 'svelte/transition';
|
||||||
Listbox,
|
import {
|
||||||
ListboxButton,
|
Listbox,
|
||||||
ListboxOption,
|
ListboxButton,
|
||||||
ListboxOptions
|
ListboxOption,
|
||||||
} from '@rgossiaux/svelte-headlessui';
|
ListboxOptions
|
||||||
import {
|
} from '@rgossiaux/svelte-headlessui';
|
||||||
CheckIcon,
|
import {
|
||||||
ChevronLeftIcon,
|
CheckIcon,
|
||||||
ChevronRightIcon
|
ChevronLeftIcon,
|
||||||
} from '@rgossiaux/svelte-heroicons/outline';
|
ChevronRightIcon
|
||||||
import { boredState } from '$root/lib/stores/boredState';
|
} from '@rgossiaux/svelte-heroicons/outline';
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
// export let pageSize = 10;
|
|
||||||
export let pageSize: number; // Reactive, bind
|
|
||||||
export let currentPage: number; // Reactive, bind
|
|
||||||
export let totalItems: number;
|
|
||||||
export let pageSizes: ReadonlyArray<Number> = [10];
|
|
||||||
export let forwardText: string;
|
|
||||||
export let backwardText: string;
|
|
||||||
export let pageSizeInputDisabled: boolean = false;
|
|
||||||
|
|
||||||
const totalPages: number = Math.ceil(totalItems / pageSize);
|
export let pageSize: number; // Reactive, bind
|
||||||
console.log('totalPages', totalPages);
|
export let page: number = 1; // Reactive, bind
|
||||||
const prevPage: number = currentPage - 1;
|
export let totalItems: number;
|
||||||
const nextPage: number = currentPage + 1;
|
export let pageSizeInputDisabled: boolean = false;
|
||||||
const hasNextPage: boolean = nextPage <= totalPages;
|
export let pageSizes: ReadonlyArray<Number> = [10];
|
||||||
const hasPrevPage: boolean = prevPage >= 1;
|
export let forwardText: string;
|
||||||
const itemsLeft: number =
|
export let backwardText: string;
|
||||||
totalItems - currentPage * $boredState.search.pageSize >= 0
|
export let disabled: boolean = false;
|
||||||
? totalItems - currentPage * $boredState.search.pageSize
|
|
||||||
: 0;
|
afterUpdate(() => {
|
||||||
|
if (page > totalPages) {
|
||||||
|
page = totalPages;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$: totalPages = Math.max(Math.ceil(totalItems / pageSize), 1);
|
||||||
|
$: backButtonDisabled = disabled || page === 1;
|
||||||
|
$: forwardButtonDisabled = disabled || page === totalPages;
|
||||||
|
$: itemsLeft = totalItems - page * pageSize >= 0 ? totalItems - page * pageSize : 0;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<span>
|
<div class="listbox">
|
||||||
<p>Items per-page:</p>
|
<p>Per-page:</p>
|
||||||
<div class="list-container">
|
<Listbox
|
||||||
<Listbox
|
class="list-box"
|
||||||
class="list-box"
|
value={pageSize || 10}
|
||||||
value={$boredState.search.pageSize}
|
on:change={(e) => {
|
||||||
on:change={(e) => {
|
dispatch('perPageEvent', { pageSize: e.detail, page });
|
||||||
dispatch('pageSizeEvent', e.detail);
|
}}
|
||||||
// boredState.update((n) => ({
|
let:open
|
||||||
// ...n,
|
>
|
||||||
// search: { totalCount, pageSize: e.detail, skip, currentPage }
|
<ListboxButton>{pageSize || 10}</ListboxButton>
|
||||||
// }));
|
{#if open}
|
||||||
}}
|
<div transition:fade={{ duration: 100 }}>
|
||||||
let:open
|
<ListboxOptions static class="options">
|
||||||
>
|
{#each pageSizes as size (size)}
|
||||||
<ListboxButton>{pageSize}</ListboxButton>
|
<ListboxOption
|
||||||
{#if open}
|
value={size}
|
||||||
<div transition:fade>
|
disabled={pageSizeInputDisabled}
|
||||||
<ListboxOptions static class="list-options">
|
class={({ active }) => (active ? 'active option' : 'option')}
|
||||||
{#each pageSizes as size (size)}
|
style="display: flex; gap: 1rem; padding: 1rem;"
|
||||||
<ListboxOption
|
let:selected
|
||||||
value={size}
|
>
|
||||||
disabled={pageSizeInputDisabled}
|
{#if selected}
|
||||||
class={({ active }) => (active ? 'active' : '')}
|
<CheckIcon height="24" width="24" />
|
||||||
let:selected
|
{/if}
|
||||||
>
|
<span class="size-option" class:selected>{size.toString()}</span>
|
||||||
{#if selected}
|
</ListboxOption>
|
||||||
<CheckIcon />
|
{/each}
|
||||||
{/if}
|
</ListboxOptions>
|
||||||
<p>{size.toString()}</p>
|
</div>
|
||||||
</ListboxOption>
|
{/if}
|
||||||
{/each}
|
</Listbox>
|
||||||
</ListboxOptions>
|
</div>
|
||||||
</div>
|
<p>
|
||||||
{/if}
|
Page {page || 1} of {totalPages || 1}
|
||||||
</Listbox>
|
</p>
|
||||||
</div>
|
<p>
|
||||||
</span>
|
{itemsLeft} Item{itemsLeft > 1 || itemsLeft === 0 ? 's' : ''} Left
|
||||||
<p>
|
</p>
|
||||||
Page {currentPage || 1} of {totalPages || 1}
|
<div style="display: flex; gap: 2rem;">
|
||||||
</p>
|
<button
|
||||||
<p>
|
type="button"
|
||||||
{itemsLeft} Item{itemsLeft > 1 || itemsLeft === 0 ? 's' : ''} Left
|
class="btn"
|
||||||
</p>
|
disabled={backButtonDisabled}
|
||||||
<button
|
on:click={() => {
|
||||||
type="button"
|
page--;
|
||||||
class="btn"
|
dispatch('previousPageEvent', { page });
|
||||||
disabled={!hasPrevPage}
|
}}
|
||||||
on:click={() => dispatch('previousPageEvent', prevPage)}
|
>
|
||||||
><ChevronLeftIcon width="24" height="24" />
|
<ChevronLeftIcon width="24" height="24" />
|
||||||
<p class="word">{backwardText || 'Prev'}</p></button
|
<p class="word">{backwardText || 'Prev'}</p>
|
||||||
>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="btn"
|
class="btn"
|
||||||
disabled={!hasNextPage}
|
disabled={forwardButtonDisabled}
|
||||||
on:click={() => dispatch('nextPageEvent', nextPage)}
|
on:click={() => {
|
||||||
><p class="word">{forwardText || 'Next'}</p>
|
page++;
|
||||||
<ChevronRightIcon width="24" height="24" /></button
|
dispatch('nextPageEvent', { page });
|
||||||
>
|
}}
|
||||||
|
>
|
||||||
|
<p class="word">{forwardText || 'Next'}</p>
|
||||||
|
<ChevronRightIcon width="24" height="24" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.container {
|
.container {
|
||||||
display: flex;
|
display: grid;
|
||||||
justify-content: space-between;
|
grid-template-columns: repeat(4, 1fr);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
margin: 3rem 0;
|
margin: 3rem 0;
|
||||||
|
|
||||||
.btn {
|
@media (max-width: 640px) {
|
||||||
display: flex;
|
grid-template-columns: repeat(2, 1fr);
|
||||||
gap: 0.5rem;
|
grid-template-rows: repeat(2, 1fr);
|
||||||
padding: 1rem;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 800px) {
|
.btn {
|
||||||
.word {
|
display: flex;
|
||||||
display: none;
|
gap: 0.5rem;
|
||||||
}
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.list-container :global(.list-box) {
|
@media (max-width: 800px) {
|
||||||
height: 100%;
|
.word {
|
||||||
position: relative;
|
display: none;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.list-container :global(.list-options) {
|
/* .list-container :global(.list-box) {
|
||||||
position: absolute;
|
height: 100%;
|
||||||
}
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
.list-container :global(.active) {
|
.list-container :global(.list-options) {
|
||||||
display: flex;
|
position: absolute;
|
||||||
gap: 1rem;
|
}
|
||||||
padding: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
.list-container :global(.active) {
|
||||||
/* min-width: 50px; */
|
display: flex;
|
||||||
&[aria-current],
|
gap: 1rem;
|
||||||
&.current {
|
padding: 1rem;
|
||||||
color: black; // TODO: Fix these colors
|
} */
|
||||||
background: white;
|
|
||||||
}
|
button {
|
||||||
&[disabled] {
|
/* min-width: 50px; */
|
||||||
pointer-events: none;
|
&[aria-current],
|
||||||
color: var(--lightGrey);
|
&.current {
|
||||||
text-decoration: line-through;
|
color: black; // TODO: Fix these colors
|
||||||
}
|
background: white;
|
||||||
}
|
}
|
||||||
|
&[disabled] {
|
||||||
|
pointer-events: none;
|
||||||
|
color: var(--lightGrey);
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.listbox {
|
||||||
|
--width: 100px;
|
||||||
|
margin: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.listbox :global(.active) {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.listbox :global(.button) {
|
||||||
|
width: var(--width);
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: var(--spacing-16) var(--spacing-24);
|
||||||
|
font-weight: 700;
|
||||||
|
background-color: var(--clr-primary);
|
||||||
|
color: var(--clr-theme-txt);
|
||||||
|
border-radius: var(--rounded-20);
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
}
|
||||||
|
.listbox :global(.arrows) {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.listbox :global(.options) {
|
||||||
|
width: var(--width);
|
||||||
|
position: absolute;
|
||||||
|
margin-top: 0.4rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--clr-theme-txt);
|
||||||
|
background-color: var(--clr-primary);
|
||||||
|
border-radius: var(--rounded-20);
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
.listbox :global(.option) {
|
||||||
|
display: block;
|
||||||
|
padding: var(--spacing-16) var(--spacing-24);
|
||||||
|
border-radius: var(--rounded-20);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.listbox :global(.active) {
|
||||||
|
background-color: var(--clr-theme-active);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
import { boredState } from '$lib/stores/boredState';
|
import { boredState } from '$lib/stores/boredState';
|
||||||
|
|
||||||
export let form: ActionData;
|
export let form: ActionData;
|
||||||
console.log('advanced search form data', form);
|
|
||||||
let submitting = $boredState?.loading;
|
let submitting = $boredState?.loading;
|
||||||
let minAge = +form?.minAge || 1;
|
let minAge = +form?.minAge || 1;
|
||||||
let minPlayers = +form?.minPlayers || 1;
|
let minPlayers = +form?.minPlayers || 1;
|
||||||
|
|
@ -78,9 +77,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<!-- <button type="submit" disabled={submitting}>Submit</button> -->
|
|
||||||
|
|
||||||
<!-- </form> -->
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
fieldset {
|
fieldset {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,9 @@
|
||||||
boredState.update((n) => ({ ...n, loading: true }));
|
boredState.update((n) => ({ ...n, loading: true }));
|
||||||
return async ({ result }) => {
|
return async ({ result }) => {
|
||||||
boredState.update((n) => ({ ...n, loading: false }));
|
boredState.update((n) => ({ ...n, loading: false }));
|
||||||
console.log('result main page search', result);
|
|
||||||
// `result` is an `ActionResult` object
|
// `result` is an `ActionResult` object
|
||||||
if (result.type === 'success') {
|
if (result.type === 'success') {
|
||||||
console.log('In success');
|
// console.log('In success');
|
||||||
const resultGames = result?.data?.games;
|
const resultGames = result?.data?.games;
|
||||||
if (resultGames?.length <= 0) {
|
if (resultGames?.length <= 0) {
|
||||||
toast.send('No results found 😿', {
|
toast.send('No results found 😿', {
|
||||||
|
|
@ -48,10 +47,10 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
gameStore.addAll(resultGames);
|
gameStore.addAll(resultGames);
|
||||||
console.log(`Frontend result: ${JSON.stringify(result)}`);
|
// console.log(`Frontend result random: ${JSON.stringify(result)}`);
|
||||||
await applyAction(result);
|
await applyAction(result);
|
||||||
} else {
|
} else {
|
||||||
console.log('Invalid');
|
// console.log('Invalid');
|
||||||
await applyAction(result);
|
await applyAction(result);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,65 +1,226 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { tick } from 'svelte';
|
||||||
|
import type { ActionData, PageData } from './$types';
|
||||||
import { fade } from 'svelte/transition';
|
import { fade } from 'svelte/transition';
|
||||||
import { Disclosure, DisclosureButton, DisclosurePanel } from '@rgossiaux/svelte-headlessui';
|
import { Disclosure, DisclosureButton, DisclosurePanel } from '@rgossiaux/svelte-headlessui';
|
||||||
import { ChevronRightIcon } from '@rgossiaux/svelte-heroicons/solid';
|
import { ChevronRightIcon } from '@rgossiaux/svelte-heroicons/solid';
|
||||||
|
import { xl, md } from '$lib/stores/mediaQueryStore';
|
||||||
import { boredState } from '$lib/stores/boredState';
|
import { boredState } from '$lib/stores/boredState';
|
||||||
import AdvancedSearch from '$lib/components/search/advancedSearch/index.svelte';
|
import AdvancedSearch from '$lib/components/search/advancedSearch/index.svelte';
|
||||||
|
import { applyAction, enhance } from '$app/forms';
|
||||||
|
import { gameStore } from '$root/lib/stores/gameSearchStore';
|
||||||
|
import { toast } from '../../toast/toast';
|
||||||
|
import Pagination from '$lib/components/pagination/index.svelte';
|
||||||
|
import Game from '$lib/components/game/index.svelte';
|
||||||
|
import { ToastType, type GameType, type SavedGameType } from '$root/lib/types';
|
||||||
|
import SkeletonPlaceholder from '../../SkeletonPlaceholder.svelte';
|
||||||
|
import RemoveCollectionDialog from '../../dialog/RemoveCollectionDialog.svelte';
|
||||||
|
import RemoveWishlistDialog from '../../dialog/RemoveWishlistDialog.svelte';
|
||||||
|
|
||||||
|
interface RemoveGameEvent extends Event {
|
||||||
|
detail: GameType | SavedGameType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export let data: PageData;
|
||||||
|
// console.log('search page data', data);
|
||||||
|
export let form: ActionData;
|
||||||
|
// console.log('search page form', form);
|
||||||
|
|
||||||
export let showButton: boolean = false;
|
export let showButton: boolean = false;
|
||||||
export let advancedSearch: boolean = false;
|
export let advancedSearch: boolean = false;
|
||||||
export let form: ActionData;
|
|
||||||
|
|
||||||
|
let gameToRemove: GameType | SavedGameType;
|
||||||
|
let numberOfGameSkeleton = 1;
|
||||||
|
let submitButton: HTMLElement;
|
||||||
|
let pageSize = 10;
|
||||||
|
let page = +form?.data?.page || 1;
|
||||||
|
let totalItems = form?.totalCount || data?.totalCount || 0;
|
||||||
let submitting = $boredState?.loading;
|
let submitting = $boredState?.loading;
|
||||||
let name = form?.name || '';
|
let name = form?.name || '';
|
||||||
let disclosureOpen = false;
|
let disclosureOpen = false;
|
||||||
|
|
||||||
|
$: skip = (page - 1) * pageSize;
|
||||||
|
$: console.log('submit button', submitButton);
|
||||||
|
$: showPagination = $gameStore?.length > 1;
|
||||||
|
|
||||||
|
if ($xl) {
|
||||||
|
numberOfGameSkeleton = 8;
|
||||||
|
} else if ($md) {
|
||||||
|
numberOfGameSkeleton = 3;
|
||||||
|
} else {
|
||||||
|
numberOfGameSkeleton = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let placeholderList = [...Array(numberOfGameSkeleton).keys()];
|
||||||
|
console.log(placeholderList);
|
||||||
|
|
||||||
if (form?.error) {
|
if (form?.error) {
|
||||||
disclosureOpen = true;
|
disclosureOpen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleNextPageEvent(event: CustomEvent) {
|
||||||
|
if (+event?.detail?.page === page + 1) {
|
||||||
|
page += 1;
|
||||||
|
}
|
||||||
|
await tick();
|
||||||
|
submitButton.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handlePreviousPageEvent(event: CustomEvent) {
|
||||||
|
if (+event?.detail?.page === page - 1) {
|
||||||
|
page -= 1;
|
||||||
|
}
|
||||||
|
await tick();
|
||||||
|
submitButton.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handlePerPageEvent(event: CustomEvent) {
|
||||||
|
console.log('Per Page Event called', event.detail);
|
||||||
|
page = 1;
|
||||||
|
pageSize = event.detail.pageSize;
|
||||||
|
await tick();
|
||||||
|
// console.log('New limit value DOM: ', document.getElementById('limit')?.getAttribute('value'));
|
||||||
|
submitButton.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleRemoveCollection(event: RemoveGameEvent) {
|
||||||
|
gameToRemove = event?.detail;
|
||||||
|
boredState.update((n) => ({
|
||||||
|
...n,
|
||||||
|
dialog: { isOpen: true, content: RemoveCollectionDialog, additionalData: gameToRemove }
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleRemoveWishlist(event: RemoveGameEvent) {
|
||||||
|
gameToRemove = event?.detail;
|
||||||
|
boredState.update((n) => ({
|
||||||
|
...n,
|
||||||
|
dialog: { isOpen: true, content: RemoveWishlistDialog, additionalData: gameToRemove }
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Keep all Pagination Values on back and forth browser
|
||||||
|
// TODO: Add cache for certain number of pages so back and forth doesn't request data again
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="search">
|
<form
|
||||||
<fieldset class="text-search" aria-busy={submitting} disabled={submitting}>
|
id="search-form"
|
||||||
<label for="name">
|
action="/search"
|
||||||
Search
|
method="post"
|
||||||
<input
|
use:enhance={() => {
|
||||||
id="name"
|
gameStore.removeAll();
|
||||||
name="name"
|
boredState.update((n) => ({ ...n, loading: true }));
|
||||||
bind:value={name}
|
return async ({ result }) => {
|
||||||
type="text"
|
boredState.update((n) => ({ ...n, loading: false }));
|
||||||
aria-label="Search boardgame"
|
// `result` is an `ActionResult` object
|
||||||
placeholder="Search boardgame"
|
if (result.type === 'error') {
|
||||||
/>
|
toast.send('Error!', { duration: 3000, type: ToastType.ERROR, dismissible: true });
|
||||||
</label>
|
await applyAction(result);
|
||||||
</fieldset>
|
} else if (result.type === 'success') {
|
||||||
{#if advancedSearch}
|
gameStore.removeAll();
|
||||||
<Disclosure>
|
gameStore.addAll(result?.data?.games);
|
||||||
<DisclosureButton
|
totalItems = result?.data?.totalCount;
|
||||||
class="disclosure-button"
|
// toast.send('Sucess!', { duration: 3000, type: ToastType.INFO, dismissible: true });
|
||||||
on:click={() => (disclosureOpen = !disclosureOpen)}
|
await applyAction(result);
|
||||||
>
|
} else {
|
||||||
<span>Advanced Search?</span>
|
await applyAction(result);
|
||||||
<ChevronRightIcon
|
}
|
||||||
class="icon disclosure-icon"
|
};
|
||||||
style={disclosureOpen
|
}}
|
||||||
? 'transform: rotate(90deg); transition: transform 0.5s ease;'
|
>
|
||||||
: 'transform: rotate(0deg); transition: transform 0.5s ease;'}
|
<input id="skip" type="hidden" name="skip" bind:value={skip} />
|
||||||
|
<input id="limit" type="hidden" name="limit" bind:value={pageSize} />
|
||||||
|
<div class="search">
|
||||||
|
<fieldset class="text-search" aria-busy={submitting} disabled={submitting}>
|
||||||
|
<label for="name">
|
||||||
|
Search
|
||||||
|
<input
|
||||||
|
id="name"
|
||||||
|
name="name"
|
||||||
|
bind:value={name}
|
||||||
|
type="text"
|
||||||
|
aria-label="Search boardgame"
|
||||||
|
placeholder="Search boardgame"
|
||||||
/>
|
/>
|
||||||
</DisclosureButton>
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
{#if advancedSearch}
|
||||||
|
<Disclosure>
|
||||||
|
<DisclosureButton
|
||||||
|
class="disclosure-button"
|
||||||
|
on:click={() => (disclosureOpen = !disclosureOpen)}
|
||||||
|
>
|
||||||
|
<span>Advanced Search?</span>
|
||||||
|
<ChevronRightIcon
|
||||||
|
class="icon disclosure-icon"
|
||||||
|
style={disclosureOpen
|
||||||
|
? 'transform: rotate(90deg); transition: transform 0.5s ease;'
|
||||||
|
: 'transform: rotate(0deg); transition: transform 0.5s ease;'}
|
||||||
|
/>
|
||||||
|
</DisclosureButton>
|
||||||
|
|
||||||
{#if disclosureOpen}
|
{#if disclosureOpen}
|
||||||
<div transition:fade>
|
<div transition:fade>
|
||||||
<!-- Using `static`, `DisclosurePanel` is always rendered,
|
<!-- Using `static`, `DisclosurePanel` is always rendered,
|
||||||
and ignores the `open` state -->
|
and ignores the `open` state -->
|
||||||
<DisclosurePanel static>
|
<DisclosurePanel static>
|
||||||
<AdvancedSearch {form} />
|
<AdvancedSearch {form} />
|
||||||
</DisclosurePanel>
|
</DisclosurePanel>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</Disclosure>
|
</Disclosure>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{#if showButton}
|
||||||
|
<button
|
||||||
|
id="search-submit"
|
||||||
|
class="btn"
|
||||||
|
type="submit"
|
||||||
|
disabled={submitting}
|
||||||
|
bind:this={submitButton}
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</form>
|
||||||
{#if showButton}
|
|
||||||
<button class="btn" type="submit" disabled={submitting}>Submit</button>
|
{#if $gameStore?.length > 0}
|
||||||
|
<div class="games">
|
||||||
|
<h1>Games Found:</h1>
|
||||||
|
<div class="games-list">
|
||||||
|
{#each $gameStore as game (game.id)}
|
||||||
|
<Game
|
||||||
|
on:handleRemoveWishlist={handleRemoveWishlist}
|
||||||
|
on:handleRemoveCollection={handleRemoveCollection}
|
||||||
|
{game}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{#if showPagination}
|
||||||
|
<Pagination
|
||||||
|
{pageSize}
|
||||||
|
{page}
|
||||||
|
{totalItems}
|
||||||
|
forwardText="Next"
|
||||||
|
backwardText="Prev"
|
||||||
|
pageSizes={[10, 25, 50, 100]}
|
||||||
|
on:nextPageEvent={handleNextPageEvent}
|
||||||
|
on:previousPageEvent={handlePreviousPageEvent}
|
||||||
|
on:perPageEvent={handlePerPageEvent}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{:else if $boredState.loading}
|
||||||
|
<div class="games">
|
||||||
|
<h1>Games Found:</h1>
|
||||||
|
<div class="games-list">
|
||||||
|
{#each placeholderList as game, i}
|
||||||
|
<SkeletonPlaceholder
|
||||||
|
style="width: 100%; height: 500px; border-radius: var(--borderRadius);"
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
@ -91,4 +252,31 @@
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.games {
|
||||||
|
margin: 2rem 0rem;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.games-list {
|
||||||
|
display: grid;
|
||||||
|
--listColumns: 4;
|
||||||
|
grid-template-columns: repeat(var(--listColumns), minmax(200px, 1fr));
|
||||||
|
gap: 2rem;
|
||||||
|
|
||||||
|
@media (max-width: 1200px) {
|
||||||
|
--listColumns: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 800px) {
|
||||||
|
--listColumns: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 650px) {
|
||||||
|
--listColumns: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,94 +1,11 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { enhance, applyAction } from '$app/forms';
|
|
||||||
import type { ActionData, PageData } from './$types';
|
import type { ActionData, PageData } from './$types';
|
||||||
import { ToastType, type GameType, type SavedGameType } from '$root/lib/types';
|
|
||||||
import { toast } from '$root/lib/components/toast/toast';
|
|
||||||
import { gameStore } from '$lib/stores/gameSearchStore';
|
|
||||||
import { boredState } from '$root/lib/stores/boredState';
|
|
||||||
import RemoveCollectionDialog from '$root/lib/components/dialog/RemoveCollectionDialog.svelte';
|
|
||||||
import Game from '$lib/components/game/index.svelte';
|
|
||||||
import TextSearch from '$lib/components/search/textSearch/index.svelte';
|
import TextSearch from '$lib/components/search/textSearch/index.svelte';
|
||||||
import RandomSearch from '$lib/components/search/random/index.svelte';
|
import RandomSearch from '$lib/components/search/random/index.svelte';
|
||||||
import Random from '$lib/components/random/index.svelte';
|
import Random from '$lib/components/random/index.svelte';
|
||||||
import Pagination from '$lib/components/pagination/index.svelte';
|
|
||||||
import RemoveWishlistDialog from '$root/lib/components/dialog/RemoveWishlistDialog.svelte';
|
|
||||||
import SkeletonPlaceholder from '$root/lib/components/SkeletonPlaceholder.svelte';
|
|
||||||
import { lg, md, sm, xl } from '$root/lib/stores/mediaQueryStore';
|
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
export let form: ActionData;
|
export let form: ActionData;
|
||||||
console.log('form routesss', form);
|
|
||||||
console.log('Formed data:', JSON.stringify(data));
|
|
||||||
let pageSize: number;
|
|
||||||
let currentPage: number;
|
|
||||||
let submitting = $boredState?.loading;
|
|
||||||
let numberOfGameSkeleton = 1;
|
|
||||||
if (xl) {
|
|
||||||
numberOfGameSkeleton = 8;
|
|
||||||
} else if (md) {
|
|
||||||
numberOfGameSkeleton = 3;
|
|
||||||
} else {
|
|
||||||
numberOfGameSkeleton = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log({ submitting });
|
|
||||||
|
|
||||||
$: totalItems = 0;
|
|
||||||
console.log('totalItems', totalItems);
|
|
||||||
|
|
||||||
// async function handleItemsPerPageChange(event) {
|
|
||||||
// const perPage = event?.detail;
|
|
||||||
// if ($gameStore.length )
|
|
||||||
// }
|
|
||||||
async function handleNextPageEvent(event: CustomEvent) {
|
|
||||||
console.log('Next page called', event);
|
|
||||||
boredState.update((n) => ({ ...n, loading: true }));
|
|
||||||
const form = event.target as HTMLFormElement;
|
|
||||||
console.log('form', form);
|
|
||||||
const response = await fetch('/api/game', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { accept: 'application/json' },
|
|
||||||
body: new FormData(form)
|
|
||||||
});
|
|
||||||
const responseData = await response.json();
|
|
||||||
boredState.update((n) => ({ ...n, loading: false }));
|
|
||||||
gameStore.removeAll();
|
|
||||||
gameStore.addAll(responseData?.games);
|
|
||||||
const skip = $boredState?.search?.skip;
|
|
||||||
const pageSize = $boredState?.search?.pageSize;
|
|
||||||
const currentPage = $boredState?.search?.currentPage;
|
|
||||||
const totalCount = responseData?.totalCount;
|
|
||||||
boredState.update((n) => ({
|
|
||||||
...n,
|
|
||||||
search: { totalCount, skip, pageSize, currentPage }
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
let gameToRemove: GameType | SavedGameType;
|
|
||||||
|
|
||||||
interface RemoveGameEvent extends Event {
|
|
||||||
detail: GameType | SavedGameType;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleRemoveCollection(event: RemoveGameEvent) {
|
|
||||||
console.log('Remove collection event handler');
|
|
||||||
console.log('event', event);
|
|
||||||
gameToRemove = event?.detail;
|
|
||||||
boredState.update((n) => ({
|
|
||||||
...n,
|
|
||||||
dialog: { isOpen: true, content: RemoveCollectionDialog, additionalData: gameToRemove }
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleRemoveWishlist(event: RemoveGameEvent) {
|
|
||||||
console.log('Remove wishlist event handler');
|
|
||||||
console.log('event', event);
|
|
||||||
gameToRemove = event?.detail;
|
|
||||||
boredState.update((n) => ({
|
|
||||||
...n,
|
|
||||||
dialog: { isOpen: true, content: RemoveWishlistDialog, additionalData: gameToRemove }
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
|
@ -96,90 +13,20 @@
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<h1>Search Boardgames!</h1>
|
<h1>Search Boardgames!</h1>
|
||||||
<p style="margin: 1rem 0;">
|
|
||||||
Input your requirements to search for board games that match your criteria.
|
|
||||||
</p>
|
|
||||||
<div class="game-search">
|
<div class="game-search">
|
||||||
<form
|
|
||||||
action="/search"
|
|
||||||
method="post"
|
|
||||||
use:enhance={() => {
|
|
||||||
gameStore.removeAll();
|
|
||||||
boredState.update((n) => ({ ...n, loading: true }));
|
|
||||||
return async ({ result }) => {
|
|
||||||
boredState.update((n) => ({ ...n, loading: false }));
|
|
||||||
console.log('result main page search', result);
|
|
||||||
// `result` is an `ActionResult` object
|
|
||||||
if (result.type === 'success') {
|
|
||||||
console.log('In success');
|
|
||||||
const resultGames = result?.data?.games;
|
|
||||||
if (resultGames?.length <= 0) {
|
|
||||||
toast.send('No results found 😿', {
|
|
||||||
duration: 3000,
|
|
||||||
type: ToastType.ERROR,
|
|
||||||
dismissible: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
gameStore.addAll(resultGames);
|
|
||||||
totalItems = result?.data?.totalCount;
|
|
||||||
console.log(`Frontend result: ${JSON.stringify(result)}`);
|
|
||||||
await applyAction(result);
|
|
||||||
} else {
|
|
||||||
console.log('Invalid');
|
|
||||||
await applyAction(result);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<TextSearch showButton advancedSearch {form} />
|
|
||||||
</form>
|
|
||||||
<section>
|
<section>
|
||||||
|
<p style="margin: 1rem 0;">
|
||||||
|
Input your requirements to search for board games that match your criteria.
|
||||||
|
</p>
|
||||||
<p>Or pick a random game!</p>
|
<p>Or pick a random game!</p>
|
||||||
<div class="random-buttons">
|
<div class="random-buttons">
|
||||||
<RandomSearch />
|
<RandomSearch />
|
||||||
<Random />
|
<Random />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
<TextSearch showButton advancedSearch {data} {form} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- <SkeletonPlaceholder style="height: 12rem; width: 12rem; border-radius: 10px;" /> -->
|
|
||||||
{#if $gameStore?.length > 0}
|
|
||||||
<div class="games">
|
|
||||||
<h1>Games Found:</h1>
|
|
||||||
<div class="games-list">
|
|
||||||
{#each $gameStore as game (game.id)}
|
|
||||||
<Game
|
|
||||||
on:handleRemoveWishlist={handleRemoveWishlist}
|
|
||||||
on:handleRemoveCollection={handleRemoveCollection}
|
|
||||||
{game}
|
|
||||||
/>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{:else if $boredState.loading}
|
|
||||||
<div class="games">
|
|
||||||
<h1>Games Found:</h1>
|
|
||||||
<div class="games-list">
|
|
||||||
{#each [...Array(numberOfGameSkeleton).keys()] as game, i}
|
|
||||||
<SkeletonPlaceholder
|
|
||||||
style="width: 100%; height: 500px; border-radius: var(--borderRadius);"
|
|
||||||
/>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<!-- <Pagination
|
|
||||||
{pageSize}
|
|
||||||
{currentPage}
|
|
||||||
{totalItems}
|
|
||||||
forwardText="Next"
|
|
||||||
backwardText="Prev"
|
|
||||||
pageSizes={[10, 25, 50, 100]}
|
|
||||||
on:nextPageEvent={handleNextPageEvent}
|
|
||||||
on:previousPageEvent={(event) => console.log('Prev page called', event)}
|
|
||||||
on:perPageEvent={(event) => console.log('Per page called', event)}
|
|
||||||
/> -->
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.game-search {
|
.game-search {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
@ -191,33 +38,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.games {
|
|
||||||
margin: 2rem 0rem;
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.games-list {
|
|
||||||
display: grid;
|
|
||||||
--listColumns: 4;
|
|
||||||
grid-template-columns: repeat(var(--listColumns), minmax(200px, 1fr));
|
|
||||||
gap: 2rem;
|
|
||||||
|
|
||||||
@media (max-width: 1200px) {
|
|
||||||
--listColumns: 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 800px) {
|
|
||||||
--listColumns: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 650px) {
|
|
||||||
--listColumns: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.random-buttons {
|
.random-buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
place-content: space-between;
|
place-content: space-between;
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,18 @@
|
||||||
import { collectionStore } from '$lib/stores/collectionStore';
|
import { collectionStore } from '$lib/stores/collectionStore';
|
||||||
import type { GameType, SavedGameType } from '$root/lib/types';
|
import type { GameType, SavedGameType } from '$root/lib/types';
|
||||||
import { boredState } from '$root/lib/stores/boredState';
|
import { boredState } from '$root/lib/stores/boredState';
|
||||||
|
import Pagination from '$root/lib/components/pagination/index.svelte';
|
||||||
import RemoveCollectionDialog from '$root/lib/components/dialog/RemoveCollectionDialog.svelte';
|
import RemoveCollectionDialog from '$root/lib/components/dialog/RemoveCollectionDialog.svelte';
|
||||||
import RemoveWishlistDialog from '$root/lib/components/dialog/RemoveWishlistDialog.svelte';
|
import RemoveWishlistDialog from '$root/lib/components/dialog/RemoveWishlistDialog.svelte';
|
||||||
|
import { tick } from 'svelte';
|
||||||
|
|
||||||
let isOpen: boolean = false;
|
|
||||||
let gameToRemove: GameType | SavedGameType;
|
let gameToRemove: GameType | SavedGameType;
|
||||||
console.log('isOpen', isOpen);
|
let pageSize = 10;
|
||||||
|
let page = 1;
|
||||||
|
|
||||||
|
$: totalItems = $collectionStore.length;
|
||||||
|
$: skip = (page - 1) * pageSize;
|
||||||
|
$: gamesShown = $collectionStore.slice(skip, skip + pageSize);
|
||||||
|
|
||||||
interface RemoveGameEvent extends Event {
|
interface RemoveGameEvent extends Event {
|
||||||
detail: GameType | SavedGameType;
|
detail: GameType | SavedGameType;
|
||||||
|
|
@ -33,6 +39,26 @@
|
||||||
dialog: { isOpen: true, content: RemoveWishlistDialog, additionalData: gameToRemove }
|
dialog: { isOpen: true, content: RemoveWishlistDialog, additionalData: gameToRemove }
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleNextPageEvent(event: CustomEvent) {
|
||||||
|
if (+event?.detail?.page === page + 1) {
|
||||||
|
page += 1;
|
||||||
|
}
|
||||||
|
await tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handlePreviousPageEvent(event: CustomEvent) {
|
||||||
|
if (+event?.detail?.page === page - 1) {
|
||||||
|
page -= 1;
|
||||||
|
}
|
||||||
|
await tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handlePerPageEvent(event: CustomEvent) {
|
||||||
|
page = 1;
|
||||||
|
pageSize = event.detail.pageSize;
|
||||||
|
await tick();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
|
@ -46,13 +72,24 @@
|
||||||
{#if $collectionStore.length === 0}
|
{#if $collectionStore.length === 0}
|
||||||
<h2>No games in your collection</h2>
|
<h2>No games in your collection</h2>
|
||||||
{:else}
|
{:else}
|
||||||
{#each $collectionStore as game (game.id)}
|
{#each gamesShown as game (game.id)}
|
||||||
<Game
|
<Game
|
||||||
on:handleRemoveWishlist={handleRemoveWishlist}
|
on:handleRemoveWishlist={handleRemoveWishlist}
|
||||||
on:handleRemoveCollection={handleRemoveCollection}
|
on:handleRemoveCollection={handleRemoveCollection}
|
||||||
{game}
|
{game}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
|
<Pagination
|
||||||
|
{pageSize}
|
||||||
|
{page}
|
||||||
|
{totalItems}
|
||||||
|
forwardText="Next"
|
||||||
|
backwardText="Prev"
|
||||||
|
pageSizes={[10, 25, 50, 100]}
|
||||||
|
on:nextPageEvent={handleNextPageEvent}
|
||||||
|
on:previousPageEvent={handlePreviousPageEvent}
|
||||||
|
on:perPageEvent={handlePerPageEvent}
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { fade, fly } from 'svelte/transition';
|
import { fade, fly } from 'svelte/transition';
|
||||||
|
import { Image } from 'svelte-lazy-loader';
|
||||||
import {
|
import {
|
||||||
ExternalLinkIcon,
|
ExternalLinkIcon,
|
||||||
MinusCircleIcon,
|
MinusCircleIcon,
|
||||||
|
|
@ -57,16 +58,25 @@
|
||||||
<section class="game">
|
<section class="game">
|
||||||
<div>
|
<div>
|
||||||
<a class="thumbnail" href={game.url}>
|
<a class="thumbnail" href={game.url}>
|
||||||
<img src={game.image_url} alt={`Image of ${game.name}`} />
|
<Image src={game.thumb_url} alt={`Image of ${game.name}`} />
|
||||||
|
<!-- <img src={game.image_url} alt={`Image of ${game.name}`} /> -->
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: grid; place-items: center; gap: 2rem;">
|
<div style="display: grid; place-items: center; gap: 2rem;">
|
||||||
<div class="details">
|
<div class="details">
|
||||||
<p>Year: {game?.year_published}</p>
|
{#if game?.year_published}
|
||||||
<p>Players: {game.players}</p>
|
<p>Year: {game?.year_published}</p>
|
||||||
<p>Playtime: {game.playtime} minutes</p>
|
{/if}
|
||||||
<p>Minimum Age: {game.min_age}</p>
|
{#if game?.players}
|
||||||
{#if game?.price !== 0.0}
|
<p>Players: {game.players}</p>
|
||||||
|
{/if}
|
||||||
|
{#if game?.playtime}
|
||||||
|
<p>Playtime: {game.playtime} minutes</p>
|
||||||
|
{/if}
|
||||||
|
{#if game?.min_age}
|
||||||
|
<p>Minimum Age: {game.min_age}</p>
|
||||||
|
{/if}
|
||||||
|
{#if +game?.price !== 0.0}
|
||||||
<p>Price: ${game?.price}</p>
|
<p>Price: ${game?.price}</p>
|
||||||
{/if}
|
{/if}
|
||||||
<LinkWithIcon external ariaLabel={`Board Game Atlas Link for ${game.name}`} url={game.url}>
|
<LinkWithIcon external ariaLabel={`Board Game Atlas Link for ${game.name}`} url={game.url}>
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,16 @@ export const actions: Actions = {
|
||||||
console.log("In search action specific")
|
console.log("In search action specific")
|
||||||
// Do things in here
|
// Do things in here
|
||||||
const form = await request.formData();
|
const form = await request.formData();
|
||||||
|
console.log('passed in limit:', form.get('limit'))
|
||||||
|
console.log('passed in skip:', form.get('skip'))
|
||||||
|
const limit = form.get('limit') || 10;
|
||||||
|
const skip = form.get('skip') || 0;
|
||||||
console.log('action form', form);
|
console.log('action form', form);
|
||||||
const queryParams: SearchQuery = {
|
const queryParams: SearchQuery = {
|
||||||
order_by: 'rank',
|
order_by: 'rank',
|
||||||
ascending: false,
|
ascending: false,
|
||||||
limit: 10,
|
limit: +limit,
|
||||||
skip: 0,
|
skip: +skip,
|
||||||
client_id: BOARD_GAME_ATLAS_CLIENT_ID,
|
client_id: BOARD_GAME_ATLAS_CLIENT_ID,
|
||||||
fuzzy_match: true,
|
fuzzy_match: true,
|
||||||
name: ''
|
name: ''
|
||||||
|
|
@ -54,9 +58,10 @@ export const actions: Actions = {
|
||||||
if (minPlayers && maxPlayers) {
|
if (minPlayers && maxPlayers) {
|
||||||
if (+minPlayers > +maxPlayers) {
|
if (+minPlayers > +maxPlayers) {
|
||||||
return invalid(400, { minPlayers, error: { id: 'minPlayers', message: 'Min must be less than max' } });
|
return invalid(400, { minPlayers, error: { id: 'minPlayers', message: 'Min must be less than max' } });
|
||||||
} else if (maxPlayers < minPlayers) {
|
|
||||||
return invalid(400, { maxPlayers, error: { id: 'maxPlayers', message: 'Max must be greater than min' } });
|
|
||||||
}
|
}
|
||||||
|
// else if (+maxPlayers < +minPlayers) {
|
||||||
|
// return invalid(400, { maxPlayers, error: { id: 'maxPlayers', message: 'Max must be greater than min' } });
|
||||||
|
// }
|
||||||
if (exactMinPlayers) {
|
if (exactMinPlayers) {
|
||||||
queryParams.min_players = +minPlayers;
|
queryParams.min_players = +minPlayers;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -118,7 +123,9 @@ export const actions: Actions = {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
games,
|
games,
|
||||||
totalCount: games.length
|
totalCount,
|
||||||
|
limit: +limit,
|
||||||
|
skip: +skip,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -126,7 +133,9 @@ export const actions: Actions = {
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
games: [],
|
games: [],
|
||||||
totalCount: 0
|
totalCount: 0,
|
||||||
|
limit,
|
||||||
|
skip
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,10 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { applyAction, enhance } from '$app/forms';
|
|
||||||
import { ToastType, type GameType, type SavedGameType } from '$root/lib/types';
|
|
||||||
import type { ActionData, PageData } from './$types';
|
import type { ActionData, PageData } from './$types';
|
||||||
import Game from '$lib/components/game/index.svelte';
|
|
||||||
import { gameStore } from '$lib/stores/gameSearchStore';
|
import { gameStore } from '$lib/stores/gameSearchStore';
|
||||||
import TextSearch from '$lib/components/search/textSearch/index.svelte';
|
import TextSearch from '$lib/components/search/textSearch/index.svelte';
|
||||||
import RemoveCollectionDialog from '$root/lib/components/dialog/RemoveCollectionDialog.svelte';
|
|
||||||
import { boredState } from '$root/lib/stores/boredState';
|
|
||||||
import { toast } from '$root/lib/components/toast/toast';
|
|
||||||
import RemoveWishlistDialog from '$root/lib/components/dialog/RemoveWishlistDialog.svelte';
|
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
console.log('search page data', data);
|
|
||||||
export let form: ActionData;
|
export let form: ActionData;
|
||||||
console.log('search page form', form);
|
|
||||||
let gameToRemove: GameType | SavedGameType;
|
|
||||||
|
|
||||||
$: if (data?.games) {
|
$: if (data?.games) {
|
||||||
gameStore.removeAll();
|
gameStore.removeAll();
|
||||||
|
|
@ -25,63 +15,13 @@
|
||||||
gameStore.removeAll();
|
gameStore.removeAll();
|
||||||
gameStore.addAll(form?.games);
|
gameStore.addAll(form?.games);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RemoveGameEvent extends Event {
|
|
||||||
detail: GameType | SavedGameType;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleRemoveCollection(event: RemoveGameEvent) {
|
|
||||||
console.log('Remove collection event handler');
|
|
||||||
console.log('event', event);
|
|
||||||
gameToRemove = event?.detail;
|
|
||||||
boredState.update((n) => ({
|
|
||||||
...n,
|
|
||||||
dialog: { isOpen: true, content: RemoveCollectionDialog, additionalData: gameToRemove }
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleRemoveWishlist(event: RemoveGameEvent) {
|
|
||||||
console.log('Remove wishlist event handler');
|
|
||||||
console.log('event', event);
|
|
||||||
gameToRemove = event?.detail;
|
|
||||||
boredState.update((n) => ({
|
|
||||||
...n,
|
|
||||||
dialog: { isOpen: true, content: RemoveWishlistDialog, additionalData: gameToRemove }
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="game-search">
|
<div class="game-search">
|
||||||
<form
|
<TextSearch showButton advancedSearch {data} {form} />
|
||||||
action="/search"
|
|
||||||
method="post"
|
|
||||||
use:enhance={() => {
|
|
||||||
boredState.update((n) => ({ ...n, loading: true }));
|
|
||||||
return async ({ result }) => {
|
|
||||||
boredState.update((n) => ({ ...n, loading: false }));
|
|
||||||
console.log(result);
|
|
||||||
// `result` is an `ActionResult` object
|
|
||||||
if (result.type === 'error') {
|
|
||||||
toast.send('Error!', { duration: 3000, type: ToastType.ERROR, dismissible: true });
|
|
||||||
await applyAction(result);
|
|
||||||
} else if (result.type === 'success') {
|
|
||||||
gameStore.removeAll();
|
|
||||||
gameStore.addAll(result?.data?.games);
|
|
||||||
// totalItems = result?.data?.totalCount;
|
|
||||||
console.log(`Frontend result: ${JSON.stringify(result)}`);
|
|
||||||
toast.send('Sucess!', { duration: 3000, type: ToastType.INFO, dismissible: true });
|
|
||||||
await applyAction(result);
|
|
||||||
} else {
|
|
||||||
await applyAction(result);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<TextSearch showButton advancedSearch {form} />
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if $gameStore?.length > 0}
|
<!-- {#if $gameStore?.length > 0}
|
||||||
<div class="games">
|
<div class="games">
|
||||||
<h1>Games Found:</h1>
|
<h1>Games Found:</h1>
|
||||||
<div class="games-list">
|
<div class="games-list">
|
||||||
|
|
@ -97,28 +37,6 @@
|
||||||
{:else if form && form?.status && form.status !== 200}
|
{:else if form && form?.status && form.status !== 200}
|
||||||
<h1>There was an error searching for games!</h1>
|
<h1>There was an error searching for games!</h1>
|
||||||
<h2>Please try again later.</h2>
|
<h2>Please try again later.</h2>
|
||||||
{/if}
|
{/if} -->
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.games {
|
|
||||||
margin: 2rem 0rem;
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.games-list {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(3, minmax(200px, 1fr));
|
|
||||||
gap: 2rem;
|
|
||||||
|
|
||||||
@media (max-width: 800px) {
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 650px) {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,18 @@
|
||||||
import { wishlistStore } from '$lib/stores/wishlistStore';
|
import { wishlistStore } from '$lib/stores/wishlistStore';
|
||||||
import type { GameType, SavedGameType } from '$root/lib/types';
|
import type { GameType, SavedGameType } from '$root/lib/types';
|
||||||
import { boredState } from '$root/lib/stores/boredState';
|
import { boredState } from '$root/lib/stores/boredState';
|
||||||
|
import Pagination from '$root/lib/components/pagination/index.svelte';
|
||||||
import RemoveWishlistDialog from '$root/lib/components/dialog/RemoveWishlistDialog.svelte';
|
import RemoveWishlistDialog from '$root/lib/components/dialog/RemoveWishlistDialog.svelte';
|
||||||
import RemoveCollectionDialog from '$root/lib/components/dialog/RemoveCollectionDialog.svelte';
|
import RemoveCollectionDialog from '$root/lib/components/dialog/RemoveCollectionDialog.svelte';
|
||||||
|
import { tick } from 'svelte';
|
||||||
|
|
||||||
let isOpen: boolean = false;
|
|
||||||
let gameToRemove: GameType | SavedGameType;
|
let gameToRemove: GameType | SavedGameType;
|
||||||
console.log('isOpen', isOpen);
|
let pageSize = 10;
|
||||||
|
let page = 1;
|
||||||
|
|
||||||
|
$: totalItems = $wishlistStore.length;
|
||||||
|
$: skip = (page - 1) * pageSize;
|
||||||
|
$: gamesShown = $wishlistStore.slice(skip, skip + pageSize);
|
||||||
|
|
||||||
interface RemoveGameEvent extends Event {
|
interface RemoveGameEvent extends Event {
|
||||||
detail: GameType | SavedGameType;
|
detail: GameType | SavedGameType;
|
||||||
|
|
@ -29,6 +35,26 @@
|
||||||
dialog: { isOpen: true, content: RemoveWishlistDialog, additionalData: gameToRemove }
|
dialog: { isOpen: true, content: RemoveWishlistDialog, additionalData: gameToRemove }
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleNextPageEvent(event: CustomEvent) {
|
||||||
|
if (+event?.detail?.page === page + 1) {
|
||||||
|
page += 1;
|
||||||
|
}
|
||||||
|
await tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handlePreviousPageEvent(event: CustomEvent) {
|
||||||
|
if (+event?.detail?.page === page - 1) {
|
||||||
|
page -= 1;
|
||||||
|
}
|
||||||
|
await tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handlePerPageEvent(event: CustomEvent) {
|
||||||
|
page = 1;
|
||||||
|
pageSize = event.detail.pageSize;
|
||||||
|
await tick();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
|
@ -42,13 +68,24 @@
|
||||||
{#if $wishlistStore.length === 0}
|
{#if $wishlistStore.length === 0}
|
||||||
<h2>No games in your wishlist</h2>
|
<h2>No games in your wishlist</h2>
|
||||||
{:else}
|
{:else}
|
||||||
{#each $wishlistStore as game}
|
{#each gamesShown as game}
|
||||||
<Game
|
<Game
|
||||||
on:handleRemoveWishlist={handleRemoveWishlist}
|
on:handleRemoveWishlist={handleRemoveWishlist}
|
||||||
on:handleRemoveCollection={handleRemoveCollection}
|
on:handleRemoveCollection={handleRemoveCollection}
|
||||||
{game}
|
{game}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
|
<Pagination
|
||||||
|
{pageSize}
|
||||||
|
{page}
|
||||||
|
{totalItems}
|
||||||
|
forwardText="Next"
|
||||||
|
backwardText="Prev"
|
||||||
|
pageSizes={[10, 25, 50, 100]}
|
||||||
|
on:nextPageEvent={handleNextPageEvent}
|
||||||
|
on:previousPageEvent={handlePreviousPageEvent}
|
||||||
|
on:perPageEvent={handlePerPageEvent}
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue