mirror of
https://github.com/lordmathis/lemma.git
synced 2025-11-05 23:44:22 +00:00
Save file on FE
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { GeistProvider, CssBaseline } from '@geist-ui/core';
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import { GeistProvider, CssBaseline, useToasts } from '@geist-ui/core';
|
||||
import Editor from './components/Editor';
|
||||
import FileTree from './components/FileTree';
|
||||
import { fetchFileList, fetchFileContent } from './services/api';
|
||||
import { fetchFileList, fetchFileContent, saveFileContent } from './services/api';
|
||||
import './App.scss';
|
||||
|
||||
function App() {
|
||||
@@ -10,6 +10,7 @@ function App() {
|
||||
const [files, setFiles] = useState([]);
|
||||
const [selectedFile, setSelectedFile] = useState(null);
|
||||
const [error, setError] = useState(null);
|
||||
const { setToast } = useToasts();
|
||||
|
||||
useEffect(() => {
|
||||
const loadFileList = async () => {
|
||||
@@ -34,12 +35,23 @@ function App() {
|
||||
const fileContent = await fetchFileContent(filePath);
|
||||
setContent(fileContent);
|
||||
setSelectedFile(filePath);
|
||||
setError(null);
|
||||
} catch (error) {
|
||||
console.error('Failed to load file content:', error);
|
||||
setError('Failed to load file content. Please try again.');
|
||||
}
|
||||
};
|
||||
|
||||
const handleSave = useCallback(async (filePath, fileContent) => {
|
||||
try {
|
||||
await saveFileContent(filePath, fileContent);
|
||||
setToast({ text: 'File saved successfully', type: 'success' });
|
||||
} catch (error) {
|
||||
console.error('Error saving file:', error);
|
||||
setToast({ text: 'Failed to save file. Please try again.', type: 'error' });
|
||||
}
|
||||
}, [setToast]);
|
||||
|
||||
return (
|
||||
<GeistProvider>
|
||||
<CssBaseline />
|
||||
@@ -57,7 +69,12 @@ function App() {
|
||||
</div>
|
||||
<div className="main-content">
|
||||
<h1>NovaMD</h1>
|
||||
<Editor content={content} onChange={setContent} />
|
||||
<Editor
|
||||
content={content}
|
||||
onChange={setContent}
|
||||
onSave={handleSave}
|
||||
filePath={selectedFile}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</GeistProvider>
|
||||
|
||||
@@ -5,17 +5,27 @@ import { EditorView, keymap } from "@codemirror/view";
|
||||
import { markdown } from "@codemirror/lang-markdown";
|
||||
import { defaultKeymap } from "@codemirror/commands";
|
||||
|
||||
const Editor = ({ content, onChange }) => {
|
||||
const Editor = ({ content, onChange, onSave, filePath }) => {
|
||||
const editorRef = useRef();
|
||||
const viewRef = useRef();
|
||||
|
||||
useEffect(() => {
|
||||
const handleSave = (view) => {
|
||||
onSave(filePath, view.state.doc.toString());
|
||||
return true;
|
||||
};
|
||||
|
||||
const state = EditorState.create({
|
||||
doc: content,
|
||||
extensions: [
|
||||
basicSetup,
|
||||
markdown(),
|
||||
keymap.of(defaultKeymap),
|
||||
keymap.of([{
|
||||
key: "Ctrl-s",
|
||||
run: handleSave,
|
||||
preventDefault: true
|
||||
}]),
|
||||
EditorView.updateListener.of((update) => {
|
||||
if (update.docChanged) {
|
||||
onChange(update.state.doc.toString());
|
||||
@@ -34,7 +44,7 @@ const Editor = ({ content, onChange }) => {
|
||||
return () => {
|
||||
view.destroy();
|
||||
};
|
||||
}, []);
|
||||
}, [filePath]);
|
||||
|
||||
useEffect(() => {
|
||||
if (viewRef.current && content !== viewRef.current.state.doc.toString()) {
|
||||
|
||||
@@ -24,4 +24,20 @@ export const fetchFileContent = async (filePath) => {
|
||||
console.error('Error fetching file content:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export const saveFileContent = async (filePath, content) => {
|
||||
const response = await fetch(`/api/v1/files/${filePath}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'text/plain',
|
||||
},
|
||||
body: content,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to save file');
|
||||
}
|
||||
|
||||
return await response.text();
|
||||
};
|
||||
Reference in New Issue
Block a user