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 { TaskPriority, TaskStatus } from '@/lib/types';
|
||||
import { getAllStatuses, getAllPriorities } from '@/lib/status-config';
|
||||
import { ensureDate, formatDateForDateTimeInput } from '@/lib/date-utils';
|
||||
|
||||
interface TaskBasicFieldsProps {
|
||||
title: string;
|
||||
@@ -109,7 +110,10 @@ export function TaskBasicFields({
|
||||
<Input
|
||||
label="Date d'échéance"
|
||||
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)}
|
||||
disabled={loading}
|
||||
/>
|
||||
|
||||
@@ -34,26 +34,28 @@ export function normalizeDate(date: Date): Date {
|
||||
* @param date - Date à formater
|
||||
* @returns Format YYYY-MM-DD
|
||||
*/
|
||||
export function formatDateForAPI(date: Date): string {
|
||||
if (!isValid(date)) {
|
||||
export function formatDateForAPI(date: Date | string): string {
|
||||
const ensuredDate = ensureDate(date);
|
||||
if (!ensuredDate || !isValid(ensuredDate)) {
|
||||
throw new Error('Date invalide fournie à formatDateForAPI');
|
||||
}
|
||||
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const year = ensuredDate.getFullYear();
|
||||
const month = String(ensuredDate.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(ensuredDate.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formate une date pour l'affichage en français
|
||||
*/
|
||||
export function formatDateForDisplay(date: Date, formatType: keyof typeof DATE_FORMATS = 'DISPLAY_MEDIUM'): string {
|
||||
if (!isValid(date)) {
|
||||
export function formatDateForDisplay(date: Date | string, formatType: keyof typeof DATE_FORMATS = 'DISPLAY_MEDIUM'): string {
|
||||
const ensuredDate = ensureDate(date);
|
||||
if (!ensuredDate || !isValid(ensuredDate)) {
|
||||
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
|
||||
*/
|
||||
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 diffTime = today.getTime() - normalizeDate(date).getTime();
|
||||
const diffTime = today.getTime() - normalizeDate(ensuredDate).getTime();
|
||||
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
|
||||
*/
|
||||
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();
|
||||
return normalizeDate(date).getTime() === normalizeDate(today).getTime();
|
||||
return normalizeDate(ensuredDate).getTime() === normalizeDate(today).getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
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)
|
||||
*/
|
||||
export function isSameDay(date1: Date, date2: Date): boolean {
|
||||
return normalizeDate(date1).getTime() === normalizeDate(date2).getTime();
|
||||
export function isSameDay(date1: Date | string, date2: Date | string): boolean {
|
||||
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
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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