diff --git a/src/components/BundlePreviewFrame.vue b/src/components/BundlePreviewFrame.vue index 66c1d1ebe0..e35e5cb152 100644 --- a/src/components/BundlePreviewFrame.vue +++ b/src/components/BundlePreviewFrame.vue @@ -4,11 +4,12 @@ import { computed, onMounted, onUnmounted, ref, watch } from 'vue' import { useI18n } from 'vue-i18n' import IconExternalLink from '~icons/lucide/external-link' import IconSmartphone from '~icons/lucide/smartphone' -import { buildPreviewSubdomain } from '../../shared/preview-subdomain.ts' +import { buildChannelPreviewSubdomain, buildPreviewSubdomain } from '../../shared/preview-subdomain.ts' const props = defineProps<{ appId: string - versionId: number + versionId?: number + channelId?: number }>() const { t } = useI18n() @@ -53,7 +54,17 @@ const currentDevice = computed(() => devices[selectedDevice.value]) // Build the preview URL using a reversible preview subdomain format. const previewUrl = computed(() => { try { - const subdomain = buildPreviewSubdomain(props.appId, props.versionId) + const hasVersionId = typeof props.versionId === 'number' + const hasChannelId = typeof props.channelId === 'number' + + if (hasVersionId === hasChannelId) { + console.error('BundlePreviewFrame requires exactly one preview target') + return null + } + + const subdomain = hasChannelId + ? buildChannelPreviewSubdomain(props.appId, props.channelId as number) + : buildPreviewSubdomain(props.appId, props.versionId as number) // Extract base domain from current host, default to capgo.app for localhost // Preserve environment segments (e.g., 'dev' in console.dev.capgo.app) const hostname = window.location.hostname diff --git a/src/pages/app/[app].channel.[channel].preview.vue b/src/pages/app/[app].channel.[channel].preview.vue new file mode 100644 index 0000000000..4d807358f0 --- /dev/null +++ b/src/pages/app/[app].channel.[channel].preview.vue @@ -0,0 +1,219 @@ + + + + + +meta: + layout: app + diff --git a/src/pages/app/[app].channel.[channel].vue b/src/pages/app/[app].channel.[channel].vue index 62c93ef1e8..b3d4e0b4df 100644 --- a/src/pages/app/[app].channel.[channel].vue +++ b/src/pages/app/[app].channel.[channel].vue @@ -10,6 +10,7 @@ import { toast } from 'vue-sonner' import IconCopy from '~icons/heroicons/clipboard-document-check' import IconCode from '~icons/heroicons/code-bracket' import Settings from '~icons/heroicons/cog-8-tooth' +import IconEye from '~icons/heroicons/eye' import IconInformation from '~icons/heroicons/information-circle' import IconSearch from '~icons/ic/round-search?raw' import IconAlertCircle from '~icons/lucide/alert-circle' @@ -83,6 +84,12 @@ function openBundle() { router.push(`/app/${route.params.app}/bundle/${channel.value.version.id}`) } +function openPreview() { + if (!channel.value) + return + router.push(`/app/${route.params.app}/channel/${id.value}/preview`) +} + async function getChannel(force = false) { if (!id.value) return @@ -669,6 +676,15 @@ async function copyCurlCommand() {
{{ channel.version.name }} +