142 lines
3.5 KiB
TypeScript
142 lines
3.5 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { View, Text, StyleSheet, Image } from 'react-native';
|
|
import { useNavigation } from '@react-navigation/native';
|
|
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
|
import { RootStackParamList } from '../navigation/types';
|
|
import { Button } from '../components';
|
|
import { colors, spacing, typography } from '../lib/theme';
|
|
import { useAuth } from '../contexts/AuthContext';
|
|
|
|
type NavigationProp = NativeStackNavigationProp<RootStackParamList, 'Onboarding'>;
|
|
|
|
const SLIDES = [
|
|
{
|
|
title: 'Welcome to Pottery Diary',
|
|
description: 'Track every step of your ceramics journey from clay to finished piece',
|
|
icon: '🏺',
|
|
},
|
|
{
|
|
title: 'Log Every Detail',
|
|
description: 'Record firing temps, cone numbers, glazes, layers, and photos for each project',
|
|
icon: '🔥',
|
|
},
|
|
{
|
|
title: 'Reproduce Your Results',
|
|
description: 'Never forget how you made that perfect glaze combination',
|
|
icon: '🎨',
|
|
},
|
|
];
|
|
|
|
export const OnboardingScreen: React.FC = () => {
|
|
const navigation = useNavigation<NavigationProp>();
|
|
const { completeOnboarding } = useAuth();
|
|
const [currentSlide, setCurrentSlide] = useState(0);
|
|
|
|
const handleNext = () => {
|
|
if (currentSlide < SLIDES.length - 1) {
|
|
setCurrentSlide(currentSlide + 1);
|
|
} else {
|
|
handleComplete();
|
|
}
|
|
};
|
|
|
|
const handleSkip = () => {
|
|
handleComplete();
|
|
};
|
|
|
|
const handleComplete = async () => {
|
|
// Save onboarding completion status
|
|
await completeOnboarding();
|
|
navigation.replace('MainTabs', { screen: 'Projects' });
|
|
};
|
|
|
|
const slide = SLIDES[currentSlide];
|
|
|
|
return (
|
|
<View style={styles.container}>
|
|
<View style={styles.content}>
|
|
<Text style={styles.icon}>{slide.icon}</Text>
|
|
<Text style={styles.title}>{slide.title}</Text>
|
|
<Text style={styles.description}>{slide.description}</Text>
|
|
</View>
|
|
|
|
<View style={styles.pagination}>
|
|
{SLIDES.map((_, index) => (
|
|
<View
|
|
key={index}
|
|
style={[styles.dot, index === currentSlide && styles.dotActive]}
|
|
/>
|
|
))}
|
|
</View>
|
|
|
|
<View style={styles.buttons}>
|
|
{currentSlide < SLIDES.length - 1 && (
|
|
<Button
|
|
title="Skip"
|
|
onPress={handleSkip}
|
|
variant="ghost"
|
|
/>
|
|
)}
|
|
<Button
|
|
title={currentSlide === SLIDES.length - 1 ? "Get Started" : "Next"}
|
|
onPress={handleNext}
|
|
style={styles.nextButton}
|
|
/>
|
|
</View>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: colors.background,
|
|
padding: spacing.xl,
|
|
},
|
|
content: {
|
|
flex: 1,
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
},
|
|
icon: {
|
|
fontSize: 80,
|
|
marginBottom: spacing.xl,
|
|
},
|
|
title: {
|
|
fontSize: typography.fontSize.xxl,
|
|
fontWeight: typography.fontWeight.bold,
|
|
color: colors.text,
|
|
textAlign: 'center',
|
|
marginBottom: spacing.md,
|
|
},
|
|
description: {
|
|
fontSize: typography.fontSize.md,
|
|
color: colors.textSecondary,
|
|
textAlign: 'center',
|
|
lineHeight: 24,
|
|
},
|
|
pagination: {
|
|
flexDirection: 'row',
|
|
justifyContent: 'center',
|
|
gap: spacing.sm,
|
|
marginBottom: spacing.lg,
|
|
},
|
|
dot: {
|
|
width: 8,
|
|
height: 8,
|
|
borderRadius: 4,
|
|
backgroundColor: colors.border,
|
|
},
|
|
dotActive: {
|
|
backgroundColor: colors.primary,
|
|
width: 24,
|
|
},
|
|
buttons: {
|
|
flexDirection: 'row',
|
|
gap: spacing.md,
|
|
},
|
|
nextButton: {
|
|
flex: 1,
|
|
},
|
|
});
|