Feat: Ajout de l'icône de priorité pour les tâches

Implémente un système de marquage de priorité pour les tâches avec une
icône étoile cliquable.

Fonctionnalités ajoutées :
- Champ priority (BOOLEAN) ajouté aux tables global_todos et note_todos
- Migration automatique avec script add-priority-field.js
- Route API PATCH /api/todos/:id/priority pour basculer la priorité
- Icône étoile (Star) dans l'interface frontend
- Tri automatique : tâches prioritaires en premier
- Index PostgreSQL pour optimiser les performances

Comportement de l'icône :
- Toujours visible et jaune quand la tâche est prioritaire
- Visible au survol (hover) quand la tâche n'est pas prioritaire
- Un clic bascule l'état prioritaire/non prioritaire
- Affichage discret (opacity 50%) pour les tâches complétées

Scripts npm ajoutés :
- npm run db:migrate:priority - Exécuter la migration

Routes API mises à jour :
- GET /api/todos - Inclut le champ priority, tri par priorité
- POST /api/todos - Accepte le champ priority
- PUT /api/todos/:id - Accepte le champ priority
- PATCH /api/todos/:id/priority - Bascule la priorité (nouveau)

UI améliorée :
- Icône étoile jaune pour les tâches prioritaires
- Animation au survol pour les interactions
- Tooltip explicatif au survol
- Onglets "Actives" et "Complétées" mis à jour
This commit is contained in:
Claude committed 2025-11-21 10:20:00 +00:00
1 parent 86e825b9d1
commit 026f0499f5
6 files changed
+160 -8

No files matched your search

+22 -1
View File
@@ -15,7 +15,7 @@ import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, Command
import { RichTextEditor } from "@/components/RichTextEditor";
import {
PlusCircle, Search, User, LogOut, Settings, ChevronDown, Plus, Archive, Trash2,
Image as ImageIcon, CheckSquare, FileText, Rss, ExternalLink, RefreshCw, Key, Zap, Paperclip, X, Edit, Calendar as CalendarIcon, Tag as TagIcon, MessageSquare, Send, Check, ChevronsUpDown
Image as ImageIcon, CheckSquare, FileText, Rss, ExternalLink, RefreshCw, Key, Zap, Paperclip, X, Edit, Calendar as CalendarIcon, Tag as TagIcon, MessageSquare, Send, Check, ChevronsUpDown, Star
} from "lucide-react";
import AuthService from "@/services/AuthService";
import AdminService from "@/services/AdminService";
@@ -553,6 +553,15 @@ const Index = () => {
}
};
const handleToggleTodoPriority = async (todoId: number) => {
try {
await TodosService.togglePriority(todoId);
setTodos(todos.map(t => t.id === todoId ? { ...t, priority: !t.priority } : t));
} catch (error) {
showError("Erreur lors de la mise à jour de la priorité");
}
};
const handleDeleteTodo = async (todoId: number) => {
try {
await TodosService.deleteTodo(todoId);
@@ -1579,6 +1588,15 @@ const Index = () => {
<span className="text-sm flex-1 leading-snug">
{todo.text}
</span>
<Button
variant="ghost"
size="icon"
className={`h-7 w-7 ${todo.priority ? '' : 'opacity-0 group-hover:opacity-100'} transition-opacity`}
onClick={() => todo.id && handleToggleTodoPriority(todo.id)}
title={todo.priority ? "Retirer la priorité" : "Marquer comme prioritaire"}
>
<Star className={`h-3.5 w-3.5 ${todo.priority ? 'fill-yellow-400 text-yellow-400' : ''}`} />
</Button>
<Button
variant="ghost"
size="icon"
@@ -1631,6 +1649,9 @@ const Index = () => {
<span className="text-sm flex-1 line-through text-muted-foreground leading-snug">
{todo.text}
</span>
{todo.priority && (
<Star className="h-3.5 w-3.5 fill-yellow-400 text-yellow-400 opacity-50" />
)}
<Button
variant="ghost"
size="icon"
+13 -3
View File
@@ -4,7 +4,7 @@ export interface Todo {
id?: number;
text: string;
completed: boolean;
priority?: 'low' | 'medium' | 'high';
priority?: boolean;
due_date?: string;
created_at?: string;
}
@@ -32,9 +32,9 @@ class TodosService {
}
}
async createTodo(text: string, priority?: 'low' | 'medium' | 'high'): Promise<Todo> {
async createTodo(text: string, priority?: boolean): Promise<Todo> {
try {
const response = await axios.post(this.baseURL, { text, priority, completed: false }, this.getAuthHeader());
const response = await axios.post(this.baseURL, { text, priority: priority || false, completed: false }, this.getAuthHeader());
return response.data;
} catch (error) {
console.error('Error creating todo:', error);
@@ -71,6 +71,16 @@ class TodosService {
throw error;
}
}
async togglePriority(todoId: number): Promise<boolean> {
try {
await axios.patch(`${this.baseURL}/${todoId}/priority`, {}, this.getAuthHeader());
return true;
} catch (error) {
console.error('Error toggling priority:', error);
throw error;
}
}
}
export default new TodosService();