| 1 | import React, { useState } from 'react';
|
| 2 | import { View, StyleSheet } from 'react-native';
|
| 3 | import { router } from 'expo-router';
|
| 4 | import { SafeAreaView } from 'react-native-safe-area-context';
|
| 5 | import { Text } from '@/components/ui/Text';
|
| 6 | import { Button } from '@/components/ui';
|
| 7 | import { useAuth } from '@/context/AuthContext';
|
| 8 | import { useThemeColor } from '@/hooks/use-theme-color';
|
| 9 |
|
| 10 | const PAGES = [
|
| 11 | {
|
| 12 | title: 'Bem vindo ao nexo',
|
| 13 | body: 'Registre seu humor ao longo do dia, sempre depois que aconteceu. É um diário, não uma cobrança.',
|
| 14 | },
|
| 15 | {
|
| 16 | title: 'No seu ritmo',
|
| 17 | body: 'Anote quantos momentos quiser. Cada registro guarda o humor, a intensidade e o que aconteceu.',
|
| 18 | },
|
| 19 | {
|
| 20 | title: 'Olhe para trás',
|
| 21 | body: 'Com o tempo, o Histórico e a Jornada mostram padrões entre humor, sono, gatilhos e ações de cuidado.',
|
| 22 | },
|
| 23 | ];
|
| 24 |
|
| 25 | export default function OnboardingScreen() {
|
| 26 | const [index, setIndex] = useState(0);
|
| 27 | const [saving, setSaving] = useState(false);
|
| 28 | const { completeOnboarding } = useAuth();
|
| 29 | const textColor = useThemeColor({}, 'text');
|
| 30 | const backgroundColor = useThemeColor({}, 'background');
|
| 31 | const tintColor = useThemeColor({}, 'tint');
|
| 32 |
|
| 33 | const page = PAGES[index];
|
| 34 | const isLast = index === PAGES.length - 1;
|
| 35 |
|
| 36 | const finish = async () => {
|
| 37 | if (saving) return;
|
| 38 |
|
| 39 | setSaving(true);
|
| 40 | try {
|
| 41 | await completeOnboarding();
|
| 42 | } catch (error) {
|
| 43 | console.error('Failed to complete onboarding:', error);
|
| 44 | } finally {
|
| 45 | setSaving(false);
|
| 46 | router.replace('/(tabs)/new');
|
| 47 | }
|
| 48 | };
|
| 49 |
|
| 50 | return (
|
| 51 | <SafeAreaView style={[styles.container, { backgroundColor }]}>
|
| 52 | <View style={styles.content}>
|
| 53 | <Text style={[styles.title, { color: textColor }]}>{page.title}</Text>
|
| 54 | <Text style={[styles.body, { color: textColor, opacity: 0.7 }]}>
|
| 55 | {page.body}
|
| 56 | </Text>
|
| 57 | </View>
|
| 58 |
|
| 59 | <View style={styles.dots}>
|
| 60 | {PAGES.map((_, i) => (
|
| 61 | <View
|
| 62 | key={i}
|
| 63 | style={[
|
| 64 | styles.dot,
|
| 65 | {
|
| 66 | backgroundColor: i === index ? tintColor : textColor,
|
| 67 | opacity: i === index ? 1 : 0.2,
|
| 68 | },
|
| 69 | ]}
|
| 70 | />
|
| 71 | ))}
|
| 72 | </View>
|
| 73 |
|
| 74 | <View style={styles.actions}>
|
| 75 | <Button
|
| 76 | title={isLast ? 'Começar' : 'Próximo'}
|
| 77 | loading={saving}
|
| 78 | onPress={() => (isLast ? finish() : setIndex((i) => i + 1))}
|
| 79 | />
|
| 80 | {!isLast && (
|
| 81 | <Button
|
| 82 | variant="outline"
|
| 83 | title="Pular"
|
| 84 | onPress={finish}
|
| 85 | disabled={saving}
|
| 86 | />
|
| 87 | )}
|
| 88 | </View>
|
| 89 | </SafeAreaView>
|
| 90 | );
|
| 91 | }
|
| 92 |
|
| 93 | const styles = StyleSheet.create({
|
| 94 | container: {
|
| 95 | flex: 1,
|
| 96 | },
|
| 97 | content: {
|
| 98 | flex: 1,
|
| 99 | justifyContent: 'center',
|
| 100 | paddingHorizontal: 24,
|
| 101 | },
|
| 102 | title: {
|
| 103 | fontSize: 28,
|
| 104 | fontWeight: 'bold',
|
| 105 | marginBottom: 12,
|
| 106 | },
|
| 107 | body: {
|
| 108 | fontSize: 16,
|
| 109 | lineHeight: 24,
|
| 110 | },
|
| 111 | dots: {
|
| 112 | flexDirection: 'row',
|
| 113 | justifyContent: 'center',
|
| 114 | gap: 8,
|
| 115 | marginBottom: 24,
|
| 116 | },
|
| 117 | dot: {
|
| 118 | width: 8,
|
| 119 | height: 8,
|
| 120 | borderRadius: 4,
|
| 121 | },
|
| 122 | actions: {
|
| 123 | gap: 12,
|
| 124 | paddingHorizontal: 24,
|
| 125 | paddingBottom: 24,
|
| 126 | },
|
| 127 | });
|