Skip to content

Commit 2291008

Browse files
AmirMohammad CheraghaliAmirMohammad Cheraghali
authored andcommitted
feat: Add pinned folders, recent structures, and resizable columns to list view
1 parent f4ebbb2 commit 2291008

2 files changed

Lines changed: 380 additions & 201 deletions

File tree

src/components/dashboard/FolderTreeSidebar.tsx

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { 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';
44
import { DOT } from './CollectionsSidebar'; // reuse colors
55

66
interface 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

1923
export 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

Comments
 (0)