import 'package:flutter/material.dart'; import '../colors/app_colors.dart'; import '../main.dart' show supabase; import '../strings/settings_strings.dart'; import '../widgets/app_dialogs.dart'; import '../widgets/entrance.dart'; import '../widgets/pill_snackbar.dart'; import '../widgets/tap_bounce.dart'; import 'credits_screen.dart'; import 'terms_screen.dart'; const Color _teal = AppColors.teal; const Color _accentPink = AppColors.pink; /// 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 confirmed = await showConfirmDialog( context, title: SettingsStrings.deleteAccountData, message: SettingsStrings.deleteAccountMessage, confirmLabel: SettingsStrings.delete, 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 ?? SettingsStrings.errorDeletingAccount(response.status), ); } await supabase.auth.signOut(); if (!mounted) return; Navigator.of(context).popUntil((route) => route.isFirst); } catch (e) { if (mounted) showPillSnackBar(context, SettingsStrings.errorDeleting(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(SettingsStrings.account), _SettingsCard( children: [ _InfoTile( icon: Icons.person_outline_rounded, title: name.isEmpty ? SettingsStrings.noName : name, subtitle: email, ), const Divider(height: 1), _ActionTile( icon: Icons.logout_rounded, title: SettingsStrings.signOut, onTap: _signOut, ), ], ), ], ), ), const SizedBox(height: 20), FadeSlideIn( delay: const Duration(milliseconds: 80), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _SectionLabel(SettingsStrings.about), _SettingsCard( children: [ _ActionTile( icon: Icons.description_outlined, title: SettingsStrings.termsOfService, onTap: () => Navigator.of(context).push( MaterialPageRoute( builder: (_) => const TermsScreen(), ), ), ), const Divider(height: 1), _ActionTile( icon: Icons.diversity_3_outlined, title: SettingsStrings.creatorsAndContributors, onTap: () => Navigator.of(context).push( MaterialPageRoute( builder: (_) => const CreditsScreen(), ), ), ), const Divider(height: 1), const _InfoTile( icon: Icons.info_outline_rounded, title: SettingsStrings.appVersion, subtitle: '1.0.0', ), ], ), ], ), ), const SizedBox(height: 20), FadeSlideIn( delay: const Duration(milliseconds: 160), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _SectionLabel(SettingsStrings.dangerZone), _SettingsCard( children: [ _ActionTile( icon: Icons.delete_forever_rounded, title: SettingsStrings.deleteAccountData, 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, ), ); } }