feat(DailyCheckboxItem, TaskCard, DailyService): enhance task emoji handling and improve data fetching

- Added emoji support in DailyCheckboxItem and TaskCard components using getTaskEmoji.
- Updated DailyService to include taskTags and primaryTag in checkbox data fetching, improving task detail retrieval.
- Refactored mapPrismaCheckbox to handle taskTags and primaryTag extraction for better task representation.
This commit is contained in:
Julien Froidefond
2025-11-03 09:29:37 +01:00
parent 08f3fb6e85
commit 9fc355abad
4 changed files with 299 additions and 38 deletions

96
src/lib/task-emoji.ts Normal file
View File

@@ -0,0 +1,96 @@
import emojiRegex from 'emoji-regex';
import { Task, Tag } from './types';
/**
* Extrait les emojis d'un texte
*/
export function extractEmojis(text: string): string[] {
const regex = emojiRegex();
return text.match(regex) || [];
}
/**
* Type pour représenter une tâche partielle avec les propriétés nécessaires pour extraire l'emoji
*/
type TaskForEmoji = Pick<Task, 'title'> &
Partial<Pick<Task, 'tags' | 'primaryTagId' | 'tagDetails' | 'primaryTag'>>;
/**
* Extrait l'emoji principal d'une tâche en suivant la logique du TaskCard:
* 1. D'abord, cherche les emojis dans le titre de la tâche
* 2. Si pas trouvé, cherche dans le tag prioritaire (primaryTag)
* 3. Si pas trouvé, cherche dans le premier tag disponible
*
* @param task La tâche (complète ou partielle) à partir de laquelle extraire l'emoji
* @param availableTags Les tags disponibles (optionnel, pour la recherche par tag)
* @returns Le premier emoji trouvé, ou null si aucun emoji n'est trouvé
*/
export function getTaskEmoji(
task: TaskForEmoji | Task | null | undefined,
availableTags?: Tag[]
): string | null {
if (!task || !task.title) {
return null;
}
// 1. Chercher les emojis dans le titre
const titleEmojis = extractEmojis(task.title);
if (titleEmojis.length > 0) {
return titleEmojis[0]; // Prendre seulement le premier emoji
}
// 2. Si pas d'emoji dans le titre, utiliser l'emoji du tag prioritaire ou du premier tag
if (task.tags && task.tags.length > 0 && availableTags) {
// Priorité au tag prioritaire, sinon premier tag
let tagToUse: Tag | null = null;
if (task.primaryTagId) {
tagToUse =
availableTags.find((tag) => tag.id === task.primaryTagId) || null;
}
if (!tagToUse && task.primaryTag) {
tagToUse = task.primaryTag;
}
if (!tagToUse) {
// Chercher par nom du premier tag
const firstTagName = task.tags[0];
tagToUse = availableTags.find((tag) => tag.name === firstTagName) || null;
}
if (tagToUse) {
const tagEmojis = extractEmojis(tagToUse.name);
if (tagEmojis.length > 0) {
return tagEmojis[0]; // Prendre seulement le premier emoji du tag
}
}
}
// 3. Si la tâche a tagDetails directement (sans avoir besoin de availableTags)
if (task.tagDetails && task.tagDetails.length > 0) {
let tagToUse: Tag | null = null;
if (task.primaryTagId) {
tagToUse =
task.tagDetails.find((tag) => tag.id === task.primaryTagId) || null;
}
if (!tagToUse && task.primaryTag) {
tagToUse = task.primaryTag;
}
if (!tagToUse) {
tagToUse = task.tagDetails[0];
}
if (tagToUse) {
const tagEmojis = extractEmojis(tagToUse.name);
if (tagEmojis.length > 0) {
return tagEmojis[0];
}
}
}
return null;
}