Skip to content

Commit b522c10

Browse files
ItsnotakaMarfuen
andauthored
feat(onboarding): add skip functionality to onboarding steps (#1925)
Co-authored-by: Mariano Fuentes <[email protected]>
1 parent d58341b commit b522c10

File tree

5 files changed

+63
-4
lines changed

5 files changed

+63
-4
lines changed

apps/app/src/app/(app)/onboarding/actions/complete-onboarding.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const onboardingCompletionSchema = z.object({
2929
}),
3030
devices: z.string().min(1),
3131
authentication: z.string().min(1),
32-
software: z.string().min(1),
32+
software: z.string().optional(),
3333
workLocation: z.string().min(1),
3434
infrastructure: z.string().min(1),
3535
dataTypes: z.string().min(1),
@@ -81,7 +81,13 @@ export const completeOnboarding = authActionClient
8181
// Save the remaining steps to context
8282
const postPaymentSteps = steps.slice(3); // Steps 4-12
8383
const contextData = postPaymentSteps
84-
.filter((step) => step.key in parsedInput)
84+
.filter((step) => {
85+
const value = parsedInput[step.key as keyof typeof parsedInput];
86+
// Filter out steps that aren't in parsedInput or have empty values (skipped steps)
87+
if (!(step.key in parsedInput)) return false;
88+
if (value === undefined || value === null || value === '') return false;
89+
return true;
90+
})
8591
.map((step) => ({
8692
question: step.question,
8793
answer:

apps/app/src/app/(app)/onboarding/components/PostPaymentOnboarding.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ export function PostPaymentOnboarding({
3434
isLoading,
3535
onSubmit,
3636
handleBack,
37+
handleSkip,
3738
isLastStep,
39+
isSkippable,
3840
currentStepNumber,
3941
totalSteps,
4042
completeNow,
@@ -193,6 +195,28 @@ export function PostPaymentOnboarding({
193195
</motion.div>
194196
)}
195197
</AnimatePresence>
198+
<AnimatePresence>
199+
{isSkippable && (
200+
<motion.div
201+
key="skip"
202+
initial={{ opacity: 0, x: 20 }}
203+
animate={{ opacity: 1, x: 0 }}
204+
exit={{ opacity: 0, x: 20 }}
205+
transition={{ duration: 0.25 }}
206+
>
207+
<Button
208+
type="button"
209+
variant="ghost"
210+
className="flex items-center gap-2 text-muted-foreground"
211+
onClick={handleSkip}
212+
disabled={isOnboarding || isFinalizing || isLoading}
213+
data-testid="onboarding-skip-button"
214+
>
215+
Skip for now
216+
</Button>
217+
</motion.div>
218+
)}
219+
</AnimatePresence>
196220
{isLocal && (
197221
<motion.div
198222
key="complete-now"

apps/app/src/app/(app)/onboarding/hooks/usePostPaymentOnboarding.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,32 @@ export function usePostPaymentOnboarding({
249249
}
250250
};
251251

252+
const handleSkip = () => {
253+
// Track skip event
254+
trackOnboardingEvent(`${step.key}_skipped`, stepIndex + 1, {
255+
phase: 'post_payment',
256+
});
257+
258+
// Clear form errors
259+
form.clearErrors();
260+
261+
// Move to next step without saving current value
262+
if (stepIndex < postPaymentSteps.length - 1) {
263+
const newStepIndex = stepIndex + 1;
264+
setStepIndex(newStepIndex);
265+
setSavedStepIndex(newStepIndex);
266+
} else {
267+
// If this is the last step, complete onboarding without this field
268+
const allAnswers: Partial<CompanyDetails> = {
269+
...savedAnswers,
270+
organizationName,
271+
};
272+
handleCompleteOnboarding(allAnswers);
273+
}
274+
};
275+
252276
const isLastStep = stepIndex === postPaymentSteps.length - 1;
277+
const isSkippable = step?.skippable ?? false;
253278

254279
return {
255280
stepIndex,
@@ -262,7 +287,9 @@ export function usePostPaymentOnboarding({
262287
isLoading,
263288
onSubmit,
264289
handleBack,
290+
handleSkip,
265291
isLastStep,
292+
isSkippable,
266293
currentStepNumber: stepIndex + 1, // Display as steps 1-9
267294
totalSteps: postPaymentSteps.length, // Total 9 steps for post-payment
268295
completeNow,

apps/app/src/app/(app)/setup/lib/constants.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export const companyDetailsSchema = z.object({
2626
jobTitle: z.string().min(1, 'Job title is required'),
2727
email: z.string().email('Please enter a valid email'),
2828
}),
29-
software: z.string().min(1, 'Please select software you use'),
29+
software: z.string().optional(),
3030
infrastructure: z.string().min(1, 'Please select your infrastructure'),
3131
dataTypes: z.string().min(1, 'Please select types of data you handle'),
3232
devices: z.string().min(1, 'Please select device types'),
@@ -111,6 +111,7 @@ export const steps: Step[] = [
111111
key: 'software',
112112
question: 'What software do you use?',
113113
placeholder: 'e.g., Rippling',
114+
skippable: true,
114115
options: [
115116
'Rippling',
116117
'Gusto',

apps/app/src/app/(app)/setup/lib/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export type CompanyDetails = {
2323
workLocation: string;
2424
infrastructure: string;
2525
dataTypes: string;
26-
software: string;
26+
software?: string;
2727
geo: string;
2828
shipping: {
2929
fullName: string;
@@ -45,4 +45,5 @@ export type Step = {
4545
placeholder: string;
4646
options?: string[];
4747
description?: string;
48+
skippable?: boolean;
4849
};

0 commit comments

Comments
 (0)