feat: implement WYSIWYG markdown editor
Add complete markdown editor with Go backend and React/TypeScript frontend. Backend: - Cobra CLI with configurable host, port, data-dir, static-dir flags - REST API for CRUD operations on markdown files (GET, POST, PUT, DELETE) - File storage with flat .md structure - Comprehensive Logrus logging for all operations - Static asset serving for frontend Frontend: - React 18 + TypeScript + Tailwind CSS - Live markdown editor with GFM preview (react-markdown) - File management UI (list, create, open, save, delete) - Theme system (Light/Dark/System) with localStorage persistence - Responsive design (320px - 1920px+) Testing: - 6 backend tests covering CRUD round-trip, validation, error handling - 19 frontend tests covering API, theme system, and UI components - All tests passing with single 'make test' command Build: - Frontend compiles to optimized assets in dist/ - Backend can serve frontend via --static-dir flag
This commit is contained in:
32
frontend/src/components/Editor.tsx
Normal file
32
frontend/src/components/Editor.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
|
||||
interface EditorProps {
|
||||
content: string;
|
||||
onChange: (content: string) => void;
|
||||
placeholder?: string;
|
||||
}
|
||||
|
||||
export function Editor({ content, onChange, placeholder = '# Start writing\n\nYour markdown here...' }: EditorProps) {
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 h-[calc(100vh-160px)] min-h-[300px]">
|
||||
<div className="border-r border-gray-200 dark:border-gray-700">
|
||||
<textarea
|
||||
value={content}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
placeholder={placeholder}
|
||||
className="w-full h-full p-4 resize-none outline-none bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 font-mono text-sm leading-relaxed"
|
||||
spellCheck={false}
|
||||
/>
|
||||
</div>
|
||||
<div className="p-4 overflow-auto bg-gray-50 dark:bg-gray-800">
|
||||
<ReactMarkdown
|
||||
remarkPlugins={[remarkGfm]}
|
||||
className="prose dark:prose-invert max-w-none"
|
||||
>
|
||||
{content || placeholder}
|
||||
</ReactMarkdown>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user