import React, { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { useToast } from '../components/Toast'; import { profileService, subscriptionService } from '../services/api'; import FactoryResetWizard from '../components/FactoryResetWizard'; import ImportBackupModal from '../components/ImportBackupModal'; import CancellationWizard from '../components/CancellationWizard'; // Lista de países com código de telefone (foco: ES, BR, US) const COUNTRY_CODES = [ { code: '+34', country: 'ES', flag: '🇪🇸', name: 'España' }, { code: '+55', country: 'BR', flag: '🇧🇷', name: 'Brasil' }, { code: '+1', country: 'US', flag: '🇺🇸', name: 'United States' }, { code: '+44', country: 'GB', flag: '🇬🇧', name: 'United Kingdom' }, { code: '+33', country: 'FR', flag: '🇫🇷', name: 'France' }, { code: '+49', country: 'DE', flag: '🇩🇪', name: 'Germany' }, { code: '+39', country: 'IT', flag: '🇮🇹', name: 'Italy' }, { code: '+351', country: 'PT', flag: '🇵🇹', name: 'Portugal' }, { code: '+52', country: 'MX', flag: '🇲🇽', name: 'México' }, { code: '+54', country: 'AR', flag: '🇦🇷', name: 'Argentina' }, { code: '+56', country: 'CL', flag: '🇨🇱', name: 'Chile' }, { code: '+57', country: 'CO', flag: '🇨🇴', name: 'Colombia' }, { code: '+58', country: 'VE', flag: '🇻🇪', name: 'Venezuela' }, { code: '+81', country: 'JP', flag: '🇯🇵', name: 'Japan' }, { code: '+86', country: 'CN', flag: '🇨🇳', name: 'China' }, ]; // Lista de países para seleção const COUNTRIES = [ { code: 'ES', name: 'España', flag: '🇪🇸' }, { code: 'BR', name: 'Brasil', flag: '🇧🇷' }, { code: 'US', name: 'United States', flag: '🇺🇸' }, { code: 'GB', name: 'United Kingdom', flag: '🇬🇧' }, { code: 'FR', name: 'France', flag: '🇫🇷' }, { code: 'DE', name: 'Germany', flag: '🇩🇪' }, { code: 'IT', name: 'Italy', flag: '🇮🇹' }, { code: 'PT', name: 'Portugal', flag: '🇵🇹' }, { code: 'MX', name: 'México', flag: '🇲🇽' }, { code: 'AR', name: 'Argentina', flag: '🇦🇷' }, { code: 'CL', name: 'Chile', flag: '🇨🇱' }, { code: 'CO', name: 'Colombia', flag: '🇨🇴' }, { code: 'VE', name: 'Venezuela', flag: '🇻🇪' }, { code: 'JP', name: 'Japan', flag: '🇯🇵' }, { code: 'CN', name: 'China', flag: '🇨🇳' }, ]; // Lista de timezones comuns const TIMEZONES = [ { value: 'Europe/Madrid', label: 'Madrid (CET/CEST)' }, { value: 'Europe/Lisbon', label: 'Lisboa (WET/WEST)' }, { value: 'Europe/London', label: 'London (GMT/BST)' }, { value: 'Europe/Paris', label: 'Paris (CET/CEST)' }, { value: 'Europe/Berlin', label: 'Berlin (CET/CEST)' }, { value: 'America/Sao_Paulo', label: 'São Paulo (BRT)' }, { value: 'America/New_York', label: 'New York (EST/EDT)' }, { value: 'America/Los_Angeles', label: 'Los Angeles (PST/PDT)' }, { value: 'America/Chicago', label: 'Chicago (CST/CDT)' }, { value: 'America/Mexico_City', label: 'Ciudad de México (CST)' }, { value: 'America/Buenos_Aires', label: 'Buenos Aires (ART)' }, { value: 'America/Santiago', label: 'Santiago (CLT)' }, { value: 'America/Bogota', label: 'Bogotá (COT)' }, { value: 'Asia/Tokyo', label: 'Tokyo (JST)' }, { value: 'Asia/Shanghai', label: 'Shanghai (CST)' }, ]; export default function Profile() { const { t, i18n } = useTranslation(); const { showToast } = useToast(); const [loading, setLoading] = useState(true); const [savingProfile, setSavingProfile] = useState(false); const [savingPassword, setSavingPassword] = useState(false); // Dados do perfil const [profile, setProfile] = useState({ first_name: '', last_name: '', email: '', phone_country_code: '+34', phone: '', accept_whatsapp: false, accept_emails: true, country: 'ES', timezone: 'Europe/Madrid', locale: 'es', }); // Dados de alteração de senha const [passwordData, setPasswordData] = useState({ current_password: '', new_password: '', new_password_confirmation: '', }); // Erros de validação const [profileErrors, setProfileErrors] = useState({}); const [passwordErrors, setPasswordErrors] = useState({}); // Modais const [showFactoryReset, setShowFactoryReset] = useState(false); const [showImportBackup, setShowImportBackup] = useState(false); const [showCancellation, setShowCancellation] = useState(false); // Subscription data const [subscriptionData, setSubscriptionData] = useState(null); useEffect(() => { loadProfile(); loadSubscription(); }, []); const loadProfile = async () => { try { setLoading(true); const response = await profileService.get(); if (response.success) { const user = response.data.user; setProfile({ first_name: user.first_name || '', last_name: user.last_name || '', email: user.email || '', phone_country_code: user.phone_country_code || '+34', phone: user.phone || '', accept_whatsapp: user.accept_whatsapp || false, accept_emails: user.accept_emails !== false, // default true country: user.country || 'ES', timezone: user.timezone || 'Europe/Madrid', locale: user.locale || i18n.language || 'es', }); } } catch (error) { console.error('Error loading profile:', error); showToast(t('profile.loadError'), 'error'); } finally { setLoading(false); } }; const loadSubscription = async () => { try { const response = await subscriptionService.getStatus(); if (response.success) { setSubscriptionData(response.data); } } catch (error) { console.error('Error loading subscription:', error); } }; const handleProfileChange = (field, value) => { setProfile(prev => ({ ...prev, [field]: value, })); // Limpar erro do campo if (profileErrors[field]) { setProfileErrors(prev => ({ ...prev, [field]: null })); } }; const handlePasswordChange = (field, value) => { setPasswordData(prev => ({ ...prev, [field]: value, })); // Limpar erro do campo if (passwordErrors[field]) { setPasswordErrors(prev => ({ ...prev, [field]: null })); } }; const handleSaveProfile = async (e) => { e.preventDefault(); setProfileErrors({}); // Validação básica if (!profile.first_name.trim()) { setProfileErrors({ first_name: [t('profile.firstNameRequired')] }); return; } if (!profile.last_name.trim()) { setProfileErrors({ last_name: [t('profile.lastNameRequired')] }); return; } if (!profile.phone.trim()) { setProfileErrors({ phone: [t('profile.phoneRequired')] }); return; } try { setSavingProfile(true); const response = await profileService.update(profile); if (response.success) { showToast(t('profile.saveSuccess'), 'success'); // Atualizar idioma se mudou if (profile.locale && profile.locale !== i18n.language) { i18n.changeLanguage(profile.locale); } } } catch (error) { console.error('Error saving profile:', error); if (error.response?.data?.errors) { setProfileErrors(error.response.data.errors); } showToast(error.response?.data?.message || t('profile.saveError'), 'error'); } finally { setSavingProfile(false); } }; const handleChangePassword = async (e) => { e.preventDefault(); setPasswordErrors({}); // Validação básica no frontend if (passwordData.new_password !== passwordData.new_password_confirmation) { setPasswordErrors({ new_password_confirmation: [t('profile.passwordMismatch')] }); return; } if (passwordData.new_password.length < 8) { setPasswordErrors({ new_password: [t('profile.passwordTooShort')] }); return; } try { setSavingPassword(true); const response = await profileService.update({ current_password: passwordData.current_password, new_password: passwordData.new_password, new_password_confirmation: passwordData.new_password_confirmation, }); if (response.success) { showToast(t('profile.passwordChanged'), 'success'); // Limpar campos de senha setPasswordData({ current_password: '', new_password: '', new_password_confirmation: '', }); } } catch (error) { console.error('Error changing password:', error); if (error.response?.data?.errors) { setPasswordErrors(error.response.data.errors); } showToast(error.response?.data?.message || t('profile.passwordError'), 'error'); } finally { setSavingPassword(false); } }; if (loading) { return (
{t('profile.subtitle')}
{subscriptionData.plan.formatted_price} / {subscriptionData.plan.billing_period === 'monthly' ? t('common.month') || 'mês' : t('common.year') || 'ano'} ({t('pricing.vatNotIncluded') || '+ IVA'})
{subscriptionData.subscription?.current_period_end && ({t('profile.renewsOn') || 'Renovação em'}: {new Date(subscriptionData.subscription.current_period_end).toLocaleDateString()}
)}{t('profile.importBackupDesc') || 'Restaure dados de um backup anteriormente exportado. Os dados serão adicionados à sua conta.'}
{t('profile.factoryResetDesc') || 'ATENÇÃO: Deleta permanentemente TODOS os seus dados. Esta ação não pode ser desfeita.'}