/// Page dédiée aux paramètres de langue /// Permet de changer la langue de l'interface et la région library language_settings_page; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../../../core/l10n/locale_provider.dart'; import '../../../../shared/design_system/unionflow_design_system.dart'; class LanguageSettingsPage extends StatefulWidget { const LanguageSettingsPage({super.key}); @override State createState() => _LanguageSettingsPageState(); } class _LanguageSettingsPageState extends State { String _selectedLanguage = 'Français'; static const _supportedLanguages = [ _LanguageOption('Français', 'fr', '🇫🇷', 'Langue par défaut'), _LanguageOption('English', 'en', '🇬🇧', 'Default language'), ]; @override void didChangeDependencies() { super.didChangeDependencies(); _syncFromProvider(); } void _syncFromProvider() { final lp = context.read(); if (lp.currentLanguageName != _selectedLanguage) { setState(() => _selectedLanguage = lp.currentLanguageName); } } Future _changeLanguage(String languageName, String code) async { final lp = context.read(); await lp.setLocale(Locale(code)); if (mounted) { setState(() => _selectedLanguage = languageName); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Langue changée en $languageName'), backgroundColor: const Color(0xFF00B894), behavior: SnackBarBehavior.floating, ), ); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF8F9FA), body: Column( children: [ _buildHeader(), Expanded( child: SingleChildScrollView( padding: const EdgeInsets.all(12), child: Column( children: [ const SizedBox(height: 16), _buildLanguageList(), const SizedBox(height: 16), _buildInfoSection(), const SizedBox(height: 80), ], ), ), ), ], ), ); } Widget _buildHeader() { return Container( margin: const EdgeInsets.all(SpacingTokens.lg), padding: const EdgeInsets.all(SpacingTokens.xxl), decoration: BoxDecoration( gradient: const LinearGradient( colors: ColorTokens.primaryGradient, begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(SpacingTokens.xl), boxShadow: [ BoxShadow( color: ColorTokens.primary.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(12), decoration: BoxDecoration( color: Colors.white.withOpacity(0.2), borderRadius: BorderRadius.circular(12), ), child: const Icon(Icons.language, color: Colors.white, size: 24), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Langue', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white, ), ), Text( 'Langue actuelle : $_selectedLanguage', style: TextStyle( fontSize: 14, color: Colors.white.withOpacity(0.8), ), ), ], ), ), ], ), ), ); } Widget _buildLanguageList() { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(Icons.translate, color: Colors.grey[600], size: 20), const SizedBox(width: 8), Text( 'Langues disponibles', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: Colors.grey[800], ), ), ], ), const SizedBox(height: 16), ..._supportedLanguages.map((lang) => _buildLanguageTile(lang)), ], ), ); } Widget _buildLanguageTile(_LanguageOption lang) { final isSelected = _selectedLanguage == lang.name; return Padding( padding: const EdgeInsets.only(bottom: 8), child: InkWell( onTap: () => _changeLanguage(lang.name, lang.code), borderRadius: BorderRadius.circular(12), child: Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: isSelected ? ColorTokens.primary.withOpacity(0.08) : Colors.grey[50], borderRadius: BorderRadius.circular(12), border: isSelected ? Border.all(color: ColorTokens.primary.withOpacity(0.4), width: 1.5) : Border.all(color: Colors.grey[200]!), ), child: Row( children: [ Text(lang.flag, style: const TextStyle(fontSize: 28)), const SizedBox(width: 14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( lang.name, style: TextStyle( fontSize: 15, fontWeight: FontWeight.w600, color: isSelected ? ColorTokens.primary : const Color(0xFF1F2937), ), ), Text( lang.description, style: TextStyle(fontSize: 12, color: Colors.grey[600]), ), ], ), ), if (isSelected) const Icon(Icons.check_circle, color: ColorTokens.primary, size: 22), ], ), ), ), ); } Widget _buildInfoSection() { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(Icons.info_outline, color: Colors.grey[600], size: 20), const SizedBox(width: 8), Text( 'Information', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: Colors.grey[800], ), ), ], ), const SizedBox(height: 12), Text( 'Le changement de langue s\'applique immédiatement à toute l\'interface. ' 'Les contenus générés par le serveur restent dans leur langue d\'origine.', style: TextStyle(fontSize: 13, color: Colors.grey[600], height: 1.5), ), ], ), ); } } class _LanguageOption { final String name; final String code; final String flag; final String description; const _LanguageOption(this.name, this.code, this.flag, this.description); }