feat: Game page linked from home page

This commit is contained in:
Bradley Shellnut 2022-07-10 21:17:59 -07:00
parent 3c1cd6e13d
commit 462b0b5310
6 changed files with 121 additions and 192 deletions

View file

@ -9,7 +9,7 @@
<article class="game-container" transition:fade> <article class="game-container" transition:fade>
<div class="game-info"> <div class="game-info">
<h2>{game.name}</h2> <h2>{game.name}</h2>
<a class="thumbnail" href={game.url}> <a class="thumbnail" href={`/game/${game.id}`}>
<img width="140" height="140" src={game.thumb_url} alt={`Image of ${game.name}`} /> <img width="140" height="140" src={game.thumb_url} alt={`Image of ${game.name}`} />
</a> </a>
</div> </div>
@ -50,5 +50,11 @@
&:hover { &:hover {
background-color: hsla(222, 9%, 65%, 1); background-color: hsla(222, 9%, 65%, 1);
} }
.game-info {
margin: 0.2rem;
display: grid;
gap: 0.5rem;
}
} }
</style> </style>

View file

@ -11,6 +11,7 @@ export const post: RequestHandler = async ({ request }) => {
client_id: import.meta.env.VITE_PUBLIC_CLIENT_ID client_id: import.meta.env.VITE_PUBLIC_CLIENT_ID
}; };
const id = form.get('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');
@ -58,6 +59,11 @@ export const post: RequestHandler = async ({ request }) => {
queryParams.lt_max_players = +maxPlayers + 1; queryParams.lt_max_players = +maxPlayers + 1;
} }
} }
if (id) {
queryParams.ids = new Array(`${id}`);
}
queryParams.random = random; queryParams.random = random;
console.log('queryParams', queryParams); console.log('queryParams', queryParams);
@ -70,9 +76,8 @@ export const post: RequestHandler = async ({ request }) => {
const urlQueryParams = new URLSearchParams(newQueryParams); const urlQueryParams = new URLSearchParams(newQueryParams);
const url = `https://api.boardgameatlas.com/api/search${ const url = `https://api.boardgameatlas.com/api/search${urlQueryParams ? `?${urlQueryParams}` : ''
urlQueryParams ? `?${urlQueryParams}` : '' }`;
}`;
const response = await fetch(url, { const response = await fetch(url, {
method: 'get', method: 'get',
headers: { headers: {

View file

@ -0,0 +1,72 @@
<script lang="ts">
import type { GameType } from '$lib/types';
import { Checkbox, NumberInput } from 'carbon-components-svelte';
// import { enhance } from "$lib/form";
export let game: GameType;
</script>
<svelte:head>
<title>{game?.name} | Bored Game</title>
</svelte:head>
<h2>{game?.name}</h2>
<section class="games">
<div>
<a class="thumbnail" href={game.url}>
<img src={game.image_url} alt={`Image of ${game.name}`} />
</a>
</div>
<div class="description">
{@html game?.description}
<div>
<p>Price: {game?.price}</p>
<p>Year Published: {game?.year_published}</p>
<p>Players: {game.players} {game.max_players === 1 ? 'player' : 'players'}</p>
<p>Playtime: {game.playtime} minutes</p>
<p>Minimum Age: {game.min_age}</p>
<a href={game.url} rel="noreferrer">Board Game Atlas Link</a>
</div>
</div>
</section>
<style lang="scss">
h2 {
text-align: center;
font-size: 2.5rem;
font-weight: 600;
margin-bottom: 3rem;
}
button {
border-radius: 4px;
margin: 0;
padding: 0.2rem;
background-color: var(--color-btn-primary-active);
}
.games {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
margin: 1rem;
}
.description {
display: grid;
gap: 1.5rem;
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>

View file

@ -1,39 +1,37 @@
import type { RequestHandler } from '@sveltejs/kit'; import type { RequestHandler } from '@sveltejs/kit';
import { boardGameApi } from '../_api'; import { boardGameApi } from '../_api';
// export const get: RequestHandler = async ({ params }) => { export const get: RequestHandler = async ({ params }) => {
// const queryParams = { // console.log('params', params);
// order_by: 'rank', const queryParams = {
// ascending: 'false', ids: `${params?.id}`,
// limit: '10', }
// } console.log('queryParams', queryParams);
// const response = await boardGameApi('get', `search`, queryParams); const response = await boardGameApi('get', `search`, queryParams);
// console.log('response', response); if (response.status === 404) {
// if (response.status === 404) { return {
// // user hasn't created a todo list. body: {
// // start with an empty array games: []
// return { }
// body: { };
// games: [] }
// }
// };
// }
// if (response.status === 200) { if (response.status === 200) {
// const gameResponse = await response.json(); const gameResponse = await response.json();
// const games = gameResponse?.games; // console.log('gameResponse', gameResponse);
// console.log('games', games); // const games = gameResponse?.games;
// return { console.log('game', gameResponse?.games[0]);
// body: { return {
// games: gameResponse?.games, body: {
// } game: gameResponse?.games[0],
// }; }
// } };
}
// return { return {
// status: response.status status: response.status
// }; };
// } }
// export const post: RequestHandler = async ({ request }) => { // export const post: RequestHandler = async ({ request }) => {
// const form = await request.formData(); // const form = await request.formData();

View file

@ -1,156 +0,0 @@
<script lang="ts">
import type { Game } from '$lib/types';
import { Checkbox, NumberInput } from 'carbon-components-svelte';
// import { enhance } from "$lib/form";
let games: Game[] = [];
let submitting = false;
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>
<svelte:head>
<title>Games</title>
</svelte:head>
<h1>Search Boardgames!</h1>
<section>
<p>Input your requirements to search for board game that match your criteria</p>
</section>
<div class="game-form">
<form on:submit|preventDefault={handleSubmit} method="post">
<fieldset aria-busy={submitting} disabled={submitting}>
<div>
<NumberInput
name="minAge"
min={0}
max={120}
bind:value={minAge}
invalidText="Number must be between 0 and 120"
label="Min Age"
/>
<Checkbox
name="exactMinAge"
bind:value={exactMinAge}
labelText="Search exact?"
bind:checked={exactMinAge}
/>
</div>
<div>
<NumberInput
name="minPlayers"
min={1}
max={50}
bind:value={minPlayers}
invalidText="Number must be between 1 and 50"
label="Min Players"
/>
<Checkbox
name="exactMinPlayers"
labelText="Search exact?"
bind:value={exactMinPlayers}
bind:checked={exactMinPlayers}
/>
</div>
<div>
<NumberInput
name="maxPlayers"
min={1}
max={50}
bind:value={maxPlayers}
invalidText="Number must be between 1 and 50"
label="Max Players"
/>
<Checkbox
name="exactMaxPlayers"
labelText="Search exact?"
bind:value={exactMaxPlayers}
bind:checked={exactMaxPlayers}
/>
</div>
</fieldset>
<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">
<h1>Games</h1>
{#each games as game}
<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 lang="scss">
h2 {
text-align: center;
font-size: 2.5rem;
font-weight: 600;
}
button {
border-radius: 4px;
margin: 0;
padding: 0.2rem;
background-color: var(--color-btn-primary-active);
}
.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>

View file

@ -184,7 +184,11 @@
grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(3, 1fr);
gap: 2rem; gap: 2rem;
@media(max-width: 580px) { @media (max-width: 800px) {
grid-template-columns: 1fr 1fr;
}
@media (max-width: 550px) {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
} }