mirror of
https://github.com/BradNut/boredgame
synced 2025-09-08 17:40:22 +00:00
Rename db folder to server, remove levelup dependencies, add sveltekit flash message, add toast library, and use both on signup.
This commit is contained in:
parent
a62bd44279
commit
a32adc3ae8
18 changed files with 188 additions and 129 deletions
|
|
@ -67,8 +67,6 @@
|
||||||
"@fontsource/fira-mono": "^4.5.10",
|
"@fontsource/fira-mono": "^4.5.10",
|
||||||
"@iconify-icons/line-md": "^1.2.23",
|
"@iconify-icons/line-md": "^1.2.23",
|
||||||
"@iconify-icons/mdi": "^1.2.47",
|
"@iconify-icons/mdi": "^1.2.47",
|
||||||
"@leveluptuts/svelte-side-menu": "^1.0.5",
|
|
||||||
"@leveluptuts/svelte-toy": "^2.0.3",
|
|
||||||
"@lucia-auth/adapter-mysql": "^1.1.1",
|
"@lucia-auth/adapter-mysql": "^1.1.1",
|
||||||
"@lucia-auth/adapter-prisma": "^3.0.0",
|
"@lucia-auth/adapter-prisma": "^3.0.0",
|
||||||
"@lukeed/uuid": "^2.0.1",
|
"@lukeed/uuid": "^2.0.1",
|
||||||
|
|
@ -85,6 +83,7 @@
|
||||||
"lucide-svelte": "^0.256.1",
|
"lucide-svelte": "^0.256.1",
|
||||||
"open-props": "^1.5.10",
|
"open-props": "^1.5.10",
|
||||||
"radix-svelte": "^0.8.0",
|
"radix-svelte": "^0.8.0",
|
||||||
|
"svelte-french-toast": "^1.2.0",
|
||||||
"svelte-lazy": "^1.2.1",
|
"svelte-lazy": "^1.2.1",
|
||||||
"svelte-lazy-loader": "^1.0.0",
|
"svelte-lazy-loader": "^1.0.0",
|
||||||
"svelte-legos": "^0.2.1",
|
"svelte-legos": "^0.2.1",
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,6 @@ dependencies:
|
||||||
'@iconify-icons/mdi':
|
'@iconify-icons/mdi':
|
||||||
specifier: ^1.2.47
|
specifier: ^1.2.47
|
||||||
version: 1.2.47
|
version: 1.2.47
|
||||||
'@leveluptuts/svelte-side-menu':
|
|
||||||
specifier: ^1.0.5
|
|
||||||
version: 1.0.5
|
|
||||||
'@leveluptuts/svelte-toy':
|
|
||||||
specifier: ^2.0.3
|
|
||||||
version: 2.0.3
|
|
||||||
'@lucia-auth/adapter-mysql':
|
'@lucia-auth/adapter-mysql':
|
||||||
specifier: ^1.1.1
|
specifier: ^1.1.1
|
||||||
version: 1.1.1(lucia-auth@1.8.0)
|
version: 1.1.1(lucia-auth@1.8.0)
|
||||||
|
|
@ -71,6 +65,9 @@ dependencies:
|
||||||
radix-svelte:
|
radix-svelte:
|
||||||
specifier: ^0.8.0
|
specifier: ^0.8.0
|
||||||
version: 0.8.0(svelte@4.1.1)
|
version: 0.8.0(svelte@4.1.1)
|
||||||
|
svelte-french-toast:
|
||||||
|
specifier: ^1.2.0
|
||||||
|
version: 1.2.0(svelte@4.1.1)
|
||||||
svelte-lazy:
|
svelte-lazy:
|
||||||
specifier: ^1.2.1
|
specifier: ^1.2.1
|
||||||
version: 1.2.1(svelte@4.1.1)
|
version: 1.2.1(svelte@4.1.1)
|
||||||
|
|
@ -1143,16 +1140,6 @@ packages:
|
||||||
'@jridgewell/resolve-uri': 3.1.0
|
'@jridgewell/resolve-uri': 3.1.0
|
||||||
'@jridgewell/sourcemap-codec': 1.4.15
|
'@jridgewell/sourcemap-codec': 1.4.15
|
||||||
|
|
||||||
/@leveluptuts/svelte-side-menu@1.0.5:
|
|
||||||
resolution: {integrity: sha512-czPmr0LEjVhr7qXYZtH4PrUrfHPYg9nS7ZHH+xDINKoajkERWlHlsBtdoJC5ZTMzGvdhLCLfF70q4xeMzJgS7w==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@leveluptuts/svelte-toy@2.0.3:
|
|
||||||
resolution: {integrity: sha512-A2pjSG4UQbWLffD3r3cC8zaNwtTmBoNJJ2TIlNzVtdlUXk1xrYtscMopB+N2ztHnfjlKWyIee4TEnF3OBVwIfQ==}
|
|
||||||
dependencies:
|
|
||||||
lodash.set: 4.3.2
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@lucia-auth/adapter-mysql@1.1.1(lucia-auth@1.8.0):
|
/@lucia-auth/adapter-mysql@1.1.1(lucia-auth@1.8.0):
|
||||||
resolution: {integrity: sha512-br+/OBDNJ+eRc6RrZnnC20ef+2VEMrXFxNYvsbryPw64ito7vg40STblpENdjJF0o4R10mjWTO43wQ+56jyXLA==}
|
resolution: {integrity: sha512-br+/OBDNJ+eRc6RrZnnC20ef+2VEMrXFxNYvsbryPw64ito7vg40STblpENdjJF0o4R10mjWTO43wQ+56jyXLA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
@ -2719,10 +2706,6 @@ packages:
|
||||||
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/lodash.set@4.3.2:
|
|
||||||
resolution: {integrity: sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/logform@2.5.1:
|
/logform@2.5.1:
|
||||||
resolution: {integrity: sha512-9FyqAm9o9NKKfiAKfZoYo9bGXXuwMkxQiQttkT4YjjVtQVIQtK6LmVtlxmCaFswo6N4AfEkHqZTV0taDtPotNg==}
|
resolution: {integrity: sha512-9FyqAm9o9NKKfiAKfZoYo9bGXXuwMkxQiQttkT4YjjVtQVIQtK6LmVtlxmCaFswo6N4AfEkHqZTV0taDtPotNg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -3857,6 +3840,15 @@ packages:
|
||||||
svelte: 4.1.1
|
svelte: 4.1.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/svelte-french-toast@1.2.0(svelte@4.1.1):
|
||||||
|
resolution: {integrity: sha512-5PW+6RFX3xQPbR44CngYAP1Sd9oCq9P2FOox4FZffzJuZI2mHOB7q5gJBVnOiLF5y3moVGZ7u2bYt7+yPAgcEQ==}
|
||||||
|
peerDependencies:
|
||||||
|
svelte: ^3.57.0 || ^4.0.0
|
||||||
|
dependencies:
|
||||||
|
svelte: 4.1.1
|
||||||
|
svelte-writable-derived: 3.1.0(svelte@4.1.1)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/svelte-hmr@0.15.2(svelte@4.1.1):
|
/svelte-hmr@0.15.2(svelte@4.1.1):
|
||||||
resolution: {integrity: sha512-q/bAruCvFLwvNbeE1x3n37TYFb3mTBJ6TrCq6p2CoFbSTNhDE9oAtEfpy+wmc9So8AG0Tja+X0/mJzX9tSfvIg==}
|
resolution: {integrity: sha512-q/bAruCvFLwvNbeE1x3n37TYFb3mTBJ6TrCq6p2CoFbSTNhDE9oAtEfpy+wmc9So8AG0Tja+X0/mJzX9tSfvIg==}
|
||||||
engines: {node: ^12.20 || ^14.13.1 || >= 16}
|
engines: {node: ^12.20 || ^14.13.1 || >= 16}
|
||||||
|
|
@ -3939,6 +3931,14 @@ packages:
|
||||||
typescript: 5.1.6
|
typescript: 5.1.6
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/svelte-writable-derived@3.1.0(svelte@4.1.1):
|
||||||
|
resolution: {integrity: sha512-cTvaVFNIJ036vSDIyPxJYivKC7ZLtcFOPm1Iq6qWBDo1fOHzfk6ZSbwaKrxhjgy52Rbl5IHzRcWgos6Zqn9/rg==}
|
||||||
|
peerDependencies:
|
||||||
|
svelte: ^3.2.1 || ^4.0.0-next.1
|
||||||
|
dependencies:
|
||||||
|
svelte: 4.1.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/svelte@4.1.1:
|
/svelte@4.1.1:
|
||||||
resolution: {integrity: sha512-Enick5fPFISLoVy0MFK45cG+YlQt6upw8skEK9zzTpJnH1DqEv8xOZwizCGSo3Q6HZ7KrZTM0J18poF7aQg5zw==}
|
resolution: {integrity: sha512-Enick5fPFISLoVy0MFK45cG+YlQt6upw8skEK9zzTpJnH1DqEv8xOZwizCGSo3Q6HZ7KrZTM0J18poF7aQg5zw==}
|
||||||
engines: {node: '>=16'}
|
engines: {node: '>=16'}
|
||||||
|
|
|
||||||
2
src/app.d.ts
vendored
2
src/app.d.ts
vendored
|
|
@ -10,7 +10,7 @@ type User = Omit<User, 'created_at' | 'updated_at'>;
|
||||||
declare global {
|
declare global {
|
||||||
namespace App {
|
namespace App {
|
||||||
interface PageData {
|
interface PageData {
|
||||||
flash?: { type: 'success' | 'error'; message: string };
|
flash?: { type: 'success' | 'error' | 'info'; message: string };
|
||||||
}
|
}
|
||||||
interface Locals {
|
interface Locals {
|
||||||
auth: import('lucia').AuthRequest;
|
auth: import('lucia').AuthRequest;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,9 @@
|
||||||
import RemoveCollectionDialog from '../../dialog/RemoveCollectionDialog.svelte';
|
import RemoveCollectionDialog from '../../dialog/RemoveCollectionDialog.svelte';
|
||||||
import RemoveWishlistDialog from '../../dialog/RemoveWishlistDialog.svelte';
|
import RemoveWishlistDialog from '../../dialog/RemoveWishlistDialog.svelte';
|
||||||
import type { ListGameSchema, SearchSchema } from '$lib/zodValidation';
|
import type { ListGameSchema, SearchSchema } from '$lib/zodValidation';
|
||||||
|
import { Label } from '$components/ui/label';
|
||||||
|
import { Input } from '$components/ui/input';
|
||||||
|
import { Button } from '$components/ui/button';
|
||||||
|
|
||||||
interface RemoveGameEvent extends Event {
|
interface RemoveGameEvent extends Event {
|
||||||
detail: GameType | SavedGameType;
|
detail: GameType | SavedGameType;
|
||||||
|
|
@ -147,22 +150,11 @@
|
||||||
<form id="search-form" action="/search" method="GET">
|
<form id="search-form" action="/search" method="GET">
|
||||||
<div class="search">
|
<div class="search">
|
||||||
<fieldset class="text-search" aria-busy={submitting} disabled={submitting}>
|
<fieldset class="text-search" aria-busy={submitting} disabled={submitting}>
|
||||||
<label class="label" for="q">
|
<Label for="label">Search</Label>
|
||||||
<span>Search</span>
|
<Input type="text" id="q" class={$errors.q && "outline outline-destructive"} name="search" placeholder="Search board games" data-invalid={$errors.q} bind:value={$form.q} />
|
||||||
<input
|
{#if $errors.q}
|
||||||
id="q"
|
<p class="text-sm text-destructive">{$errors.q}</p>
|
||||||
class="input"
|
{/if}
|
||||||
name="q"
|
|
||||||
bind:value={$form.q}
|
|
||||||
data-invalid={$errors?.q}
|
|
||||||
{...$constraints.q}
|
|
||||||
type="search"
|
|
||||||
aria-label="Search board games"
|
|
||||||
placeholder="Search board games"
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
{#if $errors?.q}<span class="invalid">{$errors?.q}</span>{/if}
|
|
||||||
|
|
||||||
<input id="skip" type="hidden" name="skip" bind:value={$form.skip} />
|
<input id="skip" type="hidden" name="skip" bind:value={$form.skip} />
|
||||||
<input id="limit" type="hidden" name="limit" bind:value={$form.limit} />
|
<input id="limit" type="hidden" name="limit" bind:value={$form.limit} />
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
@ -196,15 +188,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{#if showButton}
|
{#if showButton}
|
||||||
<button
|
<Button type="submit">Submit</Button>
|
||||||
id="search-submit"
|
|
||||||
class="btn"
|
|
||||||
type="submit"
|
|
||||||
disabled={submitting}
|
|
||||||
bind:this={submitButton}
|
|
||||||
>
|
|
||||||
Submit
|
|
||||||
</button>
|
|
||||||
{/if}
|
{/if}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { fly, fade } from 'svelte/transition';
|
import { fly, fade } from 'svelte/transition';
|
||||||
import { flip } from 'svelte/animate';
|
import { flip } from 'svelte/animate';
|
||||||
import Portal from '../../Portal.svelte';
|
import Portal from '$lib/Portal.svelte';
|
||||||
import ToastMessage from './ToastMessage.svelte';
|
import ToastMessage from './ToastMessage.svelte';
|
||||||
import { toast } from './toast';
|
import { toast } from './toast';
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -10,6 +10,8 @@
|
||||||
<div class="toast-wrapper">
|
<div class="toast-wrapper">
|
||||||
{#each $toast as toastData (toastData.id)}
|
{#each $toast as toastData (toastData.id)}
|
||||||
<div
|
<div
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
aria-label={toastData.dismissible ? 'Click to dismiss' : `${toastData.message}`}
|
aria-label={toastData.dismissible ? 'Click to dismiss' : `${toastData.message}`}
|
||||||
on:click={() => toastData.dismissible && toast.remove(toastData.id)}
|
on:click={() => toastData.dismissible && toast.remove(toastData.id)}
|
||||||
on:keydown={() => toastData.dismissible && toast.remove(toastData.id)}
|
on:keydown={() => toastData.dismissible && toast.remove(toastData.id)}
|
||||||
|
|
|
||||||
|
|
@ -4,40 +4,40 @@ import { ToastType } from '$lib/types';
|
||||||
|
|
||||||
// Custom store
|
// Custom store
|
||||||
const newToast = () => {
|
const newToast = () => {
|
||||||
const { subscribe, update } = writable<ToastData[]>([]);
|
const { subscribe, update } = writable<ToastData[]>([]);
|
||||||
|
|
||||||
function send(
|
function send(
|
||||||
message: string,
|
message: string,
|
||||||
{
|
{
|
||||||
duration = 2000,
|
duration = 2000,
|
||||||
type = ToastType.INFO,
|
type = ToastType.INFO,
|
||||||
autoDismiss = true,
|
autoDismiss = true,
|
||||||
dismissible = false,
|
dismissible = false,
|
||||||
showButton = false
|
showButton = false
|
||||||
} = {}
|
} = {}
|
||||||
) {
|
) {
|
||||||
const id = Math.floor(Math.random() * 1000);
|
const id = Math.floor(Math.random() * 1000);
|
||||||
|
|
||||||
const newMessage: ToastData = {
|
const newMessage: ToastData = {
|
||||||
id,
|
id,
|
||||||
duration,
|
duration,
|
||||||
autoDismiss,
|
autoDismiss,
|
||||||
dismissible,
|
dismissible,
|
||||||
showButton,
|
showButton,
|
||||||
type,
|
type,
|
||||||
message
|
message
|
||||||
};
|
};
|
||||||
update((store) => [...store, newMessage]);
|
update((store) => [...store, newMessage]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function remove(id: number) {
|
function remove(id: number) {
|
||||||
update((store) => {
|
update((store) => {
|
||||||
const newStore = store.filter((item: ToastData) => item.id !== id);
|
const newStore = store.filter((item: ToastData) => item.id !== id);
|
||||||
return [...newStore];
|
return [...newStore];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return { subscribe, send, remove };
|
return { subscribe, send, remove };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const toast = newToast();
|
export const toast = newToast();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import { Prisma } from '@prisma/client';
|
import { Prisma } from '@prisma/client';
|
||||||
import type { SvelteComponent } from 'svelte';
|
import type { SvelteComponent } from 'svelte';
|
||||||
|
|
||||||
|
export type Message = { status: 'error' | 'success' | 'warning' | 'info'; text: string };
|
||||||
|
|
||||||
export const gameInclude = Prisma.validator<Prisma.CollectionItemInclude>()({
|
export const gameInclude = Prisma.validator<Prisma.CollectionItemInclude>()({
|
||||||
game: {
|
game: {
|
||||||
select: {
|
select: {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
import { loadFlash } from 'sveltekit-flash-message/server';
|
import { loadFlash } from 'sveltekit-flash-message/server';
|
||||||
import type { LayoutServerLoad } from './$types';
|
import type { LayoutServerLoad } from './$types';
|
||||||
|
|
||||||
export const load: LayoutServerLoad = async ({ url, locals }) => {
|
export const load: LayoutServerLoad = loadFlash(async ({ url, locals }) => {
|
||||||
return {
|
return {
|
||||||
url: url.pathname,
|
url: url.pathname,
|
||||||
user: locals.user
|
user: locals.user
|
||||||
};
|
};
|
||||||
};
|
});
|
||||||
|
|
||||||
// loadFlash(
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import "../app.postcss";
|
import "../app.postcss";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
// import { getFlash } from 'sveltekit-flash-message/client';
|
import { getFlash } from 'sveltekit-flash-message/client';
|
||||||
|
import toast, { Toaster } from 'svelte-french-toast';
|
||||||
import { navigating, page } from '$app/stores';
|
import { navigating, page } from '$app/stores';
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
import debounce from 'just-debounce-it';
|
import debounce from 'just-debounce-it';
|
||||||
// import { Toy } from '@leveluptuts/svelte-toy';
|
|
||||||
import 'iconify-icon';
|
import 'iconify-icon';
|
||||||
import Analytics from '$lib/components/analytics.svelte';
|
import Analytics from '$lib/components/analytics.svelte';
|
||||||
import Header from '$lib/components/header/index.svelte';
|
import Header from '$lib/components/header/index.svelte';
|
||||||
|
|
@ -16,9 +16,7 @@
|
||||||
import { boredState } from '$lib/stores/boredState';
|
import { boredState } from '$lib/stores/boredState';
|
||||||
import { collectionStore } from '$lib/stores/collectionStore';
|
import { collectionStore } from '$lib/stores/collectionStore';
|
||||||
import { wishlistStore } from '$lib/stores/wishlistStore';
|
import { wishlistStore } from '$lib/stores/wishlistStore';
|
||||||
import Toast from '$lib/components/toast/Toast.svelte';
|
|
||||||
import { theme } from '$state/theme';
|
import { theme } from '$state/theme';
|
||||||
// import '$styles/styles.pcss';
|
|
||||||
import type { SavedGameType } from '$lib/types';
|
import type { SavedGameType } from '$lib/types';
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
|
|
@ -33,7 +31,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
$: isOpen = $boredState?.dialog?.isOpen;
|
$: isOpen = $boredState?.dialog?.isOpen;
|
||||||
// const flash = getFlash(page);
|
|
||||||
|
|
||||||
if (browser) {
|
if (browser) {
|
||||||
const collator = new Intl.Collator('en');
|
const collator = new Intl.Collator('en');
|
||||||
|
|
@ -74,6 +71,27 @@
|
||||||
export let data;
|
export let data;
|
||||||
$: ({ user } = data);
|
$: ({ user } = data);
|
||||||
|
|
||||||
|
const flash = getFlash(page);
|
||||||
|
let flashType;
|
||||||
|
let flashMessage;
|
||||||
|
$: flashType = $flash?.type;
|
||||||
|
$: flashMessage = $flash?.message;
|
||||||
|
console.log('flashType', flashType);
|
||||||
|
console.log('flashMessage', flashMessage);
|
||||||
|
|
||||||
|
// if ($flash && flashType && flashMessage) {
|
||||||
|
// switch (flashType) {
|
||||||
|
// case 'success':
|
||||||
|
// toast.success(flashMessage);
|
||||||
|
// break;
|
||||||
|
// case 'error':
|
||||||
|
// toast.error(flashMessage);
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// toast.error(flashMessage);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
// set the theme to the user's active theme
|
// set the theme to the user's active theme
|
||||||
$theme = user?.theme || 'system';
|
$theme = user?.theme || 'system';
|
||||||
|
|
@ -85,27 +103,29 @@
|
||||||
<Analytics />
|
<Analytics />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<!-- {#if dev}
|
|
||||||
<Toy
|
|
||||||
register={{
|
|
||||||
boredState,
|
|
||||||
collectionStore,
|
|
||||||
wishlistStore,
|
|
||||||
gameStore,
|
|
||||||
toast
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{/if} -->
|
|
||||||
|
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<Header user="{data.user}"></Header>
|
<Header user={data.user} />
|
||||||
<main>
|
|
||||||
<Transition url={data.url} transition={{ type: 'page' }}>
|
<main>
|
||||||
<slot></slot>
|
<Transition url={data.url} transition={{ type: 'page' }}>
|
||||||
</Transition>
|
<slot />
|
||||||
</main>
|
</Transition>
|
||||||
|
</main>
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{#if $flash}
|
||||||
|
<div class="status"
|
||||||
|
class:error={$flash.type == 'error'}
|
||||||
|
class:success={$flash.type == 'success'}
|
||||||
|
>
|
||||||
|
{$flash.message}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<Toaster />
|
||||||
|
|
||||||
{#if $boredState?.loading}
|
{#if $boredState?.loading}
|
||||||
<Portal>
|
<Portal>
|
||||||
<div class="loading">
|
<div class="loading">
|
||||||
|
|
@ -120,13 +140,16 @@
|
||||||
<svelte:component this={$boredState?.dialog?.content}></svelte:component>
|
<svelte:component this={$boredState?.dialog?.content}></svelte:component>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<Toast></Toast>
|
|
||||||
<!-- {#if $flash}
|
|
||||||
{@const bg = $flash.type == 'success' ? '#3D9970' : '#FF4136'}
|
|
||||||
<div style:background-color={bg} class="flash">{$flash.message}</div>
|
|
||||||
{/if} -->
|
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
|
.flash {
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
place-items: center;
|
||||||
|
padding: 0.5rem;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
.loading {
|
.loading {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { fail, redirect } from '@sveltejs/kit';
|
import { fail } from '@sveltejs/kit';
|
||||||
import { setError, superValidate } from 'sveltekit-superforms/server';
|
import { setError, superValidate } from 'sveltekit-superforms/server';
|
||||||
|
import { redirect } from 'sveltekit-flash-message/server';
|
||||||
import { auth } from '$lib/server/lucia';
|
import { auth } from '$lib/server/lucia';
|
||||||
import prisma from '$lib/prisma.js';
|
import prisma from '$lib/prisma.js';
|
||||||
import { userSchema } from '$lib/config/zod-schemas';
|
import { userSchema } from '$lib/config/zod-schemas';
|
||||||
|
|
@ -13,7 +14,8 @@ export const load = async (event) => {
|
||||||
console.log('sign in load event', event);
|
console.log('sign in load event', event);
|
||||||
const session = await event.locals.auth.validate();
|
const session = await event.locals.auth.validate();
|
||||||
if (session) {
|
if (session) {
|
||||||
throw redirect(302, '/');
|
const message = { type: 'info', message: 'You are already signed in' };
|
||||||
|
throw redirect('/', message, event);
|
||||||
}
|
}
|
||||||
const form = await superValidate(event, signInSchema);
|
const form = await superValidate(event, signInSchema);
|
||||||
return {
|
return {
|
||||||
|
|
@ -40,9 +42,9 @@ export const actions = {
|
||||||
});
|
});
|
||||||
event.locals.auth.setSession(session);
|
event.locals.auth.setSession(session);
|
||||||
|
|
||||||
const user = await prisma.authUser.findUnique({
|
const user = await prisma.user.findUnique({
|
||||||
where: {
|
where: {
|
||||||
id: session.userId
|
id: session.user.userId
|
||||||
},
|
},
|
||||||
include: {
|
include: {
|
||||||
roles: {
|
roles: {
|
||||||
|
|
@ -86,6 +88,8 @@ export const actions = {
|
||||||
}
|
}
|
||||||
form.data.username = '';
|
form.data.username = '';
|
||||||
form.data.password = '';
|
form.data.password = '';
|
||||||
return { form };
|
const message = { type: 'success', message: 'Signed In!' };
|
||||||
|
// return { form, message };
|
||||||
|
throw redirect('/', message, event);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { superForm } from 'sveltekit-superforms/client';
|
import { superForm } from 'sveltekit-superforms/client';
|
||||||
|
import * as flashModule from 'sveltekit-flash-message/client';
|
||||||
import { AlertCircle } from "lucide-svelte";
|
import { AlertCircle } from "lucide-svelte";
|
||||||
import { userSchema } from '$lib/config/zod-schemas.js';
|
import { userSchema } from '$lib/config/zod-schemas.js';
|
||||||
import Label from '$components/ui/label/Label.svelte';
|
import Label from '$components/ui/label/Label.svelte';
|
||||||
|
|
@ -9,6 +10,17 @@
|
||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
const { form, errors, enhance, delayed } = superForm(data.form, {
|
const { form, errors, enhance, delayed } = superForm(data.form, {
|
||||||
|
flashMessage: {
|
||||||
|
module: flashModule,
|
||||||
|
onError: ({ result, message }) => {
|
||||||
|
// Error handling for the flash message:
|
||||||
|
// - result is the ActionResult
|
||||||
|
// - message is the flash store (not the status message store)
|
||||||
|
const errorMessage = result.error.message
|
||||||
|
message.set({ type: 'error', message: errorMessage });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
syncFlashMessage: false,
|
||||||
taintedMessage: null,
|
taintedMessage: null,
|
||||||
validationMethod: 'oninput',
|
validationMethod: 'oninput',
|
||||||
delayMs: 0,
|
delayMs: 0,
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
import { fail, redirect } from '@sveltejs/kit';
|
import { fail, redirect, error } from '@sveltejs/kit';
|
||||||
import { setError, superValidate } from 'sveltekit-superforms/server';
|
import { setError, superValidate } from 'sveltekit-superforms/server';
|
||||||
import { redirect as flashRedirect } from 'sveltekit-flash-message/server';
|
import { redirect as flashRedirect } from 'sveltekit-flash-message/server';
|
||||||
import { LuciaError } from 'lucia';
|
import { LuciaError } from 'lucia';
|
||||||
import { auth } from '$lib/server/lucia';
|
import { auth } from '$lib/server/lucia';
|
||||||
import { userSchema } from '$lib/config/zod-schemas';
|
import { userSchema } from '$lib/config/zod-schemas';
|
||||||
import { add_user_to_role } from '$db/roles';
|
import { add_user_to_role } from '$server/roles';
|
||||||
import prisma from '$lib/prisma.js';
|
import prisma from '$lib/prisma.js';
|
||||||
|
import { Schema } from 'zod';
|
||||||
|
import type { Message } from '$lib/types.js';
|
||||||
|
|
||||||
const signUpSchema = userSchema
|
const signUpSchema = userSchema
|
||||||
.pick({
|
.pick({
|
||||||
|
|
@ -38,7 +40,7 @@ export const load = async (event) => {
|
||||||
if (session) {
|
if (session) {
|
||||||
throw redirect(302, '/');
|
throw redirect(302, '/');
|
||||||
}
|
}
|
||||||
const form = await superValidate(event, signUpSchema);
|
const form = await superValidate<typeof signUpSchema, Message>(event, signUpSchema);
|
||||||
return {
|
return {
|
||||||
form
|
form
|
||||||
};
|
};
|
||||||
|
|
@ -46,7 +48,7 @@ export const load = async (event) => {
|
||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
default: async (event) => {
|
default: async (event) => {
|
||||||
const form = await superValidate(event, signUpSchema);
|
const form = await superValidate<typeof signUpSchema, Message>(event, signUpSchema);
|
||||||
|
|
||||||
if (!form.valid) {
|
if (!form.valid) {
|
||||||
return fail(400, {
|
return fail(400, {
|
||||||
|
|
@ -99,13 +101,18 @@ export const actions = {
|
||||||
event.locals.auth.setSession(session);
|
event.locals.auth.setSession(session);
|
||||||
// const message = { type: 'success', message: 'Signed Up!' } as const;
|
// const message = { type: 'success', message: 'Signed Up!' } as const;
|
||||||
// throw flashRedirect(message, event);
|
// throw flashRedirect(message, event);
|
||||||
} catch (error) {
|
} catch (e) {
|
||||||
if (error instanceof LuciaError && error.message === `DUPLICATE_KEY_ID`) {
|
if (e instanceof LuciaError && e.message === `DUPLICATE_KEY_ID`) {
|
||||||
// key already exists
|
// key already exists
|
||||||
console.error(error);
|
console.error('Lucia Error: ', e);
|
||||||
}
|
}
|
||||||
console.log(error);
|
console.log(e);
|
||||||
return setError(form, '', 'Unable to create your account. Please try again.');
|
const message = {
|
||||||
|
type: 'error',
|
||||||
|
message: 'Unable to create your account. Please try again.'
|
||||||
|
};
|
||||||
|
throw error(500, message);
|
||||||
|
// return setError(form, '', message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { page } from '$app/stores';
|
||||||
|
import { superForm } from 'sveltekit-superforms/client';
|
||||||
|
import * as flashModule from 'sveltekit-flash-message/client';
|
||||||
import Button from '$components/ui/button/Button.svelte';
|
import Button from '$components/ui/button/Button.svelte';
|
||||||
import Input from '$components/ui/input/Input.svelte';
|
import Input from '$components/ui/input/Input.svelte';
|
||||||
import Label from '$components/ui/label/Label.svelte';
|
import Label from '$components/ui/label/Label.svelte';
|
||||||
import { userSchema } from '$lib/config/zod-schemas.js';
|
import { userSchema } from '$lib/config/zod-schemas.js';
|
||||||
import { superForm } from 'sveltekit-superforms/client';
|
import toast from 'svelte-french-toast';
|
||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
|
|
@ -17,12 +20,35 @@ import { userSchema } from '$lib/config/zod-schemas.js';
|
||||||
});
|
});
|
||||||
|
|
||||||
const { form, errors, constraints, enhance, delayed } = superForm(data.form, {
|
const { form, errors, constraints, enhance, delayed } = superForm(data.form, {
|
||||||
|
flashMessage: {
|
||||||
|
module: flashModule,
|
||||||
|
onError: ({ result, message }) => {
|
||||||
|
const errorMessage = result.error.message;
|
||||||
|
message.set({ type: 'error', message: errorMessage });
|
||||||
|
}
|
||||||
|
},
|
||||||
taintedMessage: null,
|
taintedMessage: null,
|
||||||
validators: signUpSchema,
|
validators: signUpSchema,
|
||||||
delayMs: 0,
|
delayMs: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const flash = flashModule.getFlash(page);
|
||||||
|
|
||||||
|
$: {
|
||||||
|
if ($flash) {
|
||||||
|
toast.error($flash.message, {
|
||||||
|
duration: 5000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<!-- {#if $flash}
|
||||||
|
{@const bg = $flash.type == 'success' ? '#3D9970' : '#FF4136'}
|
||||||
|
<div style:background-color={bg} class="flash">{$flash.message}</div>
|
||||||
|
{/if} -->
|
||||||
|
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<form method="POST" action="/auth/signup" use:enhance>
|
<form method="POST" action="/auth/signup" use:enhance>
|
||||||
<div class="grid w-full max-w-sm items-center gap-2.5">
|
<div class="grid w-full max-w-sm items-center gap-2.5">
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
import { superForm } from 'sveltekit-superforms/client';
|
import { superForm } from 'sveltekit-superforms/client';
|
||||||
import type { SuperValidated } from 'sveltekit-superforms';
|
import type { SuperValidated } from 'sveltekit-superforms';
|
||||||
import type { ModifyListGame } from '$lib/config/zod-schemas.js';
|
import type { ModifyListGame } from '$lib/config/zod-schemas.js';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import toast from 'svelte-french-toast';
|
||||||
// import { collectionStore } from '$lib/stores/collectionStore';
|
// import { collectionStore } from '$lib/stores/collectionStore';
|
||||||
// import type { GameType, SavedGameType } from '$lib/types';
|
// import type { GameType, SavedGameType } from '$lib/types';
|
||||||
// import { boredState } from '$lib/stores/boredState';
|
// import { boredState } from '$lib/stores/boredState';
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ const config = {
|
||||||
$assets: './src/assets',
|
$assets: './src/assets',
|
||||||
$components: './src/components',
|
$components: './src/components',
|
||||||
'$components/*': 'src/lib/components/*',
|
'$components/*': 'src/lib/components/*',
|
||||||
$db: './src/db',
|
$server: './src/server',
|
||||||
$lib: './src/lib',
|
$lib: './src/lib',
|
||||||
$state: './src/state',
|
$state: './src/state',
|
||||||
$styles: './src/styles',
|
$styles: './src/styles',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue