@rocapine/react-native-onboarding 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +216 -0
- package/dist/OnboardingStudioClient.d.ts +13 -0
- package/dist/OnboardingStudioClient.d.ts.map +1 -0
- package/dist/OnboardingStudioClient.js +71 -0
- package/dist/OnboardingStudioClient.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/infra/hooks/index.d.ts +3 -0
- package/dist/infra/hooks/index.d.ts.map +1 -0
- package/dist/infra/hooks/index.js +8 -0
- package/dist/infra/hooks/index.js.map +1 -0
- package/dist/infra/hooks/useOnboarding.d.ts +6 -0
- package/dist/infra/hooks/useOnboarding.d.ts.map +1 -0
- package/dist/infra/hooks/useOnboarding.js +17 -0
- package/dist/infra/hooks/useOnboarding.js.map +1 -0
- package/dist/infra/hooks/useOnboarding.old.d.ts +7 -0
- package/dist/infra/hooks/useOnboarding.old.d.ts.map +1 -0
- package/dist/infra/hooks/useOnboarding.old.js +20 -0
- package/dist/infra/hooks/useOnboarding.old.js.map +1 -0
- package/dist/infra/hooks/useOnboardingStep.d.ts +12 -0
- package/dist/infra/hooks/useOnboardingStep.d.ts.map +1 -0
- package/dist/infra/hooks/useOnboardingStep.js +37 -0
- package/dist/infra/hooks/useOnboardingStep.js.map +1 -0
- package/dist/infra/hooks/useOnboardingStep.old.d.ts +12 -0
- package/dist/infra/hooks/useOnboardingStep.old.d.ts.map +1 -0
- package/dist/infra/hooks/useOnboardingStep.old.js +37 -0
- package/dist/infra/hooks/useOnboardingStep.old.js.map +1 -0
- package/dist/infra/index.d.ts +3 -0
- package/dist/infra/index.d.ts.map +1 -0
- package/dist/infra/index.js +19 -0
- package/dist/infra/index.js.map +1 -0
- package/dist/infra/provider/OnboardingProvider.d.ts +29 -0
- package/dist/infra/provider/OnboardingProvider.d.ts.map +1 -0
- package/dist/infra/provider/OnboardingProvider.js +48 -0
- package/dist/infra/provider/OnboardingProvider.js.map +1 -0
- package/dist/infra/provider/OnboardingProvider.old.d.ts +61 -0
- package/dist/infra/provider/OnboardingProvider.old.d.ts.map +1 -0
- package/dist/infra/provider/OnboardingProvider.old.js +55 -0
- package/dist/infra/provider/OnboardingProvider.old.js.map +1 -0
- package/dist/infra/provider/index.d.ts +2 -0
- package/dist/infra/provider/index.d.ts.map +1 -0
- package/dist/infra/provider/index.js +7 -0
- package/dist/infra/provider/index.js.map +1 -0
- package/dist/infra/queries/getOnboarding.query.d.ts +8 -0
- package/dist/infra/queries/getOnboarding.query.d.ts.map +1 -0
- package/dist/infra/queries/getOnboarding.query.js +52 -0
- package/dist/infra/queries/getOnboarding.query.js.map +1 -0
- package/dist/steps/Carousel/types.d.ts +32 -0
- package/dist/steps/Carousel/types.d.ts.map +1 -0
- package/dist/steps/Carousel/types.js +24 -0
- package/dist/steps/Carousel/types.js.map +1 -0
- package/dist/steps/Commitment/types.d.ts +41 -0
- package/dist/steps/Commitment/types.d.ts.map +1 -0
- package/dist/steps/Commitment/types.js +27 -0
- package/dist/steps/Commitment/types.js.map +1 -0
- package/dist/steps/Loader/types.d.ts +57 -0
- package/dist/steps/Loader/types.d.ts.map +1 -0
- package/dist/steps/Loader/types.js +30 -0
- package/dist/steps/Loader/types.js.map +1 -0
- package/dist/steps/MediaContent/types.d.ts +44 -0
- package/dist/steps/MediaContent/types.d.ts.map +1 -0
- package/dist/steps/MediaContent/types.js +22 -0
- package/dist/steps/MediaContent/types.js.map +1 -0
- package/dist/steps/Picker/types.d.ts +49 -0
- package/dist/steps/Picker/types.d.ts.map +1 -0
- package/dist/steps/Picker/types.js +30 -0
- package/dist/steps/Picker/types.js.map +1 -0
- package/dist/steps/Question/types.d.ts +47 -0
- package/dist/steps/Question/types.d.ts.map +1 -0
- package/dist/steps/Question/types.js +28 -0
- package/dist/steps/Question/types.js.map +1 -0
- package/dist/steps/Ratings/types.d.ts +32 -0
- package/dist/steps/Ratings/types.d.ts.map +1 -0
- package/dist/steps/Ratings/types.js +25 -0
- package/dist/steps/Ratings/types.js.map +1 -0
- package/dist/steps/common.types.d.ts +19 -0
- package/dist/steps/common.types.d.ts.map +1 -0
- package/dist/steps/common.types.js +25 -0
- package/dist/steps/common.types.js.map +1 -0
- package/dist/steps/types.d.ts +9 -0
- package/dist/steps/types.d.ts.map +1 -0
- package/dist/steps/types.js +3 -0
- package/dist/steps/types.js.map +1 -0
- package/dist/types.d.ts +46 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +48 -0
- package/src/OnboardingStudioClient.ts +92 -0
- package/src/global.d.ts +41 -0
- package/src/index.ts +6 -0
- package/src/infra/hooks/index.ts +2 -0
- package/src/infra/hooks/useOnboarding.ts +16 -0
- package/src/infra/hooks/useOnboardingStep.ts +66 -0
- package/src/infra/index.ts +2 -0
- package/src/infra/provider/OnboardingProvider.tsx +80 -0
- package/src/infra/provider/index.ts +4 -0
- package/src/infra/queries/getOnboarding.query.ts +58 -0
- package/src/steps/Carousel/types.ts +26 -0
- package/src/steps/Commitment/types.ts +28 -0
- package/src/steps/Loader/types.ts +32 -0
- package/src/steps/MediaContent/types.ts +26 -0
- package/src/steps/Picker/types.ts +34 -0
- package/src/steps/Question/types.ts +29 -0
- package/src/steps/Ratings/types.ts +22 -0
- package/src/steps/common.types.ts +25 -0
- package/src/steps/types.ts +16 -0
- package/src/types.ts +51 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { useCallback, useContext } from "react";
|
|
2
|
+
import { useSuspenseQuery } from "@tanstack/react-query";
|
|
3
|
+
import { useFocusEffect } from "expo-router";
|
|
4
|
+
import { OnboardingProgressContext } from "../provider/OnboardingProvider";
|
|
5
|
+
import { getOnboardingQuery } from "../queries/getOnboarding.query";
|
|
6
|
+
import { BaseStepType, Onboarding, OnboardingMetadata } from "../../types";
|
|
7
|
+
import { OnboardingStepType } from "../../steps/types";
|
|
8
|
+
|
|
9
|
+
export const useOnboardingStep = <
|
|
10
|
+
StepType extends BaseStepType = OnboardingStepType
|
|
11
|
+
>({
|
|
12
|
+
stepNumber,
|
|
13
|
+
}: {
|
|
14
|
+
stepNumber: number;
|
|
15
|
+
}): {
|
|
16
|
+
step: StepType;
|
|
17
|
+
isLastStep: boolean;
|
|
18
|
+
stepsLength: number;
|
|
19
|
+
onboardingMetadata: OnboardingMetadata;
|
|
20
|
+
steps: StepType[];
|
|
21
|
+
} => {
|
|
22
|
+
// Get all config from context
|
|
23
|
+
const {
|
|
24
|
+
client,
|
|
25
|
+
locale,
|
|
26
|
+
customAudienceParams,
|
|
27
|
+
setActiveStep,
|
|
28
|
+
setTotalSteps,
|
|
29
|
+
setOnboarding,
|
|
30
|
+
} = useContext(OnboardingProgressContext);
|
|
31
|
+
|
|
32
|
+
// Build query with config from context
|
|
33
|
+
const { data } = useSuspenseQuery<Onboarding<StepType>>(
|
|
34
|
+
getOnboardingQuery<StepType>(
|
|
35
|
+
client,
|
|
36
|
+
locale,
|
|
37
|
+
customAudienceParams,
|
|
38
|
+
setOnboarding as (onboarding: Onboarding<StepType>) => void
|
|
39
|
+
)
|
|
40
|
+
);
|
|
41
|
+
const steps = data.steps;
|
|
42
|
+
const onboardingMetadata = data.metadata;
|
|
43
|
+
|
|
44
|
+
useFocusEffect(
|
|
45
|
+
useCallback(() => {
|
|
46
|
+
const currentStep = steps[stepNumber - 1];
|
|
47
|
+
setActiveStep({
|
|
48
|
+
number: stepNumber,
|
|
49
|
+
displayProgressHeader: currentStep?.displayProgressHeader ?? true,
|
|
50
|
+
});
|
|
51
|
+
setTotalSteps(steps.length);
|
|
52
|
+
}, [stepNumber, steps, setActiveStep, setTotalSteps])
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
const step = steps[stepNumber - 1];
|
|
56
|
+
const isLastStep = stepNumber >= steps.length;
|
|
57
|
+
const stepsLength = steps.length;
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
step,
|
|
61
|
+
isLastStep,
|
|
62
|
+
stepsLength,
|
|
63
|
+
onboardingMetadata,
|
|
64
|
+
steps,
|
|
65
|
+
};
|
|
66
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { createContext, useState } from "react";
|
|
2
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
3
|
+
import { OnboardingStudioClient } from "../../OnboardingStudioClient";
|
|
4
|
+
import { getOnboardingQuery } from "../queries/getOnboarding.query";
|
|
5
|
+
import { Onboarding } from "../../types";
|
|
6
|
+
import { OnboardingStepType } from "../../steps/types";
|
|
7
|
+
|
|
8
|
+
const queryClient = new QueryClient({
|
|
9
|
+
defaultOptions: {
|
|
10
|
+
queries: {
|
|
11
|
+
staleTime: Infinity,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
interface OnboardingProviderProps {
|
|
17
|
+
children: React.ReactNode;
|
|
18
|
+
client: OnboardingStudioClient;
|
|
19
|
+
locale?: string;
|
|
20
|
+
customAudienceParams?: Record<string, any>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const OnboardingProvider = ({
|
|
24
|
+
children,
|
|
25
|
+
client,
|
|
26
|
+
locale = "en",
|
|
27
|
+
customAudienceParams = {},
|
|
28
|
+
}: OnboardingProviderProps) => {
|
|
29
|
+
const [activeStep, setActiveStep] = useState({
|
|
30
|
+
number: 0,
|
|
31
|
+
displayProgressHeader: false,
|
|
32
|
+
});
|
|
33
|
+
const [totalSteps, setTotalSteps] = useState(0);
|
|
34
|
+
const [onboarding, setOnboarding] = useState<Onboarding<OnboardingStepType> | null>(null);
|
|
35
|
+
|
|
36
|
+
queryClient.prefetchQuery(getOnboardingQuery(client, locale, customAudienceParams, setOnboarding))
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<QueryClientProvider client={queryClient}>
|
|
40
|
+
|
|
41
|
+
<OnboardingProgressContext.Provider
|
|
42
|
+
value={{
|
|
43
|
+
activeStep,
|
|
44
|
+
setActiveStep,
|
|
45
|
+
totalSteps,
|
|
46
|
+
setTotalSteps,
|
|
47
|
+
client,
|
|
48
|
+
locale,
|
|
49
|
+
customAudienceParams,
|
|
50
|
+
onboarding,
|
|
51
|
+
setOnboarding,
|
|
52
|
+
}}
|
|
53
|
+
>
|
|
54
|
+
{children}
|
|
55
|
+
</OnboardingProgressContext.Provider>
|
|
56
|
+
</QueryClientProvider>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const OnboardingProgressContext = createContext<{
|
|
61
|
+
activeStep: { number: number; displayProgressHeader: boolean };
|
|
62
|
+
setActiveStep: (step: { number: number; displayProgressHeader: boolean }) => void;
|
|
63
|
+
totalSteps: number;
|
|
64
|
+
setTotalSteps: (steps: number) => void;
|
|
65
|
+
client: OnboardingStudioClient;
|
|
66
|
+
locale: string;
|
|
67
|
+
customAudienceParams: Record<string, any>;
|
|
68
|
+
onboarding: Onboarding<OnboardingStepType> | null;
|
|
69
|
+
setOnboarding: (onboarding: Onboarding<OnboardingStepType>) => void;
|
|
70
|
+
}>({
|
|
71
|
+
activeStep: { number: 0, displayProgressHeader: false },
|
|
72
|
+
setActiveStep: () => { },
|
|
73
|
+
totalSteps: 0,
|
|
74
|
+
setTotalSteps: () => { },
|
|
75
|
+
client: new OnboardingStudioClient('', {}),
|
|
76
|
+
locale: "en",
|
|
77
|
+
customAudienceParams: {},
|
|
78
|
+
onboarding: null,
|
|
79
|
+
setOnboarding: () => { },
|
|
80
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
2
|
+
import { OnboardingStudioClient } from "../../OnboardingStudioClient";
|
|
3
|
+
import { BaseStepType, Onboarding, OnboardingMetadata } from "../../types";
|
|
4
|
+
import type { UseQueryOptions } from "@tanstack/react-query";
|
|
5
|
+
|
|
6
|
+
const cacheKey = "rocapine-onboarding-studio";
|
|
7
|
+
|
|
8
|
+
export const getOnboardingQuery = <StepType extends BaseStepType>(
|
|
9
|
+
client: OnboardingStudioClient,
|
|
10
|
+
locale: string,
|
|
11
|
+
customAudienceParams: Record<string, any>,
|
|
12
|
+
setOnboarding?: (onboarding: Onboarding<StepType>) => void
|
|
13
|
+
) => {
|
|
14
|
+
return {
|
|
15
|
+
queryKey: [
|
|
16
|
+
"onboardingQuestions",
|
|
17
|
+
client.projectId,
|
|
18
|
+
client.options.isSandbox,
|
|
19
|
+
client.options.baseUrl,
|
|
20
|
+
locale,
|
|
21
|
+
JSON.stringify(customAudienceParams),
|
|
22
|
+
],
|
|
23
|
+
queryFn: async (): Promise<Onboarding<StepType>> => {
|
|
24
|
+
// Try to get data from AsyncStorage first for production
|
|
25
|
+
if (!(client?.options?.isSandbox || false)) {
|
|
26
|
+
try {
|
|
27
|
+
const cachedData = await AsyncStorage.getItem(cacheKey);
|
|
28
|
+
if (cachedData) {
|
|
29
|
+
setOnboarding && setOnboarding(JSON.parse(cachedData));
|
|
30
|
+
return JSON.parse(cachedData);
|
|
31
|
+
}
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.warn("Failed to load cached onboarding questions:", error);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Fetch from API
|
|
38
|
+
const { data, headers } = await client!.getSteps<StepType>(
|
|
39
|
+
{ locale },
|
|
40
|
+
customAudienceParams
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
console.info("onbs-onboarding-name", headers["ONBS-Onboarding-Name"]);
|
|
44
|
+
console.info("onbs-onboarding-id", headers["ONBS-Onboarding-Id"]);
|
|
45
|
+
setOnboarding && setOnboarding(data);
|
|
46
|
+
|
|
47
|
+
// Cache the steps
|
|
48
|
+
try {
|
|
49
|
+
await AsyncStorage.setItem(cacheKey, JSON.stringify(data));
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.warn("Failed to cache onboarding questions:", error);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return data;
|
|
55
|
+
},
|
|
56
|
+
staleTime: Infinity,
|
|
57
|
+
};
|
|
58
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CustomPayloadSchema } from "../common.types";
|
|
3
|
+
|
|
4
|
+
export const CarouselScreenSchema = z.object({
|
|
5
|
+
mediaUrl: z.string(),
|
|
6
|
+
title: z.string(),
|
|
7
|
+
subtitle: z.string().nullish(),
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
export const CarouselStepPayloadSchema = z.object({
|
|
11
|
+
screens: z.array(CarouselScreenSchema),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export const CarouselStepTypeSchema = z.object({
|
|
15
|
+
id: z.string(),
|
|
16
|
+
type: z.literal("Carousel"),
|
|
17
|
+
name: z.string(),
|
|
18
|
+
displayProgressHeader: z.boolean(),
|
|
19
|
+
payload: CarouselStepPayloadSchema,
|
|
20
|
+
customPayload: CustomPayloadSchema,
|
|
21
|
+
continueButtonLabel: z.string().optional().default("Continue"),
|
|
22
|
+
figmaUrl: z.string().nullish(),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export type CarouselStepType = z.infer<typeof CarouselStepTypeSchema>;
|
|
26
|
+
export type CarouselScreenType = z.infer<typeof CarouselScreenSchema>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CustomPayloadSchema } from "../common.types";
|
|
3
|
+
|
|
4
|
+
export const CommitmentItemSchema = z.object({
|
|
5
|
+
text: z.string(),
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export const CommitmentStepPayloadSchema = z.object({
|
|
9
|
+
title: z.string(),
|
|
10
|
+
subtitle: z.string().nullish(),
|
|
11
|
+
description: z.string().nullish(),
|
|
12
|
+
commitments: z.array(CommitmentItemSchema).nullish(),
|
|
13
|
+
signatureCaption: z.string().default("Your signature is not recorded"),
|
|
14
|
+
variant: z.enum(["signature", "simple"]).default("signature"),
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export const CommitmentStepTypeSchema = z.object({
|
|
18
|
+
id: z.string(),
|
|
19
|
+
type: z.literal("Commitment"),
|
|
20
|
+
name: z.string(),
|
|
21
|
+
displayProgressHeader: z.boolean(),
|
|
22
|
+
payload: CommitmentStepPayloadSchema,
|
|
23
|
+
customPayload: CustomPayloadSchema,
|
|
24
|
+
continueButtonLabel: z.string().optional().default("Continue"),
|
|
25
|
+
figmaUrl: z.string().nullish(),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export type CommitmentStepType = z.infer<typeof CommitmentStepTypeSchema>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CustomPayloadSchema, MediaSourceSchema } from "../common.types";
|
|
3
|
+
|
|
4
|
+
export const LoaderStepSchema = z.object({
|
|
5
|
+
label: z.string(),
|
|
6
|
+
completed: z.string(),
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export const LoaderStepPayloadSchema = z.object({
|
|
10
|
+
title: z.string(),
|
|
11
|
+
steps: z.array(LoaderStepSchema),
|
|
12
|
+
didYouKnowImages: z.array(MediaSourceSchema).nullish(),
|
|
13
|
+
duration: z.number().optional().default(2000),
|
|
14
|
+
variant: z
|
|
15
|
+
.enum(["bars", "circle", "texts_fading"])
|
|
16
|
+
.optional()
|
|
17
|
+
.default("bars"),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export const LoaderStepTypeSchema = z.object({
|
|
21
|
+
id: z.string(),
|
|
22
|
+
type: z.literal("Loader"),
|
|
23
|
+
name: z.string(),
|
|
24
|
+
displayProgressHeader: z.boolean(),
|
|
25
|
+
payload: LoaderStepPayloadSchema,
|
|
26
|
+
customPayload: CustomPayloadSchema,
|
|
27
|
+
continueButtonLabel: z.string().optional().default("Continue"),
|
|
28
|
+
figmaUrl: z.string().nullish(),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export type LoaderStepType = z.infer<typeof LoaderStepTypeSchema>;
|
|
32
|
+
export type LoaderStep = z.infer<typeof LoaderStepSchema>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import {
|
|
3
|
+
CustomPayloadSchema,
|
|
4
|
+
MediaSourceSchema,
|
|
5
|
+
SocialProofSchema,
|
|
6
|
+
} from "../common.types";
|
|
7
|
+
|
|
8
|
+
export const MediaContentStepPayloadSchema = z.object({
|
|
9
|
+
mediaSource: MediaSourceSchema,
|
|
10
|
+
title: z.string(),
|
|
11
|
+
description: z.string().nullish(),
|
|
12
|
+
socialProof: SocialProofSchema.nullish(),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export const MediaContentStepTypeSchema = z.object({
|
|
16
|
+
id: z.string(),
|
|
17
|
+
type: z.literal("MediaContent"),
|
|
18
|
+
name: z.string(),
|
|
19
|
+
displayProgressHeader: z.boolean(),
|
|
20
|
+
payload: MediaContentStepPayloadSchema,
|
|
21
|
+
customPayload: CustomPayloadSchema,
|
|
22
|
+
continueButtonLabel: z.string().optional().default("Continue"),
|
|
23
|
+
figmaUrl: z.string().nullish(),
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export type MediaContentStepType = z.infer<typeof MediaContentStepTypeSchema>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CustomPayloadSchema } from "../common.types";
|
|
3
|
+
|
|
4
|
+
export const PickerTypeEnum = z.enum([
|
|
5
|
+
"height",
|
|
6
|
+
"weight",
|
|
7
|
+
"age",
|
|
8
|
+
"date",
|
|
9
|
+
"gender",
|
|
10
|
+
"coach",
|
|
11
|
+
"name",
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
export const PickerStepPayloadSchema = z.object({
|
|
15
|
+
title: z.string(),
|
|
16
|
+
description: z.string().nullish(),
|
|
17
|
+
pickerType: z.union([PickerTypeEnum, z.string()]),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export const PickerStepTypeSchema = z.object({
|
|
21
|
+
id: z.string(),
|
|
22
|
+
type: z.literal("Picker"),
|
|
23
|
+
name: z.string(),
|
|
24
|
+
displayProgressHeader: z.boolean(),
|
|
25
|
+
payload: PickerStepPayloadSchema,
|
|
26
|
+
customPayload: CustomPayloadSchema,
|
|
27
|
+
continueButtonLabel: z.string().optional().default("Continue"),
|
|
28
|
+
figmaUrl: z.string().nullish(),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export type PickerStepType = z.infer<typeof PickerStepTypeSchema>;
|
|
32
|
+
|
|
33
|
+
export type WeightUnit = "kg" | "lb";
|
|
34
|
+
export type HeightUnit = "cm" | "ft";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CustomPayloadSchema, InfoBoxSchema } from "../common.types";
|
|
3
|
+
|
|
4
|
+
export const AnswerSchema = z.object({
|
|
5
|
+
label: z.string(),
|
|
6
|
+
value: z.string(),
|
|
7
|
+
icon: z.string().nullish(),
|
|
8
|
+
description: z.string().nullish(),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export const QuestionStepPayloadSchema = z.object({
|
|
12
|
+
answers: z.array(AnswerSchema),
|
|
13
|
+
title: z.string(),
|
|
14
|
+
subtitle: z.string().nullish(),
|
|
15
|
+
multipleAnswer: z.boolean(),
|
|
16
|
+
infoBox: InfoBoxSchema.nullish(),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export const QuestionStepTypeSchema = z.object({
|
|
20
|
+
id: z.string(),
|
|
21
|
+
type: z.literal("Question"),
|
|
22
|
+
name: z.string(),
|
|
23
|
+
displayProgressHeader: z.boolean(),
|
|
24
|
+
payload: QuestionStepPayloadSchema,
|
|
25
|
+
customPayload: CustomPayloadSchema,
|
|
26
|
+
figmaUrl: z.string().nullish(),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export type QuestionStepType = z.infer<typeof QuestionStepTypeSchema>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
import { CustomPayloadSchema, SocialProofSchema } from "../common.types";
|
|
3
|
+
|
|
4
|
+
export const RatingsStepPayloadSchema = z.object({
|
|
5
|
+
title: z.string(),
|
|
6
|
+
subtitle: z.string(),
|
|
7
|
+
socialProofs: z.array(SocialProofSchema),
|
|
8
|
+
rateTheAppButtonLabel: z.string().optional().default("Rate the app"),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export const RatingsStepTypeSchema = z.object({
|
|
12
|
+
id: z.string(),
|
|
13
|
+
type: z.literal("Ratings"),
|
|
14
|
+
name: z.string(),
|
|
15
|
+
displayProgressHeader: z.boolean(),
|
|
16
|
+
payload: RatingsStepPayloadSchema,
|
|
17
|
+
customPayload: CustomPayloadSchema,
|
|
18
|
+
continueButtonLabel: z.string().optional().default("Continue"),
|
|
19
|
+
figmaUrl: z.string().nullish(),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export type RatingsStepType = z.infer<typeof RatingsStepTypeSchema>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const CustomPayloadSchema = z.record(z.string(), z.any()).nullish();
|
|
4
|
+
|
|
5
|
+
export const MediaSourceSchema = z.union([
|
|
6
|
+
z.object({
|
|
7
|
+
type: z.literal("image").or(z.literal("lottie")).or(z.literal("rive")),
|
|
8
|
+
localPathId: z.string(),
|
|
9
|
+
}),
|
|
10
|
+
z.object({
|
|
11
|
+
type: z.literal("image").or(z.literal("lottie")).or(z.literal("rive")),
|
|
12
|
+
url: z.string(),
|
|
13
|
+
}),
|
|
14
|
+
]);
|
|
15
|
+
|
|
16
|
+
export const SocialProofSchema = z.object({
|
|
17
|
+
numberOfStar: z.number(),
|
|
18
|
+
content: z.string(),
|
|
19
|
+
authorName: z.string(),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export const InfoBoxSchema = z.object({
|
|
23
|
+
title: z.string(),
|
|
24
|
+
content: z.string(),
|
|
25
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CarouselStepType } from "./Carousel/types";
|
|
2
|
+
import { CommitmentStepType } from "./Commitment/types";
|
|
3
|
+
import { LoaderStepType } from "./Loader/types";
|
|
4
|
+
import { MediaContentStepType } from "./MediaContent/types";
|
|
5
|
+
import { PickerStepType } from "./Picker/types";
|
|
6
|
+
import { QuestionStepType } from "./Question/types";
|
|
7
|
+
import { RatingsStepType } from "./Ratings/types";
|
|
8
|
+
|
|
9
|
+
export type OnboardingStepType =
|
|
10
|
+
| CarouselStepType
|
|
11
|
+
| CommitmentStepType
|
|
12
|
+
| LoaderStepType
|
|
13
|
+
| MediaContentStepType
|
|
14
|
+
| PickerStepType
|
|
15
|
+
| QuestionStepType
|
|
16
|
+
| RatingsStepType;
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base step type that all onboarding steps must conform to.
|
|
3
|
+
* This is the minimal interface required by the headless SDK.
|
|
4
|
+
*/
|
|
5
|
+
export type BaseStepType = {
|
|
6
|
+
id: string;
|
|
7
|
+
type: string;
|
|
8
|
+
name: string;
|
|
9
|
+
displayProgressHeader?: boolean;
|
|
10
|
+
payload?: any;
|
|
11
|
+
customPayload?: any;
|
|
12
|
+
continueButtonLabel?: string;
|
|
13
|
+
figmaUrl?: string | null;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type OnboardingStudioClientOptions<StepType extends BaseStepType = BaseStepType> = {
|
|
17
|
+
appVersion?: string;
|
|
18
|
+
isSandbox?: boolean;
|
|
19
|
+
baseUrl?: string;
|
|
20
|
+
fallbackOnboarding?: Onboarding<StepType>;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type OnboardingOptions = {
|
|
24
|
+
locale?: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type UserDefinedParams = {
|
|
28
|
+
[key: string]: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export interface OnboardingMetadata {
|
|
32
|
+
id: string;
|
|
33
|
+
name?: string;
|
|
34
|
+
audienceId?: string;
|
|
35
|
+
audienceName?: string;
|
|
36
|
+
audienceOrder?: number;
|
|
37
|
+
locale?: string;
|
|
38
|
+
draft?: boolean;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface Onboarding<StepType extends BaseStepType = BaseStepType> {
|
|
42
|
+
metadata: OnboardingMetadata;
|
|
43
|
+
steps: StepType[];
|
|
44
|
+
configuration: any;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface GetStepsResponseHeaders {
|
|
48
|
+
"ONBS-Onboarding-Id": string | null;
|
|
49
|
+
"ONBS-Audience-Id": string | null;
|
|
50
|
+
"ONBS-Onboarding-Name": string | null;
|
|
51
|
+
}
|