feat: synchronisation mode deconnecte fin chat et stats

This commit is contained in:
2025-08-31 18:21:20 +02:00
parent f5bef999df
commit 96af94ad13
129 changed files with 125731 additions and 110375 deletions

View File

@@ -0,0 +1,319 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:geosector_app/chat/pages/rooms_page_embedded.dart';
import 'package:geosector_app/chat/chat_module.dart';
import 'package:geosector_app/core/services/chat_manager.dart';
import 'package:geosector_app/core/services/current_user_service.dart';
/// Page de communication adaptative qui s'ajuste selon le rôle de l'utilisateur
/// et la plateforme (Web vs Mobile)
class ChatCommunicationPage extends StatefulWidget {
const ChatCommunicationPage({super.key});
@override
State<ChatCommunicationPage> createState() => _ChatCommunicationPageState();
}
class _ChatCommunicationPageState extends State<ChatCommunicationPage> {
final GlobalKey<RoomsPageEmbeddedState> _roomsPageKey = GlobalKey<RoomsPageEmbeddedState>();
// Récupération du rôle de l'utilisateur
int get _userRole => CurrentUserService.instance.currentUser?.role ?? 1;
String get _userName => CurrentUserService.instance.userName ?? 'Utilisateur';
// Configuration selon le rôle
MaterialColor get _themeColor {
switch (_userRole) {
case 1: return Colors.green; // Membre
case 2: return Colors.red; // Admin Amicale
case 9: return Colors.blue; // Super Admin
default: return Colors.grey;
}
}
Color get _backgroundColor {
switch (_userRole) {
case 1: return Colors.green.shade50;
case 2: return Colors.red.shade50;
case 9: return Colors.blue.shade50;
default: return Colors.grey.shade50;
}
}
String get _pageTitle {
switch (_userRole) {
case 1: return 'Messages';
case 2: return 'Messages Administration';
case 9: return 'Centre de Communication GEOSECTOR';
default: return 'Messages';
}
}
IconData get _roleIcon {
switch (_userRole) {
case 1: return Icons.person;
case 2: return Icons.admin_panel_settings;
case 9: return Icons.shield;
default: return Icons.chat;
}
}
bool get _showStatsButton => _userRole == 9; // Super Admin uniquement
@override
Widget build(BuildContext context) {
// Détection de la plateforme
final isWeb = kIsWeb;
final isMobile = !isWeb;
// Construction adaptative
if (isWeb) {
return _buildWebLayout(context);
} else {
return _buildMobileLayout(context);
}
}
/// Layout pour Web (Desktop)
Widget _buildWebLayout(BuildContext context) {
final theme = Theme.of(context);
return Scaffold(
backgroundColor: Colors.transparent,
body: Container(
margin: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: theme.colorScheme.surface,
borderRadius: BorderRadius.circular(24),
boxShadow: [
BoxShadow(
color: theme.shadowColor.withOpacity(0.1),
blurRadius: 20,
spreadRadius: 1,
offset: const Offset(0, 4),
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(24),
child: _buildContent(theme, isWeb: true),
),
),
);
}
/// Layout pour Mobile (iOS/Android)
Widget _buildMobileLayout(BuildContext context) {
final theme = Theme.of(context);
return Scaffold(
appBar: AppBar(
title: Text(_pageTitle),
backgroundColor: _themeColor,
foregroundColor: Colors.white,
elevation: 2,
actions: _buildAppBarActions(),
),
body: _buildContent(theme, isWeb: false),
floatingActionButton: FloatingActionButton(
onPressed: _handleNewConversation,
backgroundColor: _themeColor,
foregroundColor: Colors.white,
child: const Icon(Icons.add),
tooltip: 'Nouvelle conversation',
),
);
}
/// Contenu principal commun
Widget _buildContent(ThemeData theme, {required bool isWeb}) {
// Vérifier si le chat est initialisé
if (!ChatManager.instance.isReady) {
return Center(
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.chat_bubble_outline,
size: 80,
color: _themeColor.withOpacity(0.3),
),
const SizedBox(height: 24),
Text(
'Module de communication non disponible',
style: theme.textTheme.titleLarge?.copyWith(
color: theme.colorScheme.onSurface.withOpacity(0.5),
),
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
Text(
_getUnavailableMessage(),
style: theme.textTheme.bodyMedium?.copyWith(
color: theme.colorScheme.onSurface.withOpacity(0.4),
),
textAlign: TextAlign.center,
),
if (_userRole == 9) ...[
const SizedBox(height: 16),
ElevatedButton.icon(
onPressed: _handleRetryInit,
icon: const Icon(Icons.refresh),
label: const Text('Réessayer'),
style: ElevatedButton.styleFrom(
backgroundColor: _themeColor,
foregroundColor: Colors.white,
),
),
],
],
),
),
);
}
// Le chat est initialisé
if (isWeb) {
// Version Web avec en-tête personnalisé
return Column(
children: [
_buildWebHeader(theme),
Expanded(
child: RoomsPageEmbedded(
key: _roomsPageKey,
onRefreshPressed: () {
debugPrint('Conversations actualisées');
},
),
),
],
);
} else {
// Version Mobile, contenu direct
return RoomsPageEmbedded(
key: _roomsPageKey,
onRefreshPressed: () {
debugPrint('Conversations actualisées');
},
);
}
}
/// En-tête personnalisé pour Web
Widget _buildWebHeader(ThemeData theme) {
return Container(
height: 60,
padding: const EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(
color: _backgroundColor,
border: Border(
bottom: BorderSide(
color: theme.dividerColor.withOpacity(0.1),
width: 1,
),
),
),
child: Row(
children: [
Icon(
_roleIcon,
color: _themeColor.shade600,
size: 24,
),
const SizedBox(width: 12),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
_pageTitle,
style: theme.textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.w600,
color: _themeColor.shade700,
),
),
if (_userRole == 9)
Text(
'Connecté en tant que $_userName',
style: theme.textTheme.bodySmall?.copyWith(
color: _themeColor.shade600,
),
),
],
),
),
// Boutons d'action
if (_userRole == 9) ...[
// Super Admin : Statistiques
TextButton.icon(
icon: Icon(Icons.analytics, color: _themeColor.shade600),
label: Text(
'Statistiques',
style: TextStyle(color: _themeColor.shade600),
),
onPressed: _handleShowStats,
),
],
],
),
);
}
/// Actions pour l'AppBar mobile
List<Widget> _buildAppBarActions() {
final actions = <Widget>[];
if (_showStatsButton) {
actions.add(
IconButton(
icon: const Icon(Icons.analytics),
onPressed: _handleShowStats,
tooltip: 'Statistiques',
),
);
}
return actions;
}
/// Message personnalisé selon le rôle quand le chat n'est pas disponible
String _getUnavailableMessage() {
switch (_userRole) {
case 1:
return 'Le service de messagerie n\'est pas disponible actuellement.\nVous pourrez bientôt contacter les membres de votre amicale.';
case 2:
return 'Le service de messagerie administration n\'est pas disponible.\nVous pourrez bientôt gérer les communications de votre amicale.';
case 9:
return 'Le centre de communication GEOSECTOR est temporairement indisponible.\nVérifiez la connexion au serveur.';
default:
return 'Le service de messagerie n\'est pas disponible actuellement.';
}
}
/// Gestionnaires d'événements
void _handleNewConversation() {
_roomsPageKey.currentState?.createNewConversation();
}
void _handleShowStats() {
// TODO: Implémenter l'affichage des statistiques pour Super Admin
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text('Statistiques à venir...'),
backgroundColor: _themeColor,
),
);
}
void _handleRetryInit() async {
// Réessayer l'initialisation du chat (pour Super Admin)
await ChatManager.instance.reinitialize();
if (mounted) {
setState(() {});
}
}
}