refactor: enhance date handling across components
- Replaced direct date manipulations with utility functions for consistency and readability. - Updated date formatting in `DailyCalendar`, `RecentTasks`, `CompletionRateChart`, and other components to use `formatDateShort` and `formatDateForDisplay`. - Improved date parsing in `JiraLogs`, `JiraSchedulerConfig`, and `BackupSettingsPageClient` to ensure proper handling of date strings. - Streamlined date initialization in `useDaily` and `DailyService` to utilize `getToday` and `getYesterday` for better clarity.
This commit is contained in:
@@ -4,6 +4,8 @@ import React, { useState } from 'react';
|
|||||||
import { Button } from '@/components/ui/Button';
|
import { Button } from '@/components/ui/Button';
|
||||||
import { Card } from '@/components/ui/Card';
|
import { Card } from '@/components/ui/Card';
|
||||||
import { formatDateForAPI, createDate, getToday } from '@/lib/date-utils';
|
import { formatDateForAPI, createDate, getToday } from '@/lib/date-utils';
|
||||||
|
import { format } from 'date-fns';
|
||||||
|
import { fr } from 'date-fns/locale';
|
||||||
|
|
||||||
interface DailyCalendarProps {
|
interface DailyCalendarProps {
|
||||||
currentDate: Date;
|
currentDate: Date;
|
||||||
@@ -97,10 +99,7 @@ export function DailyCalendar({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const formatMonthYear = () => {
|
const formatMonthYear = () => {
|
||||||
return viewDate.toLocaleDateString('fr-FR', {
|
return format(viewDate, 'MMMM yyyy', { locale: fr });
|
||||||
month: 'long',
|
|
||||||
year: 'numeric',
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const weekDays = ['Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim'];
|
const weekDays = ['Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim'];
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import { Task } from '@/lib/types';
|
import { Task } from '@/lib/types';
|
||||||
import { Card } from '@/components/ui/Card';
|
import { Card } from '@/components/ui/Card';
|
||||||
import { TagDisplay } from '@/components/ui/TagDisplay';
|
import { TagDisplay } from '@/components/ui/TagDisplay';
|
||||||
|
import { formatDateShort } from '@/lib/date-utils';
|
||||||
import { Badge } from '@/components/ui/Badge';
|
import { Badge } from '@/components/ui/Badge';
|
||||||
import { useTasksContext } from '@/contexts/TasksContext';
|
import { useTasksContext } from '@/contexts/TasksContext';
|
||||||
import { getPriorityConfig, getPriorityColorHex, getStatusBadgeClasses, getStatusLabel } from '@/lib/status-config';
|
import { getPriorityConfig, getPriorityColorHex, getStatusBadgeClasses, getStatusLabel } from '@/lib/status-config';
|
||||||
@@ -18,7 +19,7 @@ export function RecentTasks({ tasks }: RecentTasksProps) {
|
|||||||
|
|
||||||
// Prendre les 5 tâches les plus récentes (créées ou modifiées)
|
// Prendre les 5 tâches les plus récentes (créées ou modifiées)
|
||||||
const recentTasks = tasks
|
const recentTasks = tasks
|
||||||
.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime())
|
.sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime())
|
||||||
.slice(0, 5);
|
.slice(0, 5);
|
||||||
|
|
||||||
// Fonctions simplifiées utilisant la configuration centralisée
|
// Fonctions simplifiées utilisant la configuration centralisée
|
||||||
@@ -116,10 +117,7 @@ export function RecentTasks({ tasks }: RecentTasksProps) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="text-xs text-[var(--muted-foreground)] whitespace-nowrap">
|
<div className="text-xs text-[var(--muted-foreground)] whitespace-nowrap">
|
||||||
{new Date(task.updatedAt).toLocaleDateString('fr-FR', {
|
{formatDateShort(task.updatedAt)}
|
||||||
day: 'numeric',
|
|
||||||
month: 'short'
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
|
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
|
||||||
import { DailyMetrics } from '@/services/metrics';
|
import { DailyMetrics } from '@/services/metrics';
|
||||||
|
import { parseDate, formatDateShort } from '@/lib/date-utils';
|
||||||
|
|
||||||
interface CompletionRateChartProps {
|
interface CompletionRateChartProps {
|
||||||
data: DailyMetrics[];
|
data: DailyMetrics[];
|
||||||
@@ -12,7 +13,7 @@ export function CompletionRateChart({ data, className }: CompletionRateChartProp
|
|||||||
// Transformer les données pour le graphique
|
// Transformer les données pour le graphique
|
||||||
const chartData = data.map(day => ({
|
const chartData = data.map(day => ({
|
||||||
day: day.dayName.substring(0, 3), // Lun, Mar, etc.
|
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)),
|
||||||
completionRate: day.completionRate,
|
completionRate: day.completionRate,
|
||||||
completed: day.completed,
|
completed: day.completed,
|
||||||
total: day.totalTasks
|
total: day.totalTasks
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { useState, useEffect, useCallback, useTransition } from 'react';
|
|||||||
import { DailyCheckbox } from '@/lib/types';
|
import { DailyCheckbox } from '@/lib/types';
|
||||||
import { tasksClient } from '@/clients/tasks-client';
|
import { tasksClient } from '@/clients/tasks-client';
|
||||||
import { Button } from '@/components/ui/Button';
|
import { Button } from '@/components/ui/Button';
|
||||||
import { formatDateSmart } from '@/lib/date-utils';
|
import { formatDateSmart, parseDate } from '@/lib/date-utils';
|
||||||
import { Input } from '@/components/ui/Input';
|
import { Input } from '@/components/ui/Input';
|
||||||
import { addTodoToTask, toggleCheckbox } from '@/actions/daily';
|
import { addTodoToTask, toggleCheckbox } from '@/actions/daily';
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ export function RelatedTodos({ taskId }: RelatedTodosProps) {
|
|||||||
startTransition(async () => {
|
startTransition(async () => {
|
||||||
try {
|
try {
|
||||||
// Si une date est spécifiée, l'utiliser, sinon undefined (aujourd'hui par défaut)
|
// Si une date est spécifiée, l'utiliser, sinon undefined (aujourd'hui par défaut)
|
||||||
const targetDate = newTodoDate ? new Date(newTodoDate) : undefined;
|
const targetDate = newTodoDate ? parseDate(newTodoDate) : undefined;
|
||||||
|
|
||||||
const result = await addTodoToTask(taskId, newTodoText, targetDate);
|
const result = await addTodoToTask(taskId, newTodoText, targetDate);
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ export function RelatedTodos({ taskId }: RelatedTodosProps) {
|
|||||||
|
|
||||||
const formatDate = (date: Date | string) => {
|
const formatDate = (date: Date | string) => {
|
||||||
try {
|
try {
|
||||||
const dateObj = typeof date === 'string' ? new Date(date) : date;
|
const dateObj = typeof date === 'string' ? parseDate(date) : date;
|
||||||
if (isNaN(dateObj.getTime())) {
|
if (isNaN(dateObj.getTime())) {
|
||||||
return 'Date invalide';
|
return 'Date invalide';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { Badge } from '@/components/ui/Badge';
|
|||||||
import { Button } from '@/components/ui/Button';
|
import { Button } from '@/components/ui/Button';
|
||||||
import { formatDistanceToNow } from 'date-fns';
|
import { formatDistanceToNow } from 'date-fns';
|
||||||
import { fr } from 'date-fns/locale';
|
import { fr } from 'date-fns/locale';
|
||||||
|
import { parseDate } from '@/lib/date-utils';
|
||||||
|
|
||||||
interface SyncLog {
|
interface SyncLog {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -111,7 +112,7 @@ export function JiraLogs({ className = "" }: JiraLogsProps) {
|
|||||||
<div className="flex items-center justify-between mb-2">
|
<div className="flex items-center justify-between mb-2">
|
||||||
{getStatusBadge(log.status)}
|
{getStatusBadge(log.status)}
|
||||||
<span className="text-xs text-[var(--muted-foreground)]">
|
<span className="text-xs text-[var(--muted-foreground)]">
|
||||||
{formatDistanceToNow(new Date(log.createdAt), {
|
{formatDistanceToNow(parseDate(log.createdAt), {
|
||||||
addSuffix: true,
|
addSuffix: true,
|
||||||
locale: fr
|
locale: fr
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { Button } from '@/components/ui/Button';
|
|||||||
import { Card, CardHeader, CardContent } from '@/components/ui/Card';
|
import { Card, CardHeader, CardContent } from '@/components/ui/Card';
|
||||||
import { Badge } from '@/components/ui/Badge';
|
import { Badge } from '@/components/ui/Badge';
|
||||||
import { jiraClient, JiraSchedulerStatus } from '@/clients/jira-client';
|
import { jiraClient, JiraSchedulerStatus } from '@/clients/jira-client';
|
||||||
|
import { parseDate, getToday } from '@/lib/date-utils';
|
||||||
|
|
||||||
interface JiraSchedulerConfigProps {
|
interface JiraSchedulerConfigProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
@@ -85,8 +86,8 @@ export function JiraSchedulerConfig({ className = "" }: JiraSchedulerConfigProps
|
|||||||
const getNextSyncText = () => {
|
const getNextSyncText = () => {
|
||||||
if (!schedulerStatus?.nextSync) return 'Aucune synchronisation planifiée';
|
if (!schedulerStatus?.nextSync) return 'Aucune synchronisation planifiée';
|
||||||
|
|
||||||
const nextSync = new Date(schedulerStatus.nextSync);
|
const nextSync = parseDate(schedulerStatus.nextSync);
|
||||||
const now = new Date();
|
const now = getToday();
|
||||||
const diffMs = nextSync.getTime() - now.getTime();
|
const diffMs = nextSync.getTime() - now.getTime();
|
||||||
|
|
||||||
if (diffMs <= 0) return 'Synchronisation en cours...';
|
if (diffMs <= 0) return 'Synchronisation en cours...';
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useState } from 'react';
|
|||||||
import { Button } from '@/components/ui/Button';
|
import { Button } from '@/components/ui/Button';
|
||||||
import { Card, CardHeader, CardContent } from '@/components/ui/Card';
|
import { Card, CardHeader, CardContent } from '@/components/ui/Card';
|
||||||
import { Badge } from '@/components/ui/Badge';
|
import { Badge } from '@/components/ui/Badge';
|
||||||
|
import { getToday } from '@/lib/date-utils';
|
||||||
import { Modal } from '@/components/ui/Modal';
|
import { Modal } from '@/components/ui/Modal';
|
||||||
import { jiraClient } from '@/clients/jira-client';
|
import { jiraClient } from '@/clients/jira-client';
|
||||||
import { JiraSyncResult, JiraSyncAction } from '@/services/jira';
|
import { JiraSyncResult, JiraSyncAction } from '@/services/jira';
|
||||||
@@ -79,7 +80,7 @@ export function JiraSync({ onSyncComplete, className = "" }: JiraSyncProps) {
|
|||||||
{success ? "✓ Succès" : "⚠ Erreurs"}
|
{success ? "✓ Succès" : "⚠ Erreurs"}
|
||||||
</Badge>
|
</Badge>
|
||||||
<span className="text-[var(--muted-foreground)] text-xs">
|
<span className="text-[var(--muted-foreground)] text-xs">
|
||||||
{new Date().toLocaleTimeString()}
|
{getToday().toLocaleTimeString()}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs text-[var(--muted-foreground)]">
|
<div className="text-xs text-[var(--muted-foreground)]">
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useState, useEffect, useCallback } from 'react';
|
|||||||
import { SprintVelocity, JiraTask, AssigneeDistribution, StatusDistribution } from '@/lib/types';
|
import { SprintVelocity, JiraTask, AssigneeDistribution, StatusDistribution } from '@/lib/types';
|
||||||
import { Modal } from '@/components/ui/Modal';
|
import { Modal } from '@/components/ui/Modal';
|
||||||
import { Card, CardHeader, CardContent } from '@/components/ui/Card';
|
import { Card, CardHeader, CardContent } from '@/components/ui/Card';
|
||||||
|
import { parseDate, formatDateForDisplay } from '@/lib/date-utils';
|
||||||
import { Badge } from '@/components/ui/Badge';
|
import { Badge } from '@/components/ui/Badge';
|
||||||
import { Button } from '@/components/ui/Button';
|
import { Button } from '@/components/ui/Button';
|
||||||
|
|
||||||
@@ -144,7 +145,7 @@ export default function SprintDetailModal({
|
|||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<div className="text-sm text-gray-600">Période</div>
|
<div className="text-sm text-gray-600">Période</div>
|
||||||
<div className="text-xs text-gray-500">
|
<div className="text-xs text-gray-500">
|
||||||
{new Date(sprint.startDate).toLocaleDateString('fr-FR')} - {new Date(sprint.endDate).toLocaleDateString('fr-FR')}
|
{formatDateForDisplay(parseDate(sprint.startDate))} - {formatDateForDisplay(parseDate(sprint.endDate))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -318,7 +319,7 @@ export default function SprintDetailModal({
|
|||||||
<div className="flex items-center gap-4 text-xs text-gray-500">
|
<div className="flex items-center gap-4 text-xs text-gray-500">
|
||||||
<span>📋 {issue.issuetype.name}</span>
|
<span>📋 {issue.issuetype.name}</span>
|
||||||
<span>👤 {issue.assignee?.displayName || 'Non assigné'}</span>
|
<span>👤 {issue.assignee?.displayName || 'Non assigné'}</span>
|
||||||
<span>📅 {new Date(issue.created).toLocaleDateString('fr-FR')}</span>
|
<span>📅 {formatDateForDisplay(parseDate(issue.created))}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -427,7 +427,7 @@ export function TaskCard({ task, onEdit, compactView = false }: TaskCardProps) {
|
|||||||
{task.dueDate ? (
|
{task.dueDate ? (
|
||||||
<span className="flex items-center gap-1 text-[var(--muted-foreground)] font-mono">
|
<span className="flex items-center gap-1 text-[var(--muted-foreground)] font-mono">
|
||||||
<span className="text-[var(--primary)]">⏰</span>
|
<span className="text-[var(--primary)]">⏰</span>
|
||||||
{formatDistanceToNow(new Date(task.dueDate), {
|
{formatDistanceToNow(task.dueDate, {
|
||||||
addSuffix: true,
|
addSuffix: true,
|
||||||
locale: fr
|
locale: fr
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { Button } from '@/components/ui/Button';
|
|||||||
import { UserPreferencesProvider } from '@/contexts/UserPreferencesContext';
|
import { UserPreferencesProvider } from '@/contexts/UserPreferencesContext';
|
||||||
import { backupClient, BackupListResponse } from '@/clients/backup-client';
|
import { backupClient, BackupListResponse } from '@/clients/backup-client';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import { parseDate, getToday, formatDateForDisplay } from '@/lib/date-utils';
|
||||||
|
|
||||||
interface DatabaseStats {
|
interface DatabaseStats {
|
||||||
taskCount: number;
|
taskCount: number;
|
||||||
@@ -86,22 +87,14 @@ export function AdvancedSettingsPageClient({
|
|||||||
|
|
||||||
const formatTimeAgo = (date: Date): string => {
|
const formatTimeAgo = (date: Date): string => {
|
||||||
// Format fixe pour éviter les erreurs d'hydratation
|
// Format fixe pour éviter les erreurs d'hydratation
|
||||||
const d = new Date(date);
|
return formatDateForDisplay(date, 'DISPLAY_MEDIUM');
|
||||||
return d.toLocaleDateString('fr-FR', {
|
|
||||||
day: '2-digit',
|
|
||||||
month: '2-digit',
|
|
||||||
year: 'numeric',
|
|
||||||
hour: '2-digit',
|
|
||||||
minute: '2-digit',
|
|
||||||
hour12: false
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getNextBackupTime = (): string => {
|
const getNextBackupTime = (): string => {
|
||||||
if (!backupData.scheduler.nextBackup) return 'Non planifiée';
|
if (!backupData.scheduler.nextBackup) return 'Non planifiée';
|
||||||
|
|
||||||
const nextBackup = new Date(backupData.scheduler.nextBackup);
|
const nextBackup = parseDate(backupData.scheduler.nextBackup);
|
||||||
const now = new Date();
|
const now = getToday();
|
||||||
const diffMs = nextBackup.getTime() - now.getTime();
|
const diffMs = nextBackup.getTime() - now.getTime();
|
||||||
const diffMins = Math.floor(diffMs / (1000 * 60));
|
const diffMins = Math.floor(diffMs / (1000 * 60));
|
||||||
const diffHours = Math.floor(diffMins / 60);
|
const diffHours = Math.floor(diffMins / 60);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { Card, CardHeader, CardContent } from '@/components/ui/Card';
|
|||||||
import { Input } from '@/components/ui/Input';
|
import { Input } from '@/components/ui/Input';
|
||||||
import { Modal } from '@/components/ui/Modal';
|
import { Modal } from '@/components/ui/Modal';
|
||||||
import { Header } from '@/components/ui/Header';
|
import { Header } from '@/components/ui/Header';
|
||||||
import { formatDateForDisplay } from '@/lib/date-utils';
|
import { formatDateForDisplay, parseDate, getToday } from '@/lib/date-utils';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
interface BackupSettingsPageClientProps {
|
interface BackupSettingsPageClientProps {
|
||||||
@@ -209,8 +209,8 @@ export default function BackupSettingsPageClient({ initialData }: BackupSettings
|
|||||||
const getNextBackupTime = (): string => {
|
const getNextBackupTime = (): string => {
|
||||||
if (!data?.scheduler.nextBackup) return 'Non planifiée';
|
if (!data?.scheduler.nextBackup) return 'Non planifiée';
|
||||||
|
|
||||||
const nextBackup = new Date(data.scheduler.nextBackup);
|
const nextBackup = parseDate(data.scheduler.nextBackup);
|
||||||
const now = new Date();
|
const now = getToday();
|
||||||
const diffMs = nextBackup.getTime() - now.getTime();
|
const diffMs = nextBackup.getTime() - now.getTime();
|
||||||
const diffMins = Math.floor(diffMs / (1000 * 60));
|
const diffMins = Math.floor(diffMs / (1000 * 60));
|
||||||
const diffHours = Math.floor(diffMins / 60);
|
const diffHours = Math.floor(diffMins / 60);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { Input } from '@/components/ui/Input';
|
|||||||
import { TagForm } from '@/components/forms/TagForm';
|
import { TagForm } from '@/components/forms/TagForm';
|
||||||
import { UserPreferencesProvider } from '@/contexts/UserPreferencesContext';
|
import { UserPreferencesProvider } from '@/contexts/UserPreferencesContext';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import { formatDateForDisplay } from '@/lib/date-utils';
|
||||||
|
|
||||||
interface GeneralSettingsPageClientProps {
|
interface GeneralSettingsPageClientProps {
|
||||||
initialPreferences: UserPreferences;
|
initialPreferences: UserPreferences;
|
||||||
@@ -294,7 +295,7 @@ export function GeneralSettingsPageClient({ initialPreferences, initialTags }: G
|
|||||||
</div>
|
</div>
|
||||||
{('createdAt' in tag && (tag as Tag & { createdAt: Date }).createdAt) && (
|
{('createdAt' in tag && (tag as Tag & { createdAt: Date }).createdAt) && (
|
||||||
<div className="text-xs text-[var(--muted-foreground)]">
|
<div className="text-xs text-[var(--muted-foreground)]">
|
||||||
Créé le {new Date((tag as Tag & { createdAt: Date }).createdAt).toLocaleDateString('fr-FR')}
|
Créé le {formatDateForDisplay((tag as Tag & { createdAt: Date }).createdAt)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ interface UseDailyActions {
|
|||||||
* Hook pour la gestion d'une vue daily spécifique
|
* Hook pour la gestion d'une vue daily spécifique
|
||||||
*/
|
*/
|
||||||
export function useDaily(initialDate?: Date, initialDailyView?: DailyView): UseDailyState & UseDailyActions & { currentDate: Date } {
|
export function useDaily(initialDate?: Date, initialDailyView?: DailyView): UseDailyState & UseDailyActions & { currentDate: Date } {
|
||||||
const [currentDate, setCurrentDate] = useState<Date>(initialDate || new Date());
|
const [currentDate, setCurrentDate] = useState<Date>(initialDate || getToday());
|
||||||
const [dailyView, setDailyView] = useState<DailyView | null>(initialDailyView || null);
|
const [dailyView, setDailyView] = useState<DailyView | null>(initialDailyView || null);
|
||||||
const [loading, setLoading] = useState(!initialDailyView); // Pas de loading si on a des données SSR
|
const [loading, setLoading] = useState(!initialDailyView); // Pas de loading si on a des données SSR
|
||||||
const [refreshing, setRefreshing] = useState(false); // Pour les refresh silencieux
|
const [refreshing, setRefreshing] = useState(false); // Pour les refresh silencieux
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { prisma } from './database';
|
import { prisma } from './database';
|
||||||
import { Prisma } from '@prisma/client';
|
import { Prisma } from '@prisma/client';
|
||||||
import { DailyCheckbox, DailyView, CreateDailyCheckboxData, UpdateDailyCheckboxData, BusinessError, DailyCheckboxType, TaskStatus, TaskPriority, TaskSource } from '@/lib/types';
|
import { DailyCheckbox, DailyView, CreateDailyCheckboxData, UpdateDailyCheckboxData, BusinessError, DailyCheckboxType, TaskStatus, TaskPriority, TaskSource } from '@/lib/types';
|
||||||
import { getPreviousWorkday, normalizeDate, formatDateForAPI } from '@/lib/date-utils';
|
import { getPreviousWorkday, normalizeDate, formatDateForAPI, getToday, getYesterday } from '@/lib/date-utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service pour la gestion des checkboxes daily
|
* Service pour la gestion des checkboxes daily
|
||||||
@@ -180,7 +180,7 @@ export class DailyService {
|
|||||||
* Récupère la vue daily d'aujourd'hui
|
* Récupère la vue daily d'aujourd'hui
|
||||||
*/
|
*/
|
||||||
async getTodaysDailyView(): Promise<DailyView> {
|
async getTodaysDailyView(): Promise<DailyView> {
|
||||||
return this.getDailyView(new Date());
|
return this.getDailyView(getToday());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -188,7 +188,7 @@ export class DailyService {
|
|||||||
*/
|
*/
|
||||||
async addTodayCheckbox(text: string, taskId?: string): Promise<DailyCheckbox> {
|
async addTodayCheckbox(text: string, taskId?: string): Promise<DailyCheckbox> {
|
||||||
return this.addCheckbox({
|
return this.addCheckbox({
|
||||||
date: new Date(),
|
date: getToday(),
|
||||||
text,
|
text,
|
||||||
taskId
|
taskId
|
||||||
});
|
});
|
||||||
@@ -198,11 +198,8 @@ export class DailyService {
|
|||||||
* Ajoute une checkbox pour hier
|
* Ajoute une checkbox pour hier
|
||||||
*/
|
*/
|
||||||
async addYesterdayCheckbox(text: string, taskId?: string): Promise<DailyCheckbox> {
|
async addYesterdayCheckbox(text: string, taskId?: string): Promise<DailyCheckbox> {
|
||||||
const yesterday = new Date();
|
|
||||||
yesterday.setDate(yesterday.getDate() - 1);
|
|
||||||
|
|
||||||
return this.addCheckbox({
|
return this.addCheckbox({
|
||||||
date: yesterday,
|
date: getYesterday(),
|
||||||
text,
|
text,
|
||||||
taskId
|
taskId
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
import { JiraTask } from '@/lib/types';
|
import { JiraTask } from '@/lib/types';
|
||||||
import { prisma } from './database';
|
import { prisma } from './database';
|
||||||
import { parseDate } from '@/lib/date-utils';
|
import { parseDate, formatDateForDisplay } from '@/lib/date-utils';
|
||||||
|
|
||||||
export interface JiraConfig {
|
export interface JiraConfig {
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
@@ -389,8 +389,8 @@ export class JiraService {
|
|||||||
changes.push(`Priorité: préservée localement (${existingTask.priority})`);
|
changes.push(`Priorité: préservée localement (${existingTask.priority})`);
|
||||||
}
|
}
|
||||||
if ((existingTask.dueDate?.getTime() || null) !== (taskData.dueDate?.getTime() || null)) {
|
if ((existingTask.dueDate?.getTime() || null) !== (taskData.dueDate?.getTime() || null)) {
|
||||||
const oldDate = existingTask.dueDate ? existingTask.dueDate.toLocaleDateString() : 'Aucune';
|
const oldDate = existingTask.dueDate ? formatDateForDisplay(existingTask.dueDate) : 'Aucune';
|
||||||
const newDate = taskData.dueDate ? taskData.dueDate.toLocaleDateString() : 'Aucune';
|
const newDate = taskData.dueDate ? formatDateForDisplay(taskData.dueDate) : 'Aucune';
|
||||||
changes.push(`Échéance: ${oldDate} → ${newDate}`);
|
changes.push(`Échéance: ${oldDate} → ${newDate}`);
|
||||||
}
|
}
|
||||||
if (existingTask.jiraProject !== taskData.jiraProject) {
|
if (existingTask.jiraProject !== taskData.jiraProject) {
|
||||||
|
|||||||
Reference in New Issue
Block a user