- Introduced SchedulersPage for managing scheduled tasks. - Implemented CreateTaskDialog for creating new scheduled tasks. - Added SchedulersHeader for filtering and searching tasks. - Created SchedulersTable to display scheduled tasks with actions. - Implemented loading and error states with SchedulersLoadingStates. - Added API service for task management in schedulers. - Enhanced date formatting utility to handle timezone. - Updated AppSidebar and AppRoutes to include SchedulersPage.
145 lines
4.1 KiB
TypeScript
145 lines
4.1 KiB
TypeScript
import { formatDistanceToNow } from 'date-fns';
|
|
|
|
/**
|
|
* Parse and optionally convert a date string to a Date object with timezone handling
|
|
* @param dateString - The date string to parse
|
|
* @param isUTC - Whether to convert from UTC to local timezone (default: true)
|
|
* @returns Processed Date object or null if invalid
|
|
*/
|
|
function parseAndConvertDate(dateString: string, isUTC: boolean = true): Date | null {
|
|
try {
|
|
// If isUTC is true and the date string doesn't have timezone info, treat it as UTC
|
|
let dateToProcess = dateString;
|
|
if (isUTC && !dateString.endsWith('Z') && !dateString.includes('+') && !dateString.includes('-', 10)) {
|
|
dateToProcess = `${dateString}Z`;
|
|
}
|
|
|
|
const date = new Date(dateToProcess);
|
|
|
|
if (isNaN(date.getTime())) {
|
|
return null;
|
|
}
|
|
|
|
if (!isUTC) {
|
|
return date;
|
|
}
|
|
|
|
// Get timezone from localStorage, default to Europe/Paris
|
|
const timezone = localStorage.getItem('timezone') || 'Europe/Paris';
|
|
|
|
// Format the date in the target timezone
|
|
const formatter = new Intl.DateTimeFormat('fr-FR', {
|
|
timeZone: timezone,
|
|
year: 'numeric',
|
|
month: '2-digit',
|
|
day: '2-digit',
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
second: '2-digit',
|
|
hour12: false
|
|
});
|
|
|
|
const parts = formatter.formatToParts(date);
|
|
const partsObj = parts.reduce((acc, part) => {
|
|
acc[part.type] = part.value;
|
|
return acc;
|
|
}, {} as Record<string, string>);
|
|
|
|
// Create new date object in the target timezone
|
|
return new Date(
|
|
parseInt(partsObj.year),
|
|
parseInt(partsObj.month) - 1, // Month is 0-indexed
|
|
parseInt(partsObj.day),
|
|
parseInt(partsObj.hour),
|
|
parseInt(partsObj.minute),
|
|
parseInt(partsObj.second)
|
|
);
|
|
} catch (error) {
|
|
console.error('Error parsing date:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Format a date string to DD/MM/YYYY HH:MM:SS or DD/MM/YYYY
|
|
* @param dateString - The date string to format
|
|
* @param withTime - Whether to include time in the output (default: true)
|
|
* @param isUTC - Whether to convert from UTC to local timezone (default: true)
|
|
* @returns Formatted date string
|
|
*/
|
|
export function formatDate(
|
|
dateString: string,
|
|
withTime: boolean = true,
|
|
isUTC: boolean = true
|
|
): string {
|
|
const date = parseAndConvertDate(dateString, isUTC);
|
|
|
|
if (!date) {
|
|
return 'Invalid Date';
|
|
}
|
|
|
|
const day = date.getDate().toString().padStart(2, '0');
|
|
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
const year = date.getFullYear().toString();
|
|
|
|
const dateFormatted = `${day}/${month}/${year}`;
|
|
|
|
if (!withTime) {
|
|
return dateFormatted;
|
|
}
|
|
|
|
const hours = date.getHours().toString().padStart(2, '0');
|
|
const minutes = date.getMinutes().toString().padStart(2, '0');
|
|
const seconds = date.getSeconds().toString().padStart(2, '0');
|
|
|
|
return `${dateFormatted} ${hours}:${minutes}:${seconds}`;
|
|
}
|
|
|
|
/**
|
|
* Format a date string to show distance to now (e.g., "2 hours ago", "3 days ago")
|
|
* @param dateString - The date string to format
|
|
* @param isUTC - Whether to convert from UTC to local timezone (default: true)
|
|
* @returns Formatted distance string (e.g., "2 hours ago")
|
|
*/
|
|
export function formatDateDistanceToNow(
|
|
dateString: string,
|
|
isUTC: boolean = true
|
|
): string {
|
|
const date = parseAndConvertDate(dateString, isUTC);
|
|
|
|
if (!date) {
|
|
return 'Invalid Date';
|
|
}
|
|
|
|
return formatDistanceToNow(date, { addSuffix: true });
|
|
}
|
|
|
|
/**
|
|
* Format a date string with timezone consideration
|
|
* @param dateString - The date string to format
|
|
* @param timezone - The target timezone (default: 'UTC')
|
|
* @returns Formatted date string with timezone
|
|
*/
|
|
export function formatDateTime(dateString: string, timezone: string = 'UTC'): string {
|
|
try {
|
|
const date = new Date(dateString)
|
|
|
|
if (isNaN(date.getTime())) {
|
|
return 'Invalid Date'
|
|
}
|
|
|
|
const formatter = new Intl.DateTimeFormat('fr-FR', {
|
|
timeZone: timezone,
|
|
year: 'numeric',
|
|
month: '2-digit',
|
|
day: '2-digit',
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
hour12: false,
|
|
})
|
|
|
|
return formatter.format(date)
|
|
} catch {
|
|
return 'Invalid Date'
|
|
}
|
|
} |