Skip to content

Commit 5a0d263

Browse files
authored
Feature/new onboarding step1 (#1733)
This PR includes: - Creation of a separate onboarding from the existing one (which is currently disabled) - Creation of the step 1 of the new onboarding, guarded under a feature flag - The new onboarding now starts when cloning an agent, and uses it as part of the tutorial - EXTRA - Fix broken "email us" link in the login page
1 parent 7633e32 commit 5a0d263

File tree

45 files changed

+811
-434
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+811
-434
lines changed

apps/web/src/app/(actions)/actions/[actionType]/_lib/cloneAgent.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@ export const CloneAgentActionSpecification = {
1111
}
1212

1313
async function execute({
14-
parameters: { projectId, commitUuid },
14+
parameters: { projectId, commitUuid, hasCompletedOnboarding },
1515
router,
1616
}: ActionExecuteArgs<ActionType.CloneAgent>) {
17+
if (!hasCompletedOnboarding) {
18+
return router.push(ROUTES.onboarding.root)
19+
}
20+
1721
return router.push(
1822
ROUTES.projects
1923
.detail({ id: projectId })
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Text } from '@latitude-data/web-ui/atoms/Text'
33
import { MessageList } from '$/components/ChatWrapper'
44
import { cn } from '@latitude-data/web-ui/utils'
55
import { Button } from '@latitude-data/web-ui/atoms/Button'
6-
import { OnboardingStep } from '$/app/(onboarding)/onboarding/_components/OnboardingClient'
6+
import { OnboardingStep } from '$/app/(onboarding)/onboarding-devs/_components/OnboardingClient'
77
import { Message } from '@latitude-data/constants/legacyCompiler'
88
import { ParameterTable } from './ParameterTable'
99
import { ExperimentVariants } from './ExperimentVariants'
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
'use client'
2+
3+
import { Text } from '@latitude-data/web-ui/atoms/Text'
4+
import {
5+
DocumentVersion,
6+
Project,
7+
Commit,
8+
Dataset,
9+
} from '@latitude-data/core/browser'
10+
import { useCallback, useState } from 'react'
11+
import { ROUTES } from '$/services/routes'
12+
import useLatitudeAction from '$/hooks/useLatitudeAction'
13+
import { useNavigate } from '$/hooks/useNavigate'
14+
import { completeOnboardingAction } from '$/actions/workspaceOnboarding/complete'
15+
import { useToast } from '@latitude-data/web-ui/atoms/Toast'
16+
import { useRunOnboardingPrompt } from '$/app/(onboarding)/onboarding-devs/_components/OnboardingClient/useRunPrompt'
17+
import { OnboardingPromptStep } from '$/app/(onboarding)/onboarding-devs/_components/OnboardingClient/PromptStep'
18+
import { ExperimentStep } from '$/app/(onboarding)/onboarding-devs/_components/OnboardingClient/ExperimentStep'
19+
20+
type OnboardingStep1ContentProps = {
21+
workspaceName: string
22+
document: DocumentVersion
23+
project: Project
24+
commit: Commit
25+
dataset: Dataset
26+
}
27+
28+
export enum OnboardingStep {
29+
ShowPrompt = 1,
30+
ShowResultsAndExperiment = 2,
31+
}
32+
33+
export function OnboardingClient({
34+
workspaceName,
35+
document,
36+
project,
37+
commit,
38+
dataset,
39+
}: OnboardingStep1ContentProps) {
40+
const [currentStep, setCurrentStep] = useState<OnboardingStep>(
41+
OnboardingStep.ShowPrompt,
42+
)
43+
const navigate = useNavigate()
44+
const { toast } = useToast()
45+
const { start, messages, activeStream } = useRunOnboardingPrompt({
46+
project,
47+
commit,
48+
document,
49+
setCurrentStep,
50+
})
51+
52+
const { execute: completeOnboarding } = useLatitudeAction(
53+
completeOnboardingAction,
54+
)
55+
const onCompleteOnboarding = useCallback(
56+
async ({ experimentUuids }: { experimentUuids: string[] }) => {
57+
await completeOnboarding()
58+
toast({
59+
title: 'Experiment started!',
60+
description:
61+
"Welcome onboard! Let's check out the results of your experiment",
62+
})
63+
setTimeout(async () => {
64+
navigate.push(
65+
ROUTES.projects
66+
.detail({ id: project.id })
67+
.commits.detail({ uuid: commit.uuid })
68+
.documents.detail({ uuid: document.documentUuid })
69+
.experiments.withSelected(experimentUuids),
70+
)
71+
}, 1000)
72+
},
73+
[
74+
completeOnboarding,
75+
navigate,
76+
project.id,
77+
commit.uuid,
78+
document.documentUuid,
79+
toast,
80+
],
81+
)
82+
83+
return (
84+
<div className='space-y-16'>
85+
<div className='space-y-2'>
86+
<Text.H2B centered display='block'>
87+
Welcome to Latitude!
88+
</Text.H2B>
89+
<Text.H5 centered display='block' color='foregroundMuted'>
90+
Hello {workspaceName || 'there'}! Let's cover some Latitude basics.
91+
</Text.H5>
92+
</div>
93+
94+
<div className='space-y-6'>
95+
<div className='relative min-h-[450px]'>
96+
<OnboardingPromptStep
97+
document={document}
98+
start={start}
99+
activeStream={activeStream}
100+
currentStep={currentStep}
101+
messages={messages}
102+
/>
103+
104+
<ExperimentStep
105+
document={document}
106+
project={project}
107+
commit={commit}
108+
dataset={dataset}
109+
currentStep={currentStep}
110+
messages={messages}
111+
onCompleteOnboarding={onCompleteOnboarding}
112+
/>
113+
</div>
114+
</div>
115+
</div>
116+
)
117+
}

apps/web/src/app/(onboarding)/onboarding/_components/OnboardingClient/useRunPrompt.ts renamed to apps/web/src/app/(onboarding)/onboarding-devs/_components/OnboardingClient/useRunPrompt.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ROUTES } from '$/services/routes'
55
import { useStreamHandler } from '$/hooks/playgrounds/useStreamHandler'
66
import { usePlaygroundChat } from '$/hooks/playgroundChat/usePlaygroundChat'
77
import { ReactStateDispatch } from '@latitude-data/web-ui/commonTypes'
8-
import { OnboardingStep } from '$/app/(onboarding)/onboarding/_components/OnboardingClient'
8+
import { OnboardingStep } from '$/app/(onboarding)/onboarding-devs/_components/OnboardingClient'
99

1010
const SECONDS_BEFORE_HIDING_PROMPT_IN_SECONDS = 2000
1111
export const DOCUMENT_PARAMETERS: OnboardingParameters = {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
'use server'
2+
3+
import buildMetatags from '$/app/_lib/buildMetatags'
4+
import { CSPostHogProvider, IdentifyUser } from '$/app/providers'
5+
import { getCurrentUserOrRedirect } from '$/services/auth/getCurrentUser'
6+
import { Icon } from '@latitude-data/web-ui/atoms/Icons'
7+
import { ReactNode } from 'react'
8+
9+
export async function generateMetadata() {
10+
return buildMetatags({
11+
title: 'Onboarding',
12+
})
13+
}
14+
15+
export default async function OnboardingLayout({
16+
children,
17+
}: {
18+
children: ReactNode
19+
}) {
20+
const { workspace, user } = await getCurrentUserOrRedirect()
21+
22+
return (
23+
<CSPostHogProvider>
24+
<IdentifyUser user={user} workspace={workspace}>
25+
<div className='flex min-h-screen flex-col max-w-[768px] pt-12 pb-4 m-auto'>
26+
<div className='flex items-center justify-center'>
27+
<Icon name='logo' size='large' />
28+
</div>
29+
{children}
30+
</div>
31+
</IdentifyUser>
32+
</CSPostHogProvider>
33+
)
34+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { redirect } from 'next/navigation'
2+
import { isOnboardingCompleted } from '$/data-access/workspaceOnboarding'
3+
import { getCurrentUserOrRedirect } from '$/services/auth/getCurrentUser'
4+
import { OnboardingClient } from './_components/OnboardingClient'
5+
import { findOnboardingDocument } from '@latitude-data/core/services/documents/findOnboardingDocument'
6+
import { findOnboardingDataset } from '@latitude-data/core/services/datasets/findOnboardingDataset'
7+
import { ROUTES } from '$/services/routes'
8+
import { PageNotFoundError } from 'next/dist/shared/lib/utils'
9+
10+
export default async function OnboardingRedirect() {
11+
const isCompleted = await isOnboardingCompleted()
12+
if (isCompleted) {
13+
redirect(ROUTES.dashboard.root)
14+
}
15+
16+
const { workspace } = await getCurrentUserOrRedirect()
17+
if (!workspace?.id) {
18+
throw new PageNotFoundError('Workspace ID is required')
19+
}
20+
21+
const documentResult = await findOnboardingDocument(workspace.id)
22+
if (documentResult.error) {
23+
throw new PageNotFoundError('No document found')
24+
}
25+
const { documents, project, commit } = documentResult.value
26+
27+
const datasetResult = await findOnboardingDataset(workspace.id)
28+
if (datasetResult.error) {
29+
throw datasetResult.error
30+
}
31+
const dataset = datasetResult.value
32+
33+
return (
34+
<OnboardingClient
35+
workspaceName={workspace?.name}
36+
document={documents[0]} // TODO(onboarding): change this later once we have a new onboarding
37+
project={project}
38+
commit={commit}
39+
dataset={dataset}
40+
/>
41+
)
42+
}

0 commit comments

Comments
 (0)