Adding collection store, adding buttons to add/remove from collection, toast on add/remove, random button for collection.

This commit is contained in:
Bradley Shellnut 2022-07-26 17:23:58 -07:00
parent bb1f51dcfd
commit 7d775608cd
8 changed files with 99 additions and 6 deletions

View file

@ -1,9 +1,22 @@
<script lang="ts">
import { fade } from 'svelte/transition';
import type { GameType } from '$lib/types';
import { ToastType, type GameType } from '$lib/types';
import { collectionStore } from '$lib/stores/collectionStore';
import { toast } from '../toast/toast';
export let game: GameType;
export let detailed: boolean = false;
$: existsInCollection = $collectionStore.find((item: GameType) => item.id === game.id);
function addToCollection() {
collectionStore.add(game)
toast.send(`"${game.name}" added to collection!`, { duration: 3000, type: ToastType.INFO });
}
function removeFromCollection() {
collectionStore.remove(game.id)
toast.send(`Removed "${game.name}" from collection!`, { duration: 3000, type: ToastType.INFO });
}
</script>
<article class="game-container" transition:fade>
@ -24,6 +37,12 @@
<div class="description">{@html game.description}</div>
{/if}
</div>
{#if existsInCollection}
<button type="button" on:click={removeFromCollection}>Remove from collection -</button>
{:else}
<button type="button" on:click={addToCollection}>Add to collection +</button>
{/if}
</article>
<style lang="scss">
@ -36,6 +55,13 @@
border-radius: 10px;
}
button {
width: 100%;
border-radius: 10px;
padding: 1rem;
background-color: var(--color-btn-primary-active);
}
.game-container {
display: flex;
flex-wrap: wrap;

View file

@ -0,0 +1,26 @@
<script lang="ts">
import { boredState } from '$lib/stores/boredState';
import { gameStore } from '$lib/stores/gameSearchStore';
import { collectionStore } from '$lib/stores/collectionStore';
import { toast } from '$lib/components/toast/toast';
import { ToastType } from '$lib/types';
function getRandomCollectionGame() {
if ($collectionStore.length > 0) {
boredState.set({ loading: true });
let randomNumber: number = Math.round(Math.random() * $collectionStore.length - 1);
if ($collectionStore.at(randomNumber)) {
gameStore.removeAll();
gameStore.add($collectionStore.at(randomNumber));
boredState.set({ loading: false });
} else {
toast.send('Error!', { duration: 3000, type: ToastType.ERROR, dismissible: true });
}
boredState.set({ loading: false });
} else {
toast.send('No items in your collection!', { duration: 3000, type: ToastType.ERROR, dismissible: true });
}
}
</script>
<button class="btn" type="button" on:click={getRandomCollectionGame}>Random from collection 🎲</button>

View file

@ -26,7 +26,7 @@
<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>
<button type="submit" disabled={submitting}>Random Game 🎲</button>
</fieldset>
</form>

View file

@ -0,0 +1,28 @@
import { writable } from 'svelte/store';
import type { GameType } from '$lib/types';
// Custom store
const state = () => {
const { subscribe, set, update } = writable<GameType[]>([]);
function add(game: GameType) {
update((store) => [...store, game]);
}
function remove(id: string) {
update((store) => {
const newStore = store.filter((item: GameType) => item.id !== id);
return [...newStore];
});
}
function removeAll() {
update(() => {
return [];
});
}
return { subscribe, set, update, add, remove, removeAll };
};
export const collectionStore = state();

View file

@ -3,14 +3,17 @@ export type BoredStore = {
}
export enum ToastType {
INFO,
ERROR,
WARNING
INFO = "INFO",
ERROR = "ERROR",
WARNING = "WARNING"
}
export type ToastData = {
id: number;
duration: number;
dismissible: boolean;
showButton: boolean;
autoDismiss: boolean;
type: ToastType;
message: string;
};

View file

@ -5,14 +5,17 @@
import Transition from '$lib/components/transition/index.svelte';
import Portal from '$lib/Portal.svelte';
import { boredState } from '$lib/stores/boredState';
import { collectionStore } from '$lib/stores/collectionStore';
import { toast } from '$lib/components/toast/toast';
// import 'carbon-components-svelte/css/all.css';
import '$root/styles/styles.scss';
import Toast from '$lib/components/toast/Toast.svelte';
const dev = process.env.NODE_ENV !== 'production';
</script>
{#if dev}
<Toy register={{ boredState }} />
<Toy register={{ boredState, collectionStore, toast }} />
{/if}
<Transition transition={{ type: 'fade', duration: 250 }}>
<div class="wrapper">
@ -44,6 +47,7 @@
<div class="background" />
</Portal>
{/if}
<Toast duration={3000} />
</Transition>
<style lang="scss">

View file

@ -9,6 +9,7 @@
import TextSearch from '$lib/components/search/textSearch/index.svelte';
import AdvancedSearch from '$lib/components/search/advancedSearch/index.svelte';
import RandomSearch from '$lib/components/search/random/index.svelte';
import Random from '$lib/components/random/index.svelte';
import { gameStore } from '$lib/stores/gameSearchStore';
import { boredState } from '$lib/stores/boredState';
import { Checkbox } from 'carbon-components-svelte';
@ -27,6 +28,7 @@
<TextSearch />
<AdvancedSearch />
<RandomSearch />
<Random />
</div>
<!-- {#if submitting}

View file

@ -18,6 +18,7 @@
--clr-input-txt: hsl(177 100% 15%);
--red: #990000;
--tomatoOrange: #e54b4b;
--redBrown: #633539;
--blue: #336699;
--black: #1f273a;
@ -127,6 +128,9 @@
--rounded-4: 4px;
--rounded-20: 20px;
--toast-background: var(--color-brand);
--toast-error-background: var(--tomatoOrange);
/* Media Queryies - Not yet supported in CSS */
/*
--xsmall: 340px;