eletrotupi / tcc/ frontend/app/auth/signup.tsx7dd6bda06e1d90ac6bd0cbc1b011352cbcd81b08
5.6 KB | 216 lines Raw
1
import React, { useState } from 'react';
2
import {
3
  View,
4
  Text,
5
  StyleSheet,
6
  ScrollView,
7
  KeyboardAvoidingView,
8
  Platform,
9
  Alert,
10
} from 'react-native';
11
import { Link, router } from 'expo-router';
12
import { SafeAreaView } from 'react-native-safe-area-context';
13
import { useThemeColor } from '@/hooks/use-theme-color';
14
import { Button, Input } from '@/components/ui';
15
import { useAuth } from '@/context/AuthContext';
16

17
export default function SignupScreen() {
18
  const [firstName, setFirstName] = useState('');
19
  const [lastName, setLastName] = useState('');
20
  const [email, setEmail] = useState('');
21
  const [password, setPassword] = useState('');
22
  const [confirmPassword, setConfirmPassword] = useState('');
23
  const [errors, setErrors] = useState<{
24
    firstName?: string;
25
    email?: string;
26
    password?: string;
27
    confirmPassword?: string;
28
  }>({});
29

30
  const { signup, isLoading } = useAuth();
31
  const textColor = useThemeColor({}, 'text');
32
  const backgroundColor = useThemeColor({}, 'background');
33
  const tintColor = useThemeColor({}, 'tint');
34

35
  const validateForm = () => {
36
    const newErrors: typeof errors = {};
37

38
    if (!firstName.trim()) {
39
      newErrors.firstName = 'O nome é obrigatório';
40
    }
41

42
    if (!email) {
43
      newErrors.email = 'Email é obrigatório';
44
    } else if (!/\S+@\S+\.\S+/.test(email)) {
45
      newErrors.email = 'Por favor entre um email válido';
46
    }
47

48
    if (!password) {
49
      newErrors.password = 'Senha é obrigatório';
50
    } else if (password.length < 6) {
51
      newErrors.password = 'A senha deve conter pelo menos 6 caracteres';
52
    }
53

54
    if (!confirmPassword) {
55
      newErrors.confirmPassword = 'Por favor confirme sua senha';
56
    } else if (password !== confirmPassword) {
57
      newErrors.confirmPassword = 'As senhas não coincidem';
58
    }
59

60
    setErrors(newErrors);
61
    return Object.keys(newErrors).length === 0;
62
  };
63

64
  const handleSignup = async () => {
65
    if (!validateForm()) return;
66

67
    try {
68
      await signup({
69
        user: {
70
          firstName,
71
          lastName,
72
          email,
73
          password
74
        }
75
      });
76
      router.replace('/');
77
    } catch (error: any) {
78
	  Alert.alert('Erro:', error.message || 'Falha no cadastro. Tente novamente.');
79
    }
80
  };
81

82
  return (
83
    <SafeAreaView style={[styles.container, { backgroundColor }]}>
84
      <KeyboardAvoidingView
85
        behavior='height'
86
        style={styles.keyboardView}
87
      >
88
        <ScrollView
89
          contentContainerStyle={styles.scrollContainer}
90
          showsVerticalScrollIndicator={false}
91
        >
92
          <View style={styles.header}>
93
            <Text style={[styles.title, { color: textColor }]}>Criar conta</Text>
94
            <Text style={[styles.subtitle, { color: textColor, opacity: 0.7 }]}>
95
              Cadastre-se para começar a monitorar o seu humor.
96
            </Text>
97
          </View>
98

99
          <View style={styles.form}>
100
            <Input
101
              label="Nome"
102
              value={firstName}
103
              onChangeText={setFirstName}
104
              placeholder="Digite seu nome"
105
              error={errors.firstName}
106
            />
107

108
            <Input
109
              label="Sobrenome (opcional)"
110
              value={lastName}
111
              onChangeText={setLastName}
112
              placeholder="Digite seu sobrenome"
113
            />
114

115
            <Input
116
              label="Email"
117
              type="email"
118
              value={email}
119
              onChangeText={setEmail}
120
              placeholder="Qual seu email?"
121
              error={errors.email}
122
              autoCapitalize="none"
123
            />
124

125
            <Input
126
              label="Password"
127
              type="password"
128
              value={password}
129
              onChangeText={setPassword}
130
              placeholder="Escolha uma senha (min. 6 caracteres)"
131
              error={errors.password}
132
              showPasswordToggle
133
            />
134

135
            <Input
136
              label="Confirme a senha"
137
              type="password"
138
              value={confirmPassword}
139
              onChangeText={setConfirmPassword}
140
              placeholder="Confirme sua senha"
141
              error={errors.confirmPassword}
142
              showPasswordToggle
143
            />
144

145
            <Button
146
              title="Criar conta"
147
              onPress={handleSignup}
148
              loading={isLoading}
149
              style={styles.signupButton}
150
            />
151
          </View>
152

153
          <View style={styles.footer}>
154
            <Text style={[styles.footerText, { color: textColor, opacity: 0.7 }]}>
155
              Já tem uma conta?{' '}
156
            </Text>
157
            <Link href="/auth/login" asChild style={[styles.link, { color: tintColor }]}>
158
              <Text style={[styles.link, { color: tintColor }]}>
159
                Faça login
160
              </Text>
161
            </Link>
162
          </View>
163
        </ScrollView>
164
      </KeyboardAvoidingView>
165
    </SafeAreaView>
166
  );
167
}
168

169
const styles = StyleSheet.create({
170
  container: {
171
    flex: 1,
172
  },
173
  keyboardView: {
174
    flex: 1,
175
  },
176
  scrollContainer: {
177
    flexGrow: 1,
178
    paddingHorizontal: 24,
179
    justifyContent: 'center',
180
    minHeight: '100%',
181
  },
182
  header: {
183
    alignItems: 'center',
184
    marginBottom: 40,
185
  },
186
  title: {
187
    fontSize: 28,
188
    fontWeight: 'bold',
189
    marginBottom: 8,
190
  },
191
  subtitle: {
192
    fontSize: 16,
193
    textAlign: 'center',
194
  },
195
  form: {
196
    marginBottom: 32,
197
  },
198
  signupButton: {
199
    marginTop: 8,
200
  },
201
  link: {
202
    textAlign: 'center',
203
    fontSize: 14,
204
    fontWeight: '500',
205
  },
206
  footer: {
207
    flexDirection: 'row',
208
    justifyContent: 'center',
209
    alignItems: 'center',
210
    marginTop: 'auto',
211
    paddingBottom: 20,
212
  },
213
  footerText: {
214
    fontSize: 14,
215
  },
216
});