feat(DailyPage, DailyService, Calendar): enhance task deadline management and UI integration

- Implemented user authentication in the daily dates API route to ensure secure access.
- Added functionality to retrieve task deadlines and associated tasks, improving task management capabilities.
- Updated DailyPageClient to display tasks with deadlines in the calendar view, enhancing user experience.
- Enhanced Calendar component to visually indicate deadline dates, providing clearer task management context.
This commit is contained in:
Julien Froidefond
2025-11-11 08:46:19 +01:00
parent f7c9926348
commit 8340008839
8 changed files with 435 additions and 29 deletions

View File

@@ -10,6 +10,7 @@ import {
TaskStatus,
TaskPriority,
TaskSource,
Task,
} from '@/lib/types';
import {
getPreviousWorkday,
@@ -466,6 +467,137 @@ export class DailyService {
});
}
/**
* Récupère toutes les dates de fin (dueDate) des tâches non terminées (pour le calendrier)
* Retourne un objet avec les dates comme clés et les tâches associées
*/
async getTaskDeadlineDates(
userId: string
): Promise<Record<string, string[]>> {
const tasks = await prisma.task.findMany({
where: {
ownerId: userId,
dueDate: {
not: null,
},
status: {
notIn: ['done', 'cancelled', 'archived'],
},
},
select: {
id: true,
title: true,
dueDate: true,
},
orderBy: {
dueDate: 'asc',
},
});
const datesMap: Record<string, string[]> = {};
tasks.forEach((task) => {
if (!task.dueDate) return;
// Normaliser la date pour éviter les problèmes de timezone
const normalizedDate = normalizeDate(task.dueDate);
const dateKey = formatDateForAPI(normalizedDate);
if (!datesMap[dateKey]) {
datesMap[dateKey] = [];
}
datesMap[dateKey].push(task.title);
});
return datesMap;
}
/**
* Récupère les tâches avec deadline pour une date donnée
* Retourne un tableau de tâches complètes
*/
async getTasksByDeadlineDate(userId: string, date: Date): Promise<Task[]> {
const normalizedDate = normalizeDate(date);
const dateKey = formatDateForAPI(normalizedDate);
const tasks = await prisma.task.findMany({
where: {
ownerId: userId,
dueDate: {
not: null,
},
status: {
notIn: ['done', 'cancelled', 'archived'],
},
},
include: {
taskTags: {
include: {
tag: true,
},
},
primaryTag: true,
_count: {
select: {
dailyCheckboxes: true,
},
},
},
orderBy: {
dueDate: 'asc',
},
});
// Filtrer les tâches dont la date de fin correspond à la date demandée
const filteredTasks = tasks
.filter((task) => {
if (!task.dueDate) return false;
const taskDateKey = formatDateForAPI(normalizeDate(task.dueDate));
return taskDateKey === dateKey;
})
.map((task) => ({
id: task.id,
title: task.title,
description: task.description ?? undefined,
status: task.status as TaskStatus,
priority: task.priority as TaskPriority,
source: task.source as TaskSource,
sourceId: task.sourceId ?? undefined,
tags: task.taskTags.map((tt) => tt.tag.name),
tagDetails: task.taskTags.map((tt) => ({
id: tt.tag.id,
name: tt.tag.name,
color: tt.tag.color,
isPinned: tt.tag.isPinned,
})),
primaryTagId: task.primaryTagId ?? undefined,
primaryTag: task.primaryTag
? {
id: task.primaryTag.id,
name: task.primaryTag.name,
color: task.primaryTag.color,
isPinned: task.primaryTag.isPinned,
}
: undefined,
dueDate: task.dueDate ?? undefined,
completedAt: task.completedAt ?? undefined,
createdAt: task.createdAt,
updatedAt: task.updatedAt,
jiraProject: task.jiraProject ?? undefined,
jiraKey: task.jiraKey ?? undefined,
jiraType: task.jiraType ?? undefined,
tfsProject: task.tfsProject ?? undefined,
tfsPullRequestId: task.tfsPullRequestId ?? undefined,
tfsRepository: task.tfsRepository ?? undefined,
tfsSourceBranch: task.tfsSourceBranch ?? undefined,
tfsTargetBranch: task.tfsTargetBranch ?? undefined,
assignee: task.assignee ?? undefined,
ownerId: (task as unknown as { ownerId: string }).ownerId,
todosCount: task._count.dailyCheckboxes,
}));
return filteredTasks;
}
/**
* Récupère toutes les checkboxes non cochées (tâches en attente)
*/