react-onboarding-sdk
Version:
A TypeScript SDK for fetching onboarding data from backend APIs with React hooks support
86 lines • 3.8 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React from 'react';
import { View, Text, ActivityIndicator, StyleSheet } from 'react-native';
import TextScreen from './screens/TextScreen';
import FileUploadScreen from './screens/FileUploadScreen';
import BannerScreen from './screens/BannerScreen';
import { fetchOnboardingConfig } from './utils/api';
export default function Onboarding({ appId, baseUrl, onFinish }) {
const [loading, setLoading] = React.useState(true);
const [error, setError] = React.useState(null);
const [screens, setScreens] = React.useState([]);
const [index, setIndex] = React.useState(0);
const [collected, setCollected] = React.useState({});
React.useEffect(() => {
let mounted = true;
setLoading(true);
setError(null);
const fetchOptions = baseUrl ? { baseUrl } : {};
fetchOnboardingConfig(appId, fetchOptions)
.then((data) => {
if (!mounted)
return;
setScreens(data.screens || []);
setIndex(0);
})
.catch((e) => {
if (!mounted)
return;
setError(e?.message || 'Failed to load onboarding');
})
.finally(() => {
if (mounted)
setLoading(false);
});
return () => {
mounted = false;
};
}, [appId, baseUrl]);
const onAction = (action, fileName, fileMeta) => {
const current = screens[index];
const entry = {
screenId: current.id,
actionClicked: action.label,
timestamp: new Date().toISOString(),
...(fileName ? { fileUploaded: fileName } : {}),
...(fileMeta ? { fileMeta } : {}),
};
setCollected((prev) => ({ ...prev, [current.id]: entry }));
if (action.target === 'end') {
const finalData = { ...collected, [current.id]: entry };
console.log('Onboarding finished. Collected data:\n', JSON.stringify(finalData, null, 2));
onFinish?.(finalData);
return;
}
const nextIndex = screens.findIndex((s) => s.id === action.target);
if (nextIndex !== -1) {
setIndex(nextIndex);
}
};
if (loading) {
return (_jsxs(View, { style: styles.center, children: [_jsx(ActivityIndicator, { size: "large", color: "#007AFF" }), _jsx(Text, { style: styles.muted, children: "Loading onboarding..." })] }));
}
if (error) {
return (_jsx(View, { style: styles.center, children: _jsxs(Text, { style: styles.error, children: ["Error: ", error] }) }));
}
if (!screens.length) {
return (_jsx(View, { style: styles.center, children: _jsx(Text, { style: styles.muted, children: "No onboarding screens available" }) }));
}
const current = screens[index];
switch (current.type) {
case 'text':
return _jsx(TextScreen, { content: current.content, actions: current.actions, onAction: (a) => onAction(a) });
case 'fileUpload':
return _jsx(FileUploadScreen, { content: current.content, actions: current.actions, onAction: (a, f, m) => onAction(a, f, m) });
case 'banner':
return _jsx(BannerScreen, { content: current.content, actions: current.actions, onAction: (a) => onAction(a) });
default:
return (_jsx(View, { style: styles.center, children: _jsxs(Text, { style: styles.error, children: ["Unknown screen type: ", current.type] }) }));
}
}
const styles = StyleSheet.create({
center: { flex: 1, alignItems: 'center', justifyContent: 'center', padding: 20 },
muted: { color: '#666', marginTop: 12 },
error: { color: '#d32f2f' },
});
//# sourceMappingURL=Onboarding.js.map