@@ -38,44 +38,56 @@ class StatisticsScreen extends HookConsumerWidget {
3838 const SizedBox (height: 20 ),
3939 if (selectedActivity != null ) ...[
4040 // Time and Duration Cards (Top Priority)
41- Card (
41+ Card (
4242 elevation: 4 ,
4343 child: Padding (
4444 padding: const EdgeInsets .all (16.0 ),
4545 child: Row (
4646 mainAxisAlignment: MainAxisAlignment .spaceEvenly,
4747 children: [
48- // Start Time Column
49- Column (
50- mainAxisAlignment: MainAxisAlignment .center,
51- children: [
52- Icon (
53- Icons .access_time,
54- size: 24 ,
55- color: ColorUtils .main,
56- ),
57- const SizedBox (height: 4 ),
58- Text (
59- 'Start Time' ,
60- style: TextStyle (
61- fontSize: 12 ,
62- fontWeight: FontWeight .bold,
63- color: Theme .of (context).brightness == Brightness .dark ? Colors .white : Colors .black87,
64- ),
65- textAlign: TextAlign .center,
66- ),
67- const SizedBox (height: 4 ),
68- Text (
69- DateFormat ('HH:mm:ss\n dd/MM/yyyy' ).format (selectedActivity! .startDatetime),
70- style: const TextStyle (
71- fontSize: 10 ,
72- color: Colors .grey,
73- height: 1.2 ,
74- ),
75- textAlign: TextAlign .center,
76- ),
77- ],
78- ),
48+ // Before showing, ensure start <= end. If not, swap them.
49+ // This avoids negative durations while preserving chronological order.
50+ Builder (builder: (ctx) {
51+ DateTime start = selectedActivity! .startDatetime;
52+ DateTime end = selectedActivity! .endDatetime;
53+ if (end.isBefore (start)) {
54+ final tmp = start;
55+ start = end;
56+ end = tmp;
57+ }
58+
59+ // Start Time Column
60+ return Column (
61+ mainAxisAlignment: MainAxisAlignment .center,
62+ children: [
63+ Icon (
64+ Icons .access_time,
65+ size: 24 ,
66+ color: ColorUtils .main,
67+ ),
68+ const SizedBox (height: 4 ),
69+ Text (
70+ 'Start Time' ,
71+ style: TextStyle (
72+ fontSize: 12 ,
73+ fontWeight: FontWeight .bold,
74+ color: Theme .of (context).brightness == Brightness .dark ? Colors .white : Colors .black87,
75+ ),
76+ textAlign: TextAlign .center,
77+ ),
78+ const SizedBox (height: 4 ),
79+ Text (
80+ DateFormat ('HH:mm:ss\n dd/MM/yyyy' ).format (start),
81+ style: const TextStyle (
82+ fontSize: 10 ,
83+ color: Colors .grey,
84+ height: 1.2 ,
85+ ),
86+ textAlign: TextAlign .center,
87+ ),
88+ ],
89+ );
90+ }),
7991 // Vertical separator
8092 Container (
8193 height: 60 ,
@@ -84,37 +96,47 @@ class StatisticsScreen extends HookConsumerWidget {
8496 ? Colors .white.withValues (alpha: 0.3 )
8597 : Colors .grey.withValues (alpha: 0.3 ),
8698 ),
87- // End Time Column
88- Column (
89- mainAxisAlignment: MainAxisAlignment .center,
90- children: [
91- Icon (
92- Icons .access_time_filled,
93- size: 24 ,
94- color: ColorUtils .main,
95- ),
96- const SizedBox (height: 4 ),
97- Text (
98- 'End Time' ,
99- style: TextStyle (
100- fontSize: 12 ,
101- fontWeight: FontWeight .bold,
102- color: Theme .of (context).brightness == Brightness .dark ? Colors .white : Colors .black87,
99+ // End Time Column (uses same swapped start/end from Builder above)
100+ Builder (builder: (ctx) {
101+ DateTime start = selectedActivity! .startDatetime;
102+ DateTime end = selectedActivity! .endDatetime;
103+ if (end.isBefore (start)) {
104+ final tmp = start;
105+ start = end;
106+ end = tmp;
107+ }
108+
109+ return Column (
110+ mainAxisAlignment: MainAxisAlignment .center,
111+ children: [
112+ Icon (
113+ Icons .access_time_filled,
114+ size: 24 ,
115+ color: ColorUtils .main,
103116 ),
104- textAlign : TextAlign .center ,
105- ),
106- const SizedBox (height : 4 ) ,
107- Text (
108- DateFormat ( 'HH:mm:ss \n dd/MM/yyyy' ). format (selectedActivity ! .endDatetime) ,
109- style : const TextStyle (
110- fontSize : 10 ,
111- color : Colors .grey ,
112- height : 1.2 ,
117+ const SizedBox (height : 4 ) ,
118+ Text (
119+ 'End Time' ,
120+ style : TextStyle (
121+ fontSize : 12 ,
122+ fontWeight : FontWeight .bold,
123+ color : Theme . of (context).brightness == Brightness .dark ? Colors .white : Colors .black87 ,
124+ ) ,
125+ textAlign : TextAlign .center ,
113126 ),
114- textAlign: TextAlign .center,
115- ),
116- ],
117- ),
127+ const SizedBox (height: 4 ),
128+ Text (
129+ DateFormat ('HH:mm:ss\n dd/MM/yyyy' ).format (end),
130+ style: const TextStyle (
131+ fontSize: 10 ,
132+ color: Colors .grey,
133+ height: 1.2 ,
134+ ),
135+ textAlign: TextAlign .center,
136+ ),
137+ ],
138+ );
139+ }),
118140 // Vertical separator
119141 Container (
120142 height: 60 ,
@@ -123,37 +145,49 @@ class StatisticsScreen extends HookConsumerWidget {
123145 ? Colors .white.withValues (alpha: 0.3 )
124146 : Colors .grey.withValues (alpha: 0.3 ),
125147 ),
126- // Duration Column
127- Column (
128- mainAxisAlignment: MainAxisAlignment .center,
129- children: [
130- Icon (
131- Icons .timer,
132- size: 24 ,
133- color: ColorUtils .main,
134- ),
135- const SizedBox (height: 4 ),
136- Text (
137- 'Duration' ,
138- style: TextStyle (
139- fontSize: 12 ,
140- fontWeight: FontWeight .bold,
141- color: Theme .of (context).brightness == Brightness .dark ? Colors .white : Colors .black87,
148+ // Duration Column (calculates from ordered start/end)
149+ Builder (builder: (ctx) {
150+ DateTime start = selectedActivity! .startDatetime;
151+ DateTime end = selectedActivity! .endDatetime;
152+ if (end.isBefore (start)) {
153+ final tmp = start;
154+ start = end;
155+ end = tmp;
156+ }
157+
158+ final duration = end.difference (start);
159+
160+ return Column (
161+ mainAxisAlignment: MainAxisAlignment .center,
162+ children: [
163+ Icon (
164+ Icons .timer,
165+ size: 24 ,
166+ color: ColorUtils .main,
142167 ),
143- textAlign : TextAlign .center ,
144- ),
145- const SizedBox (height : 4 ) ,
146- Text (
147- _formatDuration (selectedActivity ! .endDatetime. difference (selectedActivity ! .startDatetime)) ,
148- style : const TextStyle (
149- fontSize : 10 ,
150- color : Colors .grey ,
151- height : 1.2 ,
168+ const SizedBox (height : 4 ) ,
169+ Text (
170+ 'Duration' ,
171+ style : TextStyle (
172+ fontSize : 12 ,
173+ fontWeight : FontWeight .bold,
174+ color : Theme . of (context).brightness == Brightness .dark ? Colors .white : Colors .black87 ,
175+ ) ,
176+ textAlign : TextAlign .center ,
152177 ),
153- textAlign: TextAlign .center,
154- ),
155- ],
156- ),
178+ const SizedBox (height: 4 ),
179+ Text (
180+ _formatDuration (duration),
181+ style: const TextStyle (
182+ fontSize: 10 ,
183+ color: Colors .grey,
184+ height: 1.2 ,
185+ ),
186+ textAlign: TextAlign .center,
187+ ),
188+ ],
189+ );
190+ }),
157191 ],
158192 ),
159193 ),
@@ -515,6 +549,11 @@ class StatisticsScreen extends HookConsumerWidget {
515549
516550 /// Formats a Duration into a readable string (HH:MM:SS).
517551 String _formatDuration (Duration duration) {
552+ // If negative, use absolute duration (handles cases where end < start)
553+ if (duration.isNegative) {
554+ duration = Duration (microseconds: duration.inMicroseconds.abs ());
555+ }
556+
518557 String twoDigits (int n) => n.toString ().padLeft (2 , '0' );
519558 final hours = twoDigits (duration.inHours);
520559 final minutes = twoDigits (duration.inMinutes.remainder (60 ));
0 commit comments