Adding calls to board game site.

This commit is contained in:
Bradley Shellnut 2022-04-19 19:15:46 -07:00
parent dae3a6f703
commit ea533499f2
10 changed files with 369 additions and 44 deletions

View file

@ -12,14 +12,14 @@
"format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ."
},
"devDependencies": {
"@playwright/test": "^1.21.0",
"@playwright/test": "^1.21.1",
"@sveltejs/adapter-auto": "next",
"@sveltejs/kit": "next",
"@sveltejs/kit": "^1.0.0-next.316",
"@types/cookie": "^0.5.0",
"@types/node": "^17.0.25",
"@typescript-eslint/eslint-plugin": "^5.20.0",
"@typescript-eslint/parser": "^5.20.0",
"carbon-components-svelte": "^0.63.0",
"carbon-components-svelte": "^0.63.1",
"carbon-icons-svelte": "^11.0.1",
"eslint": "^8.13.0",
"eslint-config-prettier": "^8.5.0",

View file

@ -3,14 +3,14 @@ lockfileVersion: 5.3
specifiers:
'@fontsource/fira-mono': ^4.5.7
'@lukeed/uuid': ^2.0.0
'@playwright/test': ^1.21.0
'@playwright/test': ^1.21.1
'@sveltejs/adapter-auto': next
'@sveltejs/kit': next
'@sveltejs/kit': ^1.0.0-next.316
'@types/cookie': ^0.5.0
'@types/node': ^17.0.25
'@typescript-eslint/eslint-plugin': ^5.20.0
'@typescript-eslint/parser': ^5.20.0
carbon-components-svelte: ^0.63.0
carbon-components-svelte: ^0.63.1
carbon-icons-svelte: ^11.0.1
cookie: ^0.5.0
eslint: ^8.13.0
@ -30,14 +30,14 @@ dependencies:
cookie: 0.5.0
devDependencies:
'@playwright/test': 1.21.0
'@playwright/test': 1.21.1
'@sveltejs/adapter-auto': 1.0.0-next.34
'@sveltejs/kit': 1.0.0-next.315_svelte@3.47.0
'@sveltejs/kit': 1.0.0-next.316_svelte@3.47.0
'@types/cookie': 0.5.0
'@types/node': 17.0.25
'@typescript-eslint/eslint-plugin': 5.20.0_b9ac9b5656ce5dffade639fcf5e491bf
'@typescript-eslint/parser': 5.20.0_eslint@8.13.0+typescript@4.6.3
carbon-components-svelte: 0.63.0
carbon-components-svelte: 0.63.1
carbon-icons-svelte: 11.0.1
eslint: 8.13.0
eslint-config-prettier: 8.5.0_eslint@8.13.0
@ -78,7 +78,7 @@ packages:
'@babel/traverse': 7.17.9
'@babel/types': 7.17.0
convert-source-map: 1.8.0
debug: 4.3.4
debug: 4.3.3
gensync: 1.0.0-beta.2
json5: 2.2.1
semver: 6.3.0
@ -550,7 +550,7 @@ packages:
'@babel/helper-split-export-declaration': 7.16.7
'@babel/parser': 7.17.9
'@babel/types': 7.17.0
debug: 4.3.4
debug: 4.3.3
globals: 11.12.0
transitivePeerDependencies:
- supports-color
@ -648,8 +648,8 @@ packages:
fastq: 1.13.0
dev: true
/@playwright/test/1.21.0:
resolution: {integrity: sha512-jvgN3ZeAG6rw85z4u9Rc4uyj6qIaYlq2xrOtS7J2+CDYhzKOttab9ix9ELcvBOCHuQ6wgTfxfJYdh6DRZmQ9hg==}
/@playwright/test/1.21.1:
resolution: {integrity: sha512-XkkTXl5gvEm4fciqeHvY5IuSS/OfQef0MO6RpBNmtm6EuYSdtUvP/sDVuWRKsDqyVdB3WSA0az7iSw79f2//JQ==}
engines: {node: '>=12'}
hasBin: true
dependencies:
@ -682,7 +682,7 @@ packages:
ms: 2.1.3
open: 8.4.0
pirates: 4.0.4
playwright-core: 1.21.0
playwright-core: 1.21.1
rimraf: 3.0.2
source-map-support: 0.4.18
stack-utils: 2.0.5
@ -730,8 +730,8 @@ packages:
esbuild: 0.14.36
dev: true
/@sveltejs/kit/1.0.0-next.315_svelte@3.47.0:
resolution: {integrity: sha512-f6ufqd9z6uicOOr1eSIclm4TonwoRtw0kuIYrDatYSZtu/081kZ5r0Vj6sXDI6tFI1kctoRzPtFECXf5zkZvlw==}
/@sveltejs/kit/1.0.0-next.316_svelte@3.47.0:
resolution: {integrity: sha512-oLjWOWzjriJD2t210r7ALuH/8ZADrJGsOODzRCRSJvRBCt0Q7VKVLqwKbM/RlZzD1k8Af2uRodQT11kP98hAIA==}
engines: {node: '>=14.13'}
hasBin: true
peerDependencies:
@ -975,7 +975,7 @@ packages:
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
engines: {node: '>= 6.0.0'}
dependencies:
debug: 4.3.4
debug: 4.3.3
transitivePeerDependencies:
- supports-color
dev: true
@ -1091,8 +1091,8 @@ packages:
resolution: {integrity: sha512-10T30NYOEQtN6C11YGg411yebhvpnC6Z102+B95eAsN0oB6KUs01ivE8u+G6FMIRtIrVlYXhL+LUwQ3/hXwDWw==}
dev: true
/carbon-components-svelte/0.63.0:
resolution: {integrity: sha512-oG5pW1/Tzuc/2MW5ekRLp6oGmIZjvIoY8y/Dg7M8Bj35hB6ofgs5BQPLa/UjsnVOEC3YqNVu18vXnvFqkjAA8A==}
/carbon-components-svelte/0.63.1:
resolution: {integrity: sha512-gB6qGalCXG87nFiPp6KzBAjTDFjZm8vcOTBa7gQFDtwL5TzM4oeg8zHxqPSpPuNJvVym/3AlVNnvHbZBRomBzQ==}
dependencies:
flatpickr: 4.6.9
dev: true
@ -1654,7 +1654,7 @@ packages:
engines: {node: '>= 10.17.0'}
hasBin: true
dependencies:
debug: 4.3.4
debug: 4.3.3
get-stream: 5.2.0
yauzl: 2.10.0
optionalDependencies:
@ -1862,7 +1862,7 @@ packages:
engines: {node: '>= 6'}
dependencies:
agent-base: 6.0.2
debug: 4.3.4
debug: 4.3.3
transitivePeerDependencies:
- supports-color
dev: true
@ -1907,8 +1907,8 @@ packages:
binary-extensions: 2.2.0
dev: true
/is-core-module/2.8.1:
resolution: {integrity: sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==}
/is-core-module/2.9.0:
resolution: {integrity: sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==}
dependencies:
has: 1.0.3
dev: true
@ -2241,8 +2241,8 @@ packages:
pngjs: 4.0.1
dev: true
/playwright-core/1.21.0:
resolution: {integrity: sha512-yDGVs9qaaW6WiefgR7wH1CGt9D6D/X4U3jNpIzH0FjjrrWLCOYQo78Tu3SkW8X+/kWlBpj49iWf3QNSxhYc12Q==}
/playwright-core/1.21.1:
resolution: {integrity: sha512-SbK5dEsai9ZUKlxcinqegorBq4GnftXd4/GfW+pLsdQIQWrLCM/JNh6YQ2Rf2enVykXCejtoXW8L5vJXBBVSJQ==}
engines: {node: '>=12'}
hasBin: true
dependencies:
@ -2382,7 +2382,7 @@ packages:
resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==}
hasBin: true
dependencies:
is-core-module: 2.8.1
is-core-module: 2.9.0
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
dev: true
@ -2489,7 +2489,7 @@ packages:
engines: {node: '>= 10'}
dependencies:
agent-base: 6.0.2
debug: 4.3.4
debug: 4.3.3
socks: 2.6.2
transitivePeerDependencies:
- supports-color

View file

@ -59,7 +59,7 @@ export function enhance(
const url = new URL(form.action);
url.search = url.hash = '';
invalidate(url.href);
// invalidate(url.href);
} else if (error) {
error({ data, form, error: null, response });
} else {

View file

@ -13,10 +13,10 @@ import { URLSearchParams } from "url";
const base = 'https://api.boardgameatlas.com/api';
export function api(method: string, resource: string, queryParams: Record<string, string>, data?: Record<string, unknown>) {
queryParams.client_key = import.meta.env.BASE_URL
export function boardGameApi(method: string, resource: string, queryParams: Record<string, string>, data?: Record<string, unknown>) {
queryParams.client_id = import.meta.env.VITE_PUBLIC_CLIENT_ID;
const urlQueryParams = new URLSearchParams(queryParams)
const url = `${base}/${resource}${urlQueryParams ? urlQueryParams : ''}`
const url = `${base}/${resource}${urlQueryParams ? `?${urlQueryParams}` : ''}`
return fetch(url, {
method,
headers: {

View file

View file

@ -0,0 +1,116 @@
<script lang="ts">
import { enhance } from "$lib/form";
let minAge = 0;
let maxAge = 0;
let minPlayers = 0;
let maxPlayers = 0;
let loading = false;
type Game = {
id: string;
handle: string;
name: string;
url: string;
edit_url: string;
price: number;
price_ca: number;
price_uk: number;
price_au: number;
msrp: number;
year_published: number;
min_players: number;
max_players: number;
min_playtime: number;
max_playtime: number;
min_age: number;
description: string;
players: string;
playtime: string;
}
export let games: Game[];
</script>
<svelte:head>
<title>Games</title>
</svelte:head>
<div class="game-form">
<form
action="/games"
method="post"
use:enhance={{
pending: () => {
loading = true;
},
result: async ({ data, form, response }) => {
loading = false;
console.log(JSON.stringify(data))
}
}}
>
<fieldset aria-busy={loading} disabled={loading}>
<label for="minAge">Min Age:
<input id="minAge" name="minAge" type="range" min="0" max="120" step="1" bind:value={minAge} />
{minAge}
</label>
<label for="maxAge">Max Age:
<input id="maxAge" name="maxAge" type="range" min="0" max="120" step="1" bind:value={maxAge} />
{maxAge}
</label>
<label for="minPlayers">Min Players:
<input id="minPlayers" name="minPlayers" type="range" min="1" max="50" step="1" bind:value={minPlayers} />
{minPlayers}
</label>
<label for="maxPlayers">Max Players:
<input id="maxPlayers" name="maxPlayers" type="range" min="1" max="50" step="1" bind:value={maxPlayers} />
{maxPlayers}
</label>
</fieldset>
<button type="submit" disabled={loading}>Submit</button>
</form>
</div>
<div class="games">
<h1>Games</h1>
{#each games as game (game.id)}
<section>
<div>
<h2>{game.name}</h2>
<p>price : {game.price}</p>
<p>year_published : {game.year_published}</p>
<p>min_players : {game.min_players}</p>
<p>max_players : {game.max_players}</p>
<p>min_playtime : {game.min_playtime}</p>
<p>max_playtime : {game.max_playtime}</p>
<p>min_age : {game.min_age}</p>
<p>players : {game.players}</p>
<p>playtime : {game.playtime}</p>
<div class="description">{@html game.description}</div>
</div>
</section>
{/each}
</div>
<style>
h2 {
text-align: center;
font-size: 2.5rem;
font-weight: 600;
}
.games {
display: grid;
gap: 2rem;
}
.description {
margin: 1rem;
}
.game-form {
display: grid;
grid-template-columns: 1fr;
}
</style>

84
src/routes/games/index.ts Normal file
View file

@ -0,0 +1,84 @@
import type { RequestHandler } from '@sveltejs/kit';
import { boardGameApi } from '../_api';
export const get: RequestHandler = async ({ params }) => {
const queryParams = {
order_by: 'rank',
ascending: 'false',
limit: '10',
}
const response = await boardGameApi('get', `search`, queryParams);
console.log('response', response);
if (response.status === 404) {
// user hasn't created a todo list.
// start with an empty array
return {
body: {
games: []
}
};
}
if (response.status === 200) {
const gameResponse = await response.json();
const games = gameResponse?.games;
console.log('games', games);
return {
body: {
games: gameResponse?.games,
}
};
}
return {
status: response.status
};
}
export const post: RequestHandler = async ({ request }) => {
const form = await request.formData();
const minAge = form.get('minAge') || 0;
console.log('minAge', minAge);
const maxAge = form.get('maxAge') || 0;
console.log('maxAge', maxAge);
const minPlayers = form.get('minPlayers') || 1;
console.log('minPlayers', minPlayers);
const maxPlayers = form.get('maxPlayers') || 1;
console.log('maxPlayers', maxPlayers);
const queryParams = {
order_by: 'rank',
ascending: 'false',
limit: '2',
gt_min_players: String(+minPlayers === 1 ? 0 : +minPlayers - 1),
lt_max_players: String(+maxPlayers + 1),
gt_min_age: String(+minAge === 1 ? 0 : +minAge - 1),
lt_max_age: String(+maxAge + 1),
}
const response = await boardGameApi('get', `search`, queryParams);
console.log('response', response);
if (response.status === 404) {
// user hasn't created a todo list.
// start with an empty array
return {
body: {
games: []
}
};
}
if (response.status === 200) {
const gameResponse = await response.json();
const games = gameResponse?.games;
console.log('games', games);
return {
body: {
games: gameResponse?.games,
}
};
}
return {
status: response.status
};
}

View file

@ -3,7 +3,38 @@
</script>
<script lang="ts">
import Counter from '$lib/Counter.svelte';
import { enhance } from "$lib/form";
import { Button } from "carbon-components-svelte";
import { NumberInput } from "carbon-components-svelte";
let minAge = 0;
let maxAge = 0;
let minPlayers = 0;
let maxPlayers = 0;
let loading = false;
// type Game = {
// id: string;
// handle: string;
// name: string;
// url: string;
// edit_url: string;
// price: number;
// price_ca: number;
// price_uk: number;
// price_au: number;
// msrp: number;
// year_published: number;
// min_players: number;
// max_players: number;
// min_playtime: number;
// max_playtime: number;
// min_age: number;
// description: string;
// players: string;
// playtime: string;
// }
export let games = [];
</script>
<svelte:head>
@ -13,20 +44,64 @@
<section>
<h1>
<div class="welcome">
<picture>
<source srcset="svelte-welcome.webp" type="image/webp" />
<img src="svelte-welcome.png" alt="Welcome" />
</picture>
Search for a board game!
</div>
to your new<br />SvelteKit app
</h1>
Games: {JSON.stringify(games, null, 2)}
<form
action="/games"
method="post"
use:enhance={{
pending: () => {
loading = true;
},
result: async ({ data, form, response }) => {
loading = false;
console.log(JSON.stringify(data))
}
}}
>
<fieldset aria-busy={loading} disabled={loading}>
<label for="minAge">Min Age:
<input id="minAge" name="minAge" type="range" min="0" max="120" step="1" bind:value={minAge} />
{minAge}
</label>
<label for="maxAge">Max Age:
<input id="maxAge" name="maxAge" type="range" min="0" max="120" step="1" bind:value={maxAge} />
{maxAge}
</label>
<label for="minPlayers">Min Players:
<input id="minPlayers" name="minPlayers" type="range" min="1" max="50" step="1" bind:value={minPlayers} />
{minPlayers}
</label>
<label for="maxPlayers">Max Players:
<input id="maxPlayers" name="maxPlayers" type="range" min="1" max="50" step="1" bind:value={maxPlayers} />
{maxPlayers}
</label>
</fieldset>
<button type="submit" disabled={loading}>Submit</button>
</form>
<h2>
try editing <strong>src/routes/index.svelte</strong>
</h2>
<Counter />
<div class="games">
<h1>Games</h1>
<!-- {#each games as game (game.id)}
<section>
<div>
<h2>{game.name}</h2>
<p>price : {game.price}</p>
<p>year_published : {game.year_published}</p>
<p>min_players : {game.min_players}</p>
<p>max_players : {game.max_players}</p>
<p>min_playtime : {game.min_playtime}</p>
<p>max_playtime : {game.max_playtime}</p>
<p>min_age : {game.min_age}</p>
<p>players : {game.players}</p>
<p>playtime : {game.playtime}</p>
<div class="description">{@html game.description}</div>
</div>
</section>
{/each} -->
</div>
</section>
<style>

50
src/routes/index.ts Normal file
View file

@ -0,0 +1,50 @@
import { boardGameApi } from './_api';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async ({ request, locals }) => {
const form = await request.formData();
const minAge = form.get('minAge') || 0;
console.log('minAge', minAge);
const maxAge = form.get('maxAge') || 0;
console.log('maxAge', maxAge);
const minPlayers = form.get('minPlayers') || 1;
console.log('minPlayers', minPlayers);
const maxPlayers = form.get('maxPlayers') || 1;
console.log('maxPlayers', maxPlayers);
const queryParams = {
order_by: 'rank',
ascending: 'false',
limit: '2',
gt_min_players: String(+minPlayers === 1 ? 0 : +minPlayers - 1),
lt_max_players: String(+maxPlayers + 1),
gt_min_age: String(+minAge === 1 ? 0 : +minAge - 1),
lt_max_age: String(+maxAge + 1),
}
const response = await boardGameApi('get', `search`, queryParams);
console.log('response', response);
if (response.status === 404) {
// user hasn't created a todo list.
// start with an empty array
return {
body: {
games: []
}
};
}
if (response.status === 200) {
const gameResponse = await response.json();
const games = gameResponse?.games;
console.log('games', games);
return {
body: {
games: gameResponse?.games,
}
};
}
return {
status: response.status
};
};

View file

@ -1,5 +1,5 @@
import { api } from './_api';
import type { RequestHandler } from './index';
import type { RequestHandler } from '@sveltejs/kit';
export const get: RequestHandler = async ({ locals }) => {
// locals.userid comes from src/hooks.js