1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-07-20 21:39:37 +02:00

Refactor AdventureCard usage and integrate event calendar components

This commit is contained in:
Sean Morley 2024-12-04 12:38:01 -05:00
parent a39e22b0a8
commit d44cb06e31
10 changed files with 124 additions and 78 deletions

View file

@ -12,6 +12,9 @@
"format": "prettier --write ." "format": "prettier --write ."
}, },
"devDependencies": { "devDependencies": {
"@event-calendar/core": "^3.7.1",
"@event-calendar/day-grid": "^3.7.1",
"@event-calendar/time-grid": "^3.7.1",
"@iconify-json/mdi": "^1.1.67", "@iconify-json/mdi": "^1.1.67",
"@sveltejs/adapter-auto": "^3.2.2", "@sveltejs/adapter-auto": "^3.2.2",
"@sveltejs/adapter-node": "^5.2.0", "@sveltejs/adapter-node": "^5.2.0",

View file

@ -18,6 +18,15 @@ importers:
specifier: ^0.9.8 specifier: ^0.9.8
version: 0.9.8(svelte@4.2.19) version: 0.9.8(svelte@4.2.19)
devDependencies: devDependencies:
'@event-calendar/core':
specifier: ^3.7.1
version: 3.7.1
'@event-calendar/day-grid':
specifier: ^3.7.1
version: 3.7.1
'@event-calendar/time-grid':
specifier: ^3.7.1
version: 3.7.1
'@iconify-json/mdi': '@iconify-json/mdi':
specifier: ^1.1.67 specifier: ^1.1.67
version: 1.1.67 version: 1.1.67
@ -374,6 +383,15 @@ packages:
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@event-calendar/core@3.7.1':
resolution: {integrity: sha512-S5D4arG7b47uhXmcT/rC7FT3UO9+KB+QhDuhfOzDgKCpAFlEBU1wt1UoHmPTbGy3J+yVMR+rmcresYUvM44+pA==}
'@event-calendar/day-grid@3.7.1':
resolution: {integrity: sha512-kwmadkhUxtQDv+0azMkePrmilFp5dljWLHsluHl1uepfJa1yXlrvFy3GMFnYuPo2Gva0MV+HnU/GMqVG8vIcWw==}
'@event-calendar/time-grid@3.7.1':
resolution: {integrity: sha512-kPC4+XhFcSoNSnYG0TSQeGylpvrbFF1g+cTcFFIW6qH3wPIeBBCo0fRuD4Tr5/q4ewZQ5lNrCkZXOpZxHJxOfw==}
'@formatjs/ecma402-abstract@2.2.1': '@formatjs/ecma402-abstract@2.2.1':
resolution: {integrity: sha512-O4ywpkdJybrjFc9zyL8qK5aklleIAi5O4nYhBVJaOFtCkNrnU+lKFeJOFC48zpsZQmR8Aok2V79hGpHnzbmFpg==} resolution: {integrity: sha512-O4ywpkdJybrjFc9zyL8qK5aklleIAi5O4nYhBVJaOFtCkNrnU+lKFeJOFC48zpsZQmR8Aok2V79hGpHnzbmFpg==}
@ -2167,6 +2185,20 @@ snapshots:
'@esbuild/win32-x64@0.21.5': '@esbuild/win32-x64@0.21.5':
optional: true optional: true
'@event-calendar/core@3.7.1':
dependencies:
svelte: 4.2.19
'@event-calendar/day-grid@3.7.1':
dependencies:
'@event-calendar/core': 3.7.1
svelte: 4.2.19
'@event-calendar/time-grid@3.7.1':
dependencies:
'@event-calendar/core': 3.7.1
svelte: 4.2.19
'@formatjs/ecma402-abstract@2.2.1': '@formatjs/ecma402-abstract@2.2.1':
dependencies: dependencies:
'@formatjs/fast-memoize': 2.2.2 '@formatjs/fast-memoize': 2.2.2

View file

@ -5,17 +5,12 @@ const PUBLIC_SERVER_URL = process.env['PUBLIC_SERVER_URL'];
export const authHook: Handle = async ({ event, resolve }) => { export const authHook: Handle = async ({ event, resolve }) => {
try { try {
let sessionid = event.cookies.get('sessionid'); let sessionid = event.cookies.get('sessionid');
console.log('sessionid:', sessionid);
if (!sessionid) { if (!sessionid) {
console.log('No sessionid cookie');
event.locals.user = null; event.locals.user = null;
return await resolve(event); return await resolve(event);
} }
// print all cookies in the request
console.log('Cookies:', event.request.headers.get('cookie'));
const serverEndpoint = PUBLIC_SERVER_URL || 'http://localhost:8000'; const serverEndpoint = PUBLIC_SERVER_URL || 'http://localhost:8000';
const cookie = event.request.headers.get('cookie') || ''; const cookie = event.request.headers.get('cookie') || '';
@ -37,8 +32,6 @@ export const authHook: Handle = async ({ event, resolve }) => {
event.locals.user = user; event.locals.user = user;
const setCookieHeader = userFetch.headers.get('Set-Cookie'); const setCookieHeader = userFetch.headers.get('Set-Cookie');
console.log('setCookieHeader:', setCookieHeader);
if (setCookieHeader) { if (setCookieHeader) {
// Regular expression to match sessionid cookie and its expiry // Regular expression to match sessionid cookie and its expiry
const sessionIdRegex = /sessionid=([^;]+).*?expires=([^;]+)/; const sessionIdRegex = /sessionid=([^;]+).*?expires=([^;]+)/;
@ -49,9 +42,6 @@ export const authHook: Handle = async ({ event, resolve }) => {
const expiryString = match[2]; const expiryString = match[2];
const expiryDate = new Date(expiryString); const expiryDate = new Date(expiryString);
console.log('Session ID:', sessionId);
console.log('Expiry Date:', expiryDate);
// Set the sessionid cookie // Set the sessionid cookie
event.cookies.set('sessionid', sessionId, { event.cookies.set('sessionid', sessionId, {
path: '/', path: '/',

View file

@ -19,9 +19,10 @@
import CardCarousel from './CardCarousel.svelte'; import CardCarousel from './CardCarousel.svelte';
import { t } from 'svelte-i18n'; import { t } from 'svelte-i18n';
export let type: string; export let type: string | null = null;
export let user: User | null; export let user: User | null;
export let collection: Collection | null = null; export let collection: Collection | null = null;
export let readOnly: boolean = false;
let isCollectionModalOpen: boolean = false; let isCollectionModalOpen: boolean = false;
let isWarningModalOpen: boolean = false; let isWarningModalOpen: boolean = false;
@ -164,61 +165,67 @@
{/each} {/each}
</ul> </ul>
{/if} {/if}
<div class="card-actions justify-end mt-2"> {#if !readOnly}
<!-- action options dropdown --> <div class="card-actions justify-end mt-2">
{#if type != 'link'} <!-- action options dropdown -->
{#if adventure.user_id == user?.uuid || (collection && user && collection.shared_with.includes(user.uuid))}
<div class="dropdown dropdown-end">
<div tabindex="0" role="button" class="btn btn-neutral-200">
<DotsHorizontal class="w-6 h-6" />
</div>
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<ul
tabindex="0"
class="dropdown-content menu bg-base-100 rounded-box z-[1] w-52 p-2 shadow"
>
<button
class="btn btn-neutral mb-2"
on:click={() => goto(`/adventures/${adventure.id}`)}
><Launch class="w-6 h-6" />{$t('adventures.open_details')}</button
>
<button class="btn btn-neutral mb-2" on:click={editAdventure}>
<FileDocumentEdit class="w-6 h-6" />
{$t('adventures.edit_adventure')}
</button>
<!-- remove from collection --> {#if type != 'link'}
{#if adventure.collection && user?.uuid == adventure.user_id} {#if adventure.user_id == user?.uuid || (collection && user && collection.shared_with.includes(user.uuid))}
<button class="btn btn-neutral mb-2" on:click={removeFromCollection} <div class="dropdown dropdown-end">
><LinkVariantRemove class="w-6 h-6" />{$t( <div tabindex="0" role="button" class="btn btn-neutral-200">
'adventures.remove_from_collection' <DotsHorizontal class="w-6 h-6" />
)}</button </div>
> <!-- svelte-ignore a11y-no-noninteractive-tabindex -->
{/if} <ul
{#if !adventure.collection} tabindex="0"
<button class="btn btn-neutral mb-2" on:click={() => (isCollectionModalOpen = true)} class="dropdown-content menu bg-base-100 rounded-box z-[1] w-52 p-2 shadow"
><Plus class="w-6 h-6" />{$t('adventures.add_to_collection')}</button
>
{/if}
<button
id="delete_adventure"
data-umami-event="Delete Adventure"
class="btn btn-warning"
on:click={() => (isWarningModalOpen = true)}
><TrashCan class="w-6 h-6" />{$t('adventures.delete')}</button
> >
</ul> <button
</div> class="btn btn-neutral mb-2"
{:else} on:click={() => goto(`/adventures/${adventure.id}`)}
<button ><Launch class="w-6 h-6" />{$t('adventures.open_details')}</button
class="btn btn-neutral-200 mb-2" >
on:click={() => goto(`/adventures/${adventure.id}`)}><Launch class="w-6 h-6" /></button <button class="btn btn-neutral mb-2" on:click={editAdventure}>
> <FileDocumentEdit class="w-6 h-6" />
{$t('adventures.edit_adventure')}
</button>
<!-- remove from collection -->
{#if adventure.collection && user?.uuid == adventure.user_id}
<button class="btn btn-neutral mb-2" on:click={removeFromCollection}
><LinkVariantRemove class="w-6 h-6" />{$t(
'adventures.remove_from_collection'
)}</button
>
{/if}
{#if !adventure.collection}
<button
class="btn btn-neutral mb-2"
on:click={() => (isCollectionModalOpen = true)}
><Plus class="w-6 h-6" />{$t('adventures.add_to_collection')}</button
>
{/if}
<button
id="delete_adventure"
data-umami-event="Delete Adventure"
class="btn btn-warning"
on:click={() => (isWarningModalOpen = true)}
><TrashCan class="w-6 h-6" />{$t('adventures.delete')}</button
>
</ul>
</div>
{:else}
<button
class="btn btn-neutral-200 mb-2"
on:click={() => goto(`/adventures/${adventure.id}`)}
><Launch class="w-6 h-6" /></button
>
{/if}
{/if} {/if}
{/if} {#if type == 'link'}
{#if type == 'link'} <button class="btn btn-primary" on:click={link}><Link class="w-6 h-6" /></button>
<button class="btn btn-primary" on:click={link}><Link class="w-6 h-6" /></button> {/if}
{/if} </div>
</div> {/if}
</div> </div>
</div> </div>

View file

@ -1,5 +1,4 @@
<script lang="ts"> <script lang="ts">
import { deserialize } from '$app/forms';
import type { Adventure, User } from '$lib/types'; import type { Adventure, User } from '$lib/types';
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
@ -59,7 +58,7 @@
{/if} {/if}
<div class="flex flex-wrap gap-4 mr-4 justify-center content-center"> <div class="flex flex-wrap gap-4 mr-4 justify-center content-center">
{#each adventures as adventure} {#each adventures as adventure}
<AdventureCard user={user ?? null} type="link" {adventure} on:link={add} /> <AdventureCard {user} type="link" {adventure} on:link={add} />
{/each} {/each}
{#if adventures.length === 0 && !isLoading} {#if adventures.length === 0 && !isLoading}
<p class="text-center text-lg"> <p class="text-center text-lg">

View file

@ -2,9 +2,16 @@ const PUBLIC_SERVER_URL = process.env['PUBLIC_SERVER_URL'];
import { redirect, type Actions } from '@sveltejs/kit'; import { redirect, type Actions } from '@sveltejs/kit';
import { themes } from '$lib'; import { themes } from '$lib';
import { fetchCSRFToken } from '$lib/index.server'; import { fetchCSRFToken } from '$lib/index.server';
import type { PageServerLoad } from './$types';
const serverEndpoint = PUBLIC_SERVER_URL || 'http://localhost:8000'; const serverEndpoint = PUBLIC_SERVER_URL || 'http://localhost:8000';
export const load = (async (event) => {
if (event.locals.user) {
return redirect(302, '/dashboard');
}
}) satisfies PageServerLoad;
export const actions: Actions = { export const actions: Actions = {
setTheme: async ({ url, cookies }) => { setTheme: async ({ url, cookies }) => {
const theme = url.searchParams.get('theme'); const theme = url.searchParams.get('theme');

View file

@ -226,7 +226,6 @@
{#each adventures as adventure} {#each adventures as adventure}
<AdventureCard <AdventureCard
user={data.user} user={data.user}
type={adventure.type}
{adventure} {adventure}
on:delete={deleteAdventure} on:delete={deleteAdventure}
on:edit={editAdventure} on:edit={editAdventure}

View file

@ -398,7 +398,6 @@
user={data.user} user={data.user}
on:edit={editAdventure} on:edit={editAdventure}
on:delete={deleteAdventure} on:delete={deleteAdventure}
type={adventure.type}
{adventure} {adventure}
{collection} {collection}
/> />
@ -521,7 +520,6 @@
user={data.user} user={data.user}
on:edit={editAdventure} on:edit={editAdventure}
on:delete={deleteAdventure} on:delete={deleteAdventure}
type={adventure.type}
{adventure} {adventure}
/> />
{/each} {/each}

View file

@ -1,9 +1,26 @@
<script lang="ts"> <script lang="ts">
import AdventureCard from '$lib/components/AdventureCard.svelte'; import AdventureCard from '$lib/components/AdventureCard.svelte';
import type { PageData } from './$types'; import type { PageData } from './$types';
// @ts-ignore
import Calendar from '@event-calendar/core';
// @ts-ignore
import TimeGrid from '@event-calendar/time-grid';
// @ts-ignore
import DayGrid from '@event-calendar/day-grid';
export let data: PageData; export let data: PageData;
let plugins = [DayGrid, TimeGrid];
let options = {
view: 'dayGridMonth',
events: [
// 2024 december 1st
{ start: '2024-12-01', end: '2024-12-02', title: 'Event 1' },
// 2024 december 2nd
{ start: '2024-12-02', end: '2024-12-03', title: 'Event 2' }
]
};
// Mock data // Mock data
const user = data.user; const user = data.user;
const recentAdventures = data.props.adventures; const recentAdventures = data.props.adventures;
@ -82,7 +99,7 @@
<h2 class="text-3xl font-semibold mb-4">Recent Adventures</h2> <h2 class="text-3xl font-semibold mb-4">Recent Adventures</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8"> <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
{#each recentAdventures as adventure} {#each recentAdventures as adventure}
<AdventureCard {adventure} type="someType" user={data.user} /> <AdventureCard {adventure} user={data.user} readOnly />
{/each} {/each}
</div> </div>
@ -100,6 +117,7 @@
</div> </div>
</div> </div>
</div> </div>
<Calendar {plugins} {options} />
<svelte:head> <svelte:head>
<title>Dashboard | AdventureLog</title> <title>Dashboard | AdventureLog</title>

View file

@ -155,7 +155,6 @@
{#each myAdventures as adventure} {#each myAdventures as adventure}
<AdventureCard <AdventureCard
user={data.user} user={data.user}
type={adventure.type}
{adventure} {adventure}
on:delete={deleteAdventure} on:delete={deleteAdventure}
on:edit={editAdventure} on:edit={editAdventure}
@ -168,13 +167,7 @@
<h2 class="text-center font-bold text-2xl mb-4">{$t('search.public_adventures')}</h2> <h2 class="text-center font-bold text-2xl mb-4">{$t('search.public_adventures')}</h2>
<div class="flex flex-wrap gap-4 mr-4 justify-center content-center"> <div class="flex flex-wrap gap-4 mr-4 justify-center content-center">
{#each publicAdventures as adventure} {#each publicAdventures as adventure}
<AdventureCard <AdventureCard user={null} {adventure} on:delete={deleteAdventure} on:edit={editAdventure} />
user={null}
type={adventure.type}
{adventure}
on:delete={deleteAdventure}
on:edit={editAdventure}
/>
{/each} {/each}
</div> </div>
{/if} {/if}