/// Page dédiée aux paramètres de confidentialité /// Gestion du profil public, partage de données, et suppression de compte library privacy_settings_page; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../../../shared/design_system/unionflow_design_system.dart'; class PrivacySettingsPage extends StatefulWidget { const PrivacySettingsPage({super.key}); @override State createState() => _PrivacySettingsPageState(); } class _PrivacySettingsPageState extends State { bool _profilePublic = false; bool _shareAnalytics = true; bool _showOnlineStatus = true; bool _allowSearchByEmail = true; static const String _keyProfilePublic = 'profile_public'; static const String _keyShareAnalytics = 'share_analytics'; static const String _keyShowOnlineStatus = 'show_online_status'; static const String _keyAllowSearchByEmail = 'allow_search_by_email'; @override void initState() { super.initState(); _loadPreferences(); } Future _loadPreferences() async { final prefs = await SharedPreferences.getInstance(); if (mounted) { setState(() { _profilePublic = prefs.getBool(_keyProfilePublic) ?? false; _shareAnalytics = prefs.getBool(_keyShareAnalytics) ?? true; _showOnlineStatus = prefs.getBool(_keyShowOnlineStatus) ?? true; _allowSearchByEmail = prefs.getBool(_keyAllowSearchByEmail) ?? true; }); } } Future _savePreference(String key, bool value) async { final prefs = await SharedPreferences.getInstance(); await prefs.setBool(key, value); } void _showSnackBar(String message) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(message), backgroundColor: AppColors.success, behavior: SnackBarBehavior.floating, ), ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Theme.of(context).scaffoldBackgroundColor, body: SafeArea( top: false, child: Column( children: [ _buildHeader(), Expanded( child: SingleChildScrollView( padding: const EdgeInsets.all(12), child: Column( children: [ const SizedBox(height: 8), _buildVisibilitySection(), const SizedBox(height: 8), _buildDataSection(), const SizedBox(height: 8), _buildDangerSection(), const SizedBox(height: 80), ], ), ), ), ], ), ), ); } Widget _buildHeader() { return Container( margin: const EdgeInsets.all(SpacingTokens.lg), padding: const EdgeInsets.all(SpacingTokens.xxl), decoration: BoxDecoration( gradient: LinearGradient( colors: ModuleColors.parametresGradient, begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(SpacingTokens.xl), boxShadow: [ BoxShadow( color: ModuleColors.parametres.withOpacity(0.3), blurRadius: 20, offset: const Offset(0, 8), ), ], ), child: SafeArea( bottom: false, child: Row( children: [ IconButton( onPressed: () => Navigator.of(context).pop(), icon: const Icon(Icons.arrow_back, color: Colors.white), ), Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.white.withOpacity(0.2), borderRadius: BorderRadius.circular(8), ), child: const Icon(Icons.privacy_tip, color: Colors.white, size: 20), ), const SizedBox(width: 16), const Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Confidentialité', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white, ), ), Text( 'Contrôler la visibilité de vos données', style: TextStyle( fontSize: 14, color: Colors.white70, ), ), ], ), ), ], ), ), ); } Widget _buildVisibilitySection() { return _buildSection( 'Visibilité du profil', 'Qui peut voir vos informations', Icons.visibility, [ _buildSwitchTile( 'Profil public', 'Permettre aux autres membres de voir votre profil', _profilePublic, (value) async { setState(() => _profilePublic = value); await _savePreference(_keyProfilePublic, value); _showSnackBar(value ? 'Profil public activé' : 'Profil public désactivé'); }, ), _buildSwitchTile( 'Statut en ligne', 'Afficher quand vous êtes connecté', _showOnlineStatus, (value) async { setState(() => _showOnlineStatus = value); await _savePreference(_keyShowOnlineStatus, value); _showSnackBar(value ? 'Statut en ligne visible' : 'Statut en ligne masqué'); }, ), _buildSwitchTile( 'Recherche par email', 'Permettre de vous trouver via votre adresse email', _allowSearchByEmail, (value) async { setState(() => _allowSearchByEmail = value); await _savePreference(_keyAllowSearchByEmail, value); _showSnackBar(value ? 'Recherche par email activée' : 'Recherche par email désactivée'); }, ), ], ); } Widget _buildDataSection() { return _buildSection( 'Données et analyses', 'Utilisation de vos données', Icons.analytics, [ _buildSwitchTile( 'Partage de données anonymes', 'Aider à améliorer l\'application avec des statistiques d\'usage anonymisées', _shareAnalytics, (value) async { setState(() => _shareAnalytics = value); await _savePreference(_keyShareAnalytics, value); _showSnackBar(value ? 'Partage de données activé' : 'Partage de données désactivé'); }, ), ], ); } Widget _buildDangerSection() { return _buildSection( 'Zone sensible', 'Actions irréversibles', Icons.warning_amber, [ InkWell( onTap: _showDeleteAccountDialog, borderRadius: BorderRadius.circular(8), child: Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 7), decoration: BoxDecoration( color: AppColors.error.withOpacity(0.05), borderRadius: BorderRadius.circular(8), border: Border.all(color: AppColors.error.withOpacity(0.2)), ), child: Row( children: [ const Icon(Icons.delete_forever, color: AppColors.error, size: 20), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Supprimer mon compte', style: TextStyle( fontSize: 14, fontWeight: FontWeight.w600, color: AppColors.error, ), ), Builder( builder: (ctx) { final isDark = Theme.of(ctx).brightness == Brightness.dark; return Text( 'Supprimer définitivement toutes vos données', style: AppTypography.subtitleSmall.copyWith( color: isDark ? AppColors.textSecondaryDark : AppColors.textSecondary, ), ); }, ), ], ), ), const Icon(Icons.arrow_forward_ios, color: AppColors.error, size: 16), ], ), ), ), ], ); } void _showDeleteAccountDialog() { showDialog( context: context, builder: (context) => AlertDialog( title: const Row( children: [ Icon(Icons.warning, color: AppColors.error), SizedBox(width: 8), Text('Supprimer le compte'), ], ), content: const Text( 'Cette action est irréversible. Toutes vos données seront supprimées définitivement.\n\n' 'Pour confirmer, veuillez contacter l\'administrateur de votre organisation.', ), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), child: const Text('Annuler'), ), ElevatedButton( onPressed: () async { Navigator.of(context).pop(); final uri = Uri.parse('mailto:support@unionflow.com?subject=Demande de suppression de compte'); if (await canLaunchUrl(uri)) { await launchUrl(uri, mode: LaunchMode.externalApplication); } }, style: ElevatedButton.styleFrom(backgroundColor: AppColors.error), child: const Text('Contacter l\'administrateur', style: TextStyle(color: AppColors.onPrimary)), ), ], ), ); } Widget _buildSection(String title, String subtitle, IconData icon, List children) { final isDark = Theme.of(context).brightness == Brightness.dark; final textPrimary = isDark ? AppColors.textPrimaryDark : AppColors.textPrimary; final textSecondary = isDark ? AppColors.textSecondaryDark : AppColors.textSecondary; return Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: isDark ? AppColors.surfaceDark : AppColors.surface, borderRadius: BorderRadius.circular(10), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(icon, color: textSecondary, size: 20), const SizedBox(width: 8), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: AppTypography.headerSmall.copyWith(fontWeight: FontWeight.w600, color: textPrimary), ), Text( subtitle, style: AppTypography.subtitleSmall.copyWith(color: textSecondary), ), ], ), ), ], ), const SizedBox(height: 8), ...children.map((child) => Padding( padding: const EdgeInsets.only(bottom: 6), child: child, )), ], ), ); } Widget _buildSwitchTile( String title, String subtitle, bool value, ValueChanged onChanged, ) { final isDark = Theme.of(context).brightness == Brightness.dark; final textPrimary = isDark ? AppColors.textPrimaryDark : AppColors.textPrimary; final textSecondary = isDark ? AppColors.textSecondaryDark : AppColors.textSecondary; return Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 7), decoration: BoxDecoration( color: isDark ? AppColors.backgroundSubtleDark : AppColors.backgroundSubtle, borderRadius: BorderRadius.circular(8), ), child: Row( children: [ const Icon(Icons.toggle_on, color: AppColors.primary, size: 20), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: AppTypography.bodyTextSmall.copyWith(fontWeight: FontWeight.w600, color: textPrimary), ), Text( subtitle, style: AppTypography.subtitleSmall.copyWith(color: textSecondary), ), ], ), ), Switch( value: value, onChanged: onChanged, activeTrackColor: AppColors.primary, thumbColor: WidgetStateProperty.resolveWith((states) => states.contains(WidgetState.selected) ? Colors.white : null), ), ], ), ); } }