@@ -14,7 +14,8 @@ const initialState = {
1414 } ,
1515} ;
1616
17- const orderByDueDate = ( t1 , t2 ) => {
17+
18+ const orderByDueDateAndPriority1 = ( t1 , t2 ) => {
1819 const lhs = t1 ?. dueDate ;
1920 const rhs = t2 ?. dueDate ;
2021 if ( ! lhs && ! rhs ) {
@@ -30,14 +31,155 @@ const orderByDueDate = (t1, t2) => {
3031 return lhs < rhs ? - 1 : 1 ;
3132} ;
3233
34+ /**
35+ * Task prioritization algorithm that combines:
36+ * 1. Overdue status (most urgent)
37+ * 2. Due today status (high urgency)
38+ * 3. Priority (importance)
39+ * 4. Due date (soonest first)
40+ * 5. Tasks without due dates (lowest priority)
41+ *
42+ * Sorting rules (in order):
43+ * 1. Overdue tasks appear first (most urgent)
44+ * 2. Tasks due today appear next
45+ * 3. Then sort by priority (high to low)
46+ * 4. For equal priority, sort by due date (earlier first)
47+ * 5. Tasks without due dates appear last
48+ */
49+ const orderByDueDateAndPriority2 = ( t1 , t2 ) => {
50+
51+ const p1 = t1 ?. priority ?? 0 ;
52+ const p2 = t2 ?. priority ?? 0 ;
53+
54+ const now = new Date ( ) ;
55+ const startOfToday = new Date ( now . getFullYear ( ) , now . getMonth ( ) , now . getDate ( ) ) . getTime ( ) ;
56+
57+ // Due date handling (Infinity for missing dates)
58+ const d1 = t1 ?. dueDate ? new Date ( t1 . dueDate ) . getTime ( ) : Infinity ;
59+ const d2 = t2 ?. dueDate ? new Date ( t2 . dueDate ) . getTime ( ) : Infinity ;
60+
61+ // Calculate days until due (negative = overdue)
62+ const daysUntilDue1 = Math . floor ( ( d1 - startOfToday ) / ( 1000 * 60 * 60 * 24 ) ) ;
63+ const daysUntilDue2 = Math . floor ( ( d2 - startOfToday ) / ( 1000 * 60 * 60 * 24 ) ) ;
64+
65+ // Status flags
66+ const isOverdue1 = daysUntilDue1 < 0 ;
67+ const isOverdue2 = daysUntilDue2 < 0 ;
68+ const isDueToday1 = daysUntilDue1 === 0 ;
69+ const isDueToday2 = daysUntilDue2 === 0 ;
70+ const hasNoDueDate1 = d1 === Infinity ;
71+ const hasNoDueDate2 = d2 === Infinity ;
72+
73+ // 1. Overdue tasks come first (most urgent)
74+ if ( isOverdue1 && ! isOverdue2 ) return - 1 ;
75+ if ( isOverdue2 && ! isOverdue1 ) return 1 ;
76+ if ( isOverdue1 && isOverdue2 ) {
77+ // If both overdue, more overdue comes first
78+ return daysUntilDue1 - daysUntilDue2 ;
79+ }
80+
81+ // 2. Tasks due today come next
82+ if ( isDueToday1 && ! isDueToday2 ) return - 1 ;
83+ if ( isDueToday2 && ! isDueToday1 ) return 1 ;
84+
85+ // 3. Then sort by priority (higher first)
86+ if ( p1 !== p2 ) return p2 - p1 ;
87+
88+ // 4. For equal priority, sort by due date (earlier first)
89+ if ( d1 !== d2 ) return d1 - d2 ;
90+
91+ // 5. Tasks without due dates come last
92+ if ( hasNoDueDate1 && ! hasNoDueDate2 ) return 1 ;
93+ if ( hasNoDueDate2 && ! hasNoDueDate1 ) return - 1 ;
94+
95+ // 6. All else being equal, maintain original order
96+ return 0 ;
97+ } ;
98+
99+ /**
100+ * Task prioritization algorithm that combines:
101+ * 1. Overdue status (most urgent)
102+ * 2. Due today status (high urgency)
103+ * 3. Priority (importance)
104+ * 4. Due date (soonest first)
105+ * 5. Tasks without due dates (lowest priority)
106+ *
107+ * Sorting rules (in order):
108+ * 1. Overdue tasks appear first (most urgent), sorted by priority (higher first)
109+ * 2. Tasks due today appear next, sorted by priority (higher first)
110+ * 3. Then sort other dates too by date and priority (high to low)
111+ * 4. For equal priority, sort by due date (earlier first)
112+ * 5. Tasks without due dates appear last
113+ */
114+
115+ const orderByDueDateAndPriority = ( t1 , t2 ) => {
116+ // Normalize priority to a number
117+ const getPriority = ( t ) =>
118+ t ?. priority === 'high' ? 10 :
119+ t ?. priority === 'medium' ? 6 :
120+ typeof t ?. priority === 'string' ? 0 :
121+ t ?. priority ?? 0 ;
122+
123+ const p1 = getPriority ( t1 ) ;
124+ const p2 = getPriority ( t2 ) ;
125+
126+ // Normalize due dates
127+ const d1 = t1 ?. dueDate ? new Date ( t1 . dueDate ) . getTime ( ) : Infinity ;
128+ const d2 = t2 ?. dueDate ? new Date ( t2 . dueDate ) . getTime ( ) : Infinity ;
129+
130+ const now = new Date ( ) ;
131+ const startOfToday = new Date ( now . getFullYear ( ) , now . getMonth ( ) , now . getDate ( ) ) . getTime ( ) ;
132+
133+ const daysUntilDue1 = Math . floor ( ( d1 - startOfToday ) / ( 1000 * 60 * 60 * 24 ) ) ;
134+ const daysUntilDue2 = Math . floor ( ( d2 - startOfToday ) / ( 1000 * 60 * 60 * 24 ) ) ;
135+
136+ const isOverdue1 = daysUntilDue1 < 0 ;
137+ const isOverdue2 = daysUntilDue2 < 0 ;
138+ const isDueToday1 = daysUntilDue1 === 0 ;
139+ const isDueToday2 = daysUntilDue2 === 0 ;
140+ const hasNoDueDate1 = d1 === Infinity ;
141+ const hasNoDueDate2 = d2 === Infinity ;
142+
143+ // 1. Overdue tasks first, sorted by priority (higher first), then by due date (earlier first)
144+ if ( isOverdue1 && ! isOverdue2 ) return - 1 ;
145+ if ( isOverdue2 && ! isOverdue1 ) return 1 ;
146+ if ( isOverdue1 && isOverdue2 ) {
147+ if ( p1 !== p2 ) return p2 - p1 ;
148+ return d1 - d2 ;
149+ }
150+
151+ // 2. Tasks due today next, sorted by priority (higher first)
152+ if ( isDueToday1 && ! isDueToday2 ) return - 1 ;
153+ if ( isDueToday2 && ! isDueToday1 ) return 1 ;
154+ if ( isDueToday1 && isDueToday2 ) {
155+ if ( p1 !== p2 ) return p2 - p1 ;
156+ return d1 - d2 ;
157+ }
158+
159+ // 3. Other tasks: sort by due date (earlier first), then by priority (higher first)
160+ if ( ! hasNoDueDate1 && ! hasNoDueDate2 ) {
161+ if ( d1 !== d2 ) return d1 - d2 ;
162+ if ( p1 !== p2 ) return p2 - p1 ;
163+ }
164+
165+ // 4. Tasks without due dates come last
166+ if ( hasNoDueDate1 && ! hasNoDueDate2 ) return 1 ;
167+ if ( hasNoDueDate2 && ! hasNoDueDate1 ) return - 1 ;
168+
169+ // 5. All else being equal, maintain original order
170+ return 0 ;
171+ } ;
172+
173+
174+
33175const _tasksReducer = createReducer (
34176 initialState ,
35177 on ( GlobalActions . clearSelected , ( state ) => ( { ...state , selected : null } ) ) ,
36178
37179 on ( Actions . setTasksList , ( state , { payload : { tasks } } ) => {
38180 return {
39181 ...state ,
40- tasksList : [ ...tasks ] . sort ( orderByDueDate ) ,
182+ tasksList : [ ...tasks ] . sort ( orderByDueDateAndPriority ) ,
41183 } ;
42184 } ) ,
43185
0 commit comments