From 1aa0d849775fbd0dfc83fa8e4cdca84d22a15042 Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 21 Oct 2025 14:47:57 +0300 Subject: [PATCH] Fix due dates to use colors: red = overdue, amber = due soon, no shade = not due yet. Thanks to xet7 ! Fixes #5963 --- client/components/cards/cardDate.css | 73 ++++++++++++++++++------- client/components/cards/cardDate.js | 81 ++++++++++++++++++++-------- client/components/cards/minicard.css | 68 +++++++++++++++++++++++ 3 files changed, 180 insertions(+), 42 deletions(-) diff --git a/client/components/cards/cardDate.css b/client/components/cards/cardDate.css index ba0b52b0f..4a873e485 100644 --- a/client/components/cards/cardDate.css +++ b/client/components/cards/cardDate.css @@ -8,39 +8,72 @@ .card-date.is-active { background-color: #b3b3b3; } -.card-date.current, -.card-date.almost-due, -.card-date.due, -.card-date.long-overdue { +/* Date status colors - red = overdue, amber = due soon, no shade = not due */ +.card-date.overdue { + background-color: #ff4444; /* Red for overdue */ color: #fff; } +.card-date.overdue:hover, +.card-date.overdue.is-active { + background-color: #cc3333; +} + +.card-date.due-soon { + background-color: #ffaa00; /* Amber for due soon */ + color: #000; +} +.card-date.due-soon:hover, +.card-date.due-soon.is-active { + background-color: #e69900; +} + +.card-date.not-due { + /* No special background - uses default date type colors */ +} + .card-date.current { - background-color: #5ba639; + background-color: #5ba639; /* Green for current/active */ + color: #fff; } .card-date.current:hover, .card-date.current.is-active { background-color: #46802c; } -.card-date.almost-due { - background-color: #edc909; + +.card-date.completed { + background-color: #90ee90; /* Light green for completed */ + color: #000; } -.card-date.almost-due:hover, -.card-date.almost-due.is-active { - background-color: #bc9f07; +.card-date.completed:hover, +.card-date.completed.is-active { + background-color: #7dd87d; } -.card-date.due { - background-color: #fa3f00; + +.card-date.completed-early { + background-color: #4caf50; /* Green for completed early */ + color: #fff; } -.card-date.due:hover, -.card-date.due.is-active { - background-color: #c73200; +.card-date.completed-early:hover, +.card-date.completed-early.is-active { + background-color: #45a049; } -.card-date.long-overdue { - background-color: #fd5d47; + +.card-date.completed-late { + background-color: #ff9800; /* Orange for completed late */ + color: #fff; } -.card-date.long-overdue:hover, -.card-date.long-overdue.is-active { - background-color: #fd3e24; +.card-date.completed-late:hover, +.card-date.completed-late.is-active { + background-color: #f57c00; +} + +.card-date.completed-on-time { + background-color: #2196f3; /* Blue for completed on time */ + color: #fff; +} +.card-date.completed-on-time:hover, +.card-date.completed-on-time.is-active { + background-color: #1976d2; } /* Date type specific colors */ diff --git a/client/components/cards/cardDate.js b/client/components/cards/cardDate.js index d5649fae1..c5c3a3b63 100644 --- a/client/components/cards/cardDate.js +++ b/client/components/cards/cardDate.js @@ -157,14 +157,18 @@ class CardReceivedDate extends CardDate { const endAt = this.data().getEnd(); const startAt = this.data().getStart(); const theDate = this.date.get(); - // if dueAt, endAt and startAt exist & are > receivedAt, receivedAt doesn't need to be flagged + const now = this.now.get(); + + // Received date logic: if received date is after start, due, or end dates, it's overdue if ( (startAt && isAfter(theDate, startAt)) || (endAt && isAfter(theDate, endAt)) || (dueAt && isAfter(theDate, dueAt)) - ) - classes += 'long-overdue'; - else classes += 'current'; + ) { + classes += 'overdue'; + } else { + classes += 'not-due'; + } return classes; } @@ -193,16 +197,22 @@ class CardStartDate extends CardDate { } classes() { - let classes = 'start-date' + ' '; + let classes = 'start-date '; const dueAt = this.data().getDue(); const endAt = this.data().getEnd(); const theDate = this.date.get(); const now = this.now.get(); - // if dueAt or endAt exist & are > startAt, startAt doesn't need to be flagged - if ((endAt && isAfter(theDate, endAt)) || (dueAt && isAfter(theDate, dueAt))) - classes += 'long-overdue'; - else if (isAfter(theDate, now)) classes += ''; - else classes += 'current'; + + // Start date logic: if start date is after due or end dates, it's overdue + if ((endAt && isAfter(theDate, endAt)) || (dueAt && isAfter(theDate, dueAt))) { + classes += 'overdue'; + } else if (isAfter(theDate, now)) { + // Start date is in the future - not due yet + classes += 'not-due'; + } else { + // Start date is today or in the past - current/active + classes += 'current'; + } return classes; } @@ -231,17 +241,33 @@ class CardDueDate extends CardDate { } classes() { - let classes = 'due-date' + ' '; + let classes = 'due-date '; const endAt = this.data().getEnd(); const theDate = this.date.get(); const now = this.now.get(); - // if the due date is after the end date, green - done early - if (endAt && isAfter(theDate, endAt)) classes += 'current'; - // if there is an end date, don't need to flag the due date - else if (endAt) classes += ''; - else if (diff(now, theDate, 'days') >= 2) classes += 'long-overdue'; - else if (diff(now, theDate, 'minute') >= 0) classes += 'due'; - else if (diff(now, theDate, 'days') >= -1) classes += 'almost-due'; + + // If there's an end date and it's before the due date, task is completed early + if (endAt && isBefore(endAt, theDate)) { + classes += 'completed-early'; + } + // If there's an end date, don't show due date status since task is completed + else if (endAt) { + classes += 'completed'; + } + // Due date logic based on current time + else { + const daysDiff = diff(theDate, now, 'days'); + if (daysDiff < 0) { + // Due date is in the past - overdue + classes += 'overdue'; + } else if (daysDiff <= 1) { + // Due today or tomorrow - due soon + classes += 'due-soon'; + } else { + // Due date is more than 1 day away - not due yet + classes += 'not-due'; + } + } return classes; } @@ -270,12 +296,23 @@ class CardEndDate extends CardDate { } classes() { - let classes = 'end-date' + ' '; + let classes = 'end-date '; const dueAt = this.data().getDue(); const theDate = this.date.get(); - if (!dueAt) classes += ''; - else if (isBefore(theDate, dueAt)) classes += 'current'; - else if (isAfter(theDate, dueAt)) classes += 'due'; + + if (!dueAt) { + // No due date set - just show as completed + classes += 'completed'; + } else if (isBefore(theDate, dueAt)) { + // End date is before due date - completed early + classes += 'completed-early'; + } else if (isAfter(theDate, dueAt)) { + // End date is after due date - completed late + classes += 'completed-late'; + } else { + // End date equals due date - completed on time + classes += 'completed-on-time'; + } return classes; } diff --git a/client/components/cards/minicard.css b/client/components/cards/minicard.css index 58745e39f..8e6158826 100644 --- a/client/components/cards/minicard.css +++ b/client/components/cards/minicard.css @@ -229,6 +229,74 @@ background-color: #ff9999; } +/* Date status colors for minicards - matching cardDate.css */ +.minicard .card-date.overdue { + background-color: #ff4444 !important; /* Red for overdue */ + color: #fff !important; +} +.minicard .card-date.overdue:hover, +.minicard .card-date.overdue.is-active { + background-color: #cc3333 !important; +} + +.minicard .card-date.due-soon { + background-color: #ffaa00 !important; /* Amber for due soon */ + color: #000 !important; +} +.minicard .card-date.due-soon:hover, +.minicard .card-date.due-soon.is-active { + background-color: #e69900 !important; +} + +.minicard .card-date.not-due { + /* No special background - uses default date type colors */ +} + +.minicard .card-date.current { + background-color: #5ba639 !important; /* Green for current/active */ + color: #fff !important; +} +.minicard .card-date.current:hover, +.minicard .card-date.current.is-active { + background-color: #46802c !important; +} + +.minicard .card-date.completed { + background-color: #90ee90 !important; /* Light green for completed */ + color: #000 !important; +} +.minicard .card-date.completed:hover, +.minicard .card-date.completed.is-active { + background-color: #7dd87d !important; +} + +.minicard .card-date.completed-early { + background-color: #4caf50 !important; /* Green for completed early */ + color: #fff !important; +} +.minicard .card-date.completed-early:hover, +.minicard .card-date.completed-early.is-active { + background-color: #45a049 !important; +} + +.minicard .card-date.completed-late { + background-color: #ff9800 !important; /* Orange for completed late */ + color: #fff !important; +} +.minicard .card-date.completed-late:hover, +.minicard .card-date.completed-late.is-active { + background-color: #f57c00 !important; +} + +.minicard .card-date.completed-on-time { + background-color: #2196f3 !important; /* Blue for completed on time */ + color: #fff !important; +} +.minicard .card-date.completed-on-time:hover, +.minicard .card-date.completed-on-time.is-active { + background-color: #1976d2 !important; +} + /* Font Awesome icons in minicard dates */ .minicard .card-date i.fa { margin-right: 0.3vw;