feat: hierarchical notebooks (tree), remove all list view code, delete 22 unused files
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m3s

- Add parentId to Notebook model (tree structure)
- Update sidebar to render parent/child notebooks with expand/collapse
- Add sub-notebook creation from parent notebook
- Remove 'list' from NotesViewMode type everywhere
- Delete 22 unused components, hooks, and UI files
- Wrap revalidatePath in try-catch to prevent save 500
- Update notebook API to support parentId in creation
This commit is contained in:
Antigravity
2026-05-09 21:02:23 +00:00
parent 5a6ec4808f
commit d90b29b34f
30 changed files with 155 additions and 4280 deletions

View File

@@ -1,36 +0,0 @@
'use client'
import { useState, useCallback } from 'react'
export type DragState = 'idle' | 'dragging' | 'drag-over'
export function useNoteDrag() {
const [draggedNoteId, setDraggedNoteId] = useState<string | null>(null)
const [dragOverNotebookId, setDragOverNotebookId] = useState<string | null>(null)
const startDrag = useCallback((noteId: string) => {
setDraggedNoteId(noteId)
}, [])
const endDrag = useCallback(() => {
setDraggedNoteId(null)
setDragOverNotebookId(null)
}, [])
const dragOver = useCallback((notebookId: string | null) => {
setDragOverNotebookId(notebookId)
}, [])
const isDragging = draggedNoteId !== null
const isDragOver = dragOverNotebookId !== null
return {
draggedNoteId,
dragOverNotebookId,
startDrag,
endDrag,
dragOver,
isDragging,
isDragOver,
}
}

View File

@@ -1,33 +0,0 @@
'use client';
import { useEffect, useRef } from 'react';
export function useResizeObserver(callback: (entry: ResizeObserverEntry) => void) {
const ref = useRef<HTMLElement>(null);
const frameId = useRef<number>(0);
useEffect(() => {
const element = ref.current;
if (!element) return;
const observer = new ResizeObserver((entries) => {
// Cancel previous frame to avoid stacking updates
if (frameId.current) cancelAnimationFrame(frameId.current);
frameId.current = requestAnimationFrame(() => {
for (const entry of entries) {
callback(entry);
}
});
});
observer.observe(element);
return () => {
observer.disconnect();
if (frameId.current) cancelAnimationFrame(frameId.current);
};
}, [callback]);
return ref;
}