Creating Button and Link with Icon components, formatting error on advanced search, and adding more to the local storage saved Game.

This commit is contained in:
Bradley Shellnut 2022-11-01 22:10:02 -05:00
parent c1d4e5a2d9
commit 06a7d342a3
9 changed files with 116 additions and 37 deletions

1
.gitignore vendored
View file

@ -8,3 +8,4 @@ node_modules
!.env.example
.vercel
.output
.idea

View file

@ -0,0 +1,25 @@
<script lang="ts">
import type { SvelteComponentTyped } from 'svelte';
export let url: string;
export let ariaLabel = `Link to ${url}`;
export let external = false;
</script>
<a
href={url}
target={external ? '_blank' : '_self'}
rel="noreferrer"
aria-label={`Board Game Atlas Link for ${ariaLabel}`}
>
<slot />
</a>
<style>
a {
display: grid;
grid-template-columns: repeat(2, auto);
place-items: center;
gap: 1rem;
}
</style>

View file

@ -0,0 +1,37 @@
<script lang="ts">
export let kind = 'primary';
export let size;
export let icon = false;
export let disabled = false;
</script>
<button class={`btn ${icon ? 'btn-icon' : ''} ${kind}`} type="button" {disabled} on:click>
<slot />
</button>
<style>
button {
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 4px;
margin: 0;
padding: 1rem;
max-width: 30rem;
background-color: var(--color-btn-primary-active);
}
.danger {
background-color: var(--warning);
}
.danger:hover {
background-color: var(--warning-hover);
}
.btn-icon {
display: grid;
grid-template-columns: repeat(2, auto);
gap: 1rem;
}
</style>

View file

@ -28,27 +28,22 @@
</script>
<article class="game-container" transition:fade>
<!-- <div class="game-info"> -->
<h2>{game.name}</h2>
<a class="thumbnail" href={`/game/${game.id}`}>
<img src={game.thumb_url} alt={`Image of ${game.name}`} />
</a>
<!-- </div> -->
{#if !minimal && game?.players && game?.playtime}
<div class="game-details">
{#if game.year_published}
<p>{game.year_published}</p>
{/if}
<p>{game.players} {game.max_players === 1 ? 'player' : 'players'}</p>
<p>{game.playtime} minutes</p>
<p>Minimum Age: {game.min_age}</p>
<!-- <a href={`/game/${game.id}`}>View Game</a> -->
{#if detailed}
<div class="description">{@html game.description}</div>
{/if}
</div>
{/if}
<div class="game-details">
<p>Players: {game.min_players} - {game.max_players}</p>
<p>Time: {game.playtime} minutes</p>
{#if game?.min_age}
<p>Min Age: {game.min_age}</p>
{/if}
{#if detailed}
<div class="description">{@html game.description}</div>
{/if}
</div>
<div class="game-buttons">
{#if existsInCollection}
<button

View file

@ -41,7 +41,9 @@
/>
</label>
{#if form?.error?.id === 'minPlayers'}
{form.error.message}
<p aria-label={`Error: ${form.error.message}`} class="center error">
Error: {form.error.message}
</p>
{/if}
</div>
<div>
@ -65,6 +67,11 @@
bind:checked={exactMaxPlayers}
/>
</label>
{#if form?.error?.id === 'maxPlayers'}
<p aria-label={`Error: ${form.error.message}`} class="center error">
Error: {form.error.message}
</p>
{/if}
</div>
</fieldset>
<!-- <button type="submit" disabled={submitting}>Submit</button> -->

View file

@ -39,6 +39,9 @@ export type SavedGameType = {
id: string;
name: string;
thumb_url: string;
min_players: number;
max_players: number;
playtime: string
}
export type GameType = {

View file

@ -1,12 +1,15 @@
import type { GameType, SavedGameType } from '$lib/types';
export function mapSavedGameToGame(game: SavedGameType): GameType {
const { id, name, thumb_url } = game;
const { id, name, thumb_url, min_players, max_players, playtime } = game;
return {
id,
name,
thumb_url
thumb_url,
min_players,
max_players,
playtime
};
}

View file

@ -9,11 +9,13 @@
} from '@rgossiaux/svelte-heroicons/outline';
import type { GameType, SavedGameType } from '$lib/types';
import { collectionStore } from '$lib/stores/collectionStore';
import Button from '$lib/components/button/index.svelte';
import RemoveCollectionDialog from '$root/lib/components/dialog/RemoveCollectionDialog.svelte';
import { addToCollection } from '$lib/util/manipulateCollection';
import type { PageData } from './$types';
import { boredState } from '$root/lib/stores/boredState';
import { browser } from '$app/environment';
import LinkWithIcon from '$root/lib/components/LinkWithIcon.svelte';
$: existsInCollection = $collectionStore.find((item: SavedGameType) => item.id === game.id);
@ -55,38 +57,36 @@
</div>
<div style="display: grid; place-items: center;">
<div class="details">
<p>Year Published: {game?.year_published}</p>
<p>Players: {game.players} {game.max_players === 1 ? 'player' : 'players'}</p>
<p>Year: {game?.year_published}</p>
<p>Players: {game.players}</p>
<p>Playtime: {game.playtime} minutes</p>
<p>Minimum Age: {game.min_age}</p>
{#if +game?.price !== 0.0}
{#if game?.price !== 0.0}
<p>Price: ${game?.price}</p>
{/if}
<a
class="with-icon"
href={game.url}
target="_blank"
rel="noreferrer"
aria-label={`Board Game Atlas Link for ${game.name}`}
>Board Game Atlas <ExternalLinkIcon width="24" height="24" /></a
>
<LinkWithIcon external ariaLabel={`Board Game Atlas Link for ${game.name}`} url={game.url}>
Board Game Atlas <ExternalLinkIcon width="24" height="24" />
</LinkWithIcon>
</div>
<div>
{#if existsInCollection}
<button class="btn button-icon remove" type="button" on:click={() => removeGame()}
>Remove from collection <MinusCircleIcon width="24" height="24" /></button
>
<Button size="md" kind="danger" icon on:click={() => removeGame()}>
Remove from collection <MinusCircleIcon width="24" height="24" />
</Button>
{:else}
<button
class="btn"
type="button"
<Button
size="md"
kind="primary"
icon
on:click={() => {
addToCollection(game);
if (browser) {
localStorage.collection = JSON.stringify($collectionStore);
}
}}>Add to collection <PlusCircleIcon width="24" height="24" /></button
}}
>
Add to collection <PlusCircleIcon width="24" height="24" />
</Button>
{/if}
</div>
</div>

View file

@ -348,4 +348,12 @@ ol {
.icon {
width: 24px;
height: 24px;
}
.center {
text-align: center;
}
.error {
color: var(--tomatoOrange);
}