summaryrefslogtreecommitdiff
path: root/src/components/AppEventDate.svelte
diff options
context:
space:
mode:
authorrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
committerrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
commitbce557cc2dc767628bed6aac87301a1be7c5431b (patch)
treeb51a051228d01fe3306cd7626d4a96768aadb944 /src/components/AppEventDate.svelte
init commit
Diffstat (limited to 'src/components/AppEventDate.svelte')
-rw-r--r--src/components/AppEventDate.svelte72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/components/AppEventDate.svelte b/src/components/AppEventDate.svelte
new file mode 100644
index 0000000..41ee248
--- /dev/null
+++ b/src/components/AppEventDate.svelte
@@ -0,0 +1,72 @@
+<script lang="ts">
+ import { onMount } from 'svelte';
+ import { fade } from 'svelte/transition';
+ import type { Optional } from '@jet/environment/types/optional';
+ import type { AppEvent } from '@jet-app/app-store/api/models';
+ import { getJet } from '~/jet';
+ import {
+ chooseAppEventDate,
+ renderDate,
+ computeAppEventFormattedDates,
+ type RequiredAppEventFormattedDate,
+ } from '~/jet/utils/app-event-formatted-date';
+
+ const jet = getJet();
+
+ /**
+ * New pattern (*prefered*): accept appEvent object and compute formattedDates on client-side.
+ * This avoids timezone differences in SSR server (UTC) which cause incorrect event date and time.
+ * By computing dates in the browser, we ensure the user sees dates in their local timezone.
+ */
+ export let appEvent:
+ | Pick<AppEvent, 'appEventBadgeKind' | 'startDate' | 'endDate'>
+ | undefined = undefined;
+
+ // Legacy pattern: accept pre-computed formattedDates from Jet
+ export let formattedDates: RequiredAppEventFormattedDate[] | undefined =
+ undefined;
+
+ let appEventDate: Optional<RequiredAppEventFormattedDate>;
+
+ onMount(() => {
+ const dates = appEvent
+ ? computeAppEventFormattedDates(
+ jet.objectGraph,
+ appEvent.appEventBadgeKind,
+ appEvent.startDate,
+ appEvent.endDate,
+ )
+ : formattedDates;
+
+ if (dates) {
+ appEventDate = chooseAppEventDate(dates);
+ }
+ });
+
+ /**
+ * `Date` instances in the view-model will have been serialized to `string`
+ * instances by ServerKit when delivered to the client; we need to normalize
+ * this so that we have a `string` both client- and server-side.
+ */
+ function normalizeDate(date: Date | string): string {
+ return typeof date === 'string' ? date : date.toISOString();
+ }
+</script>
+
+{#if appEventDate}
+ <time
+ transition:fade={{ duration: 210 }}
+ datetime={appEventDate.displayFromDate &&
+ normalizeDate(appEventDate.displayFromDate)}
+ >
+ {renderDate(jet.objectGraph.loc, appEventDate)}
+ </time>
+{:else}
+ <span aria-hidden="true">&hellip;</span>
+{/if}
+
+<style>
+ span {
+ color: transparent;
+ }
+</style>