import 'package:flutter/material.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:image_picker/image_picker.dart'; import 'dart:io'; import '../login/login_screen.dart'; class PerfilScreen extends StatefulWidget { const PerfilScreen({super.key}); @override State createState() => _PerfilScreenState(); } class _PerfilScreenState extends State { final ImagePicker _imagePicker = ImagePicker(); String? _avatarUrl; String _nome = ''; String _email = ''; bool _isLoading = true; @override void initState() { super.initState(); _loadUserData(); } Future _loadUserData() async { try { final user = Supabase.instance.client.auth.currentUser; if (user != null) { setState(() { _email = user.email ?? ''; }); // Fetch user data from users table final response = await Supabase.instance.client .from('users') .select() .eq('id', user.id) .single(); setState(() { _nome = response['nome'] ?? ''; _avatarUrl = response['avatar_url']; }); } } catch (e) { print('Error loading user data: $e'); } finally { setState(() => _isLoading = false); } } Future _pickImage() async { try { final XFile? image = await _imagePicker.pickImage( source: ImageSource.gallery, maxWidth: 512, maxHeight: 512, imageQuality: 75, ); if (image != null) { await _uploadImage(image); } } catch (e) { _showErrorSnackBar('Erro ao selecionar imagem: $e'); } } Future _uploadImage(XFile image) async { final user = Supabase.instance.client.auth.currentUser; if (user == null) { _showErrorSnackBar('Usuário não autenticado'); return; } setState(() => _isLoading = true); try { final file = File(image.path); final fileName = '${user.id}_${DateTime.now().millisecondsSinceEpoch}.jpg'; // Upload to Supabase Storage await Supabase.instance.client.storage .from('avatars') .upload(fileName, file); // Get public URL final imageUrl = Supabase.instance.client.storage .from('avatars') .getPublicUrl(fileName); // Update user's avatar_url in database await Supabase.instance.client .from('users') .update({'avatar_url': imageUrl}) .eq('id', user.id); setState(() { _avatarUrl = imageUrl; }); _showSuccessSnackBar('Foto atualizada com sucesso!'); } catch (e) { _showErrorSnackBar('Erro ao fazer upload: $e'); } finally { setState(() => _isLoading = false); } } Future _logout() async { try { await Supabase.instance.client.auth.signOut(); if (mounted) { Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute(builder: (_) => const LoginScreen()), (route) => false, ); } } catch (e) { _showErrorSnackBar('Erro ao sair: $e'); } } void _showErrorSnackBar(String message) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(message), backgroundColor: Colors.red), ); } void _showSuccessSnackBar(String message) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(message), backgroundColor: Colors.green), ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFFFE5CC), appBar: AppBar( backgroundColor: const Color(0xFF0066CC), elevation: 0, title: const Text( 'Perfil', style: TextStyle(color: Colors.white, fontSize: 20), ), centerTitle: true, ), body: _isLoading ? const Center(child: CircularProgressIndicator()) : SingleChildScrollView( padding: const EdgeInsets.all(20), child: Column( children: [ const SizedBox(height: 20), // Avatar section GestureDetector( onTap: _pickImage, child: Stack( children: [ Container( width: 120, height: 120, decoration: BoxDecoration( color: Colors.white, shape: BoxShape.circle, border: Border.all( color: const Color(0xFF0066CC), width: 3, ), ), child: _avatarUrl != null ? ClipOval( child: Image.network( _avatarUrl!, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return const Icon( Icons.person, size: 60, color: Color(0xFFCCCCCC), ); }, ), ) : const Icon( Icons.person, size: 60, color: Color(0xFFCCCCCC), ), ), Positioned( bottom: 0, right: 0, child: Container( padding: const EdgeInsets.all(8), decoration: const BoxDecoration( color: Color(0xFF0066CC), shape: BoxShape.circle, ), child: const Icon( Icons.camera_alt, color: Colors.white, size: 20, ), ), ), ], ), ), const SizedBox(height: 20), // Name section Container( width: double.infinity, padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: const Color(0xFFE0E0E0)), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Nome', style: TextStyle( fontSize: 14, color: Color(0xFF666666), fontWeight: FontWeight.w500, ), ), const SizedBox(height: 8), Text( _nome.isNotEmpty ? _nome : 'Não definido', style: const TextStyle( fontSize: 18, color: Color(0xFF333333), fontWeight: FontWeight.bold, ), ), ], ), ), const SizedBox(height: 16), // Email section Container( width: double.infinity, padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: const Color(0xFFE0E0E0)), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Email', style: TextStyle( fontSize: 14, color: Color(0xFF666666), fontWeight: FontWeight.w500, ), ), const SizedBox(height: 8), Text( _email, style: const TextStyle( fontSize: 18, color: Color(0xFF333333), fontWeight: FontWeight.bold, ), ), ], ), ), const SizedBox(height: 32), // Logout button SizedBox( width: double.infinity, height: 56, child: ElevatedButton( onPressed: _logout, style: ElevatedButton.styleFrom( backgroundColor: Colors.red, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), elevation: 0, ), child: const Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.logout, color: Colors.white), SizedBox(width: 8), Text( 'Sair da Conta', style: TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.w600, ), ), ], ), ), ), const SizedBox(height: 20), ], ), ), ); } }