11import { useState , useRef , useEffect } from 'react' ;
2- import { Database , Folder , Plus , Pencil , Trash2 , Check , X , Loader2 , ChevronRight , ChevronDown } from 'lucide-react' ;
3- import { createCollection , renameCollection , deleteCollection , type Collection } from '../../lib/structuresService' ;
2+ import { Database , Folder , Plus , Pencil , Trash2 , Check , X , Loader2 , ChevronRight , ChevronDown , Clock , Pin } from 'lucide-react' ;
3+ import { createCollection , renameCollection , deleteCollection , type Collection , type Structure } from '../../lib/structuresService' ;
44import { DOT } from './CollectionsSidebar' ; // reuse colors
55
66interface Props {
@@ -14,11 +14,16 @@ interface Props {
1414 onRenamed : ( id : string , name : string ) => void ;
1515 onDeleted : ( id : string ) => void ;
1616 onDropStructure ?: ( structureId : string , folderId : string ) => void ;
17+ recentStructures ?: Structure [ ] ;
18+ pinnedCollectionIds ?: string [ ] ;
19+ onOpenStructure ?: ( s : Structure ) => void ;
20+ onTogglePin ?: ( id : string ) => void ;
1721}
1822
1923export function FolderTreeSidebar ( {
2024 userId, collections, activeCollection, counts, uncategorizedCount,
21- onSelect, onCreated, onRenamed, onDeleted, onDropStructure
25+ onSelect, onCreated, onRenamed, onDeleted, onDropStructure,
26+ recentStructures, pinnedCollectionIds, onOpenStructure
2227} : Props ) {
2328 // Tree state
2429 const [ expandedIds , setExpandedIds ] = useState < Set < string > > ( new Set ( ) ) ;
@@ -193,6 +198,32 @@ export function FolderTreeSidebar({
193198
194199 < div className = "flex-1 overflow-y-auto px-2 pb-4 space-y-0.5 custom-scrollbar" >
195200
201+ { /* Pinned / Quick Access */ }
202+ { ( ( recentStructures && recentStructures . length > 0 ) || ( pinnedCollectionIds && pinnedCollectionIds . length > 0 ) ) && (
203+ < div className = "mb-4" >
204+ < p className = "px-2 mb-1.5 text-[10px] font-bold text-neutral-500 uppercase tracking-widest mt-2" > Quick Access</ p >
205+ { pinnedCollectionIds ?. map ( id => {
206+ const c = collections . find ( col => col . id === id ) ;
207+ if ( ! c ) return null ;
208+ return (
209+ < button key = { `pin-${ id } ` } onClick = { ( ) => onSelect ( c . id ) }
210+ className = { `w-full flex items-center gap-2 px-2 py-1.5 rounded-lg text-sm transition-all focus:outline-none mb-0.5
211+ ${ activeCollection === c . id ? 'bg-blue-500/10 text-blue-400 font-medium' : 'text-neutral-400 hover:bg-neutral-800/60 hover:text-neutral-200' } ` } >
212+ < Pin className = "w-3.5 h-3.5 shrink-0 text-blue-400/70 rotate-45" />
213+ < span className = "truncate flex-1 text-left text-[13px]" > { c . name } </ span >
214+ </ button >
215+ ) ;
216+ } ) }
217+ { recentStructures ?. map ( s => (
218+ < button key = { `recent-${ s . id } ` } onClick = { ( ) => onOpenStructure ?.( s ) }
219+ className = "w-full flex items-center gap-2 px-2 py-1.5 rounded-lg text-sm text-neutral-400 hover:bg-neutral-800/60 hover:text-neutral-200 transition-all focus:outline-none mb-0.5" >
220+ < Clock className = "w-3.5 h-3.5 shrink-0 opacity-60" />
221+ < span className = "truncate flex-1 text-left text-[13px]" > { s . name } </ span >
222+ </ button >
223+ ) ) }
224+ </ div >
225+ ) }
226+
196227 { /* All structures */ }
197228 < button onClick = { ( ) => onSelect ( null ) }
198229 className = { `w-full flex items-center gap-2 px-2 py-1.5 rounded-lg text-sm transition-all focus:outline-none mb-2
0 commit comments