mirror of
https://github.com/jcreek/SvelteKitSaasBoilerplate.git
synced 2026-07-12 18:43:50 +00:00
refactor(#35): split out toast and toast store
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher } from 'svelte';
|
||||||
import { general } from '$lib/stores/generalStore.js';
|
import { scheduleToast } from '$lib/stores/toastStore.js';
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
@@ -28,21 +28,7 @@
|
|||||||
|
|
||||||
async function forgotPassword() {
|
async function forgotPassword() {
|
||||||
if (email === '') {
|
if (email === '') {
|
||||||
general.update((value) => {
|
scheduleToast('Please enter your email address', 'error', 5000);
|
||||||
return {
|
|
||||||
...value,
|
|
||||||
hideToast: false,
|
|
||||||
toastMessage: 'Please enter your email address',
|
|
||||||
toastType: 'error'
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
general.update((value) => {
|
|
||||||
return { ...value, hideToast: true, toastMessage: '', toastType: 'success' };
|
|
||||||
});
|
|
||||||
}, 5000);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,31 +38,11 @@
|
|||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error('Error sending password reset email:', error.message);
|
console.error('Error sending password reset email:', error.message);
|
||||||
general.update((value) => {
|
scheduleToast('Error sending password reset email. Please try again.', 'error', 5000);
|
||||||
return {
|
|
||||||
...value,
|
|
||||||
hideToast: false,
|
|
||||||
toastMessage: 'Error sending password reset email. Please try again.',
|
|
||||||
toastType: 'error'
|
|
||||||
};
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
console.log('Password reset email sent:', data);
|
console.log('Password reset email sent:', data);
|
||||||
general.update((value) => {
|
scheduleToast('Password reset email sent. Please check your inbox.', 'error', 5000);
|
||||||
return {
|
|
||||||
...value,
|
|
||||||
hideToast: false,
|
|
||||||
toastMessage: 'Password reset email sent. Please check your inbox.',
|
|
||||||
toastType: 'success'
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
general.update((value) => {
|
|
||||||
return { ...value, hideToast: true, toastMessage: '', toastType: 'success' };
|
|
||||||
});
|
|
||||||
}, 5000);
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { slide } from 'svelte/transition';
|
||||||
|
import { cubicInOut } from 'svelte/easing';
|
||||||
|
import { onDestroy } from 'svelte';
|
||||||
|
import { toast } from '$lib/stores/toastStore.js';
|
||||||
|
import type { Toast } from '$lib/types/Shared/Toast';
|
||||||
|
|
||||||
|
let localToast: Toast;
|
||||||
|
const unsubscribeToToastStore = toast.subscribe((value) => {
|
||||||
|
localToast = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
unsubscribeToToastStore();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if !localToast.hideToast}
|
||||||
|
<div
|
||||||
|
id={localToast.toastType == 'success' ? 'success-toast' : 'error-toast'}
|
||||||
|
role="alert"
|
||||||
|
class="alert {localToast.toastType == 'success'
|
||||||
|
? 'alert-success'
|
||||||
|
: 'alert-error'} fixed top-20 right-3 max-w-80 z-50 text-white"
|
||||||
|
transition:slide={{ duration: 200, easing: cubicInOut }}
|
||||||
|
>
|
||||||
|
{#if localToast.toastType == 'success'}
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="stroke-current shrink-0 h-6 w-6"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
><path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
|
{:else}
|
||||||
|
<svg
|
||||||
|
class="stroke-current shrink-0 h-6 w-6"
|
||||||
|
viewBox="0 0 32 32"
|
||||||
|
xml:space="preserve"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
><g
|
||||||
|
><g id="Error_1_"
|
||||||
|
><g id="Error">
|
||||||
|
<circle cx="16" cy="16" id="BG" r="16" style="fill:#E6E6E6;" />
|
||||||
|
<path
|
||||||
|
d="M14.5,25h3v-3h-3V25z M14.5,6v13h3V6H14.5z"
|
||||||
|
id="Exclamatory_x5F_Sign"
|
||||||
|
style="fill:#D72828;"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</g></g
|
||||||
|
></svg
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<span>{localToast.toastMessage}</span>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
import { writable } from 'svelte/store';
|
|
||||||
|
|
||||||
export const general = writable({ hideToast: true, toastMessage: '', toastType: 'success' });
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import type { Toast } from '$lib/types/Shared/Toast';
|
||||||
|
import { writable } from 'svelte/store';
|
||||||
|
|
||||||
|
const MIN_DELAY = 3000;
|
||||||
|
|
||||||
|
export const toast = writable<Toast>({ hideToast: true, toastMessage: '', toastType: 'success' });
|
||||||
|
|
||||||
|
export function scheduleToast(message: string, toastType: 'success' | 'error', delay: number = MIN_DELAY) {
|
||||||
|
|
||||||
|
toast.update((value) => {
|
||||||
|
return {
|
||||||
|
...value,
|
||||||
|
hideToast: false,
|
||||||
|
toastMessage: message,
|
||||||
|
toastType: toastType
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
toast.update((value) => {
|
||||||
|
return { ...value, hideToast: true, toastMessage: '' };
|
||||||
|
});
|
||||||
|
}, Math.max(delay, MIN_DELAY));
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export type Toast = {
|
||||||
|
hideToast: boolean,
|
||||||
|
toastMessage: string,
|
||||||
|
toastType: 'success' | 'error'
|
||||||
|
}
|
||||||
@@ -1,27 +1,16 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import '../app.postcss';
|
import '../app.postcss';
|
||||||
import { onDestroy, onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { isBrowser } from '@supabase/ssr';
|
import { isBrowser } from '@supabase/ssr';
|
||||||
import { general } from '$lib/stores/generalStore.js';
|
|
||||||
import { invalidate } from '$app/navigation';
|
import { invalidate } from '$app/navigation';
|
||||||
import CookieConsent from '$lib/components/CookieConsent.svelte';
|
import CookieConsent from '$lib/components/CookieConsent.svelte';
|
||||||
import Nav from '$lib/components/navigation/Nav.svelte';
|
import Nav from '$lib/components/navigation/Nav.svelte';
|
||||||
import { slide } from 'svelte/transition';
|
import Toast from '$lib/components/shared/Toast.svelte';
|
||||||
import { cubicInOut } from 'svelte/easing';
|
|
||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
let { supabase, session } = data;
|
let { supabase, session } = data;
|
||||||
$: ({ supabase, session } = data);
|
$: ({ supabase, session } = data);
|
||||||
|
|
||||||
let localGeneral: any;
|
|
||||||
const unsubscribeToGeneralStore = general.subscribe((value) => {
|
|
||||||
localGeneral = value;
|
|
||||||
});
|
|
||||||
|
|
||||||
onDestroy(() => {
|
|
||||||
unsubscribeToGeneralStore();
|
|
||||||
});
|
|
||||||
|
|
||||||
let cookiesAccepted = false;
|
let cookiesAccepted = false;
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
@@ -122,53 +111,7 @@
|
|||||||
</nav>
|
</nav>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
{#if !localGeneral.hideToast}
|
<Toast />
|
||||||
<div
|
|
||||||
id={localGeneral.toastType == 'success' ? 'success-toast' : 'error-toast'}
|
|
||||||
role="alert"
|
|
||||||
class="alert {localGeneral.toastType == 'success'
|
|
||||||
? 'alert-success'
|
|
||||||
: 'alert-error'} fixed top-20 right-3 max-w-52 text-white"
|
|
||||||
transition:slide={{ duration: 200, easing: cubicInOut }}
|
|
||||||
>
|
|
||||||
{#if localGeneral.toastType == 'success'}
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
class="stroke-current shrink-0 h-6 w-6"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
><path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
stroke-width="2"
|
|
||||||
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
||||||
/></svg
|
|
||||||
>
|
|
||||||
{:else}
|
|
||||||
<svg
|
|
||||||
class="stroke-current shrink-0 h-6 w-6"
|
|
||||||
viewBox="0 0 32 32"
|
|
||||||
xml:space="preserve"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
><g
|
|
||||||
><g id="Error_1_"
|
|
||||||
><g id="Error">
|
|
||||||
<circle cx="16" cy="16" id="BG" r="16" style="fill:#E6E6E6;" />
|
|
||||||
<path
|
|
||||||
d="M14.5,25h3v-3h-3V25z M14.5,6v13h3V6H14.5z"
|
|
||||||
id="Exclamatory_x5F_Sign"
|
|
||||||
style="fill:#D72828;"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</g></g
|
|
||||||
></svg
|
|
||||||
>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<span>{localGeneral.toastMessage == '' ? 'Added to basket' : localGeneral.toastMessage}</span>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<style scoped lang="postcss">
|
<style scoped lang="postcss">
|
||||||
.user-circle {
|
.user-circle {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { general } from '$lib/stores/generalStore.js';
|
import { scheduleToast } from '$lib/stores/toastStore.js';
|
||||||
|
|
||||||
// Access the supabase client from the layout data
|
// Access the supabase client from the layout data
|
||||||
export let supabase: any;
|
export let supabase: any;
|
||||||
@@ -8,21 +8,7 @@
|
|||||||
|
|
||||||
async function resetPassword() {
|
async function resetPassword() {
|
||||||
if (newPassword === '') {
|
if (newPassword === '') {
|
||||||
general.update((value) => {
|
scheduleToast('Please enter a new password', 'error', 5000);
|
||||||
return {
|
|
||||||
...value,
|
|
||||||
hideToast: false,
|
|
||||||
toastMessage: 'Please enter a new password',
|
|
||||||
toastType: 'error'
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
general.update((value) => {
|
|
||||||
return { ...value, hideToast: true, toastMessage: '', toastType: 'success' };
|
|
||||||
});
|
|
||||||
}, 5000);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,37 +18,15 @@
|
|||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error('Error updating password:', error.message);
|
console.error('Error updating password:', error.message);
|
||||||
general.update((value) => {
|
scheduleToast('Error updating password. Please try again.', 'error', 5000);
|
||||||
return {
|
|
||||||
...value,
|
|
||||||
hideToast: false,
|
|
||||||
toastMessage: 'Error updating password. Please try again.',
|
|
||||||
toastType: 'error'
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
general.update((value) => {
|
|
||||||
return { ...value, hideToast: true, toastMessage: '', toastType: 'success' };
|
|
||||||
});
|
|
||||||
}, 5000);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
general.update((value) => {
|
scheduleToast(
|
||||||
return {
|
'Password updated successfully. Please sign in with your new password.',
|
||||||
...value,
|
'success',
|
||||||
hideToast: false,
|
5000
|
||||||
toastMessage: 'Password updated successfully. Please sign in with your new password.',
|
);
|
||||||
toastType: 'success'
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
general.update((value) => {
|
|
||||||
return { ...value, hideToast: true, toastMessage: '', toastType: 'success' };
|
|
||||||
});
|
|
||||||
}, 5000);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { onDestroy } from 'svelte';
|
import { onDestroy } from 'svelte';
|
||||||
import { redirect } from '@sveltejs/kit';
|
import { redirect } from '@sveltejs/kit';
|
||||||
import { basket, type Basket } from '$lib/stores/basket.js';
|
import { basket, type Basket } from '$lib/stores/basket.js';
|
||||||
import { general } from '$lib/stores/generalStore.js';
|
import { scheduleToast } from '$lib/stores/toastStore.js';
|
||||||
|
|
||||||
/** @type {import('./$types').PageData} */
|
/** @type {import('./$types').PageData} */
|
||||||
export let data;
|
export let data;
|
||||||
@@ -40,15 +40,7 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
general.update((value) => {
|
scheduleToast('Added to basket', 'success', 5000);
|
||||||
return { ...value, hideToast: false };
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
general.update((value) => {
|
|
||||||
return { ...value, hideToast: true };
|
|
||||||
});
|
|
||||||
}, 5000);
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user