import React, { useState, useCallback, useMemo } from "react"; import { View, Text, ScrollView, StyleSheet, TouchableOpacity, Alert, KeyboardAvoidingView, Platform, } from "react-native"; import { useFocusEffect } from "@react-navigation/native"; import AsyncStorage from "@react-native-async-storage/async-storage"; import { Ionicons } from "@expo/vector-icons"; import { getMyProfile, updateMyProfile } from "../../api/api"; import TextInput from "../../components/ui/TextInput"; import Button from "../../components/ui/Button"; import { useTheme } from "../../context/ThemeContext"; import { spacing, borderRadius, fontSize, fontWeight } from "../../theme"; const STORAGE_ADDRESS = "profile_default_address"; const STORAGE_PHONE = "profile_default_phone"; const STORAGE_SIGNAL = "profile_signal_pseudo"; export default function ProfileScreen() { const { colors } = useTheme(); // Données compte (backend) const [nom, setNom] = useState(""); const [prenom, setPrenom] = useState(""); const [telephone, setTelephone] = useState(""); const [username, setUsername] = useState(""); // Données locales (AsyncStorage) const [defaultAddress, setDefaultAddress] = useState(""); const [defaultPhone, setDefaultPhone] = useState(""); const [signalPseudo, setSignalPseudo] = useState(""); const [loadingProfile, setLoadingProfile] = useState(true); const [savingContact, setSavingContact] = useState(false); const loadData = useCallback(async () => { setLoadingProfile(true); const [savedAddress, savedPhone, savedSignal, profileRes] = await Promise.all([ AsyncStorage.getItem(STORAGE_ADDRESS), AsyncStorage.getItem(STORAGE_PHONE), AsyncStorage.getItem(STORAGE_SIGNAL), getMyProfile(), ]); if (savedAddress !== null) setDefaultAddress(savedAddress); if (savedPhone !== null) setDefaultPhone(savedPhone); if (savedSignal !== null) setSignalPseudo(savedSignal); if (profileRes.success && profileRes.client) { const c = profileRes.client; setNom(c.nom ?? ""); setPrenom(c.prenom ?? ""); setTelephone(c.telephone ?? ""); setUsername(c.username ?? ""); // Init téléphone par défaut si pas encore sauvegardé if (savedPhone === null && c.telephone) { setDefaultPhone(c.telephone); } } setLoadingProfile(false); }, []); useFocusEffect(useCallback(() => { loadData(); }, [loadData])); const saveLocal = async () => { await Promise.all([ AsyncStorage.setItem(STORAGE_ADDRESS, defaultAddress.trim()), AsyncStorage.setItem(STORAGE_PHONE, defaultPhone.trim()), AsyncStorage.setItem(STORAGE_SIGNAL, signalPseudo.trim()), ]); Alert.alert("Enregistré", "Informations par défaut sauvegardées"); }; const saveContact = async () => { setSavingContact(true); const res = await updateMyProfile({ nom: nom.trim(), prenom: prenom.trim(), telephone: telephone.trim() }); setSavingContact(false); if (res.success) { Alert.alert("Succès", res.message ?? "Profil mis à jour"); } else { Alert.alert("Erreur", res.message ?? "Erreur lors de la mise à jour"); } }; const styles = useMemo(() => StyleSheet.create({ container: { flex: 1, backgroundColor: colors.bgPrimary }, content: { padding: spacing.l, paddingBottom: spacing.xxxl }, header: { flexDirection: "row", alignItems: "center", gap: spacing.m, marginBottom: spacing.xl, paddingTop: spacing.m, }, avatar: { width: 56, height: 56, borderRadius: 28, backgroundColor: colors.accent, justifyContent: "center", alignItems: "center", }, username: { color: colors.textPrimary, fontSize: fontSize.lg, fontWeight: fontWeight.bold }, usernameLabel: { color: colors.textMuted, fontSize: fontSize.sm }, card: { backgroundColor: colors.bgCard, borderRadius: borderRadius.md, padding: spacing.l, marginBottom: spacing.m, borderWidth: 1, borderColor: colors.borderLight, }, cardTitle: { flexDirection: "row", alignItems: "center", gap: spacing.s, marginBottom: spacing.m, }, cardTitleText: { color: colors.textPrimary, fontSize: fontSize.md, fontWeight: fontWeight.semibold, }, hint: { color: colors.textMuted, fontSize: fontSize.xs, marginBottom: spacing.m, lineHeight: 18, }, row: { flexDirection: "row", gap: spacing.m }, half: { flex: 1 }, fieldSpacing: { marginTop: spacing.m }, saveBtn: { marginTop: spacing.m, backgroundColor: colors.accent, borderRadius: borderRadius.sm, paddingVertical: spacing.m, paddingHorizontal: spacing.l, flexDirection: "row", alignItems: "center", justifyContent: "center", gap: spacing.s, }, saveBtnSecondary: { backgroundColor: "transparent", borderWidth: 1, borderColor: colors.accent + "66", }, saveBtnText: { color: "#fff", fontSize: fontSize.sm, fontWeight: fontWeight.semibold }, saveBtnTextSecondary: { color: colors.accent }, }), [colors]); if (loadingProfile) { return ( Chargement... ); } return ( {/* Header */} @{username || "..."} Mon compte {/* Carte compte */} Mon compte } /> } /> } keyboardType="phone-pad" /> {savingContact ? "Enregistrement..." : "Enregistrer le compte"} {/* Carte adresse par défaut */} Adresse par défaut Sera pré-remplie à la commande. Modifiable si vous n'êtes pas à cette adresse. } multiline numberOfLines={2} /> {/* Carte contact livraison */} Contact livraison Numéro et pseudo Signal utilisés lors de la livraison. } keyboardType="phone-pad" /> } /> Enregistrer les infos par défaut ); }