feat: enhance date handling in TaskBasicFields and date-utils
- Integrated `ensureDate` and `formatDateForDateTimeInput` in `TaskBasicFields` for improved due date management. - Updated `date-utils` functions to accept both `Date` and `string` types, ensuring robust date validation and parsing. - Added `ensureDate` utility to handle various date inputs, improving error handling and consistency across date-related functions.
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
import { Input } from '@/components/ui/Input';
|
import { Input } from '@/components/ui/Input';
|
||||||
import { TaskPriority, TaskStatus } from '@/lib/types';
|
import { TaskPriority, TaskStatus } from '@/lib/types';
|
||||||
import { getAllStatuses, getAllPriorities } from '@/lib/status-config';
|
import { getAllStatuses, getAllPriorities } from '@/lib/status-config';
|
||||||
|
import { ensureDate, formatDateForDateTimeInput } from '@/lib/date-utils';
|
||||||
|
|
||||||
interface TaskBasicFieldsProps {
|
interface TaskBasicFieldsProps {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -109,7 +110,10 @@ export function TaskBasicFields({
|
|||||||
<Input
|
<Input
|
||||||
label="Date d'échéance"
|
label="Date d'échéance"
|
||||||
type="datetime-local"
|
type="datetime-local"
|
||||||
value={dueDate ? new Date(dueDate.getTime() - dueDate.getTimezoneOffset() * 60000).toISOString().slice(0, 16) : ''}
|
value={(() => {
|
||||||
|
const date = ensureDate(dueDate);
|
||||||
|
return date ? formatDateForDateTimeInput(date) : '';
|
||||||
|
})()}
|
||||||
onChange={(e) => onDueDateChange(e.target.value ? new Date(e.target.value) : undefined)}
|
onChange={(e) => onDueDateChange(e.target.value ? new Date(e.target.value) : undefined)}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -34,26 +34,28 @@ export function normalizeDate(date: Date): Date {
|
|||||||
* @param date - Date à formater
|
* @param date - Date à formater
|
||||||
* @returns Format YYYY-MM-DD
|
* @returns Format YYYY-MM-DD
|
||||||
*/
|
*/
|
||||||
export function formatDateForAPI(date: Date): string {
|
export function formatDateForAPI(date: Date | string): string {
|
||||||
if (!isValid(date)) {
|
const ensuredDate = ensureDate(date);
|
||||||
|
if (!ensuredDate || !isValid(ensuredDate)) {
|
||||||
throw new Error('Date invalide fournie à formatDateForAPI');
|
throw new Error('Date invalide fournie à formatDateForAPI');
|
||||||
}
|
}
|
||||||
|
|
||||||
const year = date.getFullYear();
|
const year = ensuredDate.getFullYear();
|
||||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
const month = String(ensuredDate.getMonth() + 1).padStart(2, '0');
|
||||||
const day = String(date.getDate()).padStart(2, '0');
|
const day = String(ensuredDate.getDate()).padStart(2, '0');
|
||||||
return `${year}-${month}-${day}`;
|
return `${year}-${month}-${day}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formate une date pour l'affichage en français
|
* Formate une date pour l'affichage en français
|
||||||
*/
|
*/
|
||||||
export function formatDateForDisplay(date: Date, formatType: keyof typeof DATE_FORMATS = 'DISPLAY_MEDIUM'): string {
|
export function formatDateForDisplay(date: Date | string, formatType: keyof typeof DATE_FORMATS = 'DISPLAY_MEDIUM'): string {
|
||||||
if (!isValid(date)) {
|
const ensuredDate = ensureDate(date);
|
||||||
|
if (!ensuredDate || !isValid(ensuredDate)) {
|
||||||
throw new Error('Date invalide fournie à formatDateForDisplay');
|
throw new Error('Date invalide fournie à formatDateForDisplay');
|
||||||
}
|
}
|
||||||
|
|
||||||
return format(date, DATE_FORMATS[formatType], { locale: fr });
|
return format(ensuredDate, DATE_FORMATS[formatType], { locale: fr });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,9 +68,14 @@ export function formatDateShort(date: Date): string {
|
|||||||
/**
|
/**
|
||||||
* Calcule le nombre de jours écoulés depuis une date
|
* Calcule le nombre de jours écoulés depuis une date
|
||||||
*/
|
*/
|
||||||
export function getDaysAgo(date: Date): number {
|
export function getDaysAgo(date: Date | string): number {
|
||||||
|
const ensuredDate = ensureDate(date);
|
||||||
|
if (!ensuredDate) {
|
||||||
|
throw new Error('Date invalide fournie à getDaysAgo');
|
||||||
|
}
|
||||||
|
|
||||||
const today = getToday();
|
const today = getToday();
|
||||||
const diffTime = today.getTime() - normalizeDate(date).getTime();
|
const diffTime = today.getTime() - normalizeDate(ensuredDate).getTime();
|
||||||
return Math.floor(diffTime / (1000 * 60 * 60 * 24));
|
return Math.floor(diffTime / (1000 * 60 * 60 * 24));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,25 +89,36 @@ export function formatDateLong(date: Date): string {
|
|||||||
/**
|
/**
|
||||||
* Vérifie si une date est aujourd'hui
|
* Vérifie si une date est aujourd'hui
|
||||||
*/
|
*/
|
||||||
export function isToday(date: Date): boolean {
|
export function isToday(date: Date | string): boolean {
|
||||||
|
const ensuredDate = ensureDate(date);
|
||||||
|
if (!ensuredDate) return false;
|
||||||
|
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
return normalizeDate(date).getTime() === normalizeDate(today).getTime();
|
return normalizeDate(ensuredDate).getTime() === normalizeDate(today).getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vérifie si une date est hier
|
* Vérifie si une date est hier
|
||||||
*/
|
*/
|
||||||
export function isYesterday(date: Date): boolean {
|
export function isYesterday(date: Date | string): boolean {
|
||||||
|
const ensuredDate = ensureDate(date);
|
||||||
|
if (!ensuredDate) return false;
|
||||||
|
|
||||||
const yesterday = new Date();
|
const yesterday = new Date();
|
||||||
yesterday.setDate(yesterday.getDate() - 1);
|
yesterday.setDate(yesterday.getDate() - 1);
|
||||||
return normalizeDate(date).getTime() === normalizeDate(yesterday).getTime();
|
return normalizeDate(ensuredDate).getTime() === normalizeDate(yesterday).getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare deux dates (sans tenir compte de l'heure)
|
* Compare deux dates (sans tenir compte de l'heure)
|
||||||
*/
|
*/
|
||||||
export function isSameDay(date1: Date, date2: Date): boolean {
|
export function isSameDay(date1: Date | string, date2: Date | string): boolean {
|
||||||
return normalizeDate(date1).getTime() === normalizeDate(date2).getTime();
|
const ensuredDate1 = ensureDate(date1);
|
||||||
|
const ensuredDate2 = ensureDate(date2);
|
||||||
|
|
||||||
|
if (!ensuredDate1 || !ensuredDate2) return false;
|
||||||
|
|
||||||
|
return normalizeDate(ensuredDate1).getTime() === normalizeDate(ensuredDate2).getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -258,3 +276,52 @@ export function formatDistanceToNow(date: Date, options?: { addSuffix?: boolean
|
|||||||
addSuffix: options?.addSuffix ?? true
|
addSuffix: options?.addSuffix ?? true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* S'assure qu'une valeur est un objet Date valide
|
||||||
|
* Convertit les chaînes de caractères en Date si nécessaire
|
||||||
|
*/
|
||||||
|
export function ensureDate(value: Date | string | null | undefined): Date | null {
|
||||||
|
if (value === null || value === undefined) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si c'est déjà un objet Date valide
|
||||||
|
if (value instanceof Date && isValid(value)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si c'est une chaîne de caractères, essayer de la parser
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
try {
|
||||||
|
const parsed = parseDate(value);
|
||||||
|
return parsed;
|
||||||
|
} catch {
|
||||||
|
console.warn(`Impossible de parser la date: ${value}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si c'est un objet Date mais invalide, essayer de le recréer
|
||||||
|
if (value instanceof Date) {
|
||||||
|
try {
|
||||||
|
const time = value.getTime();
|
||||||
|
if (!isNaN(time)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
console.warn('Objet Date invalide détecté');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.warn('Valeur de date non supportée:', value);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* S'assure qu'une valeur est un objet Date valide, avec une valeur par défaut
|
||||||
|
*/
|
||||||
|
export function ensureDateWithDefault(value: Date | string | null | undefined, defaultValue: Date = new Date()): Date {
|
||||||
|
const result = ensureDate(value);
|
||||||
|
return result || defaultValue;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user