mirror of
https://github.com/BradNut/boredgame
synced 2025-09-08 17:40:22 +00:00
Updating dependencies, upgrade latest svelte 5, and updating to use svelte 5 in most places.
This commit is contained in:
parent
8c47357605
commit
63ac7dfd76
22 changed files with 1000 additions and 1145 deletions
48
package.json
48
package.json
|
|
@ -23,48 +23,48 @@
|
|||
"devDependencies": {
|
||||
"@melt-ui/pp": "^0.3.2",
|
||||
"@melt-ui/svelte": "^0.81.0",
|
||||
"@playwright/test": "^1.44.1",
|
||||
"@playwright/test": "^1.45.1",
|
||||
"@resvg/resvg-js": "^2.6.2",
|
||||
"@sveltejs/adapter-auto": "^3.2.2",
|
||||
"@sveltejs/enhanced-img": "^0.2.1",
|
||||
"@sveltejs/kit": "^2.5.14",
|
||||
"@sveltejs/kit": "^2.5.18",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.1.1",
|
||||
"@types/cookie": "^0.6.0",
|
||||
"@types/node": "^20.14.2",
|
||||
"@types/node": "^20.14.10",
|
||||
"@types/pg": "^8.11.6",
|
||||
"@typescript-eslint/eslint-plugin": "^7.12.0",
|
||||
"@typescript-eslint/parser": "^7.12.0",
|
||||
"@typescript-eslint/eslint-plugin": "^7.13.0",
|
||||
"@typescript-eslint/parser": "^7.13.0",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"drizzle-kit": "^0.22.7",
|
||||
"drizzle-kit": "^0.22.8",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-svelte": "^2.39.3",
|
||||
"eslint-plugin-svelte": "^2.41.0",
|
||||
"just-clone": "^6.2.0",
|
||||
"just-debounce-it": "^3.2.0",
|
||||
"postcss": "^8.4.38",
|
||||
"postcss": "^8.4.39",
|
||||
"postcss-import": "^16.1.0",
|
||||
"postcss-load-config": "^5.1.0",
|
||||
"postcss-preset-env": "^9.5.14",
|
||||
"postcss-preset-env": "^9.5.16",
|
||||
"prettier": "^3.3.2",
|
||||
"prettier-plugin-svelte": "^3.2.4",
|
||||
"sass": "^1.77.5",
|
||||
"prettier-plugin-svelte": "^3.2.5",
|
||||
"sass": "^1.77.6",
|
||||
"satori": "^0.10.13",
|
||||
"satori-html": "^0.3.2",
|
||||
"svelte": "^4.2.18",
|
||||
"svelte-check": "^3.8.0",
|
||||
"svelte": "5.0.0-next.175",
|
||||
"svelte-check": "^3.8.4",
|
||||
"svelte-headless-table": "^0.18.2",
|
||||
"svelte-meta-tags": "^3.1.2",
|
||||
"svelte-preprocess": "^5.1.4",
|
||||
"svelte-sequential-preprocessor": "^2.0.1",
|
||||
"sveltekit-flash-message": "^2.4.4",
|
||||
"sveltekit-rate-limiter": "^0.5.1",
|
||||
"sveltekit-superforms": "^2.15.1",
|
||||
"sveltekit-superforms": "^2.15.2",
|
||||
"tailwindcss": "^3.4.4",
|
||||
"ts-node": "^10.9.2",
|
||||
"tslib": "^2.6.3",
|
||||
"tsx": "^4.15.4",
|
||||
"typescript": "^5.4.5",
|
||||
"vite": "^5.3.1",
|
||||
"tsx": "^4.16.2",
|
||||
"typescript": "^5.5.3",
|
||||
"vite": "^5.3.3",
|
||||
"vitest": "^1.6.0",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
|
|
@ -79,12 +79,12 @@
|
|||
"@iconify-icons/mdi": "^1.2.48",
|
||||
"@lucia-auth/adapter-drizzle": "^1.0.7",
|
||||
"@lukeed/uuid": "^2.0.1",
|
||||
"@neondatabase/serverless": "^0.9.3",
|
||||
"@neondatabase/serverless": "^0.9.4",
|
||||
"@paralleldrive/cuid2": "^2.2.2",
|
||||
"@sveltejs/adapter-vercel": "^5.3.2",
|
||||
"@sveltejs/adapter-vercel": "^5.4.1",
|
||||
"@types/feather-icons": "^4.29.4",
|
||||
"@vercel/og": "^0.5.20",
|
||||
"bits-ui": "^0.21.10",
|
||||
"bits-ui": "^0.21.11",
|
||||
"boardgamegeekclient": "^1.9.1",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.1",
|
||||
|
|
@ -93,7 +93,7 @@
|
|||
"dotenv-expand": "^11.0.6",
|
||||
"drizzle-orm": "^0.31.2",
|
||||
"feather-icons": "^4.29.2",
|
||||
"formsnap": "^1.0.0",
|
||||
"formsnap": "^1.0.1",
|
||||
"html-entities": "^2.5.2",
|
||||
"iconify-icon": "^2.1.0",
|
||||
"just-capitalize": "^3.2.0",
|
||||
|
|
@ -101,8 +101,8 @@
|
|||
"loader": "^2.1.1",
|
||||
"lucia": "3.2.0",
|
||||
"lucide-svelte": "^0.390.0",
|
||||
"open-props": "^1.7.4",
|
||||
"oslo": "^1.2.0",
|
||||
"open-props": "^1.7.5",
|
||||
"oslo": "^1.2.1",
|
||||
"pg": "^8.12.0",
|
||||
"postgres": "^3.4.4",
|
||||
"qrcode": "^1.5.3",
|
||||
|
|
@ -112,6 +112,6 @@
|
|||
"tailwind-merge": "^2.3.0",
|
||||
"tailwind-variants": "^0.2.1",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"zod-to-json-schema": "^3.23.0"
|
||||
"zod-to-json-schema": "^3.23.1"
|
||||
}
|
||||
}
|
||||
1718
pnpm-lock.yaml
1718
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
|
@ -41,6 +41,16 @@ export default async function seed(db: db) {
|
|||
|
||||
console.log('Admin user created.', adminUser);
|
||||
|
||||
await db
|
||||
.insert(schema.collections)
|
||||
.values({ user_id: adminUser[0].id })
|
||||
.onConflictDoNothing();
|
||||
|
||||
await db
|
||||
.insert(schema.wishlists)
|
||||
.values({ user_id: adminUser[0].id })
|
||||
.onConflictDoNothing();
|
||||
|
||||
await db
|
||||
.insert(schema.userRoles)
|
||||
.values({
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
<script lang="ts">
|
||||
const { children } = $props();
|
||||
|
||||
function portal(node: HTMLElement) {
|
||||
let target;
|
||||
|
||||
|
|
@ -25,5 +27,5 @@
|
|||
</script>
|
||||
|
||||
<div use:portal hidden>
|
||||
<slot />
|
||||
{@render children()}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,112 +1,112 @@
|
|||
<script>
|
||||
/**
|
||||
* @event {boolean} check
|
||||
*/
|
||||
/**
|
||||
* @event {boolean} check
|
||||
*/
|
||||
|
||||
/**
|
||||
* Specify the value of the checkbox
|
||||
* @type {any}
|
||||
*/
|
||||
export let value = '';
|
||||
/**
|
||||
* Specify the value of the checkbox
|
||||
* @type {any}
|
||||
*/
|
||||
export let value = '';
|
||||
|
||||
/** Specify whether the checkbox is checked */
|
||||
export let checked = false;
|
||||
/** Specify whether the checkbox is checked */
|
||||
export let checked = false;
|
||||
|
||||
/**
|
||||
* Specify the bound group
|
||||
* @type {any[]}
|
||||
*/
|
||||
export let group = undefined;
|
||||
/**
|
||||
* Specify the bound group
|
||||
* @type {any[]}
|
||||
*/
|
||||
export let group = undefined;
|
||||
|
||||
/** Specify whether the checkbox is indeterminate */
|
||||
export let indeterminate = false;
|
||||
/** Specify whether the checkbox is indeterminate */
|
||||
export let indeterminate = false;
|
||||
|
||||
/** Set to `true` to display the skeleton state */
|
||||
export let skeleton = false;
|
||||
/** Set to `true` to display the skeleton state */
|
||||
export let skeleton = false;
|
||||
|
||||
/** Set to `true` to mark the field as required */
|
||||
export let required = false;
|
||||
/** Set to `true` to mark the field as required */
|
||||
export let required = false;
|
||||
|
||||
/** Set to `true` for the checkbox to be read-only */
|
||||
export let readonly = false;
|
||||
/** Set to `true` for the checkbox to be read-only */
|
||||
export let readonly = false;
|
||||
|
||||
/** Set to `true` to disable the checkbox */
|
||||
export let disabled = false;
|
||||
/** Set to `true` to disable the checkbox */
|
||||
export let disabled = false;
|
||||
|
||||
/** Specify the label text */
|
||||
export let labelText = '';
|
||||
/** Specify the label text */
|
||||
export let labelText = '';
|
||||
|
||||
/** Set to `true` to visually hide the label text */
|
||||
export let hideLabel = false;
|
||||
/** Set to `true` to visually hide the label text */
|
||||
export let hideLabel = false;
|
||||
|
||||
/** Set a name for the input element */
|
||||
export let name = '';
|
||||
/** Set a name for the input element */
|
||||
export let name = '';
|
||||
|
||||
/**
|
||||
* Specify the title attribute for the label element
|
||||
* @type {string}
|
||||
*/
|
||||
export let title = undefined;
|
||||
/**
|
||||
* Specify the title attribute for the label element
|
||||
* @type {string}
|
||||
*/
|
||||
export let title = undefined;
|
||||
|
||||
/** Set an id for the input label */
|
||||
export let id = 'ccs-' + Math.random().toString(36);
|
||||
/** Set an id for the input label */
|
||||
export let id = 'ccs-' + Math.random().toString(36);
|
||||
|
||||
/** Obtain a reference to the input HTML element */
|
||||
export let ref = null;
|
||||
/** Obtain a reference to the input HTML element */
|
||||
export let ref = null;
|
||||
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import CheckboxSkeleton from './CheckboxSkeleton.svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import CheckboxSkeleton from './CheckboxSkeleton.svelte';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
$: useGroup = Array.isArray(group);
|
||||
$: checked = useGroup ? group.includes(value) : checked;
|
||||
$: dispatch('check', checked);
|
||||
$: useGroup = Array.isArray(group);
|
||||
$: checked = useGroup ? group.includes(value) : checked;
|
||||
$: dispatch('check', checked);
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
|
||||
{#if skeleton}
|
||||
<CheckboxSkeleton {...$$restProps} on:click on:mouseover on:mouseenter on:mouseleave />
|
||||
<CheckboxSkeleton {...$$restProps} on:click on:mouseover on:mouseenter on:mouseleave />
|
||||
{:else}
|
||||
<div
|
||||
class:bx--form-item={true}
|
||||
class:bx--checkbox-wrapper={true}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:mouseover
|
||||
on:mouseenter
|
||||
on:mouseleave
|
||||
>
|
||||
<input
|
||||
bind:this={ref}
|
||||
type="checkbox"
|
||||
{value}
|
||||
{checked}
|
||||
{disabled}
|
||||
{id}
|
||||
{indeterminate}
|
||||
{name}
|
||||
{required}
|
||||
{readonly}
|
||||
class:bx--checkbox={true}
|
||||
on:change={() => {
|
||||
if (useGroup) {
|
||||
group = group.includes(value)
|
||||
? group.filter((_value) => _value !== value)
|
||||
: [...group, value];
|
||||
} else {
|
||||
checked = !checked;
|
||||
}
|
||||
}}
|
||||
on:change
|
||||
on:blur
|
||||
/>
|
||||
<label for={id} {title} class:bx--checkbox-label={true}>
|
||||
<span class:bx--checkbox-label-text={true} class:bx--visually-hidden={hideLabel}>
|
||||
<slot name="labelText">
|
||||
{labelText}
|
||||
</slot>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
class:bx--form-item={true}
|
||||
class:bx--checkbox-wrapper={true}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:mouseover
|
||||
on:mouseenter
|
||||
on:mouseleave
|
||||
>
|
||||
<input
|
||||
bind:this={ref}
|
||||
type="checkbox"
|
||||
{value}
|
||||
{checked}
|
||||
{disabled}
|
||||
{id}
|
||||
{indeterminate}
|
||||
{name}
|
||||
{required}
|
||||
{readonly}
|
||||
class:bx--checkbox={true}
|
||||
on:change={() => {
|
||||
if (useGroup) {
|
||||
group = group.includes(value)
|
||||
? group.filter((_value) => _value !== value)
|
||||
: [...group, value];
|
||||
} else {
|
||||
checked = !checked;
|
||||
}
|
||||
}}
|
||||
on:change
|
||||
on:blur
|
||||
/>
|
||||
<label for={id} {title} class:bx--checkbox-label={true}>
|
||||
<span class:bx--checkbox-label-text={true} class:bx--visually-hidden={hideLabel}>
|
||||
<slot name="labelText">
|
||||
{labelText}
|
||||
</slot>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -8,15 +8,13 @@
|
|||
import Logo from '$components/logo.svelte';
|
||||
import type { Users } from '$db/schema';
|
||||
|
||||
export let user: Users | null = null;
|
||||
type HeaderProps = {
|
||||
user: Users | null;
|
||||
};
|
||||
|
||||
console.log('header user', user);
|
||||
let { user = null }: HeaderProps = $props();
|
||||
|
||||
let avatar: string;
|
||||
|
||||
$: if (user) {
|
||||
avatar = user.username?.slice(0, 1).toUpperCase() || ':)';
|
||||
}
|
||||
let avatar: string = $derived(user?.username?.slice(0, 1).toUpperCase() || ':)');
|
||||
</script>
|
||||
|
||||
<header>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<script lang="ts">
|
||||
export let url: string;
|
||||
export let ariaLabel = `Link to ${url}`;
|
||||
export let external = false;
|
||||
const { url, ariaLabel = `Link to ${url}`, external = false, children }: { url: string; ariaLabel?: string; external?: boolean; children: any } = $props();
|
||||
</script>
|
||||
|
||||
<a
|
||||
|
|
@ -10,7 +8,7 @@
|
|||
rel="noreferrer"
|
||||
aria-label={`Board Game Atlas Link for ${ariaLabel}`}
|
||||
>
|
||||
<slot />
|
||||
{@render children()}
|
||||
</a>
|
||||
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { fade } from 'svelte/transition';
|
||||
// import {
|
||||
// Dialog,
|
||||
// DialogDescription,
|
||||
// DialogOverlay,
|
||||
// DialogTitle
|
||||
// } from '@rgossiaux/svelte-headlessui';
|
||||
import { boredState } from '$lib/stores/boredState';
|
||||
import { collectionStore } from '$lib/stores/collectionStore';
|
||||
import { browser } from '$app/environment';
|
||||
|
|
|
|||
|
|
@ -27,10 +27,24 @@ export function userNotFullyAuthenticated(user: User | null, session: Session |
|
|||
return user && session && session.isTwoFactorAuthEnabled && !session.isTwoFactorAuthenticated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the user is not fully authenticated.
|
||||
*
|
||||
* @param {User | null} user - The user object.
|
||||
* @param {Session | null} session - The session object.
|
||||
* @returns {boolean} True if the user is not fully authenticated, otherwise false.
|
||||
*/
|
||||
export function userNotAuthenticated(user: User | null, session: Session | null) {
|
||||
return !user || !session || userNotFullyAuthenticated(user, session);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the user is fully authenticated.
|
||||
*
|
||||
* @param {User | null} user - The user object.
|
||||
* @param {Session | null} session - The session object.
|
||||
* @returns {boolean} True if the user is fully authenticated, otherwise false.
|
||||
*/
|
||||
export function userFullyAuthenticated(user: User | null, session: Session | null) {
|
||||
return !userNotAuthenticated(user, session);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
import { theme } from '$state/theme';
|
||||
import toast, { Toaster } from 'svelte-french-toast';
|
||||
|
||||
export let data;
|
||||
$: ({ user } = data);
|
||||
const { data } = $props();
|
||||
const { user } = data;
|
||||
|
||||
const flash = getFlash(page, {
|
||||
clearOnNavigate: true,
|
||||
|
|
@ -14,26 +14,27 @@
|
|||
clearArray: true
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
$effect(() => {
|
||||
// set the theme to the user's active theme
|
||||
$theme = user?.theme || 'system';
|
||||
document.querySelector('html')?.setAttribute('data-theme', $theme);
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
if ($flash) {
|
||||
if ($flash.type === 'success') {
|
||||
toast.success($flash.message);
|
||||
} else {
|
||||
toast.error($flash.message, {
|
||||
duration: 5000
|
||||
});
|
||||
}
|
||||
|
||||
$: if ($flash) {
|
||||
if ($flash.type === 'success') {
|
||||
toast.success($flash.message);
|
||||
} else {
|
||||
toast.error($flash.message, {
|
||||
duration: 5000
|
||||
});
|
||||
// Clearing the flash message could sometimes
|
||||
// be required here to avoid double-toasting.
|
||||
flash.set(undefined);
|
||||
}
|
||||
|
||||
// Clearing the flash message could sometimes
|
||||
// be required here to avoid double-toasting.
|
||||
flash.set(undefined);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<h1>Do the admin stuff</h1>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import DataTable from './user-table.svelte';
|
||||
export let data;
|
||||
const { data } = $props();
|
||||
</script>
|
||||
|
||||
<h1>Users</h1>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import { Button } from '$lib/components/ui/button';
|
||||
// import AddRolesForm from './add-roles-form.svelte';
|
||||
|
||||
export let data;
|
||||
const { data } = $props();
|
||||
|
||||
const { user, availableRoles } = data;
|
||||
const { user_roles }: { user_roles: { role: { name: string, cuid: string } }[] } = user;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
export let data;
|
||||
const { data } = $props();
|
||||
let collections = data?.collections || [];
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -56,10 +56,8 @@ export const actions: Actions = {
|
|||
return fail(401);
|
||||
}
|
||||
|
||||
const user = event.locals.user;
|
||||
|
||||
const dbUser = await db.query.users.findFirst({
|
||||
where: eq(users.id, user.id),
|
||||
where: eq(users.id, user!.id),
|
||||
});
|
||||
|
||||
if (!dbUser?.hashed_password) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import Header from '$components/Header.svelte';
|
||||
import Footer from '$components/Footer.svelte';
|
||||
|
||||
export let data;
|
||||
const { data, children } = $props();
|
||||
|
||||
console.log('layout data user', data.user);
|
||||
</script>
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
<Header user={data.user} />
|
||||
|
||||
<main>
|
||||
<slot />
|
||||
{@render children()}
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import type { MetaTagsProps } from 'svelte-meta-tags';
|
|||
import { eq } from 'drizzle-orm';
|
||||
import type { PageServerLoad } from './$types';
|
||||
import db from '../../db';
|
||||
import { collections, wishlists } from '$db/schema';
|
||||
import { collections, users, wishlists } from '$db/schema';
|
||||
import { userFullyAuthenticated } from '$lib/server/auth-utils';
|
||||
|
||||
export const load: PageServerLoad = async (event) => {
|
||||
|
|
@ -42,6 +42,10 @@ export const load: PageServerLoad = async (event) => {
|
|||
});
|
||||
|
||||
if (userFullyAuthenticated(user, session)) {
|
||||
const dbUser = await db.query.users.findFirst({
|
||||
where: eq(users.id, user!.id!),
|
||||
});
|
||||
|
||||
console.log('Sending back user details');
|
||||
const userWishlists = await db.query.wishlists.findMany({
|
||||
columns: {
|
||||
|
|
@ -60,7 +64,16 @@ export const load: PageServerLoad = async (event) => {
|
|||
|
||||
console.log('Wishlists', userWishlists);
|
||||
console.log('Collections', userCollection);
|
||||
return { metaTagsChild: metaTags, user, wishlists: userWishlists, collections: userCollection };
|
||||
return {
|
||||
metaTagsChild: metaTags,
|
||||
user: {
|
||||
firstName: dbUser?.first_name,
|
||||
lastName: dbUser?.last_name,
|
||||
username: dbUser?.username,
|
||||
},
|
||||
wishlists: userWishlists,
|
||||
collections: userCollection,
|
||||
};
|
||||
}
|
||||
|
||||
return { metaTagsChild: metaTags, user: null, wishlists: [], collections: [] };
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
<script lang="ts">
|
||||
export let data;
|
||||
|
||||
const { data } = $props();
|
||||
const { user, wishlists = [], collections = []} = data;
|
||||
|
||||
const welcome = $derived(`${data?.user?.firstName} ${data?.user?.lastName}` || user?.username)
|
||||
|
||||
$inspect(data);
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
{#if user}
|
||||
<h1>Welcome, {user.username}!</h1>
|
||||
<h1>Welcome, {welcome}!</h1>
|
||||
<div>
|
||||
<h2>You wishlists:</h2>
|
||||
{#each wishlists as wishlist}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,15 @@
|
|||
<script lang="ts">
|
||||
import { Image } from 'svelte-lazy-loader';
|
||||
import { Dices, ExternalLinkIcon, MinusIcon, PlusIcon } from 'lucide-svelte';
|
||||
import type { SavedGameType } from '$lib/types';
|
||||
import { collectionStore } from '$lib/stores/collectionStore';
|
||||
import { wishlistStore } from '$lib/stores/wishlistStore';
|
||||
import type { PageData } from './$types';
|
||||
import { Button } from '$components/ui/button';
|
||||
import AddToList from '$components/AddToList.svelte';
|
||||
import Badge from '$components/ui/badge/badge.svelte';
|
||||
|
||||
$: existsInCollection = $collectionStore.find((item: SavedGameType) => item.id === game.id);
|
||||
$: existsInWishlist = $wishlistStore.find((item: SavedGameType) => item.id === game.id);
|
||||
// $: collectionText = existsInCollection ? 'Remove from collection' : 'Add to collection';
|
||||
// $: wishlistText = existsInWishlist ? 'Remove from wishlist' : 'Add to wishlist';
|
||||
const { data } = $props();
|
||||
const { game, user, in_collection, in_wishlist } = data;
|
||||
|
||||
export let data: PageData;
|
||||
console.log('data', data);
|
||||
|
||||
$: ({ game, user, wishlist, collection, in_collection, in_wishlist } = data);
|
||||
|
||||
let seeMore: boolean = false;
|
||||
let seeMore: boolean = $state(false);
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
|
@ -86,7 +76,7 @@
|
|||
<section class="description" class:show={seeMore} class:hide={!seeMore} style="margin-top: 2rem;">
|
||||
{@html game?.description}
|
||||
</section>
|
||||
<button class="btn button-icon" type="button" on:click={() => (seeMore = !seeMore)}
|
||||
<button class="btn button-icon" type="button" onclick={() => (seeMore = !seeMore)}
|
||||
>See
|
||||
{#if !seeMore}
|
||||
More
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
import { redirect } from 'sveltekit-flash-message/server';
|
||||
import { notSignedInMessage } from '$lib/flashMessages';
|
||||
|
||||
export async function load(event) {
|
||||
const { url, locals } = event;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import Logo from "$lib/components/logo.svelte";
|
||||
import Transition from '$lib/components/transition.svelte';
|
||||
|
||||
export let data;
|
||||
let { data, children } = $props();
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
style="
|
||||
background-image:
|
||||
url(https://images.unsplash.com/photo-1588591795084-1770cb3be374?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80"
|
||||
/>
|
||||
></div>
|
||||
<div class="quote-wrapper">
|
||||
<blockquote class="quote">
|
||||
<p>
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
</div>
|
||||
<div class="auth-form">
|
||||
<Transition url={data.url} transition={{ type: 'page' }}>
|
||||
<slot />
|
||||
{@render children()}
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
import * as Alert from "$components/ui/alert";
|
||||
import { boredState } from '$lib/stores/boredState.js';
|
||||
|
||||
export let data;
|
||||
let { data } = $props();
|
||||
|
||||
const superLoginForm = superForm(data.form, {
|
||||
onSubmit: () => boredState.update((n) => ({ ...n, loading: true })),
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@
|
|||
|
||||
const dev = process.env.NODE_ENV !== 'production';
|
||||
|
||||
export let data;
|
||||
$: ({ user } = data);
|
||||
const { data, children } = $props();
|
||||
const { user } = data;
|
||||
|
||||
$: metaTags = {
|
||||
const metaTags = $derived({
|
||||
titleTemplate: '%s | Bored Game',
|
||||
description: 'Bored Game, keep track of your games.',
|
||||
openGraph: {
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
description: 'Bored Game, keep track of your games',
|
||||
},
|
||||
...$page.data.metaTagsChild
|
||||
}
|
||||
});
|
||||
|
||||
const flash = getFlash(page, {
|
||||
clearOnNavigate: true,
|
||||
|
|
@ -41,34 +41,21 @@
|
|||
});
|
||||
|
||||
|
||||
$: if ($flash) {
|
||||
if ($flash.type === 'success') {
|
||||
toast.success($flash.message);
|
||||
} else {
|
||||
toast.error($flash.message, {
|
||||
duration: 5000
|
||||
});
|
||||
$effect(() => {
|
||||
if ($flash) {
|
||||
if ($flash.type === 'success') {
|
||||
toast.success($flash.message);
|
||||
} else {
|
||||
toast.error($flash.message, {
|
||||
duration: 5000
|
||||
});
|
||||
}
|
||||
|
||||
// Clearing the flash message could sometimes
|
||||
// be required here to avoid double-toasting.
|
||||
flash.set(undefined);
|
||||
}
|
||||
|
||||
// Clearing the flash message could sometimes
|
||||
// be required here to avoid double-toasting.
|
||||
flash.set(undefined);
|
||||
}
|
||||
// flash.subscribe(($flash) => {
|
||||
// if (!$flash) return;
|
||||
|
||||
// if ($flash.type === 'success') {
|
||||
// toast.success($flash.message);
|
||||
// } else {
|
||||
// toast.error($flash.message, {
|
||||
// duration: 5000
|
||||
// });
|
||||
// }
|
||||
|
||||
// // Clearing the flash message could sometimes
|
||||
// // be required here to avoid double-toasting.
|
||||
// flash.set(undefined);
|
||||
// });
|
||||
});
|
||||
|
||||
onNavigate(async (navigation) => {
|
||||
if (!document.startViewTransition) return;
|
||||
|
|
@ -91,7 +78,7 @@
|
|||
<PageLoadingIndicator />
|
||||
|
||||
<div class="layout">
|
||||
<slot />
|
||||
{@render children()}
|
||||
</div>
|
||||
|
||||
<Toaster />
|
||||
|
|
|
|||
Loading…
Reference in a new issue