eletrotupi / tcc/ frontend/app/auth/login.tsx7742007861e4aba94c973d785c8801f8e822d1dc
5.2 KB | 207 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
import { apiClient, User } from "@/lib/api";
17
import { registerForPushNotifications } from "@/hooks/useRegisterPushToken";
18

19
export default function LoginScreen() {
20
  const [email, setEmail] = useState("");
21
  const [password, setPassword] = useState("");
22
  const [errors, setErrors] = useState<{ email?: string; password?: string }>(
23
    {},
24
  );
25

26
  const { login, updateAuthUser, isLoading } = useAuth();
27
  const textColor = useThemeColor({}, "text");
28
  const backgroundColor = useThemeColor({}, "background");
29
  const tintColor = useThemeColor({}, "tint");
30

31
  const validateForm = () => {
32
    const newErrors: { email?: string; password?: string } = {};
33

34
    if (!email) {
35
      newErrors.email = "Email é obrigatório";
36
    } else if (!/\S+@\S+\.\S+/.test(email)) {
37
      newErrors.email = "Por favor, use um email válido";
38
    }
39

40
    if (!password) {
41
      newErrors.password = "Senha é obrigatória";
42
    }
43

44
    setErrors(newErrors);
45
    return Object.keys(newErrors).length === 0;
46
  };
47

48
  const handleLogin = async () => {
49
    if (!validateForm()) return;
50

51
    try {
52
      const response = await login(email, password);
53

54
      if (response?.user) {
55
        const token = await registerForPushNotifications();
56
        if (token) {
57
          const updateResponse = await apiClient.updateUser({
58
            id: response.user.id,
59
            pushToken: token,
60
          });
61

62
          console.log("UPDATE USER response: ", updateResponse);
63

64
          if (updateResponse) {
65
            updateAuthUser(updateResponse.user);
66
          }
67
        }
68
      }
69

70
      router.replace("/");
71
    } catch (error: any) {
72
      console.log("LOGIN error: ", error);
73
      Alert.alert("Erro: ", "Falha ao fazer login");
74
    }
75
  };
76

77
  return (
78
    <SafeAreaView style={[styles.container, { backgroundColor }]}>
79
      <KeyboardAvoidingView behavior="height" style={styles.keyboardView}>
80
        <ScrollView
81
          contentContainerStyle={styles.scrollContainer}
82
          showsVerticalScrollIndicator={false}
83
        >
84
          <View style={styles.header}>
85
            <Text style={[styles.title, { color: textColor }]}>
86
              Bem vindo de volta
87
            </Text>
88
            <Text style={[styles.subtitle, { color: textColor, opacity: 0.7 }]}>
89
              Logue na sua conta nexo
90
            </Text>
91
          </View>
92

93
          <View style={styles.form}>
94
            <Input
95
              label="Email"
96
              type="email"
97
              value={email}
98
              onChangeText={setEmail}
99
              placeholder="Qual seu email?"
100
              error={errors.email}
101
              autoCapitalize="none"
102
            />
103

104
            <Input
105
              label="Senha"
106
              type="password"
107
              value={password}
108
              onChangeText={setPassword}
109
              placeholder="Qual sua senha?"
110
              error={errors.password}
111
              showPasswordToggle
112
            />
113

114
            <Button
115
              title="Entrar"
116
              onPress={handleLogin}
117
              loading={isLoading}
118
              style={styles.loginButton}
119
            />
120

121
            <Link
122
              href="/auth/forgot-password"
123
              style={[styles.link, { color: tintColor }]}
124
              asChild
125
            >
126
              <Text
127
                style={[styles.footerText, { color: textColor, opacity: 0.7 }]}
128
              >
129
                Esqueceu a senha?
130
              </Text>
131
            </Link>
132
          </View>
133

134
          <View style={styles.footer}>
135
            <Text
136
              style={[styles.footerText, { color: textColor, opacity: 0.7 }]}
137
            >
138
              Não tem uma conta ainda?{" "}
139
            </Text>
140

141
            <Link
142
              href="/auth/signup"
143
              asChild
144
              style={[styles.link, { color: tintColor }]}
145
            >
146
              <Text
147
                style={[styles.footerText, { color: textColor, opacity: 0.7 }]}
148
              >
149
                Cadastre-se
150
              </Text>
151
            </Link>
152
          </View>
153
        </ScrollView>
154
      </KeyboardAvoidingView>
155
    </SafeAreaView>
156
  );
157
}
158

159
const styles = StyleSheet.create({
160
  container: {
161
    flex: 1,
162
  },
163
  keyboardView: {
164
    flex: 1,
165
  },
166
  scrollContainer: {
167
    flexGrow: 1,
168
    paddingHorizontal: 24,
169
    justifyContent: "center",
170
    minHeight: "100%",
171
  },
172
  header: {
173
    alignItems: "center",
174
    marginBottom: 40,
175
  },
176
  title: {
177
    fontSize: 28,
178
    fontWeight: "bold",
179
    marginBottom: 8,
180
  },
181
  subtitle: {
182
    fontSize: 16,
183
    textAlign: "center",
184
  },
185
  form: {
186
    marginBottom: 32,
187
  },
188
  loginButton: {
189
    marginTop: 8,
190
    marginBottom: 16,
191
  },
192
  link: {
193
    textAlign: "center",
194
    fontSize: 14,
195
    fontWeight: "500",
196
  },
197
  footer: {
198
    flexDirection: "row",
199
    justifyContent: "center",
200
    alignItems: "center",
201
    marginTop: "auto",
202
    paddingBottom: 40,
203
  },
204
  footerText: {
205
    fontSize: 14,
206
  },
207
});