import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../providers/auth_provider.dart'; /// Sticky banner shown when the backend is unreachable. Surfaces a retry /// action and reserves space for future "last sync X min ago" messaging once /// Tier 2 offline caching lands. class OfflineBanner extends ConsumerStatefulWidget { const OfflineBanner({super.key}); @override ConsumerState createState() => _OfflineBannerState(); } class _OfflineBannerState extends ConsumerState { bool _retrying = false; Future _retry() async { if (_retrying) return; setState(() => _retrying = true); try { await ref.read(authProvider.notifier).verify(); } finally { if (mounted) setState(() => _retrying = false); } } @override Widget build(BuildContext context) { final status = ref.watch(authProvider); if (status != AuthStatus.offline) return const SizedBox.shrink(); final scheme = Theme.of(context).colorScheme; return Material( color: scheme.errorContainer, child: SafeArea( bottom: false, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), child: Row( children: [ Icon(Icons.cloud_off_outlined, size: 18, color: scheme.onErrorContainer), const SizedBox(width: 8), Expanded( child: Text( 'Offline — showing cached data.', style: TextStyle(color: scheme.onErrorContainer), ), ), TextButton( onPressed: _retrying ? null : _retry, style: TextButton.styleFrom( foregroundColor: scheme.onErrorContainer, padding: const EdgeInsets.symmetric(horizontal: 12), ), child: _retrying ? const SizedBox( width: 14, height: 14, child: CircularProgressIndicator(strokeWidth: 2), ) : const Text('Retry'), ), ], ), ), ), ); } }