import { codeBlockPlugin, codeMirrorPlugin, headingsPlugin, linkPlugin, listsPlugin, markdownShortcutPlugin, MDXEditor, quotePlugin, SandpackConfig, sandpackPlugin, thematicBreakPlugin, } from "@mdxeditor/editor"; import { useEffect, useRef, useState } from "react"; import { folderApi, FolderCreate, FolderTreeNode, FolderTreeResponse, NoteRead, } from "../api/folders"; import { NoteCreate, notesApi } from "../api/notes"; import "../main.css"; import { DndContext, DragEndEvent, PointerSensor, useSensor, useSensors, } from "@dnd-kit/core"; import "@mdxeditor/editor/style.css"; import { DroppableFolder } from "../components/sidebar/DroppableFolder"; import { DraggableNote } from "../components/sidebar/DraggableNote"; const simpleSandpackConfig: SandpackConfig = { defaultPreset: "react", presets: [ { label: "React", name: "react", meta: "live react", sandpackTemplate: "react", sandpackTheme: "dark", snippetFileName: "/App.js", snippetLanguage: "jsx", }, ], }; function Home() { const [folderTree, setFolderTree] = useState(null); const [selectedNote, setSelectedNote] = useState(null); const [title, setTitle] = useState(""); const [content, setContent] = useState("#"); const [newFolder, setNewFolder] = useState(false); const [newFolderText, setNewFolderText] = useState(""); const [selectedFolder, setSelectedFolder] = useState(null); const [encrypted, setEncrypted] = useState(false); const pointer = useSensor(PointerSensor, { activationConstraint: { distance: 30, }, }); const sensors = useSensors(pointer); useEffect(() => { loadFolderTree(); }, []); const loadFolderTree = async () => { const data = await folderApi.tree(); setFolderTree(data); }; const handleCreate = async () => { if (!title.trim()) return; const newNote: NoteCreate = { title, content, folder_id: selectedFolder, encrypted, }; await notesApi.create(newNote); setTitle(""); setContent("#"); loadFolderTree(); }; const handleCreateFolder = async () => { if (!newFolderText.trim()) return; const newFolderData: FolderCreate = { name: newFolderText, parent_id: null, }; await folderApi.create(newFolderData); setNewFolderText(""); loadFolderTree(); setNewFolder(false); }; const handleUpdate = async () => { if (!selectedNote) return; await notesApi.update(selectedNote.id, { title, content }); setSelectedNote(null); setTitle(""); setContent("#"); loadFolderTree(); }; const handleDelete = async (id: number) => { await notesApi.delete(id); loadFolderTree(); }; const selectNote = (note: NoteRead) => { console.log(note); setSelectedNote(note); setTitle(note.title); setContent(note.content); }; const clearSelection = () => { setSelectedNote(null); setTitle(""); setContent("#"); }; const newFolderRef = useRef(null); useEffect(() => { if (newFolder && newFolderRef.current) { newFolderRef.current.focus(); } }, [newFolder]); const renderFolder = (folder: FolderTreeNode, depth: number = 0) => (
0 ? "1rem" : "0" }} className="flex flex-col" >
{folder.notes.map((note) => ( ))}
{folder.children.map((child) => renderFolder(child, depth + 1))}
); const handleDragEnd = async (event: DragEndEvent) => { const { active, over } = event; if (!over) return; console.log(active.data); console.log(over.data); await notesApi.update(active.id as number, { folder_id: over.id as number, }); loadFolderTree(); }; return (
e.preventDefault()} onTouchMove={(e) => e.preventDefault()} >

Notes

{newFolder && (
setNewFolder(false)} onChange={(e) => setNewFolderText(e.target.value)} value={newFolderText} type="text" placeholder="new folder" className="border-ctp-mauve border rounded-md px-2 w-full focus:outline-none focus:ring-1 focus:ring-ctp-mauve focus:border-ctp-mauve bg-ctp-base" ref={newFolderRef} onKeyDown={(e) => { if (e.key === "Enter") { handleCreateFolder(); } }} />
)} {/* Render folder tree */} {folderTree?.folders.map((folder) => renderFolder(folder))} {/* Render orphaned notes */} {folderTree?.orphaned_notes && folderTree.orphaned_notes.length > 0 && (
Unsorted
{folderTree.orphaned_notes.map((note) => ( ))}
)}
setTitle(e.target.value)} style={{ padding: "0.5rem", marginBottom: "1rem", fontSize: "1.5rem", border: "1px solid #ccc", }} />
{selectedNote ? ( <> ) : ( )} setEncrypted(!encrypted)} />
); } export default Home;