eletrotupi / tcc/ frontend/app/auth/activate.tsx197411f7c5a8e6a2ca5e59578caa01aa863c87f4
4.2 KB | 161 lines Raw
1
import React, { useState } from 'react';
2
import {
3
  View,
4
  StyleSheet,
5
  ScrollView,
6
  KeyboardAvoidingView,
7
} from 'react-native';
8
import { Text } from '@/components/ui/Text';
9
import { Link, useLocalSearchParams, router } from 'expo-router';
10
import { SafeAreaView } from 'react-native-safe-area-context';
11
import { useThemeColor } from '@/hooks/use-theme-color';
12
import { Button, Input } from '@/components/ui';
13
import { Colors } from '@/constants/theme'
14
import { useAuth } from '@/context/AuthContext';
15
import { useToast } from '@/context/ToastContext';
16
import { translateError } from '@/lib/errors/translations';
17

18
export default function ActivateScreen() {
19
  const { userId } = useLocalSearchParams();
20
  const [code, setCode] = useState('');
21
  const [errors, setErrors] = useState<{
22
    code?: string;
23
  }>({});
24

25
  const { activate, requestActivateCode } = useAuth();
26
  const { showToast } = useToast();
27
  const [loading, setLoading] = useState(false);
28
  const textColor = useThemeColor({}, 'text');
29
  const backgroundColor = useThemeColor({}, 'background');
30
  const tintColor = useThemeColor({}, 'tint');
31

32
  const validateForm = () => {
33
    const newErrors: typeof errors = {};
34

35
    if (!code) {
36
      newErrors.code = 'O código é obrigatório';
37
    } else if (code.length < 6) {
38
      newErrors.code = 'O código deve conter pelo menos 6 caracteres';
39
    }
40

41
    setErrors(newErrors);
42

43
    return Object.keys(newErrors).length === 0;
44
  };
45

46
  const handleActivate = async () => {
47
    if (!validateForm()) return;
48

49
    setLoading(true);
50
    try {
51
      await activate(Number(code.replaceAll(' ', '')));
52
      showToast('Conta ativada com sucesso!', 'success');
53
      router.replace('/');
54
    } catch (error: any) {
55
      showToast(translateError(error.message) || 'Falha em ativar a conta', 'error');
56
    } finally {
57
      setLoading(false);
58
    }
59
  };
60

61
  const resendCode = async () => {
62
    try {
63
      await requestActivateCode();
64
      showToast('Novo código enviado. Verifique sua caixa de entrada.', 'success');
65
    } catch {
66
      showToast('Falha ao reenviar o código. Tente novamente.', 'error');
67
    }
68
  }
69

70
  return (
71
    <SafeAreaView style={[styles.container, { backgroundColor }]}>
72
      <KeyboardAvoidingView
73
        behavior='height'
74
        style={styles.keyboardView}
75
      >
76
        <ScrollView
77
          contentContainerStyle={styles.scrollContainer}
78
          showsVerticalScrollIndicator={false}
79
        >
80
          <View style={styles.header}>
81
            <Text style={[styles.title, { color: textColor }]}>Ativar a conta</Text>
82
            <Text style={[styles.subtitle, { color: textColor, opacity: 0.7 }]}>
83
              Digite o código de ativação enviado para seu email
84
            </Text>
85
          </View>
86

87
          <View style={styles.form}>
88
            <Input
89
              label="Código"
90
              type="text"
91
              value={code}
92
              onChangeText={setCode}
93
              keyboardType="number-pad"
94
              placeholder="Digite o código enviado para sua conta"
95
              error={errors.code}
96
            />
97

98
            <Button
99
              title="Ativar conta"
100
              onPress={handleActivate}
101
              loading={loading}
102
              style={styles.resetButton}
103
            />
104
          </View>
105

106
          <View style={styles.footer}>
107
            <Text style={[styles.footerText, { color: textColor, opacity: 0.7 }]}>
108
              Não recebeu?{' '}
109
            </Text>
110

111
            <Button variant="outline" title="Reenviar um novo código" onPress={resendCode} />
112
          </View>
113
        </ScrollView>
114
      </KeyboardAvoidingView>
115
    </SafeAreaView>
116
  );
117
}
118

119
const styles = StyleSheet.create({
120
  container: {
121
    flex: 1,
122
  },
123
  keyboardView: {
124
    flex: 1,
125
  },
126
  scrollContainer: {
127
    flexGrow: 1,
128
    paddingHorizontal: 24,
129
    justifyContent: 'center',
130
    minHeight: '100%',
131
  },
132
  header: {
133
    alignItems: 'center',
134
    marginBottom: 40,
135
  },
136
  title: {
137
    fontSize: 28,
138
    fontWeight: 'bold',
139
    marginBottom: 8,
140
  },
141
  subtitle: {
142
    fontSize: 16,
143
    textAlign: 'center',
144
  },
145
  form: {
146
    marginBottom: 32,
147
  },
148
  resetButton: {
149
    marginTop: 8,
150
  },
151
  footer: {
152
    marginTop: 20,
153
    borderTopColor: Colors.light.accentBlue,
154
    borderTopWidth: 1,
155
    paddingTop: 20
156
  },
157
  footerText: {
158
    textAlign: 'center',
159
    marginBottom: 10
160
  }
161
});