eletrotupi / tcc/ frontend/app/onboarding.tsx27bca510c14b3745f6fa52ae54fac66653498781
3.1 KB | 127 lines Raw
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
});