eletrotupi / tcc/ frontend/app/auth/forgot-password.tsx6bdc28a3adcc45cf37288df8777dfa536ce0f07a
3.7 KB | 136 lines Raw
1
import React, { useState } from 'react';
2
import { StyleSheet, View } from 'react-native';
3
import { Link } from 'expo-router';
4
import { useThemeColor } from '@/hooks/use-theme-color';
5
import { Button, Input } from '@/components/ui';
6
import { Text } from '@/components/ui/Text';
7
import { AuthScreen } from '@/components/auth/AuthScreen';
8
import { useAuth } from '@/context/AuthContext';
9
import { useToast } from '@/context/ToastContext';
10
import { translateError } from '@/lib/errors/translations';
11

12
export default function ForgotPasswordScreen() {
13
  const [email, setEmail] = useState('');
14
  const [emailSent, setEmailSent] = useState(false);
15
  const [errors, setErrors] = useState<{ email?: string }>({});
16

17
  const { forgotPassword } = useAuth();
18
  const { showToast } = useToast();
19
  const [loading, setLoading] = useState(false);
20
  const textColor = useThemeColor({}, 'text');
21
  const tintColor = useThemeColor({}, 'tint');
22

23
  const validateForm = () => {
24
    const newErrors: { email?: string } = {};
25

26
    if (!email) {
27
      newErrors.email = 'Email é obrigatório';
28
    } else if (!/\S+@\S+\.\S+/.test(email)) {
29
      newErrors.email = 'Por favor entre um email válido';
30
    }
31

32
    setErrors(newErrors);
33
    return Object.keys(newErrors).length === 0;
34
  };
35

36
  const handleForgotPassword = async () => {
37
    if (!validateForm()) return;
38

39
    setLoading(true);
40
    try {
41
      await forgotPassword(email);
42
      setEmailSent(true);
43
    } catch (error) {
44
      showToast(translateError(error) || 'Falha ao enviar link de recuperação', 'error');
45
    } finally {
46
      setLoading(false);
47
    }
48
  };
49

50
  if (emailSent) {
51
    return (
52
      <AuthScreen
53
        title="Verifique seu email"
54
        subtitle={`Enviamos as instruções para resetar sua senha para ${email}`}
55
        footer={
56
          <View style={styles.actions}>
57
            <Button
58
              title="Reenviar email"
59
              variant="outline"
60
              onPress={() => setEmailSent(false)}
61
            />
62

63
            <Link href="/auth/login" asChild style={StyleSheet.flatten([styles.link, { color: tintColor }])}>
64
              <Text style={StyleSheet.flatten([styles.link, { color: tintColor }])}>
65
                Voltar para login
66
              </Text>
67
            </Link>
68
          </View>
69
        }
70
      />
71
    );
72
  }
73

74
  return (
75
    <AuthScreen
76
      title="Esqueceu a senha?"
77
      subtitle="Insira seu email para receber as instruções de recuperação"
78
      footer={
79
        <View style={styles.footer}>
80
          <Text style={[styles.footerText, { color: textColor, opacity: 0.7 }]}>
81
            Lembra tua senha?{' '}
82
          </Text>
83
          <Link href="/auth/login" asChild style={StyleSheet.flatten([styles.link, { color: tintColor }])}>
84
            <Text style={StyleSheet.flatten([styles.link, { color: tintColor }])}>
85
              Faça login
86
            </Text>
87
          </Link>
88
        </View>
89
      }
90
    >
91
      <View style={styles.form}>
92
        <Input
93
          label="Email"
94
          type="email"
95
          value={email}
96
          onChangeText={setEmail}
97
          placeholder="Qual seu email?"
98
          error={errors.email}
99
          autoCapitalize="none"
100
        />
101

102
        <Button
103
          title="Enviar link de recuperação"
104
          onPress={handleForgotPassword}
105
          loading={loading}
106
          style={styles.resetButton}
107
        />
108
      </View>
109
    </AuthScreen>
110
  );
111
}
112

113
const styles = StyleSheet.create({
114
  form: {
115
    marginBottom: 32,
116
  },
117
  resetButton: {
118
    marginTop: 8,
119
  },
120
  actions: {
121
    gap: 16,
122
  },
123
  link: {
124
    textAlign: 'center',
125
    fontSize: 14,
126
    fontWeight: '500',
127
  },
128
  footer: {
129
    flexDirection: 'row',
130
    justifyContent: 'center',
131
    alignItems: 'center',
132
  },
133
  footerText: {
134
    fontSize: 14,
135
  },
136
});