import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:mobdr/service/shared_prefs.dart'; class SynchronizationPage extends StatefulWidget { @override _SynchronizationPageState createState() => _SynchronizationPageState(); } class _SynchronizationPageState extends State with SingleTickerProviderStateMixin { late AnimationController _animationController; late Animation _rotationAnimation; bool _isSyncing = false; bool _syncCompleted = false; bool _backofficeSyncCompleted = false; bool _photosSyncCompleted = false; bool _logSyncCompleted = false; @override void initState() { super.initState(); _animationController = AnimationController( vsync: this, duration: Duration(seconds: 2), ); _rotationAnimation = Tween(begin: 0, end: 1).animate(_animationController); } @override void dispose() { _animationController.dispose(); super.dispose(); } void startSync() { setState(() { _isSyncing = true; _syncCompleted = false; _backofficeSyncCompleted = false; _photosSyncCompleted = false; _logSyncCompleted = false; }); _animationController.repeat(); // Simulation d'une tâche de synchronisation Future.delayed(const Duration(seconds: 3), () { SharedPrefs().lastCalendarRefresh = DateFormat('dd/MM/yyyy HH:mm').format(DateTime.now()); setState(() { _isSyncing = false; _syncCompleted = true; _backofficeSyncCompleted = true; _photosSyncCompleted = false; _logSyncCompleted = false; }); _animationController.stop(); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Data synchronization'), ), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ SizedBox(height: 20), Center( child: Container( width: 100, height: 100, decoration: BoxDecoration( shape: BoxShape.circle, color: Colors.blue, ), child: IconButton( icon: AnimatedBuilder( animation: _animationController, builder: (BuildContext context, Widget? child) { return Transform.rotate( angle: _rotationAnimation.value * 2.0 * 3.14, child: Icon( Icons.refresh, color: Colors.white, size: 80, ), ); }, ), onPressed: _isSyncing ? null : startSync, ), ), ), SizedBox(height: 20), Text( SharedPrefs().lastCalendarRefresh.isNotEmpty ? SharedPrefs().lastCalendarRefresh : "Never", style: TextStyle(fontSize: 16), textAlign: TextAlign.center, ), SizedBox(height: 40), SyncItem( icon: Icons.business, title: 'Backoffice', description: 'Synchronisation des données du backoffice', isSyncing: _isSyncing, syncCompleted: _syncCompleted, isError: _syncCompleted && !_backofficeSyncCompleted, ), SizedBox(height: 20), SyncItem( icon: Icons.photo, title: 'Photos', description: 'Synchronisation des photos', isSyncing: _isSyncing, syncCompleted: _syncCompleted, isError: _syncCompleted && !_photosSyncCompleted, ), SizedBox(height: 20), SyncItem( icon: Icons.warning, title: 'Log', description: 'Synchronisation des journaux d\'activité', isSyncing: _isSyncing, syncCompleted: _syncCompleted, isError: _syncCompleted && !_logSyncCompleted, ), ], ), ), ); } } class SyncItem extends StatelessWidget { final IconData icon; final String title; final String description; final bool isSyncing; final bool syncCompleted; final bool isError; const SyncItem({ required this.icon, required this.title, required this.description, required this.isSyncing, required this.syncCompleted, required this.isError, }); @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( icon, color: Colors.blue, size: 24, ), SizedBox(width: 10), Text( title, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), ], ), SizedBox(height: 10), Text(description), SizedBox(height: 10), if (isSyncing) LinearProgressIndicator( backgroundColor: Colors.grey[300], valueColor: AlwaysStoppedAnimation(Colors.blue), ), if (syncCompleted) Row( children: [ Icon( isError ? Icons.error_outline : Icons.check, color: isError ? Colors.red : Colors.green, size: 20, ), SizedBox(width: 10), Text( isError ? 'Erreur de synchronisation' : 'Synchronisation terminée', style: TextStyle( color: isError ? Colors.red : Colors.green, fontWeight: FontWeight.bold, ), ), ], ), ], ); } }