import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:relationship_saver/core/config/app_theme.dart'; import 'package:relationship_saver/features/shared/frosted_card.dart'; import 'package:relationship_saver/features/signals/domain/signals_feed_synthesizer.dart'; import 'package:relationship_saver/features/signals/signals_controller.dart'; import 'package:relationship_saver/integrations/backend/models/backend_models.dart'; class SignalsView extends ConsumerWidget { const SignalsView({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final AsyncValue signals = ref.watch( signalsControllerProvider, ); return LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { final bool compact = constraints.maxWidth < 760; return Padding( padding: EdgeInsets.fromLTRB( compact ? 16 : 28, compact ? 16 : 24, compact ? 16 : 28, compact ? 20 : 28, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (compact) Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Signals', style: Theme.of(context).textTheme.headlineMedium, ), const SizedBox(height: 6), Text( 'Local and backend suggestions you can turn into follow-through.', style: Theme.of(context).textTheme.bodyLarge?.copyWith( color: AppTheme.textSecondary, ), ), const SizedBox(height: 10), IconButton.filledTonal( onPressed: () { ref.read(signalsControllerProvider.notifier).refresh(); }, icon: const Icon(Icons.refresh_rounded), tooltip: 'Refresh feed', ), ], ) else Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Signals', style: Theme.of(context).textTheme.headlineMedium, ), const SizedBox(height: 6), Text( 'Local and backend suggestions you can turn into follow-through.', style: Theme.of(context).textTheme.bodyLarge ?.copyWith(color: AppTheme.textSecondary), ), ], ), ), IconButton.filledTonal( onPressed: () { ref.read(signalsControllerProvider.notifier).refresh(); }, icon: const Icon(Icons.refresh_rounded), tooltip: 'Refresh feed', ), ], ), const SizedBox(height: 16), Expanded( child: signals.when( data: (SignalsFeed feed) { if (feed.items.isEmpty) { return const Center(child: Text('No signals right now.')); } return ListView.separated( itemCount: feed.items.length, separatorBuilder: (_, _) => const SizedBox(height: 12), itemBuilder: (BuildContext context, int index) { final SignalItem item = feed.items[index]; return FrostedCard( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( padding: const EdgeInsets.symmetric( horizontal: 10, vertical: 6, ), decoration: BoxDecoration( color: const Color(0xFFEAF8FB), borderRadius: BorderRadius.circular(99), ), child: Text( item.type.toUpperCase(), style: Theme.of(context) .textTheme .labelMedium ?.copyWith( color: AppTheme.primary, fontWeight: FontWeight.w700, ), ), ), const Spacer(), Text( '${item.createdAt.month}/${item.createdAt.day}', style: Theme.of(context).textTheme.bodySmall ?.copyWith( color: AppTheme.textSecondary, ), ), ], ), const SizedBox(height: 12), Text( item.title, style: Theme.of(context).textTheme.titleLarge, ), if (item.description case final String description) Padding( padding: const EdgeInsets.only(top: 6), child: Text( description, style: Theme.of(context).textTheme.bodyLarge ?.copyWith( color: AppTheme.textSecondary, ), ), ), if (item.metadata?[signalMetadataPersonNameKey] case final String personName) Padding( padding: const EdgeInsets.only(top: 8), child: Text( personName, style: Theme.of(context) .textTheme .labelLarge ?.copyWith( color: AppTheme.textSecondary, ), ), ), const SizedBox(height: 14), Wrap( spacing: 8, runSpacing: 6, children: [ OutlinedButton.icon( onPressed: () { ref .read( signalsControllerProvider.notifier, ) .acknowledge( item.id, SignalAction.saved, ); }, icon: Icon(_primaryActionIcon(item)), label: Text(_primaryActionLabel(item)), ), TextButton.icon( onPressed: () { ref .read( signalsControllerProvider.notifier, ) .acknowledge( item.id, SignalAction.dismissed, ); }, icon: const Icon(Icons.close_rounded), label: const Text('Dismiss'), ), ], ), ], ), ); }, ); }, error: (Object error, StackTrace stackTrace) { return Center( child: Text( 'Unable to load signals. Try refresh.', style: Theme.of(context).textTheme.bodyLarge, ), ); }, loading: () => const Center(child: CircularProgressIndicator()), ), ), ], ), ); }, ); } } String _primaryActionLabel(SignalItem item) { if (item.metadata?[signalMetadataActionKey] == createReminderSignalAction) { return 'Create Reminder'; } return 'Save'; } IconData _primaryActionIcon(SignalItem item) { if (item.metadata?[signalMetadataActionKey] == createReminderSignalAction) { return Icons.notifications_active_outlined; } return Icons.bookmark_add_outlined; }