, 'id'> & { content: string };
+
+export namespace Toast {
+ export function add(options: BasicNotificationData) {
+ const data: NotificationData = Object.assign(
+ {
+ id: nanoid(),
+ dismissable: true,
+ timeout: 10,
+ theme: 'neutral',
+ spin: false,
+ },
+ options,
+ );
+
+ store.notifications.push(data);
+ return data.id;
+ }
+
+ export function remove(notificationId: string) {
+ const currentNotifications = store.notifications;
+ store.notifications = currentNotifications.filter((n) => n.id !== notificationId);
+ }
+
+ export function clear() {
+ store.notifications = [];
+ }
+}
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index 5d83456..608db38 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -1,7 +1,17 @@
{@render children()}
+
+
+ {#each store.notifications as n (n.id)}
+
+ {/each}
+
diff --git a/src/routes/dash/account/+page.svelte b/src/routes/dash/account/+page.svelte
index c9054c9..c2bcd15 100644
--- a/src/routes/dash/account/+page.svelte
+++ b/src/routes/dash/account/+page.svelte
@@ -3,12 +3,11 @@
import { store } from '$lib/v2/globalStore.svelte.js';
import EditPage from '$lib/v2/snippets/EditPage.svelte';
- let { data, form } = $props();
+ let { data } = $props();
store.pageTitle = 'Account details';
-{form?.error}
-{form?.error}
+ import { enhance } from '$app/forms';
import { env } from '$env/dynamic/public';
import InputText from '$lib/v2/forms/InputText.svelte';
+ import { Toast } from '$lib/v2/toast/notification';
import { Button } from 'bits-ui';
+ import { untrack } from 'svelte';
import IconLogin2 from '~icons/tabler/login2';
+ import IconX from '~icons/tabler/x';
import type { PageProps } from './$types';
let { form }: PageProps = $props();
+
+ $effect(() => {
+ if (form?.error) {
+ untrack(() => {
+ Toast.add({
+ Icon: IconX,
+ content: form.error,
+ theme: 'error',
+ });
+ });
+ }
+ });
@@ -17,7 +33,7 @@
class="flex flex-col m-4 w-full max-w-120 bg-neutral-950 p-8 sm:p-12 sm:px
rounded-2xl border border-neutral-700 shadow-xl"
>
-