mirror of
https://github.com/BradNut/boredgame
synced 2025-09-08 17:40:22 +00:00
Adding collection store, adding buttons to add/remove from collection, toast on add/remove, random button for collection.
This commit is contained in:
parent
bb1f51dcfd
commit
7d775608cd
8 changed files with 99 additions and 6 deletions
|
|
@ -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;
|
||||
|
|
|
|||
26
src/lib/components/random/index.svelte
Normal file
26
src/lib/components/random/index.svelte
Normal 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>
|
||||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
28
src/lib/stores/collectionStore.ts
Normal file
28
src/lib/stores/collectionStore.ts
Normal 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();
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue