feat(brainstorm): Option D — toast + peek panel + navigation volontaire
3 points corrigés (plus d'éjection automatique du brainstorm): 1. Convertir idée → note: - Avant: setTimeout 2s → router.push (éjection forcée) - Après: toast.success persistant 10s + peek.open (drawer latéral) 2. Exporter session → note synthèse: - Avant: setTimeout 2s → router.push (éjection forcée) - Après: toast.success + peek.open 3. Voir note référencée: - Avant: router.push (éjection immédiate) - Après: peek.open (drawer latéral) Comportement: - Toast sonner avec bouton 'Ouvrir' (navigation volontaire) - NotePeekPanel mode overlay (slide droite, lecture seule, KaTeX) - Canvas brainstorm reste interactif derrière - Bouton Maximize2 dans le peek → router.push (choix explicite) - Anciens convertToast/exportToast supprimés (45 lignes JSX retirées)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
'use client'
|
||||
import { toast } from 'sonner'
|
||||
|
||||
import React, { useState, useMemo, useEffect, useRef, useCallback } from 'react'
|
||||
import { useRouter, useSearchParams } from 'next/navigation'
|
||||
@@ -26,9 +27,11 @@ import {
|
||||
LayoutGrid,
|
||||
X,
|
||||
Edit2,
|
||||
Maximize2,
|
||||
} from 'lucide-react'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { useLanguage } from '@/lib/i18n'
|
||||
import { useNotePeek, NotePeekPanel } from '@/components/note-peek'
|
||||
import {
|
||||
useBrainstormSession,
|
||||
useBrainstormSessions,
|
||||
@@ -76,6 +79,7 @@ const WAVE_COLORS: Record<number, { border: string; bg: string; text: string }>
|
||||
|
||||
export function BrainstormPage() {
|
||||
const router = useRouter()
|
||||
const peek = useNotePeek()
|
||||
const searchParams = useSearchParams()
|
||||
const { t, language } = useLanguage()
|
||||
const { data: authSession } = useSession()
|
||||
@@ -132,8 +136,7 @@ export function BrainstormPage() {
|
||||
const renameSession = useRenameBrainstormSession(activeSessionId || '')
|
||||
const [impactToast, setImpactToast] = useState<{ notesEnriched: number; notesMarkedDry: number } | null>(null)
|
||||
const [exportError, setExportError] = useState<string | null>(null)
|
||||
const [exportToast, setExportToast] = useState<{ noteTitle: string; notebookName: string } | null>(null)
|
||||
const [convertToast, setConvertToast] = useState<{ noteTitle: string; noteId: string } | null>(null)
|
||||
|
||||
const [remoteMove, setRemoteMove] = useState<{ ideaId: string; x: number; y: number; _seq: number } | null>(null)
|
||||
const [playbackIdeas, setPlaybackIdeas] = useState<any[] | null>(null)
|
||||
const [viewMode, setViewMode] = useState<'canvas' | 'list'>('canvas')
|
||||
@@ -242,11 +245,15 @@ export function BrainstormPage() {
|
||||
try {
|
||||
const result = await convertIdea.mutateAsync(idea.id)
|
||||
if (result?.id) {
|
||||
setConvertToast({ noteTitle: result.title || idea.title, noteId: result.id })
|
||||
setTimeout(() => {
|
||||
setConvertToast(null)
|
||||
router.push(`/home?openNote=${result.id}`)
|
||||
}, 2000)
|
||||
toast.success(t('brainstorm.noteCreated') || 'Note created', {
|
||||
description: result.title || idea.title,
|
||||
action: {
|
||||
label: t('notePeek.openFully') || 'Open',
|
||||
onClick: () => router.push(`/home?openNote=${result.id}`),
|
||||
},
|
||||
duration: 10000,
|
||||
})
|
||||
peek.open(result.id)
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
@@ -287,11 +294,15 @@ export function BrainstormPage() {
|
||||
const result = await exportBrainstorm.mutateAsync()
|
||||
if (result?.id) {
|
||||
const notebookName = result._notebookName || t('brainstorm.exportDefaultNotebookName')
|
||||
setExportToast({ noteTitle: result.title || t('brainstorm.exportDefaultNoteTitle'), notebookName })
|
||||
setTimeout(() => {
|
||||
setExportToast(null)
|
||||
router.push(`/home?openNote=${result.id}`)
|
||||
}, 2000)
|
||||
toast.success(t('brainstorm.noteCreated') || 'Note created', {
|
||||
description: `${result.title || t('brainstorm.exportDefaultNoteTitle')} — ${notebookName}`,
|
||||
action: {
|
||||
label: t('notePeek.openFully') || 'Open',
|
||||
onClick: () => router.push(`/home?openNote=${result.id}`),
|
||||
},
|
||||
duration: 10000,
|
||||
})
|
||||
peek.open(result.id)
|
||||
return
|
||||
}
|
||||
const impact = await finalizeBrainstorm.mutateAsync()
|
||||
@@ -846,7 +857,7 @@ export function BrainstormPage() {
|
||||
</div>
|
||||
{ref.noteId && (
|
||||
<button
|
||||
onClick={() => router.push(`/home?openNote=${ref.noteId}`)}
|
||||
onClick={() => ref.noteId && peek.open(ref.noteId)}
|
||||
className="shrink-0 px-2 py-1 text-[9px] font-bold uppercase tracking-wider rounded-lg bg-foreground/5 hover:bg-foreground/10 text-muted-foreground hover:text-foreground transition-all"
|
||||
>
|
||||
{t('brainstorm.viewNote') || 'View'}
|
||||
@@ -1124,49 +1135,15 @@ export function BrainstormPage() {
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
<AnimatePresence>
|
||||
{exportToast && (
|
||||
<motion.div
|
||||
initial={{ y: 100, opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1 }}
|
||||
exit={{ y: 100, opacity: 0 }}
|
||||
className="fixed bottom-8 left-1/2 -translate-x-1/2 z-50 px-6 py-4 bg-emerald-600 text-white rounded-2xl shadow-2xl flex items-center gap-3 text-sm font-medium"
|
||||
>
|
||||
<Wind size={18} />
|
||||
<div className="flex flex-col">
|
||||
<span className="font-bold">{exportToast.noteTitle}</span>
|
||||
<span className="text-[11px] text-emerald-100">
|
||||
{t('brainstorm.exportNotebookPrefix')} {exportToast.notebookName}
|
||||
</span>
|
||||
</div>
|
||||
<div className="ml-3 flex items-center gap-1.5 text-emerald-200 text-[10px]">
|
||||
<div className="w-1.5 h-1.5 rounded-full bg-emerald-300 animate-pulse" />
|
||||
{t('brainstorm.exportOpening')}
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
<AnimatePresence>
|
||||
{convertToast && (
|
||||
<motion.div
|
||||
initial={{ y: 100, opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1 }}
|
||||
exit={{ y: 100, opacity: 0 }}
|
||||
className="fixed bottom-8 left-1/2 -translate-x-1/2 z-50 px-6 py-4 bg-emerald-600 text-white rounded-2xl shadow-2xl flex items-center gap-3 text-sm font-medium"
|
||||
>
|
||||
<FileText size={18} />
|
||||
<div className="flex flex-col">
|
||||
<span className="font-bold">{convertToast.noteTitle}</span>
|
||||
<span className="text-[11px] text-emerald-100">{t('brainstorm.noteCreated') || 'Note Created'}</span>
|
||||
</div>
|
||||
<div className="ml-3 flex items-center gap-1.5 text-emerald-200 text-[10px]">
|
||||
<div className="w-1.5 h-1.5 rounded-full bg-emerald-300 animate-pulse" />
|
||||
{t('brainstorm.exportOpening')}
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
{/* Peek panel — drawer latéral pour aperçu note sans quitter le brainstorm */}
|
||||
<NotePeekPanel
|
||||
note={peek.note}
|
||||
blockId={peek.blockId}
|
||||
loading={peek.loading}
|
||||
mode="overlay"
|
||||
onClose={peek.close}
|
||||
onOpenFully={(n) => { router.push(`/home?openNote=${n.id}`); peek.close() }}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user