Atualização geral de optimazação e desing
This commit is contained in:
212
lib/screens/settings_screen.dart
Normal file
212
lib/screens/settings_screen.dart
Normal file
@@ -0,0 +1,212 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../main.dart' show supabase;
|
||||
import '../widgets/app_dialogs.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<SettingsBody> createState() => _SettingsBodyState();
|
||||
}
|
||||
|
||||
class _SettingsBodyState extends State<SettingsBody> {
|
||||
bool _deletingAccount = false;
|
||||
|
||||
Future<void> _signOut() async {
|
||||
await supabase.auth.signOut();
|
||||
if (!mounted) return;
|
||||
Navigator.of(context).popUntil((route) => route.isFirst);
|
||||
}
|
||||
|
||||
Future<void> _confirmDeleteAccountData() async {
|
||||
final messenger = ScaffoldMessenger.of(context);
|
||||
final confirmed = await showConfirmDialog(
|
||||
context,
|
||||
title: 'Apagar dados da conta',
|
||||
message:
|
||||
'Isso remove permanentemente seu perfil, crianças cadastradas e '
|
||||
'fotos. Essa ação não pode ser desfeita. Deseja continuar?',
|
||||
confirmLabel: 'Apagar',
|
||||
confirmColor: _accentPink,
|
||||
);
|
||||
|
||||
if (confirmed != true) return;
|
||||
|
||||
final uid = supabase.auth.currentUser?.id;
|
||||
if (uid == null) return;
|
||||
|
||||
setState(() => _deletingAccount = true);
|
||||
try {
|
||||
await supabase.from('children').delete().eq('owner_id', uid);
|
||||
await supabase.from('profiles').delete().eq('id', uid);
|
||||
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: [
|
||||
_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),
|
||||
_SectionLabel('Sobre'),
|
||||
_SettingsCard(
|
||||
children: [
|
||||
_ActionTile(
|
||||
icon: Icons.description_outlined,
|
||||
title: 'Termos de Serviço',
|
||||
onTap: () => Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(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),
|
||||
_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<Widget> 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 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,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user