diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 003711fc..a2b5d10d 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -1,34 +1,36 @@ { - "permissions": { - "allow": [ - "Bash(pnpm check:*)", - "mcp__ide__getDiagnostics", - "mcp__plugin_svelte_svelte__svelte-autofixer", - "mcp__plugin_svelte_svelte__list-sections", - "Bash(pkill:*)", - "Bash(timeout 8 pnpm dev:*)", - "Bash(git checkout:*)", - "Bash(npx svelte-kit:*)", - "Bash(ls:*)", - "Bash(pnpm format:*)", - "Bash(pnpm add:*)", - "WebSearch", - "WebFetch(domain:github.com)", - "WebFetch(domain:flipclockjs.com)", - "WebFetch(domain:codepen.io)", - "WebFetch(domain:flo-bit.dev)", - "Bash(pnpm install)", - "Bash(pnpm install:*)", - "Bash(pnpm config:*)", - "Bash(lsof:*)", - "Bash(pnpm dev)", - "Bash(pnpm exec svelte-kit:*)", - "Bash(pnpm build:*)", - "Bash(pnpm remove:*)", - "Bash(grep:*)", - "Bash(find:*)", - "Bash(npx prettier:*)", - "Bash(node -e:*)" - ] - } + "permissions": { + "allow": [ + "Bash(pnpm check:*)", + "mcp__ide__getDiagnostics", + "mcp__plugin_svelte_svelte__svelte-autofixer", + "mcp__plugin_svelte_svelte__list-sections", + "Bash(pkill:*)", + "Bash(timeout 8 pnpm dev:*)", + "Bash(git checkout:*)", + "Bash(npx svelte-kit:*)", + "Bash(ls:*)", + "Bash(pnpm format:*)", + "Bash(pnpm add:*)", + "WebSearch", + "WebFetch(domain:github.com)", + "WebFetch(domain:flipclockjs.com)", + "WebFetch(domain:codepen.io)", + "WebFetch(domain:flo-bit.dev)", + "Bash(pnpm install)", + "Bash(pnpm install:*)", + "Bash(pnpm config:*)", + "Bash(lsof:*)", + "Bash(pnpm dev)", + "Bash(pnpm exec svelte-kit:*)", + "Bash(pnpm build:*)", + "Bash(pnpm remove:*)", + "Bash(grep:*)", + "Bash(find:*)", + "Bash(npx prettier:*)", + "Bash(node -e:*)", + "mcp__plugin_svelte_svelte__get-documentation", + "WebFetch(domain:bits-ui.com)" + ] + } } diff --git a/package.json b/package.json index d889dbef..71c40663 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "@foxui/social": "^0.4.7", "@foxui/time": "^0.4.7", "@foxui/visual": "^0.4.7", + "@internationalized/date": "^3.11.0", "@number-flow/svelte": "^0.3.10", "@tailwindcss/typography": "^0.5.19", "@threlte/core": "^8.3.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 320fabac..a1ad7dba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -62,6 +62,9 @@ importers: '@foxui/visual': specifier: ^0.4.7 version: 0.4.7(svelte@5.48.0)(tailwindcss@4.1.18) + '@internationalized/date': + specifier: ^3.11.0 + version: 3.11.0 '@number-flow/svelte': specifier: ^0.3.10 version: 0.3.10(svelte@5.48.0) @@ -124,7 +127,7 @@ importers: version: 0.176.0 bits-ui: specifier: ^2.15.4 - version: 2.15.4(@internationalized/date@3.10.1)(@sveltejs/kit@2.50.1(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)))(svelte@5.48.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)))(svelte@5.48.0) + version: 2.15.4(@internationalized/date@3.11.0)(@sveltejs/kit@2.50.1(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)))(svelte@5.48.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)))(svelte@5.48.0) clsx: specifier: ^2.1.1 version: 2.1.1 @@ -964,8 +967,8 @@ packages: cpu: [x64] os: [win32] - '@internationalized/date@3.10.1': - resolution: {integrity: sha512-oJrXtQiAXLvT9clCf1K4kxp3eKsQhIaZqxEyowkBcsvZDdZkbWrVmnGknxs5flTD0VGsxrxKgBCZty1EzoiMzA==} + '@internationalized/date@3.11.0': + resolution: {integrity: sha512-BOx5huLAWhicM9/ZFs84CzP+V3gBW6vlpM02yzsdYC7TGlZJX1OJiEEHcSayF00Z+3jLlm4w79amvSt6RqKN3Q==, tarball: https://registry.npmjs.org/@internationalized/date/-/date-3.11.0.tgz} '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -1233,7 +1236,7 @@ packages: vite: ^6.3.0 || ^7.0.0 '@swc/helpers@0.5.18': - resolution: {integrity: sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==} + resolution: {integrity: sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==, tarball: https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.18.tgz} '@tailwindcss/forms@0.5.11': resolution: {integrity: sha512-h9wegbZDPurxG22xZSoWtdzc41/OlNEUQERNqI/0fOwa2aVlWGu7C35E/x6LDyD3lgtztFSSjKZyuVM0hxhbgA==} @@ -3043,7 +3046,7 @@ packages: typescript: '>=4.8.4' tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==, tarball: https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz} turndown@7.2.2: resolution: {integrity: sha512-1F7db8BiExOKxjSMU2b7if62D/XOyQyZbPKq/nUwopfgnHlqXHqQ0lvfUTeUIr1lZJzOPFn43dODyMSIfvWRKQ==} @@ -3811,7 +3814,7 @@ snapshots: '@img/sharp-win32-x64@0.34.5': optional: true - '@internationalized/date@3.10.1': + '@internationalized/date@3.11.0': dependencies: '@swc/helpers': 0.5.18 @@ -4587,7 +4590,7 @@ snapshots: dependencies: '@floating-ui/core': 1.7.3 '@floating-ui/dom': 1.7.5 - '@internationalized/date': 3.10.1 + '@internationalized/date': 3.11.0 css.escape: 1.5.1 esm-env: 1.2.2 runed: 0.23.4(svelte@5.48.0) @@ -4595,11 +4598,11 @@ snapshots: svelte-toolbelt: 0.7.1(svelte@5.48.0) tabbable: 6.4.0 - bits-ui@2.15.4(@internationalized/date@3.10.1)(@sveltejs/kit@2.50.1(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)))(svelte@5.48.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)))(svelte@5.48.0): + bits-ui@2.15.4(@internationalized/date@3.11.0)(@sveltejs/kit@2.50.1(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)))(svelte@5.48.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)))(svelte@5.48.0): dependencies: '@floating-ui/core': 1.7.3 '@floating-ui/dom': 1.7.5 - '@internationalized/date': 3.10.1 + '@internationalized/date': 3.11.0 esm-env: 1.2.2 runed: 0.35.1(@sveltejs/kit@2.50.1(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.48.0)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)))(svelte@5.48.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)))(svelte@5.48.0) svelte: 5.48.0 diff --git a/src/lib/components/DatePicker.svelte b/src/lib/components/DatePicker.svelte new file mode 100644 index 00000000..b3a03326 --- /dev/null +++ b/src/lib/components/DatePicker.svelte @@ -0,0 +1,244 @@ + + + +
+ + {#snippet children({ segments })} + {#each segments as segment, i (segment.part + i)} + {#if segment.part === 'literal'} + {segment.value} + {:else} + + {segment.value} + + {/if} + {/each} + {/snippet} + + + + + + + +
+ + + + {#snippet children({ months, weekdays })} + + + + + + + +
+ + +
+ + + + + + +
+ + {#each months as month (month.value.month)} + + + + {#each weekdays as weekday, i (i)} + + {weekday} + + {/each} + + + + + {#each month.weeks as week, weekIndex (weekIndex)} + + {#each week as day (day.toString())} + + + {#snippet children({ selected, disabled, day: dayText })} +
+ {dayText} + {#if day.day === todayDay && day.month === todayMonth && day.year === todayYear} + + {/if} +
+ {/snippet} +
+
+ {/each} +
+ {/each} +
+
+ {/each} + {/snippet} +
+
+
diff --git a/src/lib/components/DateTimePicker.svelte b/src/lib/components/DateTimePicker.svelte new file mode 100644 index 00000000..df75172b --- /dev/null +++ b/src/lib/components/DateTimePicker.svelte @@ -0,0 +1,73 @@ + + +
+ +
+ +
+
diff --git a/src/lib/components/TimePicker.svelte b/src/lib/components/TimePicker.svelte new file mode 100644 index 00000000..e9b565fa --- /dev/null +++ b/src/lib/components/TimePicker.svelte @@ -0,0 +1,101 @@ + + + +
+ + {#snippet children({ segments })} + {#each segments as segment, i (segment.part + i)} + {#if segment.part === 'literal'} + {segment.value} + {:else} + + {segment.value} + + {/if} + {/each} + {/snippet} + + + + + +
+
diff --git a/src/routes/[[actor=actor]]/events/+page.svelte b/src/routes/[[actor=actor]]/events/+page.svelte index 07b8c28c..d69df228 100644 --- a/src/routes/[[actor=actor]]/events/+page.svelte +++ b/src/routes/[[actor=actor]]/events/+page.svelte @@ -4,6 +4,8 @@ import { user } from '$lib/atproto/auth.svelte'; import { Avatar as FoxAvatar, Badge, Button } from '@foxui/core'; import Avatar from 'svelte-boring-avatars'; + import * as TID from '@atcute/tid'; + import { goto } from '$app/navigation'; let { data } = $props(); @@ -110,7 +112,17 @@ {#if isOwner} - + {/if} diff --git a/src/routes/[[actor=actor]]/events/[rkey]/+page.svelte b/src/routes/[[actor=actor]]/events/[rkey]/+page.svelte index 89da235b..ddc9d0cc 100644 --- a/src/routes/[[actor=actor]]/events/[rkey]/+page.svelte +++ b/src/routes/[[actor=actor]]/events/[rkey]/+page.svelte @@ -251,7 +251,7 @@ {eventData.name} {#if isOwner} - + {/if} diff --git a/src/routes/[[actor=actor]]/events/[rkey]/edit/+page.server.ts b/src/routes/[[actor=actor]]/events/[rkey]/edit/+page.server.ts index 463a15e7..83344078 100644 --- a/src/routes/[[actor=actor]]/events/[rkey]/edit/+page.server.ts +++ b/src/routes/[[actor=actor]]/events/[rkey]/edit/+page.server.ts @@ -22,7 +22,7 @@ export async function load({ params, platform, request }) { did: did as Did, collection: 'community.lexicon.calendar.event', rkey - }), + }).catch(() => null), cache ? cache.getProfile(did as Did).catch(() => null) : getBlentoOrBskyProfile({ did: did as Did }) @@ -40,7 +40,13 @@ export async function load({ params, platform, request }) { ]); if (!eventRecord?.value) { - throw error(404, 'Event not found'); + return { + eventData: null, + did, + rkey, + hostProfile: hostProfile ?? null, + eventCid: null + }; } const eventData: EventData = eventRecord.value as EventData; diff --git a/src/routes/[[actor=actor]]/events/[rkey]/edit/+page.svelte b/src/routes/[[actor=actor]]/events/[rkey]/edit/+page.svelte index 1095c581..b3a0212d 100644 --- a/src/routes/[[actor=actor]]/events/[rkey]/edit/+page.svelte +++ b/src/routes/[[actor=actor]]/events/[rkey]/edit/+page.svelte @@ -1,10 +1,20 @@ - Edit Event + {isNew ? 'Create Event' : 'Edit Event'}
@@ -558,23 +618,12 @@
-

Log in to edit this event.

+

+ Log in to {isNew ? 'create an event' : 'edit this event'}. +

{:else} -
- Local edit - {#if hasDraft} - - {/if} -
-
{ e.preventDefault(); @@ -600,39 +649,32 @@ onchange={onFileChange} class="hidden" /> - {#if thumbnailPreview} -
- - -
- {:else} + +
+ {/if} + - {/if} + {#if thumbnailPreview} + + {/if} +
- - + +
+ + +
@@ -686,9 +759,9 @@
-
+
{#if startDate}
- {#if startDate} -

- {formatWeekday(startDate)}, {formatFullDate(startDate)} - {#if endDate && !isSameDay} - - {formatWeekday(endDate)}, {formatFullDate(endDate)} + {#if startDate && !editingDates} + +

+ + +
+ {:else} + +
+
+ {#if endsAt} + Start + {/if} + +
+ {#if endsAt} +
+ End + + +
+ {:else} + {/if} -

-

- {formatTime(startDate)} - {#if endDate && isSameDay} - - {formatTime(endDate)} + {#if startDate} + {/if} -

+
{/if} -
- - -
@@ -757,7 +918,7 @@ {#if location}
{getLocationDisplayString(location)}

-
{:else} -
- Add location - + Add location + +
{/if} @@ -844,7 +994,8 @@ bind:value={description} rows={4} placeholder="What's this event about? @mentions, #hashtags and links will be detected automatically." - class="text-base-700 dark:text-base-300 placeholder:text-base-300 dark:placeholder:text-base-700 w-full resize-none border-0 bg-transparent leading-relaxed focus:border-0 focus:ring-0 focus:outline-none" + class="text-base-700 dark:text-base-300 placeholder:text-base-500 dark:placeholder:text-base-500 w-full resize-none border-0 bg-transparent px-0 leading-relaxed focus:border-0 focus:ring-0 focus:outline-none" + style="field-sizing: content;" >
@@ -852,8 +1003,14 @@

{error}

{/if} -
@@ -899,11 +1056,11 @@ {link.name || link.uri.replace(/^https?:\/\//, '')} - + {/each} -
- +
+ + + - + +
-
- {/if} + + + + {#if !isNew} +
+ {#if showDeleteConfirm} +
+

+ Are you sure? This cannot be undone. +

+ + +
+ {:else} + + {/if} +
+ {/if} {/if} @@ -993,12 +1200,7 @@ class="mt-2" >
- + diff --git a/src/routes/[[actor=actor]]/events/new/+page.svelte b/src/routes/[[actor=actor]]/events/new/+page.svelte deleted file mode 100644 index 0c248cdd..00000000 --- a/src/routes/[[actor=actor]]/events/new/+page.svelte +++ /dev/null @@ -1,967 +0,0 @@ - - - - Create Event - - -
-
- {#if user.isInitializing} -
-
-
-
- {:else if !user.isLoggedIn} -
-

Log in to create an event.

- -
- {:else} -
- Local draft - {#if hasDraft} - - {/if} -
- -
{ - e.preventDefault(); - handleSubmit(); - }} - > - -
- - -
- - {#if thumbnailPreview} -
- - -
- {:else} - - {/if} -
- - -
- - - - -
- { - return mode; - }, - (val) => { - if (val) mode = val; - } - } - class="w-fit" - > - In Person - Virtual - Hybrid - -
- - -
-
- {#if startDate} - - {formatMonth(startDate)} - - - {formatDay(startDate)} - - {:else} - - - - {/if} -
-
- {#if startDate} -

- {formatWeekday(startDate)}, {formatFullDate(startDate)} - {#if endDate && !isSameDay} - - {formatWeekday(endDate)}, {formatFullDate(endDate)} - {/if} -

-

- {formatTime(startDate)} - {#if endDate && isSameDay} - - {formatTime(endDate)} - {/if} -

- {/if} -
- - -
-
-
- - - {#if location} -
-
- - - - -
-

- {getLocationDisplayString(location)} -

- -
- {:else} - - {/if} - - -
-

- About -

- -
- - {#if error} -

{error}

- {/if} - - -
- - -
-

- Hosted By -

-
- - - {hostName} - -
-
- - -
-

- Links -

-
- {#each links as link, i (i)} -
- - - - - {link.name || link.uri.replace(/^https?:\/\//, '')} - - -
- {/each} -
- -
- - - {#if showLinkPopup} -
- - -
- - -
-
- {/if} -
-
-
-
- {/if} -
-
- - - -

Add location

-
{ - e.preventDefault(); - searchLocation(); - }} - class="mt-2" - > -
- - -
-
- - {#if locationError} -

{locationError}

- {/if} - - {#if locationResult} -
-
- - - - -
-

- {getLocationDisplayString(locationResult.location)} -

-

- {locationResult.displayName} -

-
-
-
- -
-
- {/if} - -

- Geocoding by Nominatim - / © - OpenStreetMap contributors -

-