diff --git a/front/src/modules/activities/components/TaskRow.tsx b/front/src/modules/activities/components/TaskRow.tsx index b690aaaf0..daf505c2d 100644 --- a/front/src/modules/activities/components/TaskRow.tsx +++ b/front/src/modules/activities/components/TaskRow.tsx @@ -9,7 +9,7 @@ import { CheckboxShape, } from '@/ui/input/checkbox/components/Checkbox'; import { OverflowingTextWithTooltip } from '@/ui/tooltip/OverflowingTextWithTooltip'; -import { beautifyExactDate } from '~/utils/date-utils'; +import { beautifyExactDate, hasDatePassed } from '~/utils/date-utils'; import { useCompleteTask } from '../hooks/useCompleteTask'; import { TaskForList } from '../types/TaskForList'; @@ -49,9 +49,12 @@ const StyledCommentIcon = styled.div` margin-left: ${({ theme }) => theme.spacing(2)}; `; -const StyledDueDate = styled.div` +const StyledDueDate = styled.div<{ + isPast: boolean; +}>` align-items: center; - color: ${({ theme }) => theme.font.color.secondary}; + color: ${({ theme, isPast }) => + isPast ? theme.font.color.danger : theme.font.color.secondary}; display: flex; gap: ${({ theme }) => theme.spacing(1)}; padding-left: ${({ theme }) => theme.spacing(2)}; @@ -98,7 +101,7 @@ export function TaskRow({ task }: { task: TaskForList }) { - + {task.dueAt && beautifyExactDate(task.dueAt)} diff --git a/front/src/utils/__tests__/date-utils.test.ts b/front/src/utils/__tests__/date-utils.test.ts index 952eb011b..6669f0b1f 100644 --- a/front/src/utils/__tests__/date-utils.test.ts +++ b/front/src/utils/__tests__/date-utils.test.ts @@ -7,6 +7,7 @@ import { beautifyPastDateAbsolute, beautifyPastDateRelativeToNow, DEFAULT_DATE_LOCALE, + hasDatePassed, parseDate, } from '../date-utils'; import { logError } from '../logError'; @@ -184,3 +185,55 @@ describe('beautifyPastDateAbsolute', () => { expect(result).toEqual(expected); }); }); + +describe('hasDatePassed', () => { + it('should log an error and return false when passed an invalid date string', () => { + const result = hasDatePassed('invalid-date-string'); + + expect(logError).toHaveBeenCalledWith( + Error('Invalid date passed to formatPastDate: "invalid-date-string"'), + ); + expect(result).toEqual(false); + }); + + it('should log an error and return false when passed NaN', () => { + const result = hasDatePassed(NaN); + + expect(logError).toHaveBeenCalledWith( + Error('Invalid date passed to formatPastDate: "NaN"'), + ); + expect(result).toEqual(false); + }); + + it('should log an error and return false when passed invalid Date object', () => { + const result = hasDatePassed(new Date(NaN)); + + expect(logError).toHaveBeenCalledWith( + Error('Invalid date passed to formatPastDate: "Invalid Date"'), + ); + expect(result).toEqual(false); + }); + + it('should return true when passed past date', () => { + const now = DateTime.local(); + const pastDate = now.minus({ day: 1 }); + + const result = hasDatePassed(pastDate.toJSDate()); + expect(result).toEqual(true); + }); + + it('should return false when passed future date', () => { + const now = DateTime.local(); + const futureDate = now.plus({ days: 1 }); + + const result = hasDatePassed(futureDate.toJSDate()); + expect(result).toEqual(false); + }); + + it('should return false when passed current date', () => { + const now = DateTime.local(); + + const result = hasDatePassed(now.toJSDate()); + expect(result).toEqual(false); + }); +}); diff --git a/front/src/utils/date-utils.ts b/front/src/utils/date-utils.ts index d83664449..feeb34c89 100644 --- a/front/src/utils/date-utils.ts +++ b/front/src/utils/date-utils.ts @@ -1,4 +1,4 @@ -import { formatDistanceToNow } from 'date-fns'; +import { differenceInCalendarDays, formatDistanceToNow } from 'date-fns'; import { DateTime } from 'luxon'; import { logError } from './logError'; @@ -88,3 +88,19 @@ export function beautifyPastDateAbsolute(pastDate: Date | string | number) { return ''; } } + +export function hasDatePassed(date: Date | string | number) { + try { + const parsedDate = parseDate(date); + + return ( + differenceInCalendarDays( + DateTime.local().toJSDate(), + parsedDate.toJSDate(), + ) >= 1 + ); + } catch (error) { + logError(error); + return false; + } +}