feat: Organisateur IA — analyse carnet + tags + doublons + regroupements
All checks were successful
CI / Lint, Unit Tests & Build (push) Successful in 5m37s
CI / Deploy production (on server) (push) Successful in 2m2s

- Service notebook-organizer.service.ts : analyse IA des notes
- Endpoint /api/ai/organize-notebook
- Dialog avec 4 sections :
  1. Résumé de l'état du carnet
  2. Tags suggérés (cliquable pour appliquer)
  3. Regroupements logiques par catégorie
  4. Détection de doublons avec explication
- Bouton 'Organiser' (Wand2) dans la barre du carnet
- i18n FR/EN complet
- Complète les 3 scénarios : Prof (wizard+exercices), Étudiant (wizard+planning), Ingénieur (organisateur)
This commit is contained in:
Antigravity
2026-06-14 20:16:01 +00:00
parent eff906d187
commit b9a80f9e64
6 changed files with 401 additions and 1 deletions

View File

@@ -20,7 +20,7 @@ import {
import { NotebookSuggestionToast } from '@/components/notebook-suggestion-toast'
import { Button } from '@/components/ui/button'
import { Plus, ArrowUpDown, Search, Sparkles, FileText, FolderOpen, ChevronRight, Tag as TagIcon, X, Menu, LayoutGrid, List, Table, Columns3, CalendarDays } from 'lucide-react'
import { Plus, ArrowUpDown, Search, Sparkles, FileText, FolderOpen, ChevronRight, Tag as TagIcon, X, Menu, LayoutGrid, List, Table, Columns3, CalendarDays, Wand2 } from 'lucide-react'
import { emitNoteChange } from '@/lib/note-change-sync'
import { useReminderCheck } from '@/hooks/use-reminder-check'
import { useAutoLabelSuggestion } from '@/hooks/use-auto-label-suggestion'
@@ -31,6 +31,7 @@ import { useEditorUI } from '@/context/editor-ui-context'
import { NoteHistoryModal } from '@/components/note-history-modal'
import { CreateNotebookDialog } from '@/components/create-notebook-dialog'
import { StudyPlannerDialog } from '@/components/wizard/study-planner-dialog'
import { NotebookOrganizerDialog } from '@/components/wizard/notebook-organizer-dialog'
import { toast } from 'sonner'
import { AnimatePresence, motion } from 'motion/react'
@@ -136,6 +137,7 @@ export function HomeClient({
const [addPropertyOpen, setAddPropertyOpen] = useState(false)
const [isEnablingStructured, setIsEnablingStructured] = useState(false)
const [showStudyPlanner, setShowStudyPlanner] = useState(false)
const [showOrganizer, setShowOrganizer] = useState(false)
const notebookFilter = searchParams.get('notebook')
const schemaHook = useNotebookSchema(notebookFilter)
@@ -1051,6 +1053,19 @@ export function HomeClient({
<span>{t('wizard.studyPlanner') || 'Planning'}</span>
</button>
)}
{searchParams.get('notebook') && (
<button
onClick={() => setShowOrganizer(true)}
disabled={!initialSettings.aiAssistantEnabled}
className={cn(
"flex items-center gap-2 text-[13px] font-medium transition-opacity",
initialSettings.aiAssistantEnabled ? "text-brand-accent hover:opacity-70" : "text-muted-foreground opacity-50 cursor-not-allowed"
)}
>
<Wand2 size={16} />
<span>{t('wizard.organizer') || 'Organiser'}</span>
</button>
)}
<button
onClick={() => setSortOrder(s => s === 'newest' ? 'oldest' : s === 'oldest' ? 'alpha' : s === 'alpha' ? 'manual' : 'newest')}
className="flex items-center gap-2 text-[13px] text-foreground font-medium hover:opacity-70 transition-opacity"
@@ -1292,6 +1307,14 @@ export function HomeClient({
onClose={() => setShowStudyPlanner(false)}
/>
)}
{showOrganizer && currentNotebook && (
<NotebookOrganizerDialog
notebookId={currentNotebook.id}
notebookName={currentNotebook.name}
onClose={() => setShowOrganizer(false)}
/>
)}
</div>
)
}