@@ -6,12 +6,16 @@ import { usePostHog } from "posthog-js/react";
66import * as React from "react" ;
77import { useState } from "react" ;
88
9- import { Card , CardContent } from "@/lib/components/card" ;
9+ import {
10+ NavigationMenu ,
11+ NavigationMenuItem ,
12+ NavigationMenuList ,
13+ } from "@/lib/components/navigation-menu" ;
1014import { Stepper } from "@/lib/components/stepper" ;
1115import { useApi } from "@/lib/fetch-client" ;
16+ import Logo from "@/lib/icons/Logo" ;
1217import { useStripe } from "@/lib/stripe" ;
1318
14- import { ApiKeyStep } from "./api-key-step" ;
1519import { CreditsStep } from "./credits-step" ;
1620import { PlanChoiceStep } from "./plan-choice-step" ;
1721import { ProviderKeyStep } from "./provider-key-step" ;
@@ -27,16 +31,12 @@ const getSteps = (flowType: FlowType) => [
2731 } ,
2832 {
2933 id : "referral" ,
30- title : "How did you hear about us?" ,
34+ title : "How did you find us?" ,
3135 optional : true ,
3236 } ,
33- {
34- id : "api-key" ,
35- title : "API Key" ,
36- } ,
3737 {
3838 id : "plan-choice" ,
39- title : "Choose Plan " ,
39+ title : "Choose your approach " ,
4040 } ,
4141 {
4242 id : flowType === "credits" ? "credits" : "provider-key" ,
@@ -48,10 +48,12 @@ const getSteps = (flowType: FlowType) => [
4848export function OnboardingWizard ( ) {
4949 const [ activeStep , setActiveStep ] = useState ( 0 ) ;
5050 const [ flowType , setFlowType ] = useState < FlowType > ( null ) ;
51- const [ hasSelectedPlan , setHasSelectedPlan ] = useState ( false ) ;
51+ const [ hasSelectedPlan , setHasSelectedPlan ] = useState ( true ) ; // Free plan is selected by default
52+ const [ selectedPlanName , setSelectedPlanName ] = useState < string > ( "Free Plan" ) ; // Free plan is default
5253 const [ isPaymentSuccessful , setIsPaymentSuccessful ] = useState ( false ) ;
5354 const [ referralSource , setReferralSource ] = useState < string > ( "" ) ;
5455 const [ referralDetails , setReferralDetails ] = useState < string > ( "" ) ;
56+
5557 const router = useRouter ( ) ;
5658 const posthog = usePostHog ( ) ;
5759 const { stripe, isLoading : stripeLoading } = useStripe ( ) ;
@@ -65,10 +67,16 @@ export function OnboardingWizard() {
6567 const STEPS = getSteps ( flowType ) ;
6668
6769 const handleStepChange = async ( step : number ) => {
68- // Special handling for plan choice step (now at index 3)
69- if ( activeStep === 3 ) {
70- if ( ! hasSelectedPlan ) {
71- // Skip to dashboard if no plan selected
70+ // Handle backward navigation
71+ if ( step < activeStep ) {
72+ setActiveStep ( step ) ;
73+ return ;
74+ }
75+
76+ // Special handling for plan choice step (now at index 2)
77+ if ( activeStep === 2 ) {
78+ if ( ! hasSelectedPlan || flowType === null ) {
79+ // Skip to dashboard if no plan selected or if continuing with free plan
7280 posthog . capture ( "onboarding_skipped" , {
7381 skippedAt : "plan_choice" ,
7482 referralSource : referralSource || "not_provided" ,
@@ -103,26 +111,28 @@ export function OnboardingWizard() {
103111 const handleSelectCredits = ( ) => {
104112 setFlowType ( "credits" ) ;
105113 setHasSelectedPlan ( true ) ;
106- setActiveStep ( 4 ) ;
114+ setSelectedPlanName ( "Buy Credits" ) ;
115+ setActiveStep ( 3 ) ;
107116 } ;
108117
109118 const handleSelectBYOK = ( ) => {
110119 setFlowType ( "byok" ) ;
111120 setHasSelectedPlan ( true ) ;
112- setActiveStep ( 4 ) ;
121+ setSelectedPlanName ( "Bring Your Own Keys" ) ;
122+ setActiveStep ( 3 ) ;
113123 } ;
114124
115125 const handleReferralComplete = ( source : string , details ?: string ) => {
116126 setReferralSource ( source ) ;
117127 if ( details ) {
118128 setReferralDetails ( details ) ;
119129 }
120- setActiveStep ( 2 ) ; // Move to API Key step
130+ setActiveStep ( 2 ) ; // Move to Plan Choice step
121131 } ;
122132
123133 // Special handling for PlanChoiceStep to pass callbacks
124134 const renderCurrentStep = ( ) => {
125- if ( activeStep === 3 ) {
135+ if ( activeStep === 2 ) {
126136 return (
127137 < PlanChoiceStep
128138 onSelectCredits = { handleSelectCredits }
@@ -133,7 +143,7 @@ export function OnboardingWizard() {
133143 }
134144
135145 // For credits step, wrap with Stripe Elements
136- if ( activeStep === 4 && flowType === "credits" ) {
146+ if ( activeStep === 3 && flowType === "credits" ) {
137147 return stripeLoading ? (
138148 < div className = "p-6 text-center" > Loading payment form...</ div >
139149 ) : (
@@ -144,7 +154,7 @@ export function OnboardingWizard() {
144154 }
145155
146156 // For BYOK step
147- if ( activeStep === 4 && flowType === "byok" ) {
157+ if ( activeStep === 3 && flowType === "byok" ) {
148158 return < ProviderKeyStep /> ;
149159 }
150160
@@ -157,24 +167,29 @@ export function OnboardingWizard() {
157167 return < ReferralStep onComplete = { handleReferralComplete } /> ;
158168 }
159169
160- if ( activeStep === 2 ) {
161- return < ApiKeyStep /> ;
162- }
163-
164170 return null ;
165171 } ;
166172
167173 // Customize stepper steps to show appropriate button text
168174 const getStepperSteps = ( ) => {
169175 return STEPS . map ( ( step , index ) => ( {
170176 ...step ,
171- // Make plan choice step show Skip when no selection
172- ...( index === 3 &&
173- ! hasSelectedPlan && {
174- customNextText : "Skip" ,
175- } ) ,
177+ // Welcome step shows dynamic text based on user state
178+ ...( index === 0 && {
179+ customNextText : "Next: How did you hear about us?" ,
180+ } ) ,
181+ // Referral step shows dynamic text based on user state
182+ ...( index === 1 && {
183+ customNextText : "Next: Choose your approach" ,
184+ } ) ,
185+ // Make plan choice step show dynamic text based on selected plan
186+ ...( index === 2 && {
187+ customNextText : hasSelectedPlan
188+ ? `Continue with ${ selectedPlanName } `
189+ : "Skip" ,
190+ } ) ,
176191 // Remove optional status from credits step when payment is successful
177- ...( index === 4 &&
192+ ...( index === 3 &&
178193 flowType === "credits" &&
179194 isPaymentSuccessful && {
180195 optional : false ,
@@ -183,22 +198,31 @@ export function OnboardingWizard() {
183198 } ;
184199
185200 return (
186- < div className = "container mx-auto max-w-3xl py-10" >
187- < Card >
188- < CardContent className = "p-6 sm:p-8" >
189- < Stepper
190- steps = { getStepperSteps ( ) }
191- activeStep = { activeStep }
192- onStepChange = { handleStepChange }
193- className = "mb-6"
194- nextButtonDisabled = {
195- activeStep === 4 && flowType === "credits" && ! isPaymentSuccessful
196- }
197- >
198- { renderCurrentStep ( ) }
199- </ Stepper >
200- </ CardContent >
201- </ Card >
201+ < div className = "container mx-auto px-4 py-10" >
202+ < NavigationMenu className = "mx-auto" >
203+ < NavigationMenuList >
204+ < NavigationMenuItem asChild >
205+ < div className = "flex items-center space-x-2" >
206+ < Logo className = "h-8 w-8 rounded-full text-black dark:text-white" />
207+ < span className = "text-xl font-bold tracking-tight text-zinc-900 dark:text-white" >
208+ LLM Gateway
209+ </ span >
210+ </ div >
211+ </ NavigationMenuItem >
212+ </ NavigationMenuList >
213+ </ NavigationMenu >
214+
215+ < Stepper
216+ steps = { getStepperSteps ( ) }
217+ activeStep = { activeStep }
218+ onStepChange = { handleStepChange }
219+ className = "mb-6"
220+ nextButtonDisabled = {
221+ activeStep === 3 && flowType === "credits" && ! isPaymentSuccessful
222+ }
223+ >
224+ { renderCurrentStep ( ) }
225+ </ Stepper >
202226 </ div >
203227 ) ;
204228}
0 commit comments