revert: toolbar restaurée à l'état 85b7e6e — le redesign cassait tout
Le redesign du toolbar a détruit le layout existant. Restauration à la version précédente qui fonctionnait (organize restauré + CSV).
This commit is contained in:
@@ -20,7 +20,7 @@ import {
|
|||||||
|
|
||||||
import { NotebookSuggestionToast } from '@/components/notebook-suggestion-toast'
|
import { NotebookSuggestionToast } from '@/components/notebook-suggestion-toast'
|
||||||
import { Button } from '@/components/ui/button'
|
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, MoreHorizontal } from 'lucide-react'
|
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 { emitNoteChange } from '@/lib/note-change-sync'
|
import { emitNoteChange } from '@/lib/note-change-sync'
|
||||||
import { useReminderCheck } from '@/hooks/use-reminder-check'
|
import { useReminderCheck } from '@/hooks/use-reminder-check'
|
||||||
import { useAutoLabelSuggestion } from '@/hooks/use-auto-label-suggestion'
|
import { useAutoLabelSuggestion } from '@/hooks/use-auto-label-suggestion'
|
||||||
@@ -34,7 +34,6 @@ import { StudyPlannerDialog } from '@/components/wizard/study-planner-dialog'
|
|||||||
import { NotebookOrganizerDialog } from '@/components/wizard/notebook-organizer-dialog'
|
import { NotebookOrganizerDialog } from '@/components/wizard/notebook-organizer-dialog'
|
||||||
import { toast } from 'sonner'
|
import { toast } from 'sonner'
|
||||||
import { AnimatePresence, motion } from 'motion/react'
|
import { AnimatePresence, motion } from 'motion/react'
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'
|
|
||||||
|
|
||||||
|
|
||||||
type SortOrder = 'newest' | 'oldest' | 'alpha' | 'manual'
|
type SortOrder = 'newest' | 'oldest' | 'alpha' | 'manual'
|
||||||
@@ -850,7 +849,7 @@ export function HomeClient({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center justify-between border-b border-foreground/5 pb-4">
|
<div className="flex items-center justify-between border-b border-foreground/5 pb-4">
|
||||||
<div className="flex items-center gap-5">
|
<div className="flex items-center gap-6">
|
||||||
<button
|
<button
|
||||||
onClick={handleAddNote}
|
onClick={handleAddNote}
|
||||||
disabled={isCreating}
|
disabled={isCreating}
|
||||||
@@ -870,6 +869,7 @@ export function HomeClient({
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Inline search — toggles an input within the toolbar */}
|
||||||
{showInlineSearch ? (
|
{showInlineSearch ? (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
{isSearching ? (
|
{isSearching ? (
|
||||||
@@ -889,13 +889,20 @@ export function HomeClient({
|
|||||||
if (searchDebounceRef.current) clearTimeout(searchDebounceRef.current)
|
if (searchDebounceRef.current) clearTimeout(searchDebounceRef.current)
|
||||||
searchDebounceRef.current = setTimeout(() => {
|
searchDebounceRef.current = setTimeout(() => {
|
||||||
const params = new URLSearchParams(searchParams.toString())
|
const params = new URLSearchParams(searchParams.toString())
|
||||||
if (q.trim()) params.set('search', q)
|
if (q.trim()) {
|
||||||
else params.delete('search')
|
params.set('search', q)
|
||||||
|
} else {
|
||||||
|
params.delete('search')
|
||||||
|
}
|
||||||
router.push(`/home?${params.toString()}`)
|
router.push(`/home?${params.toString()}`)
|
||||||
setIsSearching(false)
|
setIsSearching(false)
|
||||||
}, 300)
|
}, 300)
|
||||||
}}
|
}}
|
||||||
onBlur={() => { if (!inlineSearchQuery) setShowInlineSearch(false) }}
|
onBlur={() => {
|
||||||
|
if (!inlineSearchQuery) {
|
||||||
|
setShowInlineSearch(false)
|
||||||
|
}
|
||||||
|
}}
|
||||||
onKeyDown={e => {
|
onKeyDown={e => {
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') {
|
||||||
if (searchDebounceRef.current) clearTimeout(searchDebounceRef.current)
|
if (searchDebounceRef.current) clearTimeout(searchDebounceRef.current)
|
||||||
@@ -929,7 +936,10 @@ export function HomeClient({
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<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"
|
className="flex items-center gap-2 text-[13px] text-foreground font-medium hover:opacity-70 transition-opacity"
|
||||||
>
|
>
|
||||||
<Search size={16} />
|
<Search size={16} />
|
||||||
@@ -940,88 +950,153 @@ export function HomeClient({
|
|||||||
{!searchParams.get('notebook') && searchParams.get('shared') !== '1' && (
|
{!searchParams.get('notebook') && searchParams.get('shared') !== '1' && (
|
||||||
<button
|
<button
|
||||||
onClick={() => setBatchOrganizationOpen(true)}
|
onClick={() => setBatchOrganizationOpen(true)}
|
||||||
className="flex items-center gap-2 text-[13px] text-brand-accent font-medium hover:opacity-70 transition-opacity"
|
className="flex items-center gap-2 text-[13px] text-foreground font-medium hover:opacity-70 transition-opacity"
|
||||||
>
|
>
|
||||||
<Sparkles size={16} />
|
<Sparkles size={16} />
|
||||||
<span>{t('notes.reorganize')}</span>
|
<span>{t('notes.reorganize')}</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</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">
|
<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
|
||||||
<LayoutGrid size={13} />
|
type="button"
|
||||||
</button>
|
onClick={() => selectLayoutMode('grid')}
|
||||||
<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')}>
|
className={cn(
|
||||||
<List size={13} />
|
'p-1.5 rounded-full transition-all',
|
||||||
</button>
|
layoutMode === 'grid'
|
||||||
{notebookFilter && (
|
? 'bg-foreground text-background shadow-sm'
|
||||||
<>
|
: 'text-muted-foreground hover:text-foreground',
|
||||||
<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')}>
|
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')}
|
||||||
|
>
|
||||||
|
<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} />
|
<Table size={13} />
|
||||||
</button>
|
</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')}>
|
)}
|
||||||
<Columns3 size={13} />
|
{notebookFilter && (
|
||||||
</button>
|
<>
|
||||||
</>
|
<span className="w-px h-4 bg-border/50 mx-0.5" aria-hidden />
|
||||||
)}
|
<button
|
||||||
</div>
|
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')}
|
||||||
|
>
|
||||||
|
<Columns3 size={13} />
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
{currentNotebook && structuredModeActive && (
|
{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} />
|
<Plus size={16} />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Sort */}
|
{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>
|
||||||
|
)}
|
||||||
<button
|
<button
|
||||||
onClick={() => setSortOrder(s => s === 'newest' ? 'oldest' : s === 'oldest' ? 'alpha' : s === 'alpha' ? 'manual' : 'newest')}
|
onClick={() => setSortOrder(s => s === 'newest' ? 'oldest' : s === 'oldest' ? 'alpha' : s === 'alpha' ? 'manual' : 'newest')}
|
||||||
className="flex items-center gap-1.5 text-[13px] text-muted-foreground hover:text-foreground transition-colors"
|
className="flex items-center gap-2 text-[13px] text-foreground font-medium hover:opacity-70 transition-opacity"
|
||||||
>
|
>
|
||||||
<ArrowUpDown size={14} />
|
<ArrowUpDown size={16} />
|
||||||
<span className="hidden sm:inline">{sortLabels[sortOrder]}</span>
|
<span>{sortLabels[sortOrder]}</span>
|
||||||
</button>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user