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>
<div class="game-info">
<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}`} />
</a>
</div>
@ -50,5 +50,11 @@
&:hover {
background-color: hsla(222, 9%, 65%, 1);
}
.game-info {
margin: 0.2rem;
display: grid;
gap: 0.5rem;
}
}
</style>

View file

@ -11,6 +11,7 @@ export const post: RequestHandler = async ({ request }) => {
client_id: import.meta.env.VITE_PUBLIC_CLIENT_ID
};
const id = form.get('id');
const minAge = form.get('minAge');
const minPlayers = form.get('minPlayers');
const maxPlayers = form.get('maxPlayers');
@ -58,6 +59,11 @@ export const post: RequestHandler = async ({ request }) => {
queryParams.lt_max_players = +maxPlayers + 1;
}
}
if (id) {
queryParams.ids = new Array(`${id}`);
}
queryParams.random = random;
console.log('queryParams', queryParams);
@ -70,9 +76,8 @@ export const post: RequestHandler = async ({ request }) => {
const urlQueryParams = new URLSearchParams(newQueryParams);
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, {
method: 'get',
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 { 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: []
// }
// };
// }
export const get: RequestHandler = async ({ params }) => {
// console.log('params', params);
const queryParams = {
ids: `${params?.id}`,
}
console.log('queryParams', queryParams);
const response = await boardGameApi('get', `search`, queryParams);
if (response.status === 404) {
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,
// }
// };
// }
if (response.status === 200) {
const gameResponse = await response.json();
// console.log('gameResponse', gameResponse);
// const games = gameResponse?.games;
console.log('game', gameResponse?.games[0]);
return {
body: {
game: gameResponse?.games[0],
}
};
}
// return {
// status: response.status
// };
// }
return {
status: response.status
};
}
// export const post: RequestHandler = async ({ request }) => {
// 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);
gap: 2rem;
@media(max-width: 580px) {
@media (max-width: 800px) {
grid-template-columns: 1fr 1fr;
}
@media (max-width: 550px) {
grid-template-columns: 1fr;
}
}