+ {/* Tags */}
+
setTags(e.target.value)}
+ />
+
+ {/* Photo + GPS */}
+
+
+
+
+
+
+ {/* Boutons */}
+
+ >Annuler
+ >{loading ? '…' : submitLabel}
)
diff --git a/frontend/src/pages/TodosPage.tsx b/frontend/src/pages/TodosPage.tsx
index b56507a..36409d4 100644
--- a/frontend/src/pages/TodosPage.tsx
+++ b/frontend/src/pages/TodosPage.tsx
@@ -3,7 +3,7 @@ import { useState, useEffect, useCallback } from 'react'
import type { Todo, TodoCreate, TodoFilters } from '../api/todos'
import { fetchTodos, createTodo, updateTodo, deleteTodo, postponeTodo } from '../api/todos'
import SwipeableRow from '../components/todos/SwipeableRow'
-import TodoForm from '../components/todos/TodoForm'
+import TodoForm, { DOMAIN_COLORS } from '../components/todos/TodoForm'
import Modal from '../components/Modal'
type EditingTodo = Todo | null
@@ -12,9 +12,11 @@ const DOMAINS = [
'informatique', 'diy', 'electronique', 'domotique',
'bricolage', 'jardin', 'cuisine', 'voyage', 'animaux',
]
+
const STATUS_LABELS: Record
= {
pending: 'En cours', done: 'Terminé', cancelled: 'Annulé',
}
+
const PRIORITY_COLORS: Record = {
high: 'var(--err)', medium: 'var(--warn)', low: 'var(--ink-3)',
}
@@ -29,6 +31,8 @@ const selectStyle: React.CSSProperties = {
fontSize: 13,
}
+const noSelect: React.CSSProperties = { userSelect: 'none' }
+
export default function TodosPage() {
const [todos, setTodos] = useState([])
const [loading, setLoading] = useState(true)
@@ -98,20 +102,20 @@ export default function TodosPage() {
}
}
- // Grouper par domaine pour la vue mobile
+ // Grouper par domaine (un todo peut apparaître dans plusieurs groupes)
const grouped = DOMAINS.reduce>((acc, d) => {
- const items = todos.filter(t => t.domain === d)
+ const items = todos.filter(t => t.domains.includes(d))
if (items.length > 0) acc[d] = items
return acc
}, {})
- const sansDomaine = todos.filter(t => !t.domain)
+ const sansDomaine = todos.filter(t => t.domains.length === 0)
if (sansDomaine.length > 0) grouped['—'] = sansDomaine
return (
- {/* En-tête + filtres */}
+ {/* En-tête + filtre statut uniquement */}
-
+
Tâches
-
-
{error && (
@@ -150,29 +136,31 @@ export default function TodosPage() {
)}
- {/* Formulaire de création */}
+ {/* Modal création */}
{showForm && (
setShowForm(false)}>
- setShowForm(false)} extended />
+ setShowForm(false)} />
)}
- {/* Formulaire d'édition */}
+ {/* Modal édition */}
{editingTodo && (
setEditingTodo(null)}>
handleUpdate(editingTodo.id, data)}
onCancel={() => setEditingTodo(null)}
- extended
submitLabel="Enregistrer"
initialValues={{
title: editingTodo.title,
- domain: editingTodo.domain ?? undefined,
+ domains: editingTodo.domains,
priority: editingTodo.priority,
due_date: editingTodo.due_date ?? undefined,
body: editingTodo.body ?? undefined,
url: editingTodo.url ?? undefined,
tags: editingTodo.tags,
+ photo_path: editingTodo.photo_path ?? undefined,
+ gps_lat: editingTodo.gps_lat ?? undefined,
+ gps_lng: editingTodo.gps_lng ?? undefined,
}}
/>
@@ -186,11 +174,13 @@ export default function TodosPage() {
{!loading && Object.entries(grouped).map(([domain, items]) => (
- {/* Entête de groupe avec badge compteur */}
-
+
{domain}
@@ -232,18 +222,35 @@ export default function TodosPage() {
display: 'flex',
alignItems: 'center',
gap: 10,
+ ...noSelect,
}}>
{todo.title}
- {todo.due_date && (
-
- {new Date(todo.due_date).toLocaleDateString('fr-FR')}
- {todo.postponed_count > 0 && ` · reporté ${todo.postponed_count}×`}
-
- )}
+
+ {todo.domains.map(d => (
+ {d}
+ ))}
+ {todo.due_date && (
+
+ {new Date(todo.due_date).toLocaleDateString('fr-FR')}
+ {todo.postponed_count > 0 && ` · reporté ${todo.postponed_count}×`}
+
+ )}
+
@@ -253,7 +260,7 @@ export default function TodosPage() {
))}
{!loading && todos.length === 0 && (
-
Aucune tâche
+
Aucune tâche
)}
@@ -261,9 +268,9 @@ export default function TodosPage() {
{!loading && (
<>
- {/* Filtre période (laptop uniquement) */}
+ {/* Filtre période */}
-
Période :
+
Période :
- {['Titre', 'Domaine', 'Priorité', 'Statut', 'Date objectif', 'Reports', 'Actions'].map(h => (
- | {h} |
+ {['Titre', 'Domaines', 'Priorité', 'Statut', 'Date objectif', 'Reports', 'Actions'].map(h => (
+ {h} |
))}
@@ -297,7 +304,7 @@ export default function TodosPage() {
}}
>
setEditingTodo(todo)}
title="Double-clic pour modifier"
>
@@ -314,19 +321,38 @@ export default function TodosPage() {
)}
|
-
{todo.domain ?? '—'} |
-
+ |
+
+ {todo.domains.length === 0 ? (
+ —
+ ) : todo.domains.map(d => (
+ {d}
+ ))}
+
+ |
+
{todo.priority}
|
-
+ |
{STATUS_LABELS[todo.status] ?? todo.status}
|
-
+ |
{todo.due_date ? new Date(todo.due_date).toLocaleDateString('fr-FR') : '—'}
|
-
+ |
{todo.postponed_count > 0 ? `${todo.postponed_count}×` : '—'}
|
@@ -362,14 +388,14 @@ export default function TodosPage() {
{todos.length === 0 && (
- Aucune tâche
+ Aucune tâche
)}
>
)}
- {/* FAB mobile (au-dessus de la barre de navigation) */}
+ {/* FAB mobile */}
|