From 314885b704c09d1695480e02ae12351d5967e951 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Mon, 3 Nov 2025 23:03:50 -0800 Subject: [PATCH] feat: add utility components and helpers Add DropdownSelectField and StatusPicker components for form inputs. Add time utility functions. --- .../admin/DropdownSelectField.svelte | 159 +++++++++++++++ src/lib/components/admin/StatusPicker.svelte | 189 ++++++++++++++++++ src/lib/utils/time.ts | 27 +++ 3 files changed, 375 insertions(+) create mode 100644 src/lib/components/admin/DropdownSelectField.svelte create mode 100644 src/lib/components/admin/StatusPicker.svelte create mode 100644 src/lib/utils/time.ts diff --git a/src/lib/components/admin/DropdownSelectField.svelte b/src/lib/components/admin/DropdownSelectField.svelte new file mode 100644 index 0000000..8c7bd89 --- /dev/null +++ b/src/lib/components/admin/DropdownSelectField.svelte @@ -0,0 +1,159 @@ + + + + {#snippet children()} + + {/snippet} + + + diff --git a/src/lib/components/admin/StatusPicker.svelte b/src/lib/components/admin/StatusPicker.svelte new file mode 100644 index 0000000..5b715c8 --- /dev/null +++ b/src/lib/components/admin/StatusPicker.svelte @@ -0,0 +1,189 @@ + + +
+ + + {#if isOpen} + + {#each availableStatuses as status} + {#if status.value !== currentStatus} + handleStatusChange(status.value)}> + {status.label} + + {/if} + {/each} + + {#if viewUrl && currentStatus === 'published'} + + + View on site + + {/if} + + {/if} +
+ + diff --git a/src/lib/utils/time.ts b/src/lib/utils/time.ts new file mode 100644 index 0000000..8e945d6 --- /dev/null +++ b/src/lib/utils/time.ts @@ -0,0 +1,27 @@ +/** + * Format a date as a relative time string (e.g., "2 minutes ago") + * @param date - The date to format + * @returns A human-readable relative time string + */ +export function formatTimeAgo(date: Date | string): string { + const now = new Date() + const past = new Date(date) + const seconds = Math.floor((now.getTime() - past.getTime()) / 1000) + + if (seconds < 10) return 'just now' + if (seconds < 60) return `${seconds} seconds ago` + + const minutes = Math.floor(seconds / 60) + if (minutes < 60) return minutes === 1 ? '1 minute ago' : `${minutes} minutes ago` + + const hours = Math.floor(minutes / 60) + if (hours < 24) return hours === 1 ? '1 hour ago' : `${hours} hours ago` + + // For saves older than 24 hours, show formatted date + return past.toLocaleDateString(undefined, { + month: 'short', + day: 'numeric', + hour: 'numeric', + minute: '2-digit' + }) +}