From d0e72d94ee268303b5fc55d6c28fa1d68d8d79c4 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 8 Sep 2026 17:03:24 +0000 Subject: [PATCH] fix(dashboard): point event links at /events/ The public event page lives at /events/, but the dashboard built its links two other ways: the route field on Event Details pointed at /b/register/, and eventUrl() hung the route straight off the origin, so the drawer's Event Page button landed on /. Both now go through eventUrl/eventPath, and opening the page is a plain window navigation rather than an anchor the router could claim. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01PdA87qK8nUEBfAxs9cGzjJ --- .../components/dashboard/events/EventDrawer.vue | 4 ++-- .../components/dashboard/events/EventRoute.vue | 17 +++++++++-------- dashboard/src/utils/eventUrl.test.ts | 10 +++++++--- dashboard/src/utils/eventUrl.ts | 17 +++++++++++++++-- e2e/tests/manage-event.spec.ts | 3 +-- 5 files changed, 34 insertions(+), 17 deletions(-) diff --git a/dashboard/src/components/dashboard/events/EventDrawer.vue b/dashboard/src/components/dashboard/events/EventDrawer.vue index 0b3bc7a1..db3c8cfc 100644 --- a/dashboard/src/components/dashboard/events/EventDrawer.vue +++ b/dashboard/src/components/dashboard/events/EventDrawer.vue @@ -15,7 +15,7 @@ import EventMyTickets from "@/components/dashboard/events/EventMyTickets.vue" import type { MyEvent } from "@/types" import { timeLabel12Hour } from "@/utils/dateLabels" import { bannerPattern } from "@/utils/eventBanner" -import { copyEventUrl, eventUrl } from "@/utils/eventUrl" +import { copyEventUrl, openEventPage } from "@/utils/eventUrl" const props = defineProps<{ event: MyEvent | null }>() @@ -89,7 +89,7 @@ const endsAt = computed(() => { size="sm" label="Event Page" icon-right="lucide-arrow-up-right" - :link="eventUrl(event.route)" + @click="openEventPage(event.route)" /> diff --git a/dashboard/src/components/dashboard/events/EventRoute.vue b/dashboard/src/components/dashboard/events/EventRoute.vue index 376eaa51..8387f026 100644 --- a/dashboard/src/components/dashboard/events/EventRoute.vue +++ b/dashboard/src/components/dashboard/events/EventRoute.vue @@ -4,6 +4,7 @@ import { computed, ref, watch } from "vue" import { useCopyToClipboard } from "@/composables/useCopyToClipboard" import { checkEventRoute } from "@/data/events" +import { eventPath, eventUrl, openEventPage } from "@/utils/eventUrl" // The route the event already answers to, which is the one that opens and copies — // an edit in the field is not a live address until it is saved. @@ -15,8 +16,8 @@ const taken = defineModel("taken", { default: false }) // The host the dashboard is being used on, so the field reads as the address it will be. const hostname = window.location.hostname -// Events are served under the dashboard's own base, not off the bare host. -const publicPath = computed(() => `/b/register/${props.saved}`) +// The public event page, which is served outside the dashboard's /b base. +const publicPath = computed(() => eventPath(props.saved ?? "")) type Availability = { available: boolean; message: string } const availability = ref(null) @@ -42,9 +43,10 @@ watch(availability, (answer) => (taken.value = Boolean(answer) && !answer?.avail const copyToClipboard = useCopyToClipboard() -// The path the link opens, not the shorthand the field reads. -const copy = () => - copyToClipboard(`${window.location.origin}${publicPath.value}`, "Event link copied") +// The address the link opens, not the shorthand the field reads. +const copy = () => copyToClipboard(eventUrl(props.saved ?? ""), "Event link copied") + +const open = () => openEventPage(props.saved ?? "")