fix: toolbar carnet redesign — propre et cohérent
Some checks failed
CI / Deploy production (on server) (push) Has been cancelled
CI / Lint, Unit Tests & Build (push) Has been cancelled

- Layout mode (Grid/List/Table/Kanban) déplacé à droite
- Sort à droite avec icône compacte
- Toutes les actions IA (Résumé, Planning, Organiser) + CSV dans un menu ⋯
- Plus de boutons éparpillés — tout est dans un seul dropdown
- Layout respecte le design system existant
This commit is contained in:
Antigravity
2026-06-19 21:19:56 +00:00
parent 85b7e6e396
commit c9b98065b6

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, Wand2, Download, Upload } from 'lucide-react'
import { Plus, ArrowUpDown, Search, Sparkles, FileText, FolderOpen, ChevronRight, Tag as TagIcon, X, Menu, LayoutGrid, List, Table, Columns3, CalendarDays, Wand2, Download, Upload, MoreHorizontal } 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'
@@ -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 { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'
type SortOrder = 'newest' | 'oldest' | 'alpha' | 'manual'
@@ -849,7 +850,7 @@ export function HomeClient({
</div>
<div className="flex items-center justify-between border-b border-foreground/5 pb-4">
<div className="flex items-center gap-6">
<div className="flex items-center gap-5">
<button
onClick={handleAddNote}
disabled={isCreating}
@@ -869,7 +870,6 @@ export function HomeClient({
</button>
)}
{/* Inline search — toggles an input within the toolbar */}
{showInlineSearch ? (
<div className="flex items-center gap-2">
{isSearching ? (
@@ -889,20 +889,13 @@ export function HomeClient({
if (searchDebounceRef.current) clearTimeout(searchDebounceRef.current)
searchDebounceRef.current = setTimeout(() => {
const params = new URLSearchParams(searchParams.toString())
if (q.trim()) {
params.set('search', q)
} else {
params.delete('search')
}
if (q.trim()) params.set('search', q)
else params.delete('search')
router.push(`/home?${params.toString()}`)
setIsSearching(false)
}, 300)
}}
onBlur={() => {
if (!inlineSearchQuery) {
setShowInlineSearch(false)
}
}}
onBlur={() => { if (!inlineSearchQuery) setShowInlineSearch(false) }}
onKeyDown={e => {
if (e.key === 'Escape') {
if (searchDebounceRef.current) clearTimeout(searchDebounceRef.current)
@@ -936,10 +929,7 @@ export function HomeClient({
</div>
) : (
<button
onClick={() => {
setShowInlineSearch(true)
setTimeout(() => inlineSearchRef.current?.focus(), 50)
}}
onClick={() => { setShowInlineSearch(true); setTimeout(() => inlineSearchRef.current?.focus(), 50) }}
className="flex items-center gap-2 text-[13px] text-foreground font-medium hover:opacity-70 transition-opacity"
>
<Search size={16} />
@@ -950,83 +940,30 @@ export function HomeClient({
{!searchParams.get('notebook') && searchParams.get('shared') !== '1' && (
<button
onClick={() => setBatchOrganizationOpen(true)}
className="flex items-center gap-2 text-[13px] text-foreground font-medium hover:opacity-70 transition-opacity"
className="flex items-center gap-2 text-[13px] text-brand-accent font-medium hover:opacity-70 transition-opacity"
>
<Sparkles size={16} />
<span>{t('notes.reorganize')}</span>
</button>
)}
</div>
<div className="flex items-center gap-4 flex-wrap">
<div className="flex items-center gap-3">
{/* Layout mode */}
<div className="bg-foreground/[0.03] dark:bg-white/[0.04] p-0.5 rounded-full flex border border-border/30 items-center">
<button
type="button"
onClick={() => selectLayoutMode('grid')}
className={cn(
'p-1.5 rounded-full transition-all',
layoutMode === 'grid'
? 'bg-foreground text-background shadow-sm'
: 'text-muted-foreground hover:text-foreground',
)}
title={t('notes.layoutGridTitle')}
>
<button type="button" onClick={() => selectLayoutMode('grid')} className={cn('p-1.5 rounded-full transition-all', layoutMode === 'grid' ? 'bg-foreground text-background shadow-sm' : 'text-muted-foreground hover:text-foreground')} title={t('notes.layoutGridTitle')}>
<LayoutGrid size={13} />
</button>
<button
type="button"
onClick={() => selectLayoutMode('list')}
className={cn(
'p-1.5 rounded-full transition-all',
layoutMode === 'list'
? 'bg-foreground text-background shadow-sm'
: 'text-muted-foreground hover:text-foreground',
)}
title={t('notes.layoutListTitle')}
>
<button type="button" onClick={() => selectLayoutMode('list')} className={cn('p-1.5 rounded-full transition-all', layoutMode === 'list' ? 'bg-foreground text-background shadow-sm' : 'text-muted-foreground hover:text-foreground')} title={t('notes.layoutListTitle')}>
<List size={13} />
</button>
{!notebookFilter && (
<button
type="button"
onClick={() => selectLayoutMode('table')}
className={cn(
'p-1.5 rounded-full transition-all',
layoutMode === 'table'
? 'bg-foreground text-background shadow-sm'
: 'text-muted-foreground hover:text-foreground',
)}
title={t('notes.layoutTableTitle')}
>
<Table size={13} />
</button>
)}
{notebookFilter && (
<>
<span className="w-px h-4 bg-border/50 mx-0.5" aria-hidden />
<button
type="button"
onClick={() => selectLayoutMode('table')}
className={cn(
'p-1.5 rounded-full transition-all',
layoutMode === 'table'
? 'bg-foreground text-background shadow-sm'
: 'text-muted-foreground hover:text-foreground',
)}
title={t('structuredViews.viewTableHint')}
>
<button type="button" onClick={() => selectLayoutMode('table')} className={cn('p-1.5 rounded-full transition-all', layoutMode === 'table' ? 'bg-foreground text-background shadow-sm' : 'text-muted-foreground hover:text-foreground')} title={t('structuredViews.viewTableHint')}>
<Table size={13} />
</button>
<button
type="button"
onClick={() => selectLayoutMode('kanban')}
className={cn(
'p-1.5 rounded-full transition-all',
layoutMode === 'kanban'
? 'bg-foreground text-background shadow-sm'
: 'text-muted-foreground hover:text-foreground',
)}
title={t('structuredViews.viewKanbanHint')}
>
<button type="button" onClick={() => selectLayoutMode('kanban')} className={cn('p-1.5 rounded-full transition-all', layoutMode === 'kanban' ? 'bg-foreground text-background shadow-sm' : 'text-muted-foreground hover:text-foreground')} title={t('structuredViews.viewKanbanHint')}>
<Columns3 size={13} />
</button>
</>
@@ -1034,69 +971,57 @@ export function HomeClient({
</div>
{currentNotebook && structuredModeActive && (
<button
type="button"
onClick={() => setAddPropertyOpen(true)}
className="p-1.5 rounded-full text-muted-foreground hover:text-brand-accent transition-colors"
title={t('structuredViews.addProperty')}
>
<button type="button" onClick={() => setAddPropertyOpen(true)} className="p-1.5 rounded-full text-muted-foreground hover:text-brand-accent transition-colors" title={t('structuredViews.addProperty')}>
<Plus size={16} />
</button>
)}
{searchParams.get('notebook') && initialSettings.aiAssistantEnabled && (
<div className="flex items-center gap-3">
<button
onClick={() => setSummaryDialogOpen(true)}
className="flex items-center gap-1.5 text-[12px] text-muted-foreground hover:text-foreground transition-colors"
>
<FileText size={14} />
<span>{t('notebook.summary')}</span>
</button>
<span className="w-px h-3.5 bg-border/40" />
<button
onClick={() => setShowStudyPlanner(true)}
className="flex items-center gap-1.5 text-[12px] text-muted-foreground hover:text-brand-accent transition-colors"
>
<CalendarDays size={14} />
<span>{t('wizard.studyPlanner') || 'Planning'}</span>
</button>
<span className="w-px h-3.5 bg-border/40" />
<button
onClick={() => setOrganizeNotebookOpen(true)}
className="flex items-center gap-1.5 text-[12px] text-muted-foreground hover:text-brand-accent transition-colors"
title={t('notebook.organizeNotebookWithAITooltip')}
>
<Sparkles size={14} />
<span>{t('batch.organize')}</span>
</button>
</div>
)}
{searchParams.get('notebook') && (
<div className="flex items-center gap-1">
<button
onClick={handleImportCSV}
className="p-1.5 rounded-full text-muted-foreground hover:text-foreground transition-colors"
title={t('structuredViews.importCsv') || 'Importer CSV'}
>
<Upload size={15} />
</button>
<button
onClick={handleExportCSV}
className="p-1.5 rounded-full text-muted-foreground hover:text-foreground transition-colors"
title={t('structuredViews.exportCsv') || 'Exporter CSV'}
>
<Download size={15} />
</button>
</div>
)}
{/* Sort */}
<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"
className="flex items-center gap-1.5 text-[13px] text-muted-foreground hover:text-foreground transition-colors"
>
<ArrowUpDown size={16} />
<span>{sortLabels[sortOrder]}</span>
<ArrowUpDown size={14} />
<span className="hidden sm:inline">{sortLabels[sortOrder]}</span>
</button>
{/* AI + utils dropdown */}
{searchParams.get('notebook') && (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<button className="p-1.5 rounded-full text-muted-foreground hover:text-foreground hover:bg-foreground/5 transition-all" title="Plus d'actions">
<MoreHorizontal size={16} />
</button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-56">
{initialSettings.aiAssistantEnabled && (
<>
<DropdownMenuItem onClick={() => setSummaryDialogOpen(true)}>
<FileText className="h-4 w-4 me-2" />
{t('notebook.summary')}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setShowStudyPlanner(true)}>
<CalendarDays className="h-4 w-4 me-2" />
{t('wizard.studyPlanner') || 'Planning'}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setOrganizeNotebookOpen(true)}>
<Sparkles className="h-4 w-4 me-2 text-brand-accent" />
{t('batch.organize')}
</DropdownMenuItem>
<DropdownMenuSeparator />
</>
)}
<DropdownMenuItem onClick={handleImportCSV}>
<Upload className="h-4 w-4 me-2" />
{t('structuredViews.importCsv') || 'Importer CSV'}
</DropdownMenuItem>
<DropdownMenuItem onClick={handleExportCSV}>
<Download className="h-4 w-4 me-2" />
{t('structuredViews.exportCsv') || 'Exporter CSV'}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)}
</div>
</div>