import { BoldItalicUnderlineToggles, codeBlockPlugin, codeMirrorPlugin, diffSourcePlugin, headingsPlugin, imagePlugin, linkPlugin, listsPlugin, markdownShortcutPlugin, MDXEditor, quotePlugin, SandpackConfig, sandpackPlugin, tablePlugin, thematicBreakPlugin, toolbarPlugin, UndoRedo, DiffSourceToggleWrapper, } from "@mdxeditor/editor"; import { SetStateAction, 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"; // @ts-ignore import CheckIcon from "../assets/fontawesome/svg/circle-check.svg?react"; // @ts-ignore import SpinnerIcon from "../assets/fontawesome/svg/rotate.svg?react"; import { useNoteStore } from "../stores/notesStore"; import { create } from "zustand"; import { Sidebar } from "../components/sidebar/SideBar"; 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 [updating, setUpdating] = useState(false); const { setSelectedFolder, selectedFolder, folderTree, loadFolderTree, createNote, createFolder, updateNote, setSelectedNote, selectedNote, } = useNoteStore(); const newFolderRef = useRef(null); useEffect(() => { loadFolderTree(); }, []); useEffect(() => { if (newFolder && newFolderRef.current) { newFolderRef.current.focus(); } }, [newFolder]); useEffect(() => { if (!selectedNote) return; const timer = setTimeout(async () => { setUpdating(true); handleUpdate(); }, 2000); return () => clearTimeout(timer); }, [content, title]); const handleCreate = async () => { if (!title.trim()) return; await createNote({ title, content, folder_id: null }); }; const handleUpdate = async () => { if (!selectedNote) return; await updateNote(selectedNote.id, { title, content }); setTimeout(() => { setUpdating(false); }, 1000); }; const handleDelete = async (id: number) => { await notesApi.delete(id); loadFolderTree(); clearSelection(); }; const clearSelection = () => { setSelectedNote(null); setTitle(""); setContent(""); }; return (
{/* Sidebar */} {/* Main editor area */}
{/* Top accent bar */}
{/* Content area with padding */}
{/* Title input */} setTitle(e.target.value)} className="w-full px-0 py-3 mb-4 text-3xl font-semibold bg-transparent border-b border-ctp-surface2 focus:outline-none focus:border-ctp-mauve transition-colors placeholder:text-ctp-overlay0 text-ctp-text" /> {/* Editor */}
( <> ), }), tablePlugin(), listsPlugin(), quotePlugin(), thematicBreakPlugin(), linkPlugin(), codeBlockPlugin({ defaultCodeBlockLanguage: "js" }), sandpackPlugin({ sandpackConfig: simpleSandpackConfig }), codeMirrorPlugin({ codeBlockLanguages: { js: "JavaScript", css: "CSS", python: "Python", typescript: "TypeScript", html: "HTML", }, }), imagePlugin(), markdownShortcutPlugin(), diffSourcePlugin({ viewMode: "rich-text", diffMarkdown: "boo", }), ]} />
{/* Action bar */}
{selectedNote ? ( <> ) : ( )}
{/* Status indicator */}
{updating ? ( <> Saving... ) : ( <> Saved )}
); } export default Home; interface RenderFolderProps { folder: FolderTreeNode; depth?: number; setSelectedFolder: (id: number | null) => void; selectedFolder: number | null; selectedNote: NoteRead | null; selectNote: (note: NoteRead) => void; } const RenderFolder = ({ folder, depth = 0, setSelectedFolder, selectedFolder, selectedNote, selectNote, }: RenderFolderProps) => { const [collapse, setCollapse] = useState(false); return (
0 ? "1.5rem" : "0" }} > {collapse && ( <>
{folder.notes.map((note) => ( ))}
{folder.children.map((child) => ( ))} )}
); };