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/local/local_models.dart'; import 'package:relationship_saver/features/local/local_repository.dart'; import 'package:relationship_saver/features/shared/frosted_card.dart'; class DashboardView extends ConsumerWidget { const DashboardView({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final AsyncValue localData = ref.watch( localRepositoryProvider, ); return localData.when( data: (LocalDataState data) { final DashboardSummary summary = data.summary(); final List tasks = data.tasks; return LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { final bool compact = constraints.maxWidth < 720; return SingleChildScrollView( padding: EdgeInsets.fromLTRB( compact ? 16 : 28, compact ? 16 : 24, compact ? 16 : 28, compact ? 24 : 36, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Today', style: Theme.of(context).textTheme.headlineMedium, ), const SizedBox(height: 8), Text( 'Focus on consistency over intensity. Small moments compound.', style: Theme.of(context).textTheme.bodyLarge?.copyWith( color: AppTheme.textSecondary, ), ), const SizedBox(height: 22), Wrap( spacing: 12, runSpacing: 12, children: [ _StatCard( label: 'Active People', value: '${summary.activePeople}', accent: const Color(0xFF16B8CA), compact: compact, ), _StatCard( label: 'Upcoming Plans', value: '${summary.upcomingPlans}', accent: const Color(0xFF2B7FFF), compact: compact, ), _StatCard( label: 'Pending Ideas', value: '${summary.pendingIdeas}', accent: const Color(0xFFFFA447), compact: compact, ), _StatCard( label: 'Weekly Rhythm', value: '${summary.weeklyConsistency}%', accent: const Color(0xFF30B66A), compact: compact, ), ], ), const SizedBox(height: 24), FrostedCard( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Next Moves', style: Theme.of(context).textTheme.titleLarge, ), const SizedBox(height: 14), ...tasks.map( (DashboardTask task) => _TaskRow( task: task, compact: compact, onToggleDone: () { ref .read(localRepositoryProvider.notifier) .toggleTaskDone(task.id); }, ), ), ], ), ), ], ), ); }, ); }, loading: () => const Center(child: CircularProgressIndicator()), error: (Object error, StackTrace stackTrace) { return Center( child: Text( 'Could not load local data.', style: Theme.of(context).textTheme.bodyLarge, ), ); }, ); } } class _StatCard extends StatelessWidget { const _StatCard({ required this.label, required this.value, required this.accent, required this.compact, }); final String label; final String value; final Color accent; final bool compact; @override Widget build(BuildContext context) { return FrostedCard( padding: const EdgeInsets.all(16), child: SizedBox( width: compact ? double.infinity : 188, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( height: 8, width: 40, decoration: BoxDecoration( color: accent, borderRadius: BorderRadius.circular(99), ), ), const SizedBox(height: 16), Text( value, style: Theme.of( context, ).textTheme.headlineMedium?.copyWith(fontWeight: FontWeight.w700), ), const SizedBox(height: 4), Text( label, style: Theme.of( context, ).textTheme.bodyMedium?.copyWith(color: AppTheme.textSecondary), ), ], ), ), ); } } class _TaskRow extends StatelessWidget { const _TaskRow({ required this.task, required this.onToggleDone, required this.compact, }); final DashboardTask task; final VoidCallback onToggleDone; final bool compact; @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.only(bottom: 12), child: Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: const Color(0xFFF5FAFB), borderRadius: BorderRadius.circular(16), ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ InkWell( onTap: onToggleDone, borderRadius: BorderRadius.circular(20), child: Icon( task.done ? Icons.check_circle_rounded : Icons.radio_button_unchecked_rounded, color: task.done ? const Color(0xFF1D9C66) : const Color(0xFF1AB6C8), ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( task.title, style: Theme.of(context).textTheme.titleMedium?.copyWith( decoration: task.done ? TextDecoration.lineThrough : null, ), ), const SizedBox(height: 4), Text( task.description, style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: AppTheme.textSecondary, ), ), ], ), ), if (!compact) ...[ const SizedBox(width: 12), Text( _shortDate(task.when), style: Theme.of( context, ).textTheme.labelLarge?.copyWith(color: AppTheme.textSecondary), ), ], ], ), ), ); } } String _shortDate(DateTime value) { const List weekdays = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun', ]; final String weekday = weekdays[value.weekday - 1]; final String day = value.day.toString().padLeft(2, '0'); return '$weekday $day'; }