11import 'package:flutter/material.dart' ;
2+ import 'package:flutter_riverpod/flutter_riverpod.dart' ;
3+ import '../../providers/dashboard/dashboard_controller.dart' ;
24import '../../widgets/custom_widgets.dart' ;
35import 'package:fl_chart/fl_chart.dart' ;
46import 'package:intl/intl.dart' ;
@@ -7,20 +9,18 @@ import '../tasks/task_detail_screen.dart';
79import '../tickets/ticket_detail_screen.dart' ;
810import '../meetings/meeting_detail_screen.dart' ;
911
10- class DashboardScreen extends StatefulWidget {
12+ class DashboardScreen extends ConsumerStatefulWidget {
1113 const DashboardScreen ({super .key});
1214
1315 @override
14- State <DashboardScreen > createState () => _DashboardScreenState ();
16+ ConsumerState <DashboardScreen > createState () => _DashboardScreenState ();
1517}
1618
17- class _DashboardScreenState extends State <DashboardScreen >
19+ class _DashboardScreenState extends ConsumerState <DashboardScreen >
1820 with SingleTickerProviderStateMixin {
1921 late AnimationController _controller;
20- int _selectedTimeRange = 0 ; // 0: Week, 1: Month
2122 bool _isLoading = true ;
2223 String ? _userName;
23- String ? _currentTeamId;
2424 String ? _currentTeamName;
2525 List <Map <String , dynamic >> _userTeams = [];
2626 int _tasksTotal = 0 ;
@@ -57,6 +57,8 @@ class _DashboardScreenState extends State<DashboardScreen>
5757 }
5858
5959 void _showTeamSwitcher () {
60+ final selectedTeamId = ref.read (dashboardControllerProvider).selectedTeamId;
61+
6062 showDialog (
6163 context: context,
6264 builder: (context) {
@@ -76,7 +78,7 @@ class _DashboardScreenState extends State<DashboardScreen>
7678 itemCount: _userTeams.length,
7779 itemBuilder: (context, index) {
7880 final team = _userTeams[index];
79- final isCurrentTeam = team['id' ] == _currentTeamId ;
81+ final isCurrentTeam = team['id' ] == selectedTeamId ;
8082
8183 final scheme = Theme .of (context).colorScheme;
8284 return ListTile (
@@ -189,7 +191,9 @@ class _DashboardScreenState extends State<DashboardScreen>
189191
190192 // Set current team
191193 if (profile != null && profile['team_id' ] != null ) {
192- _currentTeamId = profile['team_id' ];
194+ ref
195+ .read (dashboardControllerProvider.notifier)
196+ .setSelectedTeam (profile['team_id' ] as String );
193197 _currentTeamName = profile['teams' ]? ['name' ] ?? 'My Team' ;
194198 }
195199
@@ -223,39 +227,14 @@ class _DashboardScreenState extends State<DashboardScreen>
223227 _allTasks = tasks;
224228 final tickets = List <Map <String , dynamic >>.from (results[1 ] as List );
225229 final meetings = List <Map <String , dynamic >>.from (results[2 ] as List );
230+ final now = DateTime .now ();
226231
227232 _tasksTotal = tasks.length;
228233 _tasksInProgress =
229234 tasks.where ((t) => t['status' ] == 'in_progress' ).length;
230235 _tasksCompleted = tasks.where ((t) => t['status' ] == 'completed' ).length;
231236
232- // Build completion series for last 7 days
233- final now = DateTime .now ();
234- final Map <int , int > dayIndexToCompleted = {
235- for (var i = 0 ; i < 7 ; i++ ) i: 0
236- };
237- for (final t in tasks) {
238- if (t['status' ] == 'completed' ) {
239- final ts = (t['updated_at' ] ?? t['created_at' ])? .toString ();
240- if (ts != null ) {
241- final updated = DateTime .tryParse (ts);
242- if (updated != null ) {
243- final diffDays = now
244- .difference (
245- DateTime (updated.year, updated.month, updated.day))
246- .inDays;
247- if (diffDays >= 0 && diffDays < 7 ) {
248- final idx = 6 - diffDays; // earlier days on the left
249- dayIndexToCompleted[idx] = (dayIndexToCompleted[idx] ?? 0 ) + 1 ;
250- }
251- }
252- }
253- }
254- }
255- _taskCompletionSpots = List .generate (
256- 7 ,
257- (i) => FlSpot (i.toDouble (), (dayIndexToCompleted[i] ?? 0 ).toDouble ()),
258- );
237+ _recomputeChartSpots ();
259238
260239 _ticketsOpen = tickets.where ((t) => t['status' ] == 'open' ).length;
261240 _ticketsInProgress =
@@ -728,6 +707,8 @@ class _DashboardScreenState extends State<DashboardScreen>
728707
729708 Widget _buildAnalyticsSection () {
730709 final colorScheme = Theme .of (context).colorScheme;
710+ final timeRange = ref.watch (dashboardControllerProvider).timeRange;
711+
731712 return Container (
732713 padding: const EdgeInsets .all (20 ),
733714 decoration: BoxDecoration (
@@ -754,7 +735,7 @@ class _DashboardScreenState extends State<DashboardScreen>
754735 .titleLarge
755736 ? .copyWith (fontWeight: FontWeight .bold),
756737 ),
757- if (_selectedTimeRange == 1 )
738+ if (timeRange == 1 )
758739 Text (
759740 DateFormat ('MMMM yyyy' ).format (DateTime .now ()),
760741 style: TextStyle (
@@ -788,7 +769,7 @@ class _DashboardScreenState extends State<DashboardScreen>
788769 style: TextStyle (color: Colors .grey.shade500),
789770 ),
790771 )
791- : _selectedTimeRange == 0
772+ : timeRange == 0
792773 // Bar Chart for Weekly view
793774 ? BarChart (
794775 BarChartData (
@@ -947,50 +928,49 @@ class _DashboardScreenState extends State<DashboardScreen>
947928 );
948929 }
949930
931+ void _recomputeChartSpots () {
932+ final timeRange = ref.read (dashboardControllerProvider).timeRange;
933+
934+ if (timeRange == 0 ) {
935+ final now = DateTime .now ();
936+ final Map <int , int > dayIndexToCompleted = {
937+ for (var i = 0 ; i < 7 ; i++ ) i: 0 ,
938+ };
939+
940+ for (final t in _allTasks) {
941+ if (t['status' ] == 'completed' ) {
942+ final ts = (t['updated_at' ] ?? t['created_at' ])? .toString ();
943+ final updated = ts != null ? DateTime .tryParse (ts) : null ;
944+ if (updated == null ) continue ;
945+
946+ final diffDays = now
947+ .difference (DateTime (updated.year, updated.month, updated.day))
948+ .inDays;
949+
950+ if (diffDays >= 0 && diffDays < 7 ) {
951+ final idx = 6 - diffDays;
952+ dayIndexToCompleted[idx] = (dayIndexToCompleted[idx] ?? 0 ) + 1 ;
953+ }
954+ }
955+ }
956+
957+ _taskCompletionSpots = List .generate (
958+ 7 ,
959+ (i) => FlSpot (i.toDouble (), (dayIndexToCompleted[i] ?? 0 ).toDouble ()),
960+ );
961+ return ;
962+ }
963+
964+ _taskCompletionSpots = _buildCurrentMonthSpots (_allTasks);
965+ }
966+
950967 Widget _timeRangeButton (String text, int index) {
951- final isSelected = _selectedTimeRange == index;
968+ final timeRange = ref.watch (dashboardControllerProvider).timeRange;
969+ final isSelected = timeRange == index;
952970 return GestureDetector (
953- //onTap: () => setState(() => _selectedTimeRange = index),
954971 onTap: () {
955- setState (() {
956- _selectedTimeRange = index;
957-
958- if (index == 0 ) {
959- // Week → reusing existing weekly logic
960- final now = DateTime .now ();
961- final Map <int , int > dayIndexToCompleted = {
962- for (var i = 0 ; i < 7 ; i++ ) i: 0
963- };
964-
965- for (final t in _allTasks) {
966- if (t['status' ] == 'completed' ) {
967- final ts = (t['updated_at' ] ?? t['created_at' ])? .toString ();
968- final updated = ts != null ? DateTime .tryParse (ts) : null ;
969- if (updated == null ) continue ;
970-
971- final diffDays = now
972- .difference (
973- DateTime (updated.year, updated.month, updated.day))
974- .inDays;
975-
976- if (diffDays >= 0 && diffDays < 7 ) {
977- final idx = 6 - diffDays;
978- dayIndexToCompleted[idx] =
979- (dayIndexToCompleted[idx] ?? 0 ) + 1 ;
980- }
981- }
982- }
983-
984- _taskCompletionSpots = List .generate (
985- 7 ,
986- (i) => FlSpot (
987- i.toDouble (), (dayIndexToCompleted[i] ?? 0 ).toDouble ()),
988- );
989- } else {
990- // Month → current calendar month
991- _taskCompletionSpots = _buildCurrentMonthSpots (_allTasks);
992- }
993- });
972+ ref.read (dashboardControllerProvider.notifier).setTimeRange (index);
973+ setState (_recomputeChartSpots);
994974 },
995975 child: Container (
996976 padding: const EdgeInsets .symmetric (horizontal: 16 , vertical: 8 ),
0 commit comments