Fix posting data to board game endpoint.

This commit is contained in:
Bradley Shellnut 2022-04-24 16:38:12 -07:00
parent 8e2257ee79
commit 6b2a529abe
8 changed files with 1363 additions and 217 deletions

View file

@ -14,7 +14,7 @@
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.21.1", "@playwright/test": "^1.21.1",
"@sveltejs/adapter-auto": "next", "@sveltejs/adapter-auto": "next",
"@sveltejs/kit": "^1.0.0-next.316", "@sveltejs/kit": "next",
"@types/cookie": "^0.5.0", "@types/cookie": "^0.5.0",
"@types/node": "^17.0.25", "@types/node": "^17.0.25",
"@typescript-eslint/eslint-plugin": "^5.20.0", "@typescript-eslint/eslint-plugin": "^5.20.0",
@ -37,6 +37,7 @@
"@fontsource/fira-mono": "^4.5.7", "@fontsource/fira-mono": "^4.5.7",
"@lukeed/uuid": "^2.0.0", "@lukeed/uuid": "^2.0.0",
"cookie": "^0.5.0", "cookie": "^0.5.0",
"node-sass": "^7.0.1",
"zod": "^3.14.4" "zod": "^3.14.4"
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -19,26 +19,23 @@
</div> </div>
<nav> <nav>
<Theme
render="toggle"
toggle={{
themes: ['white','g100'],
hideLabel: true,
size: 'sm'
}}
bind:theme
persist
persistKey="__carbon-theme"
/>
<ul> <ul>
<li class:active={$page.url.pathname === '/'}><a sveltekit:prefetch href="/">Home</a></li> <li class:active={$page.url.pathname === '/'}><a sveltekit:prefetch href="/">Home</a></li>
<li class:active={$page.url.pathname === '/about'}> <li class:active={$page.url.pathname === '/about'}>
<a sveltekit:prefetch href="/about">About</a> <a sveltekit:prefetch href="/about">About</a>
</li> </li>
<li class:active={$page.url.pathname === '/todos'}>
<a sveltekit:prefetch href="/todos">Todos</a>
</li>
</ul> </ul>
<Theme
render="toggle"
toggle={{
themes: ['white','g100'],
hideLabel: true,
size: 'sm'
}}
bind:theme
persist
persistKey="__carbon-theme"
/>
</nav> </nav>
</header> </header>

View file

@ -11,7 +11,7 @@
</main> </main>
<footer> <footer>
<p>visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to learn SvelteKit</p> <p>Built by <a target="__blank" href="https://bradleyshellnut.com">Bradley Shellnut</a></p>
</footer> </footer>
<style> <style>

View file

@ -1,21 +1,22 @@
import type { SearchQuery } from "$lib/types";
import type { RequestHandler } from "@sveltejs/kit"; import type { RequestHandler } from "@sveltejs/kit";
import type { SearchQuery } from "$lib/types";
export const post: RequestHandler = async ({ request }) => { export const post: RequestHandler = async ({ request }) => {
const form = await request.formData(); const form = await request.formData();
console.log('form', form);
const queryParams : SearchQuery = { const queryParams : SearchQuery = {
order_by: 'rank', order_by: 'rank',
ascending: false, ascending: false,
limit: 2, limit: 1,
client_id: import.meta.env.VITE_PUBLIC_CLIENT_ID, client_id: import.meta.env.VITE_PUBLIC_CLIENT_ID,
} }
const minAge = form.get('minAge'); const minAge = form.get('minAge');
const minPlayers = form.get('minPlayers'); const minPlayers = form.get('minPlayers');
const maxPlayers = form.get('maxPlayers'); const maxPlayers = form.get('maxPlayers');
const exactMinAge = form.get('exactMinAge') === 'on' || false; const exactMinAge = form.get('exactMinAge') || false;
const exactMinPlayers = form.get('exactMinPlayers') === 'on' || false; const exactMinPlayers = form.get('exactMinPlayers') || false;
const exactMaxPlayers = form.get('exactMaxPlayers') === 'on' || false; const exactMaxPlayers = form.get('exactMaxPlayers') || false;
const random = form.get('random') === 'on' || false; const random = form.get('random') === 'on' || false;
console.log("form.get('minAge')", form.get('minAge')); console.log("form.get('minAge')", form.get('minAge'));
@ -58,13 +59,16 @@ export const post: RequestHandler = async ({ request }) => {
} }
} }
queryParams.random = random; queryParams.random = random;
console.log('queryParams', queryParams);
const newQueryParams = {}; const newQueryParams = {};
for (const key in queryParams) { for (const key in queryParams) {
newQueryParams[key] = new String(queryParams[key]); console.log('key', key);
console.log('queryParams[key]', queryParams[key]);
newQueryParams[key] = `${queryParams[key]}`;
} }
const urlQueryParams = new URLSearchParams(newQueryParams); const urlQueryParams = new URLSearchParams(newQueryParams);
console.log('urlQueryParams', JSON.stringify(urlQueryParams, null, 2));
const url = `https://api.boardgameatlas.com/api/search${urlQueryParams ? `?${urlQueryParams}` : ''}` const url = `https://api.boardgameatlas.com/api/search${urlQueryParams ? `?${urlQueryParams}` : ''}`
const response = await fetch(url, { const response = await fetch(url, {

View file

@ -50,7 +50,7 @@ import { Checkbox, NumberInput } from "carbon-components-svelte";
invalidText="Number must be between 0 and 120" invalidText="Number must be between 0 and 120"
label="Min Age" label="Min Age"
/> />
<Checkbox name="exactMinAge" labelText="Search exact?" bind:checked={exactMinAge} /> <Checkbox name="exactMinAge" bind:value={exactMinAge} labelText="Search exact?" bind:checked={exactMinAge} />
</div> </div>
<div> <div>
<NumberInput <NumberInput
@ -61,7 +61,7 @@ import { Checkbox, NumberInput } from "carbon-components-svelte";
invalidText="Number must be between 1 and 50" invalidText="Number must be between 1 and 50"
label="Min Players" label="Min Players"
/> />
<Checkbox name="exactMinPlayers" labelText="Search exact?" bind:checked={exactMinPlayers} /> <Checkbox name="exactMinPlayers" labelText="Search exact?" bind:value={exactMinPlayers} bind:checked={exactMinPlayers} />
</div> </div>
<div> <div>
<NumberInput <NumberInput
@ -72,7 +72,7 @@ import { Checkbox, NumberInput } from "carbon-components-svelte";
invalidText="Number must be between 1 and 50" invalidText="Number must be between 1 and 50"
label="Max Players" label="Max Players"
/> />
<Checkbox name="exactMaxPlayers" labelText="Search exact?" bind:checked={exactMaxPlayers} /> <Checkbox name="exactMaxPlayers" labelText="Search exact?" bind:value={exactMaxPlayers} bind:checked={exactMaxPlayers} />
</div> </div>
</fieldset> </fieldset>
<button type="submit" disabled={submitting}>Submit</button> <button type="submit" disabled={submitting}>Submit</button>
@ -106,7 +106,7 @@ import { Checkbox, NumberInput } from "carbon-components-svelte";
{/each} {/each}
</div> </div>
<style> <style lang="scss">
h2 { h2 {
text-align: center; text-align: center;
font-size: 2.5rem; font-size: 2.5rem;

View file

@ -3,108 +3,147 @@
</script> </script>
<script lang="ts"> <script lang="ts">
import { enhance } from "$lib/form"; import { Checkbox, NumberInput } from "carbon-components-svelte";
import { Button } from "carbon-components-svelte"; import type { Game } from "$lib/types";
import { NumberInput } from "carbon-components-svelte"; // import { enhance } from "$lib/form";
let minAge = 0; let games: Game[] = [];
let maxAge = 0; let submitting = false;
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 = []; async function handleSubmit(event: SubmitEvent) {
submitting = true;
const form = event.target as HTMLFormElement;
console.log('form', form);
const response = await fetch('/api/games', {
method: 'post',
headers: { accept: 'application/json' },
body: new FormData(form)
});
const responseData = await response.json();
submitting = false;
games = responseData?.games;
}
let minAge = 0;
let minPlayers = 1;
let maxPlayers = 1;
let exactMinAge = false;
let exactMinPlayers = false;
let exactMaxPlayers = false;
</script> </script>
<svelte:head> <svelte:head>
<title>Home</title> <title>Home</title>
</svelte:head> </svelte:head>
<section> <h1>Search Boardgames!</h1>
<h1> <p>Input your requirements to search for board game that match your criteria</p>
<div class="welcome"> <div class="game-form">
Search for a board game! <form on:submit|preventDefault={handleSubmit} method="post">
</div> <fieldset aria-busy={submitting} disabled={submitting}>
</h1> <div>
Games: {JSON.stringify(games, null, 2)} <NumberInput
<form name="minAge"
action="/games" min={0}
method="post" max={120}
use:enhance={{ bind:value={minAge}
pending: () => { invalidText="Number must be between 0 and 120"
loading = true; label="Min Age"
}, />
result: async ({ data, form, response }) => { <Checkbox name="exactMinAge" bind:checked={exactMinAge} bind:value={exactMinAge} labelText="Search exact?" />
loading = false; </div>
console.log(JSON.stringify(data)) <div>
} <NumberInput
}} name="minPlayers"
> min={1}
<fieldset aria-busy={loading} disabled={loading}> max={50}
<label for="minAge">Min Age: bind:value={minPlayers}
<input id="minAge" name="minAge" type="range" min="0" max="120" step="1" bind:value={minAge} /> invalidText="Number must be between 1 and 50"
{minAge} label="Min Players"
</label> />
<label for="maxAge">Max Age: <Checkbox name="exactMinPlayers" labelText="Search exact?" bind:checked={exactMinPlayers} />
<input id="maxAge" name="maxAge" type="range" min="0" max="120" step="1" bind:value={maxAge} /> </div>
{maxAge} <div>
</label> <NumberInput
<label for="minPlayers">Min Players: name="maxPlayers"
<input id="minPlayers" name="minPlayers" type="range" min="1" max="50" step="1" bind:value={minPlayers} /> min={1}
{minPlayers} max={50}
</label> bind:value={maxPlayers}
<label for="maxPlayers">Max Players: invalidText="Number must be between 1 and 50"
<input id="maxPlayers" name="maxPlayers" type="range" min="1" max="50" step="1" bind:value={maxPlayers} /> label="Max Players"
{maxPlayers} />
</label> <Checkbox name="exactMaxPlayers" labelText="Search exact?" bind:checked={exactMaxPlayers} />
</fieldset> </div>
<button type="submit" disabled={loading}>Submit</button> </fieldset>
</form> <button type="submit" disabled={submitting}>Submit</button>
</form>
<form on:submit|preventDefault={handleSubmit} method="post">
<fieldset aria-busy={submitting} disabled={submitting}>
<input type="checkbox" id="random" name="random" hidden checked />
<button type="submit" disabled={submitting}>🎲</button>
</fieldset>
</form>
</div>
<div class="games"> <div class="games">
<h1>Games</h1> <h1>Games</h1>
<!-- {#each games as game (game.id)} {#each games as game}
<section> <section>
<div> <div>
<h2>{game.name}</h2> <h2>{game.name}</h2>
<p>price : {game.price}</p> <p>price : {game.price}</p>
<p>year_published : {game.year_published}</p> <p>year_published : {game.year_published}</p>
<p>min_players : {game.min_players}</p> <p>min_players : {game.min_players}</p>
<p>max_players : {game.max_players}</p> <p>max_players : {game.max_players}</p>
<p>min_playtime : {game.min_playtime}</p> <p>min_playtime : {game.min_playtime}</p>
<p>max_playtime : {game.max_playtime}</p> <p>max_playtime : {game.max_playtime}</p>
<p>min_age : {game.min_age}</p> <p>min_age : {game.min_age}</p>
<p>players : {game.players}</p> <p>players : {game.players}</p>
<p>playtime : {game.playtime}</p> <p>playtime : {game.playtime}</p>
<div class="description">{@html game.description}</div> <div class="description">{@html game.description}</div>
</div> </div>
</section> </section>
{/each} --> {/each}
</div> </div>
</section>
<style lang="scss">
h1 {
width: 100%;
}
h2 {
text-align: center;
font-size: 2.5rem;
font-weight: 600;
}
button {
border-radius: 4px;
margin: 0;
padding: 0.2rem;
background-color: palegreen;
}
.games {
display: grid;
gap: 2rem;
}
.description {
margin: 1rem;
}
.game-form {
display: flex;
place-items: center;
}
.game-form fieldset {
display: grid;
gap: 1rem;
grid-template-columns: repeat(3, minmax(200px, 1fr));
}
<style>
section { section {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -113,10 +152,6 @@
flex: 1; flex: 1;
} }
h1 {
width: 100%;
}
.welcome { .welcome {
position: relative; position: relative;
width: 100%; width: 100%;

View file

@ -6,7 +6,9 @@ import path from 'path';
const config = { const config = {
// Consult https://github.com/sveltejs/svelte-preprocess // Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors // for more information about preprocessors
preprocess: preprocess(), preprocess: preprocess({
scss: {},
}),
kit: { kit: {
adapter: adapter(), adapter: adapter(),