eletrotupi / tcc/ frontend/app/profile.tsxd5dbfbd54d2fb3166d9d8ccdd14000bdcfb0dfdb
5.7 KB | 236 lines Raw
1
import { useState, useEffect } from 'react';
2
import {
3
  View,
4
  Text,
5
  StyleSheet,
6
  ScrollView,
7
  KeyboardAvoidingView,
8
  Platform,
9
  Alert,
10
} from 'react-native';
11

12
import { ThemedView } from '@/components/ui/themed-view'
13
import { ThemedText } from '@/components/ui/themed-text'
14
import { Link, useLocalSearchParams, router } from 'expo-router';
15
import { StatusBar } from 'expo-status-bar';
16
import { SafeAreaView } from 'react-native-safe-area-context';
17
import { useThemeColor } from '@/hooks/use-theme-color';
18
import { Button, Input } from '@/components/ui';
19
import { useAuth } from '@/context/AuthContext';
20
import { apiClient } from '@/lib/api'
21

22
export default function Profile() {
23
  const { user, updateAuthUser } = useAuth();
24
  const [firstName, setFirstName] = useState(user.firstName);
25
  const [lastName, setLastName] = useState(user.lastName);
26
  const [email, setEmail] = useState(user.email);
27
  const [password, setPassword] = useState();
28
  const [confirmPassword, setConfirmPassword] = useState();
29
  const [loading, setLoading] = useState(false);
30
  const [errors, setErrors] = useState<{
31
    firstName?: string;
32
    password?: string;
33
    confirmPassword?: string;
34
  }>({});
35

36
  useEffect(() => {
37
    setFirstName(user.firstName)
38
    setLastName(user.lastName)
39
    setEmail(user.email)
40
  }, [user])
41

42
  const backgroundColor = useThemeColor({}, 'background');
43
  const textColor = useThemeColor({}, 'text');
44

45
  const validateForm = () => {
46
    const newErrors: {
47
      firstName?: string;
48
      email?: string;
49
      password?: string;
50
      confirmPassword?: string
51
    } = {};
52

53
    if (password) {
54
      if (!confirmPassword) {
55
        newErrors.confirmPassword = 'Precisa confirmar a senha';
56
      } else {
57
        if (password !== confirmPassword) {
58
          newErrors.confirmPassword = "Senhas não conferem";
59
        }
60
      }
61
    }
62

63
    if (!/\S+@\S+\.\S+/.test(email)) {
64
      newErrors.email = 'Por favor, use um email válido';
65
    }
66

67
    if (!firstName) {
68
      newErrors.firstName = 'É necessário ter um nome';
69
    }
70

71
    setErrors(newErrors);
72

73
    return Object.keys(newErrors).length === 0;
74
  }
75

76
  const handleUpdate = async () => {
77
    if (!validateForm()) return;
78

79
    const data = {};
80

81
    data.firstName = firstName
82
    data.lastName = lastName
83
    data.email = email
84

85
    if (password) {
86
      data.password = password
87
    }
88

89
    try {
90
      const id = user.id;
91

92
      const response = await apiClient.updateUser({
93
        id,
94
        firstName,
95
        lastName,
96
        email,
97
        password
98
      });
99

100
      updateAuthUser(response.user);
101

102
      router.replace('/(tabs)/insights');
103
    } catch (error: any) {
104
      console.error("[PROFILE]", error)
105
      Alert.alert('Erro: ', 'Falha ao tentar atualizar o usuário');
106
    }
107
  }
108

109
  return (
110
    <SafeAreaView style={[styles.container, { backgroundColor }]}>
111
      <StatusBar style={'dark'} />
112
      <KeyboardAvoidingView
113
        behavior='height'
114
        style={styles.keyboardView}
115
      >
116
        <ScrollView
117
          contentContainerStyle={styles.scrollContainer}
118
          showsVerticalScrollIndicator={false}
119
        >
120
          <View style={styles.header}>
121
            <Text style={[styles.title, { color: textColor }]}>Edite o seu perfil</Text>
122
            <Text style={[styles.subtitle, { color: textColor, opacity: 0.7 }]}>
123
              Altere suas configurações
124
            </Text>
125
          </View>
126

127
          <View style={styles.form}>
128
            <Input
129
              label="Primeiro Nome"
130
              type="text"
131
              value={firstName}
132
              onChangeText={setFirstName}
133
              placeholder="Qual seu nome?"
134
              error={errors.firstName}
135
            />
136

137
            <Input
138
              label="Sobrenome"
139
              type="text"
140
              value={lastName}
141
              onChangeText={setLastName}
142
              placeholder="Qual seu sobrenome?"
143
              error={errors.lastName}
144
            />
145

146
            <Input
147
              label="Email"
148
              type="text"
149
              value={email}
150
              onChangeText={setEmail}
151
              placeholder="Qual seu email?"
152
              error={errors.email}
153
            />
154

155
            <Input
156
              label="Nova senha"
157
              type="password"
158
              value={password}
159
              onChangeText={setPassword}
160
              placeholder="Digite uma nova senha"
161
              error={errors.password}
162
              showPasswordToggle
163
            />
164

165
            <Input
166
              label="Confirmar nova senha"
167
              type="password"
168
              value={confirmPassword}
169
              onChangeText={setConfirmPassword}
170
              placeholder="Confirme a nova senha"
171
              error={errors.confirmPassword}
172
              showPasswordToggle
173
            />
174

175
            <Button
176
              title="Atualizar perfil"
177
              onPress={handleUpdate}
178
              loading={loading}
179
              style={styles.resetButton}
180
            />
181
          </View>
182

183
        </ScrollView>
184
      </KeyboardAvoidingView>
185
    </SafeAreaView>
186
  )
187
}
188

189
const styles = StyleSheet.create({
190
  container: {
191
    flex: 1,
192
  },
193
  keyboardView: {
194
    flex: 1,
195
  },
196
  scrollContainer: {
197
    flexGrow: 1,
198
    paddingHorizontal: 24,
199
    justifyContent: 'start',
200
    minHeight: '100%',
201
  },
202
  header: {
203
    alignItems: 'left',
204
    marginBottom: 40,
205
  },
206
  title: {
207
    fontSize: 28,
208
    fontWeight: 'bold',
209
    marginBottom: 8,
210
  },
211
  subtitle: {
212
    fontSize: 16,
213
    textAlign: 'left',
214
  },
215
  form: {
216
    marginBottom: 32,
217
  },
218
  resetButton: {
219
    marginTop: 8,
220
  },
221
  link: {
222
    textAlign: 'center',
223
    fontSize: 14,
224
    fontWeight: '500',
225
  },
226
  footer: {
227
    flexDirection: 'row',
228
    justifyContent: 'center',
229
    alignItems: 'center',
230
    marginTop: 'auto',
231
    paddingBottom: 20,
232
  },
233
  footerText: {
234
    fontSize: 14,
235
  },
236
});