import 'package:flutter/material.dart'; import '../main.dart' show supabase; import '../widgets/app_dialogs.dart'; import '../widgets/entrance.dart'; import '../widgets/tap_bounce.dart'; import 'terms_screen.dart'; const Color _teal = Color(0xFF2F9E94); const Color _accentPink = Color(0xFFFF55A7); /// Conteúdo da aba de Configurações, para ser embutido na bottom navigation /// do LoggedHomeScreen (sem Scaffold/AppBar próprios). class SettingsBody extends StatefulWidget { const SettingsBody({super.key}); @override State createState() => _SettingsBodyState(); } class _SettingsBodyState extends State { bool _deletingAccount = false; Future _signOut() async { await supabase.auth.signOut(); if (!mounted) return; Navigator.of(context).popUntil((route) => route.isFirst); } Future _confirmDeleteAccountData() async { final messenger = ScaffoldMessenger.of(context); final confirmed = await showConfirmDialog( context, title: 'Apagar dados da conta', message: 'Isso remove permanentemente a sua conta, perfil, crianças ' 'cadastradas e fotos — incluindo o login, permitindo criar uma ' 'nova conta com o mesmo e-mail depois. Essa ação não pode ser ' 'desfeita. Deseja continuar?', confirmLabel: 'Apagar', confirmColor: _accentPink, ); if (confirmed != true) return; setState(() => _deletingAccount = true); try { // A remoção de `auth.users` exige a service role key, que o app nunca // deve carregar — por isso corre numa Edge Function (server-side); ver // supabase/functions/delete-account. Sem isto, apagar só as linhas de // `profiles`/`children` deixava o e-mail "ocupado" no Supabase Auth, // impedindo criar uma nova conta com o mesmo e-mail. final response = await supabase.functions.invoke('delete-account'); final data = response.data; final errorMessage = (data is Map) ? data['error']?.toString() : null; if (response.status != 200 || errorMessage != null) { throw StateError( errorMessage ?? 'Erro ao apagar conta (status ${response.status})', ); } await supabase.auth.signOut(); if (!mounted) return; Navigator.of(context).popUntil((route) => route.isFirst); } catch (e) { messenger.showSnackBar(SnackBar(content: Text('Erro ao apagar: $e'))); } finally { if (mounted) setState(() => _deletingAccount = false); } } @override Widget build(BuildContext context) { final user = supabase.auth.currentUser; final name = (user?.userMetadata?['name'] ?? '').toString().trim(); final email = (user?.email ?? '').trim(); return ListView( padding: const EdgeInsets.all(16), children: [ FadeSlideIn( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _SectionLabel('Conta'), _SettingsCard( children: [ _InfoTile( icon: Icons.person_outline_rounded, title: name.isEmpty ? 'Sem nome' : name, subtitle: email, ), const Divider(height: 1), _ActionTile( icon: Icons.logout_rounded, title: 'Sair', onTap: _signOut, ), ], ), ], ), ), const SizedBox(height: 20), FadeSlideIn( delay: const Duration(milliseconds: 80), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _SectionLabel('Sobre'), _SettingsCard( children: [ _ActionTile( icon: Icons.description_outlined, title: 'Termos de Serviço', onTap: () => Navigator.of(context).push( MaterialPageRoute( builder: (_) => const TermsScreen(), ), ), ), const Divider(height: 1), const _InfoTile( icon: Icons.info_outline_rounded, title: 'Versão do app', subtitle: '1.0.0', ), ], ), ], ), ), const SizedBox(height: 20), FadeSlideIn( delay: const Duration(milliseconds: 160), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _SectionLabel('Zona de risco'), _SettingsCard( children: [ _ActionTile( icon: Icons.delete_forever_rounded, title: 'Apagar dados da conta', titleColor: _accentPink, loading: _deletingAccount, onTap: _deletingAccount ? null : _confirmDeleteAccountData, ), ], ), ], ), ), const SizedBox(height: 12), ], ); } } class _SectionLabel extends StatelessWidget { const _SectionLabel(this.text); final String text; @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.only(left: 4, bottom: 8), child: Text( text, style: const TextStyle( color: _teal, fontWeight: FontWeight.w900, fontSize: 14, ), ), ); } } class _SettingsCard extends StatelessWidget { const _SettingsCard({required this.children}); final List children; @override Widget build(BuildContext context) { return Material( color: Colors.white, borderRadius: BorderRadius.circular(18), elevation: 6, shadowColor: Colors.black.withValues(alpha: 0.12), child: Column(children: children), ); } } class _InfoTile extends StatelessWidget { const _InfoTile({required this.icon, required this.title, this.subtitle}); final IconData icon; final String title; final String? subtitle; @override Widget build(BuildContext context) { return ListTile( leading: Icon(icon, color: _teal), title: Text(title, style: const TextStyle(fontWeight: FontWeight.w800)), subtitle: (subtitle == null || subtitle!.isEmpty) ? null : Text(subtitle!), ); } } class _ActionTile extends StatelessWidget { const _ActionTile({ required this.icon, required this.title, required this.onTap, this.titleColor, this.loading = false, }); final IconData icon; final String title; final VoidCallback? onTap; final Color? titleColor; final bool loading; @override Widget build(BuildContext context) { return TapBounce( scale: 0.98, child: ListTile( leading: Icon(icon, color: titleColor ?? _teal), title: Text( title, style: TextStyle(fontWeight: FontWeight.w800, color: titleColor), ), trailing: loading ? const SizedBox( width: 18, height: 18, child: CircularProgressIndicator(strokeWidth: 2), ) : const Icon(Icons.chevron_right_rounded), onTap: onTap, ), ); } }