Setting up pagination component in search results.

This commit is contained in:
Bradley Shellnut 2022-11-08 20:07:05 -06:00
parent 98346b1272
commit 78c63b75d9
8 changed files with 385 additions and 270 deletions

View file

@ -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": {

View file

@ -13,24 +13,24 @@ 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-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
@ -51,24 +51,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 +300,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 +309,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 +322,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 +346,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 +381,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 +392,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 +408,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 +418,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 +446,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 +470,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 +482,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 +1213,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 +1248,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 +1268,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 +1284,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 +2110,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 +2244,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 +2257,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'
@ -2291,7 +2291,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 +2336,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 +2438,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 +2463,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

View file

@ -1,151 +1,218 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from 'svelte'; import { afterUpdate, createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import { import {
Listbox, Listbox,
ListboxButton, ListboxButton,
ListboxOption, ListboxOption,
ListboxOptions ListboxOptions
} from '@rgossiaux/svelte-headlessui'; } from '@rgossiaux/svelte-headlessui';
import { import {
CheckIcon, CheckIcon,
ChevronLeftIcon, ChevronLeftIcon,
ChevronRightIcon ChevronRightIcon
} from '@rgossiaux/svelte-heroicons/outline'; } from '@rgossiaux/svelte-heroicons/outline';
import { boredState } from '$root/lib/stores/boredState'; import { boredState } from '$root/lib/stores/boredState';
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
// export let pageSize = 10; // export let pageSize = 10;
export let pageSize: number; // Reactive, bind export let pageSize: number; // Reactive, bind
export let currentPage: number; // Reactive, bind export let page: number = 1; // Reactive, bind
export let totalItems: number; export let totalItems: number;
export let pageSizes: ReadonlyArray<Number> = [10]; export let pageSizeInputDisabled: boolean = false;
export let forwardText: string; export let pageSizes: ReadonlyArray<Number> = [10];
export let backwardText: string; export let forwardText: string;
export let pageSizeInputDisabled: boolean = false; export let backwardText: string;
export let disabled: boolean = false;
const totalPages: number = Math.ceil(totalItems / pageSize); afterUpdate(() => {
console.log('totalPages', totalPages); if (page > totalPages) {
const prevPage: number = currentPage - 1; page = totalPages;
const nextPage: number = currentPage + 1; }
const hasNextPage: boolean = nextPage <= totalPages; });
const hasPrevPage: boolean = prevPage >= 1;
const itemsLeft: number = console.log('Pagination info');
totalItems - currentPage * $boredState.search.pageSize >= 0 console.log({ pageSize, page, totalItems });
? totalItems - currentPage * $boredState.search.pageSize
: 0; $: 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;
console.log('totalPages', totalPages);
const prevPage: number = page - 1;
const nextPage: number = page + 1;
</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={$boredState?.search?.pageSize || 10}
value={$boredState.search.pageSize} on:change={(e) => {
on:change={(e) => { dispatch('update', { 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>

View file

@ -48,7 +48,7 @@
}); });
} }
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');

View file

@ -59,7 +59,7 @@
{/if} {/if}
</div> </div>
{#if showButton} {#if showButton}
<button class="btn" type="submit" disabled={submitting}>Submit</button> <button id="search-submit" class="btn" type="submit" disabled={submitting}>Submit</button>
{/if} {/if}
<style lang="scss"> <style lang="scss">

View file

@ -5,6 +5,7 @@
import { toast } from '$root/lib/components/toast/toast'; import { toast } from '$root/lib/components/toast/toast';
import { gameStore } from '$lib/stores/gameSearchStore'; import { gameStore } from '$lib/stores/gameSearchStore';
import { boredState } from '$root/lib/stores/boredState'; import { boredState } from '$root/lib/stores/boredState';
// import { md, xl } from '$root/lib/stores/mediaQueryStore';
import RemoveCollectionDialog from '$root/lib/components/dialog/RemoveCollectionDialog.svelte'; import RemoveCollectionDialog from '$root/lib/components/dialog/RemoveCollectionDialog.svelte';
import Game from '$lib/components/game/index.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';
@ -13,27 +14,28 @@
import Pagination from '$lib/components/pagination/index.svelte'; import Pagination from '$lib/components/pagination/index.svelte';
import RemoveWishlistDialog from '$root/lib/components/dialog/RemoveWishlistDialog.svelte'; import RemoveWishlistDialog from '$root/lib/components/dialog/RemoveWishlistDialog.svelte';
import SkeletonPlaceholder from '$root/lib/components/SkeletonPlaceholder.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('form routesss', form);
console.log('Formed data:', JSON.stringify(data)); console.log('Formed data:', JSON.stringify(data));
let pageSize: number;
let currentPage: number; let pageSize = 10;
let page = 0;
let submitting = $boredState?.loading; let submitting = $boredState?.loading;
let numberOfGameSkeleton = 1; let numberOfGameSkeleton = 1;
if (xl) { // if ($xl) {
numberOfGameSkeleton = 8; // numberOfGameSkeleton = 8;
} else if (md) { // } else if ($md) {
numberOfGameSkeleton = 3; // numberOfGameSkeleton = 3;
} else { // } else {
numberOfGameSkeleton = 1; // numberOfGameSkeleton = 1;
} // }
console.log({ submitting }); console.log({ submitting });
console.log('Form total count:' + form?.totalCount);
$: totalItems = 0; console.log('Data total count: ' + data?.totalCount);
let totalItems = form?.totalCount || data?.totalCount || 0;
console.log('totalItems', totalItems); console.log('totalItems', totalItems);
// async function handleItemsPerPageChange(event) { // async function handleItemsPerPageChange(event) {
@ -42,26 +44,8 @@
// } // }
async function handleNextPageEvent(event: CustomEvent) { async function handleNextPageEvent(event: CustomEvent) {
console.log('Next page called', event); console.log('Next page called', event);
boredState.update((n) => ({ ...n, loading: true })); page = event.detail || page;
const form = event.target as HTMLFormElement; document.getElementById('search-form')?.submit();
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; let gameToRemove: GameType | SavedGameType;
@ -101,10 +85,13 @@
</p> </p>
<div class="game-search"> <div class="game-search">
<form <form
id="search-form"
action="/search" action="/search"
method="post" method="post"
use:enhance={() => { use:enhance={({ data }) => {
gameStore.removeAll(); gameStore.removeAll();
data.append('limit', pageSize.toString());
data.append('skip', Math.floor(page * pageSize).toString());
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 }));
@ -122,7 +109,7 @@
} }
gameStore.addAll(resultGames); gameStore.addAll(resultGames);
totalItems = result?.data?.totalCount; totalItems = result?.data?.totalCount;
console.log(`Frontend result: ${JSON.stringify(result)}`); console.log(`Frontend base page: ${JSON.stringify(result)}`);
await applyAction(result); await applyAction(result);
} else { } else {
console.log('Invalid'); console.log('Invalid');
@ -142,7 +129,6 @@
</section> </section>
</div> </div>
<!-- <SkeletonPlaceholder style="height: 12rem; width: 12rem; border-radius: 10px;" /> -->
{#if $gameStore?.length > 0} {#if $gameStore?.length > 0}
<div class="games"> <div class="games">
<h1>Games Found:</h1> <h1>Games Found:</h1>
@ -155,6 +141,17 @@
/> />
{/each} {/each}
</div> </div>
<Pagination
{pageSize}
{page}
{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)}
/>
</div> </div>
{:else if $boredState.loading} {:else if $boredState.loading}
<div class="games"> <div class="games">
@ -169,17 +166,6 @@
</div> </div>
{/if} {/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;

View file

@ -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: ''
@ -118,7 +122,9 @@ export const actions: Actions = {
return { return {
games, games,
totalCount: games.length totalCount,
limit: +limit,
skip: +skip,
}; };
} }
} catch (e) { } catch (e) {
@ -126,7 +132,9 @@ export const actions: Actions = {
} }
return { return {
games: [], games: [],
totalCount: 0 totalCount: 0,
limit,
skip
}; };
} }
} }

View file

@ -8,13 +8,27 @@
import RemoveCollectionDialog from '$root/lib/components/dialog/RemoveCollectionDialog.svelte'; import RemoveCollectionDialog from '$root/lib/components/dialog/RemoveCollectionDialog.svelte';
import { boredState } from '$root/lib/stores/boredState'; import { boredState } from '$root/lib/stores/boredState';
import { toast } from '$root/lib/components/toast/toast'; import { toast } from '$root/lib/components/toast/toast';
import Pagination from '$lib/components/pagination/index.svelte';
import RemoveWishlistDialog from '$root/lib/components/dialog/RemoveWishlistDialog.svelte'; import RemoveWishlistDialog from '$root/lib/components/dialog/RemoveWishlistDialog.svelte';
export let data: PageData; export let data: PageData;
console.log('search page data', data); console.log('search page data', data);
export let form: ActionData; export let form: ActionData;
console.log('search page form', form); console.log('search page form', form);
let gameToRemove: GameType | SavedGameType; let gameToRemove: GameType | SavedGameType;
let pageSize = 10;
console.log('Form data page', +form?.data?.page);
let page = +form?.data?.page || 1;
$: skip = (page - 1) * pageSize;
console.log({ skip });
let totalItems = form?.totalCount || data?.totalCount || 0;
console.log({ pageSize });
console.log({ page });
console.log({ totalItems });
let submitting = $boredState?.loading;
let numberOfGameSkeleton = 1;
console.log('Search page total count: ', totalItems);
$: if (data?.games) { $: if (data?.games) {
gameStore.removeAll(); gameStore.removeAll();
@ -49,13 +63,32 @@
dialog: { isOpen: true, content: RemoveWishlistDialog, additionalData: gameToRemove } dialog: { isOpen: true, content: RemoveWishlistDialog, additionalData: gameToRemove }
})); }));
} }
function handleNextPageEvent(event: CustomEvent) {
console.log('Next page called', event.detail);
console.log('Current page: ', page);
if (+event?.detail?.page === page + 1) {
console.log('Page equals plus one');
page += 1;
}
console.log('New page value: ', page);
console.log('New skip value: ', skip);
document.getElementById('skip')?.setAttribute('value', `${page * pageSize}`);
console.log('New skip value DOM: ', document.getElementById('skip')?.getAttribute('value'));
document.getElementById('search-submit')?.click();
}
</script> </script>
<div class="game-search"> <div class="game-search">
{skip}
<form <form
id="search-form"
action="/search" action="/search"
method="post" method="post"
use:enhance={() => { use:enhance={({ data }) => {
gameStore.removeAll();
// data.append('limit', pageSize.toString());
// data.append('skip', Math.floor(page * pageSize).toString());
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 }));
@ -68,7 +101,11 @@
gameStore.removeAll(); gameStore.removeAll();
gameStore.addAll(result?.data?.games); gameStore.addAll(result?.data?.games);
// totalItems = result?.data?.totalCount; // totalItems = result?.data?.totalCount;
console.log(`Frontend result: ${JSON.stringify(result)}`); console.log(`Frontend result search enhance: ${JSON.stringify(result)}`);
totalItems = result?.data?.totalCount;
// skip = result?.data?.skip || 0;
// page = skip / pageSize || 0;
// console.log('enhance', page, skip, totalItems);
toast.send('Sucess!', { duration: 3000, type: ToastType.INFO, dismissible: true }); toast.send('Sucess!', { duration: 3000, type: ToastType.INFO, dismissible: true });
await applyAction(result); await applyAction(result);
} else { } else {
@ -77,6 +114,8 @@
}; };
}} }}
> >
<input id="skip" type="hidden" name="skip" value={skip} />
<input id="limit" type="hidden" name="limit" value={pageSize} />
<TextSearch showButton advancedSearch {form} /> <TextSearch showButton advancedSearch {form} />
</form> </form>
</div> </div>
@ -93,6 +132,17 @@
/> />
{/each} {/each}
</div> </div>
<Pagination
{pageSize}
{page}
{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)}
/>
</div> </div>
{: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>