Adding dialog just to the game collection for now and using a custom event for removing.

This commit is contained in:
Bradley Shellnut 2022-08-30 17:36:37 -05:00
parent 7b9e1cdaa2
commit 5236ac5c2b
8 changed files with 108 additions and 65 deletions

View file

@ -1,4 +1,5 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition';
import { MinusCircleIcon, PlusCircleIcon } from '@rgossiaux/svelte-heroicons/outline';
import type { GameType, SavedGameType } from '$lib/types';
@ -8,6 +9,13 @@
export let game: GameType | SavedGameType;
export let minimal: boolean = false;
export let detailed: boolean = false;
const dispatch = createEventDispatcher();
function removeGame() {
dispatch('removeGameEvent', game);
}
$: existsInCollection = $collectionStore.find((item: SavedGameType) => item.id === game.id);
</script>
@ -36,8 +44,7 @@
aria-label="Remove from collection"
class="btn"
type="button"
on:click={() => removeFromCollection(game)}
>Remove <MinusCircleIcon width="24" height="24" /></button
on:click={() => removeGame()}>Remove <MinusCircleIcon width="24" height="24" /></button
>
{:else}
<button

View file

@ -7,7 +7,7 @@
async function getRandomCollectionGame() {
if ($collectionStore.length > 0) {
boredState.set({ loading: true, dialogOpen: false });
boredState.set({ loading: true });
let randomNumber: number = Math.round(Math.random() * $collectionStore.length - 1);
if ($collectionStore.at(randomNumber)) {
gameStore.removeAll();
@ -19,11 +19,11 @@
const responseData = await response.json();
console.log('responseData', responseData);
gameStore.add(responseData?.game);
boredState.set({ loading: false, dialogOpen: false });
boredState.set({ loading: false });
} else {
toast.send('Error!', { duration: 3000, type: ToastType.ERROR, dismissible: true });
}
boredState.set({ loading: false, dialogOpen: false });
boredState.set({ loading: false });
} else {
toast.send('No items in your collection!', {
duration: 3000,

View file

@ -4,7 +4,7 @@
async function handleSubmit(event: SubmitEvent) {
// submitting = true;
boredState.set({ loading: true, dialogOpen: false });
boredState.set({ loading: true });
const form = event.target as HTMLFormElement;
console.log('form', form);
const response = await fetch('/api/games', {
@ -14,7 +14,7 @@
});
const responseData = await response.json();
// submitting = false;
boredState.set({ loading: false, dialogOpen: false });
boredState.set({ loading: false });
gameStore.removeAll();
gameStore.addAll(responseData?.games);
// games = responseData?.games;

View file

@ -4,7 +4,7 @@ import { writable } from 'svelte/store';
// Custom store
const state = () => {
const { subscribe, set, update } = writable<BoredStore>({ loading: false, dialogOpen: false });
const { subscribe, set, update } = writable<BoredStore>({ loading: false });
// function remove(id: string) {
// update((store) => {
@ -20,7 +20,7 @@ const state = () => {
// }
function clear() {
set({ loading: false, dialogOpen: false });
set({ loading: false });
}
return { subscribe, set, update, clear };

View file

@ -1,6 +1,5 @@
export type BoredStore = {
loading: boolean;
dialogOpen: boolean;
};
export enum ToastType {

View file

@ -1,15 +1,8 @@
<script lang="ts">
import { browser } from '$app/environment';
import { fade } from 'svelte/transition';
import { navigating } from '$app/stores';
import debounce from 'just-debounce-it';
import { Toy } from '@leveluptuts/svelte-toy';
import {
Dialog,
DialogOverlay,
DialogTitle,
DialogDescription
} from '@rgossiaux/svelte-headlessui';
import Header from '$lib/components/header/Header.svelte';
import Loading from '$lib/components/loading.svelte';
import Transition from '$lib/components/transition/index.svelte';
@ -24,11 +17,11 @@
$: {
if ($navigating) {
debounce(() => {
boredState.set({ loading: true, dialogOpen: false });
boredState.set({ loading: true });
}, 250);
}
if (!$navigating) {
boredState.set({ loading: false, dialogOpen: false });
boredState.set({ loading: false });
}
}
@ -81,51 +74,10 @@
<div class="background" />
</Portal>
{/if}
{#if $boredState?.dialogOpen}
<div transition:fade>
<Dialog
open={$boredState?.dialogOpen}
on:close={() => boredState.set({ loading: false, dialogOpen: false })}
static
>
<DialogOverlay
style={'position: fixed; inset: 0; z-index: 100; background-color: rgb(0 0 0); opacity: 0.3;'}
/>
<div class="dialog">
<DialogTitle>Deactivate account</DialogTitle>
<DialogDescription>This will permanently deactivate your account</DialogDescription>
<p>
Are you sure you want to deactivate your account? All of your data will be permanently
removed. This action cannot be undone.
</p>
<button on:click={() => boredState.set({ loading: false, dialogOpen: false })}
>Deactivate</button
>
<button on:click={() => boredState.set({ loading: false, dialogOpen: false })}
>Cancel</button
>
</div>
</Dialog>
</div>
{/if}
<Toast />
</Transition>
<style lang="scss">
:global(.dialog) {
position: fixed;
top: 25%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 101;
border-radius: 10px;
background-color: var(--primary);
padding: 2rem;
/* max-width: 400px; */
}
.loading {
position: fixed;
top: 50%;

View file

@ -8,7 +8,7 @@
import { boredState } from '$root/lib/stores/boredState';
async function handleSearch(event: SubmitEvent) {
boredState.set({ loading: true, dialogOpen: false });
boredState.set({ loading: true });
const form = event.target as HTMLFormElement;
console.log('form', form);
const response = await fetch('/api/game', {
@ -17,7 +17,7 @@
body: new FormData(form)
});
const responseData = await response.json();
boredState.set({ loading: false, dialogOpen: false });
boredState.set({ loading: false });
gameStore.removeAll();
gameStore.addAll(responseData?.games);
}

View file

@ -1,6 +1,30 @@
<script lang="ts">
import { fade } from 'svelte/transition';
import {
Dialog,
DialogDescription,
DialogOverlay,
DialogTitle
} from '@rgossiaux/svelte-headlessui';
import Game from '$lib/components/game/index.svelte';
import { collectionStore } from '$lib/stores/collectionStore';
import type { GameType, SavedGameType } from '$root/lib/types';
import { removeFromCollection } from '$root/lib/util/manipulateCollection';
let isOpen: boolean = false;
let gameToRemove: GameType | SavedGameType;
console.log('isOpen', isOpen);
function handleRemoveGame(event: Event) {
console.log('event', event);
gameToRemove = event?.detail;
isOpen = true;
}
function removeGame() {
removeFromCollection(gameToRemove);
isOpen = false;
}
</script>
<svelte:head>
@ -11,11 +35,37 @@
<div class="games">
<div class="games-list">
{#each $collectionStore as game}
<Game minimal {game} />
{/each}
{#if $collectionStore.length === 0}
<h2>No games in your collection</h2>
{:else}
{#each $collectionStore as game}
<Game on:removeGameEvent={handleRemoveGame} minimal {game} />
{/each}
{/if}
</div>
</div>
{#if isOpen}
<!-- <div class="container"> -->
<div transition:fade>
<Dialog open={isOpen} on:close={() => (isOpen = false)} static>
<div transition:fade>
<DialogOverlay class="dialog-overlay" />
<div class="dialog">
<DialogTitle>Remove from collection</DialogTitle>
<DialogDescription
>Are you sure you want to remove from your collection?</DialogDescription
>
<div class="dialog-footer">
<button on:click={() => removeGame()}>Remove</button>
<button on:click={() => (isOpen = false)}>Cancel</button>
</div>
</div>
</div>
</Dialog>
</div>
<!-- </div> -->
{/if}
<style lang="scss">
h1 {
@ -39,4 +89,39 @@
grid-template-columns: 1fr;
}
}
:global(.dialog) {
display: grid;
gap: 1.5rem;
position: fixed;
top: 25%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 101;
border-radius: 10px;
background-color: var(--primary);
padding: 2rem;
max-width: 500px;
}
:global(.dialog-overlay) {
position: fixed;
inset: 0;
z-index: 100;
background-color: rgb(0 0 0);
opacity: 0.8;
}
:global(.dialog-footer) {
display: flex;
justify-content: space-between;
gap: 2rem;
margin: 1rem 0;
}
/*
.container > .button {
display: grid;
justify-content: center;
background-color: var(--primary);
} */
</style>