'use client' import { useState, useCallback } from 'react' import { motion, AnimatePresence } from 'motion/react' import { Sparkles, X, CheckCircle2, FolderPlus, Folder, ChevronDown, ChevronUp, Loader2, AlertCircle, Check } from 'lucide-react' import { cn } from '@/lib/utils' import { analyzeNotebookForOrganization, executeNotebookOrganization, type OrganizationGroup, type OrganizationPlan, } from '@/app/actions/organize-notebook' import { toast } from 'sonner' interface OrganizeNotebookDialogProps { open: boolean onOpenChange: (open: boolean) => void notebookId: string notebookName: string onDone?: () => void } type Step = 'idle' | 'analyzing' | 'preview' | 'executing' | 'done' export function OrganizeNotebookDialog({ open, onOpenChange, notebookId, notebookName, onDone, }: OrganizeNotebookDialogProps) { const [step, setStep] = useState('idle') const [plan, setPlan] = useState(null) const [editableGroups, setEditableGroups] = useState([]) const [expandedGroups, setExpandedGroups] = useState>(new Set()) const [error, setError] = useState(null) const [result, setResult] = useState<{ created: number; moved: number } | null>(null) const handleAnalyze = useCallback(async () => { setStep('analyzing') setError(null) setPlan(null) const res = await analyzeNotebookForOrganization(notebookId) if (!res.success || !res.plan) { setError(res.error ?? 'Erreur inconnue') setStep('idle') return } setPlan(res.plan) setEditableGroups(res.plan.groups.map(g => ({ ...g, notes: [...g.notes] }))) setExpandedGroups(new Set(res.plan.groups.map((_, i) => i))) setStep('preview') }, [notebookId]) const handleRenameGroup = (idx: number, name: string) => { setEditableGroups(prev => prev.map((g, i) => i === idx ? { ...g, name } : g)) } const handleToggleNote = (groupIdx: number, noteId: string) => { setEditableGroups(prev => prev.map((g, i) => { if (i !== groupIdx) return g const has = g.notes.some(n => n.id === noteId) return { ...g, notes: has ? g.notes.filter(n => n.id !== noteId) : g.notes, } })) } const handleRemoveGroup = (idx: number) => { setEditableGroups(prev => prev.filter((_, i) => i !== idx)) } const toggleExpand = (idx: number) => { setExpandedGroups(prev => { const next = new Set(prev) next.has(idx) ? next.delete(idx) : next.add(idx) return next }) } const handleExecute = useCallback(async () => { if (!plan) return setStep('executing') const finalPlan: OrganizationPlan = { notebookId: plan.notebookId, groups: editableGroups.filter(g => g.notes.length > 0 && g.name.trim()), } const res = await executeNotebookOrganization(finalPlan) if (!res.success) { setError(res.error ?? 'Erreur inconnue') setStep('preview') return } setResult({ created: res.created, moved: res.moved }) setStep('done') toast.success(`Carnet organisé — ${res.created} sous-carnet(s) créé(s), ${res.moved} note(s) déplacée(s)`) onDone?.() }, [plan, editableGroups, onDone]) const handleClose = () => { if (step === 'analyzing' || step === 'executing') return onOpenChange(false) // Reset after close animation setTimeout(() => { setStep('idle') setPlan(null) setEditableGroups([]) setError(null) setResult(null) }, 300) } if (!open) return null const totalNotes = editableGroups.reduce((acc, g) => acc + g.notes.length, 0) const newSubNbs = editableGroups.filter(g => g.isNew).length return ( {open && ( <> {/* Backdrop */} {/* Panel */} e.stopPropagation()} > {/* Header */}

Organiser le carnet

{notebookName}

{/* Content */}
{/* IDLE */} {step === 'idle' && ( {error && (

{error}

)}

L'IA va analyser les notes de ce carnet et vous proposer un plan de réorganisation en sous-carnets thématiques.

    {[ 'Regroupement par sujet ou thème', 'Création de sous-carnets manquants', 'Aperçu complet avant modification', ].map(item => (
  • {item}
  • ))}
)} {/* ANALYZING */} {step === 'analyzing' && (

Analyse en cours…

L'IA lit vos notes et identifie les thèmes

{[0, 1, 2].map(i => ( ))}
)} {/* PREVIEW */} {step === 'preview' && ( {/* Summary bar */}

{editableGroups.length} groupe(s) · {totalNotes} note(s) · {newSubNbs} nouveau(x) sous-carnet(s)

{error && (

{error}

)} {/* Groups */}
{editableGroups.map((group, idx) => ( {/* Group header */}
{group.isNew ? : }
handleRenameGroup(idx, e.target.value)} className="flex-1 bg-transparent text-[12px] font-semibold text-ink outline-none focus:text-blueprint transition-colors min-w-0" /> {group.isNew && ( Nouveau )}
{/* Notes list */} {expandedGroups.has(idx) && (
{group.notes.map(note => (
handleToggleNote(idx, note.id)} >
{note.title || 'Note sans titre'}
))}
)}
{/* Collapsed count */} {!expandedGroups.has(idx) && (
{group.notes.length} note(s)
)}
))}
)} {/* EXECUTING */} {step === 'executing' && (

Organisation en cours…

Création des sous-carnets et déplacement des notes

)} {/* DONE */} {step === 'done' && (

Carnet organisé !

{result && (

{result.created} sous-carnet(s) créé(s) · {result.moved} note(s) déplacée(s)

)}
)}
{/* Footer actions */}
{step === 'idle' && ( )} {step === 'preview' && (
)} {step === 'done' && ( )}
)}
) }