feat(dashboard): tableau de bord Second Brain configurable avec chargement progressif
All checks were successful
CI / Lint, Unit Tests & Build (push) Successful in 7m3s
CI / Deploy production (on server) (push) Successful in 23s

Briefing granulaire, pistes rapides puis enrichissement async, layout persisté v5,
suggestions agents, intégration Gmail et navigation sidebar alignée sur /home.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Antigravity
2026-07-14 16:50:53 +00:00
parent d38a99586b
commit 30da592ba2
62 changed files with 7741 additions and 335 deletions

View File

@@ -34,6 +34,7 @@ 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'
import { isDashboardHomeRoute } from '@/lib/dashboard/home-route'
type SortOrder = 'newest' | 'oldest' | 'alpha' | 'manual'
@@ -58,6 +59,10 @@ const OrganizeNotebookDialog = dynamic(
() => import('@/components/organize-notebook-dialog').then(m => ({ default: m.OrganizeNotebookDialog })),
{ ssr: false }
)
const DashboardView = dynamic(
() => import('@/components/dashboard-view').then(m => ({ default: m.DashboardView })),
{ ssr: false }
)
const NotebookSiteDialog = dynamic(
() => import('@/components/wizard/notebook-site-dialog').then(m => ({ default: m.NotebookSiteDialog })),
{ ssr: false }
@@ -225,15 +230,12 @@ export function HomeClient({
}, [])
// Sidebar carnet / inbox: fermer l'éditeur plein écran (comme la ref. architectural-grid)
// On GARDE forceList dans l'URL pour distinguer "liste" du "dashboard"
useEffect(() => {
if (searchParams.get('forceList') === '1') {
setEditingNote(null)
const params = new URLSearchParams(searchParams.toString())
params.delete('forceList')
const newUrl = params.toString() ? `/home?${params.toString()}` : '/home'
router.replace(newUrl, { scroll: false })
}
}, [searchParams, router])
}, [searchParams])
const fetchNotesForCurrentView = useCallback(
async (options?: { silent?: boolean }) => {
@@ -821,6 +823,16 @@ export function HomeClient({
emitNoteChange({ type: 'updated', note: savedNote })
}, [])
// Show dashboard when no active filter/view params
const showDashboard = !editingNote && isDashboardHomeRoute('/home', searchParams)
const handleDashboardNoteSelect = useCallback((noteId: string, notebookId: string | null) => {
const params = new URLSearchParams()
params.set('openNote', noteId)
if (notebookId) params.set('notebook', notebookId)
router.push(`/home?${params.toString()}`)
}, [router])
return (
<div
className={cn(
@@ -838,6 +850,8 @@ export function HomeClient({
fullPage
/>
</div>
) : showDashboard ? (
<DashboardView onNoteSelect={handleDashboardNoteSelect} />
) : (
<div className="flex-1 overflow-y-auto min-h-0 bg-memento-paper dark:bg-background flex flex-col">
<div