From e294ff772ba586db06df88dc31a537f8866b2f6c Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 27 Nov 2025 19:49:54 +0000 Subject: [PATCH] feat: add Kanban view to mobile interface - Add view mode toggle (List/Kanban) in mobile notes page - Integrate KanbanBoard component with drag & drop support - Support moving notes between columns via tags - Auto-refresh notes list after moving to new column - Maintain search and filter functionality in Kanban view - Add mobile-optimized horizontal scrolling for Kanban columns --- src/pages/mobile/NotesPage.tsx | 110 +++++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 25 deletions(-) diff --git a/src/pages/mobile/NotesPage.tsx b/src/pages/mobile/NotesPage.tsx index 83158a1..31c4f59 100644 --- a/src/pages/mobile/NotesPage.tsx +++ b/src/pages/mobile/NotesPage.tsx @@ -5,12 +5,14 @@ import { Input } from "@/components/ui/input"; import { Badge } from "@/components/ui/badge"; import { MobileFAB } from "@/components/mobile/MobileFAB"; import { MobileCard } from "@/components/mobile/MobileCard"; -import { Plus, Search, CheckSquare, Image as ImageIcon, Paperclip, Tag as TagIcon, FileText } from "lucide-react"; +import { Plus, Search, CheckSquare, Image as ImageIcon, Paperclip, Tag as TagIcon, FileText, LayoutGrid, List } from "lucide-react"; import NotesService, { Note } from "@/services/NotesService"; import { showError, showSuccess } from "@/utils/toast"; import { TemplateSelector } from "@/components/TemplateSelector"; import type { NoteTemplate } from "@/utils/noteTemplates"; import { AdvancedSearch, type SearchFilters, type TagOption } from "@/components/AdvancedSearch"; +import { KanbanBoard } from "@/components/KanbanBoard"; +import TagsService from "@/services/TagsService"; const NOTES_PER_PAGE = 10; @@ -29,6 +31,7 @@ export default function NotesPage() { const [showArchived, setShowArchived] = useState(false); const [page, setPage] = useState(0); const [templateSelectorOpen, setTemplateSelectorOpen] = useState(false); + const [viewMode, setViewMode] = useState<'list' | 'kanban'>('list'); const navigate = useNavigate(); const loadNotes = async () => { @@ -209,9 +212,32 @@ export default function NotesPage() { Archivées ({notes.filter(n => n.archived).length}) + + {/* View Mode Toggle */} +
+ + +
- {/* Notes List */} + {/* Notes View - List or Kanban */} + {viewMode === 'list' ? (
{paginatedNotes.length > 0 ? ( paginatedNotes.map(note => ( @@ -304,30 +330,64 @@ export default function NotesPage() { )}
)} - - {/* Pagination */} - {totalPages > 1 && ( -
- - - {page + 1} / {totalPages} - - + {/* Pagination */} + {totalPages > 1 && ( +
+ + + {page + 1} / {totalPages} + + +
+ )} +
+ ) : ( + /* Kanban View */ +
+ navigate(`/mobile/notes/${note.id}`)} + onCreateNote={(columnId) => { + setTemplateSelectorOpen(true); + }} + onMoveNote={async (noteId, newStatus) => { + const note = notes.find(n => n.id === noteId); + if (!note) return; + + // Remove old status tags + const oldStatusTags = note.tags?.filter(tag => + ['backlog', 'todo', 'in_progress', 'review', 'done'].includes(tag.name.toLowerCase()) + ) || []; + + for (const tag of oldStatusTags) { + if (tag.id && note.id) { + await TagsService.deleteTag(note.id, tag.id); + } + } + + // Add new status tag + if (note.id) { + await TagsService.addTag(note.id, newStatus); + await loadNotes(); + showSuccess(`Note déplacée vers ${newStatus}`); + } + }} + />
)}