sync_page.dart 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_riverpod/flutter_riverpod.dart';
  3. import 'package:go_router/go_router.dart';
  4. import '../../../providers/auth_provider.dart';
  5. import '../../../providers/sync_provider.dart';
  6. class SyncPage extends ConsumerStatefulWidget {
  7. const SyncPage({super.key});
  8. @override
  9. ConsumerState<SyncPage> createState() => _SyncPageState();
  10. }
  11. class _SyncPageState extends ConsumerState<SyncPage> {
  12. bool _forceFullSync = false;
  13. @override
  14. Widget build(BuildContext context) {
  15. final authState = ref.watch(authProvider);
  16. final syncState = ref.watch(syncProvider);
  17. final theme = Theme.of(context);
  18. final agente = authState.agente;
  19. return Scaffold(
  20. appBar: AppBar(
  21. title: const Text('Sincronizzazione'),
  22. actions: [
  23. IconButton(
  24. icon: const Icon(Icons.settings),
  25. onPressed: () => context.push('/dashboard/sync/settings'),
  26. ),
  27. ],
  28. ),
  29. body: SafeArea(
  30. child: Center(
  31. child: Padding(
  32. padding: const EdgeInsets.all(32),
  33. child: Column(
  34. mainAxisSize: MainAxisSize.min,
  35. children: [
  36. Icon(
  37. syncState.isSyncing ? Icons.sync : Icons.sync_outlined,
  38. size: 64,
  39. color: syncState.isSyncing
  40. ? theme.colorScheme.primary
  41. : theme.colorScheme.outline,
  42. ),
  43. const SizedBox(height: 24),
  44. Text(
  45. syncState.isSyncing
  46. ? 'Sincronizzazione in corso...'
  47. : 'Sincronizzazione dati',
  48. style: theme.textTheme.titleLarge,
  49. ),
  50. const SizedBox(height: 16),
  51. if (syncState.isSyncing) ...[
  52. LinearProgressIndicator(value: syncState.progress),
  53. const SizedBox(height: 12),
  54. Text(syncState.message, style: theme.textTheme.bodyMedium),
  55. const SizedBox(height: 8),
  56. Text('${(syncState.progress * 100).toInt()}%',
  57. style: theme.textTheme.bodySmall),
  58. ] else if (syncState.error != null) ...[
  59. Card(
  60. color: theme.colorScheme.errorContainer,
  61. child: Padding(
  62. padding: const EdgeInsets.all(12),
  63. child: Text(syncState.error!,
  64. style: TextStyle(
  65. color: theme.colorScheme.onErrorContainer)),
  66. ),
  67. ),
  68. ] else if (syncState.progress >= 1.0) ...[
  69. Icon(Icons.check_circle, size: 48, color: Colors.green),
  70. const SizedBox(height: 8),
  71. const Text('Completato!'),
  72. ],
  73. const SizedBox(height: 12),
  74. CheckboxListTile(
  75. value: _forceFullSync,
  76. onChanged: syncState.isSyncing
  77. ? null
  78. : (v) => setState(() => _forceFullSync = v!),
  79. title: const Text('Sincronizzazione completa'),
  80. subtitle:
  81. const Text('Forza il download completo di tutti i dati'),
  82. controlAffinity: ListTileControlAffinity.leading,
  83. enabled: !syncState.isSyncing,
  84. ),
  85. const SizedBox(height: 12),
  86. FilledButton.icon(
  87. onPressed: syncState.isSyncing || agente == null
  88. ? null
  89. : () => ref.read(syncProvider.notifier).startFullSync(
  90. agente.idAgente,
  91. agente.codAgente!,
  92. forceFullSync: _forceFullSync,
  93. ),
  94. icon: syncState.isSyncing
  95. ? const SizedBox(
  96. width: 20,
  97. height: 20,
  98. child: CircularProgressIndicator(strokeWidth: 2))
  99. : const Icon(Icons.sync),
  100. label: Text(syncState.isSyncing
  101. ? 'In corso...'
  102. : 'Avvia Sincronizzazione'),
  103. ),
  104. ],
  105. ),
  106. ),
  107. ),
  108. ),
  109. );
  110. }
  111. }