refactor: date utils and all calls
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
|
||||
import { Card } from '@/components/ui/Card';
|
||||
import { parseDate, formatDateShort } from '@/lib/date-utils';
|
||||
|
||||
interface CompletionTrendData {
|
||||
date: string;
|
||||
@@ -18,11 +19,11 @@ interface CompletionTrendChartProps {
|
||||
export function CompletionTrendChart({ data, title = "Tendance de Completion" }: CompletionTrendChartProps) {
|
||||
// Formatter pour les dates
|
||||
const formatDate = (dateStr: string) => {
|
||||
const date = new Date(dateStr);
|
||||
return date.toLocaleDateString('fr-FR', {
|
||||
day: 'numeric',
|
||||
month: 'short'
|
||||
});
|
||||
try {
|
||||
return formatDateShort(parseDate(dateStr));
|
||||
} catch {
|
||||
return dateStr;
|
||||
}
|
||||
};
|
||||
|
||||
// Tooltip personnalisé
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { Card } from '@/components/ui/Card';
|
||||
import { formatDateForAPI, createDate, getToday } from '@/lib/date-utils';
|
||||
|
||||
interface DailyCalendarProps {
|
||||
currentDate: Date;
|
||||
@@ -15,33 +16,30 @@ export function DailyCalendar({
|
||||
onDateSelect,
|
||||
dailyDates,
|
||||
}: DailyCalendarProps) {
|
||||
const [viewDate, setViewDate] = useState(new Date(currentDate));
|
||||
const [viewDate, setViewDate] = useState(createDate(currentDate));
|
||||
|
||||
// Formatage des dates pour comparaison (éviter le décalage timezone)
|
||||
const formatDateKey = (date: Date) => {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
return formatDateForAPI(date);
|
||||
};
|
||||
|
||||
const currentDateKey = formatDateKey(currentDate);
|
||||
|
||||
// Navigation mois
|
||||
const goToPreviousMonth = () => {
|
||||
const newDate = new Date(viewDate);
|
||||
const newDate = createDate(viewDate);
|
||||
newDate.setMonth(newDate.getMonth() - 1);
|
||||
setViewDate(newDate);
|
||||
};
|
||||
|
||||
const goToNextMonth = () => {
|
||||
const newDate = new Date(viewDate);
|
||||
const newDate = createDate(viewDate);
|
||||
newDate.setMonth(newDate.getMonth() + 1);
|
||||
setViewDate(newDate);
|
||||
};
|
||||
|
||||
const goToToday = () => {
|
||||
const today = new Date();
|
||||
const today = getToday();
|
||||
setViewDate(today);
|
||||
onDateSelect(today);
|
||||
};
|
||||
@@ -57,18 +55,18 @@ export function DailyCalendar({
|
||||
const lastDay = new Date(year, month + 1, 0);
|
||||
|
||||
// Premier lundi de la semaine contenant le premier jour
|
||||
const startDate = new Date(firstDay);
|
||||
const startDate = createDate(firstDay);
|
||||
const dayOfWeek = firstDay.getDay();
|
||||
const daysToSubtract = dayOfWeek === 0 ? 6 : dayOfWeek - 1; // Lundi = 0
|
||||
startDate.setDate(firstDay.getDate() - daysToSubtract);
|
||||
|
||||
// Générer toutes les dates du calendrier (6 semaines)
|
||||
const days = [];
|
||||
const currentDay = new Date(startDate);
|
||||
const currentDay = createDate(startDate);
|
||||
|
||||
for (let i = 0; i < 42; i++) {
|
||||
// 6 semaines × 7 jours
|
||||
days.push(new Date(currentDay));
|
||||
days.push(createDate(currentDay));
|
||||
currentDay.setDate(currentDay.getDate() + 1);
|
||||
}
|
||||
|
||||
@@ -81,8 +79,8 @@ export function DailyCalendar({
|
||||
onDateSelect(date);
|
||||
};
|
||||
|
||||
const isToday = (date: Date) => {
|
||||
const today = new Date();
|
||||
const isTodayDate = (date: Date) => {
|
||||
const today = getToday();
|
||||
return formatDateKey(date) === formatDateKey(today);
|
||||
};
|
||||
|
||||
@@ -157,7 +155,7 @@ export function DailyCalendar({
|
||||
<div className="grid grid-cols-7 gap-1">
|
||||
{days.map((date, index) => {
|
||||
const isCurrentMonthDay = isCurrentMonth(date);
|
||||
const isTodayDay = isToday(date);
|
||||
const isTodayDay = isTodayDate(date);
|
||||
const hasCheckboxes = hasDaily(date);
|
||||
const isSelectedDay = isSelected(date);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useWeeklyMetrics, useVelocityTrends } from '@/hooks/use-metrics';
|
||||
import { getToday } from '@/lib/date-utils';
|
||||
import { Card, CardHeader, CardContent } from '@/components/ui/Card';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { DailyStatusChart } from './charts/DailyStatusChart';
|
||||
@@ -19,7 +20,7 @@ interface MetricsTabProps {
|
||||
}
|
||||
|
||||
export function MetricsTab({ className }: MetricsTabProps) {
|
||||
const [selectedDate] = useState<Date>(new Date());
|
||||
const [selectedDate] = useState<Date>(getToday());
|
||||
const [weeksBack, setWeeksBack] = useState(4);
|
||||
|
||||
const { metrics, loading: metricsLoading, error: metricsError, refetch: refetchMetrics } = useWeeklyMetrics(selectedDate);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend } from 'recharts';
|
||||
import { DailyMetrics } from '@/services/metrics';
|
||||
import { parseDate, formatDateShort } from '@/lib/date-utils';
|
||||
|
||||
interface DailyStatusChartProps {
|
||||
data: DailyMetrics[];
|
||||
@@ -12,7 +13,7 @@ export function DailyStatusChart({ data, className }: DailyStatusChartProps) {
|
||||
// Transformer les données pour le graphique
|
||||
const chartData = data.map(day => ({
|
||||
day: day.dayName.substring(0, 3), // Lun, Mar, etc.
|
||||
date: new Date(day.date).toLocaleDateString('fr-FR', { day: '2-digit', month: '2-digit' }),
|
||||
date: formatDateShort(parseDate(day.date)),
|
||||
'Complétées': day.completed,
|
||||
'En cours': day.inProgress,
|
||||
'Bloquées': day.blocked,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { DailyMetrics } from '@/services/metrics';
|
||||
import { parseDate, isToday } from '@/lib/date-utils';
|
||||
|
||||
interface WeeklyActivityHeatmapProps {
|
||||
data: DailyMetrics[];
|
||||
@@ -67,7 +68,7 @@ export function WeeklyActivityHeatmap({ data, className }: WeeklyActivityHeatmap
|
||||
</div>
|
||||
|
||||
{/* Indicator si jour actuel */}
|
||||
{new Date(day.date).toDateString() === new Date().toDateString() && (
|
||||
{isToday(parseDate(day.date)) && (
|
||||
<div className="w-2 h-2 bg-blue-500 rounded-full"></div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useState, useEffect, useCallback, useTransition } from 'react';
|
||||
import { DailyCheckbox } from '@/lib/types';
|
||||
import { tasksClient } from '@/clients/tasks-client';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { formatDateSmart } from '@/lib/date-utils';
|
||||
import { Input } from '@/components/ui/Input';
|
||||
import { addTodoToTask, toggleCheckbox } from '@/actions/daily';
|
||||
|
||||
@@ -82,11 +83,7 @@ export function RelatedTodos({ taskId }: RelatedTodosProps) {
|
||||
if (isNaN(dateObj.getTime())) {
|
||||
return 'Date invalide';
|
||||
}
|
||||
return new Intl.DateTimeFormat('fr-FR', {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
year: 'numeric'
|
||||
}).format(dateObj);
|
||||
return formatDateSmart(dateObj);
|
||||
} catch (error) {
|
||||
console.error('Erreur formatage date:', error, date);
|
||||
return 'Date invalide';
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Button } from '@/components/ui/Button';
|
||||
import { Badge } from '@/components/ui/Badge';
|
||||
import { Modal } from '@/components/ui/Modal';
|
||||
import { Card, CardHeader, CardContent } from '@/components/ui/Card';
|
||||
import { formatDateForDisplay, getToday } from '@/lib/date-utils';
|
||||
|
||||
interface AnomalyDetectionPanelProps {
|
||||
className?: string;
|
||||
@@ -42,7 +43,7 @@ export default function AnomalyDetectionPanel({ className = '' }: AnomalyDetecti
|
||||
|
||||
if (result.success && result.data) {
|
||||
setAnomalies(result.data);
|
||||
setLastUpdate(new Date().toLocaleString('fr-FR'));
|
||||
setLastUpdate(formatDateForDisplay(getToday(), 'DISPLAY_LONG'));
|
||||
} else {
|
||||
setError(result.error || 'Erreur lors de la détection');
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Card, CardHeader, CardContent } from '@/components/ui/Card';
|
||||
import { Input } from '@/components/ui/Input';
|
||||
import { Modal } from '@/components/ui/Modal';
|
||||
import { Header } from '@/components/ui/Header';
|
||||
import { formatDateForDisplay } from '@/lib/date-utils';
|
||||
import Link from 'next/link';
|
||||
|
||||
interface BackupSettingsPageClientProps {
|
||||
@@ -193,16 +194,8 @@ export default function BackupSettingsPageClient({ initialData }: BackupSettings
|
||||
|
||||
const formatDate = (date: string | Date): string => {
|
||||
// Format cohérent serveur/client pour éviter les erreurs d'hydratation
|
||||
const d = new Date(date);
|
||||
return d.toLocaleDateString('fr-FR', {
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
hour12: false
|
||||
});
|
||||
const d = typeof date === 'string' ? new Date(date) : date;
|
||||
return formatDateForDisplay(d, 'DISPLAY_MEDIUM');
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
|
||||
Reference in New Issue
Block a user