onboardsync-react-native
Version:
Expo SDK for OnboardSync - Remote onboarding configuration platform with A/B testing
129 lines (113 loc) • 4.1 kB
text/typescript
/**
* A single question response from the onboarding flow.
*
* This represents the user's answer to a single question in the
* onboarding flow. The `answer` type depends on the question type:
* - For text input questions: string
* - For single choice questions: string
* - For multiple choice questions: string[]
* - For picker questions: string[] (e.g., ["175"] for height, ["June", "15", "1995"] for date)
*/
export interface OnboardingResponse {
/** The text of the question that was asked */
questionText: string;
/** The type of question: 'question_text', 'question_single_choice', 'question_multiple_choice', or 'question_picker' */
questionType: string;
/** The user's answer. Can be a string or string[] depending on question type */
answer: string | string[];
/** The screen ID where this question appeared (optional) */
screenId?: string;
/** The measurement unit for height/weight pickers: 'metric' or 'imperial' (optional) */
unit?: 'metric' | 'imperial';
}
/**
* Contains all form responses from a completed onboarding flow.
*
* This object is passed to the onComplete callback when the user
* finishes the onboarding flow, allowing you to access all the responses
* the user provided to questions in the flow.
*
* @example
* ```typescript
* <OnboardSyncComponent
* projectId="xxx"
* secretKey="xxx"
* onComplete={(result) => {
* if (result) {
* result.responses.forEach(response => {
* console.log(`${response.questionText}: ${response.answer}`);
* });
* }
* }}
* />
* ```
*/
export interface OnboardingResult {
/** The ID of the completed flow */
flowId: string;
/** All responses from the onboarding flow */
responses: OnboardingResponse[];
}
/**
* Helper class for working with OnboardingResult
*/
export class OnboardingResultHelper {
private result: OnboardingResult;
constructor(result: OnboardingResult) {
this.result = result;
}
/** Gets a response by matching the question text (case-insensitive) */
getResponseByQuestion(questionText: string): OnboardingResponse | undefined {
return this.result.responses.find(
r => r.questionText.toLowerCase() === questionText.toLowerCase()
);
}
/** Gets all text input responses */
get textResponses(): OnboardingResponse[] {
return this.result.responses.filter(r => r.questionType === 'question_text');
}
/** Gets all single choice responses */
get singleChoiceResponses(): OnboardingResponse[] {
return this.result.responses.filter(r => r.questionType === 'question_single_choice');
}
/** Gets all multiple choice responses */
get multipleChoiceResponses(): OnboardingResponse[] {
return this.result.responses.filter(r => r.questionType === 'question_multiple_choice');
}
/** Gets all choice responses (single + multiple) */
get choiceResponses(): OnboardingResponse[] {
return this.result.responses.filter(
r => r.questionType === 'question_single_choice' || r.questionType === 'question_multiple_choice'
);
}
/** Gets all picker responses (height, weight, date, custom pickers) */
get pickerResponses(): OnboardingResponse[] {
return this.result.responses.filter(r => r.questionType === 'question_picker');
}
/** Whether this result contains any responses */
get hasResponses(): boolean {
return this.result.responses.length > 0;
}
/** The number of responses */
get responseCount(): number {
return this.result.responses.length;
}
}
// Matching Flutter/Swift SDK types
export interface OnboardSyncConfig {
projectId: string;
secretKey: string;
testingEnabled?: boolean;
onComplete?: (result?: OnboardingResult) => void;
}
// Response types matching backend
export interface ConfigResponse {
backendDomain: string;
}
export interface FlowResolutionResponse {
flowId: string;
}
// Permission types
export type PermissionType = 'camera' | 'photos' | 'location' | 'contacts' | 'notifications';
// Type alias for callbacks
export type OnboardingCompleteCallback = (result?: OnboardingResult) => void;