mirror of
https://github.com/BradNut/boredgame
synced 2025-09-08 17:40:22 +00:00
Fix posting data to board game endpoint.
This commit is contained in:
parent
8e2257ee79
commit
6b2a529abe
8 changed files with 1363 additions and 217 deletions
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
1293
pnpm-lock.yaml
1293
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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, {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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%;
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue