From 2e1f3a77fbb8990d4234647365219e04e573c12f Mon Sep 17 00:00:00 2001 From: Gilles Soulier Date: Sun, 24 May 2026 12:18:20 +0200 Subject: [PATCH] =?UTF-8?q?fix(todos):=20types=20union=20TodoCreate,=20ges?= =?UTF-8?q?tion=20erreurs=20handlers,=20transition=20SwipeableRow=20r?= =?UTF-8?q?=C3=A9active?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/api/todos.ts | 8 ++-- .../src/components/todos/SwipeableRow.tsx | 9 ++-- frontend/src/pages/TodosPage.tsx | 44 +++++++++++++++---- 3 files changed, 43 insertions(+), 18 deletions(-) diff --git a/frontend/src/api/todos.ts b/frontend/src/api/todos.ts index 2f9c690..e145bd0 100644 --- a/frontend/src/api/todos.ts +++ b/frontend/src/api/todos.ts @@ -23,8 +23,8 @@ export interface TodoCreate { domain?: string category?: string tags?: string[] - status?: string - priority?: string + status?: 'pending' | 'done' | 'cancelled' + priority?: 'low' | 'medium' | 'high' due_date?: string } @@ -35,8 +35,8 @@ export interface TodoUpdate { domain?: string category?: string tags?: string[] - status?: string - priority?: string + status?: 'pending' | 'done' | 'cancelled' + priority?: 'low' | 'medium' | 'high' due_date?: string } diff --git a/frontend/src/components/todos/SwipeableRow.tsx b/frontend/src/components/todos/SwipeableRow.tsx index 2a34ee5..e387293 100644 --- a/frontend/src/components/todos/SwipeableRow.tsx +++ b/frontend/src/components/todos/SwipeableRow.tsx @@ -10,17 +10,16 @@ const THRESHOLD = 80 // pixels pour déclencher une action export default function SwipeableRow({ children, rightContent, onSwipeRight }: SwipeableRowProps) { const [offsetX, setOffsetX] = useState(0) + const [isDragging, setIsDragging] = useState(false) const startX = useRef(null) - const dragging = useRef(false) function onTouchStart(e: React.TouchEvent) { startX.current = e.touches[0].clientX - dragging.current = false + setIsDragging(true) } function onTouchMove(e: React.TouchEvent) { if (startX.current === null) return - dragging.current = true const dx = e.touches[0].clientX - startX.current // Clamp : +120px à droite, -160px à gauche (largeur des boutons) setOffsetX(Math.max(Math.min(dx, 120), -160)) @@ -31,8 +30,8 @@ export default function SwipeableRow({ children, rightContent, onSwipeRight }: S onSwipeRight() } setOffsetX(0) + setIsDragging(false) startX.current = null - dragging.current = false } const revealActions = offsetX < -(THRESHOLD / 2) @@ -64,7 +63,7 @@ export default function SwipeableRow({ children, rightContent, onSwipeRight }: S onTouchEnd={onTouchEnd} style={{ transform: `translateX(${offsetX}px)`, - transition: dragging.current ? 'none' : 'transform 0.2s ease', + transition: isDragging ? 'none' : 'transform 0.2s ease', background: offsetX > THRESHOLD / 2 ? 'var(--ok)' : 'var(--bg-3)', position: 'relative', zIndex: 1, diff --git a/frontend/src/pages/TodosPage.tsx b/frontend/src/pages/TodosPage.tsx index f4a5d84..c0c9edf 100644 --- a/frontend/src/pages/TodosPage.tsx +++ b/frontend/src/pages/TodosPage.tsx @@ -29,13 +29,17 @@ const selectStyle: React.CSSProperties = { export default function TodosPage() { const [todos, setTodos] = useState([]) const [loading, setLoading] = useState(true) + const [error, setError] = useState(null) const [showForm, setShowForm] = useState(false) const [filters, setFilters] = useState({ status: 'pending' }) const load = useCallback(async () => { setLoading(true) + setError(null) try { setTodos(await fetchTodos(filters)) + } catch { + setError('Erreur lors du chargement des tâches') } finally { setLoading(false) } @@ -44,24 +48,40 @@ export default function TodosPage() { useEffect(() => { void load() }, [load]) async function handleCreate(data: TodoCreate) { - await createTodo(data) - setShowForm(false) - void load() + try { + await createTodo(data) + setShowForm(false) + void load() + } catch { + setError('Erreur lors de la création') + } } async function handleDone(id: string) { - await updateTodo(id, { status: 'done' }) - void load() + try { + await updateTodo(id, { status: 'done' }) + void load() + } catch { + setError('Erreur lors de la mise à jour') + } } async function handleDelete(id: string) { - await deleteTodo(id) - void load() + try { + await deleteTodo(id) + void load() + } catch { + setError('Erreur lors de la suppression') + } } async function handlePostpone(id: string, days: 1 | 7) { - await postponeTodo(id, days) - void load() + try { + await postponeTodo(id, days) + void load() + } catch { + setError('Erreur lors du report') + } } // Grouper par domaine pour la vue mobile @@ -110,6 +130,12 @@ export default function TodosPage() { + {error && ( +

+ {error} +

+ )} + {/* Formulaire de création */} {showForm && (