Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions messages/en.context.json
Original file line number Diff line number Diff line change
Expand Up @@ -2050,6 +2050,10 @@
"onboarding-source-manual": "Used in Capgo web console areas: pages/admin/dashboard. Role: short UI label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"onboarding-source-mcp": "Used in Capgo web console areas: pages/admin/dashboard. Role: short UI label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"onboarding-trend": "Used in Capgo web console areas: pages/admin/dashboard. Role: UI label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"onboarding-welcome-cta": "Used in Capgo web console areas: components/dashboard. Role: UI label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"onboarding-welcome-description": "Used in Capgo web console areas: components/dashboard. Role: helper or description text. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"onboarding-welcome-eyebrow": "Used in Capgo web console areas: components/dashboard. Role: UI label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"onboarding-welcome-title": "Used in Capgo web console areas: components/dashboard. Role: section or dialog title. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"onboarding-wizard-abandoned": "Used in Capgo web console areas: pages/admin/dashboard. Role: short UI label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"onboarding-wizard-completed": "Used in Capgo web console areas: pages/admin/dashboard. Role: short UI label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
"onboarding-wizard-dropoff": "Used in Capgo web console areas: pages/admin/dashboard. Role: UI label. Translate for UI; keep Capgo product names, code, and placeholders unchanged.",
Expand Down
4 changes: 4 additions & 0 deletions messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1870,6 +1870,10 @@
"onboarding-resume-restart": "Restart",
"onboarding-resume-title": "Continue where you left off?",
"onboarding-trend": "Onboarding Trend",
"onboarding-welcome-cta": "Set up my first update",
"onboarding-welcome-description": "You’re a few steps away from the magic of over-the-air updates — and so much more.",
"onboarding-welcome-eyebrow": "Good to have you here",
"onboarding-welcome-title": "Welcome to Capgo",
"onboarding-wizard-abandoned": "Abandoned",
"onboarding-wizard-completed": "Completed",
"onboarding-wizard-dropoff": "Onboarding wizard drop-off",
Expand Down
4 changes: 3 additions & 1 deletion src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ declare module 'vue' {
AppOnboardingCliSteps: typeof import('./components/dashboard/AppOnboardingCliSteps.vue')['default']
AppOnboardingFlow: typeof import('./components/dashboard/AppOnboardingFlow.vue')['default']
AppOnboardingIconInput: typeof import('./components/dashboard/AppOnboardingIconInput.vue')['default']
AppOnboardingNextStep: typeof import('./components/dashboard/AppOnboardingNextStep.vue')['default']
AppOnboardingWelcome: typeof import('./components/dashboard/AppOnboardingWelcome.vue')['default']
AppPageFrame: typeof import('./components/dashboard/AppPageFrame.vue')['default']
AppPageNotFound: typeof import('./components/dashboard/AppPageNotFound.vue')['default']
AppSetting: typeof import('./components/dashboard/AppSetting.vue')['default']
Expand Down Expand Up @@ -93,6 +93,7 @@ declare module 'vue' {
Navbar: typeof import('./components/Navbar.vue')['default']
OnboardingExploreBanner: typeof import('./components/dashboard/OnboardingExploreBanner.vue')['default']
OnboardingSupportUsernames: typeof import('./components/dashboard/OnboardingSupportUsernames.vue')['default']
OrganizationOnboardingInvite: typeof import('./components/dashboard/OrganizationOnboardingInvite.vue')['default']
OrgEmailNotificationsPanel: typeof import('./components/dashboard/OrgEmailNotificationsPanel.vue')['default']
OrgNotificationStatsPanel: typeof import('./components/dashboard/OrgNotificationStatsPanel.vue')['default']
PageLoader: typeof import('./components/PageLoader.vue')['default']
Expand Down Expand Up @@ -121,6 +122,7 @@ declare module 'vue' {
TableLog: typeof import('./components/TableLog.vue')['default']
Tabs: typeof import('./components/Tabs.vue')['default']
TabSidebar: typeof import('./components/TabSidebar.vue')['default']
TechnicalTeammateInviteCard: typeof import('./components/dashboard/TechnicalTeammateInviteCard.vue')['default']
Toast: typeof import('./components/Toast.vue')['default']
Toggle: typeof import('./components/Toggle.vue')['default']
TrialBanner: typeof import('./components/dashboard/TrialBanner.vue')['default']
Expand Down
33 changes: 30 additions & 3 deletions src/components/dashboard/AppOnboardingFlow.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script setup lang="ts">
import type { Database, Json } from '~/types/supabase.types'
import type {
OnboardingAnalyticsStep,
OnboardingCopyEvent,
OnboardingDetailsEvent,
OnboardingDetailsEventProperties,
Expand All @@ -11,6 +12,7 @@ import type {
} from '~/utils/onboardingProgressAnalytics'
import type { OnboardingPersistOptions, OnboardingPersistResult } from '~/utils/onboardingProgressPersistence'
import type { UserOnboardingStatus } from '~/utils/userOnboardingProgress'
import { useMediaQuery } from '@vueuse/core'
import mime from 'mime'
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
Expand Down Expand Up @@ -79,6 +81,7 @@ import {
} from '~/utils/userOnboardingProgress'
import AppOnboardingCliSteps from './AppOnboardingCliSteps.vue'
import AppOnboardingIconInput from './AppOnboardingIconInput.vue'
import AppOnboardingWelcome from './AppOnboardingWelcome.vue'
import OrganizationOnboardingInvite from './OrganizationOnboardingInvite.vue'
import TechnicalTeammateInviteCard from './TechnicalTeammateInviteCard.vue'

Expand Down Expand Up @@ -124,6 +127,9 @@ interface OrganizationWebsitePreview {

const isLoading = ref(true)
const isHydratingOnboarding = ref(true)
const hasWelcomeCanvas = useMediaQuery('(min-width: 640px) and (min-height: 640px)')
const welcomePending = ref(false)
const showPreOrgWelcome = computed(() => props.preOrg && hasWelcomeCanvas.value && welcomePending.value)
Comment thread
WcaleNieWolny marked this conversation as resolved.
Resolved
const isSubmitting = ref(false)
const isImportingStore = ref(false)
const isResumeIconLoading = ref(false)
Expand Down Expand Up @@ -365,7 +371,10 @@ function trackOrganizationEvent(
const detailsFieldTracker = createOnboardingDetailsFieldDebouncer(trackDetailsEvent)

function initializeProgressTracking(resumed: boolean) {
const trackedSteps = appOnboardingSteps.value.map(step => step.id)
const initialStep: OnboardingAnalyticsStep = showPreOrgWelcome.value ? 'welcome' : flowStep.value
const trackedSteps: OnboardingAnalyticsStep[] = appOnboardingSteps.value.map(step => step.id)
if (initialStep === 'welcome')
trackedSteps.unshift('welcome')
if (!props.preOrg && resumed && flowStep.value === 'setup')
trackedSteps.push('setup')

Expand All @@ -377,7 +386,7 @@ function initializeProgressTracking(resumed: boolean) {
onboardingAttemptId: onboardingTelemetry.attemptId,
onboardingRunId: onboardingTelemetry.runId,
})
progressTracker.viewStep(flowStep.value)
progressTracker.viewStep(initialStep)
if (pendingDashboardExplored)
trackDashboardExplored()
}
Expand Down Expand Up @@ -544,6 +553,17 @@ function resetOnboardingForm() {
resetStoreImportState()
}

function showWelcomeOnDesktop() {
welcomePending.value = Boolean(props.preOrg)
}

function continueFromWelcome() {
const nextStep = flowStep.value
progressTracker?.completeStep('welcome', { nextStep })
progressTracker?.viewStep(nextStep, 'welcome')
welcomePending.value = false
}

function applyOnboardingProgress(progress: ReturnType<typeof parseUserOnboardingProgress>) {
if (!progress)
return
Expand Down Expand Up @@ -594,6 +614,7 @@ async function maybeResumeSavedOnboarding() {
else {
applyDefaultPreOrgDetails()
}
showWelcomeOnDesktop()
return false
}

Expand Down Expand Up @@ -624,6 +645,7 @@ async function maybeResumeSavedOnboarding() {
resetOnboardingForm()
existingApp.value = true
existingAppSetup.value = 'manual'
showWelcomeOnDesktop()
return false
}

Expand Down Expand Up @@ -1723,7 +1745,12 @@ defineExpose({
</script>

<template>
<section class="min-h-full overflow-y-auto bg-slate-50 px-4 py-6 sm:px-6 lg:px-8 dark:bg-slate-950">
<AppOnboardingWelcome
v-if="showPreOrgWelcome && !isLoading"
@continue="continueFromWelcome"
/>

<section v-else class="h-full min-h-0 overflow-y-auto bg-slate-50 px-4 py-6 sm:px-6 lg:px-8 dark:bg-slate-950">
<div class="mx-auto w-full max-w-3xl">
<div v-if="isLoading" class="flex min-h-[50vh] items-center justify-center">
<Spinner size="w-32 h-32" />
Expand Down
Loading
Loading